diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 8a313292bb1..00000000000 --- a/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -*.dmm merge=merge-dmm diff --git a/.gitconfig b/.gitconfig deleted file mode 100644 index de5ff6f2542..00000000000 --- a/.gitconfig +++ /dev/null @@ -1,5 +0,0 @@ -[merge "merge-dmm"] - name = mapmerge driver - driver = ./mapmerge.sh %O %A %B - recursive = text - diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 00000000000..3d10f14d8e5 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,166 @@ +# CONTRIBUTING + +## Introduction +This is the contribution guide for Paradise Station. These guidelines apply to +both new issues and new pull requests. If you are making a pull request, please refer to +the [Pull request](#pull-requests) section, and if you are making an issue report, please +refer to the [Issue Report](#issues) section, as well as the +[Issue Report Template](ISSUE_TEMPLATE.md). + +## Commenting +If you comment on an active pull request, or issue report, make sure your comment is +concise and to the point. Comments on issue reports or pull requests should be relevant +and friendly, not attacks on the author or adages about something minimally relevant. +If you believe an issue report is not a "bug", please report it to the Maintainers, or +point out specifically and concisely your reasoning in a comment on the issue report. + +## Issues +The Issues section is not a place to request features, or ask for things to be changed +because you think they should be that way; The Issues section is specifically for +reporting bugs in the code. Refer to ISSUE_TEMPLATE for the exact format that your Issue +should be in. + +#### Guidelines: + - Issue reports should be as detailed as possible, and if applicable, should include + instructions on how to reproduce the bug. + +## Pull requests +Players are welcome to participate in the development of this fork and submit their own +pull requests. If the work you are submitting is a new feature, or affects balance, it is +strongly recommended you get approval/traction for it from our forums before starting the +actual development. + +#### Guidelines: + - Pull requests should be atomic; Make one commit for each distinct change, so if a part + of a pull request needs to be removed/changed, you may simply modify that single commit. + Due to limitations of the engine, this may not always be possible; but do try your best. + - Document and explain your pull requests thoroughly. Detail what each commit changes, + and why it changes it. We do not want to have to read all of you commit names to figure + out what your pull request is about. + - Any pull request that is not solely composed of fixes or non gameplay-affecting + refactors must have a changelog. See [here](../html/changelogs/__CHANGELOG_README.txt) + for more details, and [here](../html/changelogs/example.yml) for an example changelog. + Alternatively, inline changelogs are supported through the format described + [here](https://github.com/ParadiseSS13/Paradise/pull/3291#issuecomment-172950466). + - Pull requests should not have any merge commits except in the case of fixing merge + conflicts for an existing pull request. New pull requests should not have any merge + commits. Use `git rebase` or `git reset` to update your branches, not `git pull`. + +#### BYOND Specific Guidelines: + - Any `type` or `proc` paths **must** use absolute pathing unless the file you are + working in primarily utilizes relative pathing. + - Paths must begin with `/`. It should be `/obj/machinery/fancy_robot`, + not `obj/machinery/fancy_robot`. + - New bases of datum must begin with `/datum/`. `/datum/arbitrary_datum`, + not `/arbitrary_datum`. + - Don't use strings in combination with `text2path()` unless the paths are being + dynamically created. Variables can contain normal paths just fine. + - Don't duplicate code. If you have identical code in two places, it should probably + be a new proc that they both can use. + - No magic numbers/strings. If you have a number or text that is important and used in + your code, make a `#DEFINE` statement with a name that clearly indicates it's use. + - Do not use one-line control statements (if, else, for, while, etc). The space saved + is not worth the decreased readability. + - Control statements comparing a variable to a constant should be formatted `variable`, + `operator`, `constant`. This means `if(count <= 10)` is preferred over + `if(10 >= count)`. + - **Never** use a colon `:` operator to bypass type safety checks, unless you are doing + something where the tiny performance increase is incredibly noticeable (eg, a loop for + a huge list). You should properly typecast everything and use the period `.` + operator. + - Use early returns, and avoid far-indented if blocks. This means that you should not + do this: + ``` + /datum/datum1/proc/proc1() + if (thing1) + if (!thing2) + if (thing3 == 30) + do stuff + ``` + Instead, you should do this: + ``` + /datum/datum1/proc/proc1() + if (!thing1) + return + if (thing2) + return + if (thing3 != 30) + return + do stuff + ``` + - Any pull requests that affect map files must use the map-merge tools. Pull requests + that do not follow this guideline will be automatically declined, unless explicit + permission was given. + - The following examples of code are present in the code, but are no longer acceptable: + - To display messages to all mobs that can view `src`, you should use + `visible_message()`. + - Bad: + ``` + for (var/mob/M in viewers(src)) + M.show_message("Arbitrary text") + ``` + - Good: + ``` + visible_message("Arbitrary text") + ``` + - You should not use color macros (`\red, \blue, \green, \black`) to color text, + instead, you should use span classes. `red text`, + `blue text`. + - Bad: + ``` + usr << "\red Red Text \black black text" + ``` + - Good: + ``` + usr << "Red Textblack text" + ``` + - To use variables in strings, you should **never** use the `text()` operator, use + embedded expressions directly in the string. + - Bad: + ``` + usr << text("\The [] is leaking []!", src.name, src.liquid_type) + ``` + - Good: + ``` + usr << "\The [src] is leaking [liquid_type]" + ``` + - To reference a variable/proc on the src object, you should **not** use + `src.var`/`src.proc()`. The `src.` in these cases is implied, so you should just use + `var`/`proc()`. + - Bad: + ``` + var/user = src.interactor + src.fillReserves(user) + ``` + - Good: + ``` + var/user = interactor + fillReserves(user) + ``` + + +## Maintainers +The only current official role for GitHub staff are the `Maintainers`. There are up to +three `Maintainers` at once, and they share equal power. The `Maintainers` are +responsible for properly tagging new pull requests and issues, moderating comments in +pull requests/issues, and merging/closing pull requests. + +### Maintainer List + - [MarkvA](https://github.com/Markolie) + - [Fox P McCloud](https://github.com/Fox-McCloud) + - [TheDZD](https://github.com/TheDZD) + +### Maintainer instructions + - Do not `self-merge`; this refers to the practice of opening a pull request, then + merging it yourself. A different maintainer must review and merge your pull request, no + matter how trivial. This is to ensure quality. + - A subset of this instruction: Do not push directly to the repository, always make a + pull request. + - Wait for the Travis CI build to complete. If it fails, the pull request may only be + merged if there is a very good reason (example: fixing the Travis configuration). + - Pull requests labeled as bugfixes and refactors may be merged as soon as they are + reviewed. + - The shortest waiting period for -any- feature or balancing altering pull request is 24 + hours, to allow other coders and the community time to discuss the proposed changes. + - If the discussion is active, or the change is controversial, the pull request is to be + put on hold until a consensus is reached. \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 00000000000..d7646ecb97b --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,17 @@ +**Problem Description**: +What is the problem? + +**What did you expect to happen**: +Why do you think this is a bug? + +**What happened instead**: +How is what happened different from what you expected? + +**Why is this bad/What are the consequences:** +Why do you think this is an important issue? + +**Steps to reproduce the problem**: +The most important section. Review everything you did leading up to causing the issue. + +**Possibly related stuff (which gamemode was it? What were you doing at the time? Was +anything else out of the ordinary happening?)**: Anything else you can tell us. \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index c1b99405aa7..b79cb5e0db3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,14 +1,18 @@ #pretending we're C because otherwise ruby will initialize, even with "language: dm". -language: c +language: generic sudo: false +git: + depth: 1 + env: - global: + global: - BYOND_MAJOR="509" - BYOND_MINOR="1315" - matrix: + matrix: - DM_MAPFILE="cyberiad" - DM_MAPFILE="metastation" + - DM_MAPFILE="test_away_missions" cache: directories: @@ -20,20 +24,24 @@ addons: - libc6-i386 - libgcc1:i386 - libstdc++6:i386 - - python - - python-pip - -install: - - pip install --user PyYaml -q - - pip install --user beautifulsoup4 -q before_script: - chmod +x ./install-byond.sh - ./install-byond.sh script: - - shopt -s globstar - - (! grep 'step_[xy]' _maps/map_files/**/*.dmm) - - md5sum -c - <<< "6dc1b6bf583f3bd4176b6df494caa5f1 *html/changelogs/example.yml" - - python tools/ss13_genchangelog.py html/changelog.html html/changelogs - source $HOME/BYOND-${BYOND_MAJOR}.${BYOND_MINOR}/byond/bin/byondsetup - bash dm.sh -M${DM_MAPFILE} paradise.dme + +matrix: + include: + - env: FILE_CHECKS=1 + addons: + install: + - pip install --user PyYaml -q + - pip install --user beautifulsoup4 -q + before_script: + script: + - shopt -s globstar + - (! grep 'step_[xy]' _maps/map_files/**/*.dmm) + - md5sum -c - <<< "6dc1b6bf583f3bd4176b6df494caa5f1 *html/changelogs/example.yml" + - python tools/ss13_genchangelog.py html/changelog.html html/changelogs \ No newline at end of file diff --git a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm index c5efb941401..de672ffcf45 100644 --- a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm +++ b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm @@ -383,7 +383,7 @@ "ahs" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/item/weapon/pickaxe,/obj/item/weapon/storage/firstaid/toxin,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) "aht" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/item/weapon/scalpel,/obj/item/stack/cable_coil,/obj/item/weapon/storage/firstaid/regular,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) "ahu" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/item/weapon/circular_saw,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) -"ahv" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/optable,/obj/item/organ/brain,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) +"ahv" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/optable,/obj/item/organ/internal/brain,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) "ahw" = (/obj/machinery/door/poddoor/shutters{density = 0; dir = 4; icon_state = "shutter0"; id_tag = "voxshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/shuttle/window{dir = 4; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5_mid"; tag = "icon-window5 (EAST)"},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox) "ahx" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/auxsolarport) "ahy" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/security/prison) @@ -467,7 +467,7 @@ "aiY" = (/obj/structure/table/woodentable,/obj/item/weapon/stamp/hos,/turf/simulated/floor/carpet,/area/security/hos) "aiZ" = (/obj/item/weapon/phone{desc = "Supposedly a direct line to NanoTrasen Central Command. It's not even plugged in."; pixel_x = -3; pixel_y = 3},/obj/item/weapon/cigbutt/cigarbutt{pixel_x = 5; pixel_y = -1},/obj/structure/table/woodentable,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/carpet,/area/security/hos) "aja" = (/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/hos) -"ajb" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/hos) +"ajb" = (/obj/structure/closet/firecloset,/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/crew_quarters/fitness{name = "\improper Recreation Area"}) "ajc" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/obj/machinery/door/poddoor/preopen{id_tag = "hosprivacy"; name = "privacy shutters"},/turf/simulated/floor/plating,/area/security/hos) "ajd" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/security/range) "aje" = (/obj/structure/target_stake,/obj/item/target/syndicate,/turf/simulated/floor/plasteel,/area/security/range) @@ -520,7 +520,7 @@ "ajZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/carpet,/area/security/hos) "aka" = (/obj/machinery/hologram/holopad,/obj/structure/stool/bed/chair{dir = 1},/obj/effect/landmark/start{name = "Head of Security"},/turf/simulated/floor/carpet,/area/security/hos) "akb" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/carpet,/area/security/hos) -"akc" = (/obj/structure/table/woodentable,/obj/item/device/taperecorder{pixel_x = -4; pixel_y = 0},/obj/item/device/radio/off{pixel_x = 0; pixel_y = 3},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/hos) +"akc" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/item/device/taperecorder{pixel_x = -4; pixel_y = 0},/obj/item/device/radio/off{pixel_x = 0; pixel_y = 3},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/hos) "akd" = (/turf/simulated/floor/plasteel,/area/security/range) "ake" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating,/area/maintenance/fore) "akf" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/maintenance/fore) @@ -709,9 +709,9 @@ "anG" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"}) "anH" = (/turf/simulated/floor/plating{tag = "icon-panelscorched"; icon_state = "panelscorched"},/area/maintenance/fpmaint2{name = "Port Maintenance"}) "anI" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/book/manual/chef_recipes,/obj/item/weapon/book/manual/barman_recipes,/obj/item/weapon/firealarm_electronics,/obj/item/weapon/grenade/smokebomb,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"}) -"anJ" = (/obj/structure/table,/obj/item/clothing/gloves/color/latex,/obj/item/clothing/mask/surgical,/obj/item/weapon/reagent_containers/spray/cleaner,/turf/simulated/floor/plasteel{dir = 9; icon_state = "whitered"},/area/security/brig) +"anJ" = (/obj/structure/table/woodentable,/obj/machinery/photocopier/faxmachine{department = "Head of Security's Office"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/hos) "anK" = (/obj/structure/table,/obj/item/device/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = 0; pixel_y = 26},/obj/machinery/light/small{dir = 1},/obj/item/weapon/folder/red{pixel_x = 3},/obj/item/weapon/folder/white{pixel_x = -4; pixel_y = 2},/obj/item/device/healthanalyzer,/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitered"},/area/security/brig) -"anL" = (/obj/structure/table,/obj/machinery/alarm{pixel_y = 28},/obj/machinery/computer/med_data/laptop,/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitered"},/area/security/brig) +"anL" = (/obj/machinery/atmospherics/unary/portables_connector,/turf/simulated/floor/plating,/area/maintenance/fore) "anM" = (/obj/structure/table,/obj/structure/window/reinforced{dir = 4},/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/turf/simulated/floor/plasteel{dir = 5; icon_state = "whitered"},/area/security/brig) "anN" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 9},/area/security/brig) "anO" = (/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 1},/area/security/brig) @@ -745,9 +745,9 @@ "aoq" = (/obj/structure/closet/firecloset,/turf/simulated/floor/plating,/area/maintenance/fore) "aor" = (/turf/simulated/floor/plating{tag = "icon-panelscorched"; icon_state = "panelscorched"},/area/maintenance/fore) "aos" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/turf/simulated/floor/plating,/area/maintenance/fore) -"aot" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor/plating,/area/maintenance/fore) -"aou" = (/obj/machinery/atmospherics/unary/portables_connector{dir = 8},/turf/simulated/floor/plating,/area/maintenance/fore) -"aov" = (/obj/structure/closet/firecloset,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/fitness{name = "\improper Recreation Area"}) +"aot" = (/obj/machinery/sleeper{dir = 8; name = "Prisoner Sleeper"},/turf/simulated/floor/plasteel{dir = 9; icon_state = "whitered"},/area/security/brig) +"aou" = (/obj/structure/table,/obj/item/clothing/gloves/color/latex,/obj/item/clothing/mask/surgical,/obj/item/weapon/reagent_containers/spray/cleaner,/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitered"},/area/security/brig) +"aov" = (/obj/machinery/sleep_console,/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitered"},/area/security/brig) "aow" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/crew_quarters/fitness{name = "\improper Recreation Area"}) "aox" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/turf/simulated/floor/plasteel{dir = 4; icon_state = "neutralcorner"},/area/crew_quarters/fitness{name = "\improper Recreation Area"}) "aoy" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 2; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/crew_quarters/fitness{name = "\improper Recreation Area"}) @@ -785,8 +785,8 @@ "ape" = (/obj/machinery/light_construct/small{dir = 4},/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/storage/secure/briefcase,/obj/item/weapon/disk/data,/obj/item/weapon/storage/secure/safe{pixel_x = 35; pixel_y = 0},/obj/item/weapon/grenade/flashbang,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"}) "apf" = (/turf/simulated/wall,/area/maintenance/fpmaint2{name = "Port Maintenance"}) "apg" = (/obj/machinery/portable_atmospherics/canister/sleeping_agent,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/maintenance/fore) -"aph" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/reagent_containers/glass/bottle/epinephrine,/obj/item/weapon/reagent_containers/glass/bottle/charcoal,/obj/item/weapon/reagent_containers/syringe,/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 10; icon_state = "whitered"},/area/security/brig) -"api" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whiteredcorner"},/area/security/brig) +"aph" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/reagent_containers/glass/bottle/epinephrine,/obj/item/weapon/reagent_containers/glass/bottle/charcoal,/obj/item/weapon/reagent_containers/syringe,/obj/machinery/alarm{pixel_y = 28},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitered"},/area/security/brig) +"api" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plating,/area/maintenance/fore) "apj" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/security/brig) "apk" = (/obj/machinery/door/window/westleft{base_state = "left"; dir = 4; icon_state = "left"; name = "Infirmary"; req_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitered"; tag = "icon-whitehall (WEST)"},/area/security/brig) "apl" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "redcorner"; dir = 1},/area/security/brig) @@ -820,9 +820,9 @@ "apN" = (/obj/item/target,/obj/item/target,/obj/item/target/alien,/obj/item/target/alien,/obj/item/target/alien,/obj/item/target/syndicate,/obj/item/target/syndicate,/obj/item/target/syndicate,/obj/structure/closet/crate/secure{desc = "A secure crate containing various materials for building a customised test-site."; name = "Firing Range Gear Crate"; req_access_txt = "1"},/obj/machinery/power/apc{cell_type = 2500; dir = 4; name = "Shooting Range APC"; pixel_x = 24; pixel_y = 0},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/security/range) "apO" = (/obj/structure/rack,/obj/item/weapon/storage/box/lights/mixed,/obj/item/weapon/storage/box/donkpockets,/turf/simulated/floor/plating,/area/maintenance/fore) "apP" = (/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/fore) -"apQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/space_heater,/turf/simulated/floor/plating,/area/maintenance/fore) -"apR" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plating{tag = "icon-platingdmg1"; icon_state = "platingdmg1"},/area/maintenance/fore) -"apS" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/crew_quarters/fitness{name = "\improper Recreation Area"}) +"apQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/floor/plating,/area/maintenance/fore) +"apR" = (/obj/machinery/prize_counter,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/fitness{name = "\improper Recreation Area"}) +"apS" = (/obj/structure/stool/bed/roller,/turf/simulated/floor/plasteel{dir = 10; icon_state = "whitered"},/area/security/brig) "apT" = (/obj/structure/window/reinforced,/obj/machinery/door/window/eastright{base_state = "left"; dir = 8; icon_state = "left"; name = "Fitness Ring"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/fitness{name = "\improper Recreation Area"}) "apU" = (/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/fitness{name = "\improper Recreation Area"}) "apV" = (/obj/structure/window/reinforced,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/fitness{name = "\improper Recreation Area"}) @@ -861,9 +861,9 @@ "aqC" = (/obj/structure/rack{dir = 1},/obj/item/clothing/under/rank/mailman,/obj/item/clothing/under/rank/vice{pixel_x = 4; pixel_y = -3},/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"}) "aqD" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/maintenance/fore) "aqE" = (/obj/machinery/door/airlock/glass_security{name = "N2O Storage"; req_access_txt = "3"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/maintenance/fore) -"aqF" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/morgue,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/brig) -"aqG" = (/obj/effect/landmark/start{name = "Brig Physician"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitered"; tag = "icon-whitehall (WEST)"},/area/security/brig) -"aqH" = (/obj/structure/stool/bed/roller,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "white"},/area/security/brig) +"aqF" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "whiteredcorner"},/area/security/brig) +"aqG" = (/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitered"},/area/security/brig) +"aqH" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/security/brig) "aqI" = (/obj/machinery/door/window/westleft{base_state = "right"; dir = 4; icon_state = "right"; name = "Infirmary"; req_access_txt = "0"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitered"; tag = "icon-whitehall (WEST)"},/area/security/brig) "aqJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "redcorner"; dir = 1},/area/security/brig) "aqK" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/plasteel,/area/security/brig) @@ -920,17 +920,17 @@ "arJ" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"}) "arK" = (/obj/machinery/space_heater,/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"}) "arL" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"}) -"arM" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor/plating{tag = "icon-panelscorched"; icon_state = "panelscorched"},/area/maintenance/fpmaint2{name = "Port Maintenance"}) +"arM" = (/obj/machinery/space_heater,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor/plating,/area/maintenance/fore) "arN" = (/obj/machinery/atmospherics/unary/portables_connector{dir = 8},/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"}) -"arO" = (/obj/machinery/atmospherics/unary/portables_connector{dir = 4},/obj/machinery/portable_atmospherics/canister/air,/obj/item/weapon/tank/air,/turf/simulated/floor/plating,/area/maintenance/fore) -"arP" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating,/area/maintenance/fore) -"arQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating,/area/maintenance/fore) +"arO" = (/obj/structure/closet/emcloset,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; level = 1},/turf/simulated/floor/plating{tag = "icon-platingdmg1"; icon_state = "platingdmg1"},/area/maintenance/fore) +"arP" = (/obj/structure/table,/obj/machinery/computer/med_data/laptop,/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitered"; tag = "icon-whitehall (WEST)"},/area/security/brig) +"arQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "white"},/area/security/brig) "arR" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/maintenance/fore) -"arS" = (/obj/machinery/door/airlock/maintenance{icon = 'icons/obj/doors/doorint.dmi'; name = "Brig Emergency Storage"; req_access_txt = "63"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/security/brig) -"arT" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/brig) -"arU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/light/small,/turf/simulated/floor/plasteel{dir = 10; icon_state = "whitered"},/area/security/brig) +"arS" = (/obj/effect/landmark/start{name = "Brig Physician"},/obj/structure/stool,/turf/simulated/floor/plasteel{icon_state = "white"},/area/security/brig) +"arT" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/turf/simulated/floor/plating{tag = "icon-panelscorched"; icon_state = "panelscorched"},/area/maintenance/fpmaint2{name = "Port Maintenance"}) +"arU" = (/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"}) "arV" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/iv_drip{density = 0},/turf/simulated/floor/plasteel{icon_state = "whitered"},/area/security/brig) -"arW" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/rack,/obj/item/weapon/storage/firstaid/regular,/obj/item/device/healthanalyzer{pixel_y = -2},/obj/machinery/camera{c_tag = "Brig - Infirmary"; dir = 1; network = list("SS13")},/obj/item/clothing/under/rank/medical/purple{pixel_y = -4},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 6; icon_state = "whitered"},/area/security/brig) +"arW" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/fore) "arX" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "redcorner"; dir = 1},/area/security/brig) "arY" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel,/area/security/brig) "arZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/firealarm{dir = 4; pixel_x = 28},/turf/simulated/floor/plasteel{icon_state = "redcorner"; dir = 4},/area/security/brig) @@ -1012,7 +1012,7 @@ "atx" = (/obj/machinery/disposal,/obj/machinery/alarm{pixel_y = 28},/obj/structure/disposalpipe/trunk,/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/security/warden) "aty" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 2; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/structure/rack,/obj/item/clothing/mask/gas/sechailer{pixel_x = 3; pixel_y = 3},/obj/item/clothing/mask/gas/sechailer,/obj/item/clothing/mask/gas/sechailer{pixel_x = -3; pixel_y = -3},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/security/warden) "atz" = (/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 29; pixel_y = 22},/obj/machinery/computer/crew,/obj/machinery/firealarm{dir = 4; pixel_x = 28},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/security/warden) -"atA" = (/obj/structure/table,/obj/structure/reagent_dispensers/peppertank{pixel_x = 32; pixel_y = 0},/obj/item/weapon/paper_bin{pixel_x = -2; pixel_y = 7},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/security/warden) +"atA" = (/obj/machinery/atmospherics/unary/portables_connector{dir = 4},/obj/machinery/portable_atmospherics/canister/air,/obj/item/weapon/tank/air,/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating,/area/maintenance/fore) "atB" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/reagent_dispensers/peppertank{pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 8},/area/security/main) "atC" = (/obj/structure/table,/obj/item/weapon/folder/red,/obj/item/weapon/storage/fancy/cigarettes,/turf/simulated/floor/plasteel,/area/security/main) "atD" = (/obj/structure/table,/obj/item/weapon/folder/red,/obj/item/weapon/restraints/handcuffs,/turf/simulated/floor/plasteel,/area/security/main) @@ -1071,7 +1071,7 @@ "auE" = (/obj/item/weapon/vending_refill/cigarette,/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"}) "auF" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor/plating{tag = "icon-panelscorched"; icon_state = "panelscorched"},/area/maintenance/fpmaint2{name = "Port Maintenance"}) "auG" = (/obj/structure/closet/crate,/obj/item/clothing/gloves/color/fyellow,/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"}) -"auH" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating{icon_plating = "warnplate"; icon_state = "warnplate"},/area/maintenance/fpmaint2{name = "Port Maintenance"}) +"auH" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/fore) "auI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating{icon_plating = "warnplate"; icon_state = "warnplate"},/area/maintenance/fpmaint2{name = "Port Maintenance"}) "auJ" = (/obj/structure/reagent_dispensers/watertank,/obj/item/weapon/extinguisher,/turf/simulated/floor/plating,/area/maintenance/fore) "auK" = (/obj/structure/closet/crate,/obj/item/weapon/restraints/handcuffs,/obj/item/bodybag,/obj/item/device/radio,/obj/effect/spawner/lootdrop/maintenance{lootcount = 3; name = "3maintenance loot spawner"},/turf/simulated/floor/plating,/area/maintenance/fore) @@ -1300,7 +1300,7 @@ "ayZ" = (/obj/machinery/firealarm{pixel_y = 28},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "redcorner"; dir = 4},/area/security/brig) "aza" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{icon_state = "redcorner"; dir = 4},/area/security/brig) "azb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "redcorner"; dir = 4},/area/security/brig) -"azc" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 5},/area/security/brig) +"azc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 10; icon_state = "whitered"},/area/security/brig) "azd" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; external_pressure_bound = 101.325; on = 1; pressure_checks = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/brig) "aze" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/brig) "azf" = (/obj/structure/table/woodentable,/obj/machinery/alarm{dir = 4; pixel_x = -25; pixel_y = 0},/turf/simulated/floor/wood,/area/crew_quarters/mrchangs) @@ -1438,7 +1438,7 @@ "aBH" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/brig) "aBI" = (/turf/simulated/wall,/area/crew_quarters/locker/locker_toilet{name = "\improper Restrooms"}) "aBJ" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/wood,/area/crew_quarters/mrchangs) -"aBK" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/wood,/area/crew_quarters/mrchangs) +"aBK" = (/obj/machinery/door/airlock/maintenance{icon = 'icons/obj/doors/doorint.dmi'; name = "Brig Emergency Storage"; req_access_txt = "63"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/security/brig) "aBL" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/mrchangs) "aBM" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/airlock/glass{name = "Fore Primary Hallway"},/turf/simulated/floor/wood,/area/crew_quarters/mrchangs) "aBN" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 1; icon_state = "neutralcorner"},/area/crew_quarters/sleep) @@ -1499,9 +1499,9 @@ "aCQ" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/security{name = "Detective's Office"; req_access = null; req_access_txt = "4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/turf/simulated/floor/plasteel,/area/security/detectives_office) "aCR" = (/obj/structure/grille,/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/turf/simulated/floor/plating,/area/security/detectives_office) "aCS" = (/turf/simulated/wall,/area/security/detectives_office) -"aCT" = (/obj/machinery/shower{tag = "icon-shower (EAST)"; icon_state = "shower"; dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet{name = "\improper Restrooms"}) +"aCT" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/light/small,/turf/simulated/floor/plasteel{icon_state = "whitered"},/area/security/brig) "aCU" = (/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/machinery/alarm{pixel_y = 26},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet{name = "\improper Restrooms"}) -"aCV" = (/obj/machinery/shower{tag = "icon-shower (WEST)"; icon_state = "shower"; dir = 8},/obj/effect/landmark/start{name = "Civilian"},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet{name = "\improper Restrooms"}) +"aCV" = (/obj/structure/window/reinforced{dir = 4},/obj/machinery/camera{c_tag = "Brig - Infirmary"; dir = 1; network = list("SS13")},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/closet/secure_closet/brigdoc,/turf/simulated/floor/plasteel{dir = 6; icon_state = "whitered"},/area/security/brig) "aCW" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/structure/sign/chinese{pixel_x = -32},/turf/simulated/floor/plasteel{dir = 1; icon_state = "neutralcorner"},/area/crew_quarters/sleep) "aCX" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11},/turf/simulated/floor/plasteel,/area/crew_quarters/sleep) "aCY" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/crew_quarters/sleep) @@ -1567,9 +1567,9 @@ "aEg" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fore) "aEh" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating{tag = "icon-platingdmg2"; icon_state = "platingdmg2"},/area/maintenance/fore) "aEi" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/fore) -"aEj" = (/obj/structure/mirror{pixel_x = -28},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/shower{tag = "icon-shower (EAST)"; icon_state = "shower"; dir = 4},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet{name = "\improper Restrooms"}) +"aEj" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"}) "aEk" = (/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/obj/item/weapon/bikehorn/rubberducky,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet{name = "\improper Restrooms"}) -"aEl" = (/obj/structure/mirror{pixel_x = 28},/obj/machinery/shower{tag = "icon-shower (WEST)"; icon_state = "shower"; dir = 8},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet{name = "\improper Restrooms"}) +"aEl" = (/obj/item/weapon/cigbutt,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"}) "aEm" = (/obj/machinery/washing_machine,/turf/simulated/floor/plasteel{icon_state = "barber"},/area/crew_quarters/sleep) "aEn" = (/obj/structure/table,/obj/item/clothing/under/suit_jacket/female{pixel_x = 3; pixel_y = 1},/obj/item/clothing/under/suit_jacket/really_black{pixel_x = -2; pixel_y = 0},/obj/machinery/light/small{dir = 1},/obj/item/device/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = 0; pixel_y = 28},/obj/item/clothing/accessory/waistcoat,/obj/item/clothing/under/suit_jacket/red,/obj/item/clothing/accessory/black,/turf/simulated/floor/plasteel{icon_state = "barber"},/area/crew_quarters/sleep) "aEo" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "neutralcorner"},/area/crew_quarters/sleep) @@ -1638,9 +1638,9 @@ "aFz" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fore) "aFA" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/fore) "aFB" = (/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/effect/landmark{name = "blobstart"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/turf/simulated/floor/plating,/area/maintenance/fore) -"aFC" = (/obj/machinery/shower{tag = "icon-shower (EAST)"; icon_state = "shower"; dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet{name = "\improper Restrooms"}) +"aFC" = (/obj/structure/table,/obj/structure/reagent_dispensers/peppertank{pixel_x = 32; pixel_y = 0},/obj/item/weapon/paper_bin{pixel_x = -2; pixel_y = 7},/obj/item/device/eftpos,/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/security/warden) "aFD" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet{name = "\improper Restrooms"}) -"aFE" = (/obj/machinery/shower{tag = "icon-shower (WEST)"; icon_state = "shower"; dir = 8},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet{name = "\improper Restrooms"}) +"aFE" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11},/turf/simulated/floor/plating{icon_plating = "warnplate"; icon_state = "warnplate"},/area/maintenance/fpmaint2{name = "Port Maintenance"}) "aFF" = (/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 1; icon_state = "neutralcorner"},/area/crew_quarters/sleep) "aFG" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 1; icon_state = "neutralcorner"},/area/crew_quarters/sleep) "aFH" = (/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/obj/machinery/light/small{dir = 1},/obj/machinery/power/apc{dir = 1; name = "Dormitories APC"; pixel_x = 0; pixel_y = 24},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 1; icon_state = "neutralcorner"},/area/crew_quarters/sleep) @@ -2056,7 +2056,7 @@ "aNB" = (/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/courtroom) "aNC" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/courtroom) "aND" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp/green{pixel_x = 1; pixel_y = 5},/obj/machinery/requests_console{department = "Law office"; pixel_x = 0; pixel_y = 32},/obj/machinery/newscaster{pixel_x = -31; pixel_y = 0},/turf/simulated/floor/wood,/area/lawoffice) -"aNE" = (/obj/structure/table/woodentable,/obj/item/weapon/book/manual/security_space_law,/obj/item/weapon/book/manual/security_space_law,/obj/item/weapon/pen/multi,/obj/machinery/computer/security/telescreen{desc = "Used for watching Prison Wing holding areas."; name = "Prison Monitor"; network = list("Prison"); pixel_x = 0; pixel_y = 30},/turf/simulated/floor/wood,/area/lawoffice) +"aNE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5; level = 1},/turf/simulated/floor/plating{tag = "icon-platingdmg3"; icon_state = "platingdmg3"},/area/maintenance/fpmaint2{name = "Port Maintenance"}) "aNF" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/storage/briefcase{pixel_x = -3; pixel_y = 2},/obj/item/weapon/storage/secure/briefcase{pixel_x = 2; pixel_y = -2},/obj/item/clothing/glasses/sunglasses,/turf/simulated/floor/wood,/area/lawoffice) "aNG" = (/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/obj/machinery/power/apc{dir = 1; name = "Law Office APC"; pixel_y = 24},/obj/structure/flora/kirbyplants{icon_state = "plant-21"; layer = 4.1; tag = "icon-plant-21"},/turf/simulated/floor/wood,/area/lawoffice) "aNH" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/wood,/area/lawoffice) @@ -2119,7 +2119,7 @@ "aOM" = (/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 9},/area/crew_quarters/courtroom) "aON" = (/obj/structure/table/woodentable,/obj/item/device/radio/intercom{broadcasting = 1; dir = 8; listening = 0; name = "Station Intercom (Court)"; pixel_x = 0},/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 1},/area/crew_quarters/courtroom) "aOO" = (/obj/structure/table/woodentable,/obj/item/weapon/gavelblock,/obj/item/weapon/gavelhammer,/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 1},/area/crew_quarters/courtroom) -"aOP" = (/obj/structure/table/woodentable,/obj/item/weapon/book/manual/security_space_law,/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 1},/area/crew_quarters/courtroom) +"aOP" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atm{pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 5},/area/security/brig) "aOQ" = (/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 5},/area/crew_quarters/courtroom) "aOR" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor/plasteel{tag = "icon-vault (WEST)"; icon_state = "vault"; dir = 8},/area/crew_quarters/courtroom) "aOS" = (/obj/machinery/door/window/southleft{name = "Court Cell"; req_access_txt = "2"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/courtroom) @@ -2178,14 +2178,14 @@ "aPT" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"}) "aPU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating{tag = "icon-platingdmg1"; icon_state = "platingdmg1"},/area/maintenance/fpmaint2{name = "Port Maintenance"}) "aPV" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"}) -"aPW" = (/obj/structure/table,/obj/item/clothing/gloves/color/fyellow,/obj/item/device/gps{gpstag = "AUX0"},/turf/simulated/floor/plasteel{dir = 9; icon_state = "brown"},/area/storage/primary) +"aPW" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atm{pixel_y = -32},/turf/simulated/floor/wood,/area/crew_quarters/mrchangs) "aPX" = (/turf/simulated/floor/plasteel{dir = 1; icon_state = "brown"},/area/storage/primary) "aPY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 1; icon_state = "brown"},/area/storage/primary) "aPZ" = (/obj/structure/table,/obj/item/stack/cable_coil{pixel_x = 2; pixel_y = -2},/obj/item/stack/cable_coil{pixel_x = 3; pixel_y = 5},/obj/item/weapon/screwdriver{pixel_y = 16},/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor/plasteel{dir = 1; icon_state = "brown"},/area/storage/primary) "aQa" = (/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/obj/machinery/light_switch{pixel_y = 28},/turf/simulated/floor/plasteel{dir = 1; icon_state = "brown"},/area/storage/primary) "aQb" = (/obj/machinery/vending/assist,/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plasteel{dir = 1; icon_state = "brown"},/area/storage/primary) "aQc" = (/obj/machinery/vending/tool,/turf/simulated/floor/plasteel{dir = 1; icon_state = "brown"},/area/storage/primary) -"aQd" = (/obj/structure/table,/obj/item/device/assembly/signaler,/obj/item/device/assembly/signaler,/obj/item/device/multitool,/obj/item/device/multitool{pixel_x = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plasteel{dir = 5; icon_state = "brown"},/area/storage/primary) +"aQd" = (/obj/machinery/shower{tag = "icon-shower (EAST)"; icon_state = "shower"; dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/structure/curtain/open/shower,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet{name = "\improper Restrooms"}) "aQe" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/storage/primary) "aQf" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/space,/area/space) "aQg" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload) @@ -2203,7 +2203,7 @@ "aQs" = (/obj/effect/landmark/start{name = "Internal Affairs Agent"},/turf/simulated/floor/plasteel,/area/crew_quarters/courtroom) "aQt" = (/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 4},/area/crew_quarters/courtroom) "aQu" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor/wood,/area/lawoffice) -"aQv" = (/obj/structure/table/woodentable,/obj/item/weapon/folder/red,/obj/item/weapon/folder/red,/obj/item/weapon/folder/red,/obj/item/clothing/glasses/sunglasses/big,/turf/simulated/floor/wood,/area/lawoffice) +"aQv" = (/obj/machinery/shower{tag = "icon-shower (WEST)"; icon_state = "shower"; dir = 8},/obj/effect/landmark/start{name = "Civilian"},/obj/structure/curtain/open/shower,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet{name = "\improper Restrooms"}) "aQw" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/wood,/area/lawoffice) "aQx" = (/obj/machinery/photocopier,/obj/machinery/camera{c_tag = "Law Office"; dir = 8; network = list("SS13")},/turf/simulated/floor/wood,/area/lawoffice) "aQy" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/crew_quarters/locker) @@ -2253,12 +2253,12 @@ "aRq" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/effect/landmark/start{name = "Cargo Technician"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel,/area/quartermaster/storage) "aRr" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel{dir = 8; icon_state = "loadingarea"; tag = "loading"},/area/quartermaster/storage) "aRs" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=8"; freq = 1400; location = "QM #3"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/bot/mulebot{home_destination = "QM #3"; suffix = "#3"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/quartermaster/storage) -"aRt" = (/obj/machinery/camera/autoname{dir = 4; network = list("SS13")},/obj/structure/rack,/obj/item/weapon/storage/toolbox/electrical{pixel_x = 1; pixel_y = -1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "brown"},/area/storage/primary) +"aRt" = (/obj/structure/mirror{pixel_x = -28},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/shower{tag = "icon-shower (EAST)"; icon_state = "shower"; dir = 4},/obj/structure/curtain/open/shower,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet{name = "\improper Restrooms"}) "aRu" = (/turf/simulated/floor/plasteel,/area/storage/primary) "aRv" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plasteel,/area/storage/primary) "aRw" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11},/turf/simulated/floor/plasteel,/area/storage/primary) "aRx" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/storage/primary) -"aRy" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/vending/artvend,/turf/simulated/floor/plasteel{dir = 4; icon_state = "brown"},/area/storage/primary) +"aRy" = (/obj/structure/mirror{pixel_x = 28},/obj/machinery/shower{tag = "icon-shower (WEST)"; icon_state = "shower"; dir = 8},/obj/structure/curtain/open/shower,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet{name = "\improper Restrooms"}) "aRz" = (/obj/structure/table,/obj/item/weapon/aiModule/asimov,/obj/item/weapon/aiModule/freeformcore,/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"; name = "Core Modules"; req_access_txt = "20"},/obj/structure/window/reinforced,/obj/item/weapon/aiModule/corp,/obj/item/weapon/aiModule/paladin,/obj/item/weapon/aiModule/robocop,/obj/machinery/flasher{pixel_x = 0; pixel_y = 24; id = "AI"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai_upload) "aRA" = (/turf/simulated/floor/bluegrid,/area/turret_protected/ai_upload) "aRB" = (/obj/structure/table,/obj/machinery/door/window{base_state = "left"; dir = 8; icon_state = "left"; name = "High-Risk Modules"; req_access_txt = "20"},/obj/structure/window/reinforced,/obj/machinery/flasher{pixel_x = 0; pixel_y = 24; id = "AI"},/obj/item/weapon/aiModule/antimov,/obj/item/weapon/aiModule/oxygen,/obj/item/weapon/aiModule/oneCrewMember,/obj/item/weapon/aiModule/purge,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai_upload) @@ -2342,11 +2342,11 @@ "aTb" = (/obj/structure/table/woodentable,/obj/item/weapon/paper,/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 10},/area/crew_quarters/courtroom) "aTc" = (/turf/simulated/floor/plasteel{icon_state = "neutral"},/area/crew_quarters/courtroom) "aTd" = (/obj/item/device/radio/beacon,/turf/simulated/floor/plasteel{icon_state = "neutral"},/area/crew_quarters/courtroom) -"aTe" = (/obj/structure/table/woodentable,/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 6},/area/crew_quarters/courtroom) +"aTe" = (/obj/machinery/shower{tag = "icon-shower (EAST)"; icon_state = "shower"; dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/curtain/open/shower,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet{name = "\improper Restrooms"}) "aTf" = (/obj/structure/stool/bed/chair{dir = 8; name = "Defense"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plasteel{icon_state = "green"; dir = 6},/area/crew_quarters/courtroom) "aTg" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/turf/simulated/floor/plasteel,/area/crew_quarters/courtroom) -"aTh" = (/obj/item/device/taperecorder{pixel_y = 0},/obj/item/weapon/cartridge/lawyer,/obj/machinery/door_control{id = "lawyer_blast"; name = "Privacy Shutters"; pixel_x = 0; pixel_y = -26},/obj/structure/table/woodentable,/turf/simulated/floor/wood,/area/lawoffice) -"aTi" = (/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen/multi,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/table/woodentable,/turf/simulated/floor/wood,/area/lawoffice) +"aTh" = (/obj/machinery/shower{tag = "icon-shower (WEST)"; icon_state = "shower"; dir = 8},/obj/structure/curtain/open/shower,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet{name = "\improper Restrooms"}) +"aTi" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atm{pixel_y = -32},/turf/simulated/floor/plasteel{dir = 8; icon_state = "redcorner"},/area/hallway/primary/fore) "aTj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/wood,/area/lawoffice) "aTk" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/wood,/area/lawoffice) "aTl" = (/obj/structure/closet/lawcloset,/obj/machinery/light_switch{pixel_x = 0; pixel_y = -28},/turf/simulated/floor/wood,/area/lawoffice) @@ -2395,7 +2395,7 @@ "aUc" = (/obj/structure/plasticflaps{opacity = 1},/obj/machinery/navbeacon{codes_txt = "delivery;dir=4"; freq = 1400; location = "Tool Storage"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/storage/primary) "aUd" = (/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/storage/primary) "aUe" = (/obj/structure/table,/obj/item/weapon/weldingtool,/obj/item/weapon/crowbar,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 2; icon_state = "browncorner"},/area/storage/primary) -"aUf" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "browncorner"},/area/storage/primary) +"aUf" = (/obj/structure/table/woodentable,/obj/item/weapon/book/manual/security_space_law,/obj/item/weapon/book/manual/security_space_law,/obj/machinery/computer/security/telescreen{desc = "Used for watching Prison Wing holding areas."; name = "Prison Monitor"; network = list("Prison"); pixel_x = 0; pixel_y = 30},/obj/item/weapon/cartridge/lawyer,/obj/item/weapon/pen/multi,/turf/simulated/floor/wood,/area/lawoffice) "aUg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel,/area/storage/primary) "aUh" = (/obj/structure/table,/obj/item/weapon/wirecutters,/obj/item/device/flashlight{pixel_x = 1; pixel_y = 5},/obj/machinery/requests_console{department = "Tool Storage"; departmentType = 0; pixel_x = 30; pixel_y = 0},/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/camera{c_tag = "Tool Storage"; dir = 8; network = list("SS13")},/turf/simulated/floor/plasteel{dir = 4; icon_state = "brown"},/area/storage/primary) "aUi" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/obj/structure/cable/yellow,/turf/simulated/floor/plating,/area/turret_protected/ai_upload) @@ -2460,7 +2460,7 @@ "aVp" = (/obj/structure/table,/obj/item/weapon/clipboard,/obj/item/weapon/stamp/qm{pixel_x = 0; pixel_y = 0},/obj/machinery/status_display{density = 0; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plasteel,/area/quartermaster/qm) "aVq" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/mob/living/simple_animal/mouse,/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"}) "aVr" = (/obj/structure/closet/crate{icon_state = "crateopen"; opened = 1},/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/storage/primary) -"aVs" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 4; icon_state = "browncorner"},/area/storage/primary) +"aVs" = (/obj/structure/table/woodentable,/obj/machinery/photocopier/faxmachine{department = "Magistrate's Office"},/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 1},/area/crew_quarters/courtroom) "aVt" = (/obj/structure/table,/obj/item/weapon/folder/yellow,/obj/item/weapon/folder/yellow,/obj/item/weapon/storage/firstaid/regular,/turf/simulated/floor/plasteel{dir = 1; icon_state = "browncorner"},/area/storage/primary) "aVu" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel,/area/storage/primary) "aVv" = (/obj/structure/table,/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 27},/obj/item/clothing/gloves/color/yellow,/obj/item/device/t_scanner,/turf/simulated/floor/plasteel{dir = 4; icon_state = "brown"},/area/storage/primary) @@ -2638,7 +2638,7 @@ "aYL" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/airlock{name = "Locker Room"; req_access_txt = "0"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/crew_quarters/locker) "aYM" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/power/apc{dir = 2; name = "Locker Room APC"; pixel_x = -1; pixel_y = -26},/obj/structure/cable/yellow,/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/crew_quarters/locker) "aYN" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/item/device/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = 0; pixel_y = -26},/obj/machinery/camera{c_tag = "Locker Room Port"; dir = 1; network = list("SS13")},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/crew_quarters/locker) -"aYO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/light,/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/crew_quarters/locker) +"aYO" = (/obj/structure/table,/obj/item/clothing/gloves/color/fyellow,/obj/item/device/gps{gpstag = "AUX0"},/obj/item/weapon/storage/toolbox/electrical{pixel_x = 1; pixel_y = -1},/turf/simulated/floor/plasteel{dir = 9; icon_state = "brown"},/area/storage/primary) "aYP" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/crew_quarters/locker) "aYQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/light,/obj/machinery/newscaster{pixel_x = 0; pixel_y = -32},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/crew_quarters/locker) "aYR" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/crew_quarters/locker) @@ -2694,7 +2694,7 @@ "aZP" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Fore Primary Hallway"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "redcorner"},/area/hallway/primary/fore) "aZQ" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Fore Primary Hallway"},/turf/simulated/floor/plasteel,/area/hallway/primary/fore) "aZR" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Fore Primary Hallway"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/hallway/primary/fore) -"aZS" = (/obj/structure/sign/directions/security{desc = "A direction sign, pointing out which way the security department is."; dir = 1; icon_state = "direction_sec"; pixel_x = 0; pixel_y = 8; tag = "icon-direction_sec (NORTH)"},/turf/simulated/wall,/area/crew_quarters/courtroom) +"aZS" = (/obj/structure/sign/directions/security{dir = 1; pixel_y = 8},/turf/simulated/wall,/area/crew_quarters/courtroom) "aZT" = (/obj/machinery/power/apc{cell_type = 2500; dir = 2; name = "Courtroom APC"; pixel_x = 1; pixel_y = -24},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/obj/structure/table,/obj/item/weapon/storage/fancy/donut_box,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/courtroom) "aZU" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/courtroom) "aZV" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/courtroom) @@ -2937,7 +2937,7 @@ "bey" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "neutralcorner"},/area/hallway/primary/central) "bez" = (/turf/simulated/wall,/area/storage/tools) "beA" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/storage/tools) -"beB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/airlock/maintenance{name = "Storage Room"; req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/starboard) +"beB" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/vending/cart,/turf/simulated/floor/plasteel{dir = 5; icon_state = "brown"},/area/storage/primary) "beC" = (/turf/simulated/wall/r_wall,/area/storage/tech) "beD" = (/obj/machinery/power/apc{dir = 8; name = "Tech Storage APC"; pixel_x = -27; pixel_y = 0},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plasteel{tag = "icon-vault (WEST)"; icon_state = "vault"; dir = 8},/area/storage/tech) "beE" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{tag = "icon-vault (WEST)"; icon_state = "vault"; dir = 8},/area/storage/tech) @@ -2947,7 +2947,7 @@ "beI" = (/obj/machinery/door_control{desc = "A remote control-switch for the engineering security doors."; id = "Engineering"; name = "Engineering Lockdown"; pixel_x = -24; pixel_y = -5; req_access_txt = "10"},/obj/machinery/door_control{id = "atmos"; name = "Atmospherics Lockdown"; pixel_x = -24; pixel_y = 5; req_access_txt = "24"},/obj/machinery/light{dir = 8},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/engine/chiefs_office) "beJ" = (/obj/structure/table/reinforced,/obj/item/device/flashlight/lamp,/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/engine/chiefs_office) "beK" = (/obj/structure/table/reinforced,/obj/item/weapon/folder/yellow,/obj/item/weapon/stamp/ce,/obj/item/weapon/reagent_containers/pill/patch/silver_sulf,/turf/simulated/floor/plasteel{icon_state = "neutral"},/area/engine/chiefs_office) -"beL" = (/obj/structure/table/reinforced,/obj/item/weapon/clipboard,/obj/item/weapon/paper/monitorkey,/turf/simulated/floor/plasteel{icon_state = "neutral"},/area/engine/chiefs_office) +"beL" = (/obj/structure/table/woodentable,/obj/item/weapon/folder/red,/obj/item/weapon/folder/red,/obj/item/weapon/folder/red,/obj/item/device/taperecorder{pixel_y = 0},/obj/item/clothing/glasses/sunglasses/big,/turf/simulated/floor/wood,/area/lawoffice) "beM" = (/obj/structure/table/reinforced,/obj/machinery/cell_charger,/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/engine/chiefs_office) "beN" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/engine/chiefs_office) "beO" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/shower{tag = "icon-shower (EAST)"; icon_state = "shower"; dir = 4},/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 9; icon_state = "warning"},/area/engine/engineering) @@ -3024,7 +3024,7 @@ "bgh" = (/obj/structure/closet/toolcloset,/obj/item/device/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = 0; pixel_y = 28},/turf/simulated/floor/plasteel{dir = 1; icon_state = "yellow"},/area/storage/tools) "bgi" = (/obj/structure/closet/toolcloset,/turf/simulated/floor/plasteel{dir = 5; icon_state = "yellow"},/area/storage/tools) "bgj" = (/obj/effect/decal/cleanable/cobweb,/obj/machinery/atmospherics/unary/portables_connector{dir = 4},/turf/simulated/floor/plating,/area/maintenance/starboard) -"bgk" = (/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/obj/item/weapon/cigbutt,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/starboard) +"bgk" = (/obj/machinery/camera/autoname{dir = 4; network = list("SS13")},/obj/machinery/vending/artvend,/turf/simulated/floor/plasteel{dir = 8; icon_state = "brown"},/area/storage/primary) "bgl" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating{tag = "icon-platingdmg1"; icon_state = "platingdmg1"},/area/maintenance/starboard) "bgm" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/circuitboard/borgupload{pixel_x = -1; pixel_y = 1},/obj/item/weapon/circuitboard/aiupload{pixel_x = 2; pixel_y = -2},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 4},/area/storage/tech) "bgn" = (/obj/machinery/camera{c_tag = "Secure Tech Storage"; dir = 8},/obj/item/device/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29},/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/storage/tech) @@ -3038,7 +3038,7 @@ "bgv" = (/obj/item/weapon/cartridge/engineering{pixel_x = 4; pixel_y = 5},/obj/item/weapon/cartridge/engineering{pixel_x = -3; pixel_y = 2},/obj/item/weapon/cartridge/engineering{pixel_x = 3},/obj/structure/table/reinforced,/obj/item/weapon/cartridge/atmos,/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 4},/area/engine/chiefs_office) "bgw" = (/obj/effect/landmark/start{name = "Chief Engineer"},/obj/structure/stool/bed/chair/office/light{dir = 1; pixel_y = 3},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/engine/chiefs_office) "bgx" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/engine/chiefs_office) -"bgy" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 8},/area/engine/chiefs_office) +"bgy" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/plasteel{dir = 4; icon_state = "brown"},/area/storage/primary) "bgz" = (/obj/machinery/computer/security/telescreen{desc = "Used for monitoring the singularity engine safely."; dir = 8; name = "Singularity Monitor"; network = list("Singulo"); pixel_x = 29; pixel_y = 0},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/engine/chiefs_office) "bgA" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plasteel{dir = 10; icon_state = "warning"},/area/engine/engineering) "bgB" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11},/turf/simulated/floor/plasteel{icon_state = "warning"},/area/engine/engineering) @@ -3171,7 +3171,7 @@ "biY" = (/obj/structure/reagent_dispensers/watertank,/obj/machinery/light_switch{pixel_x = 8; pixel_y = 30},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/janitor) "biZ" = (/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/janitor) "bja" = (/obj/structure/closet/l3closet/janitor,/obj/machinery/alarm{pixel_y = 28},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/janitor) -"bjb" = (/obj/structure/closet/jcloset,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/janitor) +"bjb" = (/obj/structure/table/woodentable,/obj/item/weapon/book/manual/security_space_law,/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 6},/area/crew_quarters/courtroom) "bjc" = (/obj/structure/closet/firecloset,/turf/simulated/floor/plating,/area/maintenance/maintcentral{name = "Central Maintenance"}) "bjd" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/maintcentral{name = "Central Maintenance"}) "bje" = (/turf/simulated/wall/r_wall,/area/maintenance/maintcentral{name = "Central Maintenance"}) @@ -3273,7 +3273,7 @@ "bkW" = (/turf/simulated/wall/r_wall,/area/bridge) "bkX" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/obj/machinery/door/poddoor/preopen{id_tag = "bridge blast"; layer = 2.9; name = "bridge blast door"},/turf/simulated/floor/plating,/area/bridge) "bkY" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/obj/machinery/door/poddoor/preopen{id_tag = "bridge blast"; layer = 2.9; name = "bridge blast door"},/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/bridge) -"bkZ" = (/obj/structure/table/woodentable,/obj/machinery/newscaster/security_unit{pixel_x = -30; pixel_y = 1},/turf/simulated/floor/carpet,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) +"bkZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/table/woodentable,/obj/machinery/photocopier/faxmachine{department = "Internal Affairs Office"},/turf/simulated/floor/wood,/area/lawoffice) "bla" = (/obj/effect/landmark/start{name = "Captain"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/stool/bed/chair/comfy/brown{tag = "icon-comfychair (WEST)"; icon_state = "comfychair"; dir = 8},/turf/simulated/floor/carpet,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "blb" = (/turf/simulated/floor/carpet,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "blc" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/carpet,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) @@ -3281,7 +3281,7 @@ "ble" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/captain,/obj/effect/landmark/start{name = "Captain"},/obj/machinery/camera{c_tag = "Captain's Quarters"; dir = 8; network = list("SS13")},/turf/simulated/floor/wood,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "blf" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/hallway/primary/central) "blg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/turf/simulated/floor/plasteel{dir = 4; icon_state = "yellowcorner"},/area/hallway/primary/central) -"blh" = (/obj/structure/sign/directions/engineering{desc = "A direction sign, pointing out which way the engineering department is."; dir = 4; icon_state = "direction_eng"; pixel_y = -8; tag = "icon-direction_eng (EAST)"},/turf/simulated/wall,/area/storage/tools) +"blh" = (/obj/structure/sign/directions/security{dir = 4; pixel_y = 8},/obj/structure/sign/directions/engineering{dir = 4},/turf/simulated/wall,/area/janitor) "bli" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/storage/tools) "blj" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{icon = 'icons/obj/doors/Doorengglass.dmi'; name = "Auxiliary Tool Storage"; req_access_txt = "12"},/turf/simulated/floor/plasteel,/area/storage/tools) "blk" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/storage/tools) @@ -3360,17 +3360,17 @@ "bmF" = (/obj/item/weapon/tank/air,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/maintcentral{name = "Central Maintenance"}) "bmG" = (/obj/effect/landmark{name = "blobstart"},/obj/machinery/power/apc{cell_type = 2500; dir = 4; name = "Central Maintenance APC"; pixel_x = 26; pixel_y = 0},/obj/structure/cable/yellow,/turf/simulated/floor/plating,/area/maintenance/maintcentral{name = "Central Maintenance"}) "bmH" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/machinery/door/poddoor/preopen{id_tag = "bridge blast"; layer = 2.9; name = "bridge blast door"},/obj/structure/cable/yellow,/turf/simulated/floor/plating,/area/bridge) -"bmI" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/computer/card,/turf/simulated/floor/plasteel{dir = 9; icon_state = "darkgreen"},/area/bridge) -"bmJ" = (/obj/machinery/computer/med_data,/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkgreen"},/area/bridge) -"bmK" = (/obj/machinery/computer/crew,/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkgreen"},/area/bridge) -"bmL" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/item/weapon/folder/yellow{pixel_y = 4},/obj/machinery/camera{c_tag = "Bridge - Central"; dir = 2; network = list("SS13")},/obj/structure/table/glass,/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkbrown"},/area/bridge) -"bmM" = (/obj/machinery/computer/station_alert,/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkbrown"},/area/bridge) -"bmN" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/computer/monitor{name = "Bridge Power Monitoring Console"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkbrown"},/area/bridge) -"bmO" = (/obj/machinery/computer/atmos_alert,/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkbrown"},/area/bridge) -"bmP" = (/obj/machinery/ai_status_display{pixel_y = 32},/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -1; pixel_y = 4},/obj/structure/table/glass,/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkbrown"},/area/bridge) -"bmQ" = (/obj/machinery/computer/security,/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkred"; tag = "icon-darkblue"; temperature = 273.15},/area/bridge) -"bmR" = (/obj/machinery/computer/secure_data,/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkred"; tag = "icon-darkblue"; temperature = 273.15},/area/bridge) -"bmS" = (/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/computer/prisoner,/turf/simulated/floor/plasteel{dir = 5; icon_state = "darkred"; tag = "icon-darkblue"; temperature = 273.15},/area/bridge) +"bmI" = (/obj/machinery/door_control{id = "lawyer_blast"; name = "Privacy Shutters"; pixel_x = 0; pixel_y = -26},/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen/multi,/turf/simulated/floor/wood,/area/lawoffice) +"bmJ" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/item/device/assembly/signaler,/obj/item/device/multitool{pixel_x = 4},/turf/simulated/floor/plasteel{dir = 8; icon_state = "browncorner"},/area/storage/primary) +"bmK" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/item/device/assembly/signaler,/obj/item/device/multitool{pixel_x = 4},/turf/simulated/floor/plasteel{dir = 4; icon_state = "browncorner"},/area/storage/primary) +"bmL" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/light,/obj/machinery/atm{pixel_y = -32},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/crew_quarters/locker) +"bmM" = (/obj/machinery/door/airlock/maintenance{name = "Storage Room"; req_access_txt = "12"},/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/floor/plating,/area/maintenance/starboard) +"bmN" = (/obj/structure/table/reinforced,/obj/machinery/photocopier/faxmachine{department = "Chief Engineer's Office"},/turf/simulated/floor/plasteel{icon_state = "neutral"},/area/engine/chiefs_office) +"bmO" = (/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/obj/item/weapon/cigbutt,/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/starboard) +"bmP" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/obj/item/weapon/clipboard,/obj/item/weapon/paper/monitorkey,/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 8},/area/engine/chiefs_office) +"bmQ" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/reagent_dispensers/spacecleanertank{pixel_y = 30},/turf/simulated/floor/plasteel,/area/janitor) +"bmR" = (/obj/structure/table/woodentable,/obj/machinery/newscaster/security_unit{pixel_x = -30; pixel_y = 1},/obj/machinery/photocopier/faxmachine{department = "Captain's Office"},/turf/simulated/floor/carpet,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) +"bmS" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atm{pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/hallway/primary/central) "bmT" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/obj/machinery/door/poddoor/preopen{id_tag = "bridge blast"; layer = 2.9; name = "bridge blast door"},/obj/structure/cable/yellow,/turf/simulated/floor/plating,/area/bridge) "bmU" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/photo_album{pixel_y = -4},/obj/item/device/camera{pixel_y = 4},/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (Captain)"; pixel_x = -28},/turf/simulated/floor/carpet,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "bmV" = (/obj/machinery/light_switch{pixel_y = -25},/obj/structure/table/woodentable,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/item/weapon/reagent_containers/food/drinks/flask{pixel_x = 8},/obj/item/weapon/razor{pixel_x = -4; pixel_y = 2},/obj/item/clothing/mask/cigarette/cigar,/turf/simulated/floor/carpet,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) @@ -3445,7 +3445,7 @@ "bom" = (/obj/structure/table,/obj/item/weapon/clipboard,/obj/item/weapon/folder/yellow,/obj/item/device/multitool,/obj/machinery/firealarm{dir = 8; pixel_x = -26; pixel_y = 0},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "brown"},/area/quartermaster/office{name = "\improper Cargo Office"}) "bon" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/turf/simulated/floor/plasteel,/area/quartermaster/office{name = "\improper Cargo Office"}) "boo" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/obj/machinery/light_switch{pixel_x = 27; pixel_y = 0},/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plasteel{dir = 4; icon_state = "brown"},/area/quartermaster/office{name = "\improper Cargo Office"}) -"bop" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "brown"},/area/hallway/primary/port) +"bop" = (/obj/machinery/computer/med_data,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "boq" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11},/turf/simulated/floor/plasteel,/area/hallway/primary/port) "bor" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/primary/port) "bos" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel,/area/hallway/primary/port) @@ -3457,13 +3457,13 @@ "boy" = (/obj/item/weapon/storage/box/lights/mixed,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/maintcentral{name = "Central Maintenance"}) "boz" = (/obj/item/clothing/mask/gas,/turf/simulated/floor/plating,/area/maintenance/maintcentral{name = "Central Maintenance"}) "boA" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/obj/machinery/door/poddoor/preopen{id_tag = "bridge blast"; layer = 2.9; name = "bridge blast door"},/turf/simulated/floor/plating,/area/bridge) -"boB" = (/obj/item/weapon/folder/white,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/light{dir = 8},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/table/glass,/turf/simulated/floor/plasteel{dir = 8; icon_state = "darkgreen"},/area/bridge) +"boB" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/computer/card,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "boC" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "boD" = (/obj/structure/stool/bed/chair/office/dark{dir = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "boE" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "boF" = (/obj/structure/stool/bed/chair/office/dark{dir = 1},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "boG" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) -"boH" = (/obj/item/weapon/folder/red{pixel_y = 3},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/light{dir = 4},/obj/structure/table/glass,/obj/item/weapon/folder/red{pixel_y = 3},/turf/simulated/floor/plasteel{dir = 4; icon_state = "darkred"; tag = "icon-darkblue"; temperature = 273.15},/area/bridge) +"boH" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/item/weapon/folder/yellow{pixel_y = 4},/obj/machinery/camera{c_tag = "Bridge - Central"; dir = 2; network = list("SS13")},/obj/structure/table/glass,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "boI" = (/turf/simulated/wall,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "boJ" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp/green{pixel_x = 1; pixel_y = 5},/obj/structure/window/reinforced{dir = 1; pixel_y = 2},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/weapon/bikehorn/rubberducky,/obj/machinery/light_switch{pixel_x = -28; pixel_y = 0},/obj/item/weapon/card/id/captains_spare,/turf/simulated/floor/wood,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "boK" = (/obj/machinery/door/window{dir = 1; name = "Captain's Bedroom"; req_access_txt = "20"},/turf/simulated/floor/wood,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) @@ -3529,7 +3529,7 @@ "bpS" = (/turf/simulated/floor/plasteel{dir = 2; icon_state = "brown"},/area/quartermaster/office{name = "\improper Cargo Office"}) "bpT" = (/obj/structure/disposalpipe/segment,/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{dir = 2; icon_state = "brown"},/area/quartermaster/office{name = "\improper Cargo Office"}) "bpU" = (/obj/machinery/autolathe,/obj/machinery/newscaster{pixel_x = 28; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 6; icon_state = "brown"},/area/quartermaster/office{name = "\improper Cargo Office"}) -"bpV" = (/obj/structure/closet/crate{icon_state = "crateopen"; opened = 1},/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plasteel{dir = 10; icon_state = "brown"},/area/hallway/primary/port) +"bpV" = (/obj/machinery/computer/crew,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bpW" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{dir = 8; icon_state = "browncorner"},/area/hallway/primary/port) "bpX" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "browncorner"},/area/hallway/primary/port) "bpY" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/item/stack/packageWrap{pixel_x = 2; pixel_y = -3},/obj/item/stack/packageWrap{pixel_x = 2; pixel_y = -3},/obj/item/stack/packageWrap{pixel_x = 2; pixel_y = -3},/obj/item/weapon/hand_labeler,/turf/simulated/floor/plasteel{dir = 2; icon_state = "brown"},/area/hallway/primary/port) @@ -3537,15 +3537,15 @@ "bqa" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{dir = 1; icon_state = "neutralcorner"},/area/hallway/primary/central) "bqb" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/hallway/primary/central) "bqc" = (/turf/simulated/wall/r_wall,/area/crew_quarters/heads) -"bqd" = (/obj/structure/reagent_dispensers/fueltank,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/maintcentral{name = "Central Maintenance"}) +"bqd" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/computer/monitor{name = "Bridge Power Monitoring Console"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bqe" = (/obj/item/weapon/extinguisher,/turf/simulated/floor/plating,/area/maintenance/maintcentral{name = "Central Maintenance"}) -"bqf" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/filingcabinet/chestdrawer{pixel_y = 3},/obj/machinery/alarm{dir = 4; pixel_x = -23; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 9; icon_state = "darkblue"},/area/bridge) -"bqg" = (/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = 0; pixel_y = 29},/obj/machinery/computer/teleporter,/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkblue"; tag = "icon-darkbluecorners (WEST)"},/area/bridge) -"bqh" = (/obj/item/weapon/storage/firstaid/regular{pixel_x = 3; pixel_y = 3},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/table/glass,/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkgreencorners"; tag = "icon-greencorner (NORTH)"},/area/bridge) +"bqf" = (/obj/machinery/computer/station_alert,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) +"bqg" = (/obj/machinery/ai_status_display{pixel_y = 32},/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -1; pixel_y = 4},/obj/structure/table/glass,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) +"bqh" = (/obj/machinery/computer/atmos_alert,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bqi" = (/obj/item/device/radio/beacon,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) -"bqj" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/recharger{pixel_y = 3},/obj/item/weapon/restraints/handcuffs{pixel_y = 3},/obj/structure/table/glass,/turf/simulated/floor/plasteel{dir = 4; icon_state = "darkredcorners"},/area/bridge) -"bqk" = (/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/computer/security/mining,/obj/machinery/keycard_auth{pixel_x = 0; pixel_y = 24},/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkblue"; tag = "icon-darkbluecorners (WEST)"},/area/bridge) -"bql" = (/obj/machinery/requests_console{announcementConsole = 1; department = "Bridge"; departmentType = 5; name = "Bridge RC"; pixel_x = 32; pixel_y = 0},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/computer/ordercomp,/turf/simulated/floor/plasteel{dir = 5; icon_state = "darkblue"},/area/bridge) +"bqj" = (/obj/machinery/computer/secure_data,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) +"bqk" = (/obj/machinery/computer/security,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) +"bql" = (/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/computer/prisoner,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bqm" = (/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/obj/machinery/shower{tag = "icon-shower (EAST)"; icon_state = "shower"; dir = 4},/obj/machinery/door/window/westright{dir = 4},/obj/item/weapon/soap/deluxe,/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "bqn" = (/obj/structure/mirror{pixel_y = 28},/obj/structure/sink{pixel_y = 17},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "bqo" = (/obj/structure/toilet{pixel_y = 13},/obj/machinery/light{dir = 2; icon_state = "tube1"},/obj/effect/landmark/start{name = "Captain"},/obj/machinery/light_switch{pixel_y = -25},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) @@ -3625,28 +3625,28 @@ "brK" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/quartermaster/office{name = "\improper Cargo Office"}) "brL" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 8; icon_state = "brown"},/area/hallway/primary/port) "brM" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{dir = 4; icon_state = "brown"},/area/hallway/primary/port) -"brN" = (/obj/structure/sign/directions/security{desc = "A direction sign, pointing out which way the security department is."; dir = 1; icon_state = "direction_sec"; pixel_x = 0; pixel_y = 8; tag = "icon-direction_sec (NORTH)"},/obj/structure/sign/directions/engineering{desc = "A direction sign, pointing out which way the engineering department is."; dir = 4; icon_state = "direction_eng"; pixel_y = 0; tag = "icon-direction_eng (EAST)"},/turf/simulated/wall/r_wall,/area/hallway/primary/port) +"brN" = (/obj/structure/sign/directions/engineering{dir = 4},/obj/structure/sign/directions/security{dir = 8; pixel_y = 8},/turf/simulated/wall/r_wall,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "brO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/light{dir = 4},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/hallway/primary/central) "brP" = (/obj/item/device/flashlight/lamp/green{pixel_x = 1; pixel_y = 5},/obj/machinery/door_control{id = "hop"; name = "Privacy Shutters Control"; pixel_x = 0; pixel_y = 25; req_access_txt = "28"},/obj/structure/table/woodentable,/turf/simulated/floor/wood,/area/crew_quarters/heads) -"brQ" = (/obj/machinery/requests_console{announcementConsole = 1; department = "Head of Personnel's Desk"; departmentType = 5; name = "Head of Personnel RC"; pixel_y = 30},/obj/machinery/light{dir = 1},/obj/item/weapon/storage/secure/briefcase,/obj/structure/table/woodentable,/turf/simulated/floor/wood,/area/crew_quarters/heads) +"brQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/wall/r_wall,/area/turret_protected/ai) "brR" = (/obj/machinery/recharger,/obj/machinery/keycard_auth{pixel_x = 0; pixel_y = 24},/obj/item/weapon/storage/secure/safe{pixel_x = 34; pixel_y = 0},/obj/item/device/flash,/obj/structure/table/woodentable,/turf/simulated/floor/wood,/area/crew_quarters/heads) "brS" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/maintenance/maintcentral{name = "Central Maintenance"}) "brT" = (/obj/machinery/atmospherics/unary/portables_connector{dir = 1},/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating,/area/maintenance/maintcentral{name = "Central Maintenance"}) "brU" = (/obj/item/device/radio/off,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/maintenance/maintcentral{name = "Central Maintenance"}) "brV" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=4"; freq = 1400; location = "Bridge"},/obj/structure/plasticflaps{opacity = 1},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/maintenance/maintcentral{name = "Central Maintenance"}) "brW" = (/obj/machinery/door/window/westleft{dir = 4; name = "Bridge Deliveries"; req_access_txt = "19"},/obj/machinery/door/poddoor/preopen{id_tag = "bridge blast"; name = "bridge blast door"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/bridge) -"brX" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "darkblue"; tag = "icon-darkbluecorners (WEST)"},/area/bridge) +"brX" = (/obj/structure/closet/crate{icon_state = "crateopen"; opened = 1},/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plasteel{dir = 8; icon_state = "brown"},/area/hallway/primary/port) "brY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "brZ" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bsa" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) -"bsb" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{tag = "icon-darkbluecorners"; icon_state = "darkbluecorners"; temperature = 273.15},/area/bridge) -"bsc" = (/obj/structure/window/reinforced,/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "darkblue"; tag = "icon-darkbluecorners (WEST)"},/area/bridge) -"bsd" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/window/brigdoor{dir = 2; name = "Command Desk"; req_access_txt = "19"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "darkblue"; tag = "icon-darkbluecorners (WEST)"},/area/bridge) -"bse" = (/obj/structure/window/reinforced,/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "darkblue"; tag = "icon-darkbluecorners (WEST)"},/area/bridge) -"bsf" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "darkbluecorners"; tag = "icon-darkbluecorners"; temperature = 273.15},/area/bridge) +"bsb" = (/obj/item/weapon/folder/white,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/light{dir = 8},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/table/glass,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) +"bsc" = (/obj/item/weapon/folder/red{pixel_y = 3},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/light{dir = 4},/obj/structure/table/glass,/obj/item/weapon/folder/red{pixel_y = 3},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) +"bsd" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 1},/turf/simulated/wall/r_wall,/area/construction/hallway{name = "\improper MiniSat Exterior"}) +"bse" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 5; icon_state = "intact"},/turf/simulated/wall/r_wall,/area/construction/hallway{name = "\improper MiniSat Exterior"}) +"bsf" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 10; initialize_directions = 10},/turf/simulated/wall/r_wall,/area/construction/hallway{name = "\improper MiniSat Exterior"}) "bsg" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bsh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) -"bsi" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/structure/stool/bed/chair/office/dark{dir = 1},/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/obj/machinery/camera{c_tag = "Bridge - Starboard"; dir = 8; network = list("SS13")},/turf/simulated/floor/plasteel{dir = 4; icon_state = "darkblue"; tag = "icon-darkbluecorners (WEST)"},/area/bridge) +"bsi" = (/obj/machinery/computer/merch,/turf/simulated/floor/plasteel{dir = 10; icon_state = "brown"},/area/hallway/primary/port) "bsj" = (/obj/machinery/door/airlock/command{name = "Captain's Quarters"; req_access = null; req_access_txt = "20"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment,/turf/simulated/floor/carpet,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "bsk" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/hallway/primary/central) "bsl" = (/obj/machinery/light{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/central) @@ -3731,21 +3731,21 @@ "btM" = (/obj/item/weapon/folder/blue,/obj/item/weapon/stamp/hop,/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/table/woodentable,/turf/simulated/floor/wood,/area/crew_quarters/heads) "btN" = (/obj/effect/landmark/start{name = "Head of Personnel"},/obj/structure/stool/bed/chair/office/dark{dir = 8},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/wood,/area/crew_quarters/heads) "btO" = (/obj/machinery/newscaster/security_unit{pixel_x = 32; pixel_y = 0},/obj/item/weapon/storage/box/PDAs{pixel_x = 4; pixel_y = 4},/obj/structure/table/woodentable,/obj/item/weapon/storage/box/ids,/obj/item/weapon/storage/box/ids,/turf/simulated/floor/wood,/area/crew_quarters/heads) -"btP" = (/obj/machinery/power/apc{cell_type = 10000; dir = 8; name = "Bridge APC"; pixel_x = -27; pixel_y = 0},/obj/structure/cable/yellow,/obj/machinery/camera{c_tag = "Bridge - Port"; dir = 4; network = list("SS13")},/turf/simulated/floor/plasteel{dir = 8; icon_state = "darkblue"; tag = "icon-darkbluecorners (WEST)"},/area/bridge) +"btP" = (/obj/structure/reagent_dispensers/fueltank,/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/floor/plating,/area/maintenance/maintcentral{name = "Central Maintenance"}) "btQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) -"btR" = (/turf/simulated/floor/plasteel{tag = "icon-darkbluecorners"; icon_state = "darkbluecorners"; temperature = 273.15},/area/bridge) -"btS" = (/turf/simulated/floor/plasteel{dir = 2; icon_state = "darkblue"; tag = "icon-darkbluecorners (WEST)"},/area/bridge) -"btT" = (/turf/simulated/floor/plasteel{dir = 6; icon_state = "darkblue"},/area/bridge) +"btR" = (/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = 0; pixel_y = 29},/obj/machinery/computer/teleporter,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) +"btS" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/filingcabinet/chestdrawer{pixel_y = 3},/obj/machinery/alarm{dir = 4; pixel_x = -23; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) +"btT" = (/obj/item/weapon/storage/firstaid/regular{pixel_x = 3; pixel_y = 3},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/table/glass,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "btU" = (/obj/structure/window/reinforced{dir = 8},/obj/machinery/recharger,/obj/item/weapon/restraints/handcuffs,/obj/structure/table/glass,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "btV" = (/obj/machinery/computer/communications,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "btW" = (/obj/machinery/computer/security/wooden_tv{pixel_x = 1; pixel_y = 6},/obj/structure/table/glass,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "btX" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/table/glass,/obj/item/weapon/folder/blue{pixel_y = 2},/obj/item/weapon/folder/blue{pixel_y = 2},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) -"btY" = (/turf/simulated/floor/plasteel{dir = 10; icon_state = "darkblue"},/area/bridge) -"btZ" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "darkbluecorners"; tag = "icon-darkbluecorners"; temperature = 273.15},/area/bridge) +"btY" = (/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/computer/security/mining,/obj/machinery/keycard_auth{pixel_x = 0; pixel_y = 24},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) +"btZ" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/recharger{pixel_y = 3},/obj/item/weapon/restraints/handcuffs{pixel_y = 3},/obj/structure/table/glass,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bua" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) -"bub" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 4; icon_state = "darkblue"; tag = "icon-darkbluecorners (WEST)"},/area/bridge) +"bub" = (/obj/machinery/requests_console{announcementConsole = 1; department = "Bridge"; departmentType = 5; name = "Bridge RC"; pixel_x = 32; pixel_y = 0},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/computer/ordercomp,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "buc" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/item/weapon/storage/fancy/donut_box,/obj/structure/table/glass,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) -"bud" = (/obj/structure/displaycase{pixel_y = 5},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/wood,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) +"bud" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/wall/r_wall,/area/construction/hallway{name = "\improper MiniSat Exterior"}) "bue" = (/obj/structure/sign/double/map/left{desc = "A framed picture of the station. Clockwise from security at the top (red), you see engineering (yellow), science (purple), escape (red and white), medbay (green), arrivals (blue and white), and finally cargo (brown)."; icon_state = "map-left-MS"; pixel_y = 32},/turf/simulated/floor/wood,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "buf" = (/obj/structure/sign/double/map/right{desc = "A framed picture of the station. Clockwise from security at the top (red), you see engineering (yellow), science (purple), escape (red and white), medbay (green), arrivals (blue and white), and finally cargo (brown)."; icon_state = "map-right-MS"; pixel_y = 32},/turf/simulated/floor/wood,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "bug" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment,/turf/simulated/floor/wood,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) @@ -3754,12 +3754,12 @@ "buj" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/obj/machinery/camera{c_tag = "Central Primary Hallway - Starboard - Art Storage"; dir = 4; network = list("SS13")},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/hallway/primary/central) "buk" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor/plasteel{dir = 4; icon_state = "neutralcorner"},/area/hallway/primary/central) "bul" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/effect/spawner/window{useFull = 1; tag = "fullWin"},/turf/simulated/floor/plating,/area/civilian/barber) -"bum" = (/obj/machinery/door/airlock{icon = 'icons/obj/doors/doorint.dmi'; name = "Starboard Emergency Storage"; req_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/starboard) +"bum" = (/obj/machinery/requests_console{announcementConsole = 1; department = "Head of Personnel's Desk"; departmentType = 5; name = "Head of Personnel RC"; pixel_y = 30},/obj/machinery/light{dir = 1},/obj/item/weapon/storage/secure/briefcase,/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = -2; pixel_y = 4},/obj/item/weapon/pen,/turf/simulated/floor/wood,/area/crew_quarters/heads) "bun" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "barber"},/area/civilian/barber) "buo" = (/obj/machinery/light_switch{pixel_x = 27},/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plasteel{dir = 8; icon_state = "barber"},/area/civilian/barber) "bup" = (/obj/structure/closet/secure_closet/bar{req_access_txt = "25"},/turf/simulated/floor/wood,/area/crew_quarters/bar) "buq" = (/obj/machinery/reagentgrinder,/obj/structure/table/woodentable,/turf/simulated/floor/wood,/area/crew_quarters/bar) -"bur" = (/obj/structure/table/woodentable,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/weapon/gun/projectile/revolver/doublebarrel,/obj/machinery/camera{c_tag = "Maltese Falcon - Backroom"; dir = 2; network = list("SS13")},/turf/simulated/floor/wood,/area/crew_quarters/bar) +"bur" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bus" = (/obj/structure/sink/kitchen{pixel_y = 28},/turf/simulated/floor/wood,/area/crew_quarters/bar) "but" = (/obj/machinery/door/window/southleft{base_state = "left"; dir = 2; icon_state = "left"; name = "Bar Delivery"; req_access_txt = "25"},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/crew_quarters/bar) "buu" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=1"; freq = 1400; location = "Bar"},/obj/structure/plasticflaps{opacity = 1},/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/crew_quarters/bar) @@ -3842,7 +3842,7 @@ "bvT" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel,/area/hallway/primary/central) "bvU" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1; scrub_Toxins = 0},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel,/area/hallway/primary/central) "bvV" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/hallway/primary/central) -"bvW" = (/obj/item/weapon/paper_bin{pixel_x = -2; pixel_y = 4},/obj/item/weapon/pen,/obj/structure/window/reinforced,/obj/structure/table/woodentable,/turf/simulated/floor/wood,/area/crew_quarters/heads) +"bvW" = (/obj/structure/window/reinforced,/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bvX" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/window{dir = 2; name = "HoP's Desk"; pixel_y = 0; req_access_txt = "57"},/turf/simulated/floor/wood,/area/crew_quarters/heads) "bvY" = (/obj/structure/filingcabinet/chestdrawer{pixel_y = 6},/obj/structure/window/reinforced,/turf/simulated/floor/wood,/area/crew_quarters/heads) "bvZ" = (/obj/machinery/vending/cart{req_access_txt = "57"},/turf/simulated/floor/wood,/area/crew_quarters/heads) @@ -3850,18 +3850,18 @@ "bwb" = (/obj/machinery/computer/ordercomp,/obj/machinery/computer/security/telescreen{desc = "Used for watching Prison Wing holding areas."; name = "Prison Monitor"; network = list("Prison"); pixel_x = 0; pixel_y = 30},/turf/simulated/floor/wood,/area/crew_quarters/heads) "bwc" = (/obj/structure/closet/secure_closet/hop,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/computer/security/telescreen/entertainment{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/wood,/area/crew_quarters/heads) "bwd" = (/turf/simulated/wall,/area/crew_quarters/heads) -"bwe" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 2; icon_state = "darkblue"; tag = "icon-darkbluecorners (WEST)"},/area/bridge) -"bwf" = (/obj/machinery/light,/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/structure/rack,/obj/item/weapon/storage/secure/briefcase,/obj/item/clothing/mask/cigarette/cigar,/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkblue"; tag = "icon-darkbluecorners (WEST)"},/area/bridge) -"bwg" = (/obj/structure/rack,/obj/item/device/aicard,/obj/item/device/radio/off,/obj/machinery/computer/security/telescreen{dir = 1; name = "MiniSat Monitor"; network = list("MiniSat","tcomm"); pixel_x = 0; pixel_y = -29},/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkblue"; tag = "icon-darkbluecorners (WEST)"},/area/bridge) +"bwe" = (/obj/structure/window/reinforced,/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) +"bwf" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/window/brigdoor{dir = 2; name = "Command Desk"; req_access_txt = "19"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) +"bwg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/structure/stool/bed/chair/office/dark{dir = 1},/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/obj/machinery/camera{c_tag = "Bridge - Starboard"; dir = 8; network = list("SS13")},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bwh" = (/obj/structure/window/reinforced{dir = 8},/obj/machinery/cell_charger{pixel_y = 4},/obj/structure/table/glass,/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bwi" = (/turf/simulated/floor/carpet,/area/bridge) "bwj" = (/obj/structure/stool/bed/chair/comfy/black{dir = 1},/turf/simulated/floor/carpet,/area/bridge) "bwk" = (/obj/structure/window/reinforced{dir = 4},/obj/item/weapon/paper_bin{pixel_x = -2; pixel_y = 8},/obj/structure/table/glass,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) -"bwl" = (/obj/item/device/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = 0; pixel_y = -29},/obj/structure/rack,/obj/item/device/assembly/signaler,/obj/item/device/assembly/signaler,/obj/item/device/assembly/timer,/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkblue"; tag = "icon-darkbluecorners (WEST)"},/area/bridge) -"bwm" = (/obj/machinery/light,/obj/structure/rack,/obj/item/weapon/storage/toolbox/emergency,/obj/item/weapon/storage/toolbox/emergency{pixel_x = -2; pixel_y = -3},/obj/item/weapon/wrench,/obj/item/device/multitool,/obj/machinery/newscaster{pixel_x = 0; pixel_y = -30},/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkblue"; tag = "icon-darkbluecorners (WEST)"},/area/bridge) -"bwn" = (/obj/machinery/light_switch{pixel_x = 8; pixel_y = -26},/turf/simulated/floor/plasteel{dir = 10; icon_state = "darkblue"},/area/bridge) -"bwo" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "darkblue"; tag = "icon-darkbluecorners (WEST)"},/area/bridge) -"bwp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 6; icon_state = "darkblue"},/area/bridge) +"bwl" = (/obj/structure/sign/directions/engineering{dir = 4},/obj/structure/sign/directions/security{dir = 1; pixel_y = 8},/turf/simulated/wall,/area/storage/tools) +"bwm" = (/obj/machinery/power/apc{cell_type = 10000; dir = 8; name = "Bridge APC"; pixel_x = -27; pixel_y = 0},/obj/structure/cable/yellow,/obj/machinery/camera{c_tag = "Bridge - Port"; dir = 4; network = list("SS13")},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) +"bwn" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) +"bwo" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/structure/displaycase/captains_laser,/turf/simulated/floor/wood,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) +"bwp" = (/obj/structure/table/woodentable,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/weapon/gun/projectile/revolver/doublebarrel,/obj/machinery/camera{c_tag = "Maltese Falcon - Backroom"; dir = 2; network = list("SS13")},/obj/item/device/eftpos,/turf/simulated/floor/wood,/area/crew_quarters/bar) "bwq" = (/obj/structure/closet/fireaxecabinet{pixel_y = -32},/obj/item/weapon/paper_bin{pixel_x = -2; pixel_y = 7},/obj/item/weapon/pen{pixel_y = 3},/obj/machinery/light_switch{pixel_x = 28; pixel_y = 0},/obj/structure/table/glass,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bwr" = (/obj/structure/table/woodentable,/obj/item/weapon/book/manual/security_space_law,/obj/machinery/power/apc{dir = 8; name = "Captain's Quarters APC"; pixel_x = -24; pixel_y = 0},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/obj/machinery/light/small{dir = 8},/obj/item/weapon/paper{info = "Congratulations,

Your station has been selected to carry out the Gateway Project.

The equipment will be shipped to you at the start of the next quarter.
You are to prepare a secure location to house the equipment as outlined in the attached documents.

--Nanotrasen Blue Space Research"; name = "Confidential Correspondence, Pg 1"; pixel_x = 0; pixel_y = 0},/obj/item/weapon/coin/plasma,/obj/item/weapon/melee/chainofcommand,/turf/simulated/floor/wood,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "bws" = (/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/wood,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) @@ -3964,16 +3964,16 @@ "byl" = (/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/obj/machinery/power/apc{dir = 1; name = "Head of Personnel APC"; pixel_y = 24},/obj/machinery/light{dir = 1},/turf/simulated/floor/carpet,/area/crew_quarters/heads) "bym" = (/turf/simulated/floor/carpet,/area/crew_quarters/heads) "byn" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/turf/simulated/floor/carpet,/area/crew_quarters/heads) -"byo" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_command{name = "Bridge"; req_access_txt = "19"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkblue"; tag = "icon-darkbluecorners (WEST)"},/area/bridge) -"byp" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_command{name = "Bridge"; req_access_txt = "19"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkblue"; tag = "icon-darkbluecorners (WEST)"},/area/bridge) +"byo" = (/obj/structure/window/reinforced,/obj/structure/table/woodentable,/obj/machinery/photocopier/faxmachine{department = "Head of Personnel's Office"},/turf/simulated/floor/wood,/area/crew_quarters/heads) +"byp" = (/obj/machinery/light,/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/structure/rack,/obj/item/weapon/storage/secure/briefcase,/obj/item/clothing/mask/cigarette/cigar,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "byq" = (/turf/simulated/wall,/area/bridge) "byr" = (/obj/structure/window/reinforced{dir = 8},/obj/machinery/light_switch{pixel_y = -25},/obj/machinery/vending/cola{pixel_x = 2},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bys" = (/obj/machinery/door_control{id = "bridge blast"; name = "Bridge Access Blast Door Control"; pixel_x = -1; pixel_y = -24; req_access_txt = "19"},/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/machinery/door_control{id = "council blast"; name = "Council Chamber Blast Door Control"; pixel_x = -1; pixel_y = -34; req_access_txt = "19"},/obj/machinery/camera{c_tag = "Bridge - Command Chair"; dir = 1; network = list("SS13")},/turf/simulated/floor/carpet,/area/bridge) "byt" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/carpet,/area/bridge) "byu" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/obj/machinery/door_control{id = "evashutter"; name = "E.V.A. Storage Shutter Control"; pixel_x = 0; pixel_y = -24; req_access_txt = "19"},/obj/machinery/door_control{id = "gateshutter"; name = "Gateway Shutter Control"; pixel_x = 0; pixel_y = -34; req_access_txt = "19"},/turf/simulated/floor/carpet,/area/bridge) "byv" = (/obj/structure/window/reinforced{dir = 4; pixel_x = 0},/obj/machinery/vending/snack{pixel_x = -2},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) -"byw" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_command{name = "Bridge"; req_access_txt = "19"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkblue"; tag = "icon-darkbluecorners (WEST)"},/area/bridge) -"byx" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_command{name = "Bridge"; req_access_txt = "19"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkblue"; tag = "icon-darkbluecorners (WEST)"},/area/bridge) +"byw" = (/obj/structure/rack,/obj/item/device/aicard,/obj/item/device/radio/off,/obj/machinery/computer/security/telescreen{dir = 1; name = "MiniSat Monitor"; network = list("MiniSat","tcomm"); pixel_x = 0; pixel_y = -29},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) +"byx" = (/obj/machinery/light,/obj/structure/rack,/obj/item/weapon/storage/toolbox/emergency,/obj/item/weapon/storage/toolbox/emergency{pixel_x = -2; pixel_y = -3},/obj/item/weapon/wrench,/obj/item/device/multitool,/obj/machinery/newscaster{pixel_x = 0; pixel_y = -30},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "byy" = (/obj/structure/table/woodentable,/obj/structure/window/reinforced,/obj/machinery/light_switch{pixel_x = -28; pixel_y = 0},/obj/item/weapon/storage/secure/briefcase{pixel_x = -2; pixel_y = 4},/obj/item/weapon/storage/lockbox/medal{pixel_y = 0},/turf/simulated/floor/wood,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "byz" = (/obj/machinery/door/window{dir = 2; name = "Captain's Desk"; req_access_txt = "20"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/wood,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "byA" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/obj/structure/window/reinforced,/turf/simulated/floor/wood,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) @@ -3985,14 +3985,14 @@ "byG" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plasteel,/area/hallway/primary/central) "byH" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "barber"},/area/civilian/barber) "byI" = (/obj/structure/stool/bed/chair/barber{dir = 4},/turf/simulated/floor/plasteel{dir = 8; icon_state = "barber"},/area/civilian/barber) -"byJ" = (/obj/structure/table/reinforced,/obj/structure/mirror{dir = 4; pixel_x = 28; pixel_y = 0},/obj/item/weapon/razor,/turf/simulated/floor/plasteel{dir = 8; icon_state = "barber"},/area/civilian/barber) +"byJ" = (/obj/item/device/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = 0; pixel_y = -29},/obj/structure/rack,/obj/item/device/assembly/signaler,/obj/item/device/assembly/signaler,/obj/item/device/assembly/timer,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "byK" = (/obj/structure/reagent_dispensers/beerkeg,/turf/simulated/floor/wood,/area/crew_quarters/bar) "byL" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/floor/wood,/area/crew_quarters/bar) "byM" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/wood,/area/crew_quarters/bar) "byN" = (/obj/structure/closet/gmcloset{desc = "It's a storage unit."; icon_state = "black"; name = "spare gear"},/obj/item/weapon/wrench,/turf/simulated/floor/wood,/area/crew_quarters/bar) "byO" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/starboard) "byP" = (/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor/plating{tag = "icon-platingdmg2"; icon_state = "platingdmg2"},/area/maintenance/starboard) -"byQ" = (/obj/item/weapon/storage/toolbox/emergency,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/starboard) +"byQ" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "byR" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/item/weapon/cigbutt,/turf/simulated/floor/plating,/area/maintenance/starboard) "byS" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/turf/simulated/floor/plating{tag = "icon-platingdmg3"; icon_state = "platingdmg3"},/area/maintenance/starboard) "byT" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 8; icon_state = "caution"},/area/hallway/primary/starboard) @@ -4042,7 +4042,7 @@ "bzL" = (/obj/effect/spawner/window{useFull = 1; tag = "fullWin"},/turf/simulated/floor/plating,/area/library) "bzM" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Library"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "carpetsymbol"},/area/library) "bzN" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Library"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "carpetsymbol"},/area/library) -"bzO" = (/obj/structure/sign/directions/engineering{desc = "A direction sign, pointing out which way the escape arm is."; icon_state = "direction_evac"; name = "escape arm"; tag = "icon-direction_evac"},/obj/structure/sign/directions/engineering{desc = "A direction sign, pointing out which way the medical department is."; icon_state = "direction_med"; name = "medical department"; pixel_y = 8; tag = "icon-direction_med"},/obj/structure/sign/directions/engineering{desc = "A direction sign, pointing out which way the research department is."; icon_state = "direction_sci"; name = "research department"; pixel_y = -8; tag = "icon-direction_sci"},/turf/simulated/wall,/area/library) +"bzO" = (/obj/structure/sign/directions/engineering{dir = 4},/obj/structure/sign/directions/security{dir = 1; pixel_y = 8},/turf/simulated/wall/r_wall,/area/hallway/primary/port) "bzP" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/hallway/primary/central) "bzQ" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/sortjunction{dir = 1; icon_state = "pipe-j1s"; sortType = 15},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plasteel,/area/hallway/primary/central) "bzR" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/hallway/primary/central) @@ -4055,15 +4055,15 @@ "bzY" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/carpet,/area/crew_quarters/heads) "bzZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/carpet,/area/crew_quarters/heads) "bAa" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/command{name = "Head of Personnel"; req_access = null; req_access_txt = "57"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/heads) -"bAb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plasteel{tag = "icon-darkbluecorners"; icon_state = "darkbluecorners"; temperature = 273.15},/area/bridge) +"bAb" = (/obj/machinery/light_switch{pixel_x = 8; pixel_y = -26},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bAc" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bAd" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/bridge) -"bAe" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/bookcase,/turf/simulated/floor/wood,/area/bridge) +"bAe" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_command{name = "Bridge"; req_access_txt = "19"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bAf" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/wall,/area/bridge) "bAg" = (/obj/machinery/door/airlock/command{name = "Command Desk"; req_access = null; req_access_txt = "19"},/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/bridge) "bAh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/bridge) "bAi" = (/obj/structure/bookcase,/turf/simulated/floor/wood,/area/bridge) -"bAj" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -26; pixel_y = 0},/turf/simulated/floor/plasteel{tag = "icon-darkbluecorners"; icon_state = "darkbluecorners"; temperature = 273.15},/area/bridge) +"bAj" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_command{name = "Bridge"; req_access_txt = "19"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bAk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bAl" = (/obj/machinery/vending/boozeomat,/obj/machinery/light/small{dir = 8},/turf/simulated/floor/wood,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "bAm" = (/obj/machinery/hologram/holopad{pixel_x = 9; pixel_y = -9},/turf/simulated/floor/carpet{tag = "icon-carpet6-2"; icon_state = "carpet6-2"},/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) @@ -4154,22 +4154,22 @@ "bBT" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp/green{pixel_x = 1; pixel_y = 5},/obj/machinery/computer/security/telescreen/entertainment{pixel_y = 30},/turf/simulated/floor/plasteel{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/library) "bBU" = (/obj/structure/table/woodentable,/obj/machinery/newscaster{pixel_x = 0; pixel_y = 32},/obj/item/weapon/folder,/obj/item/weapon/folder,/obj/machinery/computer/security/telescreen/entertainment{pixel_x = 30; pixel_y = 0},/turf/simulated/floor/plasteel{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/library) "bBV" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor/wood,/area/crew_quarters/heads) -"bBW" = (/obj/item/weapon/hand_labeler,/obj/item/stack/packageWrap,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/table/woodentable,/turf/simulated/floor/wood,/area/crew_quarters/heads) +"bBW" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_command{name = "Bridge"; req_access_txt = "19"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bBX" = (/obj/machinery/photocopier{pixel_y = 3},/turf/simulated/floor/wood,/area/crew_quarters/heads) "bBY" = (/obj/machinery/pdapainter,/turf/simulated/floor/wood,/area/crew_quarters/heads) "bBZ" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/computer/secure_data,/turf/simulated/floor/wood,/area/crew_quarters/heads) "bCa" = (/obj/machinery/computer/card,/turf/simulated/floor/wood,/area/crew_quarters/heads) "bCb" = (/obj/structure/stool/bed/chair/office/dark,/obj/effect/landmark/start{name = "Head of Personnel"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/light_switch{pixel_x = 38; pixel_y = -4},/obj/machinery/door_control{id = "hopqueue"; name = "Queue Shutters Control"; pixel_x = 25; pixel_y = -4; req_access_txt = "28"},/obj/machinery/door_control{id = "hop"; name = "Privacy Shutters Control"; pixel_x = 25; pixel_y = 6; req_access_txt = "28"},/obj/machinery/flasher_button{id = "hopflash"; pixel_x = 38; pixel_y = 6},/turf/simulated/floor/wood,/area/crew_quarters/heads) -"bCc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{tag = "icon-darkbluecorners"; icon_state = "darkbluecorners"; temperature = 273.15},/area/bridge) -"bCd" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/camera{c_tag = "Bridge - Port Access"; dir = 8; network = list("SS13")},/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkbluecorners"; tag = "icon-darkbluecorners"; temperature = 273.15},/area/bridge) -"bCe" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp/green{pixel_x = 1; pixel_y = 5},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) -"bCf" = (/obj/structure/table/woodentable,/obj/item/weapon/book/manual/security_space_law{pixel_y = 3},/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = 0; pixel_y = 28},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) +"bCc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_command{name = "Bridge"; req_access_txt = "19"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) +"bCd" = (/obj/structure/table/reinforced,/obj/structure/mirror{dir = 4; pixel_x = 28; pixel_y = 0},/obj/item/weapon/razor,/obj/item/device/eftpos,/turf/simulated/floor/plasteel{dir = 8; icon_state = "barber"},/area/civilian/barber) +"bCe" = (/obj/item/weapon/storage/toolbox/emergency,/obj/effect/spawner/lootdrop/maintenance,/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/floor/plating,/area/maintenance/starboard) +"bCf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bCg" = (/obj/machinery/hologram/holopad,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/light{dir = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bCh" = (/obj/machinery/camera{c_tag = "Council Chamber"; dir = 2; network = list("SS13")},/obj/machinery/light{dir = 1},/obj/machinery/ai_status_display{pixel_y = 32},/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) -"bCi" = (/obj/structure/table/woodentable,/obj/item/weapon/folder/yellow,/obj/machinery/firealarm{pixel_y = 28},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) +"bCi" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/computer/account_database,/turf/simulated/floor/bluegrid{name = "Server Base"; nitrogen = 250; oxygen = 0; temperature = 0},/area/bridge) "bCj" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/obj/machinery/light_switch{pixel_x = 28; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) -"bCk" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/camera{c_tag = "Bridge - Starboard Access"; dir = 4; network = list("SS13")},/turf/simulated/floor/plasteel{tag = "icon-darkbluecorners"; icon_state = "darkbluecorners"; temperature = 273.15},/area/bridge) -"bCl" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkbluecorners"; tag = "icon-darkbluecorners"; temperature = 273.15},/area/bridge) +"bCk" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -26; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) +"bCl" = (/obj/item/weapon/hand_labeler,/obj/item/stack/packageWrap,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/table/woodentable,/obj/item/device/eftpos,/turf/simulated/floor/wood,/area/crew_quarters/heads) "bCm" = (/obj/machinery/vending/cigarette{pixel_y = 2; products = list(/obj/item/weapon/storage/fancy/cigarettes/cigpack_syndicate = 7, /obj/item/weapon/storage/fancy/cigarettes/cigpack_uplift = 3, /obj/item/weapon/storage/fancy/cigarettes/cigpack_robust = 2, /obj/item/weapon/storage/fancy/cigarettes/cigpack_carp = 3, /obj/item/weapon/storage/fancy/cigarettes/cigpack_midori = 1, /obj/item/weapon/storage/box/matches = 10, /obj/item/weapon/lighter/random = 4)},/turf/simulated/floor/wood,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "bCn" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/carpet{tag = "icon-carpet7-3"; icon_state = "carpet7-3"},/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "bCo" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/stool/bed/chair/comfy/brown{tag = "icon-comfychair (EAST)"; icon_state = "comfychair"; dir = 4},/turf/simulated/floor/carpet,/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) @@ -4227,7 +4227,7 @@ "bDo" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = -32},/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) "bDp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/light,/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) "bDq" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = -32},/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) -"bDr" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/camera{c_tag = "Arrivals - Middle Arm"; dir = 1; network = list("SS13")},/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) +"bDr" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/camera{c_tag = "Bridge - Port Access"; dir = 8; network = list("SS13")},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bDs" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor/plasteel{tag = "icon-warningcorner (NORTH)"; icon_state = "warningcorner"; dir = 1},/area/hallway/secondary/entry{name = "Arrivals"}) "bDt" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 2; icon_state = "bluecorner"},/area/hallway/secondary/entry{name = "Arrivals"}) "bDu" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 2},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/plasteel{dir = 2; icon_state = "arrival"},/area/hallway/secondary/entry{name = "Arrivals"}) @@ -4257,8 +4257,8 @@ "bDS" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/cable/yellow,/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/obj/machinery/door/poddoor/preopen{id_tag = "hop"; name = "privacy shutters"},/turf/simulated/floor/plating,/area/crew_quarters/heads) "bDT" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/obj/machinery/door/poddoor/preopen{id_tag = "hop"; name = "privacy shutters"},/turf/simulated/floor/plating,/area/crew_quarters/heads) "bDU" = (/obj/structure/table/reinforced,/obj/machinery/door/window/brigdoor{base_state = "rightsecure"; dir = 1; icon_state = "rightsecure"; name = "Head of Personnel's Desk"; req_access_txt = "57"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/door/window/northleft{dir = 2; icon_state = "left"; name = "Reception Window"; req_access_txt = "0"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "hop"; layer = 3.1; name = "privacy shutters"; opacity = 0},/turf/simulated/floor/plasteel,/area/crew_quarters/heads) -"bDV" = (/obj/machinery/light{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -26; pixel_y = 0},/turf/simulated/floor/plasteel{tag = "icon-darkbluecorners"; icon_state = "darkbluecorners"; temperature = 273.15},/area/bridge) -"bDW" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkbluecorners"; tag = "icon-darkbluecorners"; temperature = 273.15},/area/bridge) +"bDV" = (/obj/structure/table/woodentable,/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = 0; pixel_y = 28},/obj/item/device/flashlight/lamp/green{pixel_x = 1; pixel_y = 5},/obj/structure/window/reinforced/tinted{dir = 8; icon_state = "twindow"; tag = ""},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) +"bDW" = (/obj/structure/table/woodentable,/obj/item/weapon/folder/yellow,/obj/machinery/firealarm{pixel_y = 28},/obj/item/weapon/book/manual/security_space_law{pixel_y = 3},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bDX" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/command{name = "Council Chamber"; req_access = null; req_access_txt = "19"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bDY" = (/obj/structure/stool/bed/chair/comfy/beige,/turf/simulated/floor/carpet,/area/bridge) "bDZ" = (/obj/structure/stool/bed/chair/comfy/black,/turf/simulated/floor/carpet,/area/bridge) @@ -4267,8 +4267,8 @@ "bEc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/carpet,/area/bridge) "bEd" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bEe" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/command{name = "Council Chamber"; req_access = null; req_access_txt = "19"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) -"bEf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{tag = "icon-darkbluecorners"; icon_state = "darkbluecorners"; temperature = 273.15},/area/bridge) -"bEg" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkbluecorners"; tag = "icon-darkbluecorners"; temperature = 273.15},/area/bridge) +"bEf" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/camera{c_tag = "Bridge - Starboard Access"; dir = 4; network = list("SS13")},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) +"bEg" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bEh" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/command{name = "Captain's Quarters"; req_access = null; req_access_txt = "20"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "bEi" = (/turf/simulated/floor/carpet{tag = "icon-carpet6-2"; icon_state = "carpet6-2"},/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "bEj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/carpet{tag = "icon-carpet15-11"; icon_state = "carpet15-11"},/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) @@ -4297,7 +4297,7 @@ "bEG" = (/turf/simulated/wall,/area/crew_quarters/theatre) "bEH" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/obj/effect/spawner/lootdrop{loot = list(/obj/structure/grille,/obj/structure/grille,/obj/structure/grille,/obj/structure/grille,/obj/structure/grille,/obj/item/weapon/cigbutt,/obj/item/trash/cheesie,/obj/item/trash/candy,/obj/item/trash/chips,/obj/item/trash/pistachios,/obj/item/trash/plate,/obj/item/trash/popcorn,/obj/item/trash/raisins,/obj/item/trash/sosjerky,/obj/item/trash/syndi_cakes); name = "maint grille or trash spawner"},/turf/simulated/floor/plating,/area/maintenance/starboard) "bEI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/device/radio/beacon,/turf/simulated/floor/plasteel{dir = 8; icon_state = "caution"},/area/hallway/primary/starboard) -"bEJ" = (/turf/simulated/floor/plasteel{icon_state = "caution"; dir = 4},/area/hallway/primary/starboard) +"bEJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/camera{c_tag = "Arrivals - Middle Arm"; dir = 1; network = list("SS13")},/obj/machinery/atm{pixel_y = -32},/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) "bEK" = (/obj/item/device/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = -30},/obj/item/weapon/crowbar/red,/obj/item/weapon/wrench,/obj/item/clothing/mask/gas,/obj/machinery/alarm{pixel_y = 23},/obj/structure/table,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/turf/simulated/floor/plasteel{dir = 9; icon_state = "caution"},/area/atmos) "bEL" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/light{dir = 1},/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/turf/simulated/floor/plasteel{dir = 1; icon_state = "caution"},/area/atmos) "bEM" = (/obj/machinery/computer/atmos_alert,/obj/structure/sign/double/map/left{desc = "A framed picture of the station. Clockwise from security at the top (red), you see engineering (yellow), science (purple), escape (red and white), medbay (green), arrivals (blue and white), and finally cargo (brown)."; icon_state = "map-left-MS"; pixel_y = 32},/obj/machinery/camera{c_tag = "Atmospherics - Control Room"; network = list("SS13")},/turf/simulated/floor/plasteel{dir = 1; icon_state = "caution"},/area/atmos) @@ -4349,7 +4349,7 @@ "bFG" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/bridge/meeting_room{name = "\improper Command Hallway"}) "bFH" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/flasher{id = "hopflash"; pixel_x = 28},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/bridge/meeting_room{name = "\improper Command Hallway"}) "bFI" = (/turf/simulated/wall/r_wall,/area/bridge/meeting_room{name = "\improper Command Hallway"}) -"bFJ" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11},/obj/machinery/door_control{id = "bridge blast"; name = "Bridge Access Blast Door Control"; pixel_x = 24; pixel_y = -24; req_access_txt = "19"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkbluecorners"; tag = "icon-darkbluecorners"; temperature = 273.15},/area/bridge) +"bFJ" = (/obj/machinery/light{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -26; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bFK" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/machinery/vending/coffee{pixel_x = -3},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bFL" = (/obj/machinery/door_control{id = "council blast"; name = "Council Chamber Blast Door Control"; pixel_x = 5; pixel_y = -28; req_access_txt = "19"},/obj/structure/reagent_dispensers/beerkeg{desc = "One of the more successful achievements of the NanoTrasen Corporate Warfare Division, their nuclear fission explosives are renowned for being cheap to produce and devestatingly effective. Signs explain that though this is just a model, every NanoTrasen station is equipped with one, just in case. All Captains carefully guard the disk needed to detonate them - at least, the sign says they do. There seems to be a tap on the back."; icon = 'icons/obj/stationobjs.dmi'; icon_state = "nuclearbomb0"; name = "NanoTrasen-brand nuclear fission explosive"; pixel_x = 2; pixel_y = 6},/turf/simulated/floor/carpet,/area/bridge) "bFM" = (/obj/structure/stool/bed/chair/comfy/teal{tag = "icon-comfychair (EAST)"; icon_state = "comfychair"; dir = 4},/obj/structure/stool/bed/chair/comfy/black{dir = 4},/turf/simulated/floor/carpet,/area/bridge) @@ -4360,7 +4360,7 @@ "bFR" = (/obj/machinery/door_control{id = "council blast"; name = "Council Chamber Blast Door Control"; pixel_x = -5; pixel_y = -28; req_access_txt = "19"},/turf/simulated/floor/carpet,/area/bridge) "bFS" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/vending/cigarette{pixel_x = 2},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bFT" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door_control{id = "bridge blast"; name = "Bridge Access Blast Door Control"; pixel_x = -24; pixel_y = -24; req_access_txt = "19"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) -"bFU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkbluecorners"; tag = "icon-darkbluecorners"; temperature = 273.15},/area/bridge) +"bFU" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bFV" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/carpet{tag = "icon-carpet5-1"; icon_state = "carpet5-1"},/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "bFW" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor/carpet{tag = "icon-carpetside"; icon_state = "carpetside"},/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) "bFX" = (/turf/simulated/floor/carpet{tag = "icon-carpetside"; icon_state = "carpetside"},/area/crew_quarters/captain{name = "\improper Captain's Quarters"}) @@ -4446,14 +4446,14 @@ "bHz" = (/obj/machinery/door/poddoor/shutters/preopen{id_tag = "hopqueue"; name = "HoP Queue Shutters"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "loadingarea"; tag = "loading"},/area/bridge/meeting_room{name = "\improper Command Hallway"}) "bHA" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/bridge/meeting_room{name = "\improper Command Hallway"}) "bHB" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/poddoor/shutters/preopen{id_tag = "hopqueue"; name = "HoP Queue Shutters"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{icon_state = "loadingarea"; tag = "loading"},/area/bridge/meeting_room{name = "\improper Command Hallway"}) -"bHC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/poddoor/preopen{id_tag = "bridge blast"; name = "bridge blast door"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_command{name = "Bridge Access"; req_access_txt = "19"},/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/bridge) -"bHD" = (/obj/machinery/door/poddoor/preopen{id_tag = "bridge blast"; name = "bridge blast door"},/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/airlock/glass_command{name = "Bridge Access"; req_access_txt = "19"},/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/bridge) +"bHC" = (/obj/machinery/atm{pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "caution"; dir = 4},/area/hallway/primary/starboard) +"bHD" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11},/obj/machinery/door_control{id = "bridge blast"; name = "Bridge Access Blast Door Control"; pixel_x = 24; pixel_y = -24; req_access_txt = "19"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bHE" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "council blast"; layer = 2.9; name = "Council Blast Doors"; opacity = 0},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/bridge) "bHF" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "council blast"; layer = 2.9; name = "Council Blast Doors"; opacity = 0},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/bridge) "bHG" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "council blast"; layer = 2.9; name = "Council Blast Doors"; opacity = 0},/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/bridge) "bHH" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "council blast"; layer = 2.9; name = "Council Blast Doors"; opacity = 0},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/bridge) "bHI" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "council blast"; layer = 2.9; name = "Council Blast Doors"; opacity = 0},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/bridge) -"bHJ" = (/obj/machinery/door/poddoor/preopen{id_tag = "bridge blast"; name = "bridge blast door"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_command{name = "Bridge Access"; req_access_txt = "19"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/bridge) +"bHJ" = (/obj/structure/reagent_dispensers/watertank,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"}) "bHK" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "20;12"},/turf/simulated/floor/plating,/area/maintenance/maintcentral{name = "Central Maintenance"}) "bHL" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/light{dir = 8},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/hallway/primary/central) "bHM" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=12-Central-Starboard"; location = "11.1-Command-Starboard"},/turf/simulated/floor/plasteel,/area/hallway/primary/central) @@ -4509,8 +4509,8 @@ "bIK" = (/obj/structure/stool/bed/chair,/obj/machinery/light/spot{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/turf/simulated/shuttle/floor,/area/shuttle/transport) "bIL" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0},/turf/simulated/floor/plating,/area/hallway/secondary/entry{name = "Arrivals"}) "bIM" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 4; icon_state = "arrival"},/area/hallway/secondary/entry{name = "Arrivals"}) -"bIN" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"}) -"bIO" = (/obj/item/weapon/storage/toolbox/emergency,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plating{tag = "icon-panelscorched"; icon_state = "panelscorched"},/area/maintenance/fpmaint2{name = "Port Maintenance"}) +"bIN" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/fpmaint2{name = "Port Maintenance"}) +"bIO" = (/obj/machinery/door/poddoor/preopen{id_tag = "bridge blast"; name = "bridge blast door"},/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/airlock/glass_command{name = "Bridge Access"; req_access_txt = "19"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bIP" = (/obj/item/weapon/tank/air,/obj/item/weapon/tank/air,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"}) "bIQ" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/wood,/area/security/vacantoffice) "bIR" = (/obj/structure/table/woodentable,/turf/simulated/floor/wood,/area/security/vacantoffice) @@ -4617,7 +4617,7 @@ "bKO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/bridge/meeting_room{name = "\improper Command Hallway"}) "bKP" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/bridge/meeting_room{name = "\improper Command Hallway"}) "bKQ" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/bridge/meeting_room{name = "\improper Command Hallway"}) -"bKR" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/light,/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/bridge/meeting_room{name = "\improper Command Hallway"}) +"bKR" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/poddoor/preopen{id_tag = "bridge blast"; name = "bridge blast door"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_command{name = "Bridge Access"; req_access_txt = "19"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bKS" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = -30},/obj/machinery/camera{c_tag = "Command Hallway - Port"; dir = 1; network = list("SS13")},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/bridge/meeting_room{name = "\improper Command Hallway"}) "bKT" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/alarm{dir = 1; pixel_y = -22},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/bridge/meeting_room{name = "\improper Command Hallway"}) "bKU" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/bridge/meeting_room{name = "\improper Command Hallway"}) @@ -4836,7 +4836,7 @@ "bOZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/stool{pixel_y = 8},/turf/simulated/floor/plasteel{icon_state = "bar"},/area/crew_quarters/bar) "bPa" = (/obj/machinery/light,/obj/machinery/camera{c_tag = "Kitchen Hatch"; dir = 1; network = list("SS13")},/turf/simulated/floor/plasteel{icon_state = "bar"},/area/crew_quarters/bar) "bPb" = (/obj/structure/stool{pixel_y = 8},/obj/machinery/firealarm{dir = 4; pixel_x = 28},/turf/simulated/floor/plasteel{icon_state = "bar"},/area/crew_quarters/bar) -"bPc" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/machinery/light,/turf/simulated/floor/wood,/area/crew_quarters/bar) +"bPc" = (/obj/machinery/door/poddoor/preopen{id_tag = "bridge blast"; name = "bridge blast door"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_command{name = "Bridge Access"; req_access_txt = "19"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge) "bPd" = (/obj/machinery/door/window{base_state = "right"; dir = 8; icon_state = "right"; name = "Theatre Stage"; req_access_txt = "0"},/turf/simulated/floor/carpet,/area/crew_quarters/theatre) "bPe" = (/obj/machinery/light_switch{pixel_y = -28},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/light,/turf/simulated/floor/carpet,/area/crew_quarters/theatre) "bPf" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/carpet,/area/crew_quarters/theatre) @@ -4937,7 +4937,7 @@ "bQW" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/maintenance/atmos_control{name = "Telecoms Storage"}) "bQX" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/airlock/engineering{name = "Telecoms Storage"; req_access_txt = "61"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/maintenance/atmos_control{name = "Telecoms Storage"}) "bQY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/wall/r_wall,/area/atmos) -"bQZ" = (/obj/machinery/atmospherics/binary/pump{dir = 4; name = "External to Filter"; on = 1},/obj/machinery/alarm{dir = 4; pixel_x = -23; pixel_y = 0},/obj/machinery/atmospherics/binary/volume_pump/on{dir = 4; name = "External to Filter"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "caution"},/area/atmos) +"bQZ" = (/obj/item/weapon/storage/toolbox/emergency,/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/floor/plating{tag = "icon-panelscorched"; icon_state = "panelscorched"},/area/maintenance/fpmaint2{name = "Port Maintenance"}) "bRa" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/visible/purple{dir = 4},/turf/simulated/floor/plasteel,/area/atmos) "bRb" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 2},/turf/simulated/floor/plasteel,/area/atmos) "bRc" = (/obj/item/device/radio/beacon,/turf/simulated/floor/plasteel,/area/atmos) @@ -5007,8 +5007,8 @@ "bSo" = (/obj/machinery/gateway{dir = 4},/turf/simulated/floor/plasteel{tag = "icon-vault (WEST)"; icon_state = "vault"; dir = 8},/area/gateway) "bSp" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/item/weapon/cigbutt,/turf/simulated/floor/plating,/area/maintenance/maintcentral{name = "Central Maintenance"}) "bSq" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = -32; pixel_y = 0},/obj/machinery/camera{c_tag = "Central Primary Hallway - Starboard - Kitchen"; dir = 4; network = list("SS13")},/turf/simulated/floor/plasteel{dir = 1; icon_state = "neutralcorner"},/area/hallway/primary/central) -"bSr" = (/obj/structure/table,/obj/machinery/microwave{pixel_x = -3; pixel_y = 6},/obj/machinery/door_control{id = "kitchenwindow"; name = "Window Shutter Control"; pixel_x = -26; pixel_y = 0; req_access_txt = "28"},/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/crew_quarters/kitchen) -"bSs" = (/obj/structure/table,/obj/machinery/microwave{pixel_x = -3; pixel_y = 6},/obj/machinery/door_control{id = "kitchen"; name = "Kitchen Shutters Control"; pixel_x = -4; pixel_y = 26; req_access_txt = "28"},/obj/machinery/light_switch{pixel_x = 6; pixel_y = 26},/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/crew_quarters/kitchen) +"bSr" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/light,/obj/machinery/atm{pixel_y = -32},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/bridge/meeting_room{name = "\improper Command Hallway"}) +"bSs" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/firealarm{dir = 8; pixel_x = -26; pixel_y = 0},/turf/simulated/floor/wood,/area/crew_quarters/bar) "bSt" = (/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "bSu" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "bSv" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 4},/obj/machinery/light{dir = 1},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) @@ -5093,7 +5093,7 @@ "bTW" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/turf/simulated/floor/plasteel{dir = 1; icon_state = "neutralcorner"},/area/hallway/primary/central) "bTX" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/hallway/primary/central) "bTY" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/poddoor/preopen{id_tag = "kitchenwindow"; name = "kitchen shutters"},/obj/effect/spawner/window{useFull = 1; tag = "fullWin"},/turf/simulated/floor/plating,/area/crew_quarters/kitchen) -"bTZ" = (/obj/structure/rack,/obj/item/weapon/book/manual/chef_recipes{pixel_x = 2; pixel_y = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/item/stack/packageWrap,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) +"bTZ" = (/obj/machinery/light,/obj/machinery/atm{pixel_y = -32},/turf/simulated/floor/wood,/area/crew_quarters/bar) "bUa" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "bUb" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "bUc" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) @@ -5161,11 +5161,11 @@ "bVm" = (/obj/structure/sign/securearea{pixel_x = -32; pixel_y = 0},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating{tag = "icon-platingdmg2"; icon_state = "platingdmg2"},/area/maintenance/maintcentral{name = "Central Maintenance"}) "bVn" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor/plasteel{dir = 1; icon_state = "neutralcorner"},/area/hallway/primary/central) "bVo" = (/obj/machinery/door/poddoor/preopen{id_tag = "kitchenwindow"; name = "kitchen shutters"},/obj/effect/spawner/window{useFull = 1; tag = "fullWin"},/turf/simulated/floor/plating,/area/crew_quarters/kitchen) -"bVp" = (/obj/structure/foodcart,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) +"bVp" = (/obj/machinery/alarm{dir = 4; pixel_x = -23; pixel_y = 0},/obj/machinery/atmospherics/binary/volume_pump/on{dir = 4; name = "External to Filter"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "caution"},/area/atmos) "bVq" = (/obj/effect/landmark/start{name = "Cook"},/turf/simulated/floor/plasteel{icon_state = "cafeteria"},/area/crew_quarters/kitchen) -"bVr" = (/obj/structure/table,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) -"bVs" = (/obj/structure/table,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/item/weapon/storage/box/donkpockets,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) -"bVt" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/table,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) +"bVr" = (/obj/structure/table,/obj/machinery/door_control{id = "kitchenwindow"; name = "Window Shutter Control"; pixel_x = -26; pixel_y = 0; req_access_txt = "28"},/obj/machinery/kitchen_machine/microwave,/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/crew_quarters/kitchen) +"bVs" = (/obj/structure/table,/obj/machinery/door_control{id = "kitchen"; name = "Kitchen Shutters Control"; pixel_x = -4; pixel_y = 26; req_access_txt = "28"},/obj/machinery/light_switch{pixel_x = 6; pixel_y = 26},/obj/machinery/kitchen_machine/microwave,/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/crew_quarters/kitchen) +"bVt" = (/obj/machinery/kitchen_machine/candy_maker,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "bVu" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "bVv" = (/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/obj/structure/closet/secure_closet/freezer/fridge,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "bVw" = (/obj/structure/closet/secure_closet/freezer/kitchen,/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) @@ -5252,7 +5252,7 @@ "bWZ" = (/obj/machinery/door/airlock/maintenance{name = "Gateway Maintenance"; req_access_txt = "17"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/gateway) "bXa" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/maintenance/maintcentral{name = "Central Maintenance"}) "bXb" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 1; icon_state = "neutralcorner"},/area/hallway/primary/central) -"bXc" = (/obj/structure/rack,/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) +"bXc" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/snacks/mint,/obj/item/weapon/reagent_containers/food/condiment/enzyme{layer = 5},/obj/item/weapon/reagent_containers/glass/beaker{pixel_x = 5},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "bXd" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "bXe" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "bXf" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) @@ -5320,11 +5320,11 @@ "bYp" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/camera{c_tag = "Gateway - Access"; dir = 8; network = list("SS13")},/turf/simulated/floor/plasteel{dir = 2; icon_state = "warning"},/area/gateway) "bYq" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating{icon_state = "warnplate"},/area/maintenance/maintcentral{name = "Central Maintenance"}) "bYr" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/plasteel{dir = 1; icon_state = "neutralcorner"},/area/hallway/primary/central) -"bYs" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/snacks/mint,/obj/machinery/alarm{dir = 4; pixel_x = -23; pixel_y = 0},/obj/machinery/power/apc{dir = 2; name = "Kitchen APC"; pixel_y = -24},/obj/structure/cable/yellow,/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/crew_quarters/kitchen) -"bYt" = (/obj/structure/table,/obj/item/weapon/reagent_containers/glass/beaker{pixel_x = 5},/obj/item/weapon/reagent_containers/food/condiment/enzyme{layer = 5},/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/crew_quarters/kitchen) -"bYu" = (/obj/structure/table,/obj/item/stack/packageWrap,/obj/item/weapon/hand_labeler,/obj/machinery/door_control{id = "kitchenhydro"; name = "Service Shutter Control"; pixel_x = 0; pixel_y = -24; req_access_txt = "28"},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) -"bYv" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/condiment/saltshaker{pixel_x = -3; pixel_y = 0},/obj/item/weapon/reagent_containers/food/condiment/peppermill{pixel_x = 3},/obj/item/device/radio/intercom{pixel_y = -25},/obj/item/weapon/kitchen/rollingpin,/obj/machinery/camera{c_tag = "Kitchen"; dir = 1; network = list("SS13")},/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/crew_quarters/kitchen) -"bYw" = (/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = -30},/obj/structure/table,/obj/machinery/reagentgrinder,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) +"bYs" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/table,/obj/item/weapon/book/manual/chef_recipes{pixel_x = 2; pixel_y = 6},/obj/item/stack/packageWrap,/obj/item/weapon/hand_labeler,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) +"bYt" = (/obj/structure/table,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/item/weapon/storage/box/donkpockets,/obj/item/device/eftpos,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) +"bYu" = (/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) +"bYv" = (/obj/machinery/alarm{dir = 4; pixel_x = -23; pixel_y = 0},/obj/machinery/power/apc{dir = 2; name = "Kitchen APC"; pixel_y = -24},/obj/structure/cable/yellow,/obj/structure/table,/obj/machinery/reagentgrinder,/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/crew_quarters/kitchen) +"bYw" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/condiment/saltshaker{pixel_x = -3; pixel_y = 0},/obj/item/weapon/reagent_containers/food/condiment/peppermill{pixel_x = 3},/obj/item/weapon/kitchen/rollingpin,/obj/machinery/camera{c_tag = "Kitchen"; dir = 1; network = list("SS13")},/obj/machinery/door_control{id = "kitchenhydro"; name = "Service Shutter Control"; pixel_x = 0; pixel_y = -24; req_access_txt = "28"},/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/crew_quarters/kitchen) "bYx" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "bYy" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "bYz" = (/obj/machinery/door/airlock{icon = 'icons/obj/doors/Doorsilver.dmi'; name = "Kitchen Cold Room"; req_access_txt = "28"},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) @@ -5332,7 +5332,7 @@ "bYB" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/alarm{dir = 1; pixel_y = -22},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/camera{c_tag = "Kitchen - Coldroom"; dir = 1; network = list("SS13")},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) "bYC" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/light_switch{pixel_y = -26},/obj/machinery/light,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) "bYD" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) -"bYE" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) +"bYE" = (/obj/machinery/cooker/deepfryer,/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/crew_quarters/kitchen) "bYF" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/turf/simulated/floor/plating{tag = "icon-platingdmg1"; icon_state = "platingdmg1"},/area/maintenance/starboard) "bYG" = (/obj/machinery/portable_atmospherics/canister,/turf/simulated/floor/plating,/area/maintenance/starboard) "bYH" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/starboard) @@ -5362,7 +5362,7 @@ "bZf" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/wood,/area/library) "bZg" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 27},/turf/simulated/floor/wood,/area/library) "bZh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/hallway/primary/central) -"bZi" = (/obj/structure/sign/directions/evac{tag = "icon-direction_evac (EAST)"; icon_state = "direction_evac"; dir = 4},/obj/structure/sign/directions/medical{desc = "A direction sign, pointing out which way the medical department is."; dir = 4; icon_state = "direction_med"; name = "medical department"; pixel_y = 8; tag = "icon-direction_med (EAST)"},/obj/structure/sign/directions/science{desc = "A direction sign, pointing out which way the research department is."; dir = 4; icon_state = "direction_sci"; name = "research department"; pixel_y = -8; tag = "icon-direction_sci (EAST)"},/turf/simulated/wall/r_wall,/area/ai_monitored/storage/eva{name = "E.V.A. Storage"}) +"bZi" = (/obj/structure/sign/directions/evac,/obj/structure/sign/directions/medical{pixel_y = 8},/obj/structure/sign/directions/science{pixel_y = -8},/turf/simulated/wall,/area/civilian/barber) "bZj" = (/obj/machinery/door/firedoor,/obj/machinery/door/poddoor/shutters{id_tag = "evashutter"; name = "E.V.A. Storage Shutter"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/ai_monitored/storage/eva{name = "E.V.A. Storage"}) "bZk" = (/obj/machinery/door/poddoor/shutters{id_tag = "teleshutter"; name = "Teleporter Access Shutter"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/teleporter{name = "\improper Teleporter Room"}) "bZl" = (/turf/simulated/wall/r_wall,/area/blueshield) @@ -5458,8 +5458,8 @@ "caX" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/plating,/area/maintenance/starboard) "caY" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating{tag = "icon-panelscorched"; icon_state = "panelscorched"},/area/maintenance/starboard) "caZ" = (/mob/living/simple_animal/mouse,/turf/simulated/floor/plating,/area/maintenance/starboard) -"cba" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor/plating{icon_state = "warnplate"},/area/maintenance/starboard) -"cbb" = (/obj/machinery/atmospherics/unary/portables_connector{dir = 8},/obj/machinery/portable_atmospherics/canister,/turf/simulated/floor/plating,/area/maintenance/starboard) +"cba" = (/obj/item/device/radio/intercom{pixel_y = -25},/obj/machinery/camera{c_tag = "Kitchen"; dir = 1; network = list("SS13")},/obj/machinery/kitchen_machine/grill,/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/crew_quarters/kitchen) +"cbb" = (/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = -30},/obj/machinery/kitchen_machine/oven,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "cbc" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/atmos) "cbd" = (/obj/machinery/pipedispenser,/turf/simulated/floor/plasteel{dir = 10; icon_state = "warning"},/area/atmos) "cbe" = (/obj/machinery/light{dir = 1},/obj/machinery/light_switch{pixel_y = 28},/obj/machinery/pipedispenser/disposal,/turf/simulated/floor/plasteel{icon_state = "warning"},/area/atmos) @@ -5527,7 +5527,7 @@ "cco" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/turf/simulated/floor/plating,/area/maintenance/portsolar) "ccp" = (/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/light/small{dir = 4},/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 27},/turf/simulated/floor/plating,/area/maintenance/portsolar) "ccq" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"}) -"ccr" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating{tag = "icon-panelscorched"; icon_state = "panelscorched"},/area/maintenance/fpmaint2{name = "Port Maintenance"}) +"ccr" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/foodcart,/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) "ccs" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/aft{name = "Aft Maintenance"}) "cct" = (/turf/simulated/floor/plating{tag = "icon-platingdmg1"; icon_state = "platingdmg1"},/area/maintenance/aft{name = "Aft Maintenance"}) "ccu" = (/turf/simulated/floor/plating{tag = "icon-warnplatecorner (WEST)"; icon_state = "warnplatecorner"; dir = 8},/area/maintenance/aft{name = "Aft Maintenance"}) @@ -5801,8 +5801,8 @@ "chC" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "12;5"},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "chD" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating{tag = "icon-warnplate (WEST)"; icon_state = "warnplate"; dir = 8},/area/maintenance/aft{name = "Aft Maintenance"}) "chE" = (/obj/item/weapon/reagent_containers/glass/bottle/morphine,/obj/item/trash/candy,/obj/structure/disposalpipe/segment{dir = 4},/obj/item/clothing/accessory/stethoscope,/turf/simulated/floor/plating{tag = "icon-platingdmg1"; icon_state = "platingdmg1"},/area/maintenance/aft{name = "Aft Maintenance"}) -"chF" = (/obj/item/weapon/storage/box/lights/mixed,/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) -"chG" = (/obj/item/weapon/tank/air,/obj/item/weapon/tank/air,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/maintenance/aft{name = "Aft Maintenance"}) +"chF" = (/obj/item/weapon/cigbutt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plating,/area/maintenance/starboard) +"chG" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor/plating,/area/maintenance/starboard) "chH" = (/obj/machinery/door/airlock{name = "Medbay Emergency Storage"; req_access_txt = "5"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/medical/medbay2{name = "Medbay Storage"}) "chI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whiteblue"},/area/medical/medbay2{name = "Medbay Storage"}) "chJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay2{name = "Medbay Storage"}) @@ -5932,7 +5932,7 @@ "ckd" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = -31},/mob/living/simple_animal/mouse,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/maintenance/incinerator) "cke" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door_control{id = "turbinevent"; name = "Turbine Vent Control"; pixel_x = -6; pixel_y = -24; req_access_txt = "12"},/obj/machinery/door_control{id = "auxincineratorvent"; name = "Auxiliary Vent Control"; pixel_x = 6; pixel_y = -24; req_access_txt = "12"},/obj/machinery/atmospherics/pipe/simple/visible{dir = 2},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/maintenance/incinerator) "ckf" = (/obj/machinery/meter,/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/atmospherics/pipe/manifold/visible{dir = 1},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/maintenance/incinerator) -"ckg" = (/obj/machinery/atmospherics/unary/portables_connector{dir = 8; name = "output gas connector port"},/obj/machinery/portable_atmospherics/canister,/obj/machinery/ignition_switch{id = "Incinerator"; pixel_x = -6; pixel_y = -24},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/maintenance/incinerator) +"ckg" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/floor/plating,/area/maintenance/starboard) "ckh" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/area/atmos) "cki" = (/obj/machinery/atmospherics/pipe/simple/visible/green,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/atmos) "ckj" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/atmos) @@ -6063,9 +6063,9 @@ "cmE" = (/obj/machinery/power/apc{dir = 8; name = "Incinerator APC"; pixel_x = -24; pixel_y = 0},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/maintenance/incinerator) "cmF" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/incinerator) "cmG" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/binary/valve{dir = 2; name = "output gas to space"},/obj/structure/sign/fire{pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/maintenance/incinerator) -"cmH" = (/obj/machinery/atmospherics/binary/pump{dir = 2; on = 1},/obj/machinery/light/small{dir = 8},/obj/structure/sign/fire{pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plasteel,/area/maintenance/incinerator) -"cmI" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plasteel,/area/maintenance/incinerator) -"cmJ" = (/obj/machinery/atmospherics/binary/pump{dir = 1; on = 1},/obj/structure/sign/fire{pixel_x = 32; pixel_y = 0},/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plasteel,/area/maintenance/incinerator) +"cmH" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating{icon_state = "warnplate"},/area/maintenance/starboard) +"cmI" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/floor/plating{tag = "icon-panelscorched"; icon_state = "panelscorched"},/area/maintenance/fpmaint2{name = "Port Maintenance"}) +"cmJ" = (/obj/item/weapon/storage/box/lights/mixed,/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "cmK" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/visible/green,/turf/space,/area/space) "cmL" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/visible/yellow,/turf/space,/area/space) "cmM" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/manifold/visible/yellow{dir = 8},/turf/space,/area/space) @@ -6176,7 +6176,7 @@ "coN" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1; scrub_Toxins = 0},/turf/simulated/floor/plasteel{tag = "icon-warnwhite (NORTH)"; icon_state = "warnwhite"; dir = 1},/area/medical/research{name = "Research Division"}) "coO" = (/obj/machinery/power/apc{cell_type = 10000; dir = 1; name = "Research Division APC"; pixel_x = 0; pixel_y = 25},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/camera{c_tag = "Research Division - Airlock"; dir = 2; network = list("SS13","RD")},/turf/simulated/floor/plasteel{icon_state = "warnwhite"; dir = 5},/area/medical/research{name = "Research Division"}) "coP" = (/turf/simulated/floor/plasteel{icon_state = "bot"},/area/medical/research{name = "Research Division"}) -"coQ" = (/obj/effect/landmark{name = "blobstart"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/weapon/cigbutt,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/aft{name = "Aft Maintenance"}) +"coQ" = (/obj/item/weapon/tank/air,/obj/item/weapon/tank/air,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/universal{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/maintenance/aft{name = "Aft Maintenance"}) "coR" = (/obj/structure/stool,/obj/machinery/newscaster{pixel_x = -30; pixel_y = 0},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/research{name = "Research Division"}) "coS" = (/obj/structure/stool,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/research{name = "Research Division"}) "coT" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/research{name = "Research Division"}) @@ -6240,7 +6240,7 @@ "cpZ" = (/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/chemistry) "cqa" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_Toxins = 0},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/chemistry) "cqb" = (/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteyellow"; tag = "icon-whitehall (WEST)"},/area/medical/chemistry) -"cqc" = (/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/weapon/hand_labeler,/obj/structure/table/glass,/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteyellowfull"; tag = "icon-whitehall (WEST)"},/area/medical/chemistry) +"cqc" = (/obj/machinery/atmospherics/unary/portables_connector{dir = 8; name = "output gas connector port"},/obj/machinery/portable_atmospherics/canister,/obj/machinery/ignition_switch{id = "Incinerator"; pixel_x = -6; pixel_y = -24},/obj/machinery/embedded_controller/radio/airlock/access_controller{frequency = 1449; id_tag = "turbine_control"; name = "Turbine Access Console"; pixel_x = 6; pixel_y = -26; req_access_txt = "12"; tag_exterior_door = "gas_turbine_exterior"; tag_interior_door = "gas_turbine_interior"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/maintenance/incinerator) "cqd" = (/obj/machinery/computer/rdconsole/core,/obj/machinery/alarm{dir = 4; pixel_x = -23; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "warning"},/area/toxins/lab) "cqe" = (/turf/simulated/floor/plasteel{icon_state = "warning"},/area/toxins/lab) "cqf" = (/obj/machinery/r_n_d/circuit_imprinter{pixel_y = 4},/obj/item/weapon/reagent_containers/glass/beaker/sulphuric,/turf/simulated/floor/plasteel{icon_state = "warning"},/area/toxins/lab) @@ -6255,7 +6255,7 @@ "cqo" = (/obj/item/weapon/storage/toolbox/emergency,/obj/item/clothing/mask/gas,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "cqp" = (/obj/machinery/light/small,/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "cqq" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/device/flashlight,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) -"cqr" = (/obj/item/stack/packageWrap,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) +"cqr" = (/obj/machinery/atmospherics/binary/pump{on = 1},/obj/machinery/access_button{command = "cycle_exterior"; layer = 3.1; master_tag = "turbine_control"; name = "Gas Turbine Airlock Control"; pixel_x = 5; pixel_y = -23},/obj/machinery/light/small{dir = 8},/obj/structure/sign/fire{pixel_x = -32},/turf/simulated/floor/engine,/area/maintenance/incinerator) "cqs" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/structure/sink{dir = 8; icon_state = "sink"; pixel_x = -12; pixel_y = 2},/obj/item/weapon/cigbutt,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/research{name = "Research Division"}) "cqt" = (/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/research{name = "Research Division"}) "cqu" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/research{name = "Research Division"}) @@ -6272,8 +6272,8 @@ "cqF" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/emergency,/turf/simulated/floor/plating,/area/maintenance/starboard) "cqG" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/drinks/drinkingglass{pixel_x = 4; pixel_y = 5},/obj/item/weapon/reagent_containers/food/drinks/drinkingglass{pixel_x = 6; pixel_y = -1},/obj/item/weapon/reagent_containers/food/drinks/drinkingglass{pixel_x = -4; pixel_y = 6},/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/syringe,/obj/item/weapon/reagent_containers/syringe,/turf/simulated/floor/plating,/area/maintenance/starboard) "cqH" = (/obj/item/weapon/reagent_containers/glass/bottle/toxin{pixel_x = 4; pixel_y = 2},/obj/structure/table,/obj/effect/decal/cleanable/cobweb2,/obj/machinery/reagentgrinder{pixel_y = 4},/turf/simulated/floor/plating,/area/maintenance/starboard) -"cqI" = (/obj/structure/lattice,/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/binary/pump{dir = 2; name = "Gas Pump"; on = 1},/turf/space,/area/space) -"cqJ" = (/obj/structure/cable,/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor/plating/airless,/area/maintenance/incinerator) +"cqI" = (/obj/machinery/atmospherics/binary/pump{dir = 1; on = 1},/obj/machinery/access_button{command = "cycle_interior"; master_tag = "turbine_control"; name = "Gas Turbine Airlock Control"; pixel_x = -8; pixel_y = 24},/obj/machinery/light/small{dir = 4},/obj/structure/sign/fire{pixel_x = 32},/turf/simulated/floor/engine,/area/maintenance/incinerator) +"cqJ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/engine,/area/maintenance/incinerator) "cqK" = (/turf/simulated/floor/engine{name = "n2 floor"; nitrogen = 100000; oxygen = 0},/area/atmos) "cqL" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/turf/simulated/floor/engine{name = "n2 floor"; nitrogen = 100000; oxygen = 0},/area/atmos) "cqM" = (/obj/machinery/camera{c_tag = "Atmospherics Tank - N2"; dir = 8; network = list("SS13"); pixel_x = 0; pixel_y = 0},/turf/simulated/floor/engine{name = "n2 floor"; nitrogen = 100000; oxygen = 0},/area/atmos) @@ -6311,7 +6311,7 @@ "crs" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/effect/spawner/window{useFull = 1; tag = "fullWin"},/turf/simulated/floor/plating,/area/medical/sleeper{name = "Sleepers"}) "crt" = (/obj/structure/sink{dir = 8; icon_state = "sink"; pixel_x = -12; pixel_y = 2},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitebluecorner"},/area/medical/medbay{name = "Medbay Central"}) "cru" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay{name = "Medbay Central"}) -"crv" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11},/obj/effect/landmark/start{name = "Psychiatrist"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay{name = "Medbay Central"}) +"crv" = (/obj/structure/closet/firecloset,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "crw" = (/obj/item/device/radio/intercom{broadcasting = 1; frequency = 1485; listening = 0; name = "Station Intercom (Medbay)"; pixel_x = 0; pixel_y = -30},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay{name = "Medbay Central"}) "crx" = (/obj/machinery/vending/medical,/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitebluecorner"},/area/medical/medbay{name = "Medbay Central"}) "cry" = (/obj/structure/stool/bed/roller,/obj/machinery/iv_drip{density = 0},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteblue"},/area/medical/medbay{name = "Medbay Central"}) @@ -6321,7 +6321,7 @@ "crC" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor,/obj/machinery/door/window/eastright{name = "Chemistry Desk"; req_access_txt = "5; 33"},/obj/machinery/door/window/eastright{dir = 8; name = "Chemistry Desk"; req_access_txt = "5"},/obj/item/weapon/reagent_containers/glass/bottle/morphine,/obj/item/weapon/reagent_containers/glass/bottle/toxin{pixel_x = 5; pixel_y = 4},/obj/item/weapon/reagent_containers/glass/bottle/epinephrine{pixel_x = 8},/obj/item/weapon/reagent_containers/glass/bottle/charcoal{pixel_x = -5; pixel_y = 0},/obj/item/weapon/reagent_containers/syringe/epinephrine,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/chemistry) "crD" = (/obj/structure/stool/bed/chair/office/light{dir = 8},/obj/effect/landmark/start{name = "Chemist"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whiteyellow"},/area/medical/chemistry) "crE" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/landmark/start{name = "Chemist"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/chemistry) -"crF" = (/obj/structure/stool/bed/chair/office/light,/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteyellow"; tag = "icon-whitehall (WEST)"},/area/medical/chemistry) +"crF" = (/obj/effect/landmark{name = "blobstart"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/obj/item/weapon/cigbutt,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/aft{name = "Aft Maintenance"}) "crG" = (/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/item/weapon/reagent_containers/glass/beaker{pixel_x = 8; pixel_y = 2},/obj/item/weapon/reagent_containers/glass/beaker{pixel_x = 8; pixel_y = 2},/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/dropper,/obj/structure/extinguisher_cabinet{pixel_x = 24; pixel_y = 0},/obj/structure/table/glass,/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteyellowfull"; tag = "icon-whitehall (WEST)"},/area/medical/chemistry) "crH" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/hallway/primary/aft) "crI" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/camera{c_tag = "Aft Primary Hallway - Fore"; dir = 8; network = list("SS13")},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/hallway/primary/aft) @@ -6337,8 +6337,8 @@ "crS" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/structure/closet/firecloset,/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/medical/research{name = "Research Division"}) "crT" = (/obj/structure/plasticflaps{opacity = 1},/obj/machinery/navbeacon{codes_txt = "delivery;dir=2"; freq = 1400; location = "Research Division"},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/maintenance/aft{name = "Aft Maintenance"}) "crU" = (/turf/simulated/wall/r_wall,/area/maintenance/aft{name = "Aft Maintenance"}) -"crV" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/obj/item/weapon/storage/box/lights/mixed,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/aft{name = "Aft Maintenance"}) -"crW" = (/obj/machinery/atmospherics/unary/portables_connector{dir = 8},/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating,/area/medical/research{name = "Research Division"}) +"crV" = (/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/weapon/hand_labeler,/obj/structure/table/glass,/obj/item/weapon/folder/white{pixel_y = 2},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteyellowfull"; tag = "icon-whitehall (WEST)"},/area/medical/chemistry) +"crW" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atm{pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/hallway/primary/aft) "crX" = (/obj/machinery/microwave{pixel_x = -3; pixel_y = 6},/obj/structure/table/glass,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/research{name = "Research Division"}) "crY" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/research{name = "Research Division"}) "crZ" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/research{name = "Research Division"}) @@ -6355,8 +6355,8 @@ "csk" = (/obj/structure/rack,/obj/item/clothing/suit/apron,/obj/item/clothing/mask/surgical,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "csl" = (/obj/machinery/chem_master/condimaster{name = "CondiMaster Neo"; pixel_x = -4},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "csm" = (/obj/structure/lattice,/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/insulated{dir = 5},/turf/space,/area/space) -"csn" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 8},/turf/simulated/floor/plating/airless,/area/space) -"cso" = (/obj/structure/cable,/turf/simulated/floor/plating/airless,/area/maintenance/incinerator) +"csn" = (/obj/item/stack/packageWrap,/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) +"cso" = (/obj/structure/lattice,/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/binary/pump/on,/turf/space,/area/space) "csp" = (/obj/item/weapon/wrench,/turf/simulated/floor/plating/airless,/area/space) "csq" = (/obj/machinery/light/small,/turf/simulated/floor/engine{name = "n2 floor"; nitrogen = 100000; oxygen = 0},/area/atmos) "csr" = (/obj/machinery/light/small,/turf/simulated/floor/engine{name = "o2 floor"; nitrogen = 0; oxygen = 100000},/area/atmos) @@ -6385,7 +6385,7 @@ "csO" = (/obj/machinery/reagentgrinder,/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/requests_console{department = "Chemistry"; departmentType = 2; pixel_x = -30; pixel_y = 0},/obj/structure/table/glass,/turf/simulated/floor/plasteel{dir = 8; icon_state = "whiteyellow"},/area/medical/chemistry) "csP" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/chemistry) "csQ" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/chemistry) -"csR" = (/obj/structure/table/glass,/obj/item/weapon/folder/white{pixel_y = 2},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteyellow"; tag = "icon-whitehall (WEST)"},/area/medical/chemistry) +"csR" = (/obj/structure/cable,/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/power/compressor{comp_id = "incineratorturbine"; dir = 1},/turf/simulated/floor/plating/airless,/area/maintenance/incinerator) "csS" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/obj/structure/sign/chemistry{pixel_x = -32},/turf/simulated/floor/plasteel{dir = 8; icon_state = "yellowcorner"},/area/hallway/primary/aft) "csT" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/sign/science{pixel_x = 32},/turf/simulated/floor/plasteel{dir = 2; icon_state = "purplecorner"},/area/hallway/primary/aft) "csU" = (/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitepurple"},/area/toxins/lab) @@ -6420,11 +6420,11 @@ "ctx" = (/obj/item/weapon/reagent_containers/food/drinks/cans/beer,/obj/structure/table/woodentable,/turf/simulated/floor/wood,/area/maintenance/aft{name = "Aft Maintenance"}) "cty" = (/turf/simulated/floor/wood{tag = "icon-wood-broken"; icon_state = "wood-broken"},/area/maintenance/aft{name = "Aft Maintenance"}) "ctz" = (/obj/structure/mineral_door/wood{name = "The Gobbetting Barmaid"},/turf/simulated/floor/wood,/area/maintenance/aft{name = "Aft Maintenance"}) -"ctA" = (/obj/structure/table,/obj/item/weapon/hemostat,/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/turf/simulated/floor/plasteel,/area/medical/surgery) -"ctB" = (/obj/structure/table,/obj/item/weapon/surgicaldrill,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "whitehall"; dir = 2},/area/medical/surgery) +"ctA" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay{name = "Medbay Central"}) +"ctB" = (/obj/structure/stool/bed/chair/office/light{dir = 4},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteyellow"; tag = "icon-whitehall (WEST)"},/area/medical/chemistry) "ctC" = (/obj/structure/table,/obj/item/weapon/scalpel{pixel_y = 12},/obj/item/weapon/circular_saw,/turf/simulated/floor/plasteel{icon_state = "whitehall"; dir = 2},/area/medical/surgery) "ctD" = (/obj/structure/table,/obj/item/weapon/cautery{pixel_x = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/weapon/razor{pixel_y = 5},/turf/simulated/floor/plasteel{icon_state = "whitehall"; dir = 2},/area/medical/surgery) -"ctE" = (/obj/structure/table,/obj/item/weapon/retractor,/turf/simulated/floor/plasteel,/area/medical/surgery) +"ctE" = (/obj/machinery/portable_atmospherics/canister/air,/obj/machinery/atmospherics/unary/portables_connector{dir = 1},/turf/simulated/floor/plating,/area/medical/research{name = "Research Division"}) "ctF" = (/obj/machinery/computer/med_data,/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitehall"; tag = "icon-whitehall (WEST)"},/area/medical/surgery) "ctG" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitehall"; tag = "icon-whitehall (WEST)"},/area/medical/surgery) "ctH" = (/obj/structure/table/reinforced,/obj/item/device/radio/intercom{broadcasting = 1; frequency = 1485; listening = 0; name = "Station Intercom (Medbay)"; pixel_x = 30; pixel_y = 0},/obj/structure/bedsheetbin{pixel_x = 2},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitehall"; tag = "icon-whitehall (WEST)"},/area/medical/surgery) @@ -6438,7 +6438,7 @@ "ctP" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay{name = "Medbay Central"}) "ctQ" = (/obj/structure/filingcabinet/filingcabinet,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel{dir = 8; icon_state = "barber"},/area/medical/cmo) "ctR" = (/obj/item/weapon/cartridge/medical{pixel_x = -2; pixel_y = 6},/obj/item/weapon/cartridge/medical{pixel_x = 6; pixel_y = 3},/obj/item/weapon/cartridge/medical,/obj/item/weapon/cartridge/chemistry{pixel_y = 2},/obj/structure/table/glass,/turf/simulated/floor/plasteel{dir = 8; icon_state = "barber"},/area/medical/cmo) -"ctS" = (/obj/item/weapon/folder/blue,/obj/structure/table/glass,/obj/item/weapon/stamp/cmo,/turf/simulated/floor/plasteel{dir = 8; icon_state = "barber"},/area/medical/cmo) +"ctS" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/obj/item/weapon/storage/box/lights/mixed,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/aft{name = "Aft Maintenance"}) "ctT" = (/obj/item/weapon/folder/white,/obj/item/weapon/stamp/cmo,/obj/item/clothing/glasses/hud/health,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/table/glass,/turf/simulated/floor/plasteel{dir = 8; icon_state = "barber"},/area/medical/cmo) "ctU" = (/obj/structure/closet/secure_closet/CMO,/obj/item/weapon/storage/secure/safe{pixel_x = 5; pixel_y = 26},/obj/machinery/computer/security/telescreen/entertainment{pixel_x = 30; pixel_y = 0},/obj/item/weapon/screwdriver{pixel_y = 6},/turf/simulated/floor/plasteel{dir = 8; icon_state = "barber"},/area/medical/cmo) "ctV" = (/obj/item/clothing/glasses/science{pixel_x = 2; pixel_y = 4},/obj/item/clothing/glasses/science,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/obj/structure/table/glass,/obj/item/stack/cable_coil,/obj/item/stack/cable_coil,/obj/machinery/camera{c_tag = "Chemistry"; dir = 4; network = list("SS13","Medbay")},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whiteyellow"},/area/medical/chemistry) @@ -6667,10 +6667,10 @@ "cyk" = (/obj/item/weapon/dice/d20,/obj/item/weapon/dice,/obj/structure/table/woodentable,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/maintenance/aft{name = "Aft Maintenance"}) "cyl" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/maintenance/aft{name = "Aft Maintenance"}) "cym" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) -"cyn" = (/obj/structure/table,/obj/item/weapon/hemostat,/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/obj/machinery/light{dir = 8},/obj/structure/window/reinforced/polarized{tag = "icon-rwindow (NORTH)"; icon_state = "rwindow"; dir = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery) +"cyn" = (/obj/machinery/atmospherics/unary/outlet_injector/on{dir = 8},/turf/simulated/floor/plating/airless,/area/space) "cyo" = (/obj/structure/table,/obj/item/weapon/scalpel{pixel_y = 12},/obj/item/weapon/circular_saw,/obj/structure/window/reinforced/polarized{tag = "icon-rwindow (NORTH)"; icon_state = "rwindow"; dir = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery) "cyp" = (/obj/structure/table,/obj/item/weapon/cautery{pixel_x = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/weapon/razor{pixel_y = 5},/obj/structure/window/reinforced/polarized{tag = "icon-rwindow (NORTH)"; icon_state = "rwindow"; dir = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery) -"cyq" = (/obj/structure/table,/obj/item/weapon/retractor,/obj/machinery/light{dir = 4},/obj/structure/window/reinforced/polarized{tag = "icon-rwindow (NORTH)"; icon_state = "rwindow"; dir = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery) +"cyq" = (/obj/structure/cable,/obj/machinery/power/turbine,/turf/simulated/floor/plating/airless,/area/maintenance/incinerator) "cyr" = (/obj/structure/stool/bed/roller,/obj/machinery/light/small{dir = 8},/obj/structure/sign/nosmoking_2{pixel_x = -28},/obj/machinery/iv_drip{density = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery) "cys" = (/obj/machinery/light/small{dir = 4; pixel_y = 8},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery) "cyt" = (/turf/simulated/wall,/area/medical/cryo) @@ -6682,7 +6682,7 @@ "cyz" = (/obj/structure/stool/bed/chair{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 8; icon_state = "barber"},/area/medical/cmo) "cyA" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/table/glass,/obj/item/weapon/folder/blue,/obj/item/weapon/folder/blue,/obj/item/weapon/pen,/turf/simulated/floor/plasteel{dir = 8; icon_state = "barber"},/area/medical/cmo) "cyB" = (/obj/structure/stool/bed/chair/office/light{dir = 8},/obj/machinery/requests_console{announcementConsole = 1; department = "Chief Medical Officer's Desk"; departmentType = 5; name = "Chief Medical Officer RC"; pixel_x = 0; pixel_y = -32},/obj/effect/landmark/start{name = "Chief Medical Officer"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "barber"},/area/medical/cmo) -"cyC" = (/obj/machinery/computer/security/telescreen{desc = "Used for monitoring medbay to ensure patient safety."; dir = 8; name = "Medbay Monitor"; network = list("Medbay"); pixel_x = 29; pixel_y = 0},/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = -29},/obj/item/weapon/paper_bin{pixel_x = -2; pixel_y = 5},/obj/structure/table/glass,/turf/simulated/floor/plasteel{dir = 8; icon_state = "barber"},/area/medical/cmo) +"cyC" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteyellow"; tag = "icon-whitehall (WEST)"},/area/medical/chemistry) "cyD" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/effect/landmark{name = "blobstart"},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "cyE" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "cyF" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating{tag = "icon-platingdmg1"; icon_state = "platingdmg1"},/area/maintenance/aft{name = "Aft Maintenance"}) @@ -6721,8 +6721,8 @@ "czm" = (/obj/structure/grille{density = 0; icon_state = "brokengrille"},/turf/space,/area/space) "czn" = (/obj/machinery/vending/cigarette,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/aft{name = "Aft Maintenance"}) "czo" = (/obj/machinery/vending/assist,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/aft{name = "Aft Maintenance"}) -"czp" = (/obj/structure/table,/obj/item/clothing/gloves/color/latex,/obj/item/clothing/mask/surgical,/obj/item/weapon/surgicaldrill,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery) -"czq" = (/obj/structure/table,/obj/machinery/button/windowtint{pixel_x = 25},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery) +"czp" = (/obj/structure/table,/obj/item/weapon/surgicaldrill,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/item/weapon/FixOVein,/turf/simulated/floor/plasteel{icon_state = "whitehall"; dir = 2},/area/medical/surgery) +"czq" = (/obj/structure/table,/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/obj/item/weapon/bonesetter,/obj/item/weapon/bonegel,/turf/simulated/floor/plasteel,/area/medical/surgery) "czr" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/medical,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery) "czs" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/medical,/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whiteblue"},/area/medical/patients_rooms{name = "Patient Room A"}) "czt" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/vending/wallmed1{pixel_x = 0; pixel_y = 28},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/patients_rooms{name = "Patient Room A"}) @@ -6741,7 +6741,7 @@ "czG" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel,/area/hallway/primary/aft) "czH" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/hallway/primary/aft) "czI" = (/obj/structure/sign/directions/evac{pixel_y = 0},/turf/simulated/wall,/area/maintenance/aft{name = "Aft Maintenance"}) -"czJ" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/effect/spawner/lootdrop{loot = list(/obj/structure/grille,/obj/structure/grille,/obj/structure/grille,/obj/structure/grille,/obj/structure/grille,/obj/item/weapon/cigbutt,/obj/item/trash/cheesie,/obj/item/trash/candy,/obj/item/trash/chips,/obj/item/trash/pistachios,/obj/item/trash/plate,/obj/item/trash/popcorn,/obj/item/trash/raisins,/obj/item/trash/sosjerky,/obj/item/trash/syndi_cakes); name = "maint grille or trash spawner"},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) +"czJ" = (/obj/structure/table,/obj/item/weapon/retractor,/obj/item/weapon/hemostat,/turf/simulated/floor/plasteel,/area/medical/surgery) "czK" = (/obj/item/weapon/storage/toolbox/emergency,/obj/structure/closet/firecloset,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "czL" = (/obj/item/weapon/tank/air,/obj/item/weapon/tank/air,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/machinery/space_heater,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "czM" = (/turf/simulated/wall/r_wall,/area/toxins/misc_lab{name = "\improper Research Testing Range"}) @@ -6785,7 +6785,7 @@ "cAy" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin{pixel_x = -2; pixel_y = 6},/turf/simulated/floor/plasteel{icon_state = "bluefull"},/area/medical/genetics) "cAz" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/turf/simulated/floor/plasteel{icon_state = "blue"; dir = 8},/area/hallway/primary/aft) "cAA" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/hallway/primary/aft) -"cAB" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/plating{icon_plating = "warnplate"; icon_state = "warnplate"},/area/maintenance/aft{name = "Aft Maintenance"}) +"cAB" = (/obj/structure/table/glass,/obj/machinery/photocopier/faxmachine{department = "Chief Medical Officer's Office"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "barber"},/area/medical/cmo) "cAC" = (/obj/machinery/portable_atmospherics/canister/air,/obj/machinery/atmospherics/unary/portables_connector{dir = 8},/obj/effect/spawner/lootdrop/maintenance,/obj/item/weapon/wrench,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "cAD" = (/obj/structure/reagent_dispensers/watertank,/obj/item/weapon/storage/box/lights/mixed,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "cAE" = (/obj/structure/reagent_dispensers/fueltank,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) @@ -6796,7 +6796,7 @@ "cAJ" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research{name = "Research Division"}) "cAK" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitebluecorner"},/area/medical/research{name = "Research Division"}) "cAL" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/cable/yellow,/obj/machinery/door/poddoor/preopen{id_tag = "rdprivacy"; name = "privacy shutter"},/turf/simulated/floor/plating,/area/crew_quarters/hor) -"cAM" = (/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/obj/structure/table/reinforced,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/hor) +"cAM" = (/obj/structure/table,/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/obj/machinery/light{dir = 8},/obj/structure/window/reinforced/polarized{tag = "icon-rwindow (NORTH)"; icon_state = "rwindow"; dir = 1},/obj/item/weapon/bonesetter,/obj/item/weapon/bonegel,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery) "cAN" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/hor) "cAO" = (/obj/machinery/computer/mecha,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/hor) "cAP" = (/obj/structure/table,/obj/item/device/aicard,/obj/item/weapon/circuitboard/aicore{pixel_x = -2; pixel_y = 4},/obj/item/weapon/circuitboard/teleporter,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/hor) @@ -6906,7 +6906,7 @@ "cCP" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitebluecorner"},/area/medical/research{name = "Research Division"}) "cCQ" = (/obj/machinery/power/apc{dir = 2; name = "RD Office APC"; pixel_x = 0; pixel_y = -27},/obj/structure/cable/yellow,/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/obj/structure/flora/kirbyplants/dead,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/hor) "cCR" = (/obj/machinery/hologram/holopad,/obj/machinery/light,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = -32},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/hor) -"cCS" = (/obj/structure/table,/obj/item/weapon/cartridge/signal/toxins,/obj/item/weapon/cartridge/signal/toxins{pixel_x = -4; pixel_y = 2},/obj/item/weapon/cartridge/signal/toxins{pixel_x = 4; pixel_y = 6},/obj/machinery/camera{c_tag = "Research Director's Office"; dir = 1; network = list("SS13","RD")},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/hor) +"cCS" = (/obj/structure/table,/obj/item/weapon/retractor,/obj/machinery/light{dir = 4},/obj/structure/window/reinforced/polarized{tag = "icon-rwindow (NORTH)"; icon_state = "rwindow"; dir = 1},/obj/item/weapon/hemostat,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery) "cCT" = (/obj/structure/closet/secure_closet/RD,/obj/machinery/keycard_auth{pixel_x = 0; pixel_y = -24},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/hor) "cCU" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/obj/machinery/computer/security/telescreen/entertainment{pixel_x = 0; pixel_y = -32},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/hor) "cCV" = (/obj/structure/filingcabinet/chestdrawer,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/hor) @@ -7328,7 +7328,7 @@ "cKV" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "12;5;39;6"},/obj/structure/disposalpipe/segment,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "cKW" = (/turf/simulated/floor/plasteel{dir = 6; icon_state = "whitehall"},/area/medical/medbay3{name = "Medbay Aft"}) "cKX" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay3{name = "Medbay Aft"}) -"cKY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/plasteel{dir = 10; icon_state = "whitehall"},/area/medical/medbay3{name = "Medbay Aft"}) +"cKY" = (/obj/machinery/computer/security/telescreen{desc = "Used for monitoring medbay to ensure patient safety."; dir = 8; name = "Medbay Monitor"; network = list("Medbay"); pixel_x = 29; pixel_y = 0},/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = -29},/obj/item/weapon/paper_bin{pixel_x = -2; pixel_y = 5},/obj/structure/table/glass,/obj/item/weapon/stamp/cmo,/turf/simulated/floor/plasteel{dir = 8; icon_state = "barber"},/area/medical/cmo) "cKZ" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitecorner"},/area/medical/medbay3{name = "Medbay Aft"}) "cLa" = (/obj/item/device/healthanalyzer{pixel_x = 1; pixel_y = 4},/obj/structure/sign/nosmoking_2{pixel_x = 0; pixel_y = -30},/obj/structure/table/glass,/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitehall"},/area/medical/medbay3{name = "Medbay Aft"}) "cLb" = (/obj/machinery/vending/medical,/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitecorner"},/area/medical/medbay3{name = "Medbay Aft"}) @@ -7383,7 +7383,7 @@ "cLY" = (/obj/structure/flora/kirbyplants{icon_state = "plant-21"; layer = 4.1; pixel_x = -3; pixel_y = 3; tag = "icon-plant-21"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitegreencorner"},/area/medical/medbay3{name = "Medbay Aft"}) "cLZ" = (/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay3{name = "Medbay Aft"}) "cMa" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay3{name = "Medbay Aft"}) -"cMb" = (/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 9; icon_state = "whitehall"},/area/medical/medbay3{name = "Medbay Aft"}) +"cMb" = (/obj/structure/table,/obj/item/clothing/gloves/color/latex,/obj/item/clothing/mask/surgical,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery) "cMc" = (/obj/machinery/light/small,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/morgue) "cMd" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/morgue) "cMe" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/morgue) @@ -7431,9 +7431,9 @@ "cMU" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Virology Access"; req_access_txt = "39"},/turf/simulated/floor/plasteel{icon_state = "whitegreenfull"},/area/medical/medbay3{name = "Medbay Aft"}) "cMV" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay3{name = "Medbay Aft"}) "cMW" = (/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay3{name = "Medbay Aft"}) -"cMX" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitehall"},/area/medical/medbay3{name = "Medbay Aft"}) -"cMY" = (/obj/machinery/door/airlock{name = "Medical Surplus Storeroom"; req_access_txt = "5"},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) -"cMZ" = (/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/maintenance/aft{name = "Aft Maintenance"}) +"cMX" = (/obj/structure/table,/obj/machinery/button/windowtint{pixel_x = 25},/obj/item/weapon/surgicaldrill,/obj/item/weapon/FixOVein,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery) +"cMY" = (/obj/structure/disposalpipe/segment,/obj/effect/spawner/lootdrop{loot = list(/obj/structure/grille,/obj/structure/grille,/obj/structure/grille,/obj/structure/grille,/obj/structure/grille,/obj/item/weapon/cigbutt,/obj/item/trash/cheesie,/obj/item/trash/candy,/obj/item/trash/chips,/obj/item/trash/pistachios,/obj/item/trash/plate,/obj/item/trash/popcorn,/obj/item/trash/raisins,/obj/item/trash/sosjerky,/obj/item/trash/syndi_cakes); name = "maint grille or trash spawner"},/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) +"cMZ" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 5; icon_state = "intact"},/turf/simulated/floor/plating{icon_plating = "warnplate"; icon_state = "warnplate"},/area/maintenance/aft{name = "Aft Maintenance"}) "cNa" = (/obj/structure/table,/obj/machinery/light/small{dir = 1},/obj/item/weapon/storage/backpack/duffel/medical,/obj/item/device/flashlight/pen{pixel_x = 4; pixel_y = 3},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/maintenance/aft{name = "Aft Maintenance"}) "cNb" = (/obj/structure/table,/obj/item/weapon/retractor,/obj/item/weapon/hemostat,/obj/item/device/healthanalyzer,/obj/item/clothing/glasses/eyepatch,/obj/item/weapon/reagent_containers/food/drinks/bottle/vodka{pixel_x = 3; pixel_y = 2},/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/maintenance/aft{name = "Aft Maintenance"}) "cNc" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/airlock/maintenance{name = "Morgue Maintenance"; req_access_txt = "6"},/turf/simulated/floor/plating,/area/medical/morgue) @@ -7548,7 +7548,7 @@ "cPh" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor/bluegrid{icon_state = "dark"; name = "Server Walkway"; nitrogen = 500; oxygen = 0; temperature = 80},/area/toxins/server{name = "\improper Research Division Server Room"}) "cPi" = (/obj/effect/landmark{name = "blobstart"},/obj/machinery/light/small{dir = 4},/obj/machinery/alarm/server{dir = 8; pixel_x = 22; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/visible{dir = 4; initialize_directions = 11},/turf/simulated/floor/bluegrid{icon_state = "dark"; name = "Server Walkway"; nitrogen = 500; oxygen = 0; temperature = 80},/area/toxins/server{name = "\improper Research Division Server Room"}) "cPj" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) -"cPk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) +"cPk" = (/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/obj/structure/table/reinforced,/obj/item/weapon/cartridge/signal/toxins{pixel_x = 4; pixel_y = 6},/obj/item/weapon/cartridge/signal/toxins{pixel_x = 4; pixel_y = 6},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/hor) "cPl" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating{tag = "icon-panelscorched"; icon_state = "panelscorched"},/area/maintenance/aft{name = "Aft Maintenance"}) "cPm" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/maintenance/aft{name = "Aft Maintenance"}) "cPn" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = -32},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/maintenance/aft{name = "Aft Maintenance"}) @@ -7566,11 +7566,11 @@ "cPz" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/space_heater,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "cPA" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/closet/crate,/obj/item/clothing/gloves/color/fyellow,/obj/item/weapon/wrench,/obj/effect/spawner/lootdrop/maintenance{lootcount = 2; name = "2maintenance loot spawner"},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "cPB" = (/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/structure/closet/firecloset,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) -"cPC" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/screwdriver{pixel_y = 6},/obj/item/weapon/crowbar,/obj/item/weapon/storage/pill_bottle,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) +"cPC" = (/obj/structure/table,/obj/machinery/camera{c_tag = "Research Director's Office"; dir = 1; network = list("SS13","RD")},/obj/machinery/photocopier/faxmachine{department = "Research Director's Office"},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/hor) "cPD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/item/weapon/cigbutt,/turf/simulated/floor/plating{tag = "icon-platingdmg1"; icon_state = "platingdmg1"},/area/maintenance/aft{name = "Aft Maintenance"}) "cPE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/effect/decal/cleanable/generic,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/maintenance/aft{name = "Aft Maintenance"}) "cPF" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/airlock/maintenance{name = "Medical Surplus Storeroom"; req_access_txt = "12"; req_one_access_txt = "0"},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) -"cPG" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor/plating{dir = 8; icon_state = "warnplate"; tag = ""},/area/maintenance/aft{name = "Aft Maintenance"}) +"cPG" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/screwdriver{pixel_y = 6},/obj/item/weapon/crowbar,/obj/item/weapon/storage/pill_bottle,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/maintenance/aft{name = "Aft Maintenance"}) "cPH" = (/obj/structure/closet/firecloset,/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cPI" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cPJ" = (/obj/machinery/computer/arcade,/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) @@ -7626,7 +7626,7 @@ "cQH" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cQI" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cQJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) -"cQK" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/item/device/radio/intercom{pixel_y = 25},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) +"cQK" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "cQL" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cQM" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cQN" = (/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/plasteel{dir = 5; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) @@ -7656,7 +7656,7 @@ "cRl" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "cRm" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "cRn" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/junction{dir = 8; icon_state = "pipe-j2"},/turf/simulated/floor/plating{icon_state = "warnplate"},/area/maintenance/aft{name = "Aft Maintenance"}) -"cRo" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/effect/spawner/lootdrop{loot = list(/obj/structure/grille,/obj/structure/grille,/obj/structure/grille,/obj/structure/grille,/obj/structure/grille,/obj/item/weapon/cigbutt,/obj/item/trash/cheesie,/obj/item/trash/candy,/obj/item/trash/chips,/obj/item/trash/pistachios,/obj/item/trash/plate,/obj/item/trash/popcorn,/obj/item/trash/raisins,/obj/item/trash/sosjerky,/obj/item/trash/syndi_cakes); name = "maint grille or trash spawner"},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) +"cRo" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11},/turf/simulated/floor/plasteel{dir = 10; icon_state = "whitehall"},/area/medical/medbay3{name = "Medbay Aft"}) "cRp" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating{tag = "icon-platingdmg2"; icon_state = "platingdmg2"},/area/maintenance/aft{name = "Aft Maintenance"}) "cRq" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/maintenance/aft{name = "Aft Maintenance"}) "cRr" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "12;5;39;6"},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) @@ -7688,7 +7688,7 @@ "cRR" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/starboardsolar) "cRS" = (/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/obj/machinery/power/smes,/turf/simulated/floor/plating,/area/maintenance/starboardsolar) "cRT" = (/obj/docking_port/stationary{dir = 2; dwidth = 2; height = 18; id = "skipjack_sw"; name = "southwest of SS13"; width = 19},/turf/space,/area/space) -"cRU" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/turf/simulated/wall/r_wall,/area/medical/virology) +"cRU" = (/turf/simulated/wall,/area/medical/psych) "cRV" = (/obj/machinery/alarm{dir = 4; pixel_x = -23; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plasteel{dir = 10; icon_state = "whitegreen"},/area/medical/virology) "cRW" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor/plasteel{icon_state = "whitegreen"},/area/medical/virology) "cRX" = (/obj/structure/stool,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "whitegreen"},/area/medical/virology) @@ -7701,7 +7701,7 @@ "cSe" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/chapel/office) "cSf" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/chapel/office) "cSg" = (/obj/machinery/door/morgue{name = "Relic Closet"; req_access_txt = "22"},/turf/simulated/floor/plasteel{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/chapel/office) -"cSh" = (/obj/structure/table/woodentable,/obj/item/weapon/spellbook/oneuse/smoke{name = "mysterious old book of "},/obj/item/weapon/reagent_containers/food/drinks/bottle/holywater{name = "flask of holy water"; pixel_x = -2; pixel_y = 2},/obj/item/weapon/nullrod{pixel_x = 4},/obj/item/organ/heart,/obj/item/device/soulstone,/turf/simulated/floor/plasteel{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/chapel/office) +"cSh" = (/obj/structure/table/woodentable,/obj/item/weapon/spellbook/oneuse/smoke{name = "mysterious old book of "},/obj/item/weapon/reagent_containers/food/drinks/bottle/holywater{name = "flask of holy water"; pixel_x = -2; pixel_y = 2},/obj/item/weapon/nullrod{pixel_x = 4},/obj/item/organ/internal/heart,/obj/item/device/soulstone,/turf/simulated/floor/plasteel{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/chapel/office) "cSi" = (/obj/machinery/door/airlock/maintenance{name = "Chapel Maintenance Access "; req_access_txt = "0"; req_one_access_txt = "12;27"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "cSj" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/camera{c_tag = "Departure Lounge - Port Fore"; dir = 4; network = list("SS13")},/obj/structure/flora/kirbyplants{icon_state = "plant-24"; layer = 4.1; tag = "icon-plant-24"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cSk" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel,/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) @@ -7721,8 +7721,8 @@ "cSy" = (/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/light/small{dir = 4},/obj/item/device/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29},/turf/simulated/floor/plating,/area/maintenance/starboardsolar) "cSz" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/floor/plating/airless,/area/space) "cSA" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating/airless,/area/space) -"cSB" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plating/airless,/area/space) -"cSC" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/medical/virology) +"cSB" = (/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 9; icon_state = "whitehall"},/area/medical/medbay3{name = "Medbay Aft"}) +"cSC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/airlock/medical{name = "Psych Office"; req_access_txt = "64"},/turf/simulated/floor/wood,/area/medical/psych) "cSD" = (/obj/machinery/atmospherics/unary/tank/air{dir = 1},/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/medical/virology) "cSE" = (/obj/machinery/atmospherics/unary/portables_connector{dir = 1; name = "virology air connector port"},/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/medical/virology) "cSF" = (/obj/item/trash/popcorn,/obj/structure/table/glass,/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/medical/virology) @@ -7934,9 +7934,9 @@ "cWD" = (/turf/simulated/floor/plasteel{dir = 6; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cWE" = (/obj/machinery/shower{tag = "icon-shower (EAST)"; icon_state = "shower"; dir = 4},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/toxins/xenobiology{name = "\improper Secure Lab"}) "cWF" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/xenobiology{name = "\improper Secure Lab"}) -"cWG" = (/obj/structure/closet/l3closet/scientist,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/camera{c_tag = "Secure Lab - Airlock"; dir = 8; network = list("SS13","RD")},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/toxins/xenobiology{name = "\improper Secure Lab"}) -"cWH" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/toxins/xenobiology{name = "\improper Secure Lab"}) -"cWI" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 8; pixel_y = 1},/turf/simulated/floor/plating/airless,/area/space) +"cWG" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitehall"},/area/medical/medbay3{name = "Medbay Aft"}) +"cWH" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/stool/bed/chair/comfy/beige{dir = 4},/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/effect/landmark/start{name = "Psychiatrist"},/turf/simulated/floor/wood,/area/medical/psych) +"cWI" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/light_switch{pixel_x = 0; pixel_y = 24},/turf/simulated/floor/wood,/area/medical/psych) "cWJ" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = "90Curve"},/turf/simulated/floor/plating/airless/catwalk,/area/solar/starboard) "cWK" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating/airless/catwalk,/area/solar/starboard) "cWL" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plating/airless/catwalk,/area/solar/starboard) @@ -8020,7 +8020,7 @@ "cYl" = (/obj/structure/window/reinforced{dir = 4},/obj/machinery/driver_button{id_tag = "chapelgun"; name = "Chapel Mass Driver"; pixel_x = -4; pixel_y = -26},/obj/structure/table/woodentable,/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/chapel/main) "cYm" = (/turf/simulated/floor/plating{icon_state = "warnplate"},/area/chapel/main) "cYn" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/machinery/door/poddoor/preopen{id_tag = "chapelspaceshutters"; name = "chapel shutters"},/turf/simulated/floor/plating,/area/chapel/main) -"cYo" = (/obj/structure/sink{dir = 8; icon_state = "sink"; pixel_x = -12; tag = "icon-sink (WEST)"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitepurple"},/area/toxins/xenobiology{name = "\improper Secure Lab"}) +"cYo" = (/obj/structure/table/woodentable,/obj/machinery/computer/med_data/laptop,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/wood,/area/medical/psych) "cYp" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/xenobiology{name = "\improper Secure Lab"}) "cYq" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/xenobiology{name = "\improper Secure Lab"}) "cYr" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/xenobiology{name = "\improper Secure Lab"}) @@ -8324,6 +8324,32 @@ "ded" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/dye_generator,/turf/simulated/floor/plasteel{dir = 8; icon_state = "barber"},/area/civilian/barber) "dee" = (/obj/machinery/cryopod/right,/obj/machinery/light{dir = 8},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/fitness{name = "\improper Recreation Area"}) "def" = (/obj/machinery/cryopod,/obj/machinery/light{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/fitness{name = "\improper Recreation Area"}) +"deg" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "psychoffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/psych) +"deh" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/wood,/area/medical/psych) +"dei" = (/turf/simulated/floor/wood,/area/medical/psych) +"dej" = (/obj/structure/closet/secure_closet/psychiatrist,/obj/machinery/light/small{dir = 4},/turf/simulated/floor/wood,/area/medical/psych) +"dek" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/carpet,/area/medical/psych) +"del" = (/obj/structure/stool/bed/chair/comfy/beige,/obj/machinery/door_control{id = "psychoffice"; name = "Privacy Shutters Control"; pixel_x = -25; pixel_y = 0},/turf/simulated/floor/carpet,/area/medical/psych) +"dem" = (/obj/machinery/power/apc{dir = 4; name = "Psychiatrist APC"; pixel_x = 25},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/obj/structure/flora/kirbyplants{tag = "icon-plant-25"; icon_state = "plant-25"},/turf/simulated/floor/carpet,/area/medical/psych) +"den" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) +"deo" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/carpet,/area/medical/psych) +"dep" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp/green,/turf/simulated/floor/carpet,/area/medical/psych) +"deq" = (/obj/structure/stool/psychbed,/turf/simulated/floor/carpet,/area/medical/psych) +"der" = (/obj/machinery/door/airlock/maintenance{name = "Medbay Maintenance"; req_access_txt = "5"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/medical/psych) +"des" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atm{pixel_y = 32},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) +"det" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/effect/spawner/lootdrop{loot = list(/obj/structure/grille,/obj/structure/grille,/obj/structure/grille,/obj/structure/grille,/obj/structure/grille,/obj/item/weapon/cigbutt,/obj/item/trash/cheesie,/obj/item/trash/candy,/obj/item/trash/chips,/obj/item/trash/pistachios,/obj/item/trash/plate,/obj/item/trash/popcorn,/obj/item/trash/raisins,/obj/item/trash/sosjerky,/obj/item/trash/syndi_cakes); name = "maint grille or trash spawner"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 2},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/aft{name = "Aft Maintenance"}) +"deu" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/wall/r_wall,/area/medical/virology) +"dev" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9},/turf/simulated/floor/plating,/area/medical/virology) +"dew" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/turf/simulated/floor/plating/airless,/area/space) +"dex" = (/obj/structure/table,/obj/item/candle,/obj/item/device/radio/intercom{pixel_y = 25},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) +"dey" = (/obj/machinery/atmospherics/unary/outlet_injector/on{dir = 1},/turf/simulated/floor/plating/airless,/area/space) +"dez" = (/obj/structure/closet/l3closet/scientist,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/camera{c_tag = "Secure Lab - Airlock"; dir = 8; network = list("SS13","RD")},/obj/machinery/atmospherics/pipe/simple/hidden/universal{dir = 4},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/toxins/xenobiology{name = "\improper Secure Lab"}) +"deA" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; level = 1},/turf/simulated/wall/r_wall,/area/toxins/xenobiology{name = "\improper Secure Lab"}) +"deB" = (/obj/structure/sink{dir = 8; icon_state = "sink"; pixel_x = -12; tag = "icon-sink (WEST)"},/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitepurple"},/area/toxins/xenobiology{name = "\improper Secure Lab"}) +"deC" = (/obj/machinery/door/airlock{icon = 'icons/obj/doors/doorint.dmi'; name = "Starboard Emergency Storage"; req_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/starboard) +"deD" = (/obj/structure/sign/directions/evac,/obj/structure/sign/directions/medical{pixel_y = 8},/obj/structure/sign/directions/science{pixel_y = -8},/turf/simulated/wall,/area/library) +"deE" = (/obj/structure/sign/directions/medical{dir = 4; pixel_y = 8},/obj/structure/sign/directions/evac{dir = 4},/obj/structure/sign/directions/science{dir = 4; pixel_y = -8},/turf/simulated/wall/r_wall,/area/ai_monitored/storage/eva{name = "E.V.A. Storage"}) +"deF" = (/obj/structure/sign/directions/medical{dir = 8; pixel_y = 8},/obj/structure/sign/directions/evac{dir = 8},/obj/structure/sign/directions/science{dir = 8; pixel_y = -8},/turf/simulated/wall,/area/maintenance/maintcentral{name = "Central Maintenance"}) (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -8400,123 +8426,123 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaabqaaaabqaaaaaaaaaabAaaaaaaabqaaaacAafOafPafQafRafSafTafUadsafVafyafWafXafYacQafZadsagaacQagbacQagcagdageacgagfabqaaaaaaaaaabqaaaaaaaaaabqaaaaaaaaaaaaaaaabqaaaaaaaaaaaaabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqafcaggaghagiagjagkaaaabeabfabeabqabqaaaaaaaaaaaaaaaaaaaaaaaaabfabqaegaegaegaegaegabqadFabqaegaegaegaegaegabqabfaaaaaaaeFafJaeFaeFaeFaeFaeFaeFaeFaglaeFaeFaeFaeFaeFaeFaeFafJaeFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqaaaaaaaaaaaaabqaaaabqabqabAabqabqabqabqacAagmagnagoagpagqafTagradsagsagtaguagvagwacQagxadsagwacQaeaacQagyagzagAacgaaaabqabqagBagBagBagBagBaaaabqaaaaaaagCagCagDagEagFagCagCaaaabqaaaaaaabqaaaaaaaaaabqaaaaaaaaaabqaaaaaaaaaaaaabqaaaaaaaaaaaaafbagGagHafHafHagIaaaabqaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaabeaaaaaaaaaabqaaaaaaaaaadFaaaaaaaaaabqaaaaaaaaaabdaaaaaaafhafJagJagJagJagJagJagJaehagKaehagJagJagJagJagJagJafJafkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaabqabqaaaabqaaaabqagLagMagLabqaaaaaaacAagNagOagPacAagQafTagRagSacQafyacQagTafyacQagRagUafyacQaeBacQafyagVagRacgabqabqagBagBagWagXagYagBagBabqabqagCagCagZahaahbahcahdagCagCabqaheaheahfaheaheabqabqabqabqafbafcafbafcafcafcafbafcafcafcafbafbahgafbahhahiahiahjahiahiahkaaaabqaaaaaaaaaaaaaaaaaaaaaaaaabfaaaadjadjadjadjadjabqahlabqadjadjadjadjadjabqabfaaaaaaahmahnahoahpahqahraehaglaeFaglaeFaglaehahsahtahuahvahnahwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaabqaaaaaaabqabqabqagLahxagLabqabqaaaacAacAacAacAacAahyahzahAahBahCahDahEahFahGahHahIahJahKahLahMahNahOahPahQahRabqagBagBahSahTahUahUahVagBagBabqagCahWahXahYahZaiaaibaicagCabqaheaidaieaifaheaaaaaaaaaabqafbaigafbaihaiiaijafbaikailaimafbainaioaipaiqairairairairairaiqabqabqabqabqabqaaaaaaaaaaaaaaaabfabqadCadDadDadDadDadEadFadGadHadHadHadHadIabqabfaaaaaaafKahnaeGaeGaeGaisaehaeGaeGaeGaeGaeGaehaeGaeGaitaeGahnafNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqabqabqabqabqabqabqabqagLagLaiuagLagLabqabqabqabqabqabqacnaivaiwaixaiyaizaiAaiBaiwaiCaiDaiEaiFaiGaiHaiwaiIaiJaiKaiLaiMabqagBaiNaiOaiPaiQaiRaiSaiTagBabqaiUaiVaiWaiXaiYaiZajaajbajcabqahfajdajeajfahfaaaajgajgajgafbajhajiajjajkajkajlajkajmajnajoajpajpajpaiqairairairairairaiqaaaaaaaaaaaaabqaaaaaaaaaaaaaaaabfabqaegaegaegaegaegabqadFabqaegaegaegaegaegabqabeabqaaaaehajqajrajsajtajuaehajvaeGaeGaeGajwaehajxajyajzajAajqaehaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaabqaaaaaaaaaaaaaaaabqajBajCajDajEajBaaaabqaaaaaaaaaabqacgacgajFajGajHacgajIajJajIacQacQacQacQajKajLajMajNajOajPajQacgabqagBajRaiOajSajTajUaiSajVagBabqajWajXajYajZakaakbajYakcajWabqaheajdakdajfaheajgajgakeakfafbafbafbakgakhakiakiakjakkaklakmakmaknakoaiqairairairairairakpafbafbafbaaaabqaaaaaaaaaaaaaaaabeaaaaaaaaaabqaaaaaaaaaadFaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaehakqakqaeFaeFaeFaehakraeGaeGaeGaksaehaeFaeFaeFakqakqaehaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaabqaaaaaaabqabqabqagLahxagLabqabqaaaacAacAacAacAacAahyahzahAahBahCahDahEahFahGahHahIahJahKahLahMahNahOahPahQahRabqagBagBahSahTahUahUahVagBagBabqagCahWahXahYahZaiaaibaicagCabqaheaidaieaifaheaaaaaaaaaabqafbaigafbaihaiiaijafbaikailaimafbainaioajbaiqairairairairairaiqabqabqabqabqabqaaaaaaaaaaaaaaaabfabqadCadDadDadDadDadEadFadGadHadHadHadHadIabqabfaaaaaaafKahnaeGaeGaeGaisaehaeGaeGaeGaeGaeGaehaeGaeGaitaeGahnafNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqabqabqabqabqabqabqabqagLagLaiuagLagLabqabqabqabqabqabqacnaivaiwaixaiyaizaiAaiBaiwaiCaiDaiEaiFaiGaiHaiwaiIaiJaiKaiLaiMabqagBaiNaiOaiPaiQaiRaiSaiTagBabqaiUaiVaiWaiXaiYaiZajaakcajcabqahfajdajeajfahfaaaajgajgajgafbajhajiajjajkajkajlajkajmajnajoajpajpajpaiqairairairairairaiqaaaaaaaaaaaaabqaaaaaaaaaaaaaaaabfabqaegaegaegaegaegabqadFabqaegaegaegaegaegabqabeabqaaaaehajqajrajsajtajuaehajvaeGaeGaeGajwaehajxajyajzajAajqaehaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaabqaaaaaaaaaaaaaaaabqajBajCajDajEajBaaaabqaaaaaaaaaabqacgacgajFajGajHacgajIajJajIacQacQacQacQajKajLajMajNajOajPajQacgabqagBajRaiOajSajTajUaiSajVagBabqajWajXajYajZakaakbajYanJajWabqaheajdakdajfaheajgajgakeakfafbafbafbakgakhakiakiakjakkaklakmakmaknakoaiqairairairairairakpafbafbafbaaaabqaaaaaaaaaaaaaaaabeaaaaaaaaaabqaaaaaaaaaadFaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaehakqakqaeFaeFaeFaehakraeGaeGaeGaksaehaeFaeFaeFakqakqaehaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqabqaktaktakuakuakuakuakuajBakvakwakxajBakyakzakyakyaaaabqaaaacgacgaiMacgacgacgaiMacgacgakAakBakCakDakEakFakGakHakHakHagBagBagBakIakJakKakLakMakNakOagBabqagCakPakQakRakSakTakUakVagCabqaheajdakdajfaheakWajgakXakYakZalaafbalbakhakialcaldaldaldaleakmalfalgalhairairairairairalialjalkafcaaaabqabqabqabqabqabqabfabqabqabqabqabqaaaaaaadFaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaflallallafgaaaaaaaehalmaeGaeGaeGalnaehaaaaaaaflallallafgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaloalpakualqalralsaltajBalualvalwajBalxalyalzakyakyabqaaaaaaaaaabqaaaaaaaaaabqabqalAalBalCalBalDalEalFalGakHalHalIalJagBagBagBalKalLagBagBagBagBagBalMagCagCalNalOalPalQalRagCagCalMalSalTalUalVaheajgajgalWalWalXalYafbalZakhamaambamcamcamdameamfamgamhafcairairairairairafcamiamjafcaaaabqaaaabqaaaamkamkamkamkamkamkamkabqabqabqadFabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaehamlaeGaeGaeGalnaehaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqaktammaktamnamoampamqajBajBamramsajBamtamuamvamwakyabqabqabqabqabqabqabqabqabqabqamxakDakDakDakDamyamzamAakHamBamCamDagBamEamFamGamHamIamJamKamLagBamMamNamOamPamQamRamSamTamOamUamValSamWamXamYaheamZalWalWanaalWajgafbanbancandaneanfanfangameamjanhamhafcairairairairairafcanianjafcabqabqabqabqabqamkankanlanmannankamkabqaaaanoanpanoanqanransansanqabqabeabqaaaaaaaaaaaaaaaaaaaaaaehantanuaglantanuaehaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaakuanvanwanxanyanzanAanBanCanDanEakyanFanGanHanIakzabqaaaaaaabqaaaaaaaaaajgajgajgamxanJanKanLanManNanOanPakHanQamCanRagBanSanTanUanVanWanXanYanZaoaaobaocaodaoeaofaogaohaoiaojaokaolaomaonaooaopaheaoqaoraosaotaouajgaovaowakhaoxambaoyamcaozameaoAamgaoBaoCairairairairairaoDaoEaoFaoGaoHaoGaaaabqaaaamkaoIaoJankaoJaoKamkabqaaaaoLaoMaoLanqaoNaoNaoNanqaaaabfaaaaaaaaaaaaaaaaaaaaaaaaaehaoOaoPaeGaoQaoRaehaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaktaoSaktaoTaoUaoVaoWaktaoXaoYaoZapaapbapcapdapeakyabqapfapfakzapfapfaaaajgapgapgamxaphapiapjapkaplapmapnapoappapqappaprapsapsaptapuapvapwapxapxapyapzapAapBapCapDapEapFapGapHapIapJapKapLapMapNaheapOapPalWapQapRajgapSaowakhajpapTapUapVapWapXapYamgapZaqaairairairairairaqbafbaqcaoGaqdaqeaefaefabqamkaqfaqgaqhaqiaqjamkabqanoaoLaqkaoLanqaqlaoNaoNanqaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaehaqmaqnaeGaqoaqpaehaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqaktaqqaqraqraqraqsaqtaktaquaqvaqwakyaqxaqyaqzaqAakyapfapfaqBaqCanEapfajgajgaqDaqEamxaqFaqGaqHaqIaqJaqKaqLakHaqMaqNaqOagBaqPaqQaqRaqSaqTaqUaqVaqWakHaqXaqYaqZapCaraarbarcardarearfargalSalSarhaheaheajgariajgarjajgajgafbarkarlajpajparmarnaroarparparqapZaqaairairairairairaqbarrarsaoGaqeaoGaoGaoHaoGamkartaruankarvarwamkabqaoLaoLaoMaoLanqaoNaoNaoNanqaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaflaeFarxaryarzaeFafgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarAarBaaaaaaarAaaaarAaaaaaaabqabqabqaaaaaaaaaaaaaaaabqaaaabqaaaabqaaaaktarCarDarEarFarGarHaktanHaqvapdapfarIapdapdapdarJapfarKarLarMarNapfarOarParQarRarSarTarUarVarWarXarYarZagBamIasaamIagBagBasbascasbagBasdaseasfasgashaqYasiasjaskaslasmasnasoarfaspasqasrassastasuastasvaswasxasyaszaszasAasBasCasCasDasEasFasGasGasGasHaqaairairairairairaqbasIasJaoGarsasKasLasMasNamkasOasPasQasRasSamkabqasTasUasVasWanqasXasYasZanqaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaflaeFaeFaeFafgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarAarAabqabqarAarAarAabqaaaarAarAataarAarAaaaabqapfapfakzapfabqaaaabqabqabqabqabqapfakzaktaktatbatcatdaktaktaktapdateaoZatfapbatgathapdatiapfaoXatjatkapfapfatlatmatnatoamxamxamxakDakDatpatqatratsattatuatvatwatxatyaqUatzagBaqUanYatAakHatBaqYatCatDatEatFatGatHatIarfatJatKatKamOamOamOamOatLafbafcatMafcafbatNatOatPatQatRatSatTatUatVatWatXatYatZatZatZatZatZauaaubaucaoGasJasJasJasJaudamkaueaufaugauhauiamkabqasTaujaukaulanqaumaunauoanqaaaabqabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaupabqarAabqaupabqarAarAabqarAarAarAarAarAaaaaaaaaaapfauqaurapfausautautautautautauuapfarKauvapfauwauxaoXauyauzapfauAauBauCapfarIatjauDauEauFapfauGathauHapfauIatmakeauJauKajgauLamxauMauNaqJatqapnauOauPauQauRauSauTauUauVauWauXaqUauYauZakHavaavbavcavdaveavfavgavhavgaviavjavkavlavlavmavnamOatLafbavoavpavqavravravravravravsavtavuavvavvavvavvavvavwaoGavxavyavzaoGaoGasJaoGavAavBavCasJavDavEavFavGavHavIavJamkaoHasTavKavLavManqavNavOavPanqaaaabqaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqaktammaktamnamoampamqajBajBamramsajBamtamuamvamwakyabqabqabqabqabqabqabqabqamxamxamxakDakDakDakDamyamzamAakHamBamCamDagBamEamFamGamHamIamJamKamLagBamMamNamOamPamQamRamSamTamOamUamValSamWamXamYaheamZalWalWanaanLajgafbanbancandaneanfanfangameamjanhamhafcairairairairairafcanianjafcabqabqabqabqabqamkankanlanmannankamkabqaaaanoanpanoanqanransansanqabqabeabqaaaaaaaaaaaaaaaaaaaaaaehantanuaglantanuaehaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaakuanvanwanxanyanzanAanBanCanDanEakyanFanGanHanIakzabqaaaaaaabqaaaajgajgajgamxaotaovaouanKaphanManNanOanPakHanQamCanRagBanSanTanUanVanWanXanYanZaoaaobaocaodaoeaofaogaohaoiaojaokaolaomaonaooaopaheaoqaoraosapiapQajgapRaowakhaoxambaoyamcaozameaoAamgaoBaoCairairairairairaoDaoEaoFaoGaoHaoGaaaabqaaaamkaoIaoJankaoJaoKamkabqaaaaoLaoMaoLanqaoNaoNaoNanqaaaabfaaaaaaaaaaaaaaaaaaaaaaaaaehaoOaoPaeGaoQaoRaehaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaktaoSaktaoTaoUaoVaoWaktaoXaoYaoZapaapbapcapdapeakyabqapfapfakzapfapfapgapgamxapSaqGaqFaqHapjapkaplapmapnapoappapqappaprapsapsaptapuapvapwapxapxapyapzapAapBapCapDapEapFapGapHapIapJapKapLapMapNaheapOapPalWarMarOajgaipaowakhajpapTapUapVapWapXapYamgapZaqaairairairairairaqbafbaqcaoGaqdaqeaefaefabqamkaqfaqgaqhaqiaqjamkabqanoaoLaqkaoLanqaqlaoNaoNanqaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaehaqmaqnaeGaqoaqpaehaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqaktaqqaqraqraqraqsaqtaktaquaqvaqwakyaqxaqyaqzaqAakyapfapfaqBaqCanEapfaqDaqEamxamxamxarParSarQaqIaqJaqKaqLakHaqMaqNaqOagBaqPaqQaqRaqSaqTaqUaqVaqWakHaqXaqYaqZapCaraarbarcardarearfargalSalSarhaheaheajgariajgarjajgajgafbarkarlajpajparmarnaroarparparqapZaqaairairairairairaqbarrarsaoGaqeaoGaoGaoHaoGamkartaruankarvarwamkabqaoLaoLaoMaoLanqaoNaoNaoNanqaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaflaeFarxaryarzaeFafgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarAarBaaaaaaarAaaaarAaaaaaaabqabqabqaaaaaaaaaaaaaaaabqaaaabqaaaabqaaaaktarCarDarEarFarGarHaktanHaqvapdapfarIapdapdapdarJapfarKarUarTarNapfatAarWauHarRaBKazcaCTarVaCVarXarYarZagBamIasaamIagBagBasbascasbagBasdaseasfasgashaqYasiasjaskaslasmasnasoarfaspasqasrassastasuastasvaswasxasyaszaszasAasBasCasCasDasEasFasGasGasGasHaqaairairairairairaqbasIasJaoGarsasKasLasMasNamkasOasPasQasRasSamkabqasTasUasVasWanqasXasYasZanqaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaflaeFaeFaeFafgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarAarAabqabqarAarAarAabqaaaarAarAataarAarAaaaabqapfapfakzapfabqaaaabqabqabqabqabqapfakzaktaktatbatcatdaktaktaktapdateaoZatfapbatgathapdatiapfaoXaElaEjapfapfatlatmatnatoamxamxamxakDakDatpatqatratsattatuatvatwatxatyaqUatzagBaqUanYaFCakHatBaqYatCatDatEatFatGatHatIarfatJatKatKamOamOamOamOatLafbafcatMafcafbatNatOatPatQatRatSatTatUatVatWatXatYatZatZatZatZatZauaaubaucaoGasJasJasJasJaudamkaueaufaugauhauiamkabqasTaujaukaulanqaumaunauoanqaaaabqabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaupabqarAabqaupabqarAarAabqarAarAarAarAarAaaaaaaaaaapfauqaurapfausautautautautautauuapfarKauvapfauwauxaoXauyauzapfauAauBauCapfarIatjauDauEauFapfauGaNEaFEapfauIatmakeauJauKajgauLamxauMauNaqJatqapnauOauPauQauRauSauTauUauVauWauXaqUauYauZakHavaavbavcavdaveavfavgavhavgaviavjavkavlavlavmavnamOatLafbavoavpavqavravravravravravsavtavuavvavvavvavvavvavwaoGavxavyavzaoGaoGasJaoGavAavBavCasJavDavEavFavGavHavIavJamkaoHasTavKavLavManqavNavOavPanqaaaabqaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarAabqarAabqarAarAarAataabqabqabqarAarAabqaaaabqabqakzavQavRavSavTavUavUavUavUavUavVavWavXavYavZawaawbavUawcavUawdaweawfajgajgajgajgajgajgajgajgajgajgawgajgawhajgajgajgajgajgajgamxawiawjaqJatqatratsawkawlawmawnawoawpawqawraqTawsawtawuasgawvawwawxawyawzawAawBawCawDawEawFatKawGawHawGawIamOawJawKawLawMavqavrawNawOawPawQawRawSawTavvawUawVawWavvaoGaoGasJaubavBasIaoGasJaoGavzasJawXasJaoGawYawZamkamkaxaaxbamkaxcasTasTaxdaxeanqanqaxfanqanqaxgaxhaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarAarAarAarAarAabqarAarAabqauparAarAabqabqabqabqapfapfaxiapfapfaxjaxkaxkaxkaxkaxkaxlapfapfapfapfaxmaxnaxoaxoaxoaxoaxpaxqajgaxraxsaxtaxuaxvaxwaxxaxyaxzaxAaxBaxCajgaxDaxEaxEaxEaxFamzaxGaxHaqJaxIaxJaxKaqTaxLagBagBaxMaxNaxOasgagBaxPaxMakHakHamOaxQaxRaxSaxQamOaxTaxUamOaxVatKatKaxWaxWaxWamOamOaxXafbdeeaxZdefavrayaaybayaawQaycaydayeayfaygayhayiavvayjaoGaykaylaymaynaoGasMaoGaoGaoGayoaoGaoGaypayqayramkamkamkamkasMasIaysaytayuaxhayvaywayxaxharsaxhabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBabqarAarAarAarAarAarAarAarAarAarAarAayyarAabqaupapfapfapfayzayAapfabqabqabqabqabqabqabqabqabqabqabqapfaqBayBapdaoXayCaoXayDayEayFayGayHayIajgajgajgayJayKayKayKayLajgajgayMayNayOayPayMamzamzakDayQayRapnaySaySayTayUaySayVaySayUaySayWaySayVayXayYayZayUazaazbaySaySaySayUaySazcamxazdazeazeazeazeakDatLafbaxYavoavqavrazfazgazhavraziazjazkazlazmavvavvavvaznaoGasIazoawXasJaoGasJaoGazpaoGazqazrazsaztazuazvazwazxazyazzazAazBazyazCazDazDazEazFazGaxgazHaxgaefaefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBabqarAarAarAarAarAarAarAarAarAarAarAayyarAabqaupapfapfapfayzayAapfabqabqabqabqabqabqabqabqabqabqabqapfaqBayBapdaoXayCaoXayDayEayFayGayHayIajgajgajgayJayKayKayKayLajgajgayMayNayOayPayMamzamzakDayQayRapnaySaySayTayUaySayVaySayUaySayWaySayVayXayYayZayUazaazbaySaySaySayUaySaOPamxazdazeazeazeazeakDatLafbaxYavoavqavrazfazgazhavraziazjazkazlazmavvavvavvaznaoGasIazoawXasJaoGasJaoGazpaoGazqazrazsaztazuazvazwazxazyazzazAazBazyazCazDazDazEazFazGaxgazHaxgaefaefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaupabqarAataarAarAarAarAazIabqarAarAarAarAarAarAazJazKazJazLazMapfapfabqaaaaaaaaaaaaaaaaaaaaaaaaabqapfapfapfathaoXapdaoXazNazOazPazQazRazSajgaaaabqaaaaaaaaaaaaaaaabqaaaazTazUazVazWazXazYazeazZaAaaAbaAcaAdaAdaAeaAcaAdaAfaAgaAcaAhaAiaAdaAjaAkaAlaAdaAmaAnaAoaApaApaAqaAraAsaAtaAuaAvaAwaAxaAyaAzakDatLafbaxYaAAavqavraABaACaADaAEaAFaAGaAHavvaAIaAJaAKavvaALaoGaoGaoGayoaoGaoGasJaoGaucaoGaAMaxhaxhawYaANamkaxhaxhaxhaxhaxhaxhaxhaxhaxharraxhaxhaxhaxhaxhaAOaxhabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarAarAarAarAarAarAarAarAarAarAarAabqarAarAarAabqapfapfapfaAPazSapdapfaaaaAQaARaASaARaATabqabqabqabqapfaAUapfaAVavUavUavUaAWaAXapfaAYaAZaBaajgaaaaBbaBbaBbaBbaBbaBbaBbaaaayMaBcaBdaBeayMamzamzakDaBfaBgaBhaBiaBjaBkaBhaBlaBjaBgaBmaBnaBoaBpaBqaBraBsaBtaBuaBvaBwaBxaByaBwaBzaBAaBBaBCaBDaBEaBFaBGaBHakDatLaBIaBIaBIaBIavraBJaBKaBLaBMaBNaBOayeaBPaBQaBRaBSavvaBTaBUaBVaBWaBXaBWaBYaBWaBZaBWaBWaCaaCbaCcaCdaCeaCfaCgaChaCgaCiaCjaCkaCjaClaxhaxhaxhaCiaCjaClaCmaCmaCgabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqabqabqabqarAarAarAarAarAarAarAaCnarAabqabqabqabqapfaoXazSarIakzaaaaCoaCpaCqaCpaCoaCraCraCraCsaCsaCsaCsaCtaCsaCsaCuaCuaCuaCuaCvaCuaCwajgabqaBbaCxaCyaCzaCAaCBaBbaaaayMaCCaCCaCDayMaaaaaaaCEaCFaCGaCHakDaCFaCIaCHakDaCFaCJaCHakDaCKamzaCLakDamzaCMaCNamzamzaCOaCOaCPaCQaCRaCOaCOaCSakDakDakDakDakDatLaBIaCTaCUaCVavravravravravraCWaCXaCYazlazmavvavvavvaoGaCZasIarrasJasIaDaasJaxhaxhaxhaxhaxhaDbaDcaDdaDeaDfaDgaDfaDhaDiaDjaDiaDkaCjaDlaCjaDmaDiaDjaDiaCmaDnaDoabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBabqabqabqarAarAarAarAataarAarAarAaDparAarAarAarAabqaaaabqakzayBazSaqwapfaaaaASaDqaDraDqaASaCraDsaDtaCsaDuaDvaDwaDxaDyaCsaDzaDAaDBaDCaDDaCuaCwajgaaaaBbaDEaDFaDGaDHaDIaBbaaaazTaDJaCCaDKayMaDLaDLacAaDMaDNaDOakDaDPaDNaDOakDaDQaDNaDOakDaDRaDSaDTakDaDUaDVaDWaDXaDYaCOaDZaEaaEbaEcaEdaEeaCSaEfaEgaEgaEhaEgaEiaBIaEjaEkaElaBIaEmaEnaEmavvaEoaEpaEqaEraEsaEtaEuaEvaBWaEwaxhaxhaxhaxhaxhaxhaxhaExaExaEyaEzaEAaEBaECaEDaCgaCgaCgabqabqaEEaEFaDiaDiaDiaDiaDiaEGaEEaDiaEHaCgaCgaDoabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqarAarAarAarAarAarAarAabqarAabqabqarAarAabqabqapfapfauyazSapfapfaaaaCoaDqaDqaDqaEIaEJaEKaEKaELaEMaENaEOaEPaEQaERaESaETaEUaEVaEWaCuaCwajgaaaaBbaEXaEYaEZaFaaFbaBbaaaayMaFcaCCaCCaFdaFeaFfacAaFgaDNaFhakDaFgaDNaFiakDaFgaDNaFjakDaFkaFlaFmakDaFnaFoaFpaFqaFraCOaFsaFtaFuaFvaFwaFxaCSaFyaFzaFzaFzaFAaFBaBIaFCaFDaFEaBIaFFaFGaFGaFHaFIaFJaFKavvavvavvavvavvaoGaFLaxhaFMaFNaFOaFPaFQaFRaFSaFTaFTaFTaFTaFUaFVaFWaFXaFYaCgaFZabqabqaaaaaaaaaabqabqaaaaaaabqaaaarAaDiaCgaDoabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarAarAarAarAarAarAarAarAarAarAarAabqarAarAarAabqapfapfapfaAPazSapdapfaaaaAQaARaASaARaATabqabqabqabqapfaAUapfaAVavUavUavUaAWaAXapfaAYaAZaBaajgaaaaBbaBbaBbaBbaBbaBbaBbaaaayMaBcaBdaBeayMamzamzakDaBfaBgaBhaBiaBjaBkaBhaBlaBjaBgaBmaBnaBoaBpaBqaBraBsaBtaBuaBvaBwaBxaByaBwaBzaBAaBBaBCaBDaBEaBFaBGaBHakDatLaBIaBIaBIaBIavraBJaPWaBLaBMaBNaBOayeaBPaBQaBRaBSavvaBTaBUaBVaBWaBXaBWaBYaBWaBZaBWaBWaCaaCbaCcaCdaCeaCfaCgaChaCgaCiaCjaCkaCjaClaxhaxhaxhaCiaCjaClaCmaCmaCgabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqabqabqabqarAarAarAarAarAarAarAaCnarAabqabqabqabqapfaoXazSarIakzaaaaCoaCpaCqaCpaCoaCraCraCraCsaCsaCsaCsaCtaCsaCsaCuaCuaCuaCuaCvaCuaCwajgabqaBbaCxaCyaCzaCAaCBaBbaaaayMaCCaCCaCDayMaaaaaaaCEaCFaCGaCHakDaCFaCIaCHakDaCFaCJaCHakDaCKamzaCLakDamzaCMaCNamzamzaCOaCOaCPaCQaCRaCOaCOaCSakDakDakDakDakDatLaBIaQdaCUaQvavravravravravraCWaCXaCYazlazmavvavvavvaoGaCZasIarrasJasIaDaasJaxhaxhaxhaxhaxhaDbaDcaDdaDeaDfaDgaDfaDhaDiaDjaDiaDkaCjaDlaCjaDmaDiaDjaDiaCmaDnaDoabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBabqabqabqarAarAarAarAataarAarAarAaDparAarAarAarAabqaaaabqakzayBazSaqwapfaaaaASaDqaDraDqaASaCraDsaDtaCsaDuaDvaDwaDxaDyaCsaDzaDAaDBaDCaDDaCuaCwajgaaaaBbaDEaDFaDGaDHaDIaBbaaaazTaDJaCCaDKayMaDLaDLacAaDMaDNaDOakDaDPaDNaDOakDaDQaDNaDOakDaDRaDSaDTakDaDUaDVaDWaDXaDYaCOaDZaEaaEbaEcaEdaEeaCSaEfaEgaEgaEhaEgaEiaBIaRtaEkaRyaBIaEmaEnaEmavvaEoaEpaEqaEraEsaEtaEuaEvaBWaEwaxhaxhaxhaxhaxhaxhaxhaExaExaEyaEzaEAaEBaECaEDaCgaCgaCgabqabqaEEaEFaDiaDiaDiaDiaDiaEGaEEaDiaEHaCgaCgaDoabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqarAarAarAarAarAarAarAabqarAabqabqarAarAabqabqapfapfauyazSapfapfaaaaCoaDqaDqaDqaEIaEJaEKaEKaELaEMaENaEOaEPaEQaERaESaETaEUaEVaEWaCuaCwajgaaaaBbaEXaEYaEZaFaaFbaBbaaaayMaFcaCCaCCaFdaFeaFfacAaFgaDNaFhakDaFgaDNaFiakDaFgaDNaFjakDaFkaFlaFmakDaFnaFoaFpaFqaFraCOaFsaFtaFuaFvaFwaFxaCSaFyaFzaFzaFzaFAaFBaBIaTeaFDaThaBIaFFaFGaFGaFHaFIaFJaFKavvavvavvavvavvaoGaFLaxhaFMaFNaFOaFPaFQaFRaFSaFTaFTaFTaFTaFUaFVaFWaFXaFYaCgaFZabqabqaaaaaaaaaabqabqaaaaaaabqaaaarAaDiaCgaDoabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaarAarAarAarAarAabqabqabqarAarAarAabeaaaabqabqabqapfaGaaoXaoXaGbakzaaaaaaaASaDraDraDraASaCraGcaGdaGeaEMaEKaGfaGgaGhaCsaGiaGjaGkaGlaGmaCuaCwajgabqaBbaGnaGoaGpaGqaGraBbaaaayMaGsaGsaGsayMaDLaGtacAaGuaGvaGwamxaGuaGvaGwamxaGuaGvaGwamxaGxaGyaGzamxamxaCMaGAamxaGBaCOaGCaGDaGEaGFaGGaGHaCSaGIajgajgajgaGJajgaBIaGKaGLaBIaBIaGMaGNaGOaGPaGQaGRaGSazlaGTaGUawWavvaGVaGWaxhaGXaGYaGZaGZaHaaHbaDcaHcaHdaHeaHeaHeaHfaHgaHhaHiaHjaMIaMKaMJaOhaMJaMJaOhaMJaMJaOhaMJaMJaPwarAaCgaDoabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqabqabqabqabqabqabqabqabqabqabqabqabqaHkaHlaHkabfaaaabqaaaabqapfaHmaHnanEazSapfapfaaaaCoaHoaHpaHqaCoaCraCraCraCsaHraEKaHsaGgaHtaCsaHuaHvaHwaHxaHyaCuaCwajgaaaaBbaHzaHAaHBaHCaBbaBbaaaaHDaHEaHEaHEaHFaHGaHHaHGaHIaHJaHIaHKaHIaHJaHIaHLaHIaHJaHMaHNaHOaHPaHQaHRaHSaHTaHUamxazeaCSaHVaHWaHXaHYaHZaIaaCSaIbaBIaIcaIdaIeaIfaIfaIgaIhaIiaIjaIkaIlaImaInaIoaIpayeaIqaIraIsaItavvaucaGWaxhaIuaIvaIwaIxaIyaIzaIAaIBaICaIDaIDaIDaIEaIFaHhaHiaHjarAaPxarAaPyarAarAaPyarAarAaPyarAarAaPxarAaCgaDoabqaaaaaaaaaaaaaaaaaaaaaaaaaaDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaabqaaaaaaabqabqaaaaHkaIGaHkabqabqabqabqabqapfaIHapdapdaIIaIJapfaaaaIKaARaILaARaIMabqabqabqaCraINaIOaIPaIQaIRaCsaISaITaIUaIVaIWaCuaCwajgaaaabqaaaaIXaIYaIZaaaabqaaaaHGaDLaDLaDLaHGaHGaJaaJbaJcaJdaJeaJfaJgaJhaJhaJiaJhaJjaJgaJkaJlaJmaJnaJoaJpaJqaJramxazeaCSaCSaJsaJtaCSaJuaCSaCSaGIaBIaBIaBIaJvaJwaJxaJyaJzaJAaJBaJCaJDaJEaJFaJFaJGaJHavvavvavvavvavvaubaGWaxhaJIaJJaJKaJLaJMaJNaJOaJPaJQaJRaJSaJTaJUaJVaHhaHiaHjaHjaPxaJWaaaaaaaaaaaaaJWaaaaaaaJWarAaPxabqaCgaJXabqabqabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaabqaaaaaaaaaabqaaaaHkaHlaHkaHkaJYaJYaJYaHkaHkaHkaHkaHkaJZaKaapfaaaaaaaaaaaaaaaaaaaaaaaaabqaCraKbaKcaKdaKeaKfaCsaKgaKhaCuaCuaCuaCuaKiajgaKjaKkaKlaKmaKnaKoaKpaKqaKjaHGaKraKsaKsaKtaKuaKvaKwaKxaKyaKzaKAaKBaKCaKDaKEaKCaKFaKGaKHaKIaKJaKKaKLaKMaKNaKOamxazeaKPaCSaKQaKRaCSaKSaKTaKUaKVaBIaKWaKXaKYaKZaBIaLaaLbaLcaBIaLdaLeaLfaLgaLfaLhaLiaLjaLkaLlaLmavvasJaGWaxhaLnaLoaLpaLqaLraFRaLsaLtaJQaLuaCgaCgaLvaLwaCgaHjaHjaHjaPxaaaaaaaaaaaaaaaaLxaaaaaaaaaaTMaRgabqaCgaDoabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaabqaaaaaaaaaabqaaaaHkaHlaHkaHkaJYaJYaJYaHkaHkaHkaHkaHkaJZaKaapfaaaaaaaaaaaaaaaaaaaaaaaaabqaCraKbaKcaKdaKeaKfaCsaKgaKhaCuaCuaCuaCuaKiajgaKjaKkaKlaKmaKnaKoaKpaKqaKjaHGaKraKsaKsaKtaKuaKvaKwaKxaKyaKzaKAaKBaTiaKDaKEaKCaKFaKGaKHaKIaKJaKKaKLaKMaKNaKOamxazeaKPaCSaKQaKRaCSaKSaKTaKUaKVaBIaKWaKXaKYaKZaBIaLaaLbaLcaBIaLdaLeaLfaLgaLfaLhaLiaLjaLkaLlaLmavvasJaGWaxhaLnaLoaLpaLqaLraFRaLsaLtaJQaLuaCgaCgaLvaLwaCgaHjaHjaHjaPxaaaaaaaaaaaaaaaaLxaaaaaaaaaaTMaRgabqaCgaDoabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaabqaHkaHkaLyaLzaLAaLBaLBaLCaLDaLEaLFaLGaHkaHkazSapfaaaaLHaLIaLIaLIaLIaLIaLJabqaCsaCsaCsaLKaLLaCsaCsaLMaLNaLOaLPaLQaLRaLSaLTaLUaLVaLWaLXaLYaLWaLZaMaaMbaHGaMcaMdaMeaMfaMfaMgaMfaMfaMfaMfaMfaMfaMfaMfaMgaMfaMhaMiaMjaMkaMkaMkaMlaMlaMlaMlaMlaMkaMmaMkaMnaMnaMnaMnaMoaMnaGIaBIaBIaBIaMpaMqaBIaMraBIaMsaBIaMtaMuaMvazlaMwaMxaMyazlaMzaMAaMBavvaMCaMDaxhaCgaCgaCgaCgaCgaFRaMEaMFaJQaMGaCgaMHaXGaWubssaWuddkaHjaPxaaaaaaabqabqabqabqabqaaaaaaarAaPxarAaCgaDoabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqaaaaaaaaaaaaaaaaHkaMLaMLaMLaLBaLBaLBaLBaLBaLBaMLaMLaMMaHkazSakzaaaaMNaMOaMOaMOaMOaMOaMNabqabqaMPaMQaMRaMSaMTaMUaMVaMWaMXaMYaMZaNaaNbaNcaLRaNdaNeaNfaNgaNhaNiaNjaNkaNlaNmaNnaNoaNpaaaaaaaaaabqaaaaaaaaaabqaaaaaaaaaaNqaNraNsaNtaMkaNuaNvaNwaNxaNyaNzaNAaNBaNCaMkaNDaNEaNFaNGaNHaMnaNIaBIaNJaNKaJwaMqaBIaNLaBIaNMaBIaNNaNOaNPaNQaNQaNQaNQaNQaNQaNQaNQaNQaoGaNRaxhaNSaNTaNUaNVaCgaNWaIvaMFaNXaNYaNZaOaaObaOcaOdaOeddRaHjaPxaJWabqabqaOgddSaOiabqaOjaaaarAaPxataaCgaDoabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaHkaOkaLBaLBaLBaLBaLBaLBaLBaLBaMLaMLaMLaOlaOmapfaaaaMNaOnaMOaMOaMOaMOaMNaOoaMPaMPaOpaOqaOraOraOsaOtaOuaOvaOwaOxapfaOyapfapfapfapfaOzaOAaOBaOCaODaOEaOAaOAaOAaOAaOFaaaaaaaOGaOGaOGaOGaOGaOGaOGaaaaaaaMfaOHaOIaOJaOKaOLaNAaOMaONaOOaOPaOQaORaOSaMkaOTaOUaOVaOWaOXaMnaOYaBIaBIaBIaOZaOZaBIaBIaBIaBIaBIaPaaPbaPcaNQaPdaPeaPfaPgaPhaPiaPjaNQaPkaGWaxhaNTaNTaPlaOdaPmaGYaPnaPoaPpaPqaCgaPraPsaPtaPuaPvddUddTddVaaaaaaabqddWcspaPzabqaaaaaaaTMaRgarAaCgaDoabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaabqaHkaPAaLBaLBaLBaLBaPBaLBaPCaLBaLBaMLaPDaHkaGbapfaaaaMNaMOaMOaMOaMOaMOaPEaPFaPGaPFaPHaPIaPJaPKaPLaPMaPNaPOaPPaPQaPRaPSaPTaPTaPUaPTaPVaOAaPWaPXaPYaPZaQaaQbaQcaQdaQeaQfaQgaQgaQhaQiaQjaQkaQlaQmaQmaQnaQoaQpaKGaNtaMkaQqaNAaQraNAaQsaNAaQtaNAaNAaMkaQuaQvaOVaQwaQxaMnaQyaQzaQAaQBaQCaQDaQEaQFaQGaQHaQIaQJaQKaQLaNQaQMaQNaQNaQNaQOaQPaQQaNQaQRaGWaxhaQSaQSaQTaOdaPmaJJaQUaQVaQWaQXaQYaQZaRaaRbaRcaRdaOfaHjaPxaaaaReabqaRfddXaRhabqabqaJWarAaPxabqaCgaDoabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaJYaLBaLBaLBaLBaLBaLBaLBaLBaLBaLBaRiaHkaHkaRjapfabqaMNaMOaMOaMOaMOaMOaRkaRlaRmaRlaRnaPIaRoaRoaRpaRoaOuaRqaRraRsapfapfapfapfapfapfazSaOAaRtaRuaRvaRwaRxaRxaRxaRyaOFaaaaOGaRzaRAaRAaRAaRAaRAaRBaOGaaaaMfaRCaMiaMjaMkaRDaREaRFaNAaRGaNAaRHaRIaNAaRJaRKaRLaRMaRNaROaMnaRPaRQaRRaRRaRRaRSaRTaRTaRUaRUaRVaRWaRXaRYaRZaSaaSbaSbaSbaScaSdaSeaNQaSfaGWaxhaQSaSgaShaSiaCgaSjaIvaSkaJQaSlaCgaSmaSnaSoaSoaSoaSpaHjaPxaaaaaaabqabqabqabqabqaaaaaaarAaPxabqaCgaDoabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSqaSraSsaaaaJYaLBaLBaLBaLBaLyaLBaStaSuaSuaSvaSwaHkaqBazSapfabqaMNaMOaMOaMOaMOaSxaMNaOoaMPaMPaSyaPIaSzaSAaSBaSCaSDaSEaSFaSGaSHaSIaSJaSKaSLapfaSMaOAaSNaRuaSOaSPaSQaSQaSRaSSaOFaaaaSTaSUaRAaSVaSWaSXaRAaSYaSTaaaaMfaMhaMiaMjaMkaSZaTaaTbaTcaTdaTcaTeaTfaTgaMkaThaTiaTjaTkaTlaMnaTmaTnaToaTpaTqaTraTsaTtaTuaTvaTwaTxaTyaTzaTAaTBaTCaTDaTEaTFaTGaTHaNQasIaGWaxhaCgaCgaCgaCgaCgaFRaTIaTJaTKaTLaCgaCgaLvaLwaCgaHjaHjaHjaPxaaaaaaaaaabqaaaaaaaaaaaaaaaaTMaRgabqaCgaDoabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBarBarBarBarBarBarBarBarBarBarBarBarBarBarBarBarBarBarBarBarBarBarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGaTNaTOaTNacJaHkaLBaLBaLBaLBaLBaLBaLBaLBaLBaTPaTQaHkauAaTRapfaaaaMNaMOaMOaMOaMOaMOaTSaRlaTTaRlaRnaPIaRoaRoaRpaRoaOuaOvaTUaTVaTWaTXaTYaTZaUaapfaUbaUcaUdaRuaRuaUeaUfaRuaUgaUhaOFaaaaUiaUjaUkaUlaUmaUlaUkaUnaUoaaaaMfaMhaUpaUqaMkaUraUraUraUraUsaUraUraUtaUraMkaMnaUuaUvaUwaMnaMnaUxaTnaTpaTqaUyaUzaTnaToaTqaTqaTpaUAaUBaUCaUDaUEaSbaSbaUFaScaUGaUHaNQaUIaUJaxhaUKaULaUMaUNaUOaUPaIvaSkaJQaUQaJSaURaUSaUTaHhaHiaHjaHjaPxaJWaaaaaaaJWaaaaaaaaaaaaaJWarAaPxabqaCgaJXabqabqabqabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaaaaUUaUUaUUaUUaUVaUUaUUaUUaUUaUVaUUaUUaUUaUUaUVaUUaUUaUUaUUaaaarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafdaTNaUWaTNafdaHkaPAaMLaLBaLBaLBaLBaLBaUXaLBaUYaUZaHkaVaaAWapfaaaaMNaMOaMOaMOaMOaMOaVbaVcaVdaVcaVeaPIaRoaVfaVgaVhaViaVjaOuaVkaVlaVmaVnaVoaVpapfaVqaOAaVraRuaRuaVsaVtaVuaUgaVvaOFaaaaOGaVwaVxaUkaVyaRAaVzaVAaOGaaaaMfaVBaOIaOJaVCaVDaVEaVEaVEaNCaVEaVEaVFaVGaMkaVHaVIaVJaVKaVLaVMaVKaVNaVOaVOaVPaVQaVRaVSaVTaVUaVVaVSaVWaVXaNQaVYaVZaWaaWbaWcaWdaWeaNQasJaWfaxhaWgaWhaWiaWjaWkaWlaWmaWnaWoaWpaWqaWqaWraWsaHhaWtaHjddYaPxarAddZarAarAddZarAarAddZarAarAaPxabqaCgaDoabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaWvaWwaWxaWxaWxaWyaWxaWxaWxaWxaWzaWxaWxaWxaWxaWAaWxaWxaWxaWBaWCarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqaaaaaaaaaaaaaaaaHkaMLaMLaMLaLBaLBaLBaLBaLBaLBaMLaMLaMMaHkazSakzaaaaMNaMOaMOaMOaMOaMOaMNabqabqaMPaMQaMRaMSaMTaMUaMVaMWaMXaMYaMZaNaaNbaNcaLRaNdaNeaNfaNgaNhaNiaNjaNkaNlaNmaNnaNoaNpaaaaaaaaaabqaaaaaaaaaabqaaaaaaaaaaNqaNraNsaNtaMkaNuaNvaNwaNxaNyaNzaNAaNBaNCaMkaNDaUfaNFaNGaNHaMnaNIaBIaNJaNKaJwaMqaBIaNLaBIaNMaBIaNNaNOaNPaNQaNQaNQaNQaNQaNQaNQaNQaNQaoGaNRaxhaNSaNTaNUaNVaCgaNWaIvaMFaNXaNYaNZaOaaObaOcaOdaOeddRaHjaPxaJWabqabqaOgddSaOiabqaOjaaaarAaPxataaCgaDoabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaHkaOkaLBaLBaLBaLBaLBaLBaLBaLBaMLaMLaMLaOlaOmapfaaaaMNaOnaMOaMOaMOaMOaMNaOoaMPaMPaOpaOqaOraOraOsaOtaOuaOvaOwaOxapfaOyapfapfapfapfaOzaOAaOBaOCaODaOEaOAaOAaOAaOAaOFaaaaaaaOGaOGaOGaOGaOGaOGaOGaaaaaaaMfaOHaOIaOJaOKaOLaNAaOMaONaOOaVsaOQaORaOSaMkaOTaOUaOVaOWaOXaMnaOYaBIaBIaBIaOZaOZaBIaBIaBIaBIaBIaPaaPbaPcaNQaPdaPeaPfaPgaPhaPiaPjaNQaPkaGWaxhaNTaNTaPlaOdaPmaGYaPnaPoaPpaPqaCgaPraPsaPtaPuaPvddUddTddVaaaaaaabqddWcspaPzabqaaaaaaaTMaRgarAaCgaDoabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaabqaHkaPAaLBaLBaLBaLBaPBaLBaPCaLBaLBaMLaPDaHkaGbapfaaaaMNaMOaMOaMOaMOaMOaPEaPFaPGaPFaPHaPIaPJaPKaPLaPMaPNaPOaPPaPQaPRaPSaPTaPTaPUaPTaPVaOAaYOaPXaPYaPZaQaaQbaQcbeBaQeaQfaQgaQgaQhaQiaQjaQkaQlaQmaQmaQnaQoaQpaKGaNtaMkaQqaNAaQraNAaQsaNAaQtaNAaNAaMkaQubeLaOVaQwaQxaMnaQyaQzaQAaQBaQCaQDaQEaQFaQGaQHaQIaQJaQKaQLaNQaQMaQNaQNaQNaQOaQPaQQaNQaQRaGWaxhaQSaQSaQTaOdaPmaJJaQUaQVaQWaQXaQYaQZaRaaRbaRcaRdaOfaHjaPxaaaaReabqaRfddXaRhabqabqaJWarAaPxabqaCgaDoabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaJYaLBaLBaLBaLBaLBaLBaLBaLBaLBaLBaRiaHkaHkaRjapfabqaMNaMOaMOaMOaMOaMOaRkaRlaRmaRlaRnaPIaRoaRoaRpaRoaOuaRqaRraRsapfapfapfapfapfapfazSaOAbgkaRuaRvaRwaRxaRxaRxbgyaOFaaaaOGaRzaRAaRAaRAaRAaRAaRBaOGaaaaMfaRCaMiaMjaMkaRDaREaRFaNAaRGaNAaRHaRIaNAaRJaRKaRLaRMaRNaROaMnaRPaRQaRRaRRaRRaRSaRTaRTaRUaRUaRVaRWaRXaRYaRZaSaaSbaSbaSbaScaSdaSeaNQaSfaGWaxhaQSaSgaShaSiaCgaSjaIvaSkaJQaSlaCgaSmaSnaSoaSoaSoaSpaHjaPxaaaaaaabqabqabqabqabqaaaaaaarAaPxabqaCgaDoabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSqaSraSsaaaaJYaLBaLBaLBaLBaLyaLBaStaSuaSuaSvaSwaHkaqBazSapfabqaMNaMOaMOaMOaMOaSxaMNaOoaMPaMPaSyaPIaSzaSAaSBaSCaSDaSEaSFaSGaSHaSIaSJaSKaSLapfaSMaOAaSNaRuaSOaSPaSQaSQaSRaSSaOFaaaaSTaSUaRAaSVaSWaSXaRAaSYaSTaaaaMfaMhaMiaMjaMkaSZaTaaTbaTcaTdaTcbjbaTfaTgaMkbmIbkZaTjaTkaTlaMnaTmaTnaToaTpaTqaTraTsaTtaTuaTvaTwaTxaTyaTzaTAaTBaTCaTDaTEaTFaTGaTHaNQasIaGWaxhaCgaCgaCgaCgaCgaFRaTIaTJaTKaTLaCgaCgaLvaLwaCgaHjaHjaHjaPxaaaaaaaaaabqaaaaaaaaaaaaaaaaTMaRgabqaCgaDoabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBarBarBarBarBarBarBarBarBarBarBarBarBarBarBarBarBarBarBarBarBarBarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGaTNaTOaTNacJaHkaLBaLBaLBaLBaLBaLBaLBaLBaLBaTPaTQaHkauAaTRapfaaaaMNaMOaMOaMOaMOaMOaTSaRlaTTaRlaRnaPIaRoaRoaRpaRoaOuaOvaTUaTVaTWaTXaTYaTZaUaapfaUbaUcaUdaRuaRuaUebmJaRuaUgaUhaOFaaaaUiaUjaUkaUlaUmaUlaUkaUnaUoaaaaMfaMhaUpaUqaMkaUraUraUraUraUsaUraUraUtaUraMkaMnaUuaUvaUwaMnaMnaUxaTnaTpaTqaUyaUzaTnaToaTqaTqaTpaUAaUBaUCaUDaUEaSbaSbaUFaScaUGaUHaNQaUIaUJaxhaUKaULaUMaUNaUOaUPaIvaSkaJQaUQaJSaURaUSaUTaHhaHiaHjaHjaPxaJWaaaaaaaJWaaaaaaaaaaaaaJWarAaPxabqaCgaJXabqabqabqabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaaaaUUaUUaUUaUUaUVaUUaUUaUUaUUaUVaUUaUUaUUaUUaUVaUUaUUaUUaUUaaaarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafdaTNaUWaTNafdaHkaPAaMLaLBaLBaLBaLBaLBaUXaLBaUYaUZaHkaVaaAWapfaaaaMNaMOaMOaMOaMOaMOaVbaVcaVdaVcaVeaPIaRoaVfaVgaVhaViaVjaOuaVkaVlaVmaVnaVoaVpapfaVqaOAaVraRuaRubmKaVtaVuaUgaVvaOFaaaaOGaVwaVxaUkaVyaRAaVzaVAaOGaaaaMfaVBaOIaOJaVCaVDaVEaVEaVEaNCaVEaVEaVFaVGaMkaVHaVIaVJaVKaVLaVMaVKaVNaVOaVOaVPaVQaVRaVSaVTaVUaVVaVSaVWaVXaNQaVYaVZaWaaWbaWcaWdaWeaNQasJaWfaxhaWgaWhaWiaWjaWkaWlaWmaWnaWoaWpaWqaWqaWraWsaHhaWtaHjddYaPxarAddZarAarAddZarAarAddZarAarAaPxabqaCgaDoabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaWvaWwaWxaWxaWxaWyaWxaWxaWxaWxaWzaWxaWxaWxaWxaWAaWxaWxaWxaWBaWCarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqaWDaWEaWFaWGaWDaHkaLCaMLaWHaWIaWJaLBaLBaLBaLBaUYaWKaHkazSapdakzaaaaMNaOnaMOaMOaMOaMOaMNaOoaMPaMPaWLaPIaRoaRoaRpaRoaOuaVjaWMaWNaVlaWOaWPaWQaWRapfazMaOAaWSaWTaWTaWUaWVaRuaUgaWWaOFabqaOGaOGaOGaWXaWYaWZaOGaOGaOGabqaMfaOHaXaaMjaXbaXcaVEaVEaVEaXdaVEaVEaXeaNCaXbaQCaXfaXgaXhaToaXiaToaTnaTpaToaXjaToaXkaTpaTqaToaTqaTpaXlaXmaNQaXnaXoaXpaXqaXraPiaQQaNQaXsaGWaxhaXtaXuaXvaXwaXxaXyaXzaXAaXBaXCaXDaXDaXEaXFaHhaHiaHjaMIdeaaMJdebaMJaMJdebaMJaMJdebaMJaMJdecabqaCgaDoabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaXHaXIaXJaXKaXKaXLaXKaXKaXKaXKaXMaXKaXKaXKaXKaXLaXKaXKaXNaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaWDaXPaXQaXRaXSaHkaXTaMLaXUaXVaXWaMLaMLaMLaXXaXYaXZaHkaYaaYbapfabqaYcaYdaMOaMOaMOaYeaYfabqabqaMPaWLaYgaPJaPKaYhaYiaYjaYkaYlaYmaYnaYnaYnaYnaYnapfaYoaYpaYqaYraYraYsaYtaYuaYvaYwaYxaaaaaaaaaaOGaOGaYyaOGaOGaaaaaaaaaaNqaNraYzaMjaYAaYBaYCaYDaYEaNCaNCaYFaYGaNCaYAaQCaYHaYIaYJaYKaYLaYKaYMaYNaYOaYPaYKaYKaYKaYKaYKaYKaYQaYRaYSaNQaNQaNQaNQaYTaNQaNQaNQaNQaoGaGWaxhaYVaYUaYUaUNaYWaYXaYYaYZaZaaZbaZcaZdaZeaZfaFXaZgaCgaaaabqabqaaaaaaaaaaaaabqaaaaaaabqabqarAaDiaCgaDoabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaXHaXIaXOaaaaaaaXLaaaaaaaaaaaaaXMaaaaaaaaaaaaaXLaaaaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaWDaXPaXQaXRaXSaHkaXTaMLaXUaXVaXWaMLaMLaMLaXXaXYaXZaHkaYaaYbapfabqaYcaYdaMOaMOaMOaYeaYfabqabqaMPaWLaYgaPJaPKaYhaYiaYjaYkaYlaYmaYnaYnaYnaYnaYnapfaYoaYpaYqaYraYraYsaYtaYuaYvaYwaYxaaaaaaaaaaOGaOGaYyaOGaOGaaaaaaaaaaNqaNraYzaMjaYAaYBaYCaYDaYEaNCaNCaYFaYGaNCaYAaQCaYHaYIaYJaYKaYLaYKaYMaYNbmLaYPaYKaYKaYKaYKaYKaYKaYQaYRaYSaNQaNQaNQaNQaYTaNQaNQaNQaNQaoGaGWaxhaYVaYUaYUaUNaYWaYXaYYaYZaZaaZbaZcaZdaZeaZfaFXaZgaCgaaaabqabqaaaaaaaaaaaaabqaaaaaaabqabqarAaDiaCgaDoabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaXHaXIaXOaaaaaaaXLaaaaaaaaaaaaaXMaaaaaaaaaaaaaXLaaaaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaWDaWDaZiaZjaWDaWDaWDaZkaWDaWDaZlaZmaWDaWDaWDaZnaWDaWDaZoapfapfabqaZpaZqaZraZraZraZqaZsabqabqaZtaZuaPIaRoaRoaRpaRoaOuaZvaOuaZwaYnaZxaZyaZzaZAapfazSaOAaZBaZCaZDaZEaZFaZGaZHaZIaOFaZJaZKaZJaZLaZMaZNaZOaZLaZJaZKaZJaMfaZPaZQaZRaZSaMkaMkaMkaMkaZTaZUaZVaNCaZWaMkaQCaZXaTraZYaZZaZZaZZaZZaoGaoGaoGbaababbacbadbaebafaZZbagbagaoGbahazAazybaiazybajazybakazybalaxhbambambambambanbaobapbaqbarbasbataIvbaubavaCgaCgaCgabqabqbawbaxaDiaDiaDiaDiaDiaDibawaDibayaCgaCgaDoabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaXHaXIaXOaaaaaaaXLaXLaXLaXLaXLaXMaXLaXLaXLaXLaXLaaaaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaabazbaAbaBbaCbaDbaEbaBbaFbaGbaHbaGbaIbaJbaGbaKbaLbaMbaNbaOapfaaaaaabaPbaQbaQbaQbaRaaaabqaZtbaSaWLaPIaRoaRobaTbaUaOubaVbaWbaXbaYbaZbbabbbbbcapfazSaOAaOAaOAaOBaOBbbdaOFbbebbfaOFbbgbbhbbiaZLbbjbbkbblaZLbbmbbnbbobbpbbqbbrbbsbbtbbubbvbbwaMkaMkaYAbbxaYAaMkaMkaXibbybbzaXibbAbbBbbCbbDbbEbbFaoGaoGaoGaoGbbGaoGaoGaoGaoGaoGaoGaGWasIasJbbHbbHbbHbbHbbHbbHbbHbambbIbbJbbKbambbLbbMbambbNbbOaFRaFRbbPbbQbbRaDfbbSaDfbbTaDibbUaDiaCiaCjbbVaCjaClaDibbUaDiaCmaDnaDoabqabqabfabfabeabqabeabfabfabeabeabfabfabfabeabqabqabqabqabqarBaWvbbWbbXbbXbbXbbXbbXbbYbbYbbYbbZbbYbbYbbYbbXbcabbXbbXbbXbcbaWCarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqaaabccbcdbcebcebcfbcebcebcebcgbchbcibcjbckbckbckbclbcmbcnbcoapfaaaaaaabqabqaaaaaaabqabqabqaZtbcpbcqbcrbcsaRobctbcubcvbcwbcxbcybczbcAbcBbcCbcDapfbcEbcFbcGbcHbcIbcJbcKbcLbcMbcNbcObcPbcQbcPbcRbcSbcTbcUbcVbcPbcWbcXbcXbcYbcZbdabcXbcXbdbbdcbdcbdcbddbdebdcbdcbdfbdcbdgbdhbdcbdcbdcbdibdjaoGbdkbdlbdmbdnbdobdpbdobdqbdobdrazBbakbalaubasJbbHbdsbdtbdubdvbdwbdxbambdybdzbdzbdAbdzbdBbambdCbarbdDbdEbdEbdEbdEbdEbdFaCgbdGaCjbdHaCjaDmaCgaCgaCgbdGaCjaDmaCmaCmaCgabqabqaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaarBaXHaXIaXOaaaaXLbdIbdIbdJbdKbdLbdMbdNbdKbdObdIbdPaXLaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqbccbccbdQbccaWDbccbdRbccbcdbcebdSbdTbccbdRbccbdUbdVbdWbdXapfapfapfapfakzakzakzapfapfapfaZtbdYbdZbdZbdZbdZbeaaRobebbecbedbeeaYnaYnaYnaYnbefapfapfbegapfapfbehbeibejbekbelbembenbekbelbeobepbembeqbekbekbekbelbekbekberbesbekbekbekbekbekbekbekbetbeubekbekbenbevbewbekbekbekbekbexbeybezbezbezbeAbezbezbezaoGbeBaoGaGWaoGaoGbeCbeCbeCbeCbeDbeEbeEbeFbeGbeHbambeIbeJbeKbeLbeMbeNbambeObePbeQbdEbeRbeSbeTbdEbeUaCgaCgaCgaCgaCgaCgaCgbeVaCgaCgaCgaCgaCgaLwaCgabqarBarBabearBarBarBarBabearBarBarBarBabearBarBarBarBarBarBarBarBaWvaXIaXOaaaaXLbdIbdLbeWbeXbeYbeZbfabeXbfbbdLbdPaXLaaaaZhaXIaXObfcbfcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaabccabqaaaabqaaabccbfdbccbfebfebffbfgbccbfdbccbccaWDbfhbfibfjavTavUbfkavUbflavUbfmbfnavVbfobfpbfqbfqbfrbfsbftbfubfvbfwbfxbfybfwbfzbfAbfwbfBbfCbfDbfEbfFbfGbfHbfIbfJbfKbfKbfLbfMbfNbfObfPbfQbfRbfSbfSbfSbfSbfSbfSbfSbfTbfUbfVbfVbfVbfVbfVbfVbfVbfVbfWbfXbfYbfZbfVbgabfWbfVbfVbgbbgcbgdbezbgebgfbggbghbgibezbgjbgkaoGbglaoGaaabeCbgmbgnbeCbgobgpbgqbgrbgsbgtbambgubgvbgwbgxbgybgzbambgAbgBbgCbdEbgDbgEbgFbdEbgGaOdaOdbgHaOdbgIaOdaOdaOdbgJaOdbgKbgLbgKbgLaefaefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaaaaUVbgMaXIaXOaaaaXLbdIbgNbgObdIbgPbgQbgRbdIbgSbgTbdPaXLaaaaZhaXIbgUaaabfcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqabqabqabqabqaaabccbdRbccbccbccbccbccbccbdRbccaaaaWDbgVbgWbgXbgXbgXbgXbgXbgXbgXbgXbgYbgZbfwbfwbhabhbbhabfwbfwbfwbhcbfwbhdbhebhfbhgbhhbhibhjbhkbhlbhmbhnbfGbhobfIbhpbhqbhqbhrbhqbhsbhqbhtbhubhtbhvbhvbhvbhvbhvbhvbhvbhvbhvbhvbhvbhvbhvbhvbhvbhvbhvbhwbhwbhxbhwbhwbhwbhwbhwbhwbhybfIbhzbezbhAbhBbhCbhDbhEbezbhFbhGaoGaGWaoHaaabhHbhIbhJbhKbhLbhMbhNbhObhPbhQbambhRbhSbhTbhTbhUbhVbambhWbhXbhWbdEbhYbhZbiabdEbibaCgaCgaCgaCgaCgaCgaCgaCgaCgaHjaCgaCgbdFaCgabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqabqarBbicbidbiebifaXLaXLaXLbdIbigbihbiibdIbdIbdIbijbikbilbdPaXLaXLaXLbimaWBaWCarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabinbiobipbiobiqbiobiobiqbiobipbirbisaWDbgVbitbiubivbiwbixbiybizbiAbgXbiBbiCbiDbiEbiFbiGbiFbiGbiHbiGbiIbfwbiJbiKbiLbiMbiNbiObiPbiQbiRbiSbiTbiUbiVbiWbiXbhqbiYbiZbjabjbbhqbjcbjdbjeabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqbhwbjfbjgbjhbjibjjbjkbjlbhwbjmbjnbjobezbjpbjqbjrbjsbjtbezaoGaoGaoGbjuaoGaaabeCbjvbjwbeCbjxbjybjzbjAbjBbjCbambjDbjEbjFbjGbjHbjIbamaFRbjJaFRbdEbjKbjLbjMbdEbjNbjNbjNafdacJaaaaaaaaaaaaabqaaaaaaaCgbgLaCgabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaUUaUUbjObjPaXIbjQbjRaaaaaaaXLbjSbjTbjUbdIbdIbjVbdIbdIbgSbjWbjXaXLaaaaaabjYaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabinbiobiobjZbkabkbbkcbkdbkebkfbkgbkhbkbbkibkjbccbgVbgWbkkbklbkmbknbkobkpbkqbkrbksbktbkubkvbkvbkwbkxbkybfwbfwbfwbfwbkzbkAbkBbkCbkDbhabkEbhkbhlbkFbkGbkHbkIbfIbkJbhqbkKbkLbkMbkNbkObkPbkQbkRabqabqbkSbkTbkUbkVbkWbkXbkTbkVbkWbkXbkUbkUbkYabqabqbhwbkZblablbblcblbbldblebhwblfbfIblgblhbezblibljblkbezbezbllblmaoGblnaoGblobeCbeCbeCbeCbbHbbHbbHblpblqbbHbambambambambamblrblsbambltblubltbdEblvblwblxbdEblyblzblAblBblBblCaaaaaaaaaabqaaaaaaaaaaefaaaabqaaaaaaaaaaaaaaaaaDaaaaaaaaaaaaaaaaaaaaaaaaabqabqaefblDblEblFblEblGaXOaaaaaaaaaaXLblHbdLblIblJblKblLblMblJblNbdLbdPaXLaaaaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaablOblPblQblRbkbblSblTblSblTblSblTblSbkbblUblVbccbgVblWbgXblXblYblZbmabmbbmcbgXbmdbmebmfbmgbmhbmibmjbmkbmlbmmbmnbmobmpbmqbmrbmsbmtbmubmvbmwbmxbmybmzbmAbiVbfIbkJbhqbmBbmCbmDbmEbhqbmFbmGbjeabqabqbmHbmIbmJbmKbmLbmMbmNbmObmPbmQbmRbmSbmTabqabqbhwbmUbmVbmWbmXbmYbmZbnabhwbhybnbbncbndbnebnfbnebngbnhbnibnebnebnebnjbnebnkbnlbnmbnnbnebnebnobnkbngbnjbnpbnqbnobnrbnsbntbnubnvbnwbnxbnybnzbnAbnBbnCbnDbnEbnFbnFbnGbnHbnIbnJaaaaaaaaaabqaaaaaaaaaaefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqabqabqaefblDblEbnKblEbnLaXOaaaaaaaaaaXLbnMbnNbdJbnObnPbnQbnRbnSbnTbdIbdPaXLaXLaXLaXLbnUaWCarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiqbkbbkbbipbkbblSblTblSbnVblSblTblSbkbblUblVbccbnWbnXbnYbnZboabobbocbobbiubiubodboebhcbfwbofbogbohboibojbokbolbfwbombonbojbkCboobfwbopboqborbosbotbiUbkIbfIbkJbhqboubovbowboxbhqboybozbjebkWboAbkWboBboCboDboEboDboFboDboEboDboGboHbkWboAbkWbhwboIboIboIboJboKboLboMbhwboNboOboPboQboRboSboRboTboRboUboRboRboRboVboRboWboXboYboZboRboRbpabpbbpcboVbpdboVbpebpfbpgbntbphbpibpibpjbpkbpibpibplbpmbpnbpobnFbnFbppblBblBbpqaaaaaaaaaabqaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqbpraaaaaaaaaabqbjRbjRbjObpsaXIaXOaaaaaaaaaaXLaXLblHbdIbdIbdIbptbdIbdIbdIbdIbpubcabpvaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaablObpwbpxblRbkbblSblTblSblTblSblTblSbkbblUblVbccbpybpzbpAbpBbpCbpDbpDbpEbpFbpBbpGbpHbpIbfwbpJbpKbpLbpMbpNbpObpPbfwbpQbpRbpSbpTbpUbfwbpVbpWbpXbpYbpZbfGbqabjnbqbbqcbqcbqcbqcbqcbhtbqdbqebhtbkWbqfbqgbqhboEboEboEboEbqiboEboEboEboEbqjbqkbqlbkWbqmbqnbqobqpbqqbqrbqrbqsbhwbqtbqubqvbqwbqxbqybqxbqzbqxbqAbqxbqxbqBbqxbqxbqCbqDbqxbqEbqBbqFbqGbqCbqHbqxbqIbqJbqKbqLbqMbqNbqObqPbqQbqRbpnbqSbqSbqTbqUbqVbqWbntbntbntafdbqXabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqaaabqYbqZbrabrbbrcbrdbrebrfaXIaXLaXLaXLaXLaXLbrgbrhbrgbrgbribrjbribrkbrkbrlbrmbrnaXMaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrobiobiobjZbrpbkbbrqbkbbrrbrsbkbbrtbkbbkibrubccbgVbrvbrwbrxbrybrzbrAbrBbrCbrxbrDbrEbrFbfwbrGbhabrHbrIbfwbfwbfwbfwbfwbhabrJbrKbfwbfwbiUbrLbrMbiUbiUbrNbehbfIbrObqcbrPbrQbrRbqcbrSbrTbrUbrVbrWbrXbrYbrZbsabsbbscbsdbsebscbscbsfbsabsgbshbsibkWbhwboIboIboIbsjboIboIboIbhwbskbfIbslbsmbsnbsobsnbsmbspbspbspbspbspbspaoGaoGbsqaoGaoGaoGbsrbumaoGaoGaoGbstaoGbsubsvbswbsxbsybszbsAbsBbqSbsCbsCbsDbqUbsEbjNbntbsFbsGbsHbsIbsJbsJbsKbsLabqaaaaaaabqaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaabqaaabqYbsMbsNaaaabqbsObsPbsQbsRbsSbsTbrgbsUbsVbsWbsXbsYbsZbrgbtabtbbtcbtdbtebtfbtfbtgaXMaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrobiobthbiobiqbiobiobiqbiobipbtibtjaWDbtkbtlbtmbfGbtnbtobtpbtobtqbfGbtrbtsbttbtubtvbtwbtxbtybtzbtwbtAbtBbtwbtvbtvbtCbtvbtDbtEbtFbtGbtHbtvbtIbtJbtKbkJbtLbtMbtNbtObqcbjebjebjebjebkWbtPbtQbtRbtSbtTbtUboEbtVbtWbtXbtYbtSbtZbuabubbucbhwbudbuebufbugbuhboIbuibhwbujbfIbukbuldedbunbuobsmbupbuqburbusbutbuubuvbuwbuxaoGbuybuzbuAbuBbuCaoGaxcbuDaoGbuEbuFbuGbnEbuHbuHbuHbuIbuJbqSbqSbuKbuLbuMbuNbuObuPbuQbuRbuSbuTbuTbuUbuVbuWbuWbuWbuXbuWbuWbuWbuWbuWbuWbuXbuWbuWbuWbuWbuWbuWbuXbuWbuYbuZbuTbuTbuTbvabvbbvcbvdbvdbvebvfbvgbvhbvibvjbvkbvlbvmbvnbvobvpbvqbvrbvsbvtbvubvvbbXbbXbvwaWCarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqabqabqabqaaabccbdRbccbccbccbccbccbccbdRbccaaaaWDbvxbvybvzbfGbvAbvBbvCbvBbvDbfGbvEbvFbvGbvHbvHbvIbvJbvHbvHbvKbvLbvMbvNbvHbvHbvObvHbvHbvHbvPbvQbvRbvRbvSbvTbvUbvVbqcbvWbvXbvYbqcbvZbwabwbbwcbwdbtYbwebtTbwfbwgbwhbwibwjbwibwkbwlbwmbwnbwobwpbwqbhwbwrbwsbwtbwubwvbhwbhwbhwbhybwwbwxbsmbwybwzbwAbsmbwBbwCbwDbwEbwFbwGbwHbwIbwJbwKbwLbwMbwNbwObwPbwQbwRbwSaoGbsubwTbwUbntbwVbwWbwXbwYbwZbxabxbbxcbxdbqUbxebxfbxgbxhbxiaWCaaaaaabxjbsNabqaaaaaaabqaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaabqaaabxkbxlbsLaaaabqaZhbxmbxnbxobxpbxqbxrbxsbxtbxubxvbxwbxxbxybxzbxAbxBbxCbxDbtfbxEbxFaXMaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqbccabqaaaabqaaabccbxGbccbxHbxIbfebxJbccbxGbccbccaWDbgVbxKbxLbfGbxMbvBbxNbvBbxObfGbxPbxQbxRbxSbxTbxUbxVbxWbxXbxYbxZbyabxTbxTbxTbybbxTbycbydbxVbyebxTbxTbyfbygbyhbvVbqcbyibyjbykbylbymbynbymbymbwdbyobypbyqbyqbyqbyrbysbytbyubyvbyqbyqbyqbywbyxbkWbhwbyybyzbyAbyBbyCbhwbyDbyEbyFbyGbwxbsnbyHbyIbyJbsmbyKbyLbyMbyNbspbspaoGaoGbyOaoGaoGaoGbyPbyQaoGaoGbyRbySaoGbyTbwTbyUbntbjNbjNbjNbjNbyVbjNbjNbyWbyXbyYbntbntbyZbzabzbbzcaaabqYbzdaaaabqaaaaaaabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqaaabxkbxlbsLabqbzebzfbzgbzhbzibzjbrgbzkbzlbzmbznbzobzpbrgbzqbzrbzsbrkbztbzubtfbtgaXMaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaabccbccbdQbccaWDbccbdRbccbzvbaBbzwbzxbccbdRbccbzybzzbzAbtlbtmbfGbzBbzCbtpbzCbzBbfGbzDbzEbzFbfGbzGbzHbzIbfGapfbzJapfbzKbzKbzLbzMbzNbzLbzKbzKbzKbzKbzKbzKbzObzPbzQbzRbzSbzTbzUbzVbzWbzVbzXbzYbzZbAabAbbAcbAdbAebAdbAdbAfbAgbAhbyqbyqbAibyqbAjbAkbhwbAlbAmbAnbAobApbAqbhwbArbhtbAsbbrbAtbsmbsmbsmbsmbsmbAubAvbspbspbspbAwbAxbspbAybAzbAAaoGazpbABaoGbACbADbAEbAFbAGbAHbAIbAJbAKbALbAMbAKbANbAObjNbAPbAQbARbASbATbAUbAVbAWbAXbsJbAYbAZabqabqabqabqabqaaaabqaaaabqaaaabqaaaabqaaaaaaaaaaaaaaaaaaabqbpraaabxkbBabrbbBbbBcbrebpsaXIaXLbBdbBebBfbBgbBhbBibrgbrgbBjbBkbBlbrkbrkbBmbBnbBoaXMaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaabccbBpbaBbaCbBqbBrbaBbaBbBsbBtbchbBubBvbBvbBvbBwbBxbBybBzbBAbBBbBCbBDbBEbBFbBGbBBbBHbBIbBJbBKbBKbBLbBKbBKarKbBMbBNbzKbBObBPbBQbBRbBSbzKbBTbBUbzKbBTbBUbzKbzPbfIbkJbqcbBVbBWbBXbqcbBYbBZbCabCbbwdbCcbCdbyqbCebCfbCgboEboEbAkbChbCibCjbyqbCkbClbhwbCmbCnbCobCpbCqbCrbCsbCtbhtbhybbrbhzbspbCubCvbCwbCxbCybCzbCAbspbCBbCCbCDbCEbCFbCGbCHaoGaoGaoGaoGaoGaoGbCIaoGbCJbCKbCLbCMbCNbCNbCNbCNbCNbCMbCMbCNbCObCPbCQbCRbCSbCTbCUbCVbCMbCMbCMabqaaaaaaaaaabqaaaabqaaaabqaaaabeaaaabeaaaaaaaaaaaaaaaaaaaaaabqabqabqabqabqabqabqarBbicaXIaXObCWaXLbCXbCYbCZbDabDbbDcbDdbDebDfbDgbDhbDibbXbbXbDjaXLaXLbnUaWCarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaabccbcdbcebcebDkbcebDlbDmbDnbDnbDobDnbDpbDqbDrbDsbDtbDubDvbDwbpBbDxbDybDzbDAbDBbDCbDDbDEbDFbDGbDHbDIbDJbBKbDKbDLanHbzKbDMbDNbBQbBRbBSbzKbDObDPbzKbDObDPbzKbDQbfIbkJbqcbqcbDRbqcbqcbqcbDSbDTbDUbqcbDVbDWbDXboEbwibwibDYbDZbEabEbbEcbEdbEebEfbEgbEhbEibEjbEkbElbEmbEnbhwbEobhtbEpbbrbhzbspbEqbErbCybEsbCybEtbCybEubEvbCHbEwbExbEybEzbEAbEBbECbEDbEEbEFbEGbEHaoGbEIbwTbEJbCMbEKbELbEMbENbEObCMbEPbEQbERbESbETbEUbEVbEWbEXbEYbEZbFabCMabqabqabqabqabqabqabqaaaabeaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaZhbFdaXOaaaaXLbFebFfbFgbDabFhbFibFjbFkbFlbFmbFnbDaaXLaaaaaaaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqbccbccaWDbccbdQbccaWDbccbccbccaWDbccaWDaWDaWDbnWbnXapfbFoapfapfbFpbFqbFpbFrbFpbFpbFpbFpbBKbBKbFsbFtbBKbBKbBKbFuaoXbzKbFvbFwbBQbFxbzKbzKbFybzKbzKbFzbzKbzKbFAbfIbkJbFBbFCbFDbFEbFFbFGbFDbFDbFHbFIbAkbFJbAdbFKbFLbFMbFNbFObFPbFQbFRbFSbyqbFTbFUbhwbFVbFWbFXbFYbFZbGabhwbGbbhtbhybbrbhzbspbGcbGdbGebGdbGfbGgbGhbGibEvbCHbGjbGkbCHbEvbGlbGmbGnbGobGpbGqbEGbySaoGbGrbGsbGtbGubGvbGwbGxbGybGzbCMbGAbGBbGCbGDbETbGEbGFbGGbGHbGIbGJbGKbCMabqbGLbGLbGLbGLbGLabqaaabFcaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaZhbFdaXOaaaaXLbGMbGNbGObDabGPbGQbGRbGSbGTbGUbGVbDaaXLaaaaaaaUUbjPaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaabGWbGXbGXbGYbGXbGXbGXbGZbGXbGXbHaabqbccbHbbgVbHcapfbBMayBbHdbFpbHebHfbHgbHhbHibHjbFpbHkbHkbHlbHmbHnbHobBKbFubHpbzKbHqbHrbBQbBRbHsbHtbFwbHubHvbHwbHxbzLbzPbfIbkJbFBbHybHzbHAbHAbHAbHAbHAbHBbFIbHCbHDbkWbkWbkWbHEbHFbHGbHHbHIbkWbkWbkWbHJbHCbhwbhwbEhbhwbhwbhwbhxbhwbHKbhtbHLbHMbhzbHNbHObHObHObHPbHObHQbHObHRbEvbEvbHSbEvbEvbCHbHTbHUbHVbHWbHXbHYbEGbCIaoGbHZbGsbIabIbbIcbIdbIebIfbIgbIhbIibIjbIkbIlbETbImbInbIobIpbIqbIrbIsbItbIubIvbIwbIxbIxbGLabqaaabFcaaabFbaaaabeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaZhbFdaXOaaaaXLaXLaXLaXLbDabIybIzbIAbFlbIBbICbIDbDaaXLaaaaZhbIEaWxbIFaWCarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabGWbIGbIHbIIbIJbIJbIKbIJbIJbIJbIKbGYbILbccbccbgVbIMapfbINbIObIPbFpbIQbHfbHgbIRbISbITbFpbIUbIVbIWbIXbBKbBKbBKbFuatjbzKbIYbIZbBQbBRbBQbBQbBQbBQbBQbJabBQbzMbJbbJcbJdbJebJfbJgbJfbJhbJfbJgbJfbJibJjbJkbJlbJmbJnbJobJpbJpbJqbJrbJpbJsbJtbJubJvbJwbJxbJobJybJzbJobJAbJBbJobJCbJDbJEbJFbwxbJGbCybJHbCybJIbCybJJbCybJKbEvbEvbJLbEvbEvbJMbJNbHUbJObECbHXbJPbEGbCIaoGbJQbJRbyUbGubJSbIdbJTbIdbJUbJVbJWbJXbJYbJZbETbKabKbbKcbKdbKebKfbKgbETabqbETbKhbIxbKibGLabqaaabFcaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaZhbFdaXOaaaaaaaaaaaabKjbKkbKlbKlbKmbKnbKmbKlbKlbKobpvaXLaXLbnUbKpbKqaaaarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabKrbKsbKsbKsbKsbKsbKsbKsbKsbKsbKsbKtbKubKvbKubgVbKwapfbKxbKyanEbFpbKzbHfbHgbKAbHfbKBbFpbBKbKCbBKbHmbKDbKEbBKbFuathbzKbKFbHrbKGbKHbKIbKIbKIbKIbKIbKJbKIbKKbygbKLbKMbKNbKObKPbKObKQbKRbKSbKTbKUbKVbKWbKXbKObKYbKZbLabLbbLcbLdbLabLebLfbLgbLhbLibLjbLkbLlbLmbLnbLobLpbLibLqbLrbLsbLtbLubLvbLwbLxbLybLybLzbLAbLwbLBbLCbLDbLEbCHbLFbCHbLGbLHbLIbLJbLKbLLbLMbLNaoGbLObLPbLQbLRbLSbLTbLUbLVbLWbETbLXbLYbLZbMabMbbMcbIobMdbMebMfbMgbMhbMibMjbMkbMlbIxbMmbGLabqaaabFcaaabFbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaZhbFdbMnaUUaUUaaaaaaaXMbMobMpbMqbKmbMrbKmbMsbMtbMuaXMaaaaZhaXIaXObfcarBarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqbccbccbdQbccaWDbccbdRbccbcdbcebdSbdTbccbdRbccbdUbdVbdWbdXapfapfapfapfakzakzakzapfapfapfaZtbdYbdZbdZbdZbdZbeaaRobebbecbedbeeaYnaYnaYnaYnbefapfapfbegapfapfbehbeibejbekbelbembenbekbelbeobepbembeqbekbekbekbelbekbekberbesbekbekbekbekbekbekbekbetbeubekbekbenbevbewbekbekbekbekbexbeybezbezbezbeAbezbezbezaoGbmMaoGaGWaoGaoGbeCbeCbeCbeCbeDbeEbeEbeFbeGbeHbambeIbeJbeKbmNbeMbeNbambeObePbeQbdEbeRbeSbeTbdEbeUaCgaCgaCgaCgaCgaCgaCgbeVaCgaCgaCgaCgaCgaLwaCgabqarBarBabearBarBarBarBabearBarBarBarBabearBarBarBarBarBarBarBarBaWvaXIaXOaaaaXLbdIbdLbeWbeXbeYbeZbfabeXbfbbdLbdPaXLaaaaZhaXIaXObfcbfcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaabccabqaaaabqaaabccbfdbccbfebfebffbfgbccbfdbccbccaWDbfhbfibfjavTavUbfkavUbflavUbfmbfnavVbfobfpbfqbfqbfrbfsbftbfubfvbfwbfxbfybfwbfzbfAbfwbfBbfCbfDbfEbfFbfGbfHbfIbfJbfKbfKbfLbfMbfNbfObfPbfQbfRbfSbfSbfSbfSbfSbfSbfSbfTbfUbfVbfVbfVbfVbfVbfVbfVbfVbfWbfXbfYbfZbfVbgabfWbfVbfVbgbbgcbgdbezbgebgfbggbghbgibezbgjbmOaoGbglaoGaaabeCbgmbgnbeCbgobgpbgqbgrbgsbgtbambgubgvbgwbgxbmPbgzbambgAbgBbgCbdEbgDbgEbgFbdEbgGaOdaOdbgHaOdbgIaOdaOdaOdbgJaOdbgKbgLbgKbgLaefaefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaaaaUVbgMaXIaXOaaaaXLbdIbgNbgObdIbgPbgQbgRbdIbgSbgTbdPaXLaaaaZhaXIbgUaaabfcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqabqabqabqabqaaabccbdRbccbccbccbccbccbccbdRbccaaaaWDbgVbgWbgXbgXbgXbgXbgXbgXbgXbgXbgYbgZbfwbfwbhabhbbhabfwbfwbfwbhcbfwbhdbhebhfbhgbhhbhibhjbhkbhlbhmbhnbfGbhobfIbhpblhbhqbhrbhqbhsbhqbhtbhubhtbhvbhvbhvbhvbhvbhvbhvbhvbhvbhvbhvbhvbhvbhvbhvbhvbhvbhwbhwbhxbhwbhwbhwbhwbhwbrNbhybfIbhzbezbhAbhBbhCbhDbhEbezbhFbhGaoGaGWaoHaaabhHbhIbhJbhKbhLbhMbhNbhObhPbhQbambhRbhSbhTbhTbhUbhVbambhWbhXbhWbdEbhYbhZbiabdEbibaCgaCgaCgaCgaCgaCgaCgaCgaCgaHjaCgaCgbdFaCgabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqabqarBbicbidbiebifaXLaXLaXLbdIbigbihbiibdIbdIbdIbijbikbilbdPaXLaXLaXLbimaWBaWCarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabinbiobipbiobiqbiobiobiqbiobipbirbisaWDbgVbitbiubivbiwbixbiybizbiAbgXbiBbiCbiDbiEbiFbiGbiFbiGbiHbiGbiIbfwbiJbiKbiLbiMbiNbiObiPbiQbiRbiSbiTbiUbiVbiWbiXbhqbiYbiZbjabmQbhqbjcbjdbjeabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqbhwbjfbjgbjhbjibjjbjkbjlbhwbjmbjnbjobezbjpbjqbjrbjsbjtbezaoGaoGaoGbjuaoGaaabeCbjvbjwbeCbjxbjybjzbjAbjBbjCbambjDbjEbjFbjGbjHbjIbamaFRbjJaFRbdEbjKbjLbjMbdEbjNbjNbjNafdacJaaaaaaaaaaaaabqaaaaaaaCgbgLaCgabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaUUaUUbjObjPaXIbjQbjRaaaaaaaXLbjSbjTbjUbdIbdIbjVbdIbdIbgSbjWbjXaXLaaaaaabjYaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabinbiobiobjZbkabkbbkcbkdbkebkfbkgbkhbkbbkibkjbccbgVbgWbkkbklbkmbknbkobkpbkqbkrbksbktbkubkvbkvbkwbkxbkybfwbfwbfwbfwbkzbkAbkBbkCbkDbhabkEbhkbhlbkFbkGbkHbkIbfIbkJbhqbkKbkLbkMbkNbkObkPbkQbkRabqabqbkSbkTbkUbkVbkWbkXbkTbkVbkWbkXbkUbkUbkYabqabqbhwbmRblablbblcblbbldblebhwblfbfIblgbwlbezblibljblkbezbezbllblmaoGblnaoGblobeCbeCbeCbeCbbHbbHbbHblpblqbbHbambambambambamblrblsbambltblubltbdEblvblwblxbdEblyblzblAblBblBblCaaaaaaaaaabqaaaaaaaaaaefaaaabqaaaaaaaaaaaaaaaaaDaaaaaaaaaaaaaaaaaaaaaaaaabqabqaefblDblEblFblEblGaXOaaaaaaaaaaXLblHbdLblIblJblKblLblMblJblNbdLbdPaXLaaaaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaablOblPblQblRbkbblSblTblSblTblSblTblSbkbblUblVbccbgVblWbgXblXblYblZbmabmbbmcbgXbmdbmebmfbmgbmhbmibmjbmkbmlbmmbmnbmobmpbmqbmrbmsbmtbmubmvbmwbmxbmybmzbmAbiVbfIbmSbhqbmBbmCbmDbmEbhqbmFbmGbjeabqabqbmHboBbopbpVboHbqfbqdbqhbqgbqkbqjbqlbmTabqabqbhwbmUbmVbmWbmXbmYbmZbnabhwbhybnbbncbndbnebnfbnebngbnhbnibnebnebnebnjbnebnkbnlbnmbnnbnebnebnobnkbngbnjbnpbnqbnobnrbnsbntbnubnvbnwbnxbnybnzbnAbnBbnCbnDbnEbnFbnFbnGbnHbnIbnJaaaaaaaaaabqaaaaaaaaaaefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqabqabqaefblDblEbnKblEbnLaXOaaaaaaaaaaXLbnMbnNbdJbnObnPbnQbnRbnSbnTbdIbrQaXLaXLaXLaXLbnUaWCarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiqbkbbkbbipbkbblSblTblSbnVblSblTblSbkbblUblVbccbnWbnXbnYbnZboabobbocbobbiubiubodboebhcbfwbofbogbohboibojbokbolbfwbombonbojbkCboobfwbrXboqborbosbotbiUbkIbfIbkJbhqboubovbowboxbhqboybozbjebkWboAbkWbsbboCboDboEboDboFboDboEboDboGbscbkWboAbkWbhwboIboIboIboJboKboLboMbhwboNboOboPboQboRboSboRboTboRboUboRboRboRboVboRboWboXboYboZboRboRbpabpbbpcboVbpdboVbpebpfbpgbntbphbpibpibpjbpkbpibpibplbpmbpnbpobnFbnFbppblBblBbpqaaaaaaaaaabqaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqbpraaaaaaaaaabqbjRbjRbjObpsaXIaXOaaaaaaaaaaXLaXLblHbdIbdIbdIbptbdIbdIbdIbdIbsebsdbsfaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaablObpwbpxblRbkbblSblTblSblTblSblTblSbkbblUblVbccbpybpzbpAbpBbpCbpDbpDbpEbpFbpBbpGbpHbpIbfwbpJbpKbpLbpMbpNbpObpPbfwbpQbpRbpSbpTbpUbfwbsibpWbpXbpYbpZbfGbqabjnbqbbqcbqcbqcbqcbqcbhtbtPbqebhtbkWbtSbtRbtTboEboEboEboEbqiboEboEboEboEbtZbtYbubbkWbqmbqnbqobqpbqqbqrbqrbqsbhwbqtbqubqvbqwbqxbqybqxbqzbqxbqAbqxbqxbqBbqxbqxbqCbqDbqxbqEbqBbqFbqGbqCbqHbqxbqIbqJbqKbqLbqMbqNbqObqPbqQbqRbpnbqSbqSbqTbqUbqVbqWbntbntbntafdbqXabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqaaabqYbqZbrabrbbrcbrdbrebrfaXIaXLaXLaXLaXLaXLbrgbrhbrgbrgbribrjbribrkbrkbrlbrmbrnbudaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrobiobiobjZbrpbkbbrqbkbbrrbrsbkbbrtbkbbkibrubccbgVbrvbrwbrxbrybrzbrAbrBbrCbrxbrDbrEbrFbfwbrGbhabrHbrIbfwbfwbfwbfwbfwbhabrJbrKbfwbfwbiUbrLbrMbiUbiUbzObehbfIbrObqcbrPbumbrRbqcbrSbrTbrUbrVbrWburbrYbrZbsabsabvWbwfbwebvWbvWbsabsabsgbshbwgbkWbhwboIboIboIbsjboIboIboIbhwbskbfIbslbZibsnbsobsnbsmbspbspbspbspbspbspaoGaoGbsqaoGaoGaoGbsrdeCaoGaoGaoGbstaoGbsubsvbswbsxbsybszbsAbsBbqSbsCbsCbsDbqUbsEbjNbntbsFbsGbsHbsIbsJbsJbsKbsLabqaaaaaaabqaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaabqaaabqYbsMbsNaaaabqbsObsPbsQbsRbsSbsTbrgbsUbsVbsWbsXbsYbsZbrgbtabtbbtcbtdbtebtfbtfbtgaXMaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrobiobthbiobiqbiobiobiqbiobipbtibtjaWDbtkbtlbtmbfGbtnbtobtpbtobtqbfGbtrbtsbttbtubtvbtwbtxbtybtzbtwbtAbtBbtwbtvbtvbtCbtvbtDbtEbtFbtGbtHbtvbtIbtJbtKbkJbtLbtMbtNbtObqcbjebjebjebjebkWbwmbtQboEboEboEbtUboEbtVbtWbtXboEboEbwnbuabAkbucbhwbwobuebufbugbuhboIbuibhwbujbfIbukbuldedbunbuobsmbupbuqbwpbusbutbuubuvbuwbuxaoGbuybuzbuAbuBbuCaoGaxcbuDaoGbuEbuFbuGbnEbuHbuHbuHbuIbuJbqSbqSbuKbuLbuMbuNbuObuPbuQbuRbuSbuTbuTbuUbuVbuWbuWbuWbuXbuWbuWbuWbuWbuWbuWbuXbuWbuWbuWbuWbuWbuWbuXbuWbuYbuZbuTbuTbuTbvabvbbvcbvdbvdbvebvfbvgbvhbvibvjbvkbvlbvmbvnbvobvpbvqbvrbvsbvtbvubvvbbXbbXbvwaWCarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqabqabqabqaaabccbdRbccbccbccbccbccbccbdRbccaaaaWDbvxbvybvzbfGbvAbvBbvCbvBbvDbfGbvEbvFbvGbvHbvHbvIbvJbvHbvHbvKbvLbvMbvNbvHbvHbvObvHbvHbvHbvPbvQbvRbvRbvSbvTbvUbvVbqcbyobvXbvYbqcbvZbwabwbbwcbwdboEbtQboEbypbywbwhbwibwjbwibwkbyJbyxbAbbyQbAkbwqbhwbwrbwsbwtbwubwvbhwbhwbhwbhybwwbwxbsmbwybwzbwAbsmbwBbwCbwDbwEbwFbwGbwHbwIbwJbwKbwLbwMbwNbwObwPbwQbwRbwSaoGbsubwTbwUbntbwVbwWbwXbwYbwZbxabxbbxcbxdbqUbxebxfbxgbxhbxiaWCaaaaaabxjbsNabqaaaaaaabqaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaabqaaabxkbxlbsLaaaabqaZhbxmbxnbxobxpbxqbxrbxsbxtbxubxvbxwbxxbxybxzbxAbxBbxCbxDbtfbxEbxFaXMaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqbccabqaaaabqaaabccbxGbccbxHbxIbfebxJbccbxGbccbccaWDbgVbxKbxLbfGbxMbvBbxNbvBbxObfGbxPbxQbxRbxSbxTbxUbxVbxWbxXbxYbxZbyabxTbxTbxTbybbxTbycbydbxVbyebxTbxTbyfbygbyhbvVbqcbyibyjbykbylbymbynbymbymbwdbAjbAebyqbyqbyqbyrbysbytbyubyvbyqbyqbyqbBWbCcbkWbhwbyybyzbyAbyBbyCbhwbyDbyEbyFbyGbwxbsnbyHbyIbCdbsmbyKbyLbyMbyNbspbspaoGaoGbyOaoGaoGaoGbyPbCeaoGaoGbyRbySaoGbyTbwTbyUbntbjNbjNbjNbjNbyVbjNbjNbyWbyXbyYbntbntbyZbzabzbbzcaaabqYbzdaaaabqaaaaaaabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqaaabxkbxlbsLabqbzebzfbzgbzhbzibzjbrgbzkbzlbzmbznbzobzpbrgbzqbzrbzsbrkbztbzubtfbtgaXMaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaabccbccbdQbccaWDbccbdRbccbzvbaBbzwbzxbccbdRbccbzybzzbzAbtlbtmbfGbzBbzCbtpbzCbzBbfGbzDbzEbzFbfGbzGbzHbzIbfGapfbzJapfbzKbzKbzLbzMbzNbzLbzKbzKbzKbzKbzKbzKdeDbzPbzQbzRbzSbzTbzUbzVbzWbzVbzXbzYbzZbAabCfbAcbAdbCibAdbAdbAfbAgbAhbyqbyqbAibyqbCkbAkbhwbAlbAmbAnbAobApbAqbhwbArbhtbAsbbrbAtbsmbsmbsmbsmbsmbAubAvbspbspbspbAwbAxbspbAybAzbAAaoGazpbABaoGbACbADbAEbAFbAGbAHbAIbAJbAKbALbAMbAKbANbAObjNbAPbAQbARbASbATbAUbAVbAWbAXbsJbAYbAZabqabqabqabqabqaaaabqaaaabqaaaabqaaaabqaaaaaaaaaaaaaaaaaaabqbpraaabxkbBabrbbBbbBcbrebpsaXIaXLbBdbBebBfbBgbBhbBibrgbrgbBjbBkbBlbrkbrkbBmbBnbBoaXMaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaabccbBpbaBbaCbBqbBrbaBbaBbBsbBtbchbBubBvbBvbBvbBwbBxbBybBzbBAbBBbBCbBDbBEbBFbBGbBBbBHbBIbBJbBKbBKbBLbBKbBKarKbBMbBNbzKbBObBPbBQbBRbBSbzKbBTbBUbzKbBTbBUbzKbzPbfIbkJbqcbBVbClbBXbqcbBYbBZbCabCbbwdbAkbDrbyqboEbDVbCgboEboEbAkbChbDWbCjbyqbEfbEgbhwbCmbCnbCobCpbCqbCrbCsbCtbhtbhybbrbhzbspbCubCvbCwbCxbCybCzbCAbspbCBbCCbCDbCEbCFbCGbCHaoGaoGaoGaoGaoGaoGbCIaoGbCJbCKbCLbCMbCNbCNbCNbCNbCNbCMbCMbCNbCObCPbCQbCRbCSbCTbCUbCVbCMbCMbCMabqaaaaaaaaaabqaaaabqaaaabqaaaabeaaaabeaaaaaaaaaaaaaaaaaaaaaabqabqabqabqabqabqabqarBbicaXIaXObCWaXLbCXbCYbCZbDabDbbDcbDdbDebDfbDgbDhbDibbXbbXbDjaXLaXLbnUaWCarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaabccbcdbcebcebDkbcebDlbDmbDnbDnbDobDnbDpbDqbEJbDsbDtbDubDvbDwbpBbDxbDybDzbDAbDBbDCbDDbDEbDFbDGbDHbDIbDJbBKbDKbDLanHbzKbDMbDNbBQbBRbBSbzKbDObDPbzKbDObDPbzKbDQbfIbkJbqcbqcbDRbqcbqcbqcbDSbDTbDUbqcbFJbtQbDXboEbwibwibDYbDZbEabEbbEcbEdbEebshbFUbEhbEibEjbEkbElbEmbEnbhwbEobhtbEpbbrbhzbspbEqbErbCybEsbCybEtbCybEubEvbCHbEwbExbEybEzbEAbEBbECbEDbEEbEFbEGbEHaoGbEIbwTbHCbCMbEKbELbEMbENbEObCMbEPbEQbERbESbETbEUbEVbEWbEXbEYbEZbFabCMabqabqabqabqabqabqabqaaaabeaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaZhbFdaXOaaaaXLbFebFfbFgbDabFhbFibFjbFkbFlbFmbFnbDaaXLaaaaaaaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqbccbccaWDbccbdQbccaWDbccbccbccaWDbccaWDaWDaWDbnWbnXapfbFoapfapfbFpbFqbFpbFrbFpbFpbFpbFpbBKbBKbFsbFtbBKbBKbBKbFuaoXbzKbFvbFwbBQbFxbzKbzKbFybzKbzKbFzbzKbzKbFAbfIbkJbFBbFCbFDbFEbFFbFGbFDbFDbFHbFIbAkbHDbAdbFKbFLbFMbFNbFObFPbFQbFRbFSbyqbFTbAkbhwbFVbFWbFXbFYbFZbGabhwbGbbhtbhybbrbhzbspbGcbGdbGebGdbGfbGgbGhbGibEvbCHbGjbGkbCHbEvbGlbGmbGnbGobGpbGqbEGbySaoGbGrbGsbGtbGubGvbGwbGxbGybGzbCMbGAbGBbGCbGDbETbGEbGFbGGbGHbGIbGJbGKbCMabqbGLbGLbGLbGLbGLabqaaabFcaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaZhbFdaXOaaaaXLbGMbGNbGObDabGPbGQbGRbGSbGTbGUbGVbDaaXLaaaaaaaUUbjPaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaabGWbGXbGXbGYbGXbGXbGXbGZbGXbGXbHaabqbccbHbbgVbHcapfbINbHJbHdbFpbHebHfbHgbHhbHibHjbFpbHkbHkbHlbHmbHnbHobBKbFubHpbzKbHqbHrbBQbBRbHsbHtbFwbHubHvbHwbHxbzLbzPbfIbkJbFBbHybHzbHAbHAbHAbHAbHAbHBbFIbKRbIObkWbkWbkWbHEbHFbHGbHHbHIbkWbkWbkWbPcbKRbhwbhwbEhbhwbhwbhwbhxbhwbHKbhtbHLbHMbhzbHNbHObHObHObHPbHObHQbHObHRbEvbEvbHSbEvbEvbCHbHTbHUbHVbHWbHXbHYbEGbCIaoGbHZbGsbIabIbbIcbIdbIebIfbIgbIhbIibIjbIkbIlbETbImbInbIobIpbIqbIrbIsbItbIubIvbIwbIxbIxbGLabqaaabFcaaabFbaaaabeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaZhbFdaXOaaaaXLaXLaXLaXLbDabIybIzbIAbFlbIBbICbIDbDaaXLaaaaZhbIEaWxbIFaWCarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabGWbIGbIHbIIbIJbIJbIKbIJbIJbIJbIKbGYbILbccbccbgVbIMapfbFubQZbIPbFpbIQbHfbHgbIRbISbITbFpbIUbIVbIWbIXbBKbBKbBKbFuatjbzKbIYbIZbBQbBRbBQbBQbBQbBQbBQbJabBQbzMbJbbJcbJdbJebJfbJgbJfbJhbJfbJgbJfbJibJjbJkbJlbJmbJnbJobJpbJpbJqbJrbJpbJsbJtbJubJvbJwbJxbJobJybJzbJobJAbJBbJobJCbJDbJEbJFbwxbJGbCybJHbCybJIbCybJJbCybJKbEvbEvbJLbEvbEvbJMbJNbHUbJObECbHXbJPbEGbCIaoGbJQbJRbyUbGubJSbIdbJTbIdbJUbJVbJWbJXbJYbJZbETbKabKbbKcbKdbKebKfbKgbETabqbETbKhbIxbKibGLabqaaabFcaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaZhbFdaXOaaaaaaaaaaaabKjbKkbKlbKlbKmbKnbKmbKlbKlbKobpvaXLaXLbnUbKpbKqaaaarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabKrbKsbKsbKsbKsbKsbKsbKsbKsbKsbKsbKtbKubKvbKubgVbKwapfbKxbKyanEbFpbKzbHfbHgbKAbHfbKBbFpbBKbKCbBKbHmbKDbKEbBKbFuathbzKbKFbHrbKGbKHbKIbKIbKIbKIbKIbKJbKIbKKbygbKLbKMbKNbKObKPbKObKQbSrbKSbKTbKUbKVbKWbKXbKObKYbKZbLabLbbLcbLdbLabLebLfbLgbLhbLibLjbLkbLlbLmbLnbLobLpbLibLqbLrbLsbLtbLubLvbLwbLxbLybLybLzbLAbLwbLBbLCbLDbLEbCHbLFbCHbLGbLHbLIbLJbLKbLLbLMbLNaoGbLObLPbLQbLRbLSbLTbLUbLVbLWbETbLXbLYbLZbMabMbbMcbIobMdbMebMfbMgbMhbMibMjbMkbMlbIxbMmbGLabqaaabFcaaabFbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaZhbFdbMnaUUaUUaaaaaaaXMbMobMpbMqbKmbMrbKmbMsbMtbMuaXMaaaaZhaXIaXObfcarBarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabMvbMwbMxbMybMzbMzbMAbMzbMzbMzbMAbGYbccbccbccbgVbMBapfbMCapfapfbFpbMDbMEbMFbHfbHfbHfbFpbMGbMHbBKbMIbBKbBKbBKbMJbMKbMLbFwbFwbJabMMbMNbFwbFwbFwbFwbMObMPbzLbzPbMQbMRbMSbMSbMTbMUbMVbMSbMSbMWbMWbMXbMYbMWbMZbNabNbbNcbMZbNdbNdbNebNfbNgbNdbNhbNibNjbNkbNhbNhbNlbNmbNnbNhbNobhtbNpbNqbNrbNsbNtbNubNtbNvbNwbCybCybHRbHSbEvbNxbNybNzbNybLDbNAbNBbNCbNDbNEbEGbNFaoGbNGbNHbNIbNJbNKbNLbNMbNNbNObNPbNQbNRbGIbGFbETbNSbNTbNUbNTbNUbNVbNWbETabqbGLbGLbGLbGLbGLabqaaabFcaaabFbaaabFcabfabeabqabeabfabfabeabeabfabfabfarBarBarBarBbicbNXaWxaWxbNYbrebreaXMbNZbOabObbKmbKnbKmbObbOabOcaXMaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaabMvbGXbGXbGYbGXbGXbGXbGZbGXbGXbOdabqbccbOebgVbOfapfbFuatjbOgbFpbOhbHgbOibOjbKBbHfbFpbOkbOlbBKbIUbOmbOnbBKbFuapdbzKbOobOobJabBRbOpbOpbOqbOrbOsbOtbzKbzKbJbbOubOvbMSbOwbOxbOybOzbOAbOBbOCbODbOEbOFbMWbOGbOHbOIbOJbOKbNdbOLbOMbONbOObOPbNhbOQbORbOSbOTbNhbNhbNhbNhbNhbOUbhtbNpbOVbOWbspbOXbOYbHObOZbPabHObPbbspbHSbPcbEvbEvbEvbEvbEvbPdbPebPfbPgbPhbEGbPiaxhbPjbPkbPlbPmbPnbPobPpbPqbPrbPsbPtbPubPvbPwbPwbPxbPybPzbIpbPAbPBbPCbItbIubIvbPDbPEbPEbGLabqabqbPFabqbPGabqbFcaaaaaaabqaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaarBaaabPHaXKaXNaXIaXOaaaaXMbPIbOabOabOabPJbOabOabOabPKaXMaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqbccbccaWDbccbdQbccaWDbccbccbccaWDbccaWDaWDaWDbPLbPMbPNbPObPPbPQbFpbPRbPSbOibPTbPUbPVbFpbBKbBKbBKbBKbBKbBKbBKbFuanHbzKbPWbPXbJabBRbFwbFwbPYbFwbPZbQabzKbQbbzPbfIbQcbMSbQdbQebQfbQgbQhbOBbQibQjbQkbQlbQmbQnbQobQobQobQpbQqbQrbQsbQtbQsbQubQvbQwbQxbQybQzbQAbQBbQCbQDbNhbQEbhtbQFbQGbQHbQIbQIbQIbQJbQKbQLbQMbQNbQIbQObQIbQPbQQbQRbQSbQTbEGbEGbQUbEGbEGbEGbNFbQVbQWbQXbQVbCMbCMbCMbCMbCMbQYbNObQZbRabRbbGGbRcbRdbRebRfbInbRgbRhbRibETabqbETbRjbRkbRlbGLabqaaabFcaaabFbaaabRmarBarBarBarBabearBarBarBarBabearBabqabearBarBarBarBarBaZhaXIaXOaaaaXMbRnbRobRpbOabRqbOabRrbRsbRtaXMaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaabccbRubzzbaCbRvbaCbaBbaBbRwbaBbzzbaBbRxbzzbaBbzAbRyapfbRzaoXatkbFpbRAbRBbHfbHfbHfbRCbFpbRDbREbRFbRGbRHbRIapfbFuauCbzKbRJbRKbJabRLbRMbRMbRNbFwbFwbRObzKbRPbzPbfIbOvbMSbRQbRRbRSbRTbRUbOBbRVbRWbRXbRYbMWbRZbSabSbbSabScbNdbSdbSebSfbSebSgbNhbShbSibSjbSkbSlbSmbSnbSobNhbSpbhtbSqbbrbOWbQIbSrbSsbStbSubSvbSwbSwbSxbSybQIbQIbQIbQIbQIbQIbQIbEGbSzbSAbSBbEGbSCbQVbSDbSEbSFbQVbSGbSHasMbSIbCMbSJbSKbSLbSMbSNbSObSPbSQbSRbSSbRgbSTbSUbMibMjbMkbSVbPEbSWbGLabqaaabFcaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfcbicbSXbbXbbXbSYbpvbSZbTabOabTbbOabTcbTdbKjbSYbbXbbXbTeaWCarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaabccbcdbcebcebcebcebcebTfbTgbThbDnbDnbTibTjbTkbTlbTmapfbgYauyatkbFpbHhbTnbHfbHfbTnbTobFpbTparJarLbTqbPQbRHapfbFubTrbzKbTsbTtbTubTvbFwbTwbTxbTybTzbTAbzKbTBbzPbfIbTCbMSbTDbTEbTFbTGbOBbOBbTHbTIbTJbTKbMWbRZbSabSabSabTLbNdbSdbSebTMbTNbTObNhbTPbSibTQbTRbNhbTSbTTbTUbNhbTVbhtbTWbbrbTXbTYbTZbUabUbbUcbUdbStbStbUebUfbQIbUgbUhbUibUhbUjbQIbUkbUlbUmbUnbEGbNFbQVbUobUpbUqbQVavBasJasJbUrbCMbSJbUsbUtbCNbCNbCNbUubGGbUvbGGbRgbUwbRibETabqbGLbGLbGLbGLbGLabqaaaabeaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaZhaXIaXOaaaaaaaXMbUxbOabOabOabUybUzbUAaXMaaaaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqbccbccbUBbUBbccbccbccaWDbccaWDbccaWDaWDapfbUCapfapfapfbgYauCatkbFpbTobUDbUEbHfbUEbUFbFpbUGathapdatjbUHaqwapfbFuaoXbzKbzKbzLbUIbUJbzLbzKbzKbzKbzKbUKbzKbzKbULbjnbUMbMSbUNbUObUPbUQbURbOBbUSbUTbUUbUVbMWbUWbUXbUYbUZbVabNdbVbbSebVcbVdbVebNhbVfbSibVgbVhbVibVjbVkbVlbNhbVmbhtbVnbbrbOWbVobVpbVqbVrbVsbVtbVubVqbUebVvbQIbVwbVxbVybVzbUjbQIbVAbVBbVCbVDbVEbVFbQVbVGbVHbVIbQVbVJbVKbVLbVMbCMbVNbVObRabVPbCNbVQbSRbGGbSPbVRbVSbVTbPCbItbIubIvbVUbVVbVWbGLabqaaabFcaaabFbaaabFcaaaaaaaaDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaZhaXIaXOaaaaaaaXMbVXbVYbVZbOabWabWbbVXaXMaaaaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaabccbWcbfdbccaaaabqaaaaaaaaaabqaaaaaaapfbWdbWebWfbWgbWhbWgbWibFpbFpbFpbFpbWjbFpbFpbFpbWkauyaoXapdbWlbWmapfbWnbWobzKbWpbWqbWrbWsbWtbWubWvbzKbWwbWxbWybzKbzPbfIbWzbMSbQdbTEbWAbWBbQdbOBbWCbWDbWEbWFbMWbWGbWHbWIbWJbWKbWLbWMbWNbWObWPbWQbNhbWRbWSbWTbWUbWVbWWbWXbWYbWZbXabhtbXbbbrbOWbVobXcbXdbXdbXebXfbXgbXhbXibXjbQIbXkbVxbXlbXmbXnbQIbXobXpbXqbXrbEGbNFbQVbQVbQVbQVbQVbXsasJasJbXtbCMbVNbVObRabXubXvbVQbXwbInbSPbXxbRgbXybRibETabqbETbXzbXAbXBbGLabqaaabFcaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaZhaXIaXOaaaaaaaXMbXCbKlbXDbXEbXFbKlbXGaXMaaaaaaaZhaXIaWCarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqabqbccbUBbUBbccabqabqabqabqabqabqabqabqapfbXHavUavUavUbDLathatkaoXaqBayBanHbXIbXJauCapfapfapfapfapfbXKapfapfbFuatjbzKbXLbXMbXNbXNbWsbXObXPbzKbXQbXRbXSbzKbDQbfIbXTbMSbQdbXUbXVbXWbXXbOBbXYbXZbYabMWbMWbYbbYcbYdbYebYfbNdbYgbSdbYhbYibYjbNhbYkbYlbYmbYnbSlbYobYobYpbNhbYqbhtbYrbbrbOWbQIbYsbYtbYubStbYvbYwbUcbYxbYybYzbYAbYBbYCbYDbYEbQIbEGbEGbEGbEGbEGbYFaoGbYGbUraucasJbYHaubbYIasJbCMbCMbYJbNRbVPbCNbYKbYLbGGbYMbVRbRgbYNbSUbMibMjbMkbYObVVbYPbGLabqaaabFcaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBbicbYQaXLaXLaXLbpubbXbbXbbXbcabbXbbXbbXbDjaXLaXLaXLbnUaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapfapfapfapfbWmbYRavUbYSbYTbYUbYVbYVbYVbYWbYXbYVbYTbYVbYYbYVbYZbYVaPTbZaapdbzKbZbbZcbZdbZebHrbZfbZgbzKbzKbzKbzKbzKbZhbfIbOvbZibMSbZjbZjbZjbMSbMSbMWbMWbZkbMWbMWbZlbZlbZlbZmbZlbZnbZnbZobZpbZnbZnbNhbNhbNhbNhbNhbNhbZqbZqbZqbNhbZrbhtbZsbbrbZtbZubZvbZvbZvbZwbZvbZvbZxbZybZvbZvbZvbZvbQIbZzbZAbZBbZCbZDbZEasJbZFbZGaoGbVLbZHbZIasJbYHasJasJarrbCMbZJbJWbZKbCNbCNbCNbZLbGGbZMbZNbRgbUwbRibETabqbGLbGLbGLbGLbGLabqabqbRmabqbPGabqabeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaZhaXIaXOaaaaaaaaaaaaaaaaaabZOaaaaaaaaaaaaaaaaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaabZPbZPbZQbZRbZSapfbZTapfapfapfaYabZUbZUbZUbZUbZUbZUbZUapdbZVbZWbZXbzKbZYbZZcaacabbHrbWscaccadcaeayBapfcafbzPcagcahcaicajcakcakcakcalcamcancaocakcapcaqcaicaicarcascarcarcatcarcaucavcavcawcaxcaycazcaAcaBcakcakcakcaCcaDcavcaEbbrcaFcaGcaHcaIcaJcaKcaLcaMcaNcaKcaOcaPcaQcaRbQIcaScaTcaUcaVcaWcaXcaYbZGcaZaoGaoGaoGaoGaoGcbacbbbCMbCMbCMcbcbJWbNRcbdcbecbfbKacbgcbhcbibVScbjbPCbItbIubIvcbkcblcblbGLabqaaabFcaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaZhaXIbMnaUUaUUaUUaUUaUUaUUbZOaUUaUUaUUaUUaUUaUUbjPaXIaWCarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaabMvbGXbGXbGYbGXbGXbGXbGZbGXbGXbOdabqbccbOebgVbOfapfbFuatjbOgbFpbOhbHgbOibOjbKBbHfbFpbOkbOlbBKbIUbOmbOnbBKbFuapdbzKbOobOobJabBRbOpbOpbOqbOrbOsbOtbzKbzKbJbbOubOvbMSbOwbOxbOybOzbOAbOBbOCbODbOEbOFbMWbOGbOHbOIbOJbOKbNdbOLbOMbONbOObOPbNhbOQbORbOSbOTbNhbNhbNhbNhbNhbOUbhtbNpbOVbOWbspbOXbOYbHObOZbPabHObPbbspbSsbTZbEvbEvbEvbEvbEvbPdbPebPfbPgbPhbEGbPiaxhbPjbPkbPlbPmbPnbPobPpbPqbPrbPsbPtbPubPvbPwbPwbPxbPybPzbIpbPAbPBbPCbItbIubIvbPDbPEbPEbGLabqabqbPFabqbPGabqbFcaaaaaaabqaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaarBaaabPHaXKaXNaXIaXOaaaaXMbPIbOabOabOabPJbOabOabOabPKaXMaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqbccbccaWDbccbdQbccaWDbccbccbccaWDbccaWDaWDaWDbPLbPMbPNbPObPPbPQbFpbPRbPSbOibPTbPUbPVbFpbBKbBKbBKbBKbBKbBKbBKbFuanHbzKbPWbPXbJabBRbFwbFwbPYbFwbPZbQabzKbQbbzPbfIbQcbMSbQdbQebQfbQgbQhbOBbQibQjbQkbQlbQmbQnbQobQobQobQpbQqbQrbQsbQtbQsbQubQvbQwbQxbQybQzbQAbQBbQCbQDbNhbQEbhtbQFbQGbQHbQIbQIbQIbQJbQKbQLbQMbQNbQIbQObQIbQPbQQbQRbQSbQTbEGbEGbQUbEGbEGbEGbNFbQVbQWbQXbQVbCMbCMbCMbCMbCMbQYbNObVpbRabRbbGGbRcbRdbRebRfbInbRgbRhbRibETabqbETbRjbRkbRlbGLabqaaabFcaaabFbaaabRmarBarBarBarBabearBarBarBarBabearBabqabearBarBarBarBarBaZhaXIaXOaaaaXMbRnbRobRpbOabRqbOabRrbRsbRtaXMaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaabccbRubzzbaCbRvbaCbaBbaBbRwbaBbzzbaBbRxbzzbaBbzAbRyapfbRzaoXatkbFpbRAbRBbHfbHfbHfbRCbFpbRDbREbRFbRGbRHbRIapfbFuauCbzKbRJbRKbJabRLbRMbRMbRNbFwbFwbRObzKbRPbzPbfIbOvbMSbRQbRRbRSbRTbRUbOBbRVbRWbRXbRYbMWbRZbSabSbbSabScbNdbSdbSebSfbSebSgbNhbShbSibSjbSkbSlbSmbSnbSobNhbSpbhtbSqbbrbOWbQIbVrbVsbStbSubSvbSwbSwbSxbSybQIbQIbQIbQIbQIbQIbQIbEGbSzbSAbSBbEGbSCbQVbSDbSEbSFbQVbSGbSHasMbSIbCMbSJbSKbSLbSMbSNbSObSPbSQbSRbSSbRgbSTbSUbMibMjbMkbSVbPEbSWbGLabqaaabFcaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfcbicbSXbbXbbXbSYbpvbSZbTabOabTbbOabTcbTdbKjbSYbbXbbXbTeaWCarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaabccbcdbcebcebcebcebcebTfbTgbThbDnbDnbTibTjbTkbTlbTmapfbgYauyatkbFpbHhbTnbHfbHfbTnbTobFpbTparJarLbTqbPQbRHapfbFubTrbzKbTsbTtbTubTvbFwbTwbTxbTybTzbTAbzKbTBbzPbfIbTCbMSbTDbTEbTFbTGbOBbOBbTHbTIbTJbTKbMWbRZbSabSabSabTLbNdbSdbSebTMbTNbTObNhbTPbSibTQbTRbNhbTSbTTbTUbNhbTVbhtbTWbbrbTXbTYbUabUabUbbUcbUdbStbStbUebUfbQIbUgbUhbUibUhbUjbQIbUkbUlbUmbUnbEGbNFbQVbUobUpbUqbQVavBasJasJbUrbCMbSJbUsbUtbCNbCNbCNbUubGGbUvbGGbRgbUwbRibETabqbGLbGLbGLbGLbGLabqaaaabeaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaZhaXIaXOaaaaaaaXMbUxbOabOabOabUybUzbUAaXMaaaaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqbccbccbUBbUBbccbccbccaWDbccaWDbccaWDaWDapfbUCapfapfapfbgYauCatkbFpbTobUDbUEbHfbUEbUFbFpbUGathapdatjbUHaqwapfbFuaoXbzKbzKbzLbUIbUJbzLbzKbzKbzKbzKbUKbzKbzKbULbjnbUMbMSbUNbUObUPbUQbURbOBbUSbUTbUUbUVbMWbUWbUXbUYbUZbVabNdbVbbSebVcbVdbVebNhbVfbSibVgbVhbVibVjbVkbVlbNhbVmbhtbVnbbrbOWbVobVtbVqbXcbYtbYsbVubVqbUebVvbQIbVwbVxbVybVzbUjbQIbVAbVBbVCbVDbVEbVFbQVbVGbVHbVIbQVbVJbVKbVLbVMbCMbVNbVObRabVPbCNbVQbSRbGGbSPbVRbVSbVTbPCbItbIubIvbVUbVVbVWbGLabqaaabFcaaabFbaaabFcaaaaaaaaDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaZhaXIaXOaaaaaaaXMbVXbVYbVZbOabWabWbbVXaXMaaaaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaabccbWcbfdbccaaaabqaaaaaaaaaabqaaaaaaapfbWdbWebWfbWgbWhbWgbWibFpbFpbFpbFpbWjbFpbFpbFpbWkauyaoXapdbWlbWmapfbWnbWobzKbWpbWqbWrbWsbWtbWubWvbzKbWwbWxbWybzKbzPbfIbWzbMSbQdbTEbWAbWBbQdbOBbWCbWDbWEbWFbMWbWGbWHbWIbWJbWKbWLbWMbWNbWObWPbWQbNhbWRbWSbWTbWUbWVbWWbWXbWYbWZbXabhtbXbbbrbOWbVobYubXdbXdbXebXfbXgbXhbXibXjbQIbXkbVxbXlbXmbXnbQIbXobXpbXqbXrbEGbNFbQVbQVbQVbQVbQVbXsasJasJbXtbCMbVNbVObRabXubXvbVQbXwbInbSPbXxbRgbXybRibETabqbETbXzbXAbXBbGLabqaaabFcaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaZhaXIaXOaaaaaaaXMbXCbKlbXDbXEbXFbKlbXGaXMaaaaaaaZhaXIaWCarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqabqbccbUBbUBbccabqabqabqabqabqabqabqabqapfbXHavUavUavUbDLathatkaoXaqBayBanHbXIbXJauCapfapfapfapfapfbXKapfapfbFuatjbzKbXLbXMbXNbXNbWsbXObXPbzKbXQbXRbXSbzKbDQbfIbXTbMSbQdbXUbXVbXWbXXbOBbXYbXZbYabMWbMWbYbbYcbYdbYebYfbNdbYgbSdbYhbYibYjbNhbYkbYlbYmbYnbSlbYobYobYpbNhbYqbhtbYrbbrbOWbQIbYvbYEbYwbStcbacbbbUcbYxbYybYzbYAbYBbYCbYDccrbQIbEGbEGbEGbEGbEGbYFaoGbYGbUraucasJchGchFbYIasJbCMbCMbYJbNRbVPbCNbYKbYLbGGbYMbVRbRgbYNbSUbMibMjbMkbYObVVbYPbGLabqaaabFcaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBbicbYQaXLaXLaXLbpubbXbbXbbXbcabbXbbXbbXbDjaXLaXLaXLbnUaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapfapfapfapfbWmbYRavUbYSbYTbYUbYVbYVbYVbYWbYXbYVbYTbYVbYYbYVbYZbYVaPTbZaapdbzKbZbbZcbZdbZebHrbZfbZgbzKbzKbzKbzKbzKbZhbfIbOvdeEbMSbZjbZjbZjbMSbMSbMWbMWbZkbMWbMWbZlbZlbZlbZmbZlbZnbZnbZobZpbZnbZnbNhbNhbNhbNhbNhbNhbZqbZqbZqbNhbZrdeFbZsbbrbZtbZubZvbZvbZvbZwbZvbZvbZxbZybZvbZvbZvbZvbQIbZzbZAbZBbZCbZDbZEasJbZFbZGaoGbVLbZHbZIasJbYHckgasJarrbCMbZJbJWbZKbCNbCNbCNbZLbGGbZMbZNbRgbUwbRibETabqbGLbGLbGLbGLbGLabqabqbRmabqbPGabqabeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaZhaXIaXOaaaaaaaaaaaaaaaaaabZOaaaaaaaaaaaaaaaaaaaZhaXIaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaabZPbZPbZQbZRbZSapfbZTapfapfapfaYabZUbZUbZUbZUbZUbZUbZUapdbZVbZWbZXbzKbZYbZZcaacabbHrbWscaccadcaeayBapfcafbzPcagcahcaicajcakcakcakcalcamcancaocakcapcaqcaicaicarcascarcarcatcarcaucavcavcawcaxcaycazcaAcaBcakcakcakcaCcaDcavcaEbbrcaFcaGcaHcaIcaJcaKcaLcaMcaNcaKcaOcaPcaQcaRbQIcaScaTcaUcaVcaWcaXcaYbZGcaZaoGaoGaoGaoGaoGcmHbXtbCMbCMbCMcbcbJWbNRcbdcbecbfbKacbgcbhcbibVScbjbPCbItbIubIvcbkcblcblbGLabqaaabFcaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaZhaXIbMnaUUaUUaUUaUUaUUaUUbZOaUUaUUaUUaUUaUUaUUbjPaXIaWCarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaabZScbmcbncbobZSapdcbpbPQcbqapfcbrbZUcbscbtcbucbvcbwbZUapdaoXbZWaoXbzKbzKbzKbzKbzKbzKbzKbzKbzKaxqaoXapfcbxbzPcbycbzbekbekbekbekbekbekbenbekcbAcbBcbCbembekbekbekbvTcbDcbEcbFbekbekbekbekbekcbGcbHbekbekbenbekbekbekbekcbIbekcbAcbJcbKcbLcbMcbNcbOcbNcbPcbPcbQcbRcbScbPcbOcbTbQIbQIbQIbQIcbUcbVasIarrcbWcbXasIcbXcbYcbZaoGayoaoGbCMccaccbcccccdcceccfccfccfbMcbGGbGGbGGbRgccgbRibETabqbETcchcciccjbGLabqaaabFcaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaZhcckaWxaWxaWxaWxaWxaWxaWxcclaWxaWxaWxaWxaWxaWxaWxccmaXOarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqbZSccnccoccpbZSapdccqccrapfapfccsbZUcctccuccvccwccxbZUapdapdccybYVbYTbYVbYYbYVcczccAccAccAccAccBbcGccCccDccEccFccGccHccIccJccGccGccGccKccGbdabcXccLbcYbcXbcXbcXccMccNbcZbcYbcXbcXbcXbdbccOccPccQccQccQccRccQccQccQccSccTccOccUccVccWccXccYccZcdacdbcdccddcdecdfcdgcdhcdecdibZvcdjcdkbZvcdlcbVasIasIasIasIasIcdmcdncdocdpcdqcdrcdscdtcducdvcdwcdxbGGbGGbGGbGGbGGbInbGGbRgcdybSUbMibMjbMkcdzcblcdAbGLabqaaabFcaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaaaaXKaXKaXKaXKaXKaXKaXKaXKcdBaXKaXKaXKaXKaXKaXKaXKaXKaaaarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqbZSccnccoccpbZSapdccqcmIapfapfccsbZUcctccuccvccwccxbZUapdapdccybYVbYTbYVbYYbYVcczccAccAccAccAccBbcGccCccDccEccFccGccHccIccJccGccGccGccKccGbdabcXccLbcYbcXbcXbcXccMccNbcZbcYbcXbcXbcXbdbccOccPccQccQccQccRccQccQccQccSccTccOccUccVccWccXccYccZcdacdbcdccddcdecdfcdgcdhcdecdibZvcdjcdkbZvcdlcbVasIasIasIasIasIcdmcdncdocdpcdqcdrcdscdtcducdvcdwcdxbGGbGGbGGbGGbGGbInbGGbRgcdybSUbMibMjbMkcdzcblcdAbGLabqaaabFcaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaaaaXKaXKaXKaXKaXKaXKaXKaXKcdBaXKaXKaXKaXKaXKaXKaXKaXKaaaarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaabZScdCcdDcdEbZScdFapdcdGapfcdHcdIbZUcdJcdKcdLcdMcdNbZUbZUbZUbZUbZUbZUcdObZUbZUcdPcdQcdRaoXauycdSauCcdTcdTcdTcdTcdTcdTcdTcdUcdUcdUcdUcdUcdVcdWcdWcdXcdYcdWcdZcdWceacebbbrceccedceecefceecegcehceeceeceibZubbgbbibbicejbZucekbZucelcemcelbZvcenceocdfcepceqcdecdfcercescetceubZvcevcewbZvcexceycezcdocdocdocdoceAceBceCceDceCceEbPmceFceGceHbGGceIbPwbPwbPwbPwbPwceJbGGbRgbUwceKbCMabqbGLbGLbGLbGLbGLabqaaabFcaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfcarBarBarBarBarBarBarBarBarBarBarBarBarBarBarBarBarBarBarBarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabeaaabZSceLceMceLbZSapfapfapfapfbZUceNbZUceOcePceQceRceSbZUceTceUceVbZUceWceXceYbZUceZbZUbZUbZUbZUbZUbZUcdTcfacfbcfccfdcfecffcdUcfgcfhcficdUcfjcfkcfjcflcfmcfjcfkcfjcfncfocfpcfqcfrcfscftcfscfucfvcfscftcfscfwcfxcfxcfxcfxcfxcfybZucfzcfAcfBcaHcfCcbOcdfcdhcdhcdecfDcdhcdhcdecfEbZvcfFcfGbZvcbUcfHcfIceCceCceEceCceCcfJcfKcfLcfKcfKbCMcfMcfNcfOcfPcfQbInbGGbGGceIbPwcfRbSSbRgcfSbRibCMabqabqabqabqabqabqabqabqbPFabqbPGabqbRmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaaaaaaceLcfTceLaaaabqaaaaaaaaabZUceNbZUbZUbZUbZUcfUbZUbZUcfVcfWcfVbZUbZUbZUbZUbZUcfXcfYbZUcfZcgacgbcgccgdcgecgfcggcgfcghcgicgjcgkcglcgmcgncgocgpcgqcgrcgscgtcgucgvcfkcgwcgxcgycftcgzcgAcgBcgCcgDcgEcgFcgGcgHcfxcgIcgJcgKcfxcgLbZucgMcgNcgOcgPcgQcgRcgScgTcgUcgRcgScgTcgTcgRcgVcgWcgXcgYcgZchacbVasIchbchccfKcfKcfKcfKcfKchdchechfbCMchgchhbGGbGGbSPchibIqbIqchjchkchjbIqchlchmbRibCMbCMbCMaUVaUUaUVaUUaUVaaabFcaaaabqaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabeabqabqceLceMceLabqabqabqabqabqbZUchnchochpbZUchqchrchsbZUchtchuchvchwchxchychzbZUchAchBchCchDchEchFchGchHchIchJchKchLchMchNchOcdUchPchQchRchSchTchUchVchWchXchYchZciacgwcgxcgycibciccidciecifcigcihcihciiciicijcikcilcimcfxcinbZuciocipciqcaHcirciscitciucivciuciwciucixciuciybZvcizciAciBciCcfJaoGaoGaoGcfKciDciEciFciGciHciIciJbCMciKciLciMciNciOciPciQciRciSciTciUciVciWciXbRiciYciZciYcjacjacjacjacjbabqabeaaaabqaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaacjcaaaaaaabqaaaabqaaabZUbZUbZUceNbZUcjdcjecjfcjgcjhcjicjjchychychscjkbZUcjlcjmbZUcdNcjncjocjpcdTcjqcjrcjscjtcjucjvcjwcjxcjxcjycjxcjzcjAcjBcjBcjCcjDcjEcjFcjGcjHcjIcjJcibciccicciccjKcjLcjMcjNcjOcjPcjQcjRcjScjTcfxcjUbZubZubZubZubZvbZvcjVbZvbZvbZvbZvbZvbZvbZvbZvbZvbZvbZvbZvbZvcjWcjXaoGcjYcjZcfKckackbckcckdckeckfckgbCMckhckhckickhckjckhckickkckjckjbRickhcklckmcknbCMbCMbCMckockpcjackqckoaaabFcaaaabqabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabeabqabqceLceMceLabqabqabqabqabqbZUchnchochpbZUchqchrchsbZUchtchuchvchwchxchychzbZUchAchBchCchDchEcmJcoQchHchIchJchKchLchMchNchOcdUchPchQchRchSchTchUchVchWchXchYchZciacgwcgxcgycibciccidciecifcigcihcihciiciicijcikcilcimcfxcinbZuciocipciqcaHcirciscitciucivciuciwciucixciuciybZvcizciAciBciCcfJaoGaoGaoGcfKciDciEciFciGciHciIciJbCMciKciLciMciNciOciPciQciRciSciTciUciVciWciXbRiciYciZciYcjacjacjacjacjbabqabeaaaabqaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaacjcaaaaaaabqaaaabqaaabZUbZUbZUceNbZUcjdcjecjfcjgcjhcjicjjchychychscjkbZUcjlcjmbZUcdNcjncjocjpcdTcjqcjrcjscjtcjucjvcjwcjxcjxcjycjxcjzcjAcjBcjBcjCcjDcjEcjFcjGcjHcjIcjJcibciccicciccjKcjLcjMcjNcjOcjPcjQcjRcjScjTcfxcjUbZubZubZubZubZvbZvcjVbZvbZvbZvbZvbZvbZvbZvbZvbZvbZvbZvbZvbZvcjWcjXaoGcjYcjZcfKckackbckcckdckeckfcqcbCMckhckhckickhckjckhckickkckjckjbRickhcklckmcknbCMbCMbCMckockpcjackqckoaaabFcaaaabqabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqabqaaackraaaaaaabqaaacksckscktckubZUckvckwckxbZUbZUbZUckyckzchyckAckBbZUbZUbZUckCckDbZUckEckEckEckEckEckEckEckFcjtckGckHckIcjxckJckKckLckMckNckOckPckQckRckSckTckUcgwckVcgycfsckWckXckYckZclaclbclccldclecfxclfclgclhcfxclicljcljcljclkcljcllclmclncljcljclocljcljcljcljclpclqclrclscdocltcluclvclwbVKcfKclxclyclzclAclBclCclDbCMbCMbCMclEbETclFbETclEbETclFclFclGbETclGbCMbCMbCMabqabqabqclHcjaaWCabqabqabqabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaabeabqclIabqabqabqaaaabqabqbZUcbtclJclKbZUbZUbZUclLbZUbZUbZUbZUbZUbZUbZUclMclNcjlclOclPckEclQclRclSclTclUckEclVclWclXclYclZcjxcmacmbcmccmdcmecmfcmgcmhcmicmjcmicmkcmlckVcmmcmncmocmocmocmocmpcmqcmrcmscmtcfxcmucmvcmwcfxcmxcmycmzcmzcmzcmzcmAcmzcmBcmBcmBcmBcmBcmBcmBcmBcmBcmCbZUcmDasJasJasJaoGasJazocfKcmEcmFcmGclAcmHcmIcmJclAabqabqcmKabqcmLabqcmKabqcmMcmNcmOabqcmOabqabqabqabqaaaaaacmPcjacmQaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaabeabqclIabqabqabqaaaabqabqbZUcbtclJclKbZUbZUbZUclLbZUbZUbZUbZUbZUbZUbZUclMclNcjlclOclPckEclQclRclSclTclUckEclVclWclXclYclZcjxcmacmbcmccmdcmecmfcmgcmhcmicmjcmicmkcmlckVcmmcmncmocmocmocmocmpcmqcmrcmscmtcfxcmucmvcmwcfxcmxcmycmzcmzcmzcmzcmAcmzcmBcmBcmBcmBcmBcmBcmBcmBcmBcmCbZUcmDasJasJasJaoGasJazocfKcmEcmFcmGclAcqrcqJcqIclAabqabqcmKabqcmLabqcmKabqcmMcmNcmOabqcmOabqabqabqabqaaaaaacmPcjacmQaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaarBaaacmRaaaabqaaaaaaabqaaabZUcmSbZUchnchocjecmTcjecjecmUcmVcmVcmVcmWcmVcmVcmVcmXcmYcmZcnacnbcnccndcnecnfckEcdTcngcnhcnicdTcjxcnjcnkcjxcnlcnmcmgcnncnocnpcnqcnrcmgcnscntcnucmocnvcnwcnxcnycnxcnzcmocnAcnBcnCcnDcnCcfxcfxcnEbZUcmzcnFcnGcnHcnIcnJcmBcnKcnKcnKcnLcnMcnNcnKcmBcmCbZUcnOasIcnPcnQaoGcnRcnScfKcnTcnUcnVclAclBcnWcnXclAabqbGLcnYbETcnYbGLcnYbETcnYbGLcnZbETcoabGLabqaaaabqabqabqcobcjacocabqabqabeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqarBaaacjcaaaabqaaaaaaabqaaabZUbZUbZUbZUbZUbZUbZUbZUbZUcodcoecoecofcogcogcogcogcohcogcogcogcoicojcokcolcomconcoocopcoqcorcoscotcoucovcowcoxcoycozcoAcoBcoCcoDcoEcmgcoFckVcmmcmpcoGcoHcoIcoJcoKcoLcmocoMcoNcoOcoPcmzcdNcjncoQcfYcmzcoRcoScoTcoUcoVcmBcnKcoWcoXcoYcnKcoZcpacmBcpbbZUbZUbZUbZUbZUaoGaoGaoGcfKcfKcfKcpcclAcpdcpecpfcpgabqbGLcphcpicpjbGLcpkcplcpmbGLcpncpocppbGLabqaaaabqaaabCMcpqcprcpscptaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaabeaaackrabqabqabqabqabqaaabZUcpucpvcpwcpxcpycpzcpAbZUcodcoecpBcpCcpDcpEcpFcoecpGcpHcpIcoecpJcpKcpLcpMcpNcpOcpPcpQcpRcpScpTcpUcpTcpScpTcpVcpWcpXcpYcpZcqacqbcqccmicnsckVcmmcmocqdcqecqfcqgcqhcqicqjcqkcqlcqmcqncmzcqocqpcqqcqrcmzcqscqtcqucqvcqwcmBcnKcnKcqxcnKcnKcqycqzcmBcmCbZUcqAcqBbZUcqCcqDcqEcqFcqGcqHaoGcqIclAclAcqJclAclAabqbGLcqKcqLcqMbGLcqNcqOcqPbGLcqQcqRcqSbGLabqabqabqabqcptcqTcqUcqVcqWabqabeabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaarBaaackrabqaaaaaaaaaabqaaacqXcqYcqZcracrbcpycrccrdbZUcodcoecrecrfcrgcrhcricrjcrkcrlcrmcoecrncrocrpcrqcrrcrscrtcrucrvcrwcrxcrycrycrycrzcrAcrBcrCcrDcpZcrEcrFcrGcmgcrHckVcrIcmocrJcrKcrLcrMcrNcrOcmocrPcrQcrRcrScmzcrTcrUcrVcrWcmzcrXcrYcrZcsacsbcmBcmBcsccsdcsecsecmBcsfcmBcsgcshcsicsjbZUcskasJasJasJcdKcslbZUcsmcsnclAcsoclAcspabqbGLcqKcsqcqKbGLcqNcsrcqNbGLcsscstcssbGLabqaaaabqaaacqWcqUcsucqUcjaaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqabqabqabqabqabeabqckrabqaaaaaaaaaabqaaacqXcsvcrccqZcswcpycsxbZUbZUcsycoecszcsAcszcsBcszcoecszcsCcszcoeckEcsDcsEcsFckEckEcsGcsHcsIcsJcsJcsKcsLcsMcsJcsJcsNcmgcsOcsPcsQcsRcmgcmgcsSckVcsTcmocmocsUcsVcsWcsXcsYcmocsZcnBcfwcfwcmzctacmzctbcmzcmzcfwctcctdcfwcfwctectfctgcthctictjctkctlcmBctmbZUctnctobZUctpcdKchschyctqctrbZUctscttctuctvctuarAabqbGLbGLbGLbGLbGLbGLbGLbGLbGLbGLbGLbGLbGLabqabqabqabqcjacqUcqUcqUcqWabqbFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaabqaaaaaaarBaaaclIaaaaaaaaaaaaabqaaacqXctwcqZcswctxcpyctyctzcdOcodcoectActBctCctDctEcoectFctGctHcoectIctJctKctLctMctNctOcgrctPcsJctQctRctSctTctUcsJccvcmgctVctWctXctYcmictZcuacubcuccudcuecufcugcuhcuicujcukculcumcuncuocupciccuqcurcusciccutcuucuvciccuwctecuxcuycuzcuAcuBcuCcuDcmBcmCbZUbZUcuEbZUcuFcuGchychycuHcuIcqXabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqaaaabqaaacjacqWcptbCMcptaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqarBaaacjcaaaabqaaaaaaabqaaabZUbZUbZUbZUbZUbZUbZUbZUbZUcodcoecoecofcogcogcogcogcohcogcogcogcoicojcokcolcomconcoocopcoqcorcoscotcoucovcowcoxcoycozcoAcoBcoCcoDcoEcmgcoFckVcmmcmpcoGcoHcoIcoJcoKcoLcmocoMcoNcoOcoPcmzcdNcjncrFcrvcmzcoRcoScoTcoUcoVcmBcnKcoWcoXcoYcnKcoZcpacmBcpbbZUbZUbZUbZUbZUaoGaoGaoGcfKcfKcfKcpcclAcpdcpecpfcpgabqbGLcphcpicpjbGLcpkcplcpmbGLcpncpocppbGLabqaaaabqaaabCMcpqcprcpscptaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaabeaaackrabqabqabqabqabqaaabZUcpucpvcpwcpxcpycpzcpAbZUcodcoecpBcpCcpDcpEcpFcoecpGcpHcpIcoecpJcpKcpLcpMcpNcpOcpPcpQcpRcpScpTcpUcpTcpScpTcpVcpWcpXcpYcpZcqacqbcrVcmicnsckVcrWcmocqdcqecqfcqgcqhcqicqjcqkcqlcqmcqncmzcqocqpcqqcsncmzcqscqtcqucqvcqwcmBcnKcnKcqxcnKcnKcqycqzcmBcmCbZUcqAcqBbZUcqCcqDcqEcqFcqGcqHaoGcsoclAclAcsRclAclAabqbGLcqKcqLcqMbGLcqNcqOcqPbGLcqQcqRcqSbGLabqabqabqabqcptcqTcqUcqVcqWabqabeabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaarBaaackrabqaaaaaaaaaabqaaacqXcqYcqZcracrbcpycrccrdbZUcodcoecrecrfcrgcrhcricrjcrkcrlcrmcoecrncrocrpcrqcrrcrscrtcructAcrwcrxcrycrycrycrzcrAcrBcrCcrDcpZcrEctBcrGcmgcrHckVcrIcmocrJcrKcrLcrMcrNcrOcmocrPcrQcrRcrScmzcrTcrUctSctEcmzcrXcrYcrZcsacsbcmBcmBcsccsdcsecsecmBcsfcmBcsgcshcsicsjbZUcskasJasJasJcdKcslbZUcsmcynclAcyqclAcspabqbGLcqKcsqcqKbGLcqNcsrcqNbGLcsscstcssbGLabqaaaabqaaacqWcqUcsucqUcjaaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqabqabqabqabqabeabqckrabqaaaaaaaaaabqaaacqXcsvcrccqZcswcpycsxbZUbZUcsycoecszcsAcszcsBcszcoecszcsCcszcoeckEcsDcsEcsFckEckEcsGcsHcsIcsJcsJcsKcsLcsMcsJcsJcsNcmgcsOcsPcsQcyCcmgcmgcsSckVcsTcmocmocsUcsVcsWcsXcsYcmocsZcnBcfwcfwcmzctacmzctbcmzcmzcfwctcctdcfwcfwctectfctgcthctictjctkctlcmBctmbZUctnctobZUctpcdKchschyctqctrbZUctscttctuctvctuarAabqbGLbGLbGLbGLbGLbGLbGLbGLbGLbGLbGLbGLbGLabqabqabqabqcjacqUcqUcqUcqWabqbFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaabqaaaaaaarBaaaclIaaaaaaaaaaaaabqaaacqXctwcqZcswctxcpyctyctzcdOcodcoeczqczpctCctDczJcoectFctGctHcoectIctJctKctLctMctNctOcgrctPcsJctQctRcABctTctUcsJccvcmgctVctWctXctYcmictZcuacubcuccudcuecufcugcuhcuicujcukculcumcuncuocupciccuqcurcusciccutcuucuvciccuwctecuxcuycuzcuAcuBcuCcuDcmBcmCbZUbZUcuEbZUcuFcuGchychycuHcuIcqXabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqaaaabqaaacjacqWcptbCMcptaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqabqaaaaaaabqaaaaaaabeaaacmRabqaaaaaaaaaabqaaacqXcqXcqZcpycpycqZcqZcuJcdOcodcoecuKcuLcuMcuNcuOcoecuPcuQcuRcuScuTcuUcuVcuWcuXcuYcuZcgrcgscsKcvacvbcvccvdcvecsJchscmgcvfcvgcvhcvicvjcvkcvlckVcvmcvncvocvpcvqcvrcvscvtcvucvvcvwcvxcvycvzcvAcvBcvCcvDcvEcvDcvFcvGcvHcvIcvJcvKcvLcvMcvNcvOcvPcvQcvRcvSbZUcvTcvUcvVcbvctqchychycvWcvXbZUcvYabqaaaaaaaaaabqaaaaaaaaaaaaaaaabqaaaaaaaaaabqaaaaaaaaaaaaabqaaaabqaaaaaaabqaaaabqaaaaaaabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaabqabqaaaaaaarBaaacjcaaaaaaaaaaaaabqaaacqXcvZcqZcwacqZcqZcsxbZUbZUcwbcwccwdcuLcwecuNcwfcwgcwhcwicwjcwkcwlcwmcwncwocwpcwqcwrcwscjAcwtcwucwvcwwcwxcwwcwycwzcmgcwAcwBcwCcwDcmicvkcvlckVcvmcwEcmpcwFcwGcwHcwIcwJcukcwKcwLcwMcwNcwOcwPcwQcwRcihcihcwScwTcwUcwVcwWcwXcwYcwZcxacxbcxccxdcxecmBcmCbZUcxfcxgcxhcsicxicuHcmDchycxjcqXaaaabqaaaaaaaaaabqabqabebFbbFbbFbbFbbFbbFbabebFbbFcbFbbPGabqbFcabqabqabebRmbRmbRmabeabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaabqaaaaaaarBaaackraaaaaaabqabqabqaaacqXcxkcpycracpycxlchscxmbZUcodcoecxncxocxpcxqcxrcoecxscxtcxucoecxvcxwcxxcxycxzctNcxAcgrcxBcsJcxCcxDcxEcxFcxGcsJcxHcmgcmgcxIcmgcmgcmgcmgcxJcxKcxLcmocmocmocmocmocxMcxNcmocmzcmzcxOcxPcxQcxRcxScxTcxUcxUcxUcxUcxVcxWcxXcxVcmBcmBcmBcxYcxZcyacybcmBcmCbZUcvTcycbZUcydcyecyfcygcygcyhbZUabqabqabqabqabqabqaaaabqaaaaaaaaaaaaaaaaaaaaaaaaabqaaaabqaaabFcaaaaaaabqaaaaaaabqaaaabqabqaaaaaDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBarBabqabearBaaaabearBarBabqabqabqckrabqabqabqaaaabqabqcqXcpycxlcpycyictqcyjcykcylcymcoecyncuLcyocypcyqcoecyrcxtcyscoecoecoecytcytcytcytcyucyvcywcyxcyycyzcyAcyBcyCcsJcyDcyEcyFcyGcyHcyIchBcyJcyKcyLcyMcyNcyOcyEcyPcyQcyRcyScyTcyUcyVcyWcyXcyYcyZczaczbczcczdczeczfcxVczgczhcziczjczkcmBcmBcmBcmBcmBcmBczlbZUbZUbZUbZUbZUbZUbZUcqXbZUbZUbZUaaaabqaaaaaaaaaabqabqabqabebFcbFcbFcabebFcbFcbFcabebFcbRmbFcbFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaczmaaaaaaaaaabqaaaaaaaaaabqaaaaaaabqaaaclIaaaaaaabqaaaabqaaacqXcqXcqXcqXbZUcznczobZUbZUcodcoeczpcuLcwdcuNczqcoecwdcxtcwdcwdczrcoeczscztczuczvcwrczwczxcsJczyczzczAczBczBczBczBczBczBczBczCczDczCczEczFczGczHczIczJczKczLbZUczMczMczNczMczMczOczPczQcyZczRczSczTczUczVczWcxVczXczYczZcAacAbcrUcfYclPbZUcAccmYcAdbZUcAecfYbZUaaaabqaaaaaaaaaaaaabqaaaabqaaaaaaaaaaaaaaaaaaaaaabqaaaabqaaaaaaabqaaaabqaaaabqaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaaacAfcAfcAfcAfcAfabqabqabqcAfcAfcAfcmRcAfaaaarBaaaabqaaaaaaaaaaaaabqbZUbZUbZUbZUcAgcodcwccwdcuLcwecuNcwdcAhcwdcAicwdcwdczrcoecAjcAkcAlcAmcAncAocApcsJcsJcsJcsJczBcAqcArcAscAtcAuczBcAvcAwcAxcAycAzcgxcAAbZUcABcACcADcAEczMcAFcAGcAHczMcAIcAJcAKcALcAMcANcAOcAPcAQcARcxVcAScATcAUcAVcAWcrUcAXcAYcAZcBackDcBbcAZcBccvWcqXabqabqabqabqabqabqabqabqabqaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabeabqcBdcBecBecBecBecBfckrcBgcBhcBhcBhcBhcBiabqabqabqabqabqabqabqabqaaaaaaaaaaaabZUcBjcBkcoecBlcBmcxpcBncBocoecxscwdcwdcwdcBpcoecBqcBrcBrcBrcBscBtcBucBvcBwcBxcByczBcBzcBAcBBcBCcBDczBcBEcBFcBGcBHcAzcgxcBIcBJcBKcBJcBJcBJczMcBLcBMcAGcBNcBOcBPcBQcBRcBScBTcBUcBUcBVcAQcxVcBWcATcBXcBYcBZcrUcCacCbbZUcCcchycCdbZUchycCebZUaaaabqaaaaaaaaaaaaabqabqaaaaaaaaaaaaaaaaaaaaaaaaabqaaDaaaaaaaaaaaaaaaaaaaaaaaaabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBabqcCfcCfcCfcCfcCfaaackraaacCfcCfcCfcCfcCfaaaarBaaaaaaaaaaaaabqabqaaaaaabZUbZUbZUchycBkcoecCgcChcCicCjcCkcoecClcwdcCmcCncCocoecCpcCqcCrcCscCtcCucCvcBvcCwcCxcCyczBcCzcCAcCBcCCcCDczBcCEcCFczCczCcCGcgxcmmcBJcCHcCIcCJcCKczMcCLcAGcCMczMcCNcCOcCPcxUcCQcCRcCScCTcCUcCVcxVcCWcCXcCYcCZcBYcrUbZUbZUbZUctmbZUcDabZUbZUbZUbZUabqabqaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaabqabqaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBarBabqabearBaaaabearBarBabqabqabqckrabqabqabqaaaabqabqcqXcpycxlcpycyictqcyjcykcylcymcoecAMcuLcyocypcCScoecyrcxtcyscoecoecoecytcytcytcytcyucyvcywcyxcyycyzcyAcyBcKYcsJcyDcyEcyFcyGcyHcyIchBcyJcyKcyLcyMcyNcyOcyEcyPcyQcyRcyScyTcyUcyVcyWcyXcyYcyZczaczbczcczdczeczfcxVczgczhcziczjczkcmBcmBcmBcmBcmBcmBczlbZUbZUbZUbZUbZUbZUbZUcqXbZUbZUbZUaaaabqaaaaaaaaaabqabqabqabebFcbFcbFcabebFcbFcbFcabebFcbRmbFcbFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaczmaaaaaaaaaabqaaaaaaaaaabqaaaaaaabqaaaclIaaaaaaabqaaaabqaaacqXcqXcqXbZUbZUcznczobZUbZUcodcoecMbcuLcwdcuNcMXcoecwdcxtcwdcwdczrcoeczscztczuczvcwrczwczxcsJczyczzczAczBczBczBczBczBczBczBczCczDczCczEczFczGczHczIcMYczKczLbZUczMczMczNczMczMczOczPczQcyZczRczSczTczUczVczWcxVczXczYczZcAacAbcrUcfYclPbZUcAccmYcAdbZUcAecfYbZUaaaabqaaaaaaaaaaaaabqaaaabqaaaaaaaaaaaaaaaaaaaaaabqaaaabqaaaaaaabqaaaabqaaaabqaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaaacAfcAfcAfcAfcAfabqabqabqcAfcAfcAfcmRcAfaaaarBaaaabqaaaaaaaaaaaabZUbZUbZUbZUbZUcAgcodcwccwdcuLcwecuNcwdcAhcwdcAicwdcwdczrcoecAjcAkcAlcAmcAncAocApcsJcsJcsJcsJczBcAqcArcAscAtcAuczBcAvcAwcAxcAycAzcgxcAAbZUcMZcACcADcAEczMcAFcAGcAHczMcAIcAJcAKcALcPkcANcAOcAPcAQcARcxVcAScATcAUcAVcAWcrUcAXcAYcAZcBackDcBbcAZcBccvWcqXabqabqabqabqabqabqabqabqabqaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabeabqcBdcBecBecBecBecBfckrcBgcBhcBhcBhcBhcBiabqabqabqabqabqabqabqabqbZUcFRcFScFRbZUcBjcBkcoecBlcBmcxpcBncBocoecxscwdcwdcwdcBpcoecBqcBrcBrcBrcBscBtcBucBvcBwcBxcByczBcBzcBAcBBcBCcBDczBcBEcBFcBGcBHcAzcgxcBIcBJcBKcBJcBJcBJczMcBLcBMcAGcBNcBOcBPcBQcBRcBScBTcBUcBUcBVcAQcxVcBWcATcBXcBYcBZcrUcCacCbbZUcCcchycCdbZUchycCebZUaaaabqaaaaaaaaaaaaabqabqaaaaaaaaaaaaaaaaaaaaaaaaabqaaDaaaaaaaaaaaaaaaaaaaaaaaaabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBabqcCfcCfcCfcCfcCfaaackraaacCfcCfcCfcCfcCfaaaarBaaaaaaaaaaaaabqabqbZUbZUbZUbZUbZUchycBkcoecCgcChcCicCjcCkcoecClcwdcCmcCncCocoecCpcCqcCrcCscCtcCucCvcBvcCwcCxcCyczBcCzcCAcCBcCCcCDczBcCEcCFczCczCcCGcgxcmmcBJcCHcCIcCJcCKczMcCLcAGcCMczMcCNcCOcCPcxUcCQcCRcPCcCTcCUcCVcxVcCWcCXcCYcCZcBYcrUbZUbZUbZUctmbZUcDabZUbZUbZUbZUabqabqaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaabqabqaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabeaaaabqaaaabqabqabqaaacDbaaaabqaaaabqaaaabqaaaarBaaaaaaaaaabqabqaaaabqaefbZUcDcbZUchycBkcoecoecoecoecoecoecoecoecDdcoecoecoecoecDecDfcDgcDhcDicDjcDkcDlcDmcDncDocDpcDqcDrcDscDtcDucDvcDwcDxcDyczCcmlcDzcDAcDBcDCcDDcDDcDEczMcDFcDFcDGczMcgCcCOcDHcxUcxUcxUcxUcxUcxUcxUcxVcxVcxVcDIcxVcxVcrUcAccDJcmYcDKbZUchycDLcDMcDNcDMckscksaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaaacAfcAfcAfcAfcAfabqckrabqcAfcAfcAfcAfcAfabqarBaaaaaaaaaabeaaaaaacDOcDPclJcDQcDRcDQcDScljcljcljcljcljcljcljcljcljcDTcDUcDUcDUcDUcDUcDUcDUcDVcDWcDXcDYcDZcEacEbcEccEdcEecEfcEgcEhcEicEjcEkcElcEmcEncgxcEocEpcEqcErcErcEsczMcEtcEucEuczMcEvcEwcExcEycEzcEAcEBcECcEDcEEcEFcEGcEHcEIcEJcEKcfZcELchychybZUbZUcEMbZUbZUbZUbZUabqaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqabqabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBabqcBdcBecBecBecBecBfckrcBgcBhcBhcBhcBhcBiabqaupabqabqabqarBabqabqabqabqbZUcENbZUcdNckDchychycEObZUbZUbZUbZUbZUcEPcEQcDUcERcEScETcEUcEVcDUcEWcEXcEYcBvcEZcFacFbczBcFccFdcFdcFdcFeczBcFfcFgcFhcFicFjcFkcFlcBJcFmcCIcFncFoczMcFpcFqcFrcBNcFscFtcFucFvcFwcFxcFycFzcFAcFBcFCcFDcFBcFEcFFcEKbZUcFGbZUcFHcFHcFIcFJcFKcFLcFMabqabqaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqcFNcFOcFNabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBabqcCfcCfcCfcCfcCfaaaclIabqcCfcCfcCfcCfcCfaaaarBaaaaaaaaaabqaaaaaaaaaaaabZUbZUbZUcfZbZUcjncFPcFQbZUcFRcFScFRbZUcFTcFUcFVcFWcFXcFYcFZcGacGbcGccGdcGecBvcGfcGgcGhczBcGicGjcGkcGlcGmczBcGncGocGoczCcGpcGqcGrcGscGtcGucGvcGwczMcGxcGycGzcGAcGBcGCcGDcGEcGFcGGcGHcGIcGIcGJcGKcGLcGMcGNcGOcGPcGQcGRcGScGTcGUcGVcGVcGVcGWcGXabqaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqcFOcFNcGYcFNcFOabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaupaaaabqaaaabqaaaabqaaacmRaaaabqaaaabqabqabqabqaupaaaaaaaaaabqaaaaaaaaaaaaabqaaabZUbZUbZUbZUbZUbZUbZUbZUbZUbZUbZUckDcGZcDUcHacHbcHccHdcHecHfcHgcHhcHicBvcBvcHjcBvczBczBczBczBczBczBczBcHkczCczCcHlcHmczGczHcHncHocHocHpcHqczMcHrcHscHtcHucHvcHwcHxcHycHzcHAcHBcHCcHDcHEcHFcHGcHHcHIcHJcHKcHLcHMcHNcHOcHPcHQcHRcHScHTcGXabqabqaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqcHUcFOcHVcHWcHXcFOcHUabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaaacAfcAfcAfcAfcAfabqcHYabqcAfcAfcAfcAfcAfabqarBaaaaaaaaaabeabqcHZcHZcHZcIacHZcHZcHZaaaabqaaaaaaaaaabqaaaaaabZUcIbcEQcDUcIccIdcHbcIecIfcDUcIgcIhcIicDUcIjcIkcIlcImcIncIocIncIpcIncIqcIocIrcImcIscnscgxcItcBJcIucIvcIwcIucIxcIxcIxcIxcIxcIycxPcIzcEycIAcIAcIBcICcIDcIEcIFcIGcIHcIIcIJcEKcIKcILcIMcEycINcGXcGXcFHcGXcFHarAabqaaaaaaabqaaaaaaabqabqabqaaaaaaaaaaaaaaaabqaaaabqaaaaaaaaaaaaaaaaaaaaaaaaabqaaaabqaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaabqabqcFOcFOcIOcIPcIPcIPcIQcFOcFOabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBabqcBdcBecBecBecBecBfckrcBgcBhcBhcBhcBhcBiabqarBaaaabqabqarBaaacHZcIRcIScIRcITcIRcHZcHZcIacHZcIacHZcHZabqabqbZUclPcEQcDUcDUcDUcDUcDUcDUcDUcIUcIVcIWcIXcIYcIZcJacImcJbcJccIncIocIncJdcJecJfcImcJgcnscgxcvmcwEcJhcJicJjcJkcJlcJmcJncJocJpcJqcCOczQcEKcEKcEKcEKcEKcEKcJrcJscJtcJucJvcJwcEKbZUcFGbZUcFHcJxcJycJzcJAcJBarAarAabqabqabqabqabqabqabqaaaabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqcJCcJDcJCcIPcJEcIPcJFcJGcFNabqabqabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBabqcCfcCfcCfcCfcCfaaaclIaaacCfcCfcCfcCfcCfaaaaupabqabqaaaarBabqcHZcJHcJIcJJcJKcJHcJLcJMcJNcJOcJPcJQcHZaaaaaabZUbZUcJRcJScJScJTcJScJUcJVcJWcJXcJYcJZcKacKbcKccKdcKecKfcKgcKfcKfcKhcKicKjcKkcKlcKmcKncFkcKocKpcKqcKrcKscKtcKtcKtcKucKvcJpcgCcCOcKwcEKcKxcKycKzcKAcKBcKCcKBcKDcKEcKFcEKcrUcKGccscfYcFHcFHcFHcFHcFHcKHcKIarAabqaaaaaaaaaaaaaaaabqabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaabqabqcFOcFOcKJcIPcIPcIPcKKcFOcFOabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaaaaaaabqabqabqaaaaaacKLabqaaaaaaabqabqaaaaaaarBaaaaaaaaaabeaaacHZcKMcKNcKOcKPcKMcKMcKQcKRcKScKTcKUcHZaaaaaaaaacrUcrUcrUcrUcrUbZUcKVcDUcDUcKWcKXcKYcDUcKZcLacLbcImcLccIocIncIocIncLdcLecLfcLgcLhcLicLjcLkcIxcIxcLlcLmcLncLocLpcLqcLrcJpcLscLtcLucGXcKxcKycLvcLvcLwcLxcLycLzcJucLAcEKcdNcLBceNchycLCbZUabqabqabqabqabqabqabqaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqcHUcFOcLDcLEcLFcFOcHUabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaupaaaaaaaaaaaaaaaaaaaaacKLaaaaaaaaaaaaabqaaaaaaaupaaaaaaaaaarBabqcHZcLGcLHcLIcLJcLKcLLcLMcLNcLOcLPcLQcLRcLScLScLScLRcLTcLUcLVcHZcLWcLXcDUcLYcLZcMacMbbZUbZUbZUbZUcImcIncIocIncMccIncMdcMecMfcImcMgcMhcgxcmmcIxcMicMjcMkcLocLocMlcMmcMncJpcMocMpcMqcEKcKxcKycLvcMrcKBcMscKBcMtcMucMvcEKcMwchyceNchycMxbZUabqaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqcFOcFNcMycFNcFOabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBabearBarBarBaaaaaaaaacKLaaaaaaaaaarBarBarBauparBabqabqaaaarBaaacIacMzcMAcMBcMCcMDcMEcMFcMGcMHcMIcMJcMKcMLcMMcMNcMOcMPcMBcMQcMRcMScMTcMUcMScMVcMWcMXcMYcMZcNacNbcImcImcImcImcImcImcImcNccImcImbZUcNdcgxcmmcIxcNecMjcLocLpcLocNfcNgcNhcNicNjcNkcNlcNmcNncNncNncNncNncNocNncNpcNqcNrcEKchychycNschybZUbZUbZUabqabqaaaaaaabqaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqcFNcFOcFNabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaabqaaaaaaaaaarBabqcNtabqarBaaaaaaabqaaaaaaabqaaaabqabqabqaaacHZcNucNvcNwcNxcNycNzcNAcNBcNCcNDcNEcHZcIacIacIacHZcNFcNGcNHcHZcNIcNJcDUcNKcNLcNMcNNbZUcNOcNPcNQbZUcNRcmVcNScmWcmVcNTcNUcDJcmZcNVcNWcNXcBIcIxcNYcNZcOacOacOacObcOccOdcOecOfcOgcOhcOicOjcOkcOlcOmcOncOocOpcOqcOrcOscOtcmYcmYcOucOvcOwcOxbZUbZUbZUcksaaaabqaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqabqabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaarBaaaabqaaaarBaaaaaaabqabqabqabqaaaaaaaaaabqabqcHZcOycOzcKMcOAcOycOBcOCcODcOEcOFcOGcHZcOHaaaaaacrUcrUcrUcrUcrUbZUcOIcDUcDUcDUcDUcDUbZUcOJcOKcOLbZUcOMbZUbZUbZUbZUbZUbZUbZUbZUczIcONcOOcOPcOQcORcOScOTcOUcOVcOWcLpcOXcOYcOZcPacPbcPccPdcPecPfcPgcPhcPicOpclNcPjbZUbZUbZUbZUbZUcPkcPlcPmclJcPnclJcPoabqabqaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBarBarBarBarBaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaacHZcPpcPqcKMcPqcPrcPscKMcKMcPtcKMcKMcHZabqabqabqbZUcjncfZcPucPvcPwcPxcmYcPycPzcPAcPBbZUcPCcPDcPEcPFcPGbZUcPHcPIcPJbZUcPKcPLcPMbZUcPNcPOcPPcIxcPQcPRcPScPTcPUcPVcLpcPWcIxcPXcPYciccPccPZcQacQbcQccQdcQecOpchycQfbZUcQgcQhcQibZUcQjcQkcQlbZUbZUbZUcksaaaabqaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabeaaacHZcQmcQncKMcQocQpcPscQqcQrcQscQtcQucHZaaaabqaaabZUcQvcQwcQxcQycQzcQAcQBcQAcQAcQCcQfbZUbZUbZUbZUbZUcOMbZUcQDcQEcQFcQGcQHcQIcQJcQKcQLcQMcQNcIxcIxcIxcIxcIxcQOcIxcQPcrUcrUcfwcQQcfwcOpcOpcOpcOpcOpcOpcOpcOpchycQRcQScQTcQUcQVcQWcQWcQXcQYcQWaaaaaaaaaaaaabqabqaaaaaaabqaaaaaaabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaaacHZcQZcRacKMcRacQZcRbcRccRdcRecRfcRgcIaaaaaaacRhbZUcRibZUbZUbZUcRjbZUbZUbZUbZUcRkcRlcRmcRncRocRmcRpcRqcRrcRscRtcRucRvcRwcRxcRycRycRzcRAcRBcRCcRDcREcmYcmYcRFcmYcRGcmZcRHcRIcRJcRIcRKcjNcjNcRLcRMcOtcmYcmYcmYcRNbZUcnOcROcRPcQWcRQcRRcRScQWabqabqabqabqabqabqabqabqabqabqabqabqaaDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacRTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqcHZcHZcIacHZcIacHZcRUcRVcRWcRXcRYcRZcHZabqabqcRhcSacSbcRhcSccSdcSecSfcSgcShbZUbZUbZUbZUcSibZUbZUbZUbZUbZUcSjcRtcSkcRtcSlcSmcSncRtcSocSpcSqbZUbZUbZUbZUbZUbZUcCdcSrcfZbZUcSscStcSucfwcicciccSvbZUbZUbZUbZUbZUbZUbZUbZUbZUcuEcQWcSwcSxcSycQWaaaabqaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabeaaaabqabqabqcSzcSAcSBcSCcSDcSEcSFcSGcSHcHZaaaaaacRhcSIcSJcRhcSKcSLcSMcSNcRhcRhcSOcSPcSQcSRcSScSRcSTcSUcSVcSWcSXcRtcSkcRtcSYcSZcTacRtcTbcTccTdcTecTfcTgcThcTibZUcTjbZUbZUbZUcTkcTlcTmcfwcfwcfwcTnbZUcTocTpcTqbZUcTrcTscTtbZUctocQWcTucTvcTwcQWaaaabqaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaaaabqaaaaaacTxabqbCWcHZcHZcHZcHZcHZcHZcHZaaaaaacRhcTycTzcRhcTAcTBcTCcTDcRhcTEcTFcTGcTHcTIcTJcTKcTLcTLcTMcTNcTOcTPcTQcRtcSYcTRcTacRtcSocSpcSYcTScTTcRtcTUcTVbZUcTWbZUabqaaacTXcTYcTXaaaaaacTZcSvbZUcmDchychycUacjicUbcjicUccUdcQWcUecUfcUecQWaaaabqaaaabqabqaaaaaaabqaupaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBabqcCfcCfcCfcCfcCfaaaclIabqcCfcCfcCfcCfcCfaaaarBaaaaaaaaaabqaaaaaaaaaaaabZUbZUbZUcfZbZUcjncFPcFQbZUcPGcNacNbbZUcFTcFUcFVcFWcFXcFYcFZcGacGbcGccGdcGecBvcGfcGgcGhczBcGicGjcGkcGlcGmczBcGncGocGoczCcGpcGqcGrcGscGtcGucGvcGwczMcGxcGycGzcGAcGBcGCcGDcGEcGFcGGcGHcGIcGIcGJcGKcGLcGMcGNcGOcGPcGQcGRcGScGTcGUcGVcGVcGVcGWcGXabqaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqcFOcFNcGYcFNcFOabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaupaaaabqaaaabqaaaabqaaacmRaaaabqaaaabqabqabqabqaupaaaaaaaaaabqaaaaaaaaaaaaabqaaabZUbZUbZUbZUbZUbZUbZUcNOcNPcNQbZUckDcGZcDUcHacHbcHccHdcHecHfcHgcHhcHicBvcBvcHjcBvczBczBczBczBczBczBczBcHkczCczCcHlcHmczGczHcHncHocHocHpcHqczMcHrcHscHtcHucHvcHwcHxcHycHzcHAcHBcHCcHDcHEcHFcHGcHHcHIcHJcHKcHLcHMcHNcHOcHPcHQcHRcHScHTcGXabqabqaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqcHUcFOcHVcHWcHXcFOcHUabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaaacAfcAfcAfcAfcAfabqcHYabqcAfcAfcAfcAfcAfabqarBaaaaaaaaaabeabqcHZcHZcHZcIacHZcHZcHZaaaabqaaaaaabZUcOJcOKcOLbZUcIbcEQcDUcIccIdcHbcIecIfcDUcIgcIhcIicDUcIjcIkcIlcImcIncIocIncIpcIncIqcIocIrcImcIscnscgxcItcBJcIucIvcIwcIucIxcIxcIxcIxcIxcIycxPcIzcEycIAcIAcIBcICcIDcIEcIFcIGcIHcIIcIJcEKcIKcILcIMcEycINcGXcGXcFHcGXcFHarAabqaaaaaaabqaaaaaaabqabqabqaaaaaaaaaaaaaaaabqaaaabqaaaaaaaaaaaaaaaaaaaaaaaaabqaaaabqaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaabqabqcFOcFOcIOcIPcIPcIPcIQcFOcFOabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBabqcBdcBecBecBecBecBfckrcBgcBhcBhcBhcBhcBiabqarBaaaabqabqarBaaacHZcIRcIScIRcITcIRcHZcHZcIacHZcIacHZcHZcPDcPEcPFcjicQKcDUcDUcDUcDUcDUcDUcDUcIUcIVcIWcIXcIYcIZcJacImcJbcJccIncIocIncJdcJecJfcImcJgcnscgxcvmcwEcJhcJicJjcJkcJlcJmcJncJocJpcJqcCOczQcEKcEKcEKcEKcEKcEKcJrcJscJtcJucJvcJwcEKbZUcFGbZUcFHcJxcJycJzcJAcJBarAarAabqabqabqabqabqabqabqaaaabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqabqcJCcJDcJCcIPcJEcIPcJFcJGcFNabqabqabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBabqcCfcCfcCfcCfcCfaaaclIaaacCfcCfcCfcCfcCfaaaaupabqabqaaaarBabqcHZcJHcJIcJJcJKcJHcJLcJMcJNcJOcJPcJQcHZbZUbZUbZUbZUcJRcJScJScJTcJScJUcJVcJWcJXcJYcJZcKacKbcKccKdcKecKfcKgcKfcKfcKhcKicKjcKkcKlcKmcKncFkcKocKpcKqcKrcKscKtcKtcKtcKucKvcJpcgCcCOcKwcEKcKxcKycKzcKAcKBcKCcKBcKDcKEcKFcEKcrUcKGccscfYcFHcFHcFHcFHcFHcKHcKIarAabqaaaaaaaaaaaaaaaabqabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaabqabqcFOcFOcKJcIPcIPcIPcKKcFOcFOabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaaaaaaabqabqabqaaaaaacKLabqaaaaaaabqabqaaaaaaarBaaaaaaaaaabeaaacHZcKMcKNcKOcKPcKMcKMcKQcKRcKScKTcKUcHZaaaaaaaaacrUcrUcrUcrUcrUbZUcKVcDUcDUcKWcKXcRocDUcKZcLacLbcImcLccIocIncIocIncLdcLecLfcLgcLhcLicLjcLkcIxcIxcLlcLmcLncLocLpcLqcLrcJpcLscLtcLucGXcKxcKycLvcLvcLwcLxcLycLzcJucLAcEKcdNcLBceNchycLCbZUabqabqabqabqabqabqabqaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqcHUcFOcLDcLEcLFcFOcHUabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaupaaaaaaaaaaaaaaaaaaaaacKLaaaaaaaaaaaaabqaaaaaaaupaaaaaaaaaarBabqcHZcLGcLHcLIcLJcLKcLLcLMcLNcLOcLPcLQcLRcLScLScLScLRcLTcLUcLVcHZcLWcLXcDUcLYcLZcMacSBcRUcRUcRUcRUcImcIncIocIncMccIncMdcMecMfcImcMgcMhcgxcmmcIxcMicMjcMkcLocLocMlcMmcMncJpcMocMpcMqcEKcKxcKycLvcMrcKBcMscKBcMtcMucMvcEKcMwchyceNchycMxbZUabqaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqcFOcFNcMycFNcFOabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBabearBarBarBaaaaaaaaacKLaaaaaaaaaarBarBarBauparBabqabqaaaarBaaacIacMzcMAcMBcMCcMDcMEcMFcMGcMHcMIcMJcMKcMLcMMcMNcMOcMPcMBcMQcMRcMScMTcMUcMScMVcMWcWGcSCcWIcWHcYocRUcImcImcImcImcImcImcNccImcImbZUcNdcgxcmmcIxcNecMjcLocLpcLocNfcNgcNhcNicNjcNkcNlcNmcNncNncNncNncNncNocNncNpcNqcNrcEKchychycNschybZUbZUbZUabqabqaaaaaaabqaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqcFNcFOcFNabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaabqaaaaaaaaaarBabqcNtabqarBaaaaaaabqaaaaaaabqaaaabqabqabqaaacHZcNucNvcNwcNxcNycNzcNAcNBcNCcNDcNEcHZcIacIacIacHZcNFcNGcNHcHZcNIcNJcDUcNKcNLcNMcNNdegdeidehdejcRUcNRcmVcNScmWcmVcNTcNUcDJcmZcNVcNWcNXcBIcIxcNYcNZcOacOacOacObcOccOdcOecOfcOgcOhcOicOjcOkcOlcOmcOncOocOpcOqcOrcOscOtcmYcmYcOucOvcOwcOxbZUbZUbZUcksaaaabqaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqabqabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaarBaaaabqaaaarBaaaaaaabqabqabqabqaaaaaaaaaabqabqcHZcOycOzcKMcOAcOycOBcOCcODcOEcOFcOGcHZcOHaaaaaacrUcrUcrUcrUcrUbZUcOIcDUcDUcDUcDUcDUcRUdeldekdemcRUcOMbZUbZUbZUbZUbZUbZUbZUbZUczIcONcOOcOPcOQcORcOScOTcOUcOVcOWcLpcOXcOYcOZcPacPbcPccPdcPecPfcPgcPhcPicOpclNcPjbZUbZUbZUbZUbZUdencPlcPmclJcPnclJcPoabqabqaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBarBarBarBarBaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaacHZcPpcPqcKMcPqcPrcPscKMcKMcPtcKMcKMcHZabqabqabqbZUcjncfZcPucPvcPwcPxcmYcPycPzcPAcPBcRUdepdeodeqcRUcOMbZUcPHcPIcPJbZUcPKcPLcPMbZUcPNcPOcPPcIxcPQcPRcPScPTcPUcPVcLpcPWcIxcPXcPYciccPccPZcQacQbcQccQdcQecOpchycQfbZUcQgcQhcQibZUcQjcQkcQlbZUbZUbZUcksaaaabqaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabeaaacHZcQmcQncKMcQocQpcPscQqcQrcQscQtcQucHZaaaabqaaabZUcQvcQwcQxcQycQzcQAcQBcQAcQAcQCcQfcRUcRUdercRUcRUcOMbZUcQDcQEcQFcQGcQHcQIcQJdescQLcQMcQNcIxcIxcIxcIxcIxcQOcIxcQPcrUcrUcfwcQQcfwcOpcOpcOpcOpcOpcOpcOpcOpchycQRcQScQTcQUcQVcQWcQWcQXcQYcQWaaaaaaaaaaaaabqabqaaaaaaabqaaaaaaabqabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaaacHZcQZcRacKMcRacQZcRbcRccRdcRecRfcRgcIaaaaaaacRhbZUcRibZUbZUbZUcRjbZUbZUbZUbZUcRkcRlcRmcRndetcRmcRpcRqcRrcRscRtcRucRvcRwcRxcRycRycRzcRAcRBcRCcRDcREcmYcmYcRFcmYcRGcmZcRHcRIcRJcRIcRKcjNcjNcRLcRMcOtcmYcmYcmYcRNbZUcnOcROcRPcQWcRQcRRcRScQWabqabqabqabqabqabqabqabqabqabqabqabqaaDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacRTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqcHZcHZcIacHZcIacHZdeucRVcRWcRXcRYcRZcHZabqabqcRhcSacSbcRhcSccSdcSecSfcSgcShbZUbZUbZUbZUcSibZUbZUbZUbZUbZUcSjcRtcSkcRtcSlcSmcSncRtcSocSpcSqbZUbZUbZUbZUbZUbZUcCdcSrcfZbZUcSscStcSucfwcicciccSvbZUbZUbZUbZUbZUbZUbZUbZUbZUcuEcQWcSwcSxcSycQWaaaabqaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabeaaaabqabqabqcSzcSAdewdevcSDcSEcSFcSGcSHcHZaaaaaacRhcSIcSJcRhcSKcSLcSMcSNcRhcRhcSOcSPcSQcSRcSScSRcSTcSUcSVdexcSXcRtcSkcRtcSYcSZcTacRtcTbcTccTdcTecTfcTgcThcTibZUcTjbZUbZUbZUcTkcTlcTmcfwcfwcfwcTnbZUcTocTpcTqbZUcTrcTscTtbZUctocQWcTucTvcTwcQWaaaabqaaaaaaaaaaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarBaaaabqaaaaaacTxabqdeycHZcHZcHZcHZcHZcHZcHZaaaaaacRhcTycTzcRhcTAcTBcTCcTDcRhcTEcTFcTGcTHcTIcTJcTKcTLcTLcTMcTNcTOcTPcTQcRtcSYcTRcTacRtcSocSpcSYcTScTTcRtcTUcTVbZUcTWbZUabqaaacTXcTYcTXaaaaaacTZcSvbZUcmDchychycUacjicUbcjicUccUdcQWcUecUfcUecQWaaaabqaaaabqabqaaaaaaabqaupaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabeabqabqabqaaaaaaaaaabqabqabqaaaaaaaaaabqaaaaaaaaacRhcUgcUhcUicUjcUkcUlcUmcRhcUncRhcUocUpcUqcUrcUscTHcTHcUtcUucUvcUwcUxcUycSYcUzcTacRtcSocUAcUBcUCcUDcUEcUFcUGbZUcTjbZUabqabqcTXcUHcTXabqaaacTZcUIbZUchychychycUJcUKcctcULbZUcqXcQWcUecUMcUeabqaaaabqaaaaaaabqabqabqabqarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabeaaaaaaaaaaaaaaaabqaaaaaaaaaabqaaaaaaaaacRhcTycUNcRhcUOcUPcUQcURcUScUTcRhcUUcUVcUWcUXcUYcUZcVacVbcSWcTacRtcVccVdcVecVfcVgcUwcVhcVicVjcVkcVkcVlcVmcVkbZUaefabqaaaaaacTXcVncTXaaaaaacTZcSvbZUcVocVpcVqbZUcVrcVscVqbZUaaaabqcUecUfcUeabqaaaabqaaaaaaabqabqaaaaaaarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfabeaaaaaaabqabeabfabeabqabeabeabeabqcSOcSOcSOcRhcRhcRhcRhcVtcVucRhcRhcRhcVvcVwcVxcUXcVycVzcVAcSOcSOcTacRtcRtcRtcSYcSZcTacRtcVBcVCcVDcVEabqabqaaaaaaabqaefabqaaacVFcVGcVHcVGcVIaaacTZcSvbZUbZUbZUbZUbZUbZUbZUbZUbZUaaaabqaaacVJaaaabqabqabqabqabqabqaaaaaaabqarBabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaaaacVKcVLcVMcSOcVNcVOcVPcVQcVRcVScSOcVTcVUcVVcVWcUXcUYcUZcVacVXcSOcVYcRtcVZcWacWbcWccWdcWacWecRtcWfcVkaaaabqabqabqabqabqabqabqcVGcWgcWhcWicVGaaacTZcWjcWkcWkcWkcWlcWmcTZaaaabqaaaaaaabqaaacVJaaaabqabqaaaaaaaaaabqaaaaaaaaaaupaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaaaacVKcWncVMcWocWpcWpcWpcWqcWrcWscWtcWucWvcWucWwcWpcWxcWwcWycWzcSVcWAcWBcWCcWBcWBcWBcWBcWBcWCcWBcWDcVEaaaabqaaaaaaabqaaaaaaaaacVGcWEcWFcWGcWHcWIcTZcTZcTZcTZcTZciccSvcTZabqabqaaaaaaaaaaaacWJcWKcWKcWKcWKcWKcWKcWKcWKcWKcWLaaaaaaaaaaaaaaaaaaarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaaaacVKcWncVMcWocWpcWpcWpcWqcWrcWscWtcWucWvcWucWwcWpcWxcWwcWycWzcSVcWAcWBcWCcWBcWBcWBcWBcWBcWCcWBcWDcVEaaaabqaaaaaaabqaaaaaaaaacVGcWEcWFdezdeAcyncTZcTZcTZcTZcTZciccSvcTZabqabqaaaaaaaaaaaacWJcWKcWKcWKcWKcWKcWKcWKcWKcWKcWLaaaaaaaaaaaaaaaaaaarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaaaacVKcWncWMcVRcWNcWOcWNcWPcWQcWRcWScWTcWUcWVcWVcWWcWVcWVcWXcWYcSOcWZcXacXbcXacXacXccXacXacXdcXecXfcVkabqabqaaacVGcVGcVGcVGcVGcVGcXgcXhcXicVGcVGcVGcVGcVGcVGcTZciccSvcTZabqabqabqabqabqabqabqabqabqaaaabqaaaaaaaaaaaaaaacVJaaaaaaabqaaaaaaaaaaupaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfabqaaacVKcXjcVMcVRcWNcWNcWNcXkcSOcSOcSOcSOcXlcXmcUXcXncUXcXmcXocSOcSOcVEcXpcVEcXpcVEcVEcVEcXpcXpcVEcVEcVkaaaabqabqcVGcXqcXrcXscXtcVGcXucXvcVGcVGcXwcXxcXycXzcVGcTZciccSvcTZabqcXAcXBcXCcXBcXCcXBcXDabqauparBaupabqabqabqabqcVJabqabqabqabqabqabearBarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqcSOcSOcSOcXEcUXcUXcUXcUXcXFcXGcSOcXHcXIcXJcXJcXKcXJcXJcXLcSOaaacVEcXMcVEcXacVEaaacVEcXacXNcVEaaaaaaaaaabqaaacTXcXOcXPcXQcXRcXRcXScXTcXUcXVcXVcXWcXXcXYcTXcTZciccSvcTZabqcXZcYacYbcYccYdcYecXZabqaaaabqaaaabqaaaaaaaaacYfaaaaaaabqaaaaaaaaaaaaaupaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaacVKcYgcYhcYicYjcYjcYkcXKcYlcYmcSOcSOcSOcYncYncYncYncYncSOcSOabqcVEcXpcVEcXpcVEabqcVEcXpcXpcVEabqabqabqabqaaacTXcYocYpcYqcYrcYrcYscYtcYucYucYucYucYvcYwcTXcTZciccSvcTZabqcYxcYycYbcYdcYbcYzcXCabqaaacYAcYAcYAcYAcYAabqcYBabqcYAcYAcYAcYAcYAaaaarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaacVKcYgcYhcYicYjcYjcYkcXKcYlcYmcSOcSOcSOcYncYncYncYncYncSOcSOabqcVEcXpcVEcXpcVEabqcVEcXpcXpcVEabqabqabqabqaaacTXdeBcYpcYqcYrcYrcYscYtcYucYucYucYucYvcYwcTXcTZciccSvcTZabqcYxcYycYbcYdcYbcYzcXCabqaaacYAcYAcYAcYAcYAabqcYBabqcYAcYAcYAcYAcYAaaaarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqcSOcVKcSOcSOcVKcVKcVKcVKcSOcYCcSOaaaaaaaaaaaaaaaaaaaaacYDcYEcYFcYEcYGcYEcYGcYEcYHcYEcYIcYIcYEcYJaaaaaaabqaaacVGcYKcYLcYMcYNcYOcYPcYQcYRcYScYTcYUcYVcYWcVGcTZciccSvcTZcmzcXZcYdcYbcYdcYdcYecXZabqabqcYXcYYcYYcYYcYYcYZcZacZbcZccZccZccZccZdabqarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqaaaaaaabqaaaaaaaaaaaaaaaabqabqaaaaaaaaaaaaaaaaaaaaacZecZfcZgcZhcZicZjcZkcZlcZmcZncZocZpcZqcZeaaaaaaabqaaacVGcZrcZrcZrcZrcTkcZscZtcZucTkcZrcZrcZrcZrcVGcZvcZvcSvcZwcTZcZxcXBcXCcZycXCcXBcZzabqabqcZAcZAcZAcZAcZAaaacYBaaacZAcZAcZAcZAcZAabqarBabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqabqabqabqabqabqabqabqabqaaaaaaaaaaaaaaaaaaaaaaaacYFcZBcZBcZBcZBcZBcZBcZBcZCcZDcZEcZEcZFcZeaaaaaaabqaaacVGcZGcZHcZHcZIcZJcZKcZLcZMcZNcZOcZPcZPcZPcVGcicciccWjcZQcmzcTZcTZcTZcZRcmzaaaaaaabqaaaabqaaaabqabqabqaaacYBaaaabqaaaabqaaaabqaaaarBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/_maps/map_files/MetaStation/z5.dmm b/_maps/map_files/MetaStation/z5.dmm index 35018a0de20..d4ec96886f7 100644 --- a/_maps/map_files/MetaStation/z5.dmm +++ b/_maps/map_files/MetaStation/z5.dmm @@ -419,7 +419,7 @@ "ic" = (/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteyellowcorner"},/area/research_outpost/hallway) "id" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whiteyellow"},/area/research_outpost/hallway) "ie" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whiteyellowcorner"},/area/research_outpost/hallway) -"if" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/door/firedoor{dir = 8; layer = 2.6; name = "Firelock West"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/obj/machinery/camera{c_tag = "Research Outpost Hallway Starboard"; dir = 2; network = list("Research Outpost"); pixel_x = 24},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) +"if" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/door/firedoor{dir = 8; layer = 2.6; name = "Firelock West"},/obj/machinery/camera{c_tag = "Research Outpost Hallway Starboard"; dir = 2; network = list("Research Outpost"); pixel_x = 24},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) "ig" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/structure/sign/securearea{desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; name = "RADIOACTIVE AREA"; pixel_x = 32; pixel_y = 0},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitepurple"},/area/research_outpost/hallway) "ih" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/wall/r_wall,/area/research_outpost/harvesting) "ii" = (/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/camera{c_tag = "Research Outpost Exotic Particles Airlock"; dir = 2; network = list("Research Outpost")},/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel,/area/research_outpost/harvesting) diff --git a/_maps/map_files/RandomZLevels/beach.dmm b/_maps/map_files/RandomZLevels/beach.dmm index ce54b8f6134..0141fcaa9ee 100644 --- a/_maps/map_files/RandomZLevels/beach.dmm +++ b/_maps/map_files/RandomZLevels/beach.dmm @@ -1,73 +1,437 @@ -"a" = (/turf/unsimulated/beach/sand{density = 1; opacity = 1},/area/awaymission/beach) -"b" = (/turf/unsimulated/beach/sand,/area/awaymission/beach) -"c" = (/obj/machinery/gateway{dir = 9},/turf/unsimulated/beach/sand,/area/awaymission/beach) -"d" = (/obj/machinery/gateway{dir = 1},/turf/unsimulated/beach/sand,/area/awaymission/beach) -"e" = (/obj/machinery/gateway{dir = 5},/turf/unsimulated/beach/sand,/area/awaymission/beach) -"f" = (/obj/effect/overlay/palmtree_r,/turf/unsimulated/beach/sand,/area/awaymission/beach) -"g" = (/obj/machinery/gateway{dir = 8},/turf/unsimulated/beach/sand,/area/awaymission/beach) -"h" = (/obj/machinery/gateway/centeraway,/turf/unsimulated/beach/sand,/area/awaymission/beach) -"i" = (/obj/machinery/gateway{dir = 4},/turf/unsimulated/beach/sand,/area/awaymission/beach) -"j" = (/obj/effect/overlay/palmtree_l,/obj/effect/overlay/coconut,/turf/unsimulated/beach/sand,/area/awaymission/beach) -"k" = (/obj/machinery/gateway{dir = 10},/turf/unsimulated/beach/sand,/area/awaymission/beach) -"l" = (/obj/machinery/gateway,/turf/unsimulated/beach/sand,/area/awaymission/beach) -"m" = (/obj/machinery/gateway{dir = 6},/turf/unsimulated/beach/sand,/area/awaymission/beach) -"n" = (/turf/unsimulated/wall{tag = "icon-sandstone6"; icon_state = "sandstone6"},/area/awaymission/beach) -"o" = (/turf/unsimulated/wall{tag = "icon-sandstone12"; icon_state = "sandstone12"},/area/awaymission/beach) -"p" = (/turf/unsimulated/wall{tag = "icon-sandstone10"; icon_state = "sandstone10"},/area/awaymission/beach) -"q" = (/obj/structure/closet/athletic_mixed,/turf/unsimulated/beach/sand,/area/awaymission/beach) -"r" = (/obj/item/clothing/shoes/sandal,/obj/item/clothing/shoes/sandal,/obj/item/clothing/shoes/sandal,/obj/structure/closet/crate,/turf/unsimulated/beach/sand,/area/awaymission/beach) -"s" = (/turf/unsimulated/wall{tag = "icon-sandstone3"; icon_state = "sandstone3"},/area/awaymission/beach) -"t" = (/obj/structure/closet/gmcloset{icon_closed = "black"; icon_state = "black"; name = "formal wardrobe"},/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) -"u" = (/obj/structure/closet/secure_closet/bar,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) -"v" = (/obj/structure/table/woodentable,/obj/item/weapon/book/manual/barman_recipes,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) -"w" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/drinks/shaker,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) -"x" = (/obj/structure/table/woodentable,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) -"y" = (/obj/structure/table/woodentable,/obj/item/clothing/glasses/sunglasses,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) -"z" = (/obj/machinery/vending/boozeomat{emagged = 1},/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) -"A" = (/obj/machinery/vending/cigarette,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) -"B" = (/obj/machinery/vending/cola,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) -"C" = (/obj/machinery/vending/snack,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) -"D" = (/turf/unsimulated/wall{tag = "icon-sandstone1"; icon_state = "sandstone1"},/area/awaymission/beach) -"E" = (/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) -"F" = (/obj/structure/mineral_door/wood{tag = "icon-wood"; icon_state = "wood"},/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) -"G" = (/obj/effect/overlay/palmtree_l,/turf/unsimulated/beach/sand,/area/awaymission/beach) -"H" = (/turf/unsimulated/wall{tag = "icon-sandstone0"; icon_state = "sandstone0"},/area/awaymission/beach) -"I" = (/obj/structure/table/woodentable,/obj/machinery/chem_dispenser/beer,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) -"J" = (/obj/item/weapon/beach_ball,/turf/unsimulated/beach/sand,/area/awaymission/beach) -"K" = (/obj/structure/stool,/turf/unsimulated/beach/sand,/area/awaymission/beach) -"L" = (/mob/living/simple_animal/crab,/turf/unsimulated/beach/sand,/area/awaymission/beach) -"M" = (/obj/effect/overlay/coconut,/turf/unsimulated/beach/sand,/area/awaymission/beach) -"N" = (/mob/living/simple_animal/crab/Coffee,/turf/unsimulated/beach/sand,/area/awaymission/beach) -"O" = (/obj/structure/stool/bed/chair,/turf/unsimulated/beach/sand,/area/awaymission/beach) -"P" = (/turf/unsimulated/beach/coastline,/area/awaymission/beach) -"Q" = (/turf/unsimulated/beach/coastline{density = 1; opacity = 1},/area/awaymission/beach) -"R" = (/turf/unsimulated/beach/water,/area/awaymission/beach) -"S" = (/turf/unsimulated/beach/water{density = 1; opacity = 1},/area/awaymission/beach) +"aa" = (/turf/space,/area/space) +"ab" = (/turf/unsimulated/beach/water/deep,/area/awaymission/undersea) +"ac" = (/obj/machinery/poolcontroller/seacontroller,/turf/unsimulated/beach/water/deep,/area/awaymission/undersea) +"ad" = (/turf/unsimulated/beach/water/deep/rock_wall,/area/awaymission/undersea) +"ae" = (/turf/unsimulated/beach/water/deep/sand_floor,/area/awaymission/undersea) +"af" = (/obj/structure/constructshell,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"ag" = (/obj/structure/stool/bed/chair/wood/wings,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"ah" = (/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"ai" = (/obj/structure/cult/pylon,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"aj" = (/obj/structure/cult/talisman,/obj/item/weapon/tome,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"ak" = (/obj/structure/cult/talisman,/obj/item/weapon/veilrender/crabrender,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"al" = (/obj/structure/curtain/black,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"am" = (/obj/structure/cult/forge,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"an" = (/obj/structure/flora/rock/pile,/turf/unsimulated/beach/water/deep/sand_floor,/area/awaymission/undersea) +"ao" = (/obj/structure/flora/rock,/turf/unsimulated/beach/water/deep/sand_floor,/area/awaymission/undersea) +"ap" = (/obj/structure/stool,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"aq" = (/mob/living/simple_animal/hostile/retaliate/carp,/turf/unsimulated/beach/water/deep/sand_floor,/area/awaymission/undersea) +"ar" = (/mob/living/simple_animal/hostile/retaliate/carp,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"as" = (/obj/structure/boulder,/turf/unsimulated/beach/water/deep/sand_floor,/area/awaymission/undersea) +"at" = (/obj/item/flag/cult,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"au" = (/obj/structure/mineral_door/sandstone,/obj/structure/barricade/wooden,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"av" = (/obj/item/weapon/crossbowframe,/turf/unsimulated/beach/water/deep/sand_floor,/area/awaymission/undersea) +"aw" = (/obj/item/toy/eight_ball/conch,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"ax" = (/obj/structure/reagent_dispensers/beerkeg,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"ay" = (/obj/structure/closet/cabinet,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"az" = (/obj/structure/rack/skeletal_bar/left,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"aA" = (/obj/structure/rack/skeletal_bar/right,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"aB" = (/obj/structure/rack/skeletal_bar,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"aC" = (/obj/structure/mineral_door/wood{tag = "icon-wood"; icon_state = "wood"},/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"aD" = (/obj/structure/stool/bed/chair/comfy/teal{dir = 4},/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"aE" = (/obj/structure/table/woodentable,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"aF" = (/obj/structure/stool/bed/chair/comfy/teal{dir = 8},/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"aG" = (/obj/structure/toilet,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"aH" = (/obj/structure/grille,/turf/unsimulated/beach/water/deep/sand_floor,/area/awaymission/undersea) +"aI" = (/obj/structure/stool/bed/chair/wood/wings{tag = "icon-wooden_chair_wings (EAST)"; icon_state = "wooden_chair_wings"; dir = 4},/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"aJ" = (/obj/structure/stool/bed/chair/wood/wings{tag = "icon-wooden_chair_wings (WEST)"; icon_state = "wooden_chair_wings"; dir = 8},/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"aK" = (/obj/structure/stool/bed/chair/sofa/right,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"aL" = (/obj/structure/stool/bed/chair/sofa/left,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"aM" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"aN" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"aO" = (/obj/structure/closet/crate/bin{name = "Garbage bin"},/obj/item/weapon/storage/bag/trash,/turf/unsimulated/beach/water/deep/sand_floor,/area/awaymission/undersea) +"aP" = (/obj/item/flag/species/skrell,/turf/unsimulated/beach/water/deep/sand_floor,/area/awaymission/undersea) +"aQ" = (/obj/structure/mirror{icon_state = "mirror_broke"; pixel_y = 28},/obj/item/weapon/storage/wallet/random,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"aR" = (/obj/structure/mirror{icon_state = "mirror_broke"; pixel_y = 28},/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"aS" = (/obj/structure/stool/bed,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"aT" = (/obj/structure/dresser,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"aU" = (/obj/structure/ladder/dive_point/anchor,/turf/unsimulated/beach/water/deep/sand_floor,/area/awaymission/undersea) +"aV" = (/obj/structure/barricade/wooden,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) +"aW" = (/obj/structure/grille{density = 0; icon_state = "brokengrille"},/turf/unsimulated/beach/water/deep/sand_floor,/area/awaymission/undersea) +"aX" = (/obj/item/weapon/spacecash/c500,/turf/unsimulated/beach/water/deep/sand_floor,/area/awaymission/undersea) +"aY" = (/obj/structure/closet/crate{icon_state = "crateopen"; opened = 1},/obj/item/weapon/coin/gold,/obj/item/weapon/coin/gold,/obj/item/weapon/coin/gold,/obj/item/weapon/coin/gold,/obj/item/weapon/coin/gold,/obj/item/weapon/coin/gold,/obj/item/weapon/coin/gold,/turf/unsimulated/beach/water/deep/sand_floor,/area/awaymission/undersea) +"aZ" = (/turf/unsimulated/beach/sand{density = 1; icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow"; name = "rough sand"},/area/awaymission/beach) +"ba" = (/obj/structure/flora/rock,/turf/unsimulated/beach/sand{density = 1; icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow"; name = "rough sand"},/area/awaymission/beach) +"bb" = (/obj/structure/flora/grass/brown,/turf/unsimulated/beach/sand{density = 1; icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow"; name = "rough sand"},/area/awaymission/beach) +"bc" = (/obj/structure/flora/ausbushes/leafybush,/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (NORTHWEST)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 9},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bd" = (/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (NORTHEAST)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 5},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"be" = (/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (WEST)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 8},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bf" = (/obj/structure/flora/ausbushes/genericbush,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bg" = (/obj/structure/flora/ausbushes/leafybush,/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (EAST)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 4},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bh" = (/obj/effect/decal/snow/sand/surround{tag = "icon-gravsnow_surround (NORTH)"; name = "rough sand"; icon_state = "gravsnow_surround"; dir = 1},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bi" = (/obj/effect/decal/snow/sand/edge{name = "rough sand"},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bj" = (/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bk" = (/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (EAST)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 4},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bl" = (/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (NORTHWEST)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 9},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bm" = (/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (SOUTHWEST)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 10},/turf/unsimulated/floor/grass,/area/awaymission/beach) +"bn" = (/obj/effect/decal/snow/sand/edge{name = "rough sand"},/turf/unsimulated/floor/grass,/area/awaymission/beach) +"bo" = (/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (SOUTHEAST)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 6},/turf/unsimulated/floor/grass,/area/awaymission/beach) +"bp" = (/obj/effect/decal/snow/sand/surround{name = "rough sand"},/turf/unsimulated/floor/grass,/area/awaymission/beach) +"bq" = (/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (SOUTHEAST)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 6},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"br" = (/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (SOUTHWEST)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 10},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bs" = (/obj/effect/overlay/palmtree_r,/turf/unsimulated/beach/sand{density = 1; icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow"; name = "rough sand"},/area/awaymission/beach) +"bt" = (/obj/structure/flora/ausbushes/lavendergrass,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bu" = (/obj/effect/overlay/palmtree_r,/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (NORTHWEST)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 9},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bv" = (/obj/structure/flora/ausbushes/genericbush,/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (NORTH)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 1},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bw" = (/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (NORTH)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 1},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bx" = (/obj/effect/overlay/palmtree_r,/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (NORTH)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 1},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"by" = (/obj/effect/overlay/palmtree_r,/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (EAST)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 4},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bz" = (/obj/effect/overlay/palmtree_r,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bA" = (/obj/structure/flora/ausbushes/sunnybush,/turf/unsimulated/beach/sand{density = 1; icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow"; name = "rough sand"},/area/awaymission/beach) +"bB" = (/obj/effect/overlay/palmtree_r,/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (WEST)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 8},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bC" = (/obj/effect/overlay/palmtree_l,/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (NORTH)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 1},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bD" = (/obj/effect/overlay/palmtree_r,/obj/effect/overlay/coconut,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bE" = (/obj/structure/flora/bush,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bF" = (/obj/effect/overlay/palmtree_l,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bG" = (/obj/structure/flora/ausbushes/sunnybush,/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (NORTH)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 1},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bH" = (/obj/effect/overlay/palmtree_r,/obj/effect/overlay/coconut,/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (NORTH)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 1},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bI" = (/obj/structure/flora/ausbushes/reedbush,/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (NORTHEAST)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 5},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bJ" = (/obj/structure/flora/ausbushes/lavendergrass,/turf/unsimulated/beach/sand{density = 1; icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow"; name = "rough sand"},/area/awaymission/beach) +"bK" = (/obj/effect/overlay/palmtree_l,/obj/effect/overlay/coconut,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bL" = (/obj/structure/flora/ausbushes/sunnybush,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bM" = (/obj/structure/flora/ausbushes/reedbush,/turf/unsimulated/beach/sand{density = 1; icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow"; name = "rough sand"},/area/awaymission/beach) +"bN" = (/obj/structure/flora/ausbushes/leafybush,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bO" = (/obj/structure/flora/grass/brown,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bP" = (/obj/structure/flora/rock/pile,/obj/effect/overlay/palmtree_l,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bQ" = (/obj/structure/flora/ausbushes/grassybush,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bR" = (/obj/structure/flora/ausbushes/reedbush,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bS" = (/obj/structure/flora/grass/green,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"bT" = (/obj/structure/flora/rock/pile,/obj/structure/flora/ausbushes/palebush,/turf/unsimulated/beach/sand/dense,/area/awaymission/beach) +"bU" = (/obj/structure/flora/rock/pile,/obj/structure/flora/ausbushes/genericbush,/turf/unsimulated/beach/sand/dense,/area/awaymission/beach) +"bV" = (/obj/structure/flora/rock/pile,/obj/structure/flora/ausbushes/sunnybush,/turf/unsimulated/beach/sand/dense,/area/awaymission/beach) +"bW" = (/obj/structure/flora/rock/pile,/obj/structure/flora/ausbushes/leafybush,/turf/unsimulated/beach/sand/dense,/area/awaymission/beach) +"bX" = (/obj/structure/flora/rock,/turf/unsimulated/beach/sand/dense,/area/awaymission/beach) +"bY" = (/obj/structure/flora/ausbushes/palebush,/turf/unsimulated/beach/sand/dense,/area/awaymission/beach) +"bZ" = (/obj/structure/flora/rock/pile,/obj/structure/flora/ausbushes/lavendergrass,/turf/unsimulated/beach/sand/dense,/area/awaymission/beach) +"ca" = (/obj/structure/flora/rock/pile,/obj/effect/overlay/palmtree_r,/turf/unsimulated/beach/sand/dense,/area/awaymission/beach) +"cb" = (/obj/structure/flora/rock/pile,/obj/effect/overlay/palmtree_l,/turf/unsimulated/beach/sand/dense,/area/awaymission/beach) +"cc" = (/obj/structure/flora/rock/pile,/obj/structure/flora/ausbushes/fernybush,/turf/unsimulated/beach/sand/dense,/area/awaymission/beach) +"cd" = (/obj/structure/flora/rock/pile,/obj/structure/flora/ausbushes/sunnybush,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"ce" = (/obj/structure/flora/rock/pile,/obj/structure/flora/ausbushes/leafybush,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"cf" = (/obj/structure/flora/rock/pile,/obj/structure/flora/ausbushes/fernybush,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"cg" = (/turf/unsimulated/beach/sand/dense,/area/awaymission/beach) +"ch" = (/obj/structure/flora/rock,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"ci" = (/obj/structure/flora/ausbushes/ppflowers,/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (WEST)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 8},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"cj" = (/obj/machinery/gateway{dir = 9},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"ck" = (/obj/machinery/gateway{dir = 1},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"cl" = (/obj/machinery/gateway{dir = 5},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"cm" = (/obj/structure/flora/rock/pile,/obj/structure/flora/ausbushes/palebush,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"cn" = (/obj/machinery/gateway{dir = 8},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"co" = (/obj/machinery/gateway/centeraway,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"cp" = (/obj/machinery/gateway{dir = 4},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"cq" = (/obj/effect/decal/snow/sand/edge{name = "rough sand"},/obj/structure/closet/crate/internals,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"cr" = (/obj/effect/decal/snow/sand/edge{name = "rough sand"},/obj/structure/dispenser/oxygen,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"cs" = (/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (EAST)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 4},/obj/structure/closet/athletic_mixed,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"ct" = (/turf/unsimulated/wall{tag = "icon-sandstone6"; icon_state = "sandstone6"},/area/awaymission/beach) +"cu" = (/turf/unsimulated/wall{tag = "icon-sandstone12"; icon_state = "sandstone12"},/area/awaymission/beach) +"cv" = (/turf/unsimulated/wall{tag = "icon-sandstone10"; icon_state = "sandstone10"},/area/awaymission/beach) +"cw" = (/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (WEST)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 8},/obj/effect/overlay/palmtree_l,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"cx" = (/obj/structure/flora/bush,/turf/unsimulated/beach/sand{density = 1; icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow"; name = "rough sand"},/area/awaymission/beach) +"cy" = (/obj/machinery/gateway{dir = 10},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"cz" = (/obj/machinery/gateway,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"cA" = (/obj/machinery/gateway{dir = 6},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"cB" = (/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (EAST)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 4},/obj/item/clothing/shoes/sandal,/obj/item/clothing/shoes/sandal,/obj/item/clothing/shoes/sandal,/obj/structure/closet/crate,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"cC" = (/turf/unsimulated/wall{tag = "icon-sandstone3"; icon_state = "sandstone3"},/area/awaymission/beach) +"cD" = (/obj/structure/stool,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) +"cE" = (/obj/structure/closet/gmcloset{icon_closed = "black"; icon_state = "black"; name = "formal wardrobe"},/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) +"cF" = (/obj/structure/closet/secure_closet/bar,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) +"cG" = (/obj/structure/table/woodentable,/obj/item/weapon/book/manual/barman_recipes,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) +"cH" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/drinks/shaker,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) +"cI" = (/obj/structure/table/woodentable,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) +"cJ" = (/obj/structure/table/woodentable,/obj/item/clothing/glasses/sunglasses,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) +"cK" = (/obj/machinery/vending/boozeomat{emagged = 1},/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) +"cL" = (/obj/machinery/vending/cigarette,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) +"cM" = (/obj/machinery/vending/cola,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) +"cN" = (/obj/machinery/vending/snack,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) +"cO" = (/turf/unsimulated/wall{tag = "icon-sandstone1"; icon_state = "sandstone1"},/area/awaymission/beach) +"cP" = (/obj/structure/curtain/open,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) +"cQ" = (/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) +"cR" = (/obj/effect/overlay/palmtree_r,/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (SOUTHWEST)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 10},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"cS" = (/obj/structure/mineral_door/wood{tag = "icon-wood"; icon_state = "wood"},/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) +"cT" = (/obj/structure/flora/grass/green,/turf/unsimulated/beach/sand{density = 1; icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow"; name = "rough sand"},/area/awaymission/beach) +"cU" = (/turf/unsimulated/wall{tag = "icon-sandstone0"; icon_state = "sandstone0"},/area/awaymission/beach) +"cV" = (/obj/structure/table/woodentable,/obj/machinery/chem_dispenser/soda,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) +"cW" = (/obj/structure/table/woodentable,/obj/machinery/chem_dispenser/beer,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/awaymission/beach) +"cX" = (/obj/item/weapon/beach_ball,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"cY" = (/obj/structure/flora/rock/pile,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"cZ" = (/obj/structure/stool,/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (NORTH)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 1},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"da" = (/obj/effect/overlay/palmtree_r,/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (SOUTHEAST)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 6},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"db" = (/obj/effect/overlay/palmtree_l,/obj/effect/decal/snow/sand/edge{tag = "icon-gravsnow_corner (WEST)"; name = "rough sand"; icon_state = "gravsnow_corner"; dir = 8},/turf/unsimulated/beach/sand,/area/awaymission/beach) +"dc" = (/obj/structure/flora/ausbushes/palebush,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"dd" = (/mob/living/simple_animal/crab,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"de" = (/obj/effect/overlay/coconut,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"df" = (/mob/living/simple_animal/crab/Coffee,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"dg" = (/obj/structure/stool/bed/chair,/turf/unsimulated/beach/sand,/area/awaymission/beach) +"dh" = (/obj/structure/flora/ausbushes/reedbush,/turf/unsimulated/beach/sand/dense,/area/awaymission/beach) +"di" = (/obj/structure/flora/rock/pile,/obj/structure/flora/ausbushes/stalkybush,/turf/unsimulated/beach/sand/dense,/area/awaymission/beach) +"dj" = (/turf/unsimulated/beach/coastline,/area/awaymission/beach) +"dk" = (/turf/unsimulated/beach/coastline/dense,/area/awaymission/beach) +"dl" = (/obj/effect/waterfall{dir = 1; water_frequency = 75},/turf/unsimulated/beach/coastline,/area/awaymission/beach) +"dm" = (/obj/effect/waterfall{dir = 1; water_frequency = 192},/turf/unsimulated/beach/coastline,/area/awaymission/beach) +"dn" = (/obj/effect/waterfall{dir = 1; water_frequency = 104},/turf/unsimulated/beach/coastline,/area/awaymission/beach) +"do" = (/obj/effect/waterfall{dir = 1; water_frequency = 44},/turf/unsimulated/beach/coastline,/area/awaymission/beach) +"dp" = (/obj/effect/waterfall{dir = 1; water_frequency = 97},/turf/unsimulated/beach/coastline,/area/awaymission/beach) +"dq" = (/obj/effect/waterfall{dir = 1; water_frequency = 94},/turf/unsimulated/beach/coastline,/area/awaymission/beach) +"dr" = (/turf/unsimulated/beach/water,/area/awaymission/beach) +"ds" = (/turf/unsimulated/beach/water/dense,/area/awaymission/beach) +"dt" = (/turf/unsimulated/beach/water/drop,/area/awaymission/beach) +"du" = (/turf/unsimulated/beach/water/deep,/area/awaymission/beach) +"dv" = (/obj/structure/ladder/dive_point/buoy,/turf/unsimulated/beach/water/deep,/area/awaymission/beach) +"dw" = (/turf/unsimulated/beach/water/deep/dense,/area/awaymission/beach) (1,1,1) = {" -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -bcdebbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbfba -bghibbbbjbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -bklmbbbbbbbbnoooooooooopbbqrqrqrqrqrqrqa -bbbbbbbbbbbbstuvwxyzABCsbbbbbbbbbbbbbbba -bbbbbbbbbbbbDEEEEEEEEEEsbbbbbbbbbbbbbbba -bbbbbbbbbbbbFEEEEEEEEEEsbbbbbbbbbGbbbbba -bbfbbbbbbbbbHxIxxxxxxxxDbbbGbbJbbbbbbbba -bbbbbbbbbbbbbKKKKKKKKKKbbbbbbbbbbbbbbbba -bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -bbbLbbbbbbbbbbbbbbbbbbbbbbbbbbbfbbbbbbba -bbbbbbGMbbbbbbbbbbbbbbGbbbbbNbbbMbbbbbfa -bbbJbbbbbbLbbObObObObObObbbbbbbbbbObObba -bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPQ -RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRS -RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRS -RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRS -RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRS -RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRS -RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRS -RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRS -RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRS -RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRS -RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRS +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadadadadadadadadadadadadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadadadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadadaeadadadadadadadadadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeadadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeadadadadadadadaeaeaeaeadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadadadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeadadadadadadadadaeaeadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeadadadadadaeaeadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadadaeaeaeaeaeaeadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadadadadadadadadadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadadadadadadadadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadadafadagagadafadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadahahahahahahahahadadahaiadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeadadadaeaeaeaeadaeaeaeaeaeaeaeaeadadaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadahahahaiajakaiahahahalahamadadanaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeadadadaeaeadaeaeaeaeaeaeadaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadafahahahahahahahahafadahaiadaoaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeadaeaeaeaeaeaeadaeadaeaeaeaeaeaeadaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadadadadadadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadahahapapapapapapahahadadadadanaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeadadaeadaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadahahahahahahahahahahadadadaoaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeadaeaeaeadadadaeadadaeadadadadadaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaqaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadarahapapapapapapahahadadadanaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeadaeadaeadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadahahahahahahahahahahadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeadadaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeadaeadadaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeadadadadadadadadadadaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadahahapapapapapapahahadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeadaeaqaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeadaeadadaeadaeadaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeadadaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadahahahahahahahahahahasadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeadaeaeaeaeadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeahahaeaeaeaeadaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadahahatahahatahahahaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeadaeadadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeadaeadaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeahahahahaeaeaeaeadaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadadauauadadadadasaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeahahadadahahaeaeaeadaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadasasadadadasasasaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeadadadaeavadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeahawadadahahaeaeaeadaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeadadadadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeahahahahaeaeaeaeadaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeadadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeahahaeaeaeaeadaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeadaeaeaeadaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeadadadaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeadadadadadaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadaeaeaeaqaeaeaeaeaeaeaeaeaeaeadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeadaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeadadadaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadaeadadaeadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeadadaeaeaeaeaeaeaeaeaeadaeaeaeaeaqaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeadaeadadaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeadadadaeadadaeadaeaeadaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeadadadadadadadaeadaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaqaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeadaeaeadaeaeadaeaeadaeaeaeadaeaeadaeaeadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeadaeaeaeaeadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadaeadaeaeadaeaeadaeaeaeaeaeaeaeadadadaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeadaeadadaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeadadaeadadadaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaxahahahahayadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadazaAazaAahaBadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadahahahahahahadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadahahahahahahadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadadadadadasaeaeaeadadadadaCaCadadadadaeaeaeasadadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaDaEaFahadaGadadaHaHaHadaIaEaJahahaIaEaJadaHaHaHadadaGadaKaLahahadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadahahahahadaMaNadaeaeaeadahahahahahahahahadaOaeaeadaMahadahahahaEadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadahahahahadaCadadaeaPaeadaIaEaJahahaIaEaJadaeaeaeadadaCadahahahaEadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadahahahahaCahaQadaeaeaeadahahahahahahahahadaOaeaeadaRahaCahahahahadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadahahahahadaSaTadaeaeaeadaIaEaJahahaIaEaJadaeaeaeadaSaTadahahahahadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaUaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadaCadadadadadaHaHaHadadaVaVahahaVaVadadaHaWaHadadadadadadaCadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadaeadadaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeasadaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeadadadaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaqaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeadaeaeadaeadaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaqaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeadadaeadaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeadadaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeadadaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeadaeaeaeaeadaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeadaeaeadaeaeadaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeadadaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeadaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeadaeaeaeaeaqaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeadaeadaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeadadadaeaeaeaeaeaeaeaeaeaeaeadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeadaeaeadaeaeaeaeaeaeaeadaeadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeadadaeadadaeadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeadadaeaeaeaeaeaeadaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeadaeaeadaeadaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeadadadaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadadaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeadaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeadaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeadaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeadaeaeaeaeaeaeaeaeaeaeaeadaeaeaeadaeaeaeaeaeaeaeaeadadadaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadaeaeadaeaeaeadaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeadadadaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeadaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeadadadadadadadaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadadadadadadaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeadaeaeadaeadaeadaeadadadaeadaeaeaeaeaeaeaeaeadaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeadadadadadadadadadaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeadaeaeadaeaeadaeaeaeaeaeaeaeaeaeaeaeaeadaeadaeadadaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeadadadadadadadadadaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeadaeaeaeaeaeaeaeaeadadadadadadadadadaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeadadadadadadadadadaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadadadadadadaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeadadadadadadadadaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeadadadadadadadadadaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeadadadadadadaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaqaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeadaeaeaeaeadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeadadadaeaeaeaeadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadaeaeaeadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaXaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeadadaeaeaqaeaeadadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeadadaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeadaeadaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeadadaeaeaeaeaeadadadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeadaeadaeadaeadaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeadadadadaeaeaeaeadadadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeadaeadaeaeaeadaeaeaeaqaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaqaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeadadadadadadaeaeadadadadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadaeaeaeadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeadadadadadadadaeaeadadadadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaqaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeadadadadadadadadadadadadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeadaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeadadadadadadadadadadadadadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeadadadadadadadadadadadadadadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadadaeaeaeaeaeaeaeadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeadadadadadadadadadadadadadadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeadadadaeaeaeadadadaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeadadadadadadadadadadadadadadadadadadadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeadadadadadaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeadadadadadadadadadadadadadadadadadaYadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aZaZbabbbcbdaZaZaZaZbebfbgaZbaaZaZaZbhaZbebibjbjbkaZaZblbjbkaZaZaZaZaZbmbnbnboaZbpaZaZbebjbjbqaZaZaZbrbqaZaZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aZbsaZblbtbkbsbsbsbubjbjbjbvbwbxbxbwbjbwbybsbebjbzbxbwbzbjbkbsaZaZbsbabbaZaZbsbAaZaZaZbBbjbkbsbaaZaZaZbsaZaZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +bsbubCbjbjbDbwbxbxbjbEbzbzbDbFbjbjbEbzbzbjbwbzbjbEbjbjbzbzbFbwbCbwbwbwbxbGbHbwbwbwbxbxbjbjbyaZaZaZbubwbIaZaZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +bJbBbjbDbzbEbzbjbFbzbjbzbzbtbjbFbzbjbjbDbFbjbFbzbjbzbjbKbjbjbEbjbjbDbzbEbjbfbjbzbLbjbjbzbzbjbwbxbHbzbjbjbxbwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +bMbebDbjbDbjbNbtbzbzbDbjbjbEbzbFbzbjbtbjbFbFbKbDbjbjbzbjbKbzbjbDbFbLbjbzbjbLbzbjbjbzbDbzbjbzbjbLbEbjbzbjbObjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aZbBbjbKbjbzbfbjbNbjbLbzbjbfbjbfbzbjbjbNbjbjbLbjbjbPbjbLbjbjbQbjbfbjbNbjbNbjbfbjbNbjbjbLbRbfbNbjbjbLbjbjbjbjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +bsbebzbDbSbfbTbUbVbWbXbUbVbWbTbUbXbYbVbWbTbVbXbWbVbXbTbZcabXbTcbbVccbXbWcaccbXbTbVbWccbXcbbXbTcabjbLbzbRbibiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aZbBbzbjbjbjbXcdbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjcebjcfcdbjbjbjbjbjbjbjbjbjbjbjbjbjbfbzcfcgchbjbKbkbsaZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +bscibjbzbzbLbWbjcjckclbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbibibibjbjbibibibjbjbibibibjbWbDbjbjbkbsbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +bwbjbjbQbjcmbVbjcncocpbjbjbjbjbKbjbjbjbibicqcrcqbibibibibibibibjcsctcucvbecsctcucvbecsctcucvcwbVbfbzbzbkcxaZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +bSbzbDbjbFchbXbjcyczcAbjbjbjbjbjbjbjbkctcucucucucucucucucucucvbecBcCcDcCbecBcCcDcCbecBcCcDcCbebWchbzbObkaZaZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +bjbRbjbzbjbjbWbjbjbjbjbjbjbjbjbjbjbjbkcCcEcFcGcHcIcJcKcLcMcNcCbebkcOcPcObebkcOcPcObebkcOcPcObebXbLbQbKbzbCbwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +bFbjbNbNbzbLbVbjbjbjbjbjbjbjbjbjbjbjbkcOcQcQcQcQcQcQcQcQcQcQcCbebjbwbwbwbjbjbwbwbwbjbjbwbwbwbjccbjbjbLbzbRbzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +cRbzbQbFbzbjbWbjbjbjbjbjbjbjbjbjbjbjbkcScQcQcQcQcQcQcQcQcQcQcCbebjbjbjbjbjbjbjbjbFbjbjbjbjbjbjbVbzbzbjbzbjbiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +cTbebObjbjbfcccdbjbzbjbjbjbjbjbjbjbjbkcUcVcWcIcIcIcIcIcIcIcIcObebjbjbFbjbjcXbjbjbjbjbjbjbjbjbjbWbfbjbzbjbkcTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +bMbebzbKbzbfbXcYbjbjbjbjbjbjbjbjbjbjbjbwcZcZcZcZcZcZcZcZcZcZbwbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbXbzbRbjbDdaaZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aZdbbzbjbjbjbWbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjccbLbjbObjbAbsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +bxbDbjbzbzdcbXbjbjbjddbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbzbjbjbjbjbjbjbjbjbVbzbKbzbDbdbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +bjbjbDbjbjbLbVbjbjbjbjbjbjbFdebjbjbjbjbjbjbjbjbjbjbjbjbjbjbFbjbjbjbjbjdfbjbjbjdebjbjbjbjbjbzbjbXbjbEbSbjbybbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +bFbEbFbzbjbjbWbjbjbjcXbjbjbjbjbjbjddbjbjdgbjdgbjdgbjdgbjdgbjdgbjbjbjbjbjbjbjbjbjbjdgbjdgbjbjbjbWbNbjbzbjbFbwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +bjbjbjbjbjbjdhbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjdibjbjbjbjbjbjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +djdjdjdjdjdjdkdjdldjdjdjdmdjdndjdjdjdjdjdjdodjdjdjdjdpdjdjdjdndjdjdjdjdjdpdjdjdqdjdjdpdjdmdjdjdkdjdjdjdjdjdjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +drdrdrdrdrdrdsdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdsdrdrdrdrdrdraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +drdrdrdrdrdrdsdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdsdrdrdrdrdrdraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +drdrdrdrdrdrdsdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdsdrdrdrdrdrdraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +drdrdrdrdrdrdsdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdsdrdrdrdrdrdraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +drdrdrdrdrdrdsdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdsdrdrdrdrdrdraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +drdrdrdrdrdrdsdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdsdrdrdrdrdrdraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +drdrdrdrdrdrdsdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdsdrdrdrdrdrdraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +drdrdrdrdrdrdsdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdsdrdrdrdrdrdraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +drdrdrdrdrdrdsdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdsdrdrdrdrdrdraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +drdrdrdrdrdrdsdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdsdrdrdrdrdrdraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +drdrdrdrdrdrdsdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdsdrdrdrdrdrdraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +drdrdrdrdrdrdsdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdsdrdrdrdrdrdraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +drdrdrdrdrdrdsdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdsdrdrdrdrdrdraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +drdrdrdrdrdrdsdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdsdrdrdrdrdrdraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +drdrdrdrdrdrdsdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdsdrdrdrdrdrdraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +drdrdrdrdrdrdsdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdsdrdrdrdrdrdraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +drdrdrdrdrdrdsdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdsdrdrdrdrdrdraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +drdrdrdrdrdrdsdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdtdtdtdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdsdrdrdrdrdrdraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +drdrdrdrdrdrdsdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdrdtdudvdudtdrdrdrdrdrdrdrdrdrdrdrdrdrdrdsdrdrdrdrdrdraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +drdrdrdrdrdrdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdwdwdwdwdwdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdrdrdrdrdrdraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +dtdtdtdtdtdtdtdtdtdtdtdtdtdtdtdtdtdtdtdtdtdtdtdtdtdtdtdudududududududtdtdtdtdtdtdtdtdtdtdtdtdtdtdtdtdtdtdtdtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +dudududududududududududududududududududududududududududududududududududududududududududududududududududududuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +dudududududududududududududududududududududududududududududududududududududududududududududududududududududuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +dudududududududududududududududududududududududududududududududududududududududududududududududududududududuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +dudududududududududududududududududududududududududududududududududududududududududududududududududududududuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +dudududududududududududududududududududududududududududududududududududududududududududududududududududududuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "} diff --git a/_maps/map_files/RandomZLevels/moonoutpost19.dmm b/_maps/map_files/RandomZLevels/moonoutpost19.dmm index 231fbd041e6..c9582434115 100644 --- a/_maps/map_files/RandomZLevels/moonoutpost19.dmm +++ b/_maps/map_files/RandomZLevels/moonoutpost19.dmm @@ -67,7 +67,7 @@ "bo" = (/obj/machinery/alarm/monitor{frequency = 1439; locked = 1; pixel_y = 23; req_access = "150"},/turf/simulated/floor/plasteel{heat_capacity = 1e+006; icon_state = "bar"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "bp" = (/obj/structure/table,/obj/machinery/microwave{pixel_x = -3; pixel_y = 6},/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plasteel{heat_capacity = 1e+006; icon_state = "bar"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "bq" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/item/device/radio/off{pixel_x = -4; pixel_y = 4},/obj/item/device/radio/off{pixel_x = 2},/turf/simulated/floor/plasteel{heat_capacity = 1e+006; icon_state = "warning"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) -"br" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/obj/item/weapon/paper{info = "Log 1:
We got our promised supply drop today. We were only meant to get it, what, a week ago? This bloody gateway keeps desyncing itself, and that means subsisting off recycled water and carb packs. No clue where the damn thing connects to on its off days, and HQ say we are 'not to touch it if it isn't linking to command.' We dumped off the assload of crates Jim filled, got our boxes of oxygen, food and drink, and closed the portal.

Log 2:
Damn thing is acting up again. Three days no contact this time. I thought I heard clanking noises from it yesterday. Jim is going on about the NT base or some shit. We've been over this before - They don't know we're here, that engineer was too drunk to recognise his suit, especially since I had it painted orange. He's starting to get annoying. We're safe.

Log 3:
Gateway synced itself up automatically today. I opened it for an instant to spy through it, got a glimpse of the inside of a transport container. Either HQ's redecorating or something, or there's more than two of these things."; name = "Personal Log"},/turf/simulated/floor/plasteel{dir = 6; heat_capacity = 1e+006; icon_state = "warning"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) +"br" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/obj/item/weapon/paper{info = "Log 1:
We got our promised supply drop today. We were only meant to get it, what, a week ago? This bloody gateway keeps desyncing itself, and that means subsisting off recycled water and carb packs. No clue where the damn thing connects to on its off days, and HQ say we are 'not to touch it if it isn't linking to command.' We dumped off the assload of crates Jim filled, got our boxes of oxygen, food and drink, and closed the portal.

Log 2:
Damn thing is acting up again. Three days no contact this time. I thought I heard clanking noises from it yesterday. Jim is going on about the NT base or some shit. We've been over this before – They don't know we're here, that engineer was too drunk to recognise his suit, especially since I had it painted orange. He's starting to get annoying. We're safe.

Log 3:
Gateway synced itself up automatically today. I opened it for an instant to spy through it, got a glimpse of the inside of a transport container. Either HQ's redecorating or something, or there's more than two of these things."; name = "Personal Log"},/turf/simulated/floor/plasteel{dir = 6; heat_capacity = 1e+006; icon_state = "warning"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "bs" = (/obj/machinery/door/window{dir = 1; name = "Gateway Access"; req_access_txt = "150"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plasteel{dir = 1; heat_capacity = 1e+006; icon_state = "warning"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "bt" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/item/weapon/storage/firstaid/regular,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 10; heat_capacity = 1e+006; icon_state = "warning"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "bu" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/machinery/recharger{pixel_y = 4},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{heat_capacity = 1e+006; icon_state = "warning"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) @@ -170,7 +170,7 @@ "dn" = (/turf/simulated/floor/plasteel{carbon_dioxide = 48.7; dir = 4; heat_capacity = 1e+006; icon_state = "warningcorner"; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "do" = (/turf/simulated/floor/plasteel{broken = 1; carbon_dioxide = 48.7; dir = 8; heat_capacity = 1e+006; icon_state = "damaged1"; nitrogen = 13.2; oxygen = 32.4; tag = "icon-damaged1 (WEST)"; temperature = 251},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "dp" = (/obj/structure/closet/crate,/obj/item/weapon/storage/bag/ore,/obj/structure/alien/weeds,/obj/item/device/mining_scanner,/obj/item/weapon/shovel,/obj/item/weapon/pickaxe,/turf/simulated/floor/plating{broken = 1; carbon_dioxide = 48.7; heat_capacity = 1e+006; icon_state = "platingdmg3"; nitrogen = 13.2; oxygen = 32.4; tag = "icon-platingdmg3"; temperature = 251},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) -"dq" = (/obj/structure/table/woodentable,/obj/structure/sign/poster{icon_state = "poster24"; pixel_x = 0; pixel_y = -32; serial_number = 24; subtype = 0},/obj/item/weapon/pen,/obj/item/weapon/paper{info = "Log 1:
While mining today I noticed the NT station was finished with its renovations. They placed some huge reinforced tumor on the station, looks so ugly. I wouldn't be surprised if those pigs decided to turn that little astronomy outpost into a prison with that thing, it'd be pretty typical of them.

Log 2:
Really dumb of me but I just waved at an engineer in the outpost, and he waved back. I hope to god he was too dumb or drunk to recognize the suit, because if he isn't then we might have to pull out before they come looking for us.

Log 3:
That huge reinforced tumor in their science section has been making a lot of noise lately. I've been hearing some banging and scratching from the other side and I'm kind of glad now that they reinforced this thing so much. I'll be sleeping with my gun under my pillow from now on."; name = "Personal Log"},/turf/simulated/floor/wood{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) +"dq" = (/obj/structure/table/woodentable,/obj/structure/sign/poster{icon_state = "poster24"; pixel_x = 0; pixel_y = -32; serial_number = 24; subtype = 0},/obj/item/weapon/pen,/obj/item/weapon/paper{info = "Log 1:
While mining today I noticed the NT station was finished with its renovations. They placed some huge reinforced tumor on the station – looks so ugly. I wouldn't be surprised if those pigs decided to turn that little astronomy outpost into a prison with that thing, it'd be pretty typical of them.

Log 2:
Really dumb of me, but I just waved at an engineer in the outpost, and he waved back. I hope to god he was too dumb or drunk to recognize the suit, because if he isn't, then we might have to pull out before they come looking for us.

Log 3:
That huge reinforced tumor in their science section has been making a lot of noise lately. I've been hearing some banging and scratching from the other side and I'm kind of glad now that they reinforced this thing so much. I'll be sleeping with my gun under my pillow from now on."; name = "Personal Log"},/turf/simulated/floor/wood{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "dr" = (/obj/structure/closet/secure_closet{desc = "It's a secure locker for personnel. The first card swiped gains control."; icon_broken = "cabinetdetective_broken"; icon_closed = "cabinetdetective"; icon_locked = "cabinetdetective_locked"; icon_off = "cabinetdetective_broken"; icon_opened = "cabinetdetective_open"; icon_state = "cabinetdetective_locked"; locked = 1; name = "personal closet"; req_access_txt = "150"},/obj/item/ammo_box/magazine/m10mm,/obj/item/ammo_box/magazine/m10mm,/obj/item/weapon/suppressor,/turf/simulated/floor/wood{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "ds" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/syndie,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood{heat_capacity = 1e+006},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) "dt" = (/obj/structure/closet/secure_closet{desc = "It's a secure locker for personnel. The first card swiped gains control."; icon_broken = "cabinetdetective_broken"; icon_closed = "cabinetdetective"; icon_locked = "cabinetdetective_locked"; icon_off = "cabinetdetective_broken"; icon_opened = "cabinetdetective_open"; icon_state = "cabinetdetective"; locked = 0; name = "personal closet"; req_access_txt = "150"},/obj/item/weapon/spacecash/c50,/turf/simulated/floor/wood{heat_capacity = 1e+006},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"}) @@ -303,7 +303,7 @@ "fQ" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "fR" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "0"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "fS" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/effect/decal/cleanable/blood/oil{color = "black"},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) -"fT" = (/obj/structure/filingcabinet,/obj/item/weapon/paper{info = "Entry One - 27/05/2554:
I just arrived, and already I hate my job. I'm stuck on this shithole of an outpost, trying to avoid these damn eggheads running all over the place preparing for god knows what. There's no crimes to stop, no syndies to kill, and I'm not even allowed to beat the fuckin' assistant senseless! They said I was transferred from Space Station 13 for 'good behavior', but this feels more like a punishment than a reward. All I know is that if I don't get some action soon, I'm going to go insane.

Entry Two - 03/06/2554:
Okay, so get this: we got a fuckin' deathsquad coming in today! I thought the day I saw one of them would be the day my employment was 'terminated', if you get my drift. They're escorting some sort of weird alien creature for the eggheads to study. I heard one of the docs telling the chef that this thing killed a whole security force before it was captured. I sure as hell hope that I don't have to fight it.

Entry Three - 08/06/2554:
My first real bit of 'action' today, if you could call it that. Crazy Ivan got in a fight with Kuester today about his Booze-O-Mat. Apparently one of the crewmembers had stolen a couple bottles of booze from the machine after Ivan disabled the ID lock. Tell you the truth, I don't blame the thief. Everyone is going a little stir-crazy in here, and the bartender is being damn stingy with the alcohol. Either way, once they started to pick a fight, I had to take them down. It's a damn shame that we don't have a brig, though. I had to lock Ivan in a fuckin' freezer, for god's sake. Let's hope that we can keep our sanity together, at least for a while.

Entry Four - 10/06/2554:
Jesus fucking Christ riding on a motorbike. These things the scientists are studying are terrifying! Fucking great huge purple bug things as tall as the ceiling, with blades for arms and drooling at the mouth. I don't think my taser will do jack shit against these damn things, but the eggheads say that they're safely contained. If they do, I have a feeling that it's only a matter of time before we're all screwed. These bastards look like walking death.

Entry Five - 18/06/2554:
Finally caught who stole the booze from Kuester. It was that fuckin' loser assistant Steve! He was in the dorms, chugging his worries away. I took one of the bottles back to the barkeep, but no one has to know about this second one. I think I'm gonna enjoy this while watching tomorrow's Thunderdome match.

Entry Six - 19/06/2554:
Oh, great. The chef is still sleeping, so we get Ivan's gruel for breakfast today. I overheard Sano and Douglas saying something about the aliens being restless, so we might get some action today. As long as it happens after the big game, I'm fine with it. I still got one beer to drink before I'm ready to die."; name = "Personal Log - Kenneth Cunningham"},/turf/simulated/floor/plasteel{dir = 9; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) +"fT" = (/obj/structure/filingcabinet,/obj/item/weapon/paper{info = "Entry One — 27/05/2554:
I just arrived, and already I hate my job. I'm stuck on this shithole of an outpost, trying to avoid these damn eggheads running all over the place preparing for god knows what. There's no crimes to stop, no syndies to kill, and I'm not even allowed to beat the fuckin' assistant senseless! They said I was transferred from Space Station 13 for 'good behavior', but this feels more like a punishment than a reward. All I know is that if I don't get some action soon, I'm going to go insane.

Entry Two — 03/06/2554:
Okay, so get this: we got a fuckin' deathsquad coming in today! I thought the day I saw one of them would be the day my employment was 'terminated', if you get my drift. They're escorting some sort of weird alien creature for the eggheads to study. I heard one of the docs telling the chef that this thing killed a whole security force before it was captured. I sure as hell hope that I don't have to fight it.

Entry Three — 08/06/2554:
My first real bit of 'action' today, if you could call it that. Crazy Ivan got in a fight with Kuester today about his Booze-O-Mat. Apparently one of the crewmembers had stolen a couple bottles of booze from the machine after Ivan disabled the ID lock. Tell you the truth, I don't blame the thief. Everyone is going a little stir-crazy in here, and the bartender is being damn stingy with the alcohol. Either way, once they started to pick a fight, I had to take them down. It's a damn shame that we don't have a brig, though. I had to lock Ivan in a fuckin' freezer, for god's sake. Let's hope that we can keep our sanity together, at least for a while.

Entry Four — 10/06/2554:
Jesus fucking Christ riding on a motorbike. These things the scientists are studying are terrifying! Fucking great huge purple bug things as tall as the ceiling, with blades for arms and drooling at the mouth. I don't think my taser will do jack shit against these damn things, but the eggheads say that they're safely contained. If they do, I have a feeling that it's only a matter of time before we're all screwed. These bastards look like walking death.

Entry Five — 18/06/2554:
Finally caught who stole the booze from Kuester. It was that fuckin' loser assistant Steve! He was in the dorms, chugging his worries away. I took one of the bottles back to the barkeep, but no one has to know about this second one. I think I'm gonna enjoy this while watching tomorrow's Thunderdome match.

Entry Six — 19/06/2554:
Oh, great. The chef is still sleeping, so we get Ivan's gruel for breakfast today. I overheard Sano and Douglas saying something about the aliens being restless, so we might get some action today. As long as it happens after the big game, I'm fine with it. I still got one beer to drink before I'm ready to die."; name = "Personal Log — Kenneth Cunningham"},/turf/simulated/floor/plasteel{dir = 9; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "fU" = (/obj/structure/closet/secure_closet{icon_broken = "secbroken"; icon_closed = "sec"; icon_locked = "sec1"; icon_off = "secoff"; icon_opened = "secopen"; icon_state = "sec1"; locked = 1; name = "security officer's locker"; req_access_txt = "201"},/obj/item/clothing/suit/armor/vest,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/grenade/flashbang,/obj/item/weapon/storage/belt/security,/obj/item/weapon/reagent_containers/food/drinks/cans/beer{pixel_x = -3; pixel_y = -2},/obj/machinery/alarm/monitor{frequency = 1439; locked = 0; pixel_y = 23; req_access = null},/turf/simulated/floor/plasteel{dir = 1; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "fV" = (/obj/structure/sign/poster{icon_state = "poster21_legit"; pixel_y = 32; serial_number = 21; subtype = 1},/obj/item/device/radio/off,/obj/item/weapon/screwdriver{pixel_y = 10},/turf/simulated/floor/plasteel{dir = 5; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "fW" = (/obj/structure/grille,/obj/structure/window/full/reinforced,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) @@ -335,7 +335,7 @@ "gw" = (/obj/structure/disposalpipe/segment{desc = "An underfloor disposal pipe. This one has been applied with an acid-proof coating."; dir = 4; name = "Acid-Proof disposal pipe"; unacidable = 1},/obj/structure/alien/weeds,/obj/structure/alien/resin/wall,/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "gx" = (/obj/structure/disposalpipe/segment{desc = "An underfloor disposal pipe. This one has been applied with an acid-proof coating."; dir = 2; icon_state = "pipe-c"; name = "Acid-Proof disposal pipe"; unacidable = 1},/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "gy" = (/obj/structure/table,/obj/effect/decal/cleanable/dirt,/obj/machinery/cell_charger,/obj/item/weapon/stock_parts/cell/high,/obj/item/device/radio/off,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) -"gz" = (/obj/structure/table,/obj/item/weapon/paper{info = "Ivan Volodin Stories:

Entry Won - 28/05/2554:
Hello. I am Crazy Ivan. Boss say I must write. I do good job fixing outpost. Is very good job. Much better than mines. Many nice people. I cause no trouble.

Entry Too - 05/06/2554:
I am finding problem with Booze-O-Mat. Is not problem. I solve very easy. Use yellow tool to make purple light go off. I am good engineer! Bartender will be very happy.

Entry Tree - 08/06/2554:
Bartender is not happy. Security man is not happy. Cannot feel legs, is very cold in freezer. Is not good. Table is jammed into door, have no tools. Is very not good. But, on bright side, found meat! Shall chew to keep spirits up.

Entry Fore - 12/06/2554:
Big nasty purple bug looked at me today. Make nervous. Blue wall wire can be broken, then bad thing happens. Very very bad thing. Man in orange spacesuit wave at me today too. He seem nice. Wonder who was?

Entry Fiv - 15/06/2554:
I eat cornflakes today. Is good day. Sun shine for a while. Was nice. I also take ride on disposals chute. Was fun, but tiny. Get clog out of pipes, was vodka bottle. Is empty. This make many sads.

Entry Sex: 19/06/2554:
Purple bugs jumpy today. When waved, get hiss. Maybe very bad. Maybe just ill. Do not know. Is science problem, is not engineer problem. I eat sandwich. Is glorious job. Wish to never end."; name = "Personal Log - Ivan Volodin"},/turf/simulated/floor/plating{broken = 1; heat_capacity = 1e+006; icon_state = "platingdmg3"; tag = "icon-platingdmg3"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) +"gz" = (/obj/structure/table,/obj/item/weapon/paper{info = "Ivan Volodin Stories:

Entry Won — 28/05/2554:
Hello. I am Crazy Ivan. Boss say I must write. I do good job fixing outpost. Is very good job. Much better than mines. Many nice people. I cause no trouble.

Entry Too — 05/06/2554:
I am finding problem with Booze-O-Mat. Is not problem. I solve very easy. Use yellow tool to make purple light go off. I am good engineer! Bartender will be very happy.

Entry Tree — 08/06/2554:
Bartender is not happy. Security man is not happy. Cannot feel legs, is very cold in freezer. Is not good. Table is jammed into door, have no tools. Is very not good. But, on bright side, found meat! Shall chew to keep spirits up.

Entry Fore — 12/06/2554:
Big nasty purple bug looked at me today. Make nervous. Blue wall wire can be broken, then bad thing happens. Very very bad thing. Man in orange spacesuit wave at me today too. He seem nice. Wonder who was?

Entry Fiv — 15/06/2554:
I eat cornflakes today. Is good day. Sun shine for a while. Was nice. I also take ride on disposals chute. Was fun, but tiny. Get clog out of pipes, was vodka bottle. Is empty. This make many sads.

Entry Sex: 19/06/2554:
Purple bugs jumpy today. When waved, get hiss. Maybe very bad. Maybe just ill. Do not know. Is science problem, is not engineer problem. I eat sandwich. Is glorious job. Wish to never end."; name = "Personal Log — Ivan Volodin"},/turf/simulated/floor/plating{broken = 1; heat_capacity = 1e+006; icon_state = "platingdmg3"; tag = "icon-platingdmg3"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "gA" = (/obj/machinery/light/small,/obj/structure/closet/toolcloset,/obj/item/clothing/gloves/color/yellow,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "gB" = (/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "gC" = (/obj/machinery/computer/monitor,/obj/structure/cable,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) @@ -346,7 +346,7 @@ "gH" = (/obj/structure/cable,/obj/machinery/power/apc/noalarm{cell_type = 15000; dir = 4; locked = 0; name = "Worn-out APC"; pixel_x = 25; req_access = null; start_charge = 100},/turf/simulated/floor/plasteel{dir = 2; heat_capacity = 1e+006; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "gI" = (/obj/structure/table,/obj/item/weapon/retractor,/obj/item/weapon/hemostat,/obj/structure/alien/weeds,/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "gJ" = (/obj/structure/table,/obj/machinery/light/small{active_power_usage = 0; dir = 4; icon_state = "bulb-broken"; status = 2},/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) -"gK" = (/obj/structure/filingcabinet/filingcabinet,/obj/machinery/light/small{active_power_usage = 0; dir = 8; icon_state = "bulb-broken"; status = 2},/obj/item/weapon/paper{info = "Researcher: Dr. Sakuma Sano
Date: 04/06/2554

Report:
As expected, all that is left of the monkeys we sent in earlier is a group of xenomorph larvae. It is quite clear that the facehuggers are not selective in their hosts, and so far the gestation process has been shown to have a 100% success rate.

The larvae themselves have been behaving very differently from the lone larva we first observed, and despite shying away from humans they are clearly comfortable with others of their kind. Our previous suspicions on larvae have been confirmed with their demonstration of playfulness: they are not nearly as aggressive or violent when young, before molting to adulthood.

The majority of the play we observed involved a sort of hide-and-seek, and occasionally wrestling by tangling themselves and struggling out of it. While normally we would write these off as instinctual play for honing their skills when they molt, their growth period is so incredibly fast and they are still such adept killers that it would serve no practical purpose. The only explanation for this is perhaps to create bonds and friendships with each other, if that is even possible for such an incredibly hostile race. It may be that they are much more reasonable with each other than other life forms.

It had become clear that now was the best time to extract a xenomorph for dissecting, as these were all still larvae and the queen was still attached to its ovipositor and would be immobile. With the approval of the research director, we sent in our medical robot that had been dubbed 'Head Surgeon' into the containment pen, dropping the shields for only a fraction of a second to allow it entry. The larvae were cautious, but the curiosity of one had him within grabbing range of our robot. It was brought out and quickly euthanized through lethal injection, courtesy of our mechanical doctor."; name = "Larva Xenomorph Social Interactions & Capturing Procedure"},/obj/item/weapon/paper{info = "Researcher: Dr. Sakuma Sano
Date: 04/06/2554

Report:
I have studied many interesting and diverse life-forms as a xenobiologist ranging from creatures as large as cows, to specimens too small see with the naked eye. This is by far the largest alien I have ever seen. The alien we were previously studying has molted and has become an absolutely enormous creature. Standing at over 15 feet tall and weighing in at likely two tons or more, the xenomorph queen is an absolutely breathtakingly large and cruel monster. Its behavior has changed drastically from when it was a drone, having become far more comfortable with sitting and staring at us, rather than smashing at the windows.

The queen, physiologically speaking, is fairly similar to the other xenomorphs, with a few key differences. Its enormous size demands large legs, while the back seems to be always hunched forward. The dorsal tubes on the back have changed to several large spikes, and we observed the alien now sports a second pair of smaller arms on its chest. The purpose of these secondary arms is still unknown. Finally, the queen's crown has become incredibly large, with what seems to be a retractable slot to hide its head in. The dome appears to be extremely thick near the front, and will likely be able to resist a lot of trauma. Despite the enormous size it has grown to, it is not that much slower than it used to be.

After two hours of doing relatively nothing but staring, the queen began to produce an unusually large amount of resin and weeds, quickly shaping up a large nest that it then hid behind. It then proceeded to smash out all the lights, leaving us with very little to see with our cameras. When we looked through the back cameras, we had discovered that it had grown a large ovipositor, and was releasing large eggs onto the ground. This had us all in agreement that this stage of the life cycle was the queen.

Over the next few hours, the eggs grew to their full sizes, and we provided the subject with new monkey hosts. When they approached the eggs, they opened to release more facehuggers. It seems that we have observed the full cycle of reproduction for this species. We can expect more larvae in the next few hours."; name = "Queen Xenomorph Physiology & Behavior Observation"},/obj/item/weapon/paper{info = "Researcher: Dr. Sakuma Sano
Date: 03/06/2554

Report:
The other scientists and I can hardly believe our eyes. The snake-like larva has molted into a 7 foot tall insectoid nightmare in just a few hours. It's obvious now as to why such heavy duty containment was needed. It immediately tried to escape however by flinging itself at the window in a flurry of swipes and stabs. It seems its behavior has returned to a state that is very similar to the facehugger, though I doubt with the same intent! Thankfully, our glass and shields have shown to be more than sturdy enough for such a violent creature, and so far, any attempts at the creature escaping have been in vain.

As for its physiology, the creature has an elongated head with what appears to be have an exoskeleton resembling an external rib-cage on the torso. The alien is also fairly skinny with a lean body. The little amount of meat on the alien appears to be entirely muscle. We assume this makes it deceptively strong, while remaining agile at the same time. One of the most interesting things we have seen is its pharyngeal jaw. It has some what of an inner mouth capable of being fired externally at extremely high speeds. It has already caused many dents in the walls and a few small cracks in the window with it. The alien also has a couple of dorsal tubes on its back, their purpose unknown. Finally, this monster sports a long ridged tail, complete with a large and extremely sharp blade at the tip.

Normally I would be absolutely terrified of something like this, but I'm putting my trust in Nanotrasen with the containment. After all, they wouldn't build a cell that could fail to contain its subject, would they?"; name = "Adult Xenomorph Physiology & Behavior Observation"},/obj/item/weapon/paper{info = "Researcher: Dr. Sakuma Sano
Date: 03/06/2554

Report:
When the larva first emerged from the chest of the monkey, it seemed very curious. It would wander around aimlessly for awhile and then sit still. We are unable to determine the gender of the larva, or even determine if it has a gender. After some time had passed, it seemed to lose interest in its surroundings and sat mostly still while occasionally wagging its tail. We decided to throw in a live mouse to see if it would consume it. The larva quickly attacked and ate the mouse and seemed to get larger very suddenly, this suggests that the larvae are capable of metabolizing and directing all the energy towards growth at previously thought impossible speeds. It is a shame that we cannot observe the process more closely, as we do not currently know how dangerous or violent this creature is or will become as it matures fully.

It is tempting to imagine the possibilities of utilizing such a mechanism. The capability of skipping years of growth time for children, repairing bodily damage in a matter of moments, even its usage in existing cloning technology."; name = "Larva Xenomorph Physiology & Behavior Observation"},/obj/item/weapon/paper{info = "Researcher: Dr. Sakuma Sano
Date: 03/06/2554

Report:
The test subject we were provided with truly is alien. It is a small spider-like creature with bony legs leading to a smooth body. It has a long tail connected to it, and it has shown extremely aggressive behavior by flinging its entire body at the glass and shields to no avail. While doing so, we noticed there was a small pink hole in the middle of the body.

When we sent in a monkey through the crude but effective disposal tube, the alien immediately jumped at its face and latched on. The monkey was quickly suffocated by its constricting tail, unable to pry off the fingers. The monkey at first seemed to be dead, but was observed to be breathing. The recently named alien 'facehugger' fell off dead and curled its legs up like a spider moments after it had finished with the monkey's body.

While the monkey appeared to be unharmed, we kept it in the cell for a couple more hours until we were horrified to discover it screaming out in pain as a snake-like creature erupted from the monkey's chest! It appears that the 'facehugger' is only the start of this life cycle. The impregnation cycle involving the creatures growing inside the chests of their hosts seems to only be the beginning."; name = "'Facehugger' Xenomorph Physiology & Behavior Observation"},/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) +"gK" = (/obj/structure/filingcabinet/filingcabinet,/obj/machinery/light/small{active_power_usage = 0; dir = 8; icon_state = "bulb-broken"; status = 2},/obj/item/weapon/paper{info = "Researcher: Dr. Sakuma Sano
Date: 04/06/2554

Report:
As expected, all that is left of the monkeys we sent in earlier is a group of xenomorph larvae. It is quite clear that the facehuggers are not selective in their hosts, and so far the gestation process has been shown to have a 100% success rate.

The larvae themselves have been behaving very differently from the lone larva we first observed, and despite shying away from humans, they are clearly comfortable with others of their kind. Our previous suspicions on larvae have been confirmed with their demonstration of playfulness: they are not nearly as aggressive nor violent when young, before molting to adulthood.

The majority of the play we observed involved a sort of hide-and-seek, and occasionally wrestling by tangling themselves and struggling out of it. While normally we would write these off as instinctual play for honing their skills when they molt, their growth period is so incredibly fast and they are still such adept killers, that it would serve no practical purpose. The only explanation for this is perhaps to create bonds and friendships with each other, if that is even possible for such an incredibly hostile race. It may be that they are much more reasonable with each other than other life forms.

It had become clear that now was the best time to extract a xenomorph for dissecting, as these were all still larvae and the queen was still attached to its ovipositor and would be immobile. With the approval of the research director, we sent in our medical robot that had been dubbed 'Head Surgeon' into the containment pen, dropping the shields for only a fraction of a second to allow it entry. The larvae were cautious, but the curiosity of one had him within grabbing range of our robot. It was brought out and quickly euthanized through lethal injection, courtesy of our mechanical doctor."; name = "Larva Xenomorph Social Interactions & Capturing Procedure"},/obj/item/weapon/paper{info = "Researcher: Dr. Sakuma Sano
Date: 04/06/2554

Report:
I have studied many interesting and diverse life-forms as a xenobiologist, ranging from creatures as large as cows, to specimens too small see with the naked eye. This is by far the largest alien I have ever seen. The alien we were previously studying has molted and has become an absolutely enormous creature. Standing at over 15 feet tall, and weighing in at likely two tons or more, the xenomorph queen is an absolutely breathtakingly large and cruel monster. Its behavior has changed drastically from when it was a drone, having become far more comfortable with sitting and staring at us, rather than smashing at the windows.

The queen, physiologically speaking, is fairly similar to the other xenomorphs, with a few key differences. Its enormous size demands large legs, while the back seems to be always hunched forward. The dorsal tubes on the back have changed to several large spikes, and we observed that the alien now sports a second pair of smaller arms on its chest. The purpose of these secondary arms is still unknown. Finally, the queen's crown has become incredibly large, with what seems to be a retractable slot to hide its head in. The dome appears to be extremely thick near the front, and will likely be able to resist a lot of trauma. Despite the enormous size it has grown to, it is not much slower than it used to be.

After two hours of doing relatively nothing but staring, the queen began to produce an unusually large amount of resin and weeds, quickly shaping up a large nest, that it then hid behind. It then proceeded to smash out all the lights, leaving us with very little to see with our cameras. When we looked through the back cameras, we had discovered that it had grown a large ovipositor, and was releasing large eggs onto the ground. This had us all in agreement that this stage of the life cycle was the queen.

Over the next few hours, the eggs grew to their full sizes, and we provided the subject with new monkey hosts. When they approached the eggs, they opened to release more facehuggers. It seems that we have observed the full cycle of reproduction for this species. We can expect more larvae in the next few hours."; name = "Queen Xenomorph Physiology & Behavior Observation"},/obj/item/weapon/paper{info = "Researcher: Dr. Sakuma Sano
Date: 03/06/2554

Report:
The other scientists and I can hardly believe our eyes. The snake-like larva has molted into a 7 foot tall insectoid nightmare in just a few hours. It's obvious now as to why such heavy duty containment was needed. It immediately tried to escape, however, by flinging itself at the window in a flurry of swipes and stabs. It seems its behavior has returned to a state that is very similar to the facehugger, though I doubt with the same intent! Thankfully, our glass and shields have shown to be more than sturdy enough for such a violent creature, and so far, any attempts at the creature escaping have been in vain.

As for its physiology, the creature has an elongated head, with what appears to be have an exoskeleton resembling an external rib-cage on the torso. The alien is also fairly skinny with a lean body. The little amount of meat on the alien appears to be entirely muscle. We assume this makes it deceptively strong, while remaining agile at the same time. One of the most interesting things we have seen is its pharyngeal jaw. It has somewhat of an inner mouth, capable of being fired externally at extremely high speeds. It has already caused many dents in the walls and a few small cracks in the window with it. The alien also has a couple of dorsal tubes on its back, their purpose unknown. Finally, this monster sports a long ridged tail, complete with a large and extremely sharp blade at the tip.

Normally I would be absolutely terrified of something like this, but I'm putting my trust in Nanotrasen with the containment. After all, they wouldn't build a cell that could fail to contain its subject – would they?"; name = "Adult Xenomorph Physiology & Behavior Observation"},/obj/item/weapon/paper{info = "Researcher: Dr. Sakuma Sano
Date: 03/06/2554

Report:
When the larva first emerged from the chest of the monkey, it seemed very curious. It would wander around aimlessly for awhile and then sit still. We are unable to determine the gender of the larva, or even determine if it has a gender. After some time had passed, it seemed to lose interest in its surroundings and sat mostly still while occasionally wagging its tail. We decided to throw in a live mouse to see if it would consume it. The larva quickly attacked and ate the mouse, and seemed to get larger very suddenly; this suggests that the larvae are capable of metabolizing and directing all the energy towards growth at previously-thought impossible speeds. It is a shame that we cannot observe the process more closely, as we do not currently know how dangerous or violent this creature is, or will become, as it matures fully.

It is tempting to imagine the possibilities of utilizing such a mechanism. The capability of skipping years of growth time for children, repairing bodily damage in a matter of moments, even its usage in existing cloning technology."; name = "Larva Xenomorph Physiology & Behavior Observation"},/obj/item/weapon/paper{info = "Researcher: Dr. Sakuma Sano
Date: 03/06/2554

Report:
The test subject we were provided with truly is alien. It is a small spider-like creature with bony legs, leading to a smooth body. It has a long tail connected to it, and it has shown extremely aggressive behavior by flinging its entire body at the glass and shields to no avail. While doing so, we noticed there was a small pink hole in the middle of the body.

When we sent in a monkey through the crude but effective disposal tube, the alien immediately jumped at its face and latched on. The monkey was quickly suffocated by its constricting tail, unable to pry off the fingers. The monkey at first seemed to be dead, but was observed to be breathing. The recently named alien 'facehugger' fell off, dead, and curled its legs up like a spider moments after it had finished with the monkey's body.

While the monkey appeared to be unharmed, we kept it in the cell for a couple more hours, until we were horrified to discover it screaming out in pain, as a snake-like creature erupted from the monkey's chest! It appears that the 'facehugger' is only the start of this life cycle. The impregnation cycle involving the creatures growing inside the chests of their hosts seems to only be the beginning."; name = "'Facehugger' Xenomorph Physiology & Behavior Observation"},/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "gL" = (/obj/structure/table/reinforced,/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/obj/item/device/radio/off,/turf/simulated/floor/plasteel{dir = 8; heat_capacity = 1e+006; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "gM" = (/obj/structure/cable,/obj/machinery/door/poddoor/preopen{desc = "A heavy duty blast door that opens mechanically. This one has been applied with an acid-proof coating."; id_tag = "Awaylab"; name = "Acid-Proof containment chamber blast door"; unacidable = 1},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/grille,/obj/structure/window/full/reinforced,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "gN" = (/obj/structure/disposalpipe/segment{desc = "An underfloor disposal pipe. This one has been applied with an acid-proof coating."; name = "Acid-Proof disposal pipe"; unacidable = 1},/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) @@ -359,7 +359,7 @@ "gU" = (/obj/machinery/optable,/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel{dir = 1; heat_capacity = 1e+006; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "gV" = (/obj/machinery/computer/operating,/obj/structure/alien/weeds,/turf/simulated/floor/plasteel{dir = 1; heat_capacity = 1e+006; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "gW" = (/obj/structure/table,/obj/item/clothing/gloves/color/latex,/obj/item/clothing/mask/surgical,/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel{dir = 1; heat_capacity = 1e+006; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) -"gX" = (/obj/structure/filingcabinet/filingcabinet,/obj/item/weapon/paper{info = "Researcher: Dr. Mark Douglas
Date: 17/06/2554

Report:
Earlier today we have observed a new phenomenon with our subjects. While feeding them our last monkey subject and throwing out the box, the aliens merely looked at us instead of infecting the monkey right away. They looked to be collectively distressed as they would no longer be given hosts, where instead we would move to the next phase of the experiment. When I glanced at the gas tanks and piping leading to their cell, I looked back to see all of them were up against the glass, even the queen! It was as if they all understood what was going to happen, even though we knew only the queen had the cognitive capability to do so.

The only explanation for this is a form of communication between the aliens, but we have seen no such action take place anywhere in the cell until now. We also know that regular drone and hunter xenomorphs have no personality or instinct to survive by themselves. Perhaps the queen has a direct link to them? A form of a commander or overseer that controls their every move? A hivemind?"; name = "The Hivemind Hypothesis"},/obj/item/weapon/paper{info = "Researcher: Dr. Sakuma Sano
Date: 08/06/2554

Report:
The xenomorphs we have come to study here are a remarkable species. They are almost universally aggressive across all castes, showing no remorse or guilt or pause before or after acts of violence. They appear to be a species entirely designed to kill. Oddly enough, even their method of reproduction is a brutal two-for-one method of birthing a new xenomorph and killing its host.

The lone xenomorph we studied only five days ago showed little sign of intelligence. Only a simple drone that flung itself at the safety glass and shields repeatedly and thankfully without success. Once the drone molted into a queen, it became much more calm and calculating, merely looking at us and waiting while building its nest. As the hive grew in size and in numbers, so too did the intelligence of the common hunter and drone. We are still researching how they can communicate with one another and the relationship between the different castes and the queen. We will continue to update our research as we learn more about the species."; name = "A Preliminary Study of Alien Behavior"},/obj/item/weapon/paper{info = "Researcher: Dr. Mark Douglas
Date: 06/06/2554

Report:
While observing the growing number of aliens in the containment cell, we began to notice subtle differences that were consistently repeating. Like ants, these creatures clearly have different specialized variations that determine their roles in the hive. We have dubbed the three currently observed castes as Hunters, Drones, and Sentinels.

Hunters have been observed to be by far the most aggressive and agile of the three, constantly running on every surface and frequently swiping at the windows. They are also remarkably good at camouflaging themselves in darkness and on their resin structures, appearing almost invisible to the unwary observer. They are always the first to reach the monkeys we send in leading us to believe that this caste is primarily used for finding and retrieving hosts.

Drones on the other hand are much more docile and seem more shy by comparison, though not any less aggressive than the other castes. They have been observed to have a much wider head and lack dorsal tubes. They have shown to be less agile and visibly more fragile than any other caste. The drone however has never been observed to interact with the monkeys directly and instead preferring maintenance of the hive by building walls of resin and moving eggs around the nest. As far as we know, we have only ever observed a drone become a queen, and we have no way of knowing if the other castes have that capability.

Lastly, we have the Sentinels, which appear at first glance to be the guards of the hive. They have so far been only observed to remain near the queen and the eggs, frequently curled up against the walls. We have only observed one instance where they have interacted with a monkey who strayed too closely to the queen, and was pounced and held down immediately until it was applied with a facehugger. Their lack of movement makes it difficult to determine their exact purpose as guards, sentries, or other role."; name = "The Xenomorph 'Castes'"},/obj/item/weapon/paper{info = "Researcher: Dr. Mark Douglas
Date: 04/06/2554

Report:
After an extremely dangerous, time consuming and costly dissection, we have managed to record and identify several of the organs inside of the first stage of the xenomorph cycle: the larva. This procedure took an extensive amount of time because these creatures have incredibly, almost-comically acidic blood that can melt through almost anything in a few moments. We had to use over a dozen scalpels and retractors to complete the autopsy.

The larva seems to possess far fewer and quite different organs than that of a human. There is a stomach, with no digestive tract, a heart, which seems to lack any blood-oxygen circulation purpose, and an elongated brain, even though its as dumb as any large cat. It also lacks any liver, kidneys, or other basic organs.

We can't determine the exact nature of how these creatures grow, nor if they gain organs as they become adults. The larger breeds of xenomorph are too dangerous to kill and capture to give us an accurate answer to these questions. All that we can conclude is that being able to function with so little and yet be so deadly means that these creatures are highly evolved and likely to be extremely durable to various hazards that would otherwise be lethal to humans."; name = "Larva Xenomorph Autopsy Report"},/obj/structure/alien/weeds,/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) +"gX" = (/obj/structure/filingcabinet/filingcabinet,/obj/item/weapon/paper{info = "Researcher: Dr. Mark Douglas
Date: 17/06/2554

Report:
Earlier today we have observed a new phenomenon with our subjects. While feeding them our last monkey subject and throwing out the box, the aliens merely looked at us, instead of infecting the monkey right away. They looked to be collectively distressed as they would no longer be given hosts, where instead we would move to the next phase of the experiment. When I glanced at the gas tanks and piping leading to their cell, I looked back to see all of them were up against the glass, even the queen! It was as if they all understood what was going to happen, even though we knew only the queen had the cognitive capability to do so.

The only explanation for this is a form of communication between the aliens, but we have seen no such action take place anywhere in the cell until now. We also know that regular drone and hunter xenomorphs have no personality or instinct to survive by themselves. Perhaps the queen has a direct link to them? A form of a commander or overseer that controls their every move? A hivemind?"; name = "The Hivemind Hypothesis"},/obj/item/weapon/paper{info = "Researcher: Dr. Sakuma Sano
Date: 08/06/2554

Report:
The xenomorphs we have come to study here are a remarkable species. They are almost universally aggressive across all castes, showing no remorse or guilt or pause before or after acts of violence. They appear to be a species entirely designed to kill. Oddly enough, even their method of reproduction is a brutal two-for-one method of birthing a new xenomorph and killing its host.

The lone xenomorph we studied only five days ago showed little sign of intelligence. Only a simple drone that flung itself at the safety glass and shields repeatedly and thankfully without success. Once the drone molted into a queen, it became much more calm and calculating, merely looking at us and waiting while building its nest. As the hive grew in size and in numbers, so too did the intelligence of the common hunter and drone. We are still researching how they can communicate with one another and the relationship between the different castes and the queen. We will continue to update our research as we learn more about the species."; name = "A Preliminary Study of Alien Behavior"},/obj/item/weapon/paper{info = "Researcher: Dr. Mark Douglas
Date: 06/06/2554

Report:
While observing the growing number of aliens in the containment cell, we began to notice subtle differences that were consistently repeating. Like ants, these creatures clearly have different specialized variations that determine their roles in the hive. We have dubbed the three currently observed castes as Hunters, Drones, and Sentinels.

Hunters have been observed to be by far the most aggressive and agile of the three, constantly running on every surface and frequently swiping at the windows. They are also remarkably good at camouflaging themselves in darkness and on their resin structures, appearing almost invisible to the unwary observer. They are always the first to reach the monkeys we send in leading us to believe that this caste is primarily used for finding and retrieving hosts.

Drones on the other hand are much more docile and seem more shy by comparison, though not any less aggressive than the other castes. They have been observed to have a much wider head and lack dorsal tubes. They have shown to be less agile and visibly more fragile than any other caste. The drone however has never been observed to interact with the monkeys directly and instead preferring maintenance of the hive by building walls of resin and moving eggs around the nest. As far as we know, we have only ever observed a drone become a queen, and we have no way of knowing if the other castes have that capability.

Lastly, we have the Sentinels, which appear at first glance to be the guards of the hive. They have so far been only observed to remain near the queen and the eggs, frequently curled up against the walls. We have only observed one instance where they have interacted with a monkey who strayed too closely to the queen, and was pounced and held down immediately until it was applied with a facehugger. Their lack of movement makes it difficult to determine their exact purpose as guards, sentries, or other role."; name = "The Xenomorph 'Castes'"},/obj/item/weapon/paper{info = "Researcher: Dr. Mark Douglas
Date: 04/06/2554

Report:
After an extremely dangerous, time consuming and costly dissection, we have managed to record and identify several of the organs inside of the first stage of the xenomorph cycle: the larva. This procedure took an extensive amount of time because these creatures have incredibly, almost-comically acidic blood that can melt through almost anything in a few moments. We had to use over a dozen scalpels and retractors to complete the autopsy.

The larva seems to possess far fewer and quite different organs than that of a human. There is a stomach, with no digestive tract, a heart, which seems to lack any blood-oxygen circulation purpose, and an elongated brain, even though its as dumb as any large cat. It also lacks any liver, kidneys, or other basic organs.

We can't determine the exact nature of how these creatures grow, nor if they gain organs as they become adults. The larger breeds of xenomorph are too dangerous to kill and capture to give us an accurate answer to these questions. All that we can conclude is that being able to function with so little and yet be so deadly means that these creatures are highly evolved and likely to be extremely durable to various hazards that would otherwise be lethal to humans."; name = "Larva Xenomorph Autopsy Report"},/obj/structure/alien/weeds,/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "gY" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "gZ" = (/obj/effect/decal/cleanable/dirt,/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel{dir = 8; heat_capacity = 1e+006; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "ha" = (/obj/machinery/shieldwallgen{locked = 0; req_access = null},/obj/structure/cable,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) @@ -381,7 +381,7 @@ "hq" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/effect/decal/cleanable/blood/oil{color = "black"},/turf/simulated/floor/plating{broken = 1; heat_capacity = 1e+006; icon_state = "platingdmg3"; tag = "icon-platingdmg3"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "hr" = (/obj/structure/closet/secure_closet{icon_broken = "rdsecurebroken"; icon_closed = "rdsecure"; icon_locked = "rdsecure1"; icon_off = "rdsecureoff"; icon_opened = "rdsecureopen"; icon_state = "rdsecure1"; locked = 1; name = "research director's locker"; req_access_txt = "201"},/obj/item/weapon/storage/backpack/satchel_tox,/obj/item/clothing/gloves/color/latex,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "hs" = (/obj/structure/table,/obj/item/weapon/cartridge/signal/toxins,/obj/item/weapon/cartridge/signal/toxins{pixel_x = -4; pixel_y = 2},/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) -"ht" = (/obj/structure/filingcabinet/chestdrawer,/obj/machinery/light/small{active_power_usage = 0; dir = 1; icon_state = "bulb-broken"; status = 2},/obj/machinery/alarm/monitor{frequency = 1439; locked = 0; pixel_y = 23; req_access = null},/obj/item/weapon/paper{info = "Personal Log for Research Director Gerald Rosswell

Entry One - 17/05/2554:
You know, I can't believe I took this position so suddenly. I saw that corporate needed a research director for one of it's outposts and thought it would be a cakewalk, there isn't going to be a lot of research to be done on a tiny outpost. Mainly just running scans on the gas giant we are orbiting or some basic RnD. However, they conveniently forgot to tell me that me and my science staff would have to pull double duty as medical staff and that there is no one higher up on the chain of command here, so I get to pull triple duty as acting captain as well! This shit is probably allowed in some 3 point fine print buried underneath the literally thousands of pages of contracts. Well, at least the research will be easy work.

Entry Two - 25/05/2554:
Well, we all expected it at the outpost, CentComm has decided to completely change what research we are doing. They've decided that we should be research the species known as 'xenomporphs'. They announced this change 4 days ago and along with it, sadly, the termination of our current science staff barring me. Not to mention the constant noise made by the construction detail they sent to staple on an xenobiology lab ensuring no one has been able to sleep decently ever since they announced the shift. To make matters worse our current security guard actually died of a heart attack today. Just goes to show that 75 year old men shouldn't be security guards. Still can't believe that they decided to do this major change less than a month after the outpost was established.

Entry Three - 27/05/2554:
The new security guard arrived today. Apparently transferred here from the research station that also is orbiting the gas giant. He seems to be rather angry about his transfer. Considering the rumors I've heard about the research station he's probably caught off guard by the fact that Steve hasn't tried to force an IED down his throat.

Entry Four - 06/06/2554:
My requests for additional security and containment measures for the 'xenomorph' has been denied. Does Central Command not notice how dangerous these creatures are? The only thing keeping them in is a force field, a minor problem with the power grid and the entire hive is loose. What would stop them then, the lone security guard with a dinky little taser? Kenneth can barely handle a short-tempered engineer. We are under equipped and under staffed, we are inevitably going to be destroyed unless we get the equipment and staff we need.

Entry Five - 10/06/2554:
Cunningham got a good look at the xenomorph in containment. He was frightened for the rest of the day, rather amusing if it wasn't for the fact that we are all trapped on this scrap heap with naught but a force field keeping those xenomorphs in.

Entry Six - 17/06/2554:
The reactions from the specimens today has shown that they possess strange mental properties. Mark hypothesizes that they possibly have a sort of hive mind, while nothing is certain this would explain how xenomorphs seem to have vastly increased intellect when a 'queen' is present. Of course, to test this hypothesis would require many complicated procedures which we will not be able to undertake. But we do not know the full extend of the xenomorph mind, it may or may not be able to find a way to circumvent our containment system. I will resend my request for additional security measures along with this new found information."; name = "Personal Log - Gerald Rosswell"},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) +"ht" = (/obj/structure/filingcabinet/chestdrawer,/obj/machinery/light/small{active_power_usage = 0; dir = 1; icon_state = "bulb-broken"; status = 2},/obj/machinery/alarm/monitor{frequency = 1439; locked = 0; pixel_y = 23; req_access = null},/obj/item/weapon/paper{info = "Personal Log for Research Director Gerald Rosswell

Entry One — 17/05/2554:
You know, I can't believe I took this position so suddenly. I saw that corporate needed a research director for one of its outposts and thought it would be a cakewalk; there isn't going to be a lot of research to be done on a tiny outpost. Mainly just running scans on the gas giant we are orbiting or some basic RnD. However, they conveniently forgot to tell me that I and my science staff would have to pull double duty as medical staff, and that there is no one higher up on the chain of command here, so I get to pull triple duty as acting captain as well! This shit is probably allowed in some 3pt. fine print buried underneath the literally thousands of pages of contracts. Well, at least the research will be easy work.

Entry Two — 25/05/2554:
Well, we all expected it at the outpost: CentComm has decided to completely change what research we are doing. They've decided that we should be researching the species known as 'xenomorphs'. They announced this change 4 days ago, and along with it, sadly, the termination of our current science staff, barring me. Not to mention the constant noise made by the construction detail they sent, to staple on a xenobiology lab, ensuring no one has been able to sleep decently ever since they announced the shift. To make matters worse, our current security guard actually died of a heart attack today. Just goes to show, that 75 year old men shouldn't be security guards. Still can't believe that they decided to do this major change less than a month after the outpost was established.

Entry Three — 27/05/2554:
The new security guard arrived today. Apparently transferred here from the research station that also is orbiting the gas giant. He seems to be rather angry about his transfer. Considering the rumors I've heard about the research station, he's probably caught off guard by the fact that Steve hasn't tried to force an IED down his throat.

Entry Four — 06/06/2554:
My requests for additional security and containment measures for the 'xenomorph' has been denied. Does Central Command not notice how dangerous these creatures are? The only thing keeping them in is a force field: a minor problem with the power grid and the entire hive is loose. What would stop them then, the lone security guard with a dinky little taser? Kenneth can barely handle a short-tempered engineer. We are under-equipped and under-staffed, we are inevitably going to be destroyed, unless we get the equipment and staff we need.

Entry Five — 10/06/2554:
Cunningham got a good look at the xenomorph in containment. He was frightened for the rest of the day, rather amusing if it wasn't for the fact that we are all trapped on this scrap heap, with naught but a force field keeping those xenomorphs in.

Entry Six — 17/06/2554:
The reactions from the specimens today have shown that they possess strange mental properties. Mark hypothesizes that they possibly have a sort of hive mind; while nothing is certain, this would explain how xenomorphs seem to have vastly increased intellect when a 'queen' is present. Of course, testing this hypothesis would require many complicated procedures which we will not be able to undertake. Although we do not know the full extend of the xenomorph mind, it may or may not be able to find a way to circumvent our containment system. I will resubmit my request for additional security measures, along with this newfound information."; name = "Personal Log — Gerald Rosswell"},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "hu" = (/obj/structure/closet/crate/bin,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "hv" = (/obj/structure/grille,/obj/machinery/door/poddoor{id_tag = "AwayRD"; layer = 2.9; name = "privacy shutter"},/obj/structure/window/full/reinforced,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "hw" = (/turf/simulated/floor/plasteel{dir = 1; heat_capacity = 1e+006; icon_state = "whitepurplecorner"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) @@ -434,7 +434,7 @@ "ir" = (/obj/structure/stool/bed/chair/office/light{dir = 1; pixel_y = 3},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "is" = (/turf/simulated/floor/plasteel{dir = 8; heat_capacity = 1e+006; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "it" = (/obj/effect/decal/cleanable/blood/splatter{color = "red"},/turf/simulated/floor/plasteel{heat_capacity = 1e+006; icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) -"iu" = (/obj/item/weapon/storage/secure/safe{pixel_x = 32; pixel_y = 0},/obj/effect/decal/cleanable/blood/splatter,/obj/item/weapon/pen,/obj/item/weapon/paper/crumpled{info = "19 06 2554

I fucking knew it. There was a major breach, that idiotic force field failed and the xenomorphs rushed out and took out the scientists. I've managed to make it to my office and closed the blast doors. I can hear them trying to pry open the doors. Probably don't have long. I have no clue what has happened to the rest of the crew, for all I know they've been killed to produce more of the fucks."; name = "Hastily Written Note"},/turf/simulated/floor/plasteel{dir = 4; heat_capacity = 1e+006; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) +"iu" = (/obj/item/weapon/storage/secure/safe{pixel_x = 32; pixel_y = 0},/obj/effect/decal/cleanable/blood/splatter,/obj/item/weapon/pen,/obj/item/weapon/paper/crumpled{info = "19 06 2554

I fucking knew it. There was a major breach, that idiotic force field failed, and the xenomorphs rushed out and took out the scientists. I've managed to make it to my office and closed the blast doors. I can hear them trying to pry open the doors. Probably don't have long. I have no clue what has happened to the rest of the crew, for all I know they've been killed to produce more of the fucks."; name = "Hastily Written Note"},/turf/simulated/floor/plasteel{dir = 4; heat_capacity = 1e+006; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "iv" = (/obj/structure/sign/securearea{pixel_y = 32},/obj/machinery/shower{dir = 4; icon_state = "shower"; name = "emergency shower"; tag = "icon-shower (EAST)"},/turf/simulated/floor/plasteel{dir = 9; heat_capacity = 1e+006; icon_state = "warnwhite"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "iw" = (/obj/structure/closet/firecloset,/turf/simulated/floor/plasteel{dir = 5; heat_capacity = 1e+006; icon_state = "warnwhite"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) "ix" = (/obj/structure/toilet{dir = 4},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plasteel{heat_capacity = 1e+006; icon_state = "freezerfloor"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) @@ -662,7 +662,7 @@ "mL" = (/obj/machinery/door/airlock/shuttle{name = "Shuttle Airlock"},/turf/simulated/shuttle/floor,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) "mM" = (/obj/machinery/door/airlock/external,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) "mN" = (/obj/machinery/door/airlock/external,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) -"mO" = (/obj/machinery/light/small{dir = 4},/obj/effect/decal/cleanable/dirt,/obj/structure/noticeboard{dir = 8; pixel_x = 32; pixel_y = 0},/obj/item/weapon/paper{info = "

Welcome to Moon Outpost 19! Property of Nanotrasen Inc.




Staff Roster:
-Dr. Gerald Rosswell: Research Director & Acting Captain
-Dr. Sakuma Sano: Xenobiologist
-Dr. Mark Douglas: Xenobiologist
-Kenneth Cunningham: Security Officer-Ivan Volodin: Engineer
-Mathias Kuester: Bartender
-Sven Edling: Chef
-Steve: Assistant

Please enjoy your stay, and report any abnormalities to an officer."; name = "Welcome Notice"},/obj/machinery/camera{c_tag = "Arrivals South"; dir = 8; network = list("MO19")},/turf/simulated/floor/plasteel{dir = 4; heat_capacity = 1e+006; icon_state = "warning"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) +"mO" = (/obj/machinery/light/small{dir = 4},/obj/effect/decal/cleanable/dirt,/obj/structure/noticeboard{dir = 8; pixel_x = 32; pixel_y = 0},/obj/item/weapon/paper{info = "

Welcome to Moon Outpost 19! Property of Nanotrasen Inc.


Staff Roster:


Please enjoy your stay, and report any abnormalities to an officer."; name = "Welcome Notice"},/obj/machinery/camera{c_tag = "Arrivals South"; dir = 8; network = list("MO19")},/turf/simulated/floor/plasteel{dir = 4; heat_capacity = 1e+006; icon_state = "warning"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) "mP" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating/airless/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) "mQ" = (/obj/machinery/light/small{dir = 8},/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; dir = 9; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/plasteel{carbon_dioxide = 48.7; dir = 8; heat_capacity = 1e+006; icon_state = "neutralcorner"; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) "mR" = (/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; dir = 4; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/plasteel{burnt = 1; carbon_dioxide = 48.7; dir = 8; heat_capacity = 1e+006; icon_state = "floorscorched2"; nitrogen = 13.2; oxygen = 32.4; tag = "icon-floorscorched2 (WEST)"; temperature = 251},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm index c4bcd7b34d2..a43e0d5aada 100644 --- a/_maps/map_files/cyberiad/cyberiad.dmm +++ b/_maps/map_files/cyberiad/cyberiad.dmm @@ -168,7 +168,7 @@ "adl" = (/obj/structure/table/woodentable,/obj/machinery/atmospherics/unary/vent_pump,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/carpet,/area/security/hos) "adm" = (/obj/structure/table/woodentable,/turf/simulated/floor/carpet,/area/security/hos) "adn" = (/obj/machinery/door_control{id = "Prison Gate"; name = "Prison Wing Lockdown"; pixel_x = -28; pixel_y = 7; req_access_txt = "2"},/obj/machinery/door_control{id = "Secure Gate"; name = "Brig Lockdown"; pixel_x = -28; pixel_y = -3; req_access_txt = "2"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/hos) -"ado" = (/obj/structure/table/woodentable,/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/hos) +"ado" = (/obj/structure/table/woodentable,/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen/multi,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/hos) "adp" = (/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = 0; pixel_y = 10},/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/obj/effect/decal/warning_stripes/east,/obj/item/clothing/glasses/welding,/obj/item/device/radio/intercom/department/security{pixel_x = -28},/turf/simulated/floor/plasteel,/area/security/podbay) "adq" = (/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor/engine,/area/security/podbay) "adr" = (/obj/machinery/light{dir = 1; on = 1},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/engine,/area/security/podbay) @@ -314,7 +314,7 @@ "agb" = (/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 1},/area/security/securehallway) "agc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 5},/area/security/securehallway) "agd" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/wall,/area/security/podbay) -"age" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/obj/structure/table/reinforced,/obj/item/clothing/suit/jacket,/obj/item/clothing/head/beret/sec,/obj/machinery/light_switch{pixel_x = -25},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/podbay) +"age" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/obj/structure/table/reinforced,/obj/item/clothing/suit/jacket/pilot,/obj/item/clothing/head/beret/sec,/obj/machinery/light_switch{pixel_x = -25},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/podbay) "agf" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/podbay) "agg" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/podbay) "agh" = (/obj/structure/closet/secure_closet/security,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 4; name = "Security Podbay APC"; pixel_x = 25},/obj/item/device/spacepod_equipment/weaponry/laser,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/podbay) @@ -1724,7 +1724,7 @@ "aHh" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24; shock_proof = 1},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor/plating,/area/maintenance/electrical) "aHi" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/electrical) "aHj" = (/obj/structure/table,/obj/item/clothing/gloves/color/fyellow,/obj/item/weapon/storage/toolbox/electrical,/obj/item/device/multitool,/obj/item/device/radio/intercom{pixel_x = 25},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/maintenance/electrical) -"aHk" = (/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/space) +"aHk" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel,/area/hallway/primary/starboard/east) "aHl" = (/obj/structure/sign/pods,/turf/simulated/wall,/area/hallway/secondary/entry) "aHm" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9; icon_state = "intact"},/turf/simulated/floor/plating,/area/engine/engineering) "aHn" = (/obj/item/weapon/wrench,/turf/simulated/floor/plating,/area/maintenance/fpmaint2) @@ -3551,7 +3551,7 @@ "bqo" = (/obj/machinery/camera{c_tag = "Starboard Primary Hallway 1"; dir = 2; network = list("SS13")},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel,/area/hallway/primary/starboard/west) "bqp" = (/obj/machinery/status_display{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel,/area/hallway/primary/starboard/west) "bqq" = (/obj/machinery/atm{pixel_y = 32},/turf/simulated/floor/plasteel,/area/hallway/primary/starboard/west) -"bqr" = (/turf/simulated/floor/plasteel,/area/hallway/primary/starboard) +"bqr" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 10},/obj/item/weapon/pen/multi/fountain,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door_control{id = "captainofficedoor"; name = "Office Door"; normaldoorcontrol = 1; pixel_x = 5; pixel_y = -3; req_access_txt = "20"},/obj/item/device/radio/intercom{pixel_x = -28},/turf/simulated/floor/wood,/area/crew_quarters/captain) "bqs" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor/plasteel,/area/hallway/primary/starboard/west) "bqt" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/effect/spawner/window/reinforced,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plating,/area/engine/gravitygenerator) "bqu" = (/turf/simulated/floor/plasteel{dir = 9; icon_state = "green"},/area/hallway/primary/starboard/west) @@ -3559,7 +3559,7 @@ "bqw" = (/turf/simulated/floor/plasteel{dir = 5; icon_state = "green"},/area/hallway/primary/starboard/west) "bqx" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plasteel,/area/hallway/primary/starboard/east) "bqy" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/hallway/primary/starboard/east) -"bqz" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel,/area/hallway/primary/starboard) +"bqz" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen/multi,/obj/item/weapon/pen/multi,/obj/item/device/megaphone,/turf/simulated/floor/plasteel,/area/crew_quarters/heads) "bqA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/hallway/primary/starboard/east) "bqB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/hallway/primary/starboard/east) "bqC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atm{pixel_y = 32},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/hallway/primary/starboard/east) @@ -3735,7 +3735,7 @@ "btQ" = (/obj/machinery/vending/cigarette,/turf/simulated/floor/wood,/area/bridge/meeting_room) "btR" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload) "btS" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload) -"btT" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 10},/obj/item/weapon/pen{pixel_y = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door_control{id = "captainofficedoor"; name = "Office Door"; normaldoorcontrol = 1; pixel_x = 5; pixel_y = -3; req_access_txt = "20"},/obj/item/device/radio/intercom{pixel_x = -28},/turf/simulated/floor/wood,/area/crew_quarters/captain) +"btT" = (/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/structure/table/glass,/obj/item/weapon/pen/multi,/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/hor) "btU" = (/obj/structure/table/woodentable,/obj/item/weapon/folder/blue,/obj/item/weapon/stamp/captain,/turf/simulated/floor/wood,/area/crew_quarters/captain) "btV" = (/obj/structure/table/woodentable,/obj/item/weapon/hand_tele,/turf/simulated/floor/wood,/area/crew_quarters/captain) "btW" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp/green,/turf/simulated/floor/wood,/area/crew_quarters/captain) @@ -4004,9 +4004,9 @@ "byZ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/turf/simulated/floor/wood,/area/crew_quarters/captain) "bza" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/computer/security/telescreen/entertainment{pixel_x = 32},/turf/simulated/floor/wood,/area/crew_quarters/captain) "bzb" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plasteel{dir = 8; icon_state = "bluecorner"},/area/hallway/primary/central/se) -"bzc" = (/obj/item/clothing/glasses/science,/obj/item/clothing/glasses/science,/obj/item/clothing/glasses/science,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/structure/table/glass,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/chemistry) +"bzc" = (/obj/machinery/chem_heater,/obj/machinery/alarm{pixel_y = 22},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/chemistry) "bzd" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/chemistry) -"bze" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/chemistry) +"bze" = (/obj/item/clothing/glasses/science,/obj/item/clothing/glasses/science,/obj/item/clothing/glasses/science,/obj/structure/table/glass,/obj/structure/reagent_dispensers/fueltank/chem{pixel_x = -32},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/chemistry) "bzf" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/chemistry) "bzg" = (/obj/item/weapon/hand_labeler,/obj/item/weapon/reagent_containers/spray/cleaner{desc = "Someone has crossed out the 'Space' from Space Cleaner and written in Chemistry. Scrawled on the back is, 'Okay, whoever filled this with polytrinic acid, it was only funny the first time. It was hard enough replacing the CMO's first cat!'"; name = "Chemistry Cleaner"},/obj/item/device/radio/intercom{frequency = 1459; name = "station intercom (General)"; pixel_x = 28},/obj/structure/table/glass,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/chemistry) "bzh" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/reception) @@ -4239,7 +4239,7 @@ "bDA" = (/turf/space,/turf/simulated/shuttle/wall{icon_state = "swall_f6"; dir = 2},/area/shuttle/research) "bDB" = (/obj/structure/grille,/obj/structure/window/full/shuttle,/turf/simulated/shuttle/plating,/area/shuttle/research) "bDC" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 8},/turf/unsimulated/floor,/area/shuttle/specops) -"bDD" = (/obj/machinery/camera{c_tag = "CentCom Special Ops. Shuttle"; dir = 2; network = list("ERT","CentCom")},/obj/structure/stool/bed/chair,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops) +"bDD" = (/obj/machinery/camera{c_tag = "CentComm Special Ops. Shuttle"; dir = 2; network = list("ERT","CentComm")},/obj/structure/stool/bed/chair,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops) "bDE" = (/obj/effect/spawner/window/reinforced,/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = 0},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry) "bDF" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry) "bDG" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry) @@ -4596,7 +4596,7 @@ "bKt" = (/obj/machinery/vending/cart,/turf/simulated/floor/plasteel,/area/quartermaster/office) "bKu" = (/obj/structure/closet/secure_closet/hop2,/turf/simulated/floor/plasteel,/area/crew_quarters/heads) "bKv" = (/turf/simulated/floor/plasteel,/area/crew_quarters/heads) -"bKw" = (/obj/structure/table,/obj/item/weapon/pen,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/obj/item/device/megaphone,/turf/simulated/floor/plasteel,/area/crew_quarters/heads) +"bKw" = (/obj/item/weapon/paper_bin,/obj/item/weapon/folder/white{pixel_y = 10},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/weapon/reagent_containers/food/drinks/coffee,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/accessory/stethoscope,/obj/item/weapon/stamp/cmo,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 32; pixel_y = 0},/obj/structure/table/glass,/obj/item/weapon/pen/multi,/turf/simulated/floor/plasteel{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/medical/cmo) "bKx" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/turf/simulated/floor/plasteel,/area/crew_quarters/heads) "bKy" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 32; pixel_y = 0},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel,/area/crew_quarters/heads) "bKz" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/crew_quarters/heads) @@ -4969,7 +4969,7 @@ "bRC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/plasteel{dir = 5; icon_state = "whitehall"},/area/medical/research{name = "Research Division"}) "bRD" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plasteel{dir = 9; icon_state = "whitehall"},/area/medical/research{name = "Research Division"}) "bRE" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/crew_quarters/hor) -"bRF" = (/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/obj/structure/table/glass,/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/hor) +"bRF" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter/zippo,/obj/item/weapon/pen/multi,/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/engine/chiefs_office) "bRG" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/hor) "bRH" = (/obj/machinery/computer/mecha,/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/hor) "bRI" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/rack,/obj/item/device/taperecorder{pixel_x = -3},/obj/item/device/paicard{pixel_x = 4},/turf/simulated/floor/plasteel{dir = 10; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTHEAST)"},/area/crew_quarters/hor) @@ -5416,7 +5416,7 @@ "cah" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/disposalpipe/segment,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/cmo) "cai" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/cmo) "caj" = (/obj/structure/stool/bed/chair/office/dark{dir = 1},/obj/effect/landmark/start{name = "Chief Medical Officer"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/cmo) -"cak" = (/obj/item/weapon/paper_bin,/obj/item/weapon/pen,/obj/item/weapon/folder/white{pixel_y = 10},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/weapon/reagent_containers/food/drinks/coffee,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/accessory/stethoscope,/obj/item/weapon/stamp/cmo,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 32; pixel_y = 0},/obj/structure/table/glass,/turf/simulated/floor/plasteel{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/medical/cmo) +"cak" = (/obj/machinery/prize_counter,/turf/simulated/floor/wood,/area/crew_quarters/bar) "cal" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/cmo) "cam" = (/obj/machinery/photocopier,/turf/simulated/floor/plasteel{tag = "icon-whiteblue (SOUTHWEST)"; icon_state = "whiteblue"; dir = 10},/area/medical/medbay2) "can" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{tag = "icon-whitebluecorner (WEST)"; icon_state = "whitebluecorner"; dir = 8},/area/medical/medbay2) @@ -7180,7 +7180,6 @@ "cId" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/engine/chiefs_office) "cIe" = (/obj/structure/table/reinforced,/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/machinery/photocopier/faxmachine{department = "Chief Engineer's Office"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/engine/chiefs_office) "cIf" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/table/reinforced,/obj/item/weapon/clipboard,/obj/item/weapon/folder/yellow,/obj/item/weapon/stamp/ce,/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/engine/chiefs_office) -"cIg" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/pen,/obj/item/weapon/lighter/zippo,/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/engine/chiefs_office) "cIh" = (/obj/structure/closet/secure_closet/engineering_welding,/turf/simulated/floor/plasteel,/area/engine/equipmentstorage) "cIi" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plasteel,/area/engine/equipmentstorage) "cIj" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/engine/equipmentstorage) @@ -7722,6 +7721,7 @@ "cSz" = (/obj/machinery/camera{c_tag = "Atmospherics South-East"; dir = 1; network = list("SS13")},/obj/machinery/atmospherics/binary/valve/digital/open{name = "Mixed Air Outlet Valve"},/turf/simulated/floor/plasteel{icon_state = "arrival"; dir = 6},/area/atmos) "cSA" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "atmos"; name = "Atmos Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/atmos) "cSB" = (/turf/simulated/floor/plating/airless,/obj/structure/cable,/obj/machinery/power/tracker,/turf/simulated/floor/plating/airless/catwalk{tag = "icon-catwalk1"; icon_state = "catwalk1"},/area/solar/starboard) +"cSC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/chemistry) "cSD" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/grille,/turf/simulated/floor/plating/airless,/area/engine/engineering) "cSE" = (/turf/simulated/floor/plating/airless,/area/engine/engineering) "cSF" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/green{dir = 6},/turf/simulated/floor/plating,/area/atmos) @@ -8471,7 +8471,7 @@ "dha" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/item/broken_device,/obj/item/robot_parts/chest,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) "dhb" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/item/weapon/scalpel,/obj/item/stack/cable_coil,/obj/item/weapon/storage/firstaid/regular,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) "dhc" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/item/weapon/pickaxe,/obj/item/weapon/storage/firstaid/toxin,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) -"dhd" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/optable,/obj/item/organ/brain,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) +"dhd" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/optable,/obj/item/organ/internal/brain,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) "dhe" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/item/weapon/circular_saw,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) "dhf" = (/obj/machinery/door/poddoor/shutters{density = 0; dir = 4; icon_state = "shutter0"; id_tag = "voxshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/shuttle/window{dir = 4; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5_mid"; tag = "icon-window5 (EAST)"},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox) "dhg" = (/obj/item/weapon/storage/toolbox/syndicate,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) @@ -8813,7 +8813,7 @@ bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbi bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaDEaDGcUCaEDaDEaEFddzaEGaEJaEKazHaELaEMaENaDKaEOazHaxVaxVaxVaxVaxVaxVaxVaCLaxVaEPaEQaERaxVaESaETaEUazHaEOaxVaENaEVaBEaBFaEWbikbikbikbikbikaEXaEYaEZaFaaFbaFcaFdaDMaabaCMaFeaFfaFgaCMaFhazOaFiaFjaFkaFlaABaFnaBPaFoaFpaFqaFraFsaFtaFuaFvaydaFwaFxaFyaFzaFAaCZaDaaDbaFBaEhaFCaFCaFCaEhaEhaFDaFEaFEaFFaEiaFGaFHaFIaFIaFJaFKaFLaFMaChaChaChaChaChaFNaFOaFPaFQbikbikazvayHayHaFRayHaEsaFSayHaFTaFUaFUaFUaFUaFVaFUaFWayHayHayHayHayHayHayHayHayJayIaDCaFXaFYaFYaDCaFZaGaaGbaDCbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaDEaGcaGdaGeaDEaGcaGdaGeaEJaBzazHaGfazHazHazHazHazHaxVaGgaGhaGiaGjaGkaxVaCLaxVaEQaGlaEPaGmaGnaGoaxVaGpaxVaxVaxVaxVaGpaCLaEWbikazyazyazyazyaGqaEYaGraGsaGtaGuaGvaGwaDMaCMaBHaGxaGxaGxaGyaGzaGAaGzaGzaGzaGBaGCaGDaGEaGFaGFaGFaGFaGGaGHaGIaxqaGJazIatsaGKaGLaCZaDaaDbaEgaFCaGMaGMaGNaFCaEhaGOaGPaGPaGQaGRaFGaGSaGTaGUaGVaEhaGWaFQaChaChaChaChaChaFQaGXaGYaFQaabaabayGayHayHayJayJaEsaGZaGZaAiaAiaAiaEsaEsaEsayGaHaaHbayGayJayJayGayJayJayGayGaHcaHdaHeaHfaHgaHhaHiaFXaHjaDCbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaCuaDEaEIaHlaCuaDEaEIaHlaCuaxVaCBaxVaxVaxVaxVaxVazHaxVazHaHnaHoazHazHaxVaCLaxVaHpaabaHpaxVaBvaGoaxVaHqaHraxVaENaBzaxVaAwaDMaDMaHsaHsaHsaHsaHsaHsaHsaHsaHsaGvaGvaGwaHtaHuaHvaHwaHxaHyaHzaHAaHBaHBaHBaHBaHCaHDaHEaHFaHGaHBaHBaHHaHHaHIaHJaHKaHLaHMaHNaGKaHOaHPaHPaDbaEgaFCaHQaHRaHSaFCaEhaGOaGPaGPaGQaHTaFGaGSaGUaGUaGVaEhaGWaFQaChaChaChaChaChaFQaHUaGYaFQbikbikayGaHVayHayHaHWayJaHXazwaHYaHZayKayGaFSayKayGaIaayHayGaIbayHayGaIcaIdaIeaFUaIfaFUaIgaIhaIiaIjaIkaIlaImaDCaDDaDDaacaacaDDaDDaDDaDDaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaInaIoaHkaIoaIqaIoaIoaIoaIsaItaIuaIuaIuaIuaIvaxVazHaxVaIwaIxaIyazHaIzaGpaCLaxVaxVaxVaxVaxVaxVaGpaxVazHaIyaCBazHazHaGvaIAaIBaICaIDaIDaIDaIDaIEaIDaIDaIFaIGaICaIHaIIaIIaIIaIIaIIaIIaIIaIJaIKaIKaIKaIKaILaIMaIKaINaIKaIOaILaIKaIKaIKaIKaIPaIQaIRaISaITaFzaIUaIVaHPaIWaEgaFCaIXaIYaGMaFCaEhaIZaJaaJaaJbaEiaFGaJcaJdaJdaJeaEhaJfaJgaChaChaChaChaChaJhaJiaJjaFQbikbikayGayHayHayHayHayHayHaIeaFUaFUaFUaFUaFUaFUaFUaCmayHayHayHayHaDzayHayHaDxayHaJkaJlaJmaJnaJoaFYaFYaFYaJpaDCaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaInaIoaIoaIoaIqaIoaIoaIoaIsaItaIuaIuaIuaIuaIvaxVazHaxVaIwaIxaIyazHaIzaGpaCLaxVaxVaxVaxVaxVaxVaGpaxVazHaIyaCBazHazHaGvaIAaIBaICaIDaIDaIDaIDaIEaIDaIDaIFaIGaICaIHaIIaIIaIIaIIaIIaIIaIIaIJaIKaIKaIKaIKaILaIMaIKaINaIKaIOaILaIKaIKaIKaIKaIPaIQaIRaISaITaFzaIUaIVaHPaIWaEgaFCaIXaIYaGMaFCaEhaIZaJaaJaaJbaEiaFGaJcaJdaJdaJeaEhaJfaJgaChaChaChaChaChaJhaJiaJjaFQbikbikayGayHayHayHayHayHayHaIeaFUaFUaFUaFUaFUaFUaFUaCmayHayHayHayHaDzayHayHaDxayHaJkaJlaJmaJnaJoaFYaFYaFYaJpaDCaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaInaJqaJraJsaJtaJuaJvaJwaJxaJvaJyaJzaJvaJvaJAaxVazHaxVaJBazHazHaJCaJDaxVaEVaBFazHazHazHazHazHazHaGpaJEazHaxVaEKaEKaDMaJFaDMaJGaJHaJIaJIaJIaJJaJIaJIaJIaJKaJGaJLaJMaJMaJMaJMaJMaJMaJMaGvaIKaJNaJOaJPaJQaJRawxaJTaJUaJVaJWaJXaJOaJYaIKaJZaxqaKaazIaKbaGKaKcaKdaKdaKeaKfaKgaKhaKiaKiaKjaKkaKlaKjaKkaKkaKmaKnaKoaEhaEhaKpaEhaKqaKraChaChaChaChaChaKraCfaCfaCfayGayGayGayKayJayJaAkayGayGaDxayJayGaKsayJayGaAkayGaDxaHVayJayGaAkayGayHaHVaDxayHaKtaDCaKuaIhaKvaKwaKxaIhaKyaDCaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabaabaDEaKzaKAaKzaKBaJraJraKCaKzaKAaKzaKDaKEaKFaKGaxVazHaGpaGpaxVaxVaxVaKHaKHaKHazNaKHaKHaKHaKHaKHaGvaDMaDMaDMaDMaDMaDMaDMaJFaKIaJGbikaabbikaabbikaabbikaabbikaJGaJLaJMaKJaKKaKLaKMaKNaJMaGvaIKaKOaKOaKPaKQaKRaKSaKTaKSaKUaKVaKWaKOaKOaIKaJZaxqaKXazIaKbaGKaGLaCZaDaaDbaEgaKYaKZaLaaLbaLcaLcaLdaLeaLcaLeaLfaLgaLhaLiaLjaLkaLlaCfaKraChaChaChaChaChaKrayGaCtayHaLmaLnayJayGayJaCtayHayGaCtaDxayGaLoayHayGaLpayHayJaLqaLrayGaLsayHayJaAkaAkaDxaAkaLtaDCaLuaIhaLvaLwaLvaIhaLxaDCaabaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabaLyaCuaLzaGdaKzaLAaLBaLCaLDaKzaGdaLEaInaCuaLFaLGaxVazHazHazHazHazHazHaKHaLHaLIaLJaLKaLLaLMaLHaKHaLNaLOaIDaIDaIDaIDaIDaIDaLPaLQaJGaabaLRaLRaLRaLRaLRaLRaLRaabaJGaJLaJMaLSaLTaLUaLVaLSaJMaGvaIKaIKaIKaIKaLWaLXaJOaLYaJOaLXaLZaIKaIKaIKaIKaJZaxqaMaazIaKbaGKaFAaCZaDaaDbaFBaMbaMcaMcaMcaMcaMcaMcaMcaMdaMcaMeaMeaMeaMeaMeaMfayGaCfaKraChaChaChaChaChaKrayGayGayHaMgaLnayJaMhayGayHayHayGayHaDxayJayHayHayGayHayHayJaDxayIayGayHayHayJaMiayHaDxayHaMjaMkaMkaDCaDCaDCaDCaDCaDCaDCaDDaDDaDDaDDaDDaabbikbikbikbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik @@ -8834,32 +8834,32 @@ bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbi bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikblsbltbltblubltbltbltblvbltbltbmPaabaInaLAaJtbilbgNbimbinbiobipbiqbirbisbitbgNbiubivbiwbixbcobiybecbecbgRbgTbizbiAbgRbecbecbiBbiCbcobejbekbctbctbiDbctbcvbiEbiFbiGbcvbiHbhfbiIbhfbiJbesbeubiKaXOaXPaXPbiLbiMbiNbcEbiObfRbiPbhobhobiQbiRbiSakybiSbiUbiVbiWbiXbiYbiZbjabcEbjbbiMbjcbjdbjebeGaYiaYibjfbmwbjgbmwbmwbmwbjhbjibmwbhDbjjbglbmwbeLbeMbeMbjkbjlbjmbjnbjobjpbhLbjqaVbbjrbhNbeXbeYbeYbeXbhPbjsaVbbjtbjuaRDbjvaRDaRDbjwbbQbjxbjyaTvbjzbjAaWSbjBbdvbjCbjDbjEbjFbjFbjGbjHbjIbdvbjJbjKbatbjLbatbavbatbatddAbaAbaAbaAbaAbgKbqUddBbmKbutbwmbtmbmKbutbwmbtmbmKddCbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikblsbohbptbojbpwbpwbqWbpwbpwbpwbqWblubjNaInaKzaKBbfqbgNbimbjObjPbimbjQbjRbjSbjTbgNbjUaFmbjWbcsbcobjXbjYbjZbkabkbbkcbkdbkebkebkebkfbkgbcobejbivbkhbkibkjbkkbcvbcvbcvbcvbcvbklbkmbknbkobkpbesbeubiKaXJaXJaXJbkqbkrbksbktbkubkvbhobkwbkxbkybkzbkAbkBbkCbkDbkEbkFbkGbkubkHbkIbkJbkKbkMbkLbkObkObkPaYibkQaMebmwbkRbkSbglbmwbkTbkUbmwbkVbkWbglbmwbnMbeMbeMbeMbeNbeMbkXbeMbjpbhLbkYaVbbkZbhNbeXbeYbeYbeXbhPblaaVbblbblcbldbleblfblgblhblibljbljbljbljbljbljblkbllblmbfgbfgbfgbfgbfgbfgblnbloblpbgHbatbatbatbavbatbatddDbgKblrblrblrbaAbwmbtmbmKbutbBQbtmbmKbutbBQbtmbmKbutbwmbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbqYbqXbqXbqXbqXbqXbqXbqXbqXbqXbqXbqZbraaGdbraaJrbfqbgNblwbimblxblxblxblybimblzbgNblAblBbjWblCblCblCblCblDblCblEbecblFblGblHblHblIblJbcoblKblLblMblNblOblPblQblRblSblRblTblTblTblTblTblUberbeublVblWblXblYblZbmabmbbmcbmdbkBbmebmfbmgbmgbmgbmgbmhbmgbmibmjbmkbmlbmebmmbmnbcEbmobmpbmqbkNbmsbmtaYiaYibjfbmwbnCbmwbmwbmwaRebmwbmwbmvbmvbmwbmwbmxbeMbeMbmybmzbeMbeMbeMbmAbmBbmCaVbbgxbhNbeXbeXbeXbeXbhPbmDaVbbmEbmFbmFbmGbmFbmHbbPbbPbbPbbPbmIbbPbbPbbPbmJblobfgbfgbfgbfgbfgbfgbfgblnbloblpbgHbatbfjbfjbfkbfjbatddEbaAbmLbmMbmNbaAbBQbtmbmKbutbBQbtmbmKbutbBQbtmbmKbutbBQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbrcbrbbrebrdbrfbrfbrgbrfbrfbrfbrgbluaInaInaKzbrVbcjbmQbimbmRblxblxblxblybmRbimbgNbmSbmTbjWblCbmUbmVbmWbmXblCbmYbmZbnabcobnbbncbndbnebcobejbnfbngbngbnhbngbngbngbngbnibnjbnjbnjbnkbnjbnlbnmbnnbnobnpbnqbnqbnqbnqbnqbnqbnrbnsbnrbmgbmgbntbnubnvbnwbnxbnybntbnzbmgbnAbnBbnAbnAbnAbnAbnAbnAbnAbmtaYiaYiaMebnEbnDbmwbnGbmwbnFbmwbnIbnHbnJbmwbpjaUTbnKbnLaUTaUTczObnNddybnNaUTaUTaVbbnObnPbnQbnQbnQbnQbnPbnRaVbbnSbmFbmFbmGbnTaRDbnUbnVbnWbnXbnYbnZboabobbocaQbbodaRSboebfgbfgboeaRSbofaQbbogbgHbatbgIbgIbgJbgIbatddDbgKblrblrblrbaAbGVbtmbmKbutbGVbtmbmKbutbGVbtmbmKbutbGVbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbrcbrbbrebrdbrfbrfbrgbrfbrfbrfbrgbluaInaInaKzbrVbcjbmQbimbmRblxblxblxblybmRbimbgNbmSbmTbjWblCbmUbmVbmWbmXblCbmYbmZbnabcobnbbncbndbnebcobejbnfbngbngbnhbngbngbngbngbnibnjbnjbnjbnkbnjbnlbnmbnnbnobnpbnqbnqbnqbnqbnqbnqbnrbnsbnrbmgbmgbntbnubnvbnwbnxbnybntbnzbmgbnAbnBbnAbnAbnAbnAbnAbnAbnAbmtaYiaYiaMebnEbnDcakbnGbmwbnFbmwbnIbnHbnJbmwbpjaUTbnKbnLaUTaUTczObnNddybnNaUTaUTaVbbnObnPbnQbnQbnQbnQbnPbnRaVbbnSbmFbmFbmGbnTaRDbnUbnVbnWbnXbnYbnZboabobbocaQbbodaRSboebfgbfgboeaRSbofaQbbogbgHbatbgIbgIbgJbgIbatddDbgKblrblrblrbaAbGVbtmbmKbutbGVbtmbmKbutbGVbtmbmKbutbGVbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbrcbltbltblubltbltbltblvbltbltbtnaabaInboibdFbokbgNbjObjObjObimbolbombonboobgNbopboqbjWblCborblCbosbotblCboubovbowbcobnbbncbndbiCbcobejbnfbngboxboybozboAboBbngboCboDboEboFbnmbnmbnmbnmboGboHboIbnqboJboKboLboMboNboOboPboQbmgboRbnvboSboTboUboTboSbnvboVbmgboWboXboYboZbpabpbbpcbpdbnAbpebpfbpfbpgaMeaMeaMeaMebphbjfbphbpiaMeaURaMeaMeaUTaUTaUTaUTbplbpkbpkbpkbpkbpmbpJaVbbakbpnbakbpobpobakbpnbakaVbbnSbmFbmFbppbnTaRDaRDaRDaRDaRDbjvaRDaRDaRDaRDaQbbpqaQcaQcaQcaQcaQcaQcaQbaQbbprbpsbatbatbatbavbatbatddAbaAbaAbaAbaAbgKbqUddFbmKbmKbmKbmKbmKbmKbmKbmKbmKddGbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaLyaCuaKzaKzaKzaDEaDEaDEaDEaDEaDEbtobpubgNbgNbgNbgNbgNbgNbpvbgNbgNbgNbejbejbpxblCbpybpzbosbpAblCdlEbpCbpBbcobnbbncbndbecbcobejbnfbngbpDbpEbpFboAbpFbngboCbpGbpHbpIbmubpKbpLbnmbpMbpNboIbpObpPbpQbpRbpSbpSbpRbpTbpUbmgbpVbnvbnvbpWbpXboTboSbnvbpYbmkbpZbqabqbbqcbqdbqebqbbqfbnAbqgbqhbqibqjbqkbqlbqmbqnbqnbqnbqnbqnbqnbqobqpbqqbqrbqnbqsbqnbqnbqnbqnbqnbqnbqnbqndcZbqubqvbqvbqvbqvbqvbqvbqwbqlbqxbqybqybqzbqAbqBbqAbqCbqAbqDbqEbqFbqAbqGbqHbqIbqJbqKbqKbqKbqKbqKbqKbqKbqLbqMbqNbqNbqNbqNbqObqNbqPbKnddHbPfddIbiibPfdlbbmKbmKbmKbmKddKbmKddKbmKbmKbmKddGbdBbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaLyaCuaKzaKzaKzaDEaDEaDEaDEaDEaDEbtobpubgNbgNbgNbgNbgNbgNbpvbgNbgNbgNbejbejbpxblCbpybpzbosbpAblCdlEbpCbpBbcobnbbncbndbecbcobejbnfbngbpDbpEbpFboAbpFbngboCbpGbpHbpIbmubpKbpLbnmbpMbpNboIbpObpPbpQbpRbpSbpSbpRbpTbpUbmgbpVbnvbnvbpWbpXboTboSbnvbpYbmkbpZbqabqbbqcbqdbqebqbbqfbnAbqgbqhbqibqjbqkbqlbqmbqnbqnbqnbqnbqnbqnbqobqpbqqbqnbqnbqsbqnbqnbqnbqnbqnbqnbqnbqndcZbqubqvbqvbqvbqvbqvbqvbqwbqlbqxbqybqyaHkbqAbqBbqAbqCbqAbqDbqEbqFbqAbqGbqHbqIbqJbqKbqKbqKbqKbqKbqKbqKbqLbqMbqNbqNbqNbqNbqObqNbqPbKnddHbPfddIbiibPfdlbbmKbmKbmKbmKddKbmKddKbmKbmKbmKddGbdBbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbtpbtqbtqbtqbtqbwpbwpbtqbtqbxZbikaabaInaLAaJtbzPbzObzRbzQbzQbzQbzQbzSbzUbzTbcsbdVbBFbrhblCblCblCbribotblCbcobcobcobcobnbbrjbrkbrlbcobrmbrnbngbrobrpboAbpFbrqbngboCbrrbpHbpIbpIbrsbrtbnmbrubpNboIbpObrvbrwbrxbrybrzbrAbpTbrBbmgbrCbpWbnvbrDbrEbrDbnvbpWbrFbnzbrGbqbbqbbqcbrHbqebqbbrIbnAbrJbqibqibqjbqkbqlbqnbqnbqnbqnbqnbqnbqnbrKbqnbqnbqnbqnbqnbqnbrLbrMbrMbrMbrMbrMbrMbrMbrMbrMbrMbrMbrMbrMbrMbrNbrObrPbqKbqKbrQbmFbmFbmFbmFbmFbmGbmFbmFbmFbmFbmFbmFbmFbmFbmFbmFbmFbmFbrRbmFbrSbrTbatbatbatbatbatbatbatddLbaAbgKbaAbaAbaAbqUddMddOddNbdBddPbdBddPbdBddQddMddObqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbBGbDCbBHdjhbDDdjidjidjkdjjbtqbxZbjNaInaInaKBbrWbrXbrYbrXbrXbrXbrXbrZbsabsbbcsbcsbscbsdblCbmUbsebsfbpAblCbsgbshbsgbcobcobcobcobsibcobsjbskbngbslbsmbpFbsnbsobngboCbnmbspbpIbpIbpIbsqbnmbsrbpNboIbpObssbrwbrxbstbsubrAbpTbsvbmgbswbsxbnvbsybszbsAboSbsBbsCbsDbsEbsFbsGbsHbsIbsJbqbbsKbnAbsLbsMbqibqjbqkbqlbqnbsNbqnbqnbqnbqnbsObsPbsPbsPbsPbsQbqnbqnbqnbqnbsRbqnbsNbsSbqnbsTbsUbsVbqnbsWbsXbsXbsYbsZbtabtbbmFbmFbmFbmFbmFbmFbmFbtcbtdbmFbmFbmFbmFbmFbmFbmFbmFbmFbmFbmFbtebtfbtfbtgddSddRddUddTddTddTddTddVddWbaAaabbikbikaabbqUddXddZddYdeabqUbikbqUdecdebdecdecbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbBGbDCdjldjidjidjidjidjidjidjideHdjnaGddjnaJrbtrbrXbtsbttbtubtvbtwbrZbtxbtybtzbtzbtAbtBblCblCblCbosbtCborbcsbcsbcsbcsbtDbejbejbskbejbsjbskbngbtEbtFbtGbtHboAbngbtIbnmbtJbpIbpIbpIbtKbtLbtMbpNbtNbnqbtObtPbpRbpRbpRbpRbpTbtQbmgbtRbtSbmgbmgbmgbmgbmgbmgbmgbnzbnAbtTbtUbtVbtWbtXbtYbtZbnAbvubuabuabucbucbucbucbucbucbucbudbudbuebufbugbugbufbuebudbudbuhbuhbuhbuhbuhbuhbuibuibujbuibuibuibuibuibukafkbumbunbmFbmFbuobuobupbupbupbupbupbuqbtfbtfbtebtfbmFbtfbtfbtfbtfburbusbusbusbusdedbuubuubuubuubuubuubuubuubuubikbikbikbikbdBddYddYddYdeebqUbikbqUdefdebdebdegbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbBGbDCdjodjpdjpdjidjpdjpdjpbtqdjqaInaInaInaKBbuvbrXbuwbuxbuxbuxbuybrZbejbuzbuAbuBbuCbuDblCbmUbuEbosbuFborbuGbuHbuIbuJbuKbuLbuLbuMbuLbuNbuObngbuPbuQbuRbuSbuTbuUbuVbnmbuWbpIbpIbuXbuYbuZbtMbpNbvabnqbvbbvcbvdbvebvfbvgbvhbnqbnqbvibvjbvkbvlbvmbvlbvnbvjbikbvobnAbvpbvqbvrbvsbtXbqbbvtbnAbxebvwbxfbucbvxbvybvzbvAbvBbvCbvDbvEbvFbvGbvHbvHbvGbvIbvJbvKbuhbvLbvMbvNbvObuhbvPbvQbvRbvSbvTbvUbvUbvVbukafNbvXbvYbvZbvYbwabwabupbwbbwcbwdbupbwebwfbwebupbwgbtfburbusbwhbwibwhbusbwjbwkbusdeicngbxXbwobikbikbikbikbikbikbikbikbikbikbqUddXddZddYdejbqUbikbqUdekdekdekdekbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbBGbDCdjldjidjidjidjidjidjidjideHdjnaGddjnaJrbtrbrXbtsbttbtubtvbtwbrZbtxbtybtzbtzbtAbtBblCblCblCbosbtCborbcsbcsbcsbcsbtDbejbejbskbejbsjbskbngbtEbtFbtGbtHboAbngbtIbnmbtJbpIbpIbpIbtKbtLbtMbpNbtNbnqbtObtPbpRbpRbpRbpRbpTbtQbmgbtRbtSbmgbmgbmgbmgbmgbmgbmgbnzbnAbqrbtUbtVbtWbtXbtYbtZbnAbvubuabuabucbucbucbucbucbucbucbudbudbuebufbugbugbufbuebudbudbuhbuhbuhbuhbuhbuhbuibuibujbuibuibuibuibuibukafkbumbunbmFbmFbuobuobupbupbupbupbupbuqbtfbtfbtebtfbmFbtfbtfbtfbtfburbusbusbusbusdedbuubuubuubuubuubuubuubuubuubikbikbikbikbdBddYddYddYdeebqUbikbqUdefdebdebdegbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbBGbDCdjodjpdjpdjidjpdjpdjpbtqdjqaInaInaInaKBbuvbrXbuwbuxbuxbuxbuybrZbejbuzbuAbuBbuCbuDblCbmUbuEbosbuFborbuGbuHbuIbuJbuKbuLbuLbuMbuLbuNbuObngbuPbuQbuRbuSbuTbuUbuVbnmbuWbpIbpIbuXbuYbuZbtMbpNbvabnqbvbbvcbvdbvebvfbvgbvhbnqbnqbvibvjbvkbvlbvmbvlbvnbvjbikbvobnAbvpbvqbvrbvsbtXbqbbvtbnAbxebvwbxfbucbzcbvybvzbvAbvBbvCbvDbvEbvFbvGbvHbvHbvGbvIbvJbvKbuhbvLbvMbvNbvObuhbvPbvQbvRbvSbvTbvUbvUbvVbukafNbvXbvYbvZbvYbwabwabupbwbbwcbwdbupbwebwfbwebupbwgbtfburbusbwhbwibwhbusbwjbwkbusdeicngbxXbwobikbikbikbikbikbikbikbikbikbikbqUddXddZddYdejbqUbikbqUdekdekdekdekbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjrbtqbtqbtqbtqbtqbtqbtqbtqdjqbikbikaInbwqbdFbwrbrXbwsbrXbwtbuxbwubwvbrZbwwbwxbwybwzbuDblCblCblCblCblCblCbwAbwBbwCbwDbwEbngbngbngbngbngbngbngbwFbngbngbngbwGbngbwHbwIbwJbpIbpIbpIbwKbtLbwLbpNbwMbnqbwNbvcbnrbnrbnrbnqbwObnqbwPbwQbwRbwSbwTbwUbwVbwWbwXbwYbwZbnAbxabqbbxbbxcbtXbxdbqbbnAbzbbxgbANbucbxhbxibxjbxkbxlbxmbxnbvHbvHbvHbvHbvHbvHbvHbvHbxobxpbxqbxrbxsbxtbuhbxubxvbxwbxxbxybxzbxvbxAbukbDdbvXbxCbxDbxEbxFbxFbxGbxHbxIbxJbxKbxLbxMbxNbupbxObxPbxQbusbxRbxSbxTbxUbxUbxVbusbxWbxXbxYbwobikbikbikbikbikbikbikbikbikbikbDybtldemdemdemdenbikdeodepdepdepbtlbDzbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaLyaCuaKzaKzaInaInaInaInaInaInaInaKBaJrbyabrXbybbycbydbyebyebyfbygbyhbyibyibyjbykbtzbtzbtzbtzbtzbtzbylbymbymbynbyobngbypbyqbyrbysbytbyubyvbywbngbyxbyybyzbuVbtLbwJbpIbpIbyAbnmbnmbyBbyCbyDbyEbyFbyGbyHbyIbyJbyKbyLbyMbyNbyObwXbyPbyQbyPbyQbyRbwXbwYbySbyTbyUbyVbyWbyXbyYbyZbzabyTbAObvwbvwbucbzcbzdbzebzfbzgbucbxnbvHbvHbvHbvHbvHbvHbvHbzhbzibzjbzkbzlbxqbzmbuhbznbzobzpbxxbxAbxzbzqbzrbukbIbbztbzubzvbzvbzwbzxbzybzzbzAbzAbzAbzBbzAbzCbzDbzEbzFbzGbzHbzIbzJbzKbzKbzKbzLbusbzMbxXbzNbwobikbikbikbikbikbikbikbikbikbikbikbDyderderderbDzbikbDyderderderbDzbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaLyaCuaKzaKzaInaInaInaInaInaInaInaKBaJrbyabrXbybbycbydbyebyebyfbygbyhbyibyibyjbykbtzbtzbtzbtzbtzbtzbylbymbymbynbyobngbypbyqbyrbysbytbyubyvbywbngbyxbyybyzbuVbtLbwJbpIbpIbyAbnmbnmbyBbyCbyDbyEbyFbyGbyHbyIbyJbyKbyLbyMbyNbyObwXbyPbyQbyPbyQbyRbwXbwYbySbyTbyUbyVbyWbyXbyYbyZbzabyTbAObvwbvwbucbzebzdcSCbzfbzgbucbxnbvHbvHbvHbvHbvHbvHbvHbzhbzibzjbzkbzlbxqbzmbuhbznbzobzpbxxbxAbxzbzqbzrbukbIbbztbzubzvbzvbzwbzxbzybzzbzAbzAbzAbzBbzAbzCbzDbzEbzFbzGbzHbzIbzJbzKbzKbzKbzLbusbzMbxXbzNbwobikbikbikbikbikbikbikbikbikbikbikbDyderderderbDzbikbDyderderderbDzbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaIndjtdjsdjuaIoaIoaIobdFaJraJrbrXbzVbrXbzWbzXbzYbzZbrXbcsbAabAabAbbAcbAbbAbbAbbAcbAbbcsbcsbngbngbngbAdbngbAebAebAebAebAebAebyvbAfbAgbAhbAibAjbAkbAlbAmbAnbAobApbAqbArbAsbAtbAubAvbAwbAwbAxbAybAzbAAbABbACbADbAEbvjbAFbwVbAGbwTbAHbvjbikbAIbAJbAKbALbAJbAJbAJbAJbAMbnAbCBbvwbCCbAPbAQbARbASbATbAUbucbAVbAWbAXbAYbAZbBabBbbBcbvHbBdbuhbBebzlbBfbBgbuhbBhbBibxwbxxbxAbxzbxvbxAbukbDdbvXbBjbBkbBlbBmbBnbBobBpbBqbBrbBsbBtbBubBvbupbBwbBxbBybusbBzbBAbBBbxUbBCbBDbusbzMbxXbBEbwobikbikbikbikaabaabaabaabaabaabaabaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaIndjwdjvdjuaJqaJqbBIbBJaJqbBKbrXbBLbycbBMbBNbBObBPbrXbikaabaabdetdesdesdesdesdesdeubikbikbBRbBSbBTbBUbBVbAebAebAebAebAebAebBWbBXbBYbBZbCabCbbCcbCdbnmbnmbCebCfbnmbnmbCgbChbCibCjbCkbClbClbCmbClbCnbCobCpbCqbAEbvjbCrbvlbvlbvlbCsbvjbikbAIbAJbCtbCubCvbCwbCxbCybCzbCAbEsbvwbEtbucbvxbCDbCEbCFbCGbCHbCIbCJbCKbCLbCMbCNbCObCPbCQbCRbCSbCTbzlbCUbCVbuhbCWbCXbCYbCZbDabDbbDcbvVbukbIcbDebDfbDgbDgbDhbDibDjbDkbDlbDmbDnbDobDpbDqbupbDrbBxbDsbusbDtbDubDvbxUbxUbDwbusbxWbxXbDxbwobikbikbikbikaabbDAbFfbDBbFfbDBbFfbFgaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaIndjudjubDEaInaInaLyaCubDFbDGbrXbDHbycbycbycbrXbrXbrXbikbikbikdewdevdevdexdevdevdewbikbikbBRbDIbAebDJbDKbDKbDKbDKbDKbDLbDMbDKbDNbDObDPbDQbDRbDSbDTbnmbDUbpIbDVbDWbtLbDXbDYbDZbCjbCjbCpbEabEbbEcbEdbEebCpbvibAEbvjbEfbEgbEhbqtbEjbvjbikbEkbAJbElbEmbEnbEobEpbEobEqbErbFWbvwbHBbucbEubEubEvbEwbExbEybEzbEAbEBbECbEDbEDbEEbEFbEGbEHbuhbCTbEIaJSbuhbuhbuibEKbELbEMbuibukbukbukbENbIdbvXbEPbBkbBlbEQbDgbDjbERbESbESbETbxJbEUbEVbEWbEXbxPbEYbusbEZbFabxUbFbbFcbFdbusbzMbFebwobwobikbikbikbikaabbFhbFjbFibGSbFkbGTbFhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjydjydjydjydjAdjzdjydjydjydjydjBbikbikbikbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevdewbFnbBRbBRbFobFpbFqbFrbFrbFrbFpbAebyvbAfbAebAebAgbFsbFtbFubFvbFwbFxbFybpIbpIbFzbtLbDXbDYbFAbFBbFCbFDbFEbFFbFGbFHbFIbCpbFJbFKbwRbFLbFMbFNbFObFPbwXbwYbFQbAJbFRbFSbFTbEobFUbEobFVbErbJebvwbKObucbFYbFZbGabGbbGcbGdbGebGfbGgbGgbGhbGibGgbGgbGjbGkbGlbGmbGnbGobGpbGqbGrbGsbGtbGubGvbGwbKhbIebKjbKibvXbGBbGCbGDbGEbGFbxGbGGbESbESbGHbGIbEUbGJbupbGKbGKbGLbusbGMbGNbGObGPbxUbGQbusbzMbGRbwobikbikbikbikbikaabbGUbIybFibFkbFibKkbDBaabbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjCdjEdjDdjGdjFdjIdjHdjFdjJdjLdjKdjydjydjBbikbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevbGWbmrbNkbmrbGXbGYbGZbGYbGYbGYbGYbHabyvbAfbHbbngbngbHcbpIbAibFvbHdbtLbHebHfbHfbHgbHhbHibHjbHkbHlbHmbHnbHobHpbHqbHrbHsbCpbCqbAEbvjbEibHubHvbHwbHxbvjbikbEkbHybHzbHybHybHybHybHybHAbHybKPbvwbKObucbHCbHDbHDbHEbHFbEybHGbHHbHIbHJbHKbHLbHMbHIbHNbHObHPbHQbHRbHSbHTbHTbHUbHVbHWbHXbHYbLibLCbLBbNdbNcbNebIfbIfbIgbIhbIibxGbIjbxJbxJbIkbIlbEUbImbInbIobIpbIqbIrbIsbItbIubIvbIubusbusbIwbEXbGxbLDbLDbLDbLDbLDbGxbFhbFkbFibFkbFkbGTbFhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjydjHdjHdjHdjMdjFdjNdjNdjFdjOdjHdjHdjQdjPdjydjBbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevbLFbKmbIAbKmbIBbAebFqbFrbFrbFrbAebAebyvbAfbICbIDbngbIEbpIbAibFvbIFbtLbIGbpIbrsbpIbIHbDXbvvbIIbHlbHmbIJbIKbILbIMbINbIObIPbIQbIRbISbISbITbIUbIVbvjbvjbikbEkbHybIWbIXbIYbIZbJabJbbJcbJdbMhbvwbKObCHbJfbJgbJhbJibJjbEybJkbJlbJmbJnbJobJpbJqbJrbJsbJtbJubJvbJwbJxbJybJzbJAbJBbJCbJDbJEbGwchEbIecnfcjubvYbJIbJJbJKbJLbJLbxGbJMbJNbJObxGbJPbEUbJQbxGbJRbJSbJTbJUbJVbJWbJXbJYbJZbKabKbbKcbKdbKebKfbKfbIxbJFbJHbKgbKlbFfbDBbNhbDBbFfbLEaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjydjSdjRdjUdjTdjVdjFdjWdjHdjXdjHdjHdjHdjHdjHdjMdjFbikbikbikbikbikbikbikbikbikbikdewdeCdevdevdevcOfdewbFnbBRbBRdezbAebFqbAebAebAebAebAebyvbAfbICbKobngbKpbpIbKqbKrbpIbKsbpHbpIbpIbKtbtLbDXbvvbIIbHlbHmbCpbKubKvbKwbKxbKybKzbKAbKBbKCbKDbwXbKEbKFbwXbwYbwYbKGbHybKHbKIbKJbKKbKLbKLbKMbKNbMibvwbMjbucbEybKQbEubKRbKSbEybJkbKTbKUbKVbKWbKXbKYbKUbJkbKZbLabLbcchbLbbLcbLbbLdbLdbLebLfbLgbLhbLhcpLbLgbLgbLhbLhbLjbLkbLjbLjbxGbxGbxGbxGbxGbLlbLmbBobxGbLnbLobLpbLqbLqbLrbLsbLtbLubLvbLwbLxbLybLzbLAbLAbEObGAbHZbGxbGzbGzbGzbIabGxbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjydjSdjRdjUdjTdjVdjFdjWdjHdjXdjHdjHdjHdjHdjHdjMdjFbikbikbikbikbikbikbikbikbikbikdewdeCdevdevdevcOfdewbFnbBRbBRdezbAebFqbAebAebAebAebAebyvbAfbICbKobngbKpbpIbKqbKrbpIbKsbpHbpIbpIbKtbtLbDXbvvbIIbHlbHmbCpbKubKvbqzbKxbKybKzbKAbKBbKCbKDbwXbKEbKFbwXbwYbwYbKGbHybKHbKIbKJbKKbKLbKLbKMbKNbMibvwbMjbucbEybKQbEubKRbKSbEybJkbKTbKUbKVbKWbKXbKYbKUbJkbKZbLabLbcchbLbbLcbLbbLdbLdbLebLfbLgbLhbLhcpLbLgbLgbLhbLhbLjbLkbLjbLjbxGbxGbxGbxGbxGbLlbLmbBobxGbLnbLobLpbLqbLqbLrbLsbLtbLubLvbLwbLxbLybLzbLAbLAbEObGAbHZbGxbGzbGzbGzbIabGxbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjZdjYdjHdjHdkadkadkadjFdjHdjHdjFdkbdkddkcdkfdkedkgdjFbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevbWobKmbIAbKmbFobLGbLHbAebAebAebLGbAebyvbAfbICbLIbngbLJbpIbAibFvbpIbnmbLKbpIbpIbLLbtLbDXbvvbLMbHlbLNbCpbLObLPbLQbLRbLSbKzbLTbLUbLVbLWbLXbLYbLZbMabikbikbikbHybMbbMcbMdbMdbMebMfbMgbHybNSbNRbKObNTbMkbMlbMmbMnbMobMpbMqbJlbMrbMsbMtbMubMvbMrbJkbKZbMwbMxbMybMzbMAbMBbLdbMCbMDbMEbLgbMFbMGbMHbMIbMJbMKbMLbKabMMbLqbLqbMNbMObLqbMPbMQbMRbMSbMTbLqbMUbiTbMWbMXbMYbMZbNabNbbNabNabNabIwbEXbGxbLDbLDbGxcnccndcnebOQbOSbUHbYdbGzbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkhdjYdjHdjHdjHdjHdjHdkidjHdjHdjFdjydjydjydjydjydjydkjbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevdeEdeDdeGdeDbNlbNmbNnbNnbNnbNnbNnbNobNpbNqbICbNrbngbNsbNtbNubNvbNwbNxbNybNybNybNzbNzbNAbvvbNBbNCbHmbCpbNDbNEbNFbKvbNGbKzbNHbNIbNJbNKbNLbFNbNMbMabikbikbikbHybNNbNObNPbNQbMebMfbMgbHybPibNUbQObPjbNVbNWbNXbNYbNZbOabObbOcbKUbKUbOdbOebKUbKUbJkbKZbOfbOgbOhbOibOjbOkbLdbOlbOmbOnbOobOpbOqbOrbOrbOsbOtbOubOvbOwbJVbJVbOxbJVbOybJVbOzbJVbOAbOBbOBbOCbODbOEbOFbOGbOHcsjbOJbOKbOLbNabOMbONbikbikbikbGxbORbJFbOPbOQbKgbOObNibGxbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkkdjydkmdkldkodkndjHdjFdjHdjHdjFdjHdkqdkpdkrbikbikbikbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevdewbFnbBRbBRbngbngbBRbBRbBRbBRbBRbngbngbBRbBRbBRbngbOVbOVbOVbOWbOVbNzbOXbOYbOZbPabNzbDXbvvbPbbPcbPcbCpbCpbCpbCpbCpbPdbKzbISbIRbPebNKbPgbPhbMabMabvjbvjbvjbHybHzbHybHybHybHybHybHybHybQPbvwbQQbPkbPlbPmbPnbPlbPlbPobPpbPqbPrbPsbPtbPubPvbPwbMqbPxbPybPzbPAbPBbPCbPDbPEbPFbPGbPHbPIbPJbPKbPLbMHbPMbLhbLhbPNbPObPNbPPbPQbPPbPPbPPbPRbPSbPTbPTbPUbPVbPWbPXbOFbPYbPZbQabQbbQcbQdbNabOMbONbikbikbikbGxbNfbNgbGxbKgbGxbGxbKgbGxbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjydjydjydjydjydjydjFdjOdjHdksdjHdkudktdkvbikbikbikbikbikbikbikbikbikbikbikbikbikdeJdeIdevdeKdevdeLdeMbikbikbikbikbikbikbikbikbikbikbQgaabbikbikbikbikbOVbQhbQibQjbQkbNzbQlbQmbQnbQobNzbDXbvvbQpbQqbQrbQsbQtbQubQvbQwbQxbQybQzbQAbQBbQCbQDbQEbQFbQGbQHbQIbQJbQKbQLbQMbQRbuabQSbvwbShbSgbSibvwbSjbPlbQTbQUbQVbQWbQXbJkbQYbQZbRabRbbRcbRdbRebRfbRgbRhbRibLbbRjbOibRkbRlbRmbRnbRobRpbLgbRqbMHbMHbMHbRrbLhbPNbRsbRtbRubRvbRwbRxbRybPPbRzbRAbRBbPTbPTbRCbPWbRDbREbRFbRGbRHbRIbRJbRKbNabRLbwobikbikbikbGxbGxbGxbGxbikbikaabbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjydjydjydjydjydjydjFdjOdjHdksdjHdkudktdkvbikbikbikbikbikbikbikbikbikbikbikbikbikdeJdeIdevdeKdevdeLdeMbikbikbikbikbikbikbikbikbikbikbQgaabbikbikbikbikbOVbQhbQibQjbQkbNzbQlbQmbQnbQobNzbDXbvvbQpbQqbQrbQsbQtbQubQvbQwbQxbQybQzbQAbQBbQCbQDbQEbQFbQGbQHbQIbQJbQKbQLbQMbQRbuabQSbvwbShbSgbSibvwbSjbPlbQTbQUbQVbQWbQXbJkbQYbQZbRabRbbRcbRdbRebRfbRgbRhbRibLbbRjbOibRkbRlbRmbRnbRobRpbLgbRqbMHbMHbMHbRrbLhbPNbRsbRtbRubRvbRwbRxbRybPPbRzbRAbRBbPTbPTbRCbPWbRDbREbtTbRGbRHbRIbRJbRKbNabRLbwobikbikbikbGxbGxbGxbGxbikbikaabbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjydkxdkwdkydkxdkzdjFdjHdjHdjFdjHdkBdkAdkCbikbikbikbikbikbikbikbikbikbikbikbikbikdeOdeNdePdePdePdeNdeQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbOVbRMbRNbRObRPbNybRQbRRbRSbRTbNzbDXbRUbRVbvvbvvbFXbRWbubbQNbQMbRXbRYbRXbRZbSabSabSbbScbSdbSabSabSebSabSfbSabQMbQRbuabSlbSkbTJbTIbTLbTKbvwbPlbSmbQUbSnbSobSpbJkbSqbSrbSsbStbSubSvbSwbSxbJkbSybSzbLbbSAbSBbSBbSCbSDbSEbSFbSGbLgbSHbSIbMHbSJbSKbLhbPNbSLbSMbSNbSObSPbSQbSRbPPbSSbRAbSTbSTbPTbSUbSVbSWbSXbSYbSZbTabTbbTcbTdbNabOMbwobTebikbikbikbikbikbikbikbikaabbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjZdjYdkDdkDdkDdkDdkDdkEdjHdjHdjFdjydjydjydjydjydjydjBbikbikbikbikbikbikbikbikbikbikbikdeRdeSdeSdeSdeTbikbikbikbikbikbikbikbikbOUbOTbQebOTbQfbikbikbikbOVbOVbTjbTkbRObTlbNybTmbQnbTnbTobNzbDXbTpbTqbTrbTsbTtbTubTvbTwbTxbTybTzbTAbTBbTCbTCbTDbTEbTEbTEbTEbTEbTEbTFbTGbTHbTNbTMbTPbTOdlidjmdlkdljdllbPlbTQbQUbQVbTRbSpbJkbSqbSrbTSbTTbTUbTVbTWbTXbJsbTYbTZbLbbLbbUabUabLbbSDbLdbUbbUcbLgbUdbUebUfbUgbUhbLhbPNbUibUjbUkbUlbUmbUnbUobPPbUpbRAbSTbSTbPTbUqbUrbUsbUtbUubUvbUwbUxbUybUzbNabOMbUAbUBbUAbUCbUDbUCbUCbUCbikbikbikbikaabaabaabaabbikbikbikbikbikbikbikbikbikbikbikbikaabaabaabaabaabbikbikbikbikaabaabaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkhdjYdkDdkDdkDdkFdkGdjFdjHdjHdjFdjHdjHdjHdkHdjHdkIdjFbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbTgbTfbTibThbTgbUIbUIbUIbOVbUJbUKbULbUMbUNbUObUPbUQbUQbURbNzbUSbUTbUUbUVbUVbUWbUXbUYbUVbUZbUZbVabVbbVcbUZbUZbVdbQMbQMbVebVfbVfbVfbVgbVhbVfbVfbVibVjbVkbVkbVlbVkbVmbVnbVkbVobVpbVqbPlbVrbVsbSqbVtbVubVvbVwbVxbVybVubJkbSybVzbVAbVBbVCbVDbVEbVFbVGbVHbVIbVJbVKbVLbVMbVNbVObLhbPNbPNbVPbVQbVRbVSbVRbVTbPPbVUbVVbVWbVWbPTbVXbVYbVZbNabNabNabNabNabNabNabNabOMbUAbWabWbbWcbWdbWdbWebUCbikbikbikbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikaabbWfbWfbWfbWfbWgbWgbWhbWhbWhbWhbWiaabaabbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkkdjydkKdkJdkDdkLdkMdjFdjHdjHdkNdjHdjHdjHdkOdjHdkPdjFbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbQebUEbUFbUEbQebUIbWmbWlbOVbWnbWpbWqbWrbWsbNzbWtbWubWvbWwbNzbUTbUTbWxbUVbWybWzbWAbWBbWCbUZbWDbWEbWFbWGbWHbUZbWIbWJbWKbVfbWLbWMbWObWNbWPbWQbWRbWSbWTbWUbWVbWWbWXbWYbWZbXabXbbXcbXdbXebXfbXgbXhbSrbXibXjbXkbXlbXmbXnbJsbXobXpbXqbXrbVDbXsbXsbXtbXubLgbXvbXwbXxbXybXzbXAbXBbLhbXCbXDbXEbXFbXEbXEbXGbXHbXIbXJbXKbXLbXMbPTbXNbXObPXbEXbxXbXPbXQbXRbXRbXQbXRbXSbUAbXTbXUbWcbWdbXWbXVbUCbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbWfbXXbXYbXXbWgbWhbWhbXZbYabXZbWhbWhaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkkdjydkQdkDdkDdkRdjFdjHdjHdjFdkSdjHdjHdkUdkTdjydkjbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbTgbUGbUEbUEdeycOWbTkbTkdeAbZAbTkbWqbYhbYibNzbNzbNzbNzbNzbNzbYjbUTbYkbYlbYmbYnbYnbYnbYobUZbYpbYqbYqbYqbYrbYsbYtbYubYvbYwbYxbYybYzbYAbYBbYCbVfbVibYDbVkbYEbYFbYGbYHbYIbVkbSmbQVbSnbSobYJbYKbYLbYMbYNbYObYPbYQbYRbVubYSbYTbYUbYVbYWbYXbYYbYZbZabZbbLgbLgbLgbLgbLgbZcbZdbZebLhbZfbXEbXEbZgbZhbXEbZibZjbZkbZlbRAbZmbZmbPTbPVbZnbPXbEXbUAbZobUAbUAbUAbUAbUAbUAbUAbZpbZqbUCbZrbZtbZsbUCaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacbZubXXbXXbZvbWhbWhbXZbXZbZwbXZbXZbWhbWhaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkkdjydkWdkVdkXdjFdjHdkYdjFdkZdladjHdjydjydkjbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbQebUFbUFbUFbQebUIbYfbYebZzbZAbTkbZBbZCbZDbZEbZFbZFbZFbZGbUTbUTbUTbWxbUVbZHbYnbZIbYnbZJbUZbYpbYqbZKbYqbZLbUZbZMbZNbZObVfbZPbZQbZRbZSbZTbZUbZVbZWbZXbZYbZZcaacabcaccadbVkbTQbQVbQVcaebYJbYKcafcagcahbXjcaicajcakcalcamcancaocapcaqcarcascasbXscatbVAcaucavcawcaxcaycazcaAbZjbZfcaBbXEbXEbXEcaCcaDbZjbZkcaEbRAbZmbZmbPTcaFcaGbPXbEXcaHcaIcaJbUAcaKcaLcaMcaNcaOcaPcaQbUCcaRcaScaTbUCbUAbUAbUAbUAbUAbUAbUAbUAbikbikbikbikbikaabbikbikbikbikbikbikbikcaUbWhbZubWhbWhbXZbXZbXZbXZbXZbXZbXZbWhbWhaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkkdjydkWdkVdkXdjFdjHdkYdjFdkZdladjHdjydjydkjbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbQebUFbUFbUFbQebUIbYfbYebZzbZAbTkbZBbZCbZDbZEbZFbZFbZFbZGbUTbUTbUTbWxbUVbZHbYnbZIbYnbZJbUZbYpbYqbZKbYqbZLbUZbZMbZNbZObVfbZPbZQbZRbZSbZTbZUbZVbZWbZXbZYbZZcaacabcaccadbVkbTQbQVbQVcaebYJbYKcafcagcahbXjcaicajbKwcalcamcancaocapcaqcarcascasbXscatbVAcaucavcawcaxcaycazcaAbZjbZfcaBbXEbXEbXEcaCcaDbZjbZkcaEbRAbZmbZmbPTcaFcaGbPXbEXcaHcaIcaJbUAcaKcaLcaMcaNcaOcaPcaQbUCcaRcaScaTbUCbUAbUAbUAbUAbUAbUAbUAbUAbikbikbikbikbikaabbikbikbikbikbikbikbikcaUbWhbZubWhbWhbXZbXZbXZbXZbXZbXZbXZbWhbWhaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkkdjydjydjydjydjydjydjydjydjydjydkjbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaahbikbikbikbikbikbikbTgbWjbYbbWkbTgbUIbUIbUIbOVcaYcaZcaZcaZbOVbOVbUTcbacbacbbcbcbUTcbdcbebUVbZHbYnbYnbYncbfbUZbYpbYqbYqcbgcbhcbicbjcbkcblbVfbVfbVfbVfbVfcbmbVfbVfcbncbobVkbVkcbpbVkbVnbVkbVkbPlcbqcbqbPlccicbrcbscbtcbucbvcbwcbxcbycbzcbAcbBcaocapcbCcbDcbEcbFcbGcbHbVAcbIcbJcbKcbLcbMcbNcbOcbPcbQcbPcbRcbRcbRcbPcbScbPcbPcbTcbUbZmbZmbPTcbVbZnbPXcbWcbXcbYcbZccaccbccccccccdcceccfccgcckccjcdqcclcfeccmccnccoccpccqccrccscctaabaabaabaabaabaabaabaabbikbikbikbikbikbWgbWhccuccvccvbXZbXZbXZbXZbXZbXZbXZbXZbWhbWhaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbYcbOTbYgbOTbZxbikaabbikbOVbOVbUIbUIbUIbOVbikbUTccAccBccCccDbZFccEccFbUVccGccHccIbYnccJccKccLccMccNccOccPbUZccQccRccSccTccUccUccUccUccVccWccXccYccYccZccZcdacdbcdcbVibPlcddcdecdfcdgcdhbYKcdicbtcdjcdkcdlcdmbSwcdncdocdpcffcdrcdrcdscdrcdrcdrcdtbVAcducdvcdwcdxcdycdzcdAcbPcdBcdCcdDcdEcdFcdCcdGcdHcdCcdIcdJbRBbPTbPTcdKcdLcdMcdNcdOcdPcdQcdRcdScdTcdUcdVcdWcdXcdYcdZceacebceaceccebcebcebcedceecefcegcehaabbikbikbikbikaabbikbikbikbikbikbikbikbWhbWhceibXZbXZbXZbXZbXZbXZbXZbXZbXZbXZbXZbWhbWhaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabcejbUTbUTbUTcekbUTbUTcelbUVcemcenceocepceqcercescetceucevcewccKcexceycezceAceBceBceBceBceCceDceEceFceGceFceHceIceJceKceLceMceNceOcePceQceRceSceTceUceVceWceXceYceZcfacfbcfccfgbMmbMmcfichOcgHceYchVcfjcfjcfkcfjcflcfmcfncfocbPcfpcfqcfrcfscfrcftcfucfvcdCbPTcfwbPTbPTcfxcfybZnbBxbEXbUAcfzbUAbUAcfAcfBcfCcfDcfEcebcfFcfGcfHcdUcfHcdUcfIcdUcdUbUAcfJcfKcfLcfMaabaabaabaabaabaabaabaabbikbikbikbikbikbWhbXZbXZbXZbXZbXZbXZcfNbXZcfObXZbXZbXZbXZbXZbWhbWhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik @@ -8887,7 +8887,7 @@ bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbi bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGbikaabbikaabaabcEraabaabaabcEraabbikaabcEraabbikbikbikbikbikbikbikbikcDccDccDccEscEtcEucEvcEwcExcEycDfcDfcEzcEAcvKcvKcEBcECcECcECcECcEDcEEcEFcEEcEEcEEcDtcDtcEGcEHcEIcEJcEKcDzcELcDwcDzcDzcDzcDzcEMcBCcENcEOcCycDFcCAcDFcBIcDHcDIcEPcEQcERcEScETcEUaabcEVcEWcDTcEXcCKcHBcoDcHDcHCcxKcxJczVcxMclUcIIcDVdcsclUcDWcDYczVcEbcEaclUcusbGycITcoAbikckPcwtcwucwvcFjcARczbcFkcJJcJIcJKcJKcFocFpcFqcJLckPaabaabaabbikbikbikbikbikbikbwocJMcvzbwobwobwobwobwoaabaabaabcJNcJNcJNcJNcJNcJNaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikafxaabcFscFtcFtcFucFvcFwcFwcFwcFvcFwcFwcFwcFvcFwcFwcFxcFtcFtcFtcFtcFtcFycFzcFAcFBcFCcFDcFEcFFcFGcfRcwWcFHcDfcvKcvKcvKcFIcEBcECcFJcFKcFLcyrcFNcDucFPcFOcFQcFScFTcSpcFVcFWcFXcFScFYcFZcDwcGacDzcDzcDzcGbcBCcGccGccDFcGdcGecGfcGgcGhcGicGjcGkcGlcGmcGncDOcGocDQcGpcDTcDTcCKcHBcoDcEhclUcyMcyLcyNcFfclUcnkclTcFfclUcyQcyScyRcyTcyTclUcusbGycJOcoAbikckPcxOcxPcxOcGAcxRcqUcGBcJPcGCcqUcqUcGDcwAcwAcwAckPbikbikaabaabbikbikbikbikbikbwocyKcvzbwobikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGbikaabbikaabaabcGFaabbikaabcGFaabbikaabcGFaabbikbikbikbikbikbikbikbikcDccDccDccGGcGHcFMcDdcGJcfRcGKcExcExcExcExcGLcExcFGcECcGMcGNcGOcGPcGQcGRcGScGTcGUcGVcGWcGXcGYcGZcHacHbcFYcELcDwcHccHdcDzcDzcHecBCcHfcHgcDFcHhcCAcHicHjcHkcHlcHmcHncHocHpcHocHqaabcCKcCKcCKcCKcCKcHBcoAcEhclUcIJcyVcyYcyXcEecEccEgcEfcHwcGucHZczVcIRcIQclUcusbGycJRcoAbikckPcxOcxOcxOcFjcHEcHFcHGcJScHIcCZcCZcCZcHJcHKcHLcHMbikbikbikaabaabbikbikbikbikbwobwocvzbwobikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGacGafxaabaabczocHOczqbikczocHOczqbikczocHOczqaabbikbikbikbikbikbikbikaabaabcDccDdcDdcDdcDdcHPcHQcHRcfRcHScfRcfRcEBcHTcfRcECcHUcHVcGOcHWcFNcHXcHYcIacIacIbcIccIdcIecIfcIgcIbcIhcIicIjcIkcIlcImcIncIocIpcIqcGfcIrcIscItcIucIvcIwcIxcIycIzcIAcIBcICcIDcDPcDQcIEcIFcIFcCKcHBcoAcEhclUclUclUclUclUcJhcANcBRcJQcMccBScMecMdcMCcBVclUcuscGqcGrcGrcGrcJTcJTcJTcJTcJTcJUcKTcKbcKUcIUczbcIVczbcIWczbcIXcHMbikbikbikbikaabaabbikbikbikbikbwocvzbwoaabaabaabaabaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGacGafxaabaabczocHOczqbikczocHOczqbikczocHOczqaabbikbikbikbikbikbikbikaabaabcDccDdcDdcDdcDdcHPcHQcHRcfRcHScfRcfRcEBcHTcfRcECcHUcHVcGOcHWcFNcHXcHYcIacIacIbcIccIdcIecIfbRFcIbcIhcIicIjcIkcIlcImcIncIocIpcIqcGfcIrcIscItcIucIvcIwcIxcIycIzcIAcIBcICcIDcDPcDQcIEcIFcIFcCKcHBcoAcEhclUclUclUclUclUcJhcANcBRcJQcMccBScMecMdcMCcBVclUcuscGqcGrcGrcGrcJTcJTcJTcJTcJTcJUcKTcKbcKUcIUczbcIVczbcIWczbcIXcHMbikbikbikbikaabaabbikbikbikbikbwocvzbwoaabaabaabaabaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikczocHOczqaabczocHOczqbikczocHOczqbikbikbikaabbikbikbikbikaabaabaabbikbikaabaabcJbcJbcJbcJbcJbcJbcJbcJccJbcJbcECcJdcJecGOcHWcFNcJfcFNcJgcLhcDtcJicJjcFWcJkcFRcDtcJmcDzcDwcJncJocJpcIncJqcJrcJscJtcJucJvcJwcJtcJxcJycJzcJAcDFcJBcJCcJDcJEaabcEVcJFcJGcJHcCKcHBcoDcKWcKVcKVcKVcKXclUcNDcyLcCLcNEcyScCMcyTcyTcyScCNclUcuscGvbVibGycKYcKZcoAbikbikckPcJVcJWcJXcJYcJVcJWcJZcKacJVcJWcLackPaabaabaabaabaabaabaabaabaabaabbwocvzbwobwobwobikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjcbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikafxaabczocHOczqbikczocHOczqbikczocHOczqaabbikbikbikbikbikbikbikaabaabbikbikaabaabaabcJbcKjcKjcKkcGIcKmcKmcKncKocKocKpcKqcKrcGOcHWcGOcKscGOcGOcGOcDtcKtcKucKvcKwcKxcKycKzcKAcKBcKCcKCcKCcKDcKEcKFcKGcKHcKIcHhcCAcKJcKKcKLcKMcKNcDFcJBcKOcKPcKQcKRcDQcKScIFcIFcCKcHBcoDcEhbVibVibVibYDclUcOtcCOczVcOBcyScPocPMcyTcPVcPQclUcuscGvbVibGycyHbGycoAbikbikckPcLicLjcLkcwAcLlcLmcLncwAcLocLpcLqckPaabaabbikbikbikbikbikbikbikbikbwocvzbxXbxXbwoaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikafxaabczocHOczqbikczocHOczqaabczocHOczqaabaabaabbikaabbikbikaabaabbikbikbikaabbikbikcJbcKjcKjcKkcLscLscLscLtcLucLvcECcLwcLxcLycLzcLAcLBcLCcLDcLDcLEcLFcLGcGOcGOcGOcLHcLIcLJcLKcLLcLMcLNcLOcLPcECcLQcLQcLRcHhcCAcLScLTcLUcLVcLWcDFcLXcLYcLZcMacMbcCKcCKcCKcCKcCKcHBcoDcEhcLbbGybGybYDclUcPYczVcDXcQgcDZcQMcRwcyTdbkcYuclUcuscGvczhbGychCcITcoAbikbikckPcMpcxOcxOcwAcMpcxOcxOcwAcMpcxOcxOckPbikaabaabbikbikbikbikbikbikbikbwocLccyJbxXbwobwobwocJNcJNaabaabaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik diff --git a/_maps/map_files/cyberiad/z2.dmm b/_maps/map_files/cyberiad/z2.dmm index 020f1c9bfbb..eba50f4ebb5 100644 --- a/_maps/map_files/cyberiad/z2.dmm +++ b/_maps/map_files/cyberiad/z2.dmm @@ -184,9 +184,15 @@ "dB" = (/obj/structure/table/holotable,/obj/item/clothing/suit/armor/riot/knight/blue,/obj/item/clothing/head/helmet/knight/blue,/obj/item/weapon/holo/claymore/blue,/turf/simulated/floor/holofloor{dir = 2; icon_state = "blue"},/area/holodeck/source_knightarena) "dC" = (/obj/structure/table/holotable,/turf/simulated/floor/holofloor{dir = 10; icon_state = "blue"},/area/holodeck/source_knightarena) "dD" = (/obj/structure/table/holotable,/obj/machinery/readybutton{pixel_y = 0},/turf/simulated/floor/holofloor{dir = 6; icon_state = "blue"},/area/holodeck/source_knightarena) +"dE" = (/obj/structure/rack,/obj/item/clothing/under/color/red,/obj/item/clothing/shoes/brown,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/restraints/legcuffs/beartrap,/obj/item/weapon/sleeping_carp_scroll,/obj/item/weapon/twohanded/bostaff,/turf/unsimulated/floor{icon_state = "dark"},/area/tdome/arena_source) +"dF" = (/obj/structure/rack,/obj/item/clothing/under/color/green,/obj/item/clothing/shoes/brown,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/restraints/legcuffs/beartrap,/obj/item/weapon/sleeping_carp_scroll,/obj/item/weapon/twohanded/bostaff,/turf/unsimulated/floor{icon_state = "dark"},/area/tdome/arena_source) "dG" = (/turf/simulated/floor/holofloor{tag = "icon-asteroid1 (EAST)"; icon_state = "asteroid1"; dir = 4},/area/holodeck/source_desert) +"dH" = (/obj/structure/rack,/obj/item/clothing/under/color/red,/obj/item/clothing/shoes/brown,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/restraints/legcuffs/beartrap,/obj/item/weapon/sleeping_carp_scroll,/obj/item/weapon/twohanded/bostaff,/turf/unsimulated/floor{icon_state = "dark"},/area/tdome/arena) +"dI" = (/obj/structure/rack,/obj/item/clothing/under/color/green,/obj/item/clothing/shoes/brown,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/restraints/legcuffs/beartrap,/obj/item/weapon/sleeping_carp_scroll,/obj/item/weapon/twohanded/bostaff,/turf/unsimulated/floor{icon_state = "dark"},/area/tdome/arena) +"dJ" = (/obj/structure/rack,/obj/item/toy/sword,/obj/item/weapon/gun/projectile/revolver/capgun,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/ninja/holding) "dK" = (/obj/structure/stool/bed,/turf/unsimulated/floor{icon_state = "panelscorched"},/area/prison/solitary) "dL" = (/obj/structure/stool/bed,/obj/effect/decal/cleanable/cobweb,/turf/unsimulated/floor{name = "plating"},/area/prison/solitary) +"dM" = (/obj/machinery/prize_counter/upgraded,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/ninja/holding) "dN" = (/turf/simulated/floor/holofloor{tag = "icon-asteroid3 (EAST)"; icon_state = "asteroid3"; dir = 4},/area/holodeck/source_desert) "dO" = (/turf/simulated/floor/holofloor{tag = "icon-carpet1-0 (EAST)"; icon_state = "carpet1-0"; dir = 4},/area/holodeck/source_theatre) "dP" = (/obj/structure/stool,/turf/simulated/floor/holofloor{tag = "icon-carpet5-1 (EAST)"; icon_state = "carpet5-1"; dir = 4},/area/holodeck/source_theatre) @@ -250,8 +256,6 @@ "fB" = (/obj/machinery/vending/boozeomat,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/ninja/holding) "fC" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/ninja/holding) "fD" = (/obj/structure/rack,/obj/item/device/camera,/obj/machinery/light/spot{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/ninja/holding) -"fE" = (/obj/structure/rack,/obj/item/toy/sword,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/ninja/holding) -"fF" = (/obj/structure/rack,/obj/item/weapon/gun/projectile/revolver/capgun,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/ninja/holding) "fG" = (/obj/machinery/computer/arcade,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/ninja/holding) "fH" = (/turf/unsimulated/beach/sand,/area/ninja/holding) "fI" = (/obj/effect/overlay/palmtree_r,/obj/effect/overlay/coconut,/turf/unsimulated/beach/sand,/area/ninja/holding) @@ -379,7 +383,7 @@ "in" = (/obj/machinery/vending/snack,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "io" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/obj/item/weapon/storage/backpack/satchel,/turf/unsimulated/floor{dir = 9; icon_state = "carpetside"},/area/wizard_station) "ip" = (/obj/structure/mirror{pixel_y = 28},/turf/unsimulated/floor{dir = 1; icon_state = "carpetside"},/area/wizard_station) -"iq" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/rd,/turf/unsimulated/floor{dir = 5; icon_state = "carpetside"},/area/wizard_station) +"iq" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/wiz,/turf/unsimulated/floor{dir = 5; icon_state = "carpetside"},/area/wizard_station) "ir" = (/turf/space,/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/syndicate_mothership) "is" = (/turf/unsimulated/wall{desc = "Why it no open!"; icon_state = "pdoor1"; name = "Shuttle Bay Blast Door"},/area/syndicate_mothership) "it" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/syndicate_mothership) @@ -391,8 +395,6 @@ "iC" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion (NORTH)"; icon_state = "propulsion"; dir = 1},/turf/space,/area/shuttle/syndicate_elite/mothership) "iD" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion_l (NORTH)"; icon_state = "propulsion_l"; dir = 1},/turf/space,/area/shuttle/syndicate_elite/mothership) "iE" = (/turf/space,/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/shuttle/syndicate_elite/mothership) -"iJ" = (/obj/structure/rack,/obj/item/clothing/under/color/red,/obj/item/clothing/shoes/brown,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/legcuffs/beartrap,/obj/item/weapon/sleeping_carp_scroll,/obj/item/weapon/twohanded/bostaff,/turf/unsimulated/floor{icon_state = "dark"},/area/tdome/arena_source) -"iK" = (/obj/structure/rack,/obj/item/clothing/under/color/green,/obj/item/clothing/shoes/brown,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/legcuffs/beartrap,/obj/item/weapon/sleeping_carp_scroll,/obj/item/weapon/twohanded/bostaff,/turf/unsimulated/floor{icon_state = "dark"},/area/tdome/arena_source) "iL" = (/obj/structure/bookcase{name = "bookcase (Tactics)"},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "iM" = (/obj/item/device/radio/intercom/syndicate{pixel_x = 28},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "iN" = (/obj/structure/table/woodentable,/obj/item/trash/tray,/obj/item/weapon/paper/spells,/turf/unsimulated/floor{dir = 10; icon_state = "carpetside"},/area/wizard_station) @@ -630,7 +632,7 @@ "sY" = (/obj/structure/stool{pixel_y = 8},/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/control) "sZ" = (/obj/structure/table,/obj/machinery/processor{pixel_x = 0; pixel_y = 10},/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/control) "ta" = (/obj/machinery/mech_bay_recharge_port/upgraded,/turf/unsimulated/floor{icon_state = "bot"},/area/centcom/specops) -"tb" = (/obj/machinery/camera{c_tag = "CentCom Special Ops. Assault Armor North"; dir = 2; network = list("ERT","CentCom")},/obj/mecha/combat/marauder/seraph/loaded,/turf/unsimulated/floor{icon_state = "delivery"; dir = 6},/area/centcom/specops) +"tb" = (/obj/machinery/camera{c_tag = "CentComm Special Ops. Assault Armor North"; dir = 2; network = list("ERT","CentComm")},/obj/mecha/combat/marauder/seraph/loaded,/turf/unsimulated/floor{icon_state = "delivery"; dir = 6},/area/centcom/specops) "tc" = (/obj/item/device/radio/intercom/specops{pixel_y = 25},/turf/unsimulated/floor{dir = 4; heat_capacity = 1; icon_state = "warning"},/area/centcom/specops) "td" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "te" = (/obj/machinery/recharge_station/upgraded,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) @@ -678,7 +680,7 @@ "tU" = (/turf/unsimulated/floor{icon_state = "green"; dir = 5},/area/centcom/control) "tV" = (/obj/machinery/door/poddoor{icon_state = "pdoor1"; id_tag = "ASSAULT0"; name = "Launch Bay #0"; p_open = 0},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) "tW" = (/obj/machinery/mass_driver{dir = 8; drive_range = 50; id_tag = "ASSAULT0"; name = "gravpult"},/turf/unsimulated/floor{icon_state = "bot"},/area/centcom/specops) -"tX" = (/obj/machinery/camera{c_tag = "CentCom Special Ops. Assault Armor South"; dir = 1; network = list("ERT","CentCom")},/turf/unsimulated/floor{icon_state = "loadingarea"; dir = 8},/area/centcom/specops) +"tX" = (/obj/machinery/camera{c_tag = "CentComm Special Ops. Assault Armor South"; dir = 1; network = list("ERT","CentComm")},/turf/unsimulated/floor{icon_state = "loadingarea"; dir = 8},/area/centcom/specops) "tY" = (/obj/item/device/radio/intercom/specops{pixel_y = -28},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) "tZ" = (/turf/unsimulated/floor{icon_state = "green"; dir = 4},/area/centcom/control) "ua" = (/obj/machinery/door/poddoor{icon_state = "pdoor1"; id_tag = "ASSAULT"; name = "Assault Armor"; p_open = 0},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) @@ -689,10 +691,10 @@ "uf" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "ug" = (/obj/machinery/portable_atmospherics/canister/air,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "uh" = (/obj/structure/reagent_dispensers/water_cooler,/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) -"ui" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/table,/obj/item/weapon/storage/box/cups,/obj/machinery/camera{c_tag = "CentCom Special Ops. Ready Room North"; dir = 2; network = list("ERT","CentCom")},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"ui" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/table,/obj/item/weapon/storage/box/cups,/obj/machinery/camera{c_tag = "CentComm Special Ops. Ready Room North"; dir = 2; network = list("ERT","CentComm")},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "uj" = (/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "uk" = (/obj/effect/landmark{name = "Response Team"},/obj/effect/landmark{name = "Commando"},/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"ul" = (/obj/effect/landmark{name = "Response Team"},/obj/effect/landmark{name = "Commando"},/obj/machinery/camera{c_tag = "CentCom Special Ops. Starting Room"; dir = 2; network = list("ERT","CentCom")},/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"ul" = (/obj/effect/landmark{name = "Response Team"},/obj/effect/landmark{name = "Commando"},/obj/machinery/camera{c_tag = "CentComm Special Ops. Starting Room"; dir = 2; network = list("ERT","CentComm")},/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "um" = (/obj/structure/table,/obj/machinery/recharger{pixel_y = 4},/obj/item/device/radio/intercom/specops{pixel_y = 25},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "un" = (/turf/unsimulated/wall/fakeglass{dir = 8; icon_state = "fakewindows3"; tag = "icon-fakewindows (WEST)"},/area/centcom/specops) "uo" = (/turf/unsimulated/floor{icon_state = "asteroid6"; name = "sand"},/area/centcom/specops) @@ -725,7 +727,7 @@ "uP" = (/obj/structure/table/reinforced,/obj/effect/landmark{name = "nukecode"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "uQ" = (/obj/structure/table/reinforced,/obj/item/weapon/paper,/obj/item/weapon/pen,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "uR" = (/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) -"uS" = (/obj/machinery/camera{c_tag = "CentCom Special Ops. Ready Room East"; dir = 8; network = list("ERT","CentCom")},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"uS" = (/obj/machinery/camera{c_tag = "CentComm Special Ops. Ready Room East"; dir = 8; network = list("ERT","CentComm")},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "uT" = (/obj/effect/forcefield{desc = "You can't get in. Heh."; layer = 1; name = "Blocker"},/turf/unsimulated/wall/fakeglass{dir = 8; icon_state = "fakewindows3"; tag = "icon-fakewindows (WEST)"},/area/centcom/specops) "uU" = (/obj/machinery/door/airlock/centcom{name = "Special Operations Command"; opacity = 1; req_access_txt = "114"},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) "uV" = (/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) @@ -744,14 +746,14 @@ "vi" = (/obj/machinery/computer/med_data,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "vj" = (/obj/structure/toilet{dir = 4},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/specops) "vk" = (/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/specops) -"vl" = (/obj/effect/decal/cleanable/vomit{name = "urine"},/obj/machinery/camera{c_tag = "CentCom Special Ops. Bathroom"; dir = 2; network = list("ERT","CentCom")},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/specops) +"vl" = (/obj/effect/decal/cleanable/vomit{name = "urine"},/obj/machinery/camera{c_tag = "CentComm Special Ops. Bathroom"; dir = 2; network = list("ERT","CentComm")},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/specops) "vm" = (/obj/structure/table/reinforced,/obj/item/ashtray/glass{icon_state = "ashtray_half_gl"},/obj/item/weapon/cigbutt/cigarbutt{pixel_x = 3; pixel_y = 3},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "vn" = (/obj/machinery/door/poddoor/shutters{dir = 8; id_tag = "specopsoffice"; name = "Privacy Shutters"},/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows2 (NORTH)"; icon_state = "fakewindows2"; dir = 1},/area/centcom/specops) "vo" = (/turf/unsimulated/floor{dir = 9; icon_state = "carpetside"},/area/centcom/specops) "vp" = (/turf/unsimulated/floor{dir = 1; icon_state = "carpetside"},/area/centcom/specops) "vq" = (/turf/unsimulated/floor{dir = 5; icon_state = "carpetside"},/area/centcom/specops) "vr" = (/turf/unsimulated/floor{icon_state = "green"; dir = 9},/area/centcom/control) -"vs" = (/obj/machinery/computer/security{network = list("SS13","Telecomms","Research Outpost","Mining Outpost","ERT","CentCom","Thunderdome")},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) +"vs" = (/obj/machinery/computer/security{network = list("SS13","Telecomms","Research Outpost","Mining Outpost","ERT","CentComm","Thunderdome")},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "vt" = (/obj/machinery/computer/station_alert,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "vu" = (/obj/machinery/computer/communications,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "vv" = (/obj/machinery/computer/robotics,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) @@ -766,7 +768,7 @@ "vF" = (/obj/machinery/door/airlock/centcom{name = "Telecommunications"; opacity = 1; req_access_txt = "107"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "vG" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/structure/mirror{dir = 4; pixel_x = -32; pixel_y = 0},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/specops) "vH" = (/obj/item/device/radio/intercom/specops{pixel_y = -28},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/specops) -"vI" = (/obj/machinery/camera{c_tag = "CentCom Special Ops. Ready Room South"; dir = 1; network = list("ERT","CentCom")},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"vI" = (/obj/machinery/camera{c_tag = "CentComm Special Ops. Ready Room South"; dir = 1; network = list("ERT","CentComm")},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "vJ" = (/obj/machinery/newscaster{layer = 3.3; pixel_x = 0; pixel_y = -27},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "vL" = (/obj/item/device/radio/intercom/specops{pixel_y = -28},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "vM" = (/obj/structure/table/woodentable{dir = 10},/obj/machinery/door_control{desc = "A remote control switch to block view of the singularity."; icon_state = "doorctrl0"; id = "SPECOPS"; name = "Ready Room"; pixel_y = 16; req_access_txt = "114"},/obj/machinery/door_control{desc = "A remote control switch to block view of the singularity."; icon_state = "doorctrl0"; id = "ASSAULT"; name = "Assault Armor"; pixel_y = -4; req_access_txt = "114"},/obj/machinery/door_control{desc = "A remote control switch to block view of the singularity."; icon_state = "doorctrl0"; id = "specopsoffice"; name = "Privacy Shutters"; pixel_y = 6; req_access_txt = "114"},/turf/unsimulated/floor{dir = 8; icon_state = "carpetside"},/area/centcom/specops) @@ -1068,7 +1070,7 @@ "Gc" = (/obj/machinery/door/airlock/hatch{desc = "You've heard rumors of the horrors that go on within this lab."; name = "Laboratory (DANGER!)"; req_access_txt = "0"},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "Gd" = (/obj/machinery/computer/ordercomp,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "Ge" = (/obj/machinery/computer/crew,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) -"Gf" = (/obj/machinery/computer/security{network = list("SS13","Telecomms","Research Outpost","Mining Outpost","ERT","CentCom","Thunderdome")},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) +"Gf" = (/obj/machinery/computer/security{network = list("SS13","Telecomms","Research Outpost","Mining Outpost","ERT","CentComm","Thunderdome")},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "Gg" = (/obj/machinery/computer/rdservercontrol{badmin = 1; name = "Master R&D Server Controller"},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "Gh" = (/obj/machinery/r_n_d/server/centcom,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "Gi" = (/obj/structure/table,/obj/item/weapon/card/id/silver{pixel_x = -3; pixel_y = -3},/obj/item/weapon/card/id/captains_spare,/obj/item/weapon/card/id/lifetime{pixel_x = 3; pixel_y = 3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) @@ -1167,11 +1169,9 @@ "HZ" = (/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "white"},/area/tdome) "Ia" = (/obj/item/device/camera,/turf/unsimulated/floor{tag = "icon-redbluefull (WEST)"; icon_state = "redbluefull"; dir = 8},/area/tdome/tdomeobserve) "Ib" = (/obj/structure/toilet{dir = 8},/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/admin) -"Ic" = (/obj/structure/rack,/obj/item/clothing/under/color/red,/obj/item/clothing/shoes/brown,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/legcuffs/beartrap,/obj/item/weapon/sleeping_carp_scroll,/obj/item/weapon/twohanded/bostaff,/turf/unsimulated/floor{icon_state = "dark"},/area/tdome/arena) "Id" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows (WEST)"; icon_state = "fakewindows"; dir = 8},/area/tdome) "Ie" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows2 (WEST)"; icon_state = "fakewindows2"; dir = 8},/area/tdome) "If" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows (EAST)"; icon_state = "fakewindows"; dir = 4},/area/tdome) -"Ig" = (/obj/structure/rack,/obj/item/clothing/under/color/green,/obj/item/clothing/shoes/brown,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/legcuffs/beartrap,/obj/item/weapon/sleeping_carp_scroll,/obj/item/weapon/twohanded/bostaff,/turf/unsimulated/floor{icon_state = "dark"},/area/tdome/arena) "Ih" = (/obj/machinery/door/poddoor{id_tag = "thunderdomeaxe"; name = "Axe Supply"},/turf/unsimulated/floor{icon_state = "dark"},/area/tdome/arena) "Ii" = (/obj/structure/rack,/obj/item/clothing/under/color/red,/obj/item/clothing/shoes/brown,/obj/item/clothing/suit/armor/tdome/red,/obj/item/clothing/head/helmet/thunderdome,/obj/item/weapon/melee/energy/sword/saber/red,/turf/unsimulated/floor{icon_state = "dark"},/area/tdome/arena) "Ij" = (/obj/machinery/door/poddoor{id_tag = "thunderdomegen"; name = "General Supply"},/turf/unsimulated/floor{icon_state = "dark"},/area/tdome/arena) @@ -1232,7 +1232,7 @@ ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapap ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckbockckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpeoepeneoepbseqeDeqeqeqbsereEeFeGerbseHeHeIeJeJbseveKeveLevbseMeNeNeNeObsePeQeQeQeRbD ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapavapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpepeneoepenbseqeqeqeXeqbsereYeYeYerbseHeZeZeZeJbsevevevevevbseMeNeNeNeObsePeQeQeQeRbD ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfffffffffffgfgfhfififjfgfgfgfgfgfgfgfgfgfkfgfgfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpeneoepeneobseqeqeqeqeqbserererererbseHeIeIeIeJbsevevevevevbseMeNeNeNeObsePeQeQeQeRbD -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNftfufvfwfffgfxfyfzfAfAfBfCfDfEfFfGfHfIfHfHfJfKfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpeoepeneoepbseqeqeqfMeqbserfNfOfPerbsfQfRfRfRfSbsevfTevevevbsfUfVfVfVfWbsePeQeQeQeRbD +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNftfufvfwfffgfxfyfzfAfAfBfCfDdJdMfGfHfIfHfHfJfKfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpeoepeneoepbseqeqeqfMeqbserfNfOfPerbsfQfRfRfRfSbsevfTevevevbsfUfVfVfVfWbsePeQeQeQeRbD ckckckckckckckclckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfffffffufufufffggbfyfyfyfyfygcgdgdgdgefHfHfHgffHfHfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpepeneoepenbseqgkeqeqeqbserglgmgnerbsgogpgpgpgqbsevevevgrevbsgsgtgtgtgubsgveQeQeQgwbD ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNgygzgAfufufufffggBfygCgDgEgFgGgdgdgdgdfHfHgHfHgIfIfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpeneoepeneobseqeqeqeqeDbserglgmgnerbsgJeIgKeIgLbsevevevevevbsgMeNeNeNgNbsgveQeQeQgwbD ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckcmckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNgOgPgQfufufufffggRgdgegegegegegdgdgdgdfHfHfHgSfHfHfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpeoepeneoepbsgTeqeqeqeqbserglgmgnerbsgJgUgUgUgLbsgVgVgVgVgVbsgMeNeNeNgNbsgveQeQeQgwbD @@ -1248,7 +1248,7 @@ ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckck ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbZhzhzhzhzhzbZhzhzhzhzhzbZhzhzhzhzhzbZ ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihihihihihihihihihihihihaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNatatatatataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihiiijikiliminihioipiqihaNaNirisisisisisitaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNatauauauataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbZbZbZbZbZbZbZaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbZbZbZbZbZbZbZaNaNaNaNaN -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihikikikikikikikixiyizihaNaNisiAiBiCiDiEitaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNatauayauataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbZiJiJiJiJiJbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZiKiKiKiKiKbZaNaNaNaNaN +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihikikikikikikikixiyizihaNaNisiAiBiCiDiEitaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNatauayauataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbZdEdEdEdEdEbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZdFdFdFdFdFbZaNaNaNaNaN ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihiLiLikikikiMihiNiOiPihaNaNisiQiRiRiRiQititititaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNatauauauataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbZbZbZiZiZiZiZiZjajbjcjcjcjcjcjcjcjcjcjcjcjcjcjbjaiZiZiZiZiZbZbZbZaNaNaN ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihikikikikjdjdihihjeihihaNaNisiQjfjfjfiQitjgjhitaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNatatatatataFaGaGaGaGaGaGaGaHatataIatataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbZjljmbZbZbZbZbZjnjojpjpjpjpjpjpjpjpjpjpjpjpjpjqjnbZbZbZbZbZjmjrbZaNaNaN ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihjAjAikjBjCjDihjEjejFihaNaNisiQjGjHjIiQititititititititititititaNaNaNaNaNaNaNaNaNaNaNataJaJaJaKauauauauauauauauaKaKaKauaJataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbZjljmbZbZbZbZbZjnjojpjpjpjpjpjpjpjpjpjpjpjpjpjqjnbZbZbZbZbZjmjrbZaNaNaN @@ -1455,7 +1455,7 @@ aNaNaNaNaNHjHxHyHyHyHyHzHjHEHFHGHFHHHIHJHJHJHIHHHJHHHJHKHjaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNHjHRHyHyHyHyHSHjHJHTHTHTHTHTHJHJHJHTHTHTHTHTHUHjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEMDwDwDwDwGZHVHWDADwDwDwDwEnaNDIDKDKDAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNHjHRHXHYHYHyHyHZHJHJHJIaHJHJHJHJHJHJHJIaHJHJHJHjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEMaNaNEMDAGXIbDAEnaNaNaNaNaNEfDKDKDAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNHjHjHjHjHjHjHjHjHJHTHTHTHTHTHJHJHJHTHTHTHTHTHJHjHjHjHjHjHjHjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEMDwDwEnaNDtDxDyDyDzGaDKDKDAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNHjIcIcIcIcIcHjIdIeIeIeIeIeIeIeIeIeIeIeIeIeIfHjIgIgIgIgIgHjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDIDKDKDKDKDKDKDKDAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNHjdHdHdHdHdHHjIdIeIeIeIeIeIeIeIeIeIeIeIeIeIfHjdIdIdIdIdIHjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDIDKDKDKDKDKDKDKDAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNHjHjHjIhIhIhIhIhjajbjcjcjcjcjcjcjcjcjcjcjcjcjcjbjaIhIhIhIhIhHjHjHjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEfDKDKDKDKDKDKFkDAEnaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNHjIiIjIkIkIkIkIkIlImjcjcjcjcjcjcjcjcjcjcjcjcjcInIlIoIoIoIoIoIjIpHjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEMDwDwDMIqDMDwDwEnaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNHjIiIjIkIrIkIrIkIlImjcjcjcjcjcjcjcjcjcjcjcjcjcInIlIoIsIoIsIoIjIpHjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDAItDKDKDKIuDAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN diff --git a/_maps/test_away_missions.dm b/_maps/test_away_missions.dm new file mode 100644 index 00000000000..3da5879bd94 --- /dev/null +++ b/_maps/test_away_missions.dm @@ -0,0 +1,16 @@ +// This is for Travis testing. DO NOT SET THIS AS THE GAME'S MAP NORMALLY! + +#if !defined(MAP_FILE) + #include "map_files\RandomZLevels\beach.dmm" + #include "map_files\RandomZLevels\listeningpost.dmm" + #include "map_files\RandomZLevels\moonoutpost19.dmm" + #include "map_files\RandomZLevels\undergroundoutpost45.dmm" + + #include "map_files\RandomZLevels\evil_santa.dmm" + + #define MAP_FILE "beach.dmm" + #define MAP_NAME "Away Missions Test" + +#elif !defined(MAP_OVERRIDE) + #warn a map has already been included. +#endif \ No newline at end of file diff --git a/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm b/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm index e6731d4ea17..3366777a081 100644 --- a/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm +++ b/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm @@ -12,6 +12,7 @@ use_power = 1 can_unwrench = 1 + var/open = 0 var/area/initial_loc var/area_uid @@ -339,6 +340,29 @@ else user << "You need more welding fuel to complete this task." return 1 + if(istype(W, /obj/item/weapon/screwdriver)) + if(!welded) + if(open) + user << " Now closing the vent." + if (do_after(user, 20, target = src)) + open = 0 + user.visible_message("[user] screwdrivers the vent shut.", "You screwdriver the vent shut.", "You hear a screwdriver.") + else + user << " Now opening the vent." + if (do_after(user, 20, target = src)) + open = 1 + user.visible_message("[user] screwdrivers the vent shut.", "You screwdriver the vent shut.", "You hear a screwdriver.") + return + if(istype(W, /obj/item/weapon/paper)) + if(!welded) + if(open) + user.drop_item(W) + W.forceMove(src) + if(!open) + user << "You can't shove that down there when it is closed" + else + user << "The vent is welded." + return if(istype(W, /obj/item/device/multitool)) update_multitool_menu(user) return 1 @@ -349,6 +373,12 @@ return ..() +/obj/machinery/atmospherics/unary/vent_pump/attack_hand() + if(!welded) + if(open) + for(var/obj/item/weapon/W in src) + W.forceMove(get_turf(src)) + /obj/machinery/atmospherics/unary/vent_pump/examine(mob/user) ..(user) diff --git a/code/LINDA/LINDA_fire.dm b/code/LINDA/LINDA_fire.dm index f82cd83d3a6..afbeb0a0e45 100644 --- a/code/LINDA/LINDA_fire.dm +++ b/code/LINDA/LINDA_fire.dm @@ -49,6 +49,7 @@ layer = TURF_LAYER blend_mode = BLEND_ADD + light_range = 3 var/volume = 125 var/temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST @@ -57,8 +58,6 @@ /obj/effect/hotspot/New() ..() - color = heat2color(temperature) - set_light(3, 1, color) air_master.hotspots += src perform_exposure() dir = pick(cardinal) @@ -88,10 +87,8 @@ if(item && item != src) // It's possible that the item is deleted in temperature_expose item.fire_act(null, temperature, volume) -// animate(src, color = heat2color(temperature), 5) color = heat2color(temperature) set_light(l_color = color) - return 0 @@ -122,7 +119,6 @@ if(bypassing) icon_state = "3" - set_light(7,3) location.burn_tile() //Possible spread due to radiated heat @@ -138,10 +134,8 @@ else if(volume > CELL_VOLUME*0.4) icon_state = "2" - set_light(5, 2) else icon_state = "1" - set_light(3, 1) if(temperature > location.max_fire_temperature_sustained) location.max_fire_temperature_sustained = temperature @@ -156,9 +150,9 @@ // Garbage collect itself by nulling reference to it /obj/effect/hotspot/Destroy() + set_light(0) air_master.hotspots -= src DestroyTurf() - set_light(0) if(istype(loc, /turf/simulated)) var/turf/simulated/T = loc if(T.active_hotspot == src) diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm new file mode 100644 index 00000000000..14161a5775f --- /dev/null +++ b/code/__DEFINES/is_helpers.dm @@ -0,0 +1 @@ +#define ismovableatom(A) istype(A, /atom/movable) \ No newline at end of file diff --git a/code/__DEFINES/pda.dm b/code/__DEFINES/pda.dm new file mode 100644 index 00000000000..d22b90870b0 --- /dev/null +++ b/code/__DEFINES/pda.dm @@ -0,0 +1,3 @@ +#define PDA_APP_UPDATE 0 +#define PDA_APP_NOUPDATE 1 +#define PDA_APP_UPDATE_SLOW 2 \ No newline at end of file diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 03a684fc743..73258a2875c 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -15,13 +15,11 @@ if (isarea(A)) return A -/proc/get_area(O) - if(isarea(O)) - return O - var/turf/loc = get_turf(O) - if(loc) - var/area/res = loc.loc - .= res +/proc/get_area(atom/A) + if(!istype(A)) + return + for(A, A && !isarea(A), A=A.loc); //semicolon is for the empty statement + return A /proc/get_area_name(N) //get area by its name for(var/area/A in world) diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index e9a71917425..35b82c2fae3 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -20,7 +20,9 @@ init_sprite_accessory_subtypes(/datum/sprite_accessory/socks, socks_list, socks_m, socks_f) init_subtypes(/datum/surgery_step, surgery_steps) - sort_surgeries() + + for(var/path in (subtypesof(/datum/surgery))) + surgeries_list += new path() init_datum_subtypes(/datum/job, joblist, list(/datum/job/ai, /datum/job/cyborg), "title") init_datum_subtypes(/datum/superheroes, all_superheroes, null, "name") diff --git a/code/__HELPERS/names.dm b/code/__HELPERS/names.dm index 5189b24b551..70c597c2d7b 100644 --- a/code/__HELPERS/names.dm +++ b/code/__HELPERS/names.dm @@ -260,7 +260,7 @@ var/syndicate_code_response//Code response for traitors. if(2) syndicate_code_phrase += pick("How do I get to","How do I find","Where is","Where do I find") syndicate_code_phrase += " " - syndicate_code_phrase += pick("Escape","Engineering","Atmos","the bridge","the brig","Clown Planet","CentCom","the library","the chapel","a bathroom","Med Bay","Tool Storage","the escape shuttle","Robotics","a locker room","the living quarters","the gym","the autolathe","QM","the bar","the theater","the derelict") + syndicate_code_phrase += pick("Escape","Engineering","Atmos","the bridge","the brig","Clown Planet","CentComm","the library","the chapel","a bathroom","Med Bay","Tool Storage","the escape shuttle","Robotics","a locker room","the living quarters","the gym","the autolathe","QM","the bar","the theater","the derelict") syndicate_code_phrase += "?" if(3) if(prob(70)) @@ -287,7 +287,7 @@ var/syndicate_code_response//Code response for traitors. if(prob(80)) syndicate_code_response += pick("Try looking for them near","I they ran off to","Yes. I saw them near","Nope. I'm heading to","Try searching") syndicate_code_response += " " - syndicate_code_response += pick("Escape","Engineering","Atmos","the bridge","the brig","Clown Planet","CentCom","the library","the chapel","a bathroom","Med Bay","Tool Storage","the escape shuttle","Robotics","a locker room","the living quarters","the gym","the autolathe","QM","the bar","the theater","the derelict") + syndicate_code_response += pick("Escape","Engineering","Atmos","the bridge","the brig","Clown Planet","CentComm","the library","the chapel","a bathroom","Med Bay","Tool Storage","the escape shuttle","Robotics","a locker room","the living quarters","the gym","the autolathe","QM","the bar","the theater","the derelict") syndicate_code_response += "." else if(prob(60)) syndicate_code_response += pick("No. I'm busy, sorry.","I don't have the time.","Not sure, maybe?","There is no time.") diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 5b720291b48..865cf6f7384 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -19,8 +19,8 @@ return copytext(sqltext, 2, lentext(sqltext));//Quote() adds quotes around input, we already do that /proc/format_table_name(table as text) - return sqlfdbktableprefix + table - + return sqlfdbktableprefix + table + /* * Text sanitization */ @@ -39,9 +39,9 @@ //Removes a few problematic characters /proc/sanitize_simple(var/t,var/list/repl_chars = list("\n"="#","\t"="#")) for(var/char in repl_chars) - replacetext(t, char, repl_chars[char]) + t = replacetext(t, char, repl_chars[char]) return t - + /proc/readd_quotes(var/t) var/list/repl_chars = list(""" = "\"") for(var/char in repl_chars) @@ -210,12 +210,11 @@ proc/checkhtml(var/t) /proc/replacetextEx(text, find, replacement) return list2text(text2listEx(text, find), replacement) #endif - /proc/replace_characters(var/t,var/list/repl_chars) for(var/char in repl_chars) t = replacetext(t, char, repl_chars[char]) - return t - + return t + //Adds 'u' number of zeros ahead of the text 't' /proc/add_zero(t, u) while (length(t) < u) @@ -320,11 +319,11 @@ proc/checkhtml(var/t) for(var/i = length(text); i > 0; i--) new_text += copytext(text, i, i+1) return new_text - + //This proc strips html properly, but it's not lazy like the other procs. //This means that it doesn't just remove < and > and call it a day. //Also limit the size of the input, if specified. -/proc/strip_html_properly(var/input, var/max_length = MAX_MESSAGE_LEN) +/proc/strip_html_properly(var/input, var/max_length = MAX_MESSAGE_LEN, allow_lines = 0) if(!input) return var/opentag = 1 //These store the position of < and > respectively. @@ -346,11 +345,11 @@ proc/checkhtml(var/t) break if(max_length) input = copytext(input,1,max_length) - return sanitize(input) + return sanitize(input, allow_lines ? list("\t" = " ") : list("\n" = " ", "\t" = " ")) + +/proc/trim_strip_html_properly(var/input, var/max_length = MAX_MESSAGE_LEN, allow_lines = 0) + return trim(strip_html_properly(input, max_length, allow_lines)) -/proc/trim_strip_html_properly(var/input, var/max_length = MAX_MESSAGE_LEN) - return trim(strip_html_properly(input, max_length)) - //Used in preferences' SetFlavorText and human's set_flavor verb //Previews a string of len or less length /proc/TextPreview(var/string,var/len=40) @@ -365,10 +364,10 @@ proc/checkhtml(var/t) //alternative copytext() for encoded text, doesn't break html entities (" and other) /proc/copytext_preserve_html(var/text, var/first, var/last) return html_encode(copytext(html_decode(text), first, last)) - + //Run sanitize(), but remove <, >, " first to prevent displaying them as > < &34; in some places, after html_encode(). //Best used for sanitize object names, window titles. //If you have a problem with sanitize() in chat, when quotes and >, < are displayed as html entites - //this is a problem of double-encode(when & becomes &), use sanitize() with encode=0, but not the sanitizeSafe()! /proc/sanitizeSafe(var/input, var/max_length = MAX_MESSAGE_LEN, var/encode = 1, var/trim = 1, var/extra = 1) - return sanitize(replace_characters(input, list(">"=" ","<"=" ", "\""="'")), max_length, encode, trim, extra) \ No newline at end of file + return sanitize(replace_characters(input, list(">"=" ","<"=" ", "\""="'")), max_length, encode, trim, extra) \ No newline at end of file diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index 2421c64b62f..99c641f6dd0 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -424,4 +424,23 @@ proc/tg_text2list(text, glue=",", assocglue=";") if(temp <= 16) . = 0 else - . = max(0, min(255, 138.5177312231 * log(temp - 10) - 305.0447927307)) \ No newline at end of file + . = max(0, min(255, 138.5177312231 * log(temp - 10) - 305.0447927307)) + +//Argument: Give this a space-separated string consisting of 6 numbers. Returns null if you don't +/proc/text2matrix(var/matrixtext) + var/list/matrixtext_list = text2list(matrixtext, " ") + var/list/matrix_list = list() + for(var/item in matrixtext_list) + var/entry = text2num(item) + if(entry == null) + return null + matrix_list += entry + if(matrix_list.len < 6) + return null + var/a = matrix_list[1] + var/b = matrix_list[2] + var/c = matrix_list[3] + var/d = matrix_list[4] + var/e = matrix_list[5] + var/f = matrix_list[6] + return matrix(a, b, c, d, e, f) \ No newline at end of file diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index be1a99c72df..1e17e84735d 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -272,108 +272,6 @@ Turf and target are seperate in case you want to teleport some distance from a t user << "[target] is empty!" return -//This will update a mob's name, real_name, mind.name, data_core records, pda and id -//Calling this proc without an oldname will only update the mob and skip updating the pda, id and records ~Carn -/mob/proc/fully_replace_character_name(var/oldname,var/newname) - if(!newname) return 0 - real_name = newname - name = newname - if(mind) - mind.name = newname - if(dna) - dna.real_name = real_name - - if(isrobot(src)) - var/mob/living/silicon/robot/R = src - if(oldname != real_name) - R.notify_ai(3, oldname, newname) - R.custom_name = newname - R.updatename() - if(oldname) - //update the datacore records! This is goig to be a bit costly. - for(var/list/L in list(data_core.general,data_core.medical,data_core.security,data_core.locked)) - for(var/datum/data/record/R in L) - if(R.fields["name"] == oldname) - R.fields["name"] = newname - break - - //update our pda and id if we have them on our person - var/list/searching = GetAllContents(searchDepth = 3) - var/search_id = 1 - var/search_pda = 1 - - for(var/A in searching) - if( search_id && istype(A,/obj/item/weapon/card/id) ) - var/obj/item/weapon/card/id/ID = A - if(ID.registered_name == oldname) - ID.registered_name = newname - ID.name = "[newname]'s ID Card ([ID.assignment])" - if(!search_pda) break - search_id = 0 - - else if( search_pda && istype(A,/obj/item/device/pda) ) - var/obj/item/device/pda/PDA = A - if(PDA.owner == oldname) - PDA.owner = newname - PDA.name = "PDA-[newname] ([PDA.ownjob])" - if(!search_id) break - search_pda = 0 - - //Fixes renames not being reflected in objective text - var/list/O = subtypesof(/datum/objective) - var/length - var/pos - for(var/datum/objective/objective in O) - if(objective.target != mind) continue - length = lentext(oldname) - pos = findtextEx(objective.explanation_text, oldname) - objective.explanation_text = copytext(objective.explanation_text, 1, pos)+newname+copytext(objective.explanation_text, pos+length) - return 1 - - - -//Generalised helper proc for letting mobs rename themselves. Used to be clname() and ainame() -//Last modified by Carn -/mob/proc/rename_self(var/role, var/allow_numbers=0) - spawn(0) - var/oldname = real_name - - var/time_passed = world.time - var/newname - - for(var/i=1,i<=3,i++) //we get 3 attempts to pick a suitable name. - newname = input(src,"You are a [role]. Would you like to change your name to something else?", "Name change",oldname) as text - if((world.time-time_passed)>300) - return //took too long - newname = reject_bad_name(newname,allow_numbers) //returns null if the name doesn't meet some basic requirements. Tidies up a few other things like bad-characters. - - for(var/mob/living/M in player_list) - if(M == src) - continue - if(!newname || M.real_name == newname) - newname = null - break - if(newname) - break //That's a suitable name! - src << "Sorry, that [role]-name wasn't appropriate, please try another. It's possibly too long/short, has bad characters or is already taken." - - if(!newname) //we'll stick with the oldname then - return - - if(cmptext("ai",role)) - if(isAI(src)) - var/mob/living/silicon/ai/A = src - oldname = null//don't bother with the records update crap - //world << "[newname] is the AI!" - //world << sound('sound/AI/newAI.ogg') - // Set eyeobj name - A.SetName(newname) - - - fully_replace_character_name(oldname,newname) - - - //Picks a string of symbols to display as the law number for hacked or ion laws /proc/ionnum() return "[pick("!","@","#","$","%","^","&","*")][pick("!","@","#","$","%","^","&","*")][pick("!","@","#","$","%","^","&","*")][pick("!","@","#","$","%","^","&","*")]" @@ -1001,7 +899,7 @@ proc/anim(turf/location as turf,target as mob|obj,a_icon,a_icon_state as text,fl -proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0) +/proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0, var/atom/newloc = null) if(!original) return null @@ -1010,15 +908,23 @@ proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0) if(sameloc) O=new original.type(original.loc) else - O=new original.type(locate(0,0,0)) + O=new original.type(newloc) if(perfectcopy) if((O) && (original)) - for(var/V in original.vars) - if(!(V in list("type","loc","locs","vars", "parent", "parent_type","verbs","ckey","key"))) - O.vars[V] = original.vars[V] - return O + var/static/list/forbidden_vars = list("type","loc","locs","vars", "parent","parent_type", "verbs","ckey","key","power_supply","contents","reagents","stat","x","y","z","group") + for(var/V in original.vars - forbidden_vars) + if(istype(original.vars[V],/list)) + var/list/L = original.vars[V] + O.vars[V] = L.Copy() + else if(istype(original.vars[V],/datum)) + continue // this would reference the original's object, that will break when it is used or deleted. + else + O.vars[V] = original.vars[V] + if(istype(O)) + O.update_icon() + return O /area/proc/copy_contents_to(var/area/A , var/platingRequired = 0 ) //Takes: Area. Optional: If it should copy to areas that don't have plating @@ -1124,7 +1030,7 @@ proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0) for(var/V in T.vars) - if(!(V in list("type","loc","locs","vars", "parent", "parent_type","verbs","ckey","key","x","y","z","contents", "luminosity"))) + if(!(V in list("type","loc","locs","vars", "parent", "parent_type","verbs","ckey","key","x","y","z","contents", "luminosity", "group"))) X.vars[V] = T.vars[V] // var/area/AR = X.loc @@ -1778,3 +1684,58 @@ var/mob/dview/dview_mob = new tY = max(1, min(world.maxy, origin.y + (text2num(tY) - (world.view + 1)))) return locate(tX, tY, tZ) +/proc/pick_closest_path(value) + var/list/matches = get_fancy_list_of_types() + if (!isnull(value) && value!="") + matches = filter_fancy_list(matches, value) + + if(matches.len==0) + return + + var/chosen + if(matches.len==1) + chosen = matches[1] + else + chosen = input("Select an atom type", "Spawn Atom", matches[1]) as null|anything in matches + if(!chosen) + return + chosen = matches[chosen] + return chosen + + +var/list/TYPES_SHORTCUTS = list( + /obj/effect/decal/cleanable = "CLEANABLE", + /obj/item/device/radio/headset = "HEADSET", + /obj/item/clothing/head/helmet/space = "SPESSHELMET", + /obj/item/weapon/book/manual = "MANUAL", + /obj/item/weapon/reagent_containers/food/drinks = "DRINK", //longest paths comes first + /obj/item/weapon/reagent_containers/food = "FOOD", + /obj/item/weapon/reagent_containers = "REAGENT_CONTAINERS", + /obj/machinery/atmospherics = "ATMOS", + /obj/machinery/portable_atmospherics = "PORT_ATMOS", +// /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/missile_rack = "MECHA_MISSILE_RACK", + /obj/item/mecha_parts/mecha_equipment = "MECHA_EQUIP", +// /obj/item/organ/internal = "ORGAN_INT", +) + +var/global/list/g_fancy_list_of_types = null +/proc/get_fancy_list_of_types() + if (isnull(g_fancy_list_of_types)) //init + var/list/temp = sortList(subtypesof(/atom) - typesof(/area) - /atom/movable) + g_fancy_list_of_types = new(temp.len) + for(var/type in temp) + var/typename = "[type]" + for (var/tn in TYPES_SHORTCUTS) + if (copytext(typename,1, length("[tn]/")+1)=="[tn]/" /*findtextEx(typename,"[tn]/",1,2)*/ ) + typename = TYPES_SHORTCUTS[tn]+copytext(typename,length("[tn]/")) + break + g_fancy_list_of_types[typename] = type + return g_fancy_list_of_types + +/proc/filter_fancy_list(list/L, filter as text) + var/list/matches = new + for(var/key in L) + var/value = L[key] + if(findtext("[key]", filter) || findtext("[value]", filter)) + matches[key] = value + return matches \ No newline at end of file diff --git a/code/_globalvars/lists/misc.dm b/code/_globalvars/lists/misc.dm index d6fc14b4f3f..52d05ac6d65 100644 --- a/code/_globalvars/lists/misc.dm +++ b/code/_globalvars/lists/misc.dm @@ -14,7 +14,7 @@ var/list/heartstopper = list("capulettium", "capulettium_plus") //this stops the var/list/cheartstopper = list() //this stops the heart when overdose is met -- c = conditional var/list/restricted_camera_networks = list( //Those networks can only be accessed by preexisting terminals. AIs and new terminals can't use them. - "CentCom", + "CentComm", "ERT", "NukeOps", "Thunderdome", diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm index 381ade73a80..01cfb1c6b39 100644 --- a/code/_globalvars/lists/mobs.dm +++ b/code/_globalvars/lists/mobs.dm @@ -72,4 +72,5 @@ var/global/list/blocked_mobs = list(/mob/living/simple_animal, var/global/list/med_hud_users = list() var/global/list/sec_hud_users = list() var/global/list/antag_hud_users = list() +var/global/list/surgeries_list = list() //items that ask to be called every cycle diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm index a20149b8c97..d6689af71b2 100644 --- a/code/_globalvars/lists/objects.dm +++ b/code/_globalvars/lists/objects.dm @@ -26,4 +26,4 @@ var/global/list/power_monitors = list() var/global/list/beacons = list() var/global/list/shuttle_caller_list = list() //list of all communication consoles and AIs, for automatic shuttle calls when there are none. -var/global/list/tracked_implants = list() //list of all current implants that are tracked to work out what sort of trek everyone is on. Sadly not on lavaworld not implemented... \ No newline at end of file +var/global/list/tracked_implants = list() //list of all current implants that are tracked to work out what sort of trek everyone is on. Sadly not on lavaworld not implemented... diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index 5b9dd3bc6c7..b44ba964628 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -10,8 +10,8 @@ Note that AI have no need for the adjacency proc, and so this proc is a lot cleaner. */ /mob/living/silicon/ai/DblClickOn(var/atom/A, params) - if(client.buildmode) // comes after object.Click to allow buildmode gui objects to be clicked - build_click(src, client.buildmode, params, A) + if(client.click_intercept) + client.click_intercept.InterceptClickOn(src, params, A) return if(control_disabled || stat) return @@ -23,13 +23,14 @@ /mob/living/silicon/ai/ClickOn(var/atom/A, params) + if(client.click_intercept) + client.click_intercept.InterceptClickOn(src, params, A) + return + if(world.time <= next_click) return next_click = world.time + 1 - if(client.buildmode) // comes after object.Click to allow buildmode gui objects to be clicked - build_click(src, client.buildmode, params, A) - return if(control_disabled || stat) return diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index b82cd7ab9d1..d43d12b1e8b 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -34,14 +34,14 @@ * mob/RangedAttack(atom,params) - used only ranged, only used for tk and laser eyes but could be changed */ /mob/proc/ClickOn( var/atom/A, var/params ) + if(client.click_intercept) + client.click_intercept.InterceptClickOn(src, params, A) + return + if(world.time <= next_click) return next_click = world.time + 1 - if(client && client.buildmode) - build_click(src, client.buildmode, params, A) - return - var/list/modifiers = params2list(params) if(modifiers["shift"] && modifiers["ctrl"]) CtrlShiftClickOn(A) @@ -319,17 +319,9 @@ LE.current = T LE.yo = U.y - T.y LE.xo = U.x - T.x - spawn( 1 ) + spawn(1) LE.process() -/mob/living/carbon/human/LaserEyes() - if(nutrition>0) - ..() - nutrition = max(nutrition - rand(1,5),0) - handle_regular_hud_updates() - else - src << "\red You're out of energy! You need food!" - /mob/proc/PowerGlove(atom/A) return diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm index fd54407f19e..6fd00ba1f17 100644 --- a/code/_onclick/cyborg.dm +++ b/code/_onclick/cyborg.dm @@ -7,13 +7,14 @@ */ /mob/living/silicon/robot/ClickOn(var/atom/A, var/params) + if(client.click_intercept) + client.click_intercept.InterceptClickOn(src, params, A) + return + if(world.time <= next_click) return next_click = world.time + 1 - if(client.buildmode) // comes after object.Click to allow buildmode gui objects to be clicked - build_click(src, client.buildmode, params, A) - return var/list/modifiers = params2list(params) if(modifiers["shift"] && modifiers["ctrl"]) diff --git a/code/_onclick/hud/action.dm b/code/_onclick/hud/action.dm index 9987fe47511..4461e1c8539 100644 --- a/code/_onclick/hud/action.dm +++ b/code/_onclick/hud/action.dm @@ -221,6 +221,22 @@ /datum/action/item_action/hands_free check_flags = AB_CHECK_ALIVE|AB_CHECK_INSIDE +///prset for organ actions +/datum/action/item_action/organ_action + check_flags = AB_CHECK_ALIVE + +/datum/action/item_action/organ_action/CheckRemoval(mob/living/carbon/user) + if(!iscarbon(user)) + return 1 + if(target in user.internal_organs) + return 0 + return 1 + +/datum/action/item_action/organ_action/IsAvailable() + var/obj/item/organ/internal/I = target + if(!I.owner) + return 0 + return ..() //Preset for spells /datum/action/spell_action diff --git a/code/_onclick/hud/ai.dm b/code/_onclick/hud/ai.dm index 790cbd305bc..0049537e9b4 100644 --- a/code/_onclick/hud/ai.dm +++ b/code/_onclick/hud/ai.dm @@ -100,7 +100,7 @@ /obj/screen/ai/pda_msg_send/Click() if(isAI(usr)) var/mob/living/silicon/ai/AI = usr - AI.cmd_send_pdamesg(usr) + AI.aiPDA.cmd_send_pdamesg() /obj/screen/ai/pda_msg_show name = "PDA - Show Message Log" @@ -109,7 +109,7 @@ /obj/screen/ai/pda_msg_show/Click() if(isAI(usr)) var/mob/living/silicon/ai/AI = usr - AI.cmd_show_message_log(usr) + AI.aiPDA.cmd_show_message_log() /obj/screen/ai/image_take name = "Take Image" diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 9ab4aa159d0..01953690274 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -31,8 +31,21 @@ var/messagesource = M if (can_operate(M)) //Checks if mob is lying down on table for surgery - if (do_surgery(M,user,src)) - return 0 + if(istype(src,/obj/item/robot_parts))//popup ovveride for direct attach + if(!attempt_initiate_surgery(src, M, user,1)) + return 0 + else + return 1 + if(istype(src,/obj/item/weapon/screwdriver) && M.get_species() == "Machine") + if(!attempt_initiate_surgery(src, M, user)) + return 0 + else + return 1 + if(is_sharp(src)) + if(!attempt_initiate_surgery(src, M, user)) + return 0 + else + return 1 if (istype(M,/mob/living/carbon/brain)) messagesource = M:container @@ -53,6 +66,8 @@ // M.lastattacker = null ///////////////////////// + if(istype(M, /mob/living/simple_animal)) + return 0 // No sanic-speed double-attacks for you - simple mobs will handle being attacked on their own var/power = force if(!istype(M, /mob/living/carbon/human)) diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index 47ed53749bc..891601d2d51 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -1,14 +1,15 @@ /mob/dead/observer/DblClickOn(var/atom/A, var/params) - if(client.buildmode) - build_click(src, client.buildmode, params, A) + if(client.click_intercept) + client.click_intercept.InterceptClickOn(src, params, A) return + if(can_reenter_corpse && mind && mind.current) if(A == mind.current || (mind.current in A)) // double click your corpse or whatever holds it reenter_corpse() // (cloning scanner, body bag, closet, mech, etc) return // seems legit. - // Things you might plausibly want to follow - if((ismob(A) && A != src) || istype(A,/obj/machinery/bot) || istype(A,/obj/singularity)) + // Follow !!ALL OF THE THINGS!! + if(istype(A, /atom/movable) && A != src) ManualFollow(A) // Otherwise jump @@ -17,8 +18,8 @@ forceMove(get_turf(A)) /mob/dead/observer/ClickOn(var/atom/A, var/params) - if(client.buildmode) - build_click(src, client.buildmode, params, A) + if(client.click_intercept) + client.click_intercept.InterceptClickOn(src, params, A) return if(world.time <= next_move) return diff --git a/code/controllers/Processes/timer.dm b/code/controllers/Processes/timer.dm new file mode 100644 index 00000000000..49024083940 --- /dev/null +++ b/code/controllers/Processes/timer.dm @@ -0,0 +1,81 @@ +var/global/datum/controller/process/timer/timer_master + +/datum/controller/process/timer + var/list/processing_timers = list() + var/list/hashes = list() + +/datum/controller/process/timer/setup() + name = "timer" + schedule_interval = 5 //every 0.5 seconds + timer_master = src + +/datum/controller/process/timer/statProcess() + ..() + stat(null, "[processing_timers.len] timers") + +/datum/controller/process/timer/doWork() + if(!processing_timers.len) + disabled = 1 //nothing to do, lets stop firing. + return + for(last_object in processing_timers) + var/datum/timedevent/event = last_object + if(!event.thingToCall || qdeleted(event.thingToCall)) + qdel(event) + if(event.timeToRun <= world.time) + runevent(event) + qdel(event) + SCHECK + +/datum/controller/process/timer/proc/runevent(datum/timedevent/event) + set waitfor = 0 + call(event.thingToCall, event.procToCall)(arglist(event.argList)) + +/datum/timedevent + var/thingToCall + var/procToCall + var/timeToRun + var/argList + var/id + var/hash + var/static/nextid = 1 + +/datum/timedevent/New() + id = nextid + nextid++ + +/datum/timedevent/Destroy() + timer_master.processing_timers -= src + timer_master.hashes -= hash + return QDEL_HINT_IWILLGC + +/proc/addtimer(thingToCall, procToCall, wait, unique = FALSE, ...) + if(!timer_master) //can't run timers before the mc has been created + return + if(!thingToCall || !procToCall || wait <= 0) + return + if(timer_master.disabled) + timer_master.disabled = 0 + + var/datum/timedevent/event = new() + event.thingToCall = thingToCall + event.procToCall = procToCall + event.timeToRun = world.time + wait + event.hash = list2text(args) + if(args.len > 4) + event.argList = args.Copy(5) + + // Check for dupes if unique = 1. + if(unique) + if(event.hash in timer_master.hashes) + return + // If we are unique (or we're not checking that), add the timer and return the id. + timer_master.processing_timers += event + timer_master.hashes += event.hash + return event.id + +/proc/deltimer(id) + for(var/datum/timedevent/event in timer_master.processing_timers) + if(event.id == id) + qdel(event) + return 1 + return 0 \ No newline at end of file diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index e65ced5c08c..208c41ffcf6 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -135,7 +135,7 @@ var/comms_password = "" var/use_irc_bot = 0 - var/irc_bot_host = "" + var/list/irc_bot_host = list() var/main_irc = "" var/admin_irc = "" var/python_path = "" //Path to the python executable. Defaults to "python" on windows and "/usr/bin/env python2" on unix @@ -458,7 +458,7 @@ config.comms_password = value if("irc_bot_host") - config.irc_bot_host = value + config.irc_bot_host = text2list(value, ";") if("main_irc") config.main_irc = value diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index 89f4a277796..2088a50d748 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -1,434 +1,432 @@ - // reference: /client/proc/modify_variables(var/atom/O, var/param_var_name = null, var/autodetect_class = 0) -client - proc/debug_variables(datum/D in world) - set category = "Debug" - set name = "View Variables" - //set src in world +/client/proc/debug_variables(datum/D in world) + set category = "Debug" + set name = "View Variables" + //set src in world - if(!usr.client || !usr.client.holder) - usr << "\red You need to be an administrator to access this." - return - - - var/title = "" - var/body = "" - - if(!D) return - if(istype(D, /atom)) - var/atom/A = D - title = "[A.name] (\ref[A]) = [A.type]" - - #ifdef VARSICON - if (A.icon) - body += debug_variable("icon", new/icon(A.icon, A.icon_state, A.dir), 0) - #endif - - var/icon/sprite - - if(istype(D,/atom)) - var/atom/AT = D - if(AT.icon && AT.icon_state) - sprite = new /icon(AT.icon, AT.icon_state) - usr << browse_rsc(sprite, "view_vars_sprite.png") - - title = "[D] (\ref[D]) = [D.type]" - - body += {" "} - - body += "" - - body += "
" - - if(sprite) - body += "" - - body += "
" - else - body += "
" - - body += "
" - - if(istype(D,/atom)) - var/atom/A = D - if(isliving(A)) - body += "[D]" - if(A.dir) - body += "
<< [dir2text(A.dir)] >>" - var/mob/living/M = A - body += "
[M.ckey ? M.ckey : "No ckey"] / [M.real_name ? M.real_name : "No real name"]" - body += {" -
- BRUTE:[M.getBruteLoss()] - FIRE:[M.getFireLoss()] - TOXIN:[M.getToxLoss()] - OXY:[M.getOxyLoss()] - CLONE:[M.getCloneLoss()] - BRAIN:[M.getBrainLoss()] - - - - "} - else - body += "[D]" - if(A.dir) - body += "
<< [dir2text(A.dir)] >>" - else - body += "[D]" - - body += "
" - - body += "
" - - var/formatted_type = text("[D.type]") - if(length(formatted_type) > 25) - var/middle_point = length(formatted_type) / 2 - var/splitpoint = findtext(formatted_type,"/",middle_point) - if(splitpoint) - formatted_type = "[copytext(formatted_type,1,splitpoint)]
[copytext(formatted_type,splitpoint)]" - else - formatted_type = "Type too long" //No suitable splitpoint (/) found. - - body += "
[formatted_type]" - - if(src.holder && src.holder.marked_datum && src.holder.marked_datum == D) - body += "
Marked Object" - - body += "
" - - body += "
Refresh" - - //if(ismob(D)) - // body += "
Show player panel

" - - body += {"
-
" - - body += "

" - - body += "E - Edit, tries to determine the variable type by itself.
" - body += "C - Change, asks you for the var type first.
" - body += "M - Mass modify: changes this variable for all objects of this type.

" - - body += "
Search:

" - - body += "
    " - - var/list/names = list() - for (var/V in D.vars) - names += V - - names = sortList(names) - - for (var/V in names) - body += debug_variable(V, D.vars[V], 0, D) - - body += "
" - - var/html = "" - if (title) - html += "[title]" - html += {""} - html += "" - html += body - - html += {" - - "} - - html += "" - - usr << browse(html, "window=variables\ref[D];size=475x650") - + if(!usr.client || !usr.client.holder) + usr << "\red You need to be an administrator to access this." return - proc/debug_variable(name, value, level, var/datum/DA = null) - var/html = "" - if(DA) - html += "
  • (E) (C) (M) " + var/title = "" + var/body = "" + + if(!D) return + if(istype(D, /atom)) + var/atom/A = D + title = "[A.name] (\ref[A]) = [A.type]" + + #ifdef VARSICON + if (A.icon) + body += debug_variable("icon", new/icon(A.icon, A.icon_state, A.dir), 0) + #endif + + var/icon/sprite + + if(istype(D,/atom)) + var/atom/AT = D + if(AT.icon && AT.icon_state) + sprite = new /icon(AT.icon, AT.icon_state) + usr << browse_rsc(sprite, "view_vars_sprite.png") + + title = "[D] (\ref[D]) = [D.type]" + + body += {" "} + + body += "" + + body += "
    " + + if(sprite) + body += "" + + body += "
    " + else + body += "
    " + + body += "
    " + + if(istype(D,/atom)) + var/atom/A = D + if(isliving(A)) + body += "[D]" + if(A.dir) + body += "
    << [dir2text(A.dir)] >>" + var/mob/living/M = A + body += "
    [M.ckey ? M.ckey : "No ckey"] / [M.real_name ? M.real_name : "No real name"]" + body += {" +
    + BRUTE:[M.getBruteLoss()] + FIRE:[M.getFireLoss()] + TOXIN:[M.getToxLoss()] + OXY:[M.getOxyLoss()] + CLONE:[M.getCloneLoss()] + BRAIN:[M.getBrainLoss()] + + + + "} else - html += "
  • " + body += "[D]" + if(A.dir) + body += "
    << [dir2text(A.dir)] >>" + else + body += "[D]" - if (isnull(value)) - html += "[name] = null" + body += "
  • " - else if (istext(value)) - html += "[name] = \"[value]\"" + body += "
    " - else if (isicon(value)) - #ifdef VARSICON - var/icon/I = new/icon(value) - var/rnd = rand(1,10000) - var/rname = "tmp\ref[I][rnd].png" - usr << browse_rsc(I, rname) - html += "[name] = ([value]) " - #else - html += "[name] = /icon ([value])" - #endif + var/formatted_type = text("[D.type]") + if(length(formatted_type) > 25) + var/middle_point = length(formatted_type) / 2 + var/splitpoint = findtext(formatted_type,"/",middle_point) + if(splitpoint) + formatted_type = "[copytext(formatted_type,1,splitpoint)]
    [copytext(formatted_type,splitpoint)]" + else + formatted_type = "Type too long" //No suitable splitpoint (/) found. + + body += "
    [formatted_type]" + + if(src.holder && src.holder.marked_datum && src.holder.marked_datum == D) + body += "
    Marked Object" + + body += "
    " + + body += "
    Refresh" + + //if(ismob(D)) + // body += "
    Show player panel

    " + + body += {"
    +
    " + + body += "

    " + + body += "E - Edit, tries to determine the variable type by itself.
    " + body += "C - Change, asks you for the var type first.
    " + body += "M - Mass modify: changes this variable for all objects of this type.

    " + + body += "
    Search:

    " + + body += "
      " + + var/list/names = list() + for (var/V in D.vars) + names += V + + names = sortList(names) + + for (var/V in names) + body += debug_variable(V, D.vars[V], 0, D) + + body += "
    " + + var/html = "" + if (title) + html += "[title]" + html += {""} + html += "" + html += body + + html += {" + + "} + + html += "" + + usr << browse(html, "window=variables\ref[D];size=475x650") + + return + +/client/proc/debug_variable(name, value, level, var/datum/DA = null) + var/html = "" + + if(DA) + html += "
  • (E) (C) (M) " + else + html += "
  • " + + if (isnull(value)) + html += "[name] = null" + + else if (istext(value)) + html += "[name] = \"[value]\"" + + else if (isicon(value)) + #ifdef VARSICON + var/icon/I = new/icon(value) + var/rnd = rand(1,10000) + var/rname = "tmp\ref[I][rnd].png" + usr << browse_rsc(I, rname) + html += "[name] = ([value]) " + #else + html += "[name] = /icon ([value])" + #endif /* else if (istype(value, /image)) - #ifdef VARSICON - var/rnd = rand(1, 10000) - var/image/I = value + #ifdef VARSICON + var/rnd = rand(1, 10000) + var/image/I = value - src << browse_rsc(I.icon, "tmp\ref[value][rnd].png") - html += "[name] = " - #else - html += "[name] = /image ([value])" - #endif + src << browse_rsc(I.icon, "tmp\ref[value][rnd].png") + html += "[name] = " + #else + html += "[name] = /image ([value])" + #endif */ - else if (isfile(value)) - html += "[name] = '[value]'" + else if (isfile(value)) + html += "[name] = '[value]'" - else if (istype(value, /datum)) - var/datum/D = value - html += "[name] \ref[value] = [D.type]" + else if (istype(value, /datum)) + var/datum/D = value + html += "[name] \ref[value] = [D.type]" - else if (istype(value, /client)) - var/client/C = value - html += "[name] \ref[value] = [C] [C.type]" - // - else if (istype(value, /list)) - var/list/L = value - html += "[name] = /list ([L.len])" + else if (istype(value, /client)) + var/client/C = value + html += "[name] \ref[value] = [C] [C.type]" +// + else if (istype(value, /list)) + var/list/L = value + html += "[name] = /list ([L.len])" - if (L.len > 0 && !(name == "underlays" || name == "overlays" || name == "vars" || L.len > 500)) - // not sure if this is completely right... - if(0) //(L.vars.len > 0) - html += "
      " - html += "
    " - else - html += "" + if (L.len > 0 && !(name == "underlays" || name == "overlays" || name == "vars" || L.len > 500)) + // not sure if this is completely right... + if(0) //(L.vars.len > 0) + html += "
      " + html += "
    " + else + html += "" - else - html += "[name] = [value]" - /* - // Bitfield stuff - if(round(value)==value) // Require integers. - var/idx=0 - var/bit=0 - var/bv=0 - html += "
    " - for(var/block=0;block<8;block++) - html += " " - for(var/i=0;i<4;i++) - idx=(block*4)+i - bit=1 << idx - bv=value & bit - html += "[bv?1:0]" - html += "" - html += "
    " - */ - html += "
  • " + else + html += "[name] = [value]" + /* + // Bitfield stuff + if(round(value)==value) // Require integers. + var/idx=0 + var/bit=0 + var/bv=0 + html += "
    " + for(var/block=0;block<8;block++) + html += " " + for(var/i=0;i<4;i++) + idx=(block*4)+i + bit=1 << idx + bv=value & bit + html += "[bv?1:0]" + html += "" + html += "
    " + */ + html += "" - return html + return html /client/proc/view_var_Topic(href, href_list, hsrc) //This should all be moved over to datum/admins/Topic() or something ~Carn @@ -450,7 +448,7 @@ client if( !new_name || !M ) return message_admins("Admin [key_name_admin(usr)] renamed [key_name_admin(M)] to [new_name].") - M.fully_replace_character_name(M.real_name,new_name) + M.rename_character(M.real_name, new_name) href_list["datumrefresh"] = href_list["rename"] else if(href_list["varnameedit"] && href_list["datumedit"]) @@ -993,8 +991,8 @@ client if(locate(new_organ) in M.internal_organs) usr << "Mob already has that organ." return - - new new_organ(M) + var/obj/item/organ/internal/organ = new new_organ + organ.insert(M) message_admins("[key_name_admin(usr)] has given [key_name_admin(M)] the organ [new_organ]") log_admin("[key_name(usr)] has given [key_name(M)] the organ [new_organ]") @@ -1006,7 +1004,7 @@ client usr << "This can only be done to instances of type /mob/living/carbon" return - var/obj/item/organ/rem_organ = input("Please choose an organ to remove.","Organ",null) as null|anything in M.internal_organs + var/obj/item/organ/internal/rem_organ = input("Please choose an organ to remove.","Organ",null) as null|anything in M.internal_organs if(!M) usr << "Mob doesn't exist anymore" @@ -1017,7 +1015,7 @@ client return usr << "Removed [rem_organ] from [M]." - rem_organ.removed() + rem_organ.remove(M) message_admins("[key_name_admin(usr)] has removed the organ [rem_organ] from [key_name_admin(M)]") log_admin("[key_name(usr)] has removed the organ [rem_organ] from [key_name(M)]") qdel(rem_organ) diff --git a/code/datums/hud.dm b/code/datums/hud.dm index e01ceb3e295..70a97f648f8 100644 --- a/code/datums/hud.dm +++ b/code/datums/hud.dm @@ -24,8 +24,8 @@ var/datum/atom_hud/huds = list( \ /datum/atom_hud/proc/remove_hud_from(mob/M) if(!M) return - //if(src in M.permanent_huds)//I will deal with you later -Fethas - // return + if(src in M.permanent_huds)//I will deal with you later -Fethas + return for(var/atom/A in hudatoms) remove_from_single_hud(M, A) hudusers -= M diff --git a/code/datums/martial.dm b/code/datums/martial.dm index bfd5a3b6757..1d730315707 100644 --- a/code/datums/martial.dm +++ b/code/datums/martial.dm @@ -5,6 +5,8 @@ var/current_target = null var/temporary = 0 var/datum/martial_art/base = null // The permanent style + var/deflection_chance = 0 //Chance to deflect projectiles + var/help_verb = null /datum/martial_art/proc/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) return 0 @@ -25,29 +27,32 @@ return /datum/martial_art/proc/basic_hit(var/mob/living/carbon/human/A,var/mob/living/carbon/human/D) - add_logs(D, A, "punched") - A.do_attack_animation(D) - var/damage = rand(0,9) - var/atk_verb = "punch" + A.do_attack_animation(D) + var/damage = rand(A.species.punchdamagelow, A.species.punchdamagehigh) + var/datum/unarmed_attack/attack = A.species.unarmed + + var/atk_verb = "[pick(attack.attack_verb)]" if(D.lying) atk_verb = "kick" if(!damage) - playsound(D.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + playsound(D.loc, attack.miss_sound, 25, 1, -1) D.visible_message("[A] has attempted to [atk_verb] [D]!") return 0 var/obj/item/organ/external/affecting = D.get_organ(ran_zone(A.zone_sel.selecting)) var/armor_block = D.run_armor_check(affecting, "melee") - playsound(D.loc, 'sound/weapons/punch1.ogg', 25, 1, -1) - + playsound(D.loc, attack.attack_sound, 25, 1, -1) D.visible_message("[A] has [atk_verb]ed [D]!", \ "[A] has [atk_verb]ed [D]!") D.apply_damage(damage, BRUTE, affecting, armor_block) - if((D.stat != DEAD) && damage >= 9) + + add_logs(D, A, "punched") + + if((D.stat != DEAD) && damage >= A.species.punchstunthreshold) D.visible_message("[A] has weakened [D]!!", \ "[A] has weakened [D]!") D.apply_effect(4, WEAKEN, armor_block) @@ -57,6 +62,8 @@ return 1 /datum/martial_art/proc/teach(var/mob/living/carbon/human/H,var/make_temporary=0) + if(help_verb) + H.verbs += help_verb if(make_temporary) temporary = 1 if(H.martial_art && H.martial_art.temporary) @@ -71,30 +78,31 @@ if(H.martial_art != src) return H.martial_art = base - + if(help_verb) + H.verbs -= help_verb /datum/martial_art/boxing name = "Boxing" /datum/martial_art/boxing/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - A << " Can't disarm while boxing!" + A << "Can't disarm while boxing!" return 1 /datum/martial_art/boxing/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - A << " Can't grab while boxing!" + A << "Can't grab while boxing!" return 1 /datum/martial_art/boxing/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_logs(D, A, "punched") + A.do_attack_animation(D) var/atk_verb = pick("left hook","right hook","straight punch") - var/damage = rand(5,8) - + var/damage = rand(5, 8) + A.species.punchdamagelow if(!damage) playsound(D.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) D.visible_message("[A] has attempted to hit [D] with a [atk_verb]!") + add_logs(D, A, "attempted to hit", atk_verb) return 0 @@ -103,11 +111,11 @@ playsound(D.loc, 'sound/weapons/punch1.ogg', 25, 1, -1) - D.visible_message("[A] has hit [D] with a [atk_verb]!", \ "[A] has hit [D] with a [atk_verb]!") D.apply_damage(damage, STAMINA, affecting, armor_block) + add_logs(D, A, "punched") if(D.getStaminaLoss() > 50) var/knockout_prob = D.getStaminaLoss() + rand(-15,15) if((D.stat != DEAD) && prob(knockout_prob)) @@ -182,6 +190,12 @@ /datum/martial_art/wrestling name = "Wrestling" + help_verb = /mob/living/carbon/human/proc/wrestling_help + +// combo refence since wrestling uses a different format to sleeping carp and plasma fist. +// Clinch "G" +// Suplex "GD" +// Advanced grab "G" /datum/martial_art/wrestling/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) D.grabbedby(A,1) @@ -197,13 +211,15 @@ /datum/martial_art/wrestling/proc/Suplex(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_logs(D, A, "suplexed") + D.visible_message("[A] suplexes [D]!", \ "[A] suplexes [D]!") D.forceMove(A.loc) var/armor_block = D.run_armor_check(null, "melee") D.apply_damage(30, BRUTE, null, armor_block) D.apply_effect(6, WEAKEN, armor_block) + add_logs(D, A, "suplexed") + A.SpinAnimation(10,1) D.SpinAnimation(10,1) @@ -230,12 +246,24 @@ D.apply_damage(10, STAMINA, affecting, armor_block) return 1 +/mob/living/carbon/human/proc/wrestling_help() + set name = "Recall Teachings" + set desc = "Remember how to wrestle." + set category = "Wrestling" + + usr << "You flex your muscles and have a revelation..." + usr << "Clinch: Grab. Passively gives you a chance to immediately aggressively grab someone. Not always successful." + usr << "Suplex: Disarm someone you are grabbing. Suplexes your target to the floor. Greatly injures them and leaves both you and your target on the floor." + usr << "Advanced grab: Grab. Passively causes stamina damage when grabbing someone." + #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)) @@ -271,7 +299,7 @@ "[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) + D.throw_at(throw_target, 200, 4,A) A.say("HYAH!") return @@ -285,26 +313,37 @@ return /datum/martial_art/plasma_fist/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("H") + add_to_streak("H",D) if(check_streak(A,D)) return 1 basic_hit(A,D) return 1 /datum/martial_art/plasma_fist/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("D") + add_to_streak("D",D) if(check_streak(A,D)) return 1 basic_hit(A,D) return 1 /datum/martial_art/plasma_fist/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("G") + add_to_streak("G",D) if(check_streak(A,D)) return 1 basic_hit(A,D) return 1 +/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" + + usr << "You clench your fists and have a flashback of knowledge..." + usr << "Tornado Sweep: Harm Harm Disarm. Repulses target and everyone back." + usr << "Throwback: Disarm Harm Disarm. Throws the target and an item at them." + usr << "The Plasma Fist: Harm Disarm Disarm Disarm Harm. Knocks the brain out of the opponent and gibs their body." + +//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" @@ -312,6 +351,8 @@ #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 /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)) @@ -344,7 +385,7 @@ D.emote("scream") D.drop_item() D.apply_damage(5, BRUTE, pick("l_arm", "r_arm")) - D.Stun(1) + D.Stun(3) return 1 return basic_hit(A,D) @@ -375,7 +416,8 @@ "[A] kicks you in the jaw!") D.apply_damage(20, BRUTE, "head") D.drop_item() - playsound(get_turf(D), 'sound/weapons/punch1.ogg', 75, 1, -1) + playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1) + D.Stun(4) return 1 return basic_hit(A,D) @@ -386,32 +428,36 @@ if(D.stat) D.death() //FINISH HIM! D.apply_damage(50, BRUTE, "chest") - playsound(get_turf(D), 'sound/weapons/punch1.ogg', 100, 1, -1) + playsound(get_turf(D), 'sound/weapons/punch1.ogg', 75, 1, -1) return 1 return basic_hit(A,D) /datum/martial_art/the_sleeping_carp/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("G") + add_to_streak("G",D) if(check_streak(A,D)) return 1 - ..() + D.grabbedby(A,1) var/obj/item/weapon/grab/G = A.get_active_hand() if(G) G.state = GRAB_AGGRESSIVE //Instant aggressive grab -/datum/martial_art/the_sleeping_carp/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("H") +/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 - D.visible_message("[A] [pick("punches", "kicks", "chops", "hits", "slams")] [D]!", \ - "[A] hits you!") - D.apply_damage(10, BRUTE) - playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1) + var/atk_verb = pick("punches", "kicks", "chops", "hits", "slams") + D.visible_message("[A] [atk_verb] [D]!", \ + "[A] [atk_verb] you!") + D.apply_damage(rand(10,15), BRUTE) + playsound(get_turf(D), 'sound/weapons/punch1.ogg', 25, 1, -1) + 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") + add_to_streak("D",D) if(check_streak(A,D)) return 1 return ..() @@ -422,6 +468,7 @@ set category = "Sleeping Carp" usr << "You retreat inward and recall the teachings of the Sleeping Carp..." + usr << "Wrist Wrench: Disarm Disarm. Forces opponent to drop item in hand." usr << "Back Kick: Harm Grab. Opponent must be facing away. Knocks down." usr << "Stomach Knee: Grab Harm. Knocks the wind out of opponent and stuns." @@ -459,6 +506,7 @@ if(slot == slot_belt) var/mob/living/carbon/human/H = user style.teach(H,1) + user << "You have an urge to flex your muscles and get into a fight. You have the knowledge of a thousand wrestlers before you. You can remember more by using the Recall teaching verb in the wrestling tab." return /obj/item/weapon/storage/belt/champion/wrestling/dropped(mob/user) @@ -467,11 +515,12 @@ var/mob/living/carbon/human/H = user if(H.get_item_by_slot(slot_belt) == src) style.remove(H) + user << "You no longer have an urge to flex your muscles." return /obj/item/weapon/plasma_fist_scroll - name = "Plasma Fist Scroll" - desc = "Teaches the traditional wizard martial art." + name = "frayed scroll" + desc = "An aged and frayed scrap of paper written in shifting runes. There are hand-drawn illustrations of pugilism." icon = 'icons/obj/wizard.dmi' icon_state ="scroll2" var/used = 0 @@ -483,9 +532,11 @@ var/mob/living/carbon/human/H = user var/datum/martial_art/plasma_fist/F = new/datum/martial_art/plasma_fist(null) F.teach(H) - H << "You learn the PLASMA FIST style." + H << "You have learned the ancient martial art of Plasma Fist." used = 1 - desc += "It looks like it's magic was used up." + desc = "It's completely blank." + name = "empty scroll" + icon_state = "blankscroll" /obj/item/weapon/sleeping_carp_scroll name = "mysterious scroll" @@ -496,11 +547,8 @@ /obj/item/weapon/sleeping_carp_scroll/attack_self(mob/living/carbon/human/user as mob) if(!istype(user) || !user) return - user << "You begin to read the scroll..." - user << "And all at once the secrets of the Sleeping Carp fill your mind. The ancient clan's martial teachings have been imbued into this scroll. As you read through it, \ - these secrets flood into your mind and body. You now know the martial techniques of the Sleeping Carp. Your hand-to-hand combat has become much more effective, and you may now perform powerful \ - combination attacks. To learn more about these combos, use the Recall Teachings ability in the Sleeping Carp tab." - user.verbs += /mob/living/carbon/human/proc/sleeping_carp_help + user << "You have learned the ancient martial art of the Sleeping Carp! Your hand-to-hand combat has become much more effective, and you are now able to deflect any projectiles \ + directed toward you. However, you are also unable to use any ranged weaponry. You can learn more about your newfound art by using the Recall Teachings verb in the Sleeping Carp tab." var/datum/martial_art/the_sleeping_carp/theSleepingCarp = new(null) theSleepingCarp.teach(user) user.drop_item() @@ -508,16 +556,16 @@ new /obj/effect/decal/cleanable/ash(get_turf(src)) qdel(src) - /obj/item/weapon/twohanded/bostaff name = "bo staff" desc = "A long, tall staff made of polished wood. Traditionally used in ancient old-Earth martial arts. Can be wielded to both kill and incapacitate." - force = 8 + force = 10 w_class = 4 slot_flags = SLOT_BACK - force_unwielded = 8 - force_wielded = 18 + force_unwielded = 10 + force_wielded = 24 throwforce = 20 + throw_speed = 2 attack_verb = list("smashed", "slammed", "whacked", "thwacked") icon = 'icons/obj/weapons.dmi' icon_state = "bostaff0" @@ -572,7 +620,7 @@ if(total_health <= config.health_threshold_crit && !H.stat) H.visible_message("[user] delivers a heavy hit to [H]'s head, knocking them out cold!", \ "[user] knocks you unconscious!") - H.sleeping += 30 + H.SetSleeping(30) H.adjustBrainLoss(25) return else diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 6287bd5a1d7..56d8fac2d57 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -53,6 +53,7 @@ var/has_been_rev = 0//Tracks if this mind has been a rev or not + var/miming = 0 // Mime's vow of silence var/datum/faction/faction //associated faction var/datum/changeling/changeling //changeling holder var/datum/vampire/vampire //vampire holder diff --git a/code/datums/spell.dm b/code/datums/spell.dm index 236b7c8e9b1..f129f085bdc 100644 --- a/code/datums/spell.dm +++ b/code/datums/spell.dm @@ -19,6 +19,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin var/charge_max = 100 //recharge time in deciseconds if charge_type = "recharge" or starting charges if charge_type = "charges" var/charge_counter = 0 //can only cast spells if it equals recharge, ++ each decisecond if charge_type = "recharge" or -- each cast if charge_type = "charges" + var/still_recharging_msg = "The spell is still recharging." var/holder_var_type = "bruteloss" //only used if charge_type equals to "holder_var" var/holder_var_amount = 20 //same. The amount adjusted with the mob's var when the spell is used @@ -27,6 +28,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin var/clothes_req = 1 //see if it requires clothes var/stat_allowed = 0 //see if it requires being conscious/alive, need to set to 1 for ghostpells var/invocation = "HURP DURP" //what is uttered when the wizard casts the spell + var/invocation_emote_self = null var/invocation_type = "none" //can be none, whisper and shout var/range = 7 //the range of the spell; outer radius for aoe spells var/message = "" //whatever it says to the guy affected by it @@ -74,7 +76,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin switch(charge_type) if("recharge") if(charge_counter < charge_max) - user << "[name] is still recharging." + user << still_recharging_msg return 0 if("charges") if(!charge_counter) @@ -128,10 +130,13 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin user.whisper(invocation) else user.whisper(replacetext(invocation," ","`")) + if("emote") + user.visible_message(invocation, invocation_emote_self) //same style as in mob/living/emote.dm /obj/effect/proc_holder/spell/New() ..() + still_recharging_msg = "[name] is still recharging." charge_counter = charge_max /obj/effect/proc_holder/spell/Destroy() diff --git a/code/datums/spells/fake_gib.dm b/code/datums/spells/fake_gib.dm index 5b8dc339c8e..23d2343e10e 100644 --- a/code/datums/spells/fake_gib.dm +++ b/code/datums/spells/fake_gib.dm @@ -1,17 +1,11 @@ -/obj/effect/proc_holder/spell/targeted/fake_gib +/obj/effect/proc_holder/spell/targeted/touch/fake_disintegrate name = "Disintegrate" - desc = "This spell instantly kills somebody adjacent to you with the vilest of magick." + desc = "This spell charges your hand with vile energy that can be used to violently explode victims." + hand_path = "/obj/item/weapon/melee/touch_attack/fake_disintegrate" - school = "conjuration" - charge_max = 20 + school = "evocation" + charge_max = 600 clothes_req = 0 - invocation = "EI NATH" - invocation_type = "shout" - range = -1 - include_user = 1 - cooldown_min = 5 //25 deciseconds reduction per rank + cooldown_min = 200 //100 deciseconds reduction per rank - sparks_spread = 3 - sparks_amt = 1 - - action_icon_state = "spell_disintegrate" \ No newline at end of file + action_icon_state = "gib" \ No newline at end of file diff --git a/code/datums/spells/horsemask.dm b/code/datums/spells/horsemask.dm index 99e7b0c8a0d..2c31c943284 100644 --- a/code/datums/spells/horsemask.dm +++ b/code/datums/spells/horsemask.dm @@ -14,7 +14,7 @@ selection_type = "range" var/list/compatible_mobs = list(/mob/living/carbon/human) - action_icon_state = "spell_horse" + action_icon_state = "barn" /obj/effect/proc_holder/spell/targeted/horsemask/cast(list/targets, mob/user = usr) if(!targets.len) diff --git a/code/datums/spells/inflict_handler.dm b/code/datums/spells/inflict_handler.dm index 7e8eb6b1641..435909e3abe 100644 --- a/code/datums/spells/inflict_handler.dm +++ b/code/datums/spells/inflict_handler.dm @@ -25,13 +25,6 @@ switch(destroys) if("gib") target.gib() - if("gib_brain") - if(ishuman(target)) - var/mob/living/carbon/C = target - if(C.brain_op_stage != 4) // Their brain is already taken out - var/obj/item/organ/brain/B = new(C.loc) - B.transfer_identity(C) - target.gib() if("disintegrate") target.dust() diff --git a/code/datums/spells/mime.dm b/code/datums/spells/mime.dm new file mode 100644 index 00000000000..5e5ddb91db2 --- /dev/null +++ b/code/datums/spells/mime.dm @@ -0,0 +1,59 @@ +/obj/effect/proc_holder/spell/aoe_turf/conjure/mime_wall + name = "Invisible wall" + desc = "The mime's performance transmutates into physical reality." + school = "mime" + panel = "Mime" + summon_type = list(/obj/effect/forcefield/mime) + invocation_type = "emote" + invocation_emote_self = "You form a wall in front of yourself." + summon_lifespan = 300 + charge_max = 300 + clothes_req = 0 + range = 0 + + action_icon_state = "mime" + action_background_icon_state = "bg_mime" + +/obj/effect/proc_holder/spell/aoe_turf/conjure/mime_wall/Click() + if(usr && usr.mind) + if(!usr.mind.miming) + usr << "You must dedicate yourself to silence first." + return + invocation = "[usr.real_name] looks as if a wall is in front of them." + else + invocation_type ="none" + ..() + + +/obj/effect/proc_holder/spell/targeted/mime/speak + name = "Speech" + desc = "Make or break a vow of silence." + school = "mime" + panel = "Mime" + clothes_req = 0 + charge_max = 3000 + range = -1 + include_user = 1 + + action_icon_state = "mime" + action_background_icon_state = "bg_mime" + +/obj/effect/proc_holder/spell/targeted/mime/speak/Click() + if(!usr) + return + if(!ishuman(usr)) + return + var/mob/living/carbon/human/H = usr + if(H.mind.miming) + still_recharging_msg = "You can't break your vow of silence that fast!" + else + still_recharging_msg = "You'll have to wait before you can give your vow of silence again!" + ..() + +/obj/effect/proc_holder/spell/targeted/mime/speak/cast(list/targets,mob/user = usr) + for(var/mob/living/carbon/human/H in targets) + H.mind.miming=!H.mind.miming + if(H.mind.miming) + H << "You make a vow of silence." + else + H << "You break your vow of silence." \ No newline at end of file diff --git a/code/datums/spells/mind_transfer.dm b/code/datums/spells/mind_transfer.dm index 90b6f25ab4d..6d7b0539fb1 100644 --- a/code/datums/spells/mind_transfer.dm +++ b/code/datums/spells/mind_transfer.dm @@ -42,6 +42,10 @@ Also, you never added distance checking after target is selected. I've went ahea user << "They appear to be catatonic. Not even magic can affect their vacant mind." return + if(user.suiciding) + user << "You're killing yourself! You can't concentrate enough to do this!" + return + if(target.mind.special_role in protected_roles) user << "Their mind is resisting your spell." return diff --git a/code/datums/spells/summonitem.dm b/code/datums/spells/summonitem.dm index e813ec0ffda..4a12b4bb9f9 100644 --- a/code/datums/spells/summonitem.dm +++ b/code/datums/spells/summonitem.dm @@ -24,7 +24,7 @@ if(!marked_item) //linking item to the spell message = "" for(var/obj/item in hand_items) - if(istype(item, /obj/item/organ/brain)) //Yeah, sadly this doesn't work due to the organ system. + if(istype(item, /obj/item/organ/internal/brain)) //Yeah, sadly this doesn't work due to the organ system. break marked_item = item message += "You mark [item] for recall." diff --git a/code/datums/spells/wizard.dm b/code/datums/spells/wizard.dm index 904b7d54e63..98423b3e5fc 100644 --- a/code/datums/spells/wizard.dm +++ b/code/datums/spells/wizard.dm @@ -85,8 +85,6 @@ emp_heavy = 6 emp_light = 10 - action_icon_state = "tech" - /obj/effect/proc_holder/spell/targeted/turf_teleport/blink name = "Blink" desc = "This spell randomly teleports you a short distance." @@ -144,7 +142,7 @@ summon_type = list("/obj/effect/forcefield") summon_lifespan = 300 - action_icon_state = "spell_forcewall" + action_icon_state = "shield" /obj/effect/proc_holder/spell/aoe_turf/conjure/timestop name = "Stop Time" diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm index 3523a69bf9c..b9311f76992 100644 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -524,6 +524,27 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine cost = 10 containername = "singularity generator crate" +/datum/supply_packs/engineering/engine/tesla + name = "Energy Ball Generator Crate" + contains = list(/obj/machinery/the_singularitygen/tesla) + cost = 10 + containername = "energy ball generator crate" + +/datum/supply_packs/engineering/engine/coil + name = "Tesla Coil Crate" + contains = list(/obj/machinery/power/tesla_coil, + /obj/machinery/power/tesla_coil, + /obj/machinery/power/tesla_coil) + cost = 10 + containername = "tesla coil crate" + +/datum/supply_packs/engineering/engine/grounding + name = "Grounding Rod Crate" + contains = list(/obj/machinery/power/grounding_rod, + /obj/machinery/power/grounding_rod) + cost = 10 + containername = "grounding rod crate" + /datum/supply_packs/engineering/engine/collector name = "Collector Crate" contains = list(/obj/machinery/power/rad_collector, diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index 16d00449a55..2e25e2fd816 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -191,7 +191,7 @@ var/list/uplink_items = list() /datum/uplink_item/jobspecific/pickpocketgloves name = "Pickpocket's Gloves" - desc = "A pair of sleek gloves to aid in pickpocketing, while wearing these you can see inside the pockets of any unsuspecting mark, loot the ID or pockets without them knowing, and pickpocketing puts the item directly into your hand." + desc = "A pair of sleek gloves to aid in pickpocketing. While wearing these, you can loot your target without them knowing. Pickpocketing puts the item directly into your hand." reference = "PG" item = /obj/item/clothing/gloves/color/black/thief cost = 6 @@ -365,11 +365,12 @@ var/list/uplink_items = list() surplus = 0 /datum/uplink_item/dangerous/emp - name = "EMP Kit" - desc = "A box that contains two EMP grenades, an EMP implant and a short ranged recharging device disguised as a flashlight. Useful to disrupt communication and silicon lifeforms." - reference = "EMP" + name = "EMP Grenades and Implanter Kit" + desc = "A box that contains two EMP grenades and an EMP implant. Useful to disrupt communication, \ + security's energy weapons, and silicon lifeforms when you're in a tight spot." + reference = "EMPK" item = /obj/item/weapon/storage/box/syndie_kit/emp - cost = 5 + cost = 2 /datum/uplink_item/dangerous/syndicate_minibomb name = "Syndicate Minibomb" @@ -517,6 +518,15 @@ var/list/uplink_items = list() /datum/uplink_item/stealthy_weapons category = "Stealthy and Inconspicuous Weapons" +/datum/uplink_item/stealthy_weapons/martialarts + name = "Martial Arts Scroll" + desc = "This scroll contains the secrets of an ancient martial arts technique. You will master unarmed combat, \ + deflecting all ranged weapon fire, but you also refuse to use dishonorable ranged weaponry." + reference = "SCS" + item = /obj/item/weapon/sleeping_carp_scroll + cost = 17 + excludefrom = list(/datum/game_mode/nuclear) + /datum/uplink_item/stealthy_weapons/edagger name = "Energy Dagger" desc = "A dagger made of energy that looks and functions as a pen when off." @@ -658,6 +668,15 @@ var/list/uplink_items = list() cost = 2 surplus = 30 +/datum/uplink_item/stealthy_tools/emplight + name = "EMP Flashlight" + desc = "A small, self-charging, short-ranged EMP device disguised as a flashlight. \ + Useful for disrupting headsets, cameras, and borgs during stealth operations." + reference = "EMPL" + item = /obj/item/device/flashlight/emp + cost = 2 + surplus = 30 + // DEVICE AND TOOLS /datum/uplink_item/device_tools diff --git a/code/defines/procs/announce.dm b/code/defines/procs/announce.dm index 0267bd88d98..7993badfb0e 100644 --- a/code/defines/procs/announce.dm +++ b/code/defines/procs/announce.dm @@ -51,7 +51,7 @@ var/tmp/message_sound = new_sound ? sound(new_sound) : sound if(!msg_sanitized) - message = trim_strip_html_properly(message) + message = trim_strip_html_properly(message, allow_lines = 1) message_title = html_encode(message_title) Message(message, message_title, from) diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index 0234fb2c076..941cd2cdd64 100644 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -17,7 +17,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area var/fire = null - var/atmos = 1 var/atmosalm = 0 var/poweralm = 1 var/party = null @@ -2402,12 +2401,17 @@ area/security/podbay /area/awaymission/beach name = "Beach" - icon_state = "null" + icon_state = "beach" luminosity = 1 lighting_use_dynamic = 0 requires_power = 0 ambientsounds = list('sound/ambience/shore.ogg', 'sound/ambience/seag1.ogg','sound/ambience/seag2.ogg','sound/ambience/seag2.ogg') +/area/awaymission/undersea + name = "Undersea" + icon_state = "undersea" + + ////////////////////////AWAY AREAS/////////////////////////////////// /area/awaycontent @@ -2576,62 +2580,3 @@ var/list/the_station_areas = list ( /area/turret_protected/ai, ) - - - -/area/beach - name = "Keelin's private beach" - icon_state = "null" - luminosity = 1 - lighting_use_dynamic = 0 - requires_power = 0 - var/sound/mysound = null - - New() - ..() - var/sound/S = new/sound() - mysound = S - S.file = 'sound/ambience/shore.ogg' - S.repeat = 1 - S.wait = 0 - S.channel = 123 - S.volume = 100 - S.priority = 255 - S.status = SOUND_UPDATE - process() - - Entered(atom/movable/Obj,atom/OldLoc) - if(ismob(Obj)) - if(Obj:client) - mysound.status = SOUND_UPDATE - Obj << mysound - return - - Exited(atom/movable/Obj) - if(ismob(Obj)) - if(Obj:client) - mysound.status = SOUND_PAUSED | SOUND_UPDATE - Obj << mysound - - proc/process() - //set background = 1 - - var/sound/S = null - var/sound_delay = 0 - if(prob(25)) - S = sound(file=pick('sound/ambience/seag1.ogg','sound/ambience/seag2.ogg','sound/ambience/seag3.ogg'), volume=100) - sound_delay = rand(0, 50) - - for(var/mob/living/carbon/human/H in src) -// if(H.s_tone > -55) //ugh...nice/novel idea but please no. -// H.s_tone-- -// H.update_body() - if(H.client) - mysound.status = SOUND_UPDATE - H << mysound - if(S) - spawn(sound_delay) - H << S - - spawn(60) .() - diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 4647eeec6ba..9dc2918dd8f 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -354,18 +354,12 @@ return if((istype(M,/mob/living/carbon/human/)) && (M.m_intent == "run")). - //M.AdjustStunned(5) - //M.AdjustWeakened(5) - - if(M.stunned <= 5) M.stunned = 5 - if(M.weakened <= 5) M.weakened = 5 + M.Stun(5) + M.Weaken(5) else if (istype(M,/mob/living/carbon/human/)) - //M.AdjustStunned(2) - //M.AdjustWeakened(2) - - if(M.stunned <= 2) M.stunned = 2 - if(M.weakened <= 2) M.weakened = 2 + M.Stun(2) + M.Weaken(2) M << "Gravity!" diff --git a/code/game/asteroid.dm b/code/game/asteroid.dm index cdb0cb7de64..d38e05c701b 100644 --- a/code/game/asteroid.dm +++ b/code/game/asteroid.dm @@ -61,7 +61,7 @@ var/global/max_secret_rooms = 6 walltypes = list(/turf/simulated/wall/r_wall=2,/turf/simulated/wall=2,/turf/simulated/mineral/random/high_chance=1) floortypes = list(/turf/simulated/floor,/turf/simulated/floor/engine) treasureitems = list(/obj/machinery/bot/medbot/mysterious=1, /obj/item/weapon/circular_saw=1, /obj/structure/closet/critter/cat=2) - fluffitems = list(/obj/effect/decal/cleanable/blood=5,/obj/item/organ/appendix=2,/obj/structure/closet/crate/freezer=2, + fluffitems = list(/obj/effect/decal/cleanable/blood=5,/obj/item/organ/internal/appendix=2,/obj/structure/closet/crate/freezer=2, /obj/machinery/optable=1,/obj/item/weapon/scalpel=1,/obj/item/weapon/storage/firstaid/regular=3, /obj/item/weapon/tank/anesthetic=1, /obj/item/weapon/surgical_drapes=2, /obj/item/device/mass_spectrometer/adv=1,/obj/item/clothing/glasses/hud/health=1) @@ -72,7 +72,7 @@ var/global/max_secret_rooms = 6 treasureitems = list(/obj/item/device/soulstone=1, /obj/item/clothing/suit/space/cult=1, /obj/item/weapon/bedsheet/cult=2, /obj/item/clothing/suit/cultrobes=2, /mob/living/simple_animal/hostile/creature=3) fluffitems = list(/obj/effect/gateway=1,/obj/effect/gibspawner=1,/obj/structure/cult/talisman=1,/obj/item/toy/crayon/red=2, - /obj/item/organ/heart=2, /obj/effect/decal/cleanable/blood=4,/obj/structure/table/woodentable=2,/obj/item/weapon/ectoplasm=3, + /obj/item/organ/internal/heart=2, /obj/effect/decal/cleanable/blood=4,/obj/structure/table/woodentable=2,/obj/item/weapon/ectoplasm=3, /obj/item/clothing/head/helmet/space/cult=1, /obj/item/clothing/shoes/cult=1) if("wizden") diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index d88ce84ae37..f48fce27d2d 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -97,27 +97,25 @@ /atom/movable/Crossed(atom/movable/AM) return -/atom/movable/Bump(var/atom/A as mob|obj|turf|area, yes) +/atom/movable/Bump(var/atom/A as mob|obj|turf|area, sendBump) if(src.throwing) src.throw_impact(A) - if ((A && yes)) + if (A && sendBump) A.last_bumped = world.time A.Bumped(src) - return - ..() - return + else + ..() /atom/movable/proc/forceMove(atom/destination) + if(loc) + loc.Exited(src) + loc = destination if(destination) - if(loc) - loc.Exited(src) - loc = destination loc.Entered(src) for(var/atom/movable/AM in loc) AM.Crossed(src) - return 1 - return 0 + return 1 //called when src is thrown into hit_atom /atom/movable/proc/throw_impact(atom/hit_atom, var/speed) diff --git a/code/game/dna/dna2_domutcheck.dm b/code/game/dna/dna2_domutcheck.dm index 8bf993f43eb..9d8f68fd81a 100644 --- a/code/game/dna/dna2_domutcheck.dm +++ b/code/game/dna/dna2_domutcheck.dm @@ -38,14 +38,12 @@ gene.activate(M,connected,flags) if(M) M.active_genes |= gene.type - M.update_icon = 1 // If Gene is NOT active: else // testing("[gene.name] deactivated!") gene.deactivate(M,connected,flags) if(M) M.active_genes -= gene.type - M.update_icon = 1 */ // Use this to force a mut check on a single gene! @@ -97,11 +95,9 @@ gene.activate(M,connected,flags) if(M) M.active_genes |= gene.type - M.update_icon = 1 // If Gene is NOT active: else //testing("[gene.name] deactivated!") gene.deactivate(M,connected,flags) if(M) M.active_genes -= gene.type - M.update_icon = 1 diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm index 4aa0453a52d..781c3a1d230 100644 --- a/code/game/dna/dna2_helpers.dm +++ b/code/game/dna/dna2_helpers.dm @@ -161,9 +161,9 @@ H.s_tone = 35 - dna.GetUIValueRange(DNA_UI_SKIN_TONE, 220) // Value can be negative. if (dna.GetUIState(DNA_UI_GENDER)) - H.gender = FEMALE + H.change_gender(FEMALE, 0) else - H.gender = MALE + H.change_gender(MALE, 0) //Hair var/hair = dna.GetUIValueRange(DNA_UI_HAIR_STYLE,hair_styles_list.len) diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm index 3e3a3d4287a..570fada2073 100644 --- a/code/game/dna/dna_modifier.dm +++ b/code/game/dna/dna_modifier.dm @@ -36,6 +36,18 @@ ser["type"] = "se" return ser +/datum/dna2/record/proc/copy() + var/datum/dna2/record/newrecord = new /datum/dna2/record + newrecord.dna = dna.Clone() + newrecord.types = types + newrecord.name = name + newrecord.mind = mind + newrecord.ckey = ckey + newrecord.languages = languages + newrecord.implant = implant + return newrecord + + /////////////////////////// DNA MACHINES /obj/machinery/dna_scannernew name = "\improper DNA modifier" @@ -929,7 +941,7 @@ var/blk = input(usr,"Select Block","Block") in all_dna_blocks(selectedbuf) success = setInjectorBlock(I,blk,buf) else - I.buf = buf + I.buf = buf.copy() waiting_for_user_input=0 if(success) I.forceMove(src.loc) @@ -944,7 +956,7 @@ //src.temphtml = "Invalid disk. Please try again." return 0 - src.buffers[bufferId]=src.disk.buf + src.buffers[bufferId]=src.disk.buf.copy() //src.temphtml = "Data loaded." return 1 @@ -955,7 +967,7 @@ var/datum/dna2/record/buf = src.buffers[bufferId] - src.disk.buf = buf + src.disk.buf = buf.copy() src.disk.name = "data disk - '[buf.dna.real_name]'" //src.temphtml = "Data saved." return 1 diff --git a/code/game/dna/genes/goon_disabilities.dm b/code/game/dna/genes/goon_disabilities.dm index e5ebf16975c..04fa6d5f524 100644 --- a/code/game/dna/genes/goon_disabilities.dm +++ b/code/game/dna/genes/goon_disabilities.dm @@ -348,8 +348,7 @@ L.adjust_fire_stacks(0.5) L.visible_message("\red [L.name] suddenly bursts into flames!") - L.on_fire = 1 - L.update_icon = 1 + L.IgniteMob() playsound(L.loc, 'sound/effects/bamf.ogg', 50, 0) //////////////////////////////////////////////////////////////////////// diff --git a/code/game/dna/genes/goon_powers.dm b/code/game/dna/genes/goon_powers.dm index 300074bfa54..e0fbd6b8f0a 100644 --- a/code/game/dna/genes/goon_powers.dm +++ b/code/game/dna/genes/goon_powers.dm @@ -428,16 +428,16 @@ if (FAT in usr.mutations && prob(66)) usr.visible_message("\red [usr.name] crashes due to their heavy weight!") //playsound(usr.loc, 'zhit.wav', 50, 1) - usr.weakened += 10 - usr.stunned += 5 + usr.AdjustWeakened(10) + usr.AdjustStunned(5) usr.layer = prevLayer if (istype(usr.loc,/obj/)) var/obj/container = usr.loc usr << "\red You leap and slam your head against the inside of [container]! Ouch!" - usr.paralysis += 3 - usr.weakened += 5 + usr.AdjustParalysis(3) + usr.AdjustWeakened(5) container.visible_message("\red [usr.loc] emits a loud thump and rattles a bit.") playsound(usr.loc, 'sound/effects/bang.ogg', 50, 1) var/wiggle = 6 diff --git a/code/game/dna/genes/monkey.dm b/code/game/dna/genes/monkey.dm index 474c034f21c..5d410c634b4 100644 --- a/code/game/dna/genes/monkey.dm +++ b/code/game/dna/genes/monkey.dm @@ -10,7 +10,7 @@ /datum/dna/gene/monkey/activate(var/mob/living/carbon/human/H, var/connected, var/flags) if(!istype(H,/mob/living/carbon/human)) return - if(issmall(H)) + if(issmall(H)) return for(var/obj/item/W in H) if(istype(W,/obj/item/organ)) @@ -18,13 +18,13 @@ if(istype(W,/obj/item/weapon/implant)) continue H.unEquip(W) - + H.regenerate_icons() + H.SetStunned(1) H.canmove = 0 - H.stunned = 1 H.icon = null H.invisibility = 101 - + var/atom/movable/overlay/animation = new /atom/movable/overlay(H.loc) animation.icon_state = "blank" animation.icon = 'icons/mob/mob.dmi' @@ -32,9 +32,8 @@ flick("h2monkey", animation) sleep(22) qdel(animation) - - H.stunned = 0 - H.update_canmove() + + H.SetStunned(0) H.invisibility = initial(H.invisibility) if(!H.species.primitive_form) //If the creature in question has no primitive set, this is going to be messy. @@ -62,11 +61,11 @@ continue H.unEquip(W) H.regenerate_icons() + H.SetStunned(1) H.canmove = 0 - H.stunned = 1 H.icon = null H.invisibility = 101 - + var/atom/movable/overlay/animation = new /atom/movable/overlay(H.loc) animation.icon_state = "blank" animation.icon = 'icons/mob/mob.dmi' @@ -75,8 +74,7 @@ sleep(22) qdel(animation) - H.stunned = 0 - H.update_canmove() + H.SetStunned(0) H.invisibility = initial(H.invisibility) if(!H.species.greater_form) //If the creature in question has no primitive set, this is going to be messy. @@ -84,6 +82,8 @@ return H.set_species(H.species.greater_form) + H.real_name = H.dna.real_name + H.name = H.real_name if(H.hud_used) H.hud_used.instantiate() diff --git a/code/game/dna/genes/vg_powers.dm b/code/game/dna/genes/vg_powers.dm index 215b07158b9..da98fde4544 100644 --- a/code/game/dna/genes/vg_powers.dm +++ b/code/game/dna/genes/vg_powers.dm @@ -184,9 +184,9 @@ Obviously, requires DNA2. var/new_gender = alert(usr, "Please select gender.", "Character Generation", "Male", "Female") if (new_gender) if(new_gender == "Male") - M.gender = MALE + M.change_gender(MALE) else - M.gender = FEMALE + M.change_gender(FEMALE) M.regenerate_icons() M.check_dna() diff --git a/code/game/gamemodes/changeling/powers/augmented_eyesight.dm b/code/game/gamemodes/changeling/powers/augmented_eyesight.dm index d303d022753..832973d4ce6 100644 --- a/code/game/gamemodes/changeling/powers/augmented_eyesight.dm +++ b/code/game/gamemodes/changeling/powers/augmented_eyesight.dm @@ -4,18 +4,80 @@ /obj/effect/proc_holder/changeling/augmented_eyesight name = "Augmented Eyesight" desc = "Creates heat receptors in our eyes and dramatically increases light sensing ability." - helptext = "Grants us night vision and thermal vision. It may be toggled on or off." + helptext = "Grants us thermal vision or flash protection. We will become a lot more vulnerable to flash-based devices while thermal vision is active." chemical_cost = 0 dna_cost = 2 //Would be 1 without thermal vision + var/active = 0 //Whether or not vision is enhanced + +/obj/effect/proc_holder/changeling/augmented_eyesight/sting_action(mob/living/carbon/human/user) + if(!istype(user)) + return + if(user.get_int_organ(/obj/item/organ/internal/cyberimp/eyes/thermals/ling)) + user << "Our eyes are protected from flashes." + var/obj/item/organ/internal/cyberimp/eyes/O = new /obj/item/organ/internal/cyberimp/eyes/shield/ling() + O.insert(user) -/obj/effect/proc_holder/changeling/augmented_eyesight/sting_action(var/mob/user) - if(!user.vision_type) - user << "We feel a minute twitch in our eyes, and darkness creeps away." - user.vision_type = new /datum/vision_override/nightvision/thermals/ling_augmented_eyesight else - user << "Our vision dulls. Shadows gather." - user.vision_type = null + var/obj/item/organ/internal/cyberimp/eyes/O = new /obj/item/organ/internal/cyberimp/eyes/thermals/ling() + O.insert(user) + return 1 + /obj/effect/proc_holder/changeling/augmented_eyesight/on_refund(mob/user) - user.vision_type = null \ No newline at end of file + var/obj/item/organ/internal/cyberimp/eyes/O = user.get_organ_slot("eye_ling") + if(O) + O.remove(user) + qdel(O) + + + + + +/obj/item/organ/internal/cyberimp/eyes/shield/ling + name = "protective membranes" + desc = "These variable transparency organic membranes will protect you from welders and flashes and heal your eye damage." + icon_state = "ling_eyeshield" + eye_colour = null + implant_overlay = null + origin_tech = "biotech=4" + slot = "eye_ling" + status = 0 + +/obj/item/organ/internal/cyberimp/eyes/shield/ling/on_life() + ..() + var/obj/item/organ/internal/eyes/E = owner.get_int_organ(/obj/item/organ/internal/eyes) + if(owner.eye_blind || owner.eye_blurry || (owner.sdisabilities & BLIND) || (owner.disabilities & NEARSIGHTED) || (E.damage > 0)) + owner.reagents.add_reagent("oculine", 1) + +/obj/item/organ/internal/cyberimp/eyes/shield/ling/prepare_eat() + var/obj/S = ..() + S.reagents.add_reagent("oculine", 15) + return S + + +/obj/item/organ/internal/cyberimp/eyes/thermals/ling + name = "heat receptors" + desc = "These heat receptors dramatically increases eyes light sensing ability." + icon_state = "ling_thermal" + eye_colour = null + implant_overlay = null + origin_tech = "biotech=5;magnets=5" + slot = "eye_ling" + status = 0 + aug_message = "We feel a minute twitch in our eyes, and darkness creeps away." + +/obj/item/organ/internal/cyberimp/eyes/thermals/ling/emp_act(severity) + return + +/obj/item/organ/internal/cyberimp/eyes/thermals/ling/insert(mob/living/carbon/M, special = 0) + ..() + if(ishuman(owner)) + var/mob/living/carbon/human/H = owner + H.weakeyes = 1 + +/obj/item/organ/internal/cyberimp/eyes/thermals/ling/remove(mob/living/carbon/M, special = 0) + if(ishuman(owner)) + var/mob/living/carbon/human/H = owner + H.weakeyes = 0 + ..() \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/panacea.dm b/code/game/gamemodes/changeling/powers/panacea.dm index 469283d1436..c2d12e6a9a8 100644 --- a/code/game/gamemodes/changeling/powers/panacea.dm +++ b/code/game/gamemodes/changeling/powers/panacea.dm @@ -10,6 +10,15 @@ /obj/effect/proc_holder/changeling/panacea/sting_action(var/mob/user) user << "We cleanse impurities from our form." + + var/obj/item/organ/internal/body_egg/egg = user.get_int_organ(/obj/item/organ/internal/body_egg) + if(egg) + egg.remove(user) + if(iscarbon(user)) + var/mob/living/carbon/human/C = user + C.vomit() + egg.forceMove(get_turf(user)) + user.reagents.add_reagent("mutadone", 10) user.reagents.add_reagent("potass_iodide", 10) user.reagents.add_reagent("charcoal", 20) diff --git a/code/game/gamemodes/changeling/powers/revive.dm b/code/game/gamemodes/changeling/powers/revive.dm index f7cbbd4195f..797f8887767 100644 --- a/code/game/gamemodes/changeling/powers/revive.dm +++ b/code/game/gamemodes/changeling/powers/revive.dm @@ -57,7 +57,7 @@ O.trace_chemicals = list() O.wounds = list() O.wound_update_accuracy = 1 - for(var/obj/item/organ/IO in H.internal_organs) + for(var/obj/item/organ/internal/IO in H.internal_organs) IO.damage = 0 IO.trace_chemicals = list() H.updatehealth() diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index a1a5d646544..85d2228cda7 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -16,8 +16,6 @@ return 0 if(iscultist(mind.current)) return 1 //If they're already in the cult, assume they are convertable - if(jobban_isbanned(mind.current, "cultist") || jobban_isbanned(mind.current, "Syndicate")) - return 0 if(ishuman(mind.current) && (mind.assigned_role in list("Captain", "Chaplain"))) return 0 if(ishuman(mind.current)) @@ -57,7 +55,7 @@ /datum/game_mode/cult/announce() world << "The current game mode is - Cult!" - world << "Some crewmembers are attempting to start a cult!
    \nCultists - complete your objectives. Convert crewmembers to your cause by using the convert rune. Remember - there is no you, there is only the cult.
    \nPersonnel - Do not let the cult succeed in its mission. Brainwashing them with the chaplain's bible reverts them to whatever CentCom-allowed faith they had.
    " + world << "Some crewmembers are attempting to start a cult!
    \nCultists - complete your objectives. Convert crewmembers to your cause by using the convert rune. Remember - there is no you, there is only the cult.
    \nPersonnel - Do not let the cult succeed in its mission. Brainwashing them with the chaplain's bible reverts them to whatever CentComm-allowed faith they had.
    " /datum/game_mode/cult/pre_setup() @@ -186,6 +184,9 @@ cult += cult_mind add_cult_viewpoint(cult_mind.current) update_cult_icons_added(cult_mind) + cult_mind.current.attack_log += "\[[time_stamp()]\] Has been converted to the cult!" + if(jobban_isbanned(cult_mind.current, ROLE_CULTIST)) + replace_jobbaned_player(cult_mind.current, ROLE_CULTIST, ROLE_CULTIST) return 1 diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 18883600ad4..43bb42dbd8c 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -582,8 +582,8 @@ var/list/sacrificed = list() if(!(iscultist(V))) victims += V//Checks for cult status and mob type for(var/obj/item/I in src.loc)//Checks for MMIs/brains/Intellicards - if(istype(I,/obj/item/organ/brain)) - var/obj/item/organ/brain/B = I + if(istype(I,/obj/item/organ/internal/brain)) + var/obj/item/organ/internal/brain/B = I victims += B.brainmob else if(istype(I,/obj/item/device/mmi)) var/obj/item/device/mmi/B = I diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index b9c678c74f7..73ce77d0474 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -133,11 +133,11 @@ else msg += "However, we were unable to send you the $[pay] you're entitled." if(useMS && P) - // THIS SHOULD HAVE DONE EVERYTHING FOR ME useMS.send_pda_message("[P.owner]", "[command_name()] Payroll", msg) - // BUT NOPE, NEED TO DO THIS BULLSHIT. - P.play_ringtone() + var/datum/data/pda/app/messenger/PM = P.find_program(/datum/data/pda/app/messenger) + if(PM) + PM.play_ringtone() //Search for holder of the PDA. var/mob/living/L = null if(P.loc && isliving(P.loc)) @@ -445,4 +445,17 @@ proc/get_nt_opposed() for(var/obj/machinery/nuclearbomb/bomb in world) if(bomb && bomb.r_code && bomb.z == ZLEVEL_STATION) nukecode = bomb.r_code - return nukecode \ No newline at end of file + return nukecode + +/datum/game_mode/proc/replace_jobbaned_player(mob/living/M, role_type, pref) + var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as a [role_type]?", "[role_type]", null, pref, 100) + var/mob/dead/observer/theghost = null + if(candidates.len) + theghost = pick(candidates) + M << "Your mob has been taken over by a ghost! Appeal your job ban if you want to avoid this in the future!" + message_admins("[key_name_admin(theghost)] has taken control of ([key_name_admin(M)]) to replace a jobbanned player.") + M.ghostize() + M.key = theghost.key + else + message_admins("[M] ([M.key] has been converted into [role_type] with an active antagonist jobban for said role since no ghost has volunteered to take their place.") + M << "You have been converted into [role_type] with an active jobban. Any further violations of the rules on your part are likely to result in a permanent ban." \ No newline at end of file diff --git a/code/game/gamemodes/miniantags/borer/borer.dm b/code/game/gamemodes/miniantags/borer/borer.dm index 578d2e55b60..83d6cf04063 100644 --- a/code/game/gamemodes/miniantags/borer/borer.dm +++ b/code/game/gamemodes/miniantags/borer/borer.dm @@ -26,6 +26,13 @@ if(M.mind && (istype(M, /mob/dead/observer))) M << "Thought-speech, [src] -> [B.truename]: [message]" +/mob/living/captive_brain/say_understands(var/mob/other, var/datum/language/speaking = null) + var/mob/living/simple_animal/borer/B = src.loc + if(!istype(B)) + log_to_dd("Trapped mind found without a borer!") + return 0 + return B.host.say_understands(other, speaking) + /mob/living/captive_brain/emote(var/message) return @@ -53,13 +60,92 @@ pass_flags = PASSTABLE ventcrawler = 2 + var/talk_inside_host = 0 // So that borers don't accidentally give themselves away on a botched message var/used_dominate - var/chemicals = 10 // Chemicals used for reproduction and spitting neurotoxin. + var/chemicals = 10 // Chemicals used for reproduction and chemical injection. + var/max_chems = 250 // How many chemicals that can be stored in total var/mob/living/carbon/human/host // Human host for the brain worm. var/truename // Name used for brainworm-speak. var/mob/living/captive_brain/host_brain // Used for swapping control of the body back and forth. var/controlling // Used in human death check. var/docile = 0 // Sugar can stop borers from acting. + var/list/borer_injection_chems = list("mannitol","salglu_solution","methamphetamine", "hydrocodone", "spaceacillin", "mitocholide", "charcoal", "salbutamol", "capulettium_plus") + +/mob/living/simple_animal/borer/verb/Communicate() + set category = "Borer" + set name = "Converse with Host" + set desc = "Send a silent message to your host." + if(!host) + src << "You do not have a host to communicate with!" + return + + var/input = stripped_input(src, "Please enter a message to tell your host.", "Borer", "") + if(!input) return + + + var/say_string = (docile) ? "slurs" :"states" + if(host) + host << "[src.truename] [say_string]: [input]" + log_say("Borer Communication: [key_name(src)] -> [key_name(host)] : [input]") + for(var/M in dead_mob_list) + if(istype(M, /mob/dead/observer)) + M << "Borer Communication from [src.truename] ([ghost_follow_link(src, ghost=M)]): [input]" + src << "[src.truename] [say_string]: [input]" + host.verbs += /mob/living/proc/borer_comm + +/mob/living/simple_animal/borer/verb/toggle_silence_inside_host() + set name = "Toggle speech inside Host" + set category = "Borer" + set desc = "Toggle whether you will be able to say audible messages while inside your host." + + if(talk_inside_host) + talk_inside_host = 0 + src << "You will no longer talk audibly while inside a host." + else + talk_inside_host = 1 + src << "You will now be able to audibly speak from inside of a host." + +/mob/living/proc/borer_comm() + set name = "Converse with Borer" + set category = "Borer" + set desc = "Communicate mentally with your borer." + + + var/mob/living/simple_animal/borer/B = src.has_brain_worms() + if(!B) + return + + var/input = stripped_input(src, "Please enter a message to tell the borer.", "Message", "") + if(!input) return + + B << "[src] says: [input]" + log_say("Borer Communication: [key_name(src)] -> [key_name(B)] : [input]") + + for(var/M in dead_mob_list) + if(istype(M, /mob/dead/observer)) + M << "Borer Communication from [src] ([ghost_follow_link(src, ghost=M)]): [input]" + src << "[src] says: [input]" + +/mob/living/proc/trapped_mind_comm() + set name = "Converse with Trapped Mind" + set category = "Borer" + set desc = "Communicate mentally with the trapped mind of your host." + + + var/mob/living/simple_animal/borer/B = src.has_brain_worms() + if(!B || !B.host_brain) + return + var/mob/living/captive_brain/CB = B.host_brain + var/input = stripped_input(src, "Please enter a message to tell the trapped mind.", "Message", "") + if(!input) return + + CB << "[B.truename] says: [input]" + log_say("Borer Communication: [key_name(B)] -> [key_name(CB)] : [input]") + + for(var/M in dead_mob_list) + if(istype(M, /mob/dead/observer)) + M << "Borer Communication from [B] ([ghost_follow_link(src, ghost=M)]): [input]" + src << "[B.truename] says: [input]" /mob/living/simple_animal/borer/Life() @@ -84,7 +170,7 @@ src << "\blue You shake off your lethargy as the sugar leaves your host's blood." docile = 0 - if(chemicals < 250) + if(chemicals < max_chems) chemicals++ if(controlling) @@ -102,11 +188,16 @@ /mob/living/simple_animal/borer/New(var/by_gamemode=0) ..() add_language("Cortical Link") - truename = "[pick("Primary","Secondary","Tertiary","Quaternary")] [rand(1000,9999)]" + updatename() if(!by_gamemode) request_player() +/mob/living/simple_animal/borer/proc/updatename() + var/index_num = rand(1000,9999) + real_name = "Cortical Borer ([index_num])" + truename = "[pick("Primary","Secondary","Tertiary","Quaternary")] [index_num]" + /mob/living/simple_animal/borer/Stat() ..() statpanel("Status") @@ -127,7 +218,7 @@ M << "Cortical link, [truename]: [copytext(message, 2)]" /mob/living/simple_animal/borer/verb/dominate_victim() - set category = "Alien" + set category = "Borer" set name = "Dominate Victim" set desc = "Freeze the limbs of a potential host with supernatural fear." @@ -167,7 +258,7 @@ used_dominate = world.time /mob/living/simple_animal/borer/verb/bond_brain() - set category = "Alien" + set category = "Borer" set name = "Assume Control" set desc = "Fully connect to the brain of your host." @@ -233,13 +324,15 @@ host.verbs += /mob/living/carbon/proc/release_control host.verbs += /mob/living/carbon/proc/punish_host host.verbs += /mob/living/carbon/proc/spawn_larvae + host.verbs -= /mob/living/proc/borer_comm + host.verbs += /mob/living/proc/trapped_mind_comm if(src && !src.key) src.key = "@[borer_key]" return /mob/living/simple_animal/borer/verb/secrete_chemicals() - set category = "Alien" + set category = "Borer" set name = "Secrete Chemicals (30)" set desc = "Push some chemicals into your host's bloodstream." @@ -259,8 +352,12 @@ if(chemicals < chem_cost) src << "You don't have enough chemicals!" - - var/chem = input("Select a chemical to secrete.", "Chemicals") as null|anything in list("mannitol","salglu_solution","methamphetamine", "hydrocodone", "spaceacillin", "mitocholide", "charcoal", "salbutamol", "capulettium_plus") + var/list/nice_name_chem_list = list() + for(var/rgnt in borer_injection_chems) + var/datum/reagent/R2 = chemical_reagents_list[rgnt] + nice_name_chem_list[R2.name] = rgnt + var/chem_name = input("Select a chemical to secrete.", "Chemicals") as null|anything in nice_name_chem_list + var/chem = nice_name_chem_list[chem_name] if(!chem || chemicals < chem_cost || !host || controlling || !src || stat) //Sanity check. return @@ -271,12 +368,12 @@ src << "Doing so would cause grievous harm to your host, reducing ability to reproduce. Aborting." return - src << "You squirt a measure of [chem] from your reservoirs into [host]'s bloodstream." + src << "You squirt a measure of [chem_name] from your reservoirs into [host]'s bloodstream." host.reagents.add_reagent(chem, injection_amount) chemicals -= chem_cost /mob/living/simple_animal/borer/verb/release_host() - set category = "Alien" + set category = "Borer" set name = "Release Host" set desc = "Slither out of your host." @@ -325,6 +422,8 @@ host.verbs -= /mob/living/carbon/proc/release_control host.verbs -= /mob/living/carbon/proc/punish_host host.verbs -= /mob/living/carbon/proc/spawn_larvae + host.verbs += /mob/living/proc/borer_comm + host.verbs -= /mob/living/proc/trapped_mind_comm if(host_brain) @@ -362,6 +461,71 @@ return + +//Brain slug proc for voluntary removal of control. +/mob/living/carbon/proc/release_control() + + set category = "Borer" + set name = "Release Control" + set desc = "Release control of your host's body." + + var/mob/living/simple_animal/borer/B = has_brain_worms() + + if(B && B.host_brain) + src << "\red You withdraw your probosci, releasing control of [B.host_brain]" + + B.detatch() + + else + src << "\red ERROR NO BORER OR BRAINMOB DETECTED IN THIS MOB, THIS IS A BUG !" + +//Brain slug proc for tormenting the host. +/mob/living/carbon/proc/punish_host() + set category = "Borer" + set name = "Torment host" + set desc = "Punish your host with agony." + + var/mob/living/simple_animal/borer/B = has_brain_worms() + + if(!B) + return + + if(B.host_brain.ckey) + src << "\red You send a punishing spike of psychic agony lancing into your host's brain." + B.host_brain << "\red Horrific, burning agony lances through you, ripping a soundless scream from your trapped mind!" + +//Check for brain worms in head. +/mob/proc/has_brain_worms() + + for(var/I in contents) + if(istype(I,/mob/living/simple_animal/borer)) + return I + + return 0 + +/mob/living/carbon/proc/spawn_larvae() + set category = "Borer" + set name = "Reproduce (100)" + set desc = "Spawn several young." + + var/mob/living/simple_animal/borer/B = has_brain_worms() + + if(!B) + return + + if(B.chemicals >= 100) + src << "\red Your host twitches and quivers as you rapdly excrete several larvae from your sluglike body." + visible_message("\red [src] heaves violently, expelling a rush of vomit and a wriggling, sluglike creature!") + B.chemicals -= 100 + + new /obj/effect/decal/cleanable/vomit(get_turf(src)) + playsound(loc, 'sound/effects/splat.ogg', 50, 1) + new /mob/living/simple_animal/borer(get_turf(src)) + + else + src << "You do not have enough chemicals stored to reproduce." + return + /mob/living/simple_animal/borer/proc/leave_host() if(!host) return @@ -375,12 +539,13 @@ host.machine = null var/mob/living/H = host + H.verbs -= /mob/living/proc/borer_comm H.status_flags &= ~PASSEMOTES host = null return /mob/living/simple_animal/borer/verb/infest() - set category = "Alien" + set category = "Borer" set name = "Infest" set desc = "Infest a suitable humanoid host." @@ -428,18 +593,12 @@ if(M in view(1, src)) src << "You wiggle into [M]'s ear." + /* if(!M.stat) M << "Something disgusting and slimy wiggles into your ear!" + */ // Let's see how stealthborers work out - src.host = M - src.forceMove(M) - - if(istype(M,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = M - var/obj/item/organ/external/head = H.get_organ("head") - head.implants += src - - host.status_flags |= PASSEMOTES + perform_infestation(M) return else @@ -455,8 +614,6 @@ var/obj/item/organ/external/head = H.get_organ("head") head.implants += src - host_brain.name = M.name - host_brain.real_name = M.real_name host.status_flags |= PASSEMOTES /mob/living/simple_animal/borer/can_use_vents() @@ -487,13 +644,12 @@ if(!candidate) return - src.mind = candidate.mob.mind - src.ckey = candidate.ckey + src.key = candidate.key if(src.mind) src.mind.assigned_role = "Cortical Borer" /mob/living/simple_animal/borer/verb/borerhide() - set category = "Alien" + set category = "Borer" set name = "Hide" set desc = "Allows to hide beneath tables or certain items. Toggled on or off." @@ -502,13 +658,16 @@ if (layer != TURF_LAYER+0.2) layer = TURF_LAYER+0.2 - src << text("\green You are now hiding.") - for(var/mob/O in oviewers(src, null)) - if ((O.client && !( O.blinded ))) - O << text("[] scurries to the ground!", src) + src << "\green You are now hiding." else layer = MOB_LAYER - src << text("\green You have stopped hiding.") - for(var/mob/O in oviewers(src, null)) - if ((O.client && !( O.blinded ))) - O << text("[] slowly peaks up from the ground...", src) + src << "\green You have stopped hiding." + +/mob/living/simple_animal/borer/say(var/message) + var/datum/language/dialect = parse_language(message) + if(!dialect) + dialect = get_default_language() + if(!istype(dialect, /datum/language/corticalborer) && loc == host && !talk_inside_host) + src << "You've disabled audible speech while inside a host! Re-enable it under the borer tab, or stick to borer communications." + return + ..() diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm index dfe8d1838e0..4f7c9608a2c 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant.dm @@ -58,6 +58,7 @@ if(unreveal_time && world.time >= unreveal_time) unreveal_time = 0 revealed = 0 + incorporeal_move = 3 invisibility = INVISIBILITY_REVENANT src << "You are once more concealed." if(unstun_time && world.time >= unstun_time) @@ -86,8 +87,9 @@ src << "You feel your essence fraying!" /mob/living/simple_animal/revenant/ClickOn(var/atom/A, var/params) //Copypaste from ghost code - revenants can't interact with the world directly. - if(client.buildmode) - build_click(src, client.buildmode, params, A) + + if(client.click_intercept) + client.click_intercept.InterceptClickOn(src, params, A) return var/list/modifiers = params2list(params) @@ -315,6 +317,7 @@ return revealed = 1 invisibility = 0 + incorporeal_move = 0 if(!unreveal_time) src << "You have been revealed!" unreveal_time = world.time + time diff --git a/code/game/gamemodes/miniantags/slaughter/slaughter.dm b/code/game/gamemodes/miniantags/slaughter/slaughter.dm index f5edb4ac363..5f9b320a2a5 100644 --- a/code/game/gamemodes/miniantags/slaughter/slaughter.dm +++ b/code/game/gamemodes/miniantags/slaughter/slaughter.dm @@ -93,7 +93,7 @@ new /obj/effect/decal/cleanable/blood (src.loc) new /obj/effect/gibspawner/generic(get_turf(src)) new /obj/effect/gibspawner/generic(get_turf(src)) - new /obj/item/weapon/demonheart(src.loc) + new /obj/item/organ/internal/heart/demonheart(src.loc) playsound(get_turf(src),'sound/misc/demon_dies.ogg', 200, 1) visible_message("[src] screams in anger as it collapses into a puddle of viscera, its most recent meals spilling out of it.") for(var/mob/living/M in consumed_mobs) @@ -138,7 +138,7 @@ //////////The Loot //The loot from killing a slaughter demon - can be consumed to allow the user to blood crawl -/obj/item/weapon/demonheart +/obj/item/organ/internal/heart/demonheart name = "demon heart" desc = "Still it beats furiously, emanating an aura of utter hate." icon = 'icons/obj/surgery.dmi' @@ -146,7 +146,7 @@ origin_tech = "combat=5;biotech=8" -/obj/item/weapon/demonheart/attack_self(mob/living/user) +/obj/item/organ/internal/heart/demonheart/attack_self(mob/living/user) user.visible_message("[user] raises [src] to their mouth and tears into it with their teeth!", \ "An unnatural hunger consumes you. You raise [src] to your mouth and devour it!") playsound(user, 'sound/misc/Demon_consume.ogg', 50, 1) @@ -159,8 +159,14 @@ user.bloodcrawl = BLOODCRAWL_EAT else user <<"...and you don't feel any different." - qdel(src) + user.drop_item() + insert(user) //Consuming the heart literally replaces your heart with a demon heart. H A R D C O R E + +/obj/item/organ/internal/heart/demonheart/remove(mob/living/carbon/M, special = 0) + ..() + if(M.mind) + M.bloodcrawl = 0 //Objectives and helpers. diff --git a/code/game/gamemodes/mutiny/directives/ipc_virus_directive.dm b/code/game/gamemodes/mutiny/directives/ipc_virus_directive.dm index c67780b709d..6ec1d60890b 100644 --- a/code/game/gamemodes/mutiny/directives/ipc_virus_directive.dm +++ b/code/game/gamemodes/mutiny/directives/ipc_virus_directive.dm @@ -62,7 +62,7 @@ datum/directive/ipc_virus/get_remaining_orders() return text -/hook/debrain/proc/debrain_directive(obj/item/organ/brain/B) +/hook/debrain/proc/debrain_directive(var/obj/item/organ/internal/brain/B) var/datum/directive/ipc_virus/D = get_directive("ipc_virus") if (!D) return 1 diff --git a/code/game/gamemodes/mutiny/directives/research_to_ripleys_directive.dm b/code/game/gamemodes/mutiny/directives/research_to_ripleys_directive.dm index 566b34a8d0e..62cfc678d17 100644 --- a/code/game/gamemodes/mutiny/directives/research_to_ripleys_directive.dm +++ b/code/game/gamemodes/mutiny/directives/research_to_ripleys_directive.dm @@ -41,7 +41,7 @@ datum/directive/research_to_ripleys/initialize() special_orders = list( "Reassign all research personnel, excluding the Research Director, to Shaft Miner.", - "Deliver [MATERIALS_REQUIRED] sheets of metal or minerals via the supply shuttle to CentCom.") + "Deliver [MATERIALS_REQUIRED] sheets of metal or minerals via the supply shuttle to CentComm.") datum/directive/research_to_ripleys/directives_complete() if (materials_shipped < MATERIALS_REQUIRED) return 0 diff --git a/code/game/gamemodes/mutiny/emergency_authentication_device.dm b/code/game/gamemodes/mutiny/emergency_authentication_device.dm index 061e3c85cc5..2a48ac8c3b7 100644 --- a/code/game/gamemodes/mutiny/emergency_authentication_device.dm +++ b/code/game/gamemodes/mutiny/emergency_authentication_device.dm @@ -49,7 +49,7 @@ return if(!mode.current_directive.directives_complete()) - state("Command aborted. Communication with CentCom is prohibited until Directive X has been completed.") + state("Command aborted. Communication with CentComm is prohibited until Directive X has been completed.") return check_key_existence() @@ -81,7 +81,7 @@ return if(!mode.current_directive.directives_complete()) - state({"Command aborted. Communication with CentCom is prohibited until Directive X has been completed."}) + state({"Command aborted. Communication with CentComm is prohibited until Directive X has been completed."}) return check_key_existence() @@ -92,7 +92,7 @@ state("Key received. Thank you, Captain [mode.head_loyalist].") spawn(5) - state(secondary_key ? "Your keys have been authenticated. Communication with CentCom is now authorized." : "Please insert the Emergency Secondary Authentication Key now.") + state(secondary_key ? "Your keys have been authenticated. Communication with CentComm is now authorized." : "Please insert the Emergency Secondary Authentication Key now.") return if(istype(O, /obj/item/weapon/mutiny/auth_key/secondary) && !secondary_key) @@ -102,10 +102,10 @@ state("Key received. Thank you, Secondary Authenticator [mode.head_mutineer].") spawn(5) - state(captains_key ? "Your keys have been authenticated. Communication with CentCom is now authorized." : "Please insert the Captain's Authentication Key now.") + state(captains_key ? "Your keys have been authenticated. Communication with CentComm is now authorized." : "Please insert the Captain's Authentication Key now.") return ..() /obj/machinery/emergency_authentication_device/examine(mob/user) - user << {"This is a specialized communications device that is able to instantly send a message to Nanotrasen High Command via quantum entanglement with a sister device at CentCom.
    + user << {"This is a specialized communications device that is able to instantly send a message to Nanotrasen High Command via quantum entanglement with a sister device at CentComm.
    The EAD's status is [get_status()]."} diff --git a/code/game/gamemodes/mutiny/mutiny.dm b/code/game/gamemodes/mutiny/mutiny.dm index 1d2faebe5ff..113cffa46c0 100644 --- a/code/game/gamemodes/mutiny/mutiny.dm +++ b/code/game/gamemodes/mutiny/mutiny.dm @@ -105,7 +105,9 @@ datum/game_mode/mutiny if (!pda) return 0 - pda.play_ringtone() + var/datum/data/pda/app/messenger/pdam = pda.find_program(/datum/data/pda/app/messenger) + if(pdam) + pdam.play_ringtone() head_mutineer.current << fluff.get_pda_body() return 1 diff --git a/code/game/gamemodes/nuclear/nuclear_challenge.dm b/code/game/gamemodes/nuclear/nuclear_challenge.dm index 7ab4e51f56e..621f159eced 100644 --- a/code/game/gamemodes/nuclear/nuclear_challenge.dm +++ b/code/game/gamemodes/nuclear/nuclear_challenge.dm @@ -9,10 +9,13 @@ desc = "Use to send a declaration of hostilities to the target, delaying your shuttle departure for 20 minutes while they prepare for your assault. \ Such a brazen move will attract the attention of powerful benefactors within the Syndicate, who will supply your team with a massive amount of bonus telecrystals. \ Must be used within five minutes, or your benefactors will lose interest." + var/declaring_war = 0 /obj/item/device/nuclear_challenge/attack_self(mob/living/user) + if(declaring_war) + return if(player_list.len < MIN_CHALLENGE_PLAYERS) user << "The enemy crew is too small to be worth declaring war on." return @@ -24,9 +27,11 @@ user << "It's too late to declare hostilities. Your benefactors are already busy with other schemes. You'll have to make do with what you have on hand." return + declaring_war = 1 var/are_you_sure = alert(user, "Consult your team carefully before you declare war on [station_name()]]. Are you sure you want to alert the enemy crew?", "Declare war?", "Yes", "No") if(are_you_sure == "No") user << "On second thought, the element of surprise isn't so bad after all." + declaring_war = 0 return var/war_declaration = "[user.real_name] has declared his intent to utterly destroy [station_name()] with a nuclear device, and dares the crew to try and stop them." diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm index 74e81484c97..7d3176a7348 100644 --- a/code/game/gamemodes/revolution/revolution.dm +++ b/code/game/gamemodes/revolution/revolution.dm @@ -225,6 +225,8 @@ rev_mind.current << "\red You are now a revolutionary! Help your cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them kill the heads to win the revolution!" rev_mind.special_role = "Revolutionary" update_rev_icons_added(rev_mind) + if(jobban_isbanned(rev_mind.current, ROLE_REV)) + replace_jobbaned_player(rev_mind.current, ROLE_REV, ROLE_REV) return 1 ////////////////////////////////////////////////////////////////////////////// //Deals with players being converted from the revolution (Not a rev anymore)// // Modified to handle borged MMIs. Accepts another var if the target is being borged at the time -- Polymorph. diff --git a/code/game/gamemodes/shadowling/shadowling.dm b/code/game/gamemodes/shadowling/shadowling.dm index 551fb869839..a11fd4a5fa6 100644 --- a/code/game/gamemodes/shadowling/shadowling.dm +++ b/code/game/gamemodes/shadowling/shadowling.dm @@ -155,6 +155,8 @@ Made by Xhuis new_thrall_mind.current << "Your body has been irreversibly altered. The attentive can see this - you may conceal it by wearing a mask." new_thrall_mind.current << "Though not nearly as powerful as your masters, you possess some weak powers. These can be found in the Thrall Abilities tab." new_thrall_mind.current << "You may communicate with your allies by speaking in the Shadowling Hivemind (:8)." + if(jobban_isbanned(new_thrall_mind.current, ROLE_SHADOWLING)) + replace_jobbaned_player(new_thrall_mind.current, ROLE_SHADOWLING, ROLE_SHADOWLING) return 1 diff --git a/code/game/gamemodes/shadowling/shadowling_abilities.dm b/code/game/gamemodes/shadowling/shadowling_abilities.dm index f4186557627..2dfa31cc4a0 100644 --- a/code/game/gamemodes/shadowling/shadowling_abilities.dm +++ b/code/game/gamemodes/shadowling/shadowling_abilities.dm @@ -80,8 +80,9 @@ F.update_brightness() else if(istype(I, /obj/item/device/pda)) var/obj/item/device/pda/P = I - P.fon = 0 - P.set_light(0) + var/datum/data/pda/utility/flashlight/FL = P.find_program(/datum/data/pda/utility/flashlight) + if(FL && FL.fon) + FL.start() else if(istype(I, /obj/item/clothing/head/helmet/space/rig)) var/obj/item/clothing/head/helmet/space/rig/R = I if(R.on) diff --git a/code/game/gamemodes/vampire/vampire.dm b/code/game/gamemodes/vampire/vampire.dm index 40da7a5bca3..7d304204613 100644 --- a/code/game/gamemodes/vampire/vampire.dm +++ b/code/game/gamemodes/vampire/vampire.dm @@ -203,6 +203,7 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha var/list/powers = list() // list of available powers and passives, see defines in setup.dm var/mob/living/carbon/human/draining // who the vampire is draining of blood var/nullified = 0 //Nullrod makes them useless for a short while. + var/upgradedRegen = 0 /datum/vampire/New(gend = FEMALE) gender = gend @@ -324,8 +325,9 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha vamp.powers.Add(VAMP_BATS) if(!(VAMP_SCREAM in vamp.powers)) vamp.powers.Add(VAMP_SCREAM) - // Commented out until we can figured out a way to stop this from spamming. - //src << "\blue Your rejuvination abilities have improved and will now heal you over time when used." + if(!(vamp.upgradedRegen)) // to prevent spamming + src << "Your rejuvination abilities have improved and will now heal you over time when used." + vamp.upgradedRegen = 1 // TIER 3.5 (/vg/) if(vamp.bloodtotal >= 250) diff --git a/code/game/gamemodes/vampire/vampire_powers.dm b/code/game/gamemodes/vampire/vampire_powers.dm index e07f24983b1..5794b144d51 100644 --- a/code/game/gamemodes/vampire/vampire_powers.dm +++ b/code/game/gamemodes/vampire/vampire_powers.dm @@ -75,9 +75,9 @@ var/datum/mind/M = usr.mind if(!M) return if(M.current.vampire_power(0, 1)) - M.current.weakened = 0 - M.current.stunned = 0 - M.current.paralysis = 0 + M.current.SetWeakened(0) + M.current.SetStunned(0) + M.current.SetParalysis(0) M.current.adjustStaminaLoss(-75) //M.vampire.bloodusable -= 10 M.current << "\blue You flush your system with clean blood and remove any incapacitating effects." diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index b5cb650c2b6..dc484b22d5e 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -642,7 +642,7 @@ var/global/list/multiverse = list() if(heresy) spawnheresy(M)//oh god why else - M.makeSkeleton() + M.set_species("Skeleton") M.visible_message(" A massive amount of flesh sloughs off [M] and a skeleton rises up!") M.revive() equip_skeleton(M) diff --git a/code/game/gamemodes/wizard/godhand.dm b/code/game/gamemodes/wizard/godhand.dm index e8bdb02c764..3ba98fcecee 100644 --- a/code/game/gamemodes/wizard/godhand.dm +++ b/code/game/gamemodes/wizard/godhand.dm @@ -44,12 +44,6 @@ if(!proximity || target == user || !ismob(target) || !iscarbon(user) || user.lying || user.handcuffed) //exploding after touching yourself would be bad return var/mob/M = target - if(ishuman(M) || issmall(M)) - var/mob/living/carbon/C_target = M - var/obj/item/organ/brain/B - if(C_target.brain_op_stage != 4) // Their brain is already taken out - B = new(C_target.loc) - B.transfer_identity(C_target) var/datum/effect/system/spark_spread/sparks = new sparks.set_up(4, 0, M.loc) //no idea what the 0 is sparks.start() @@ -73,4 +67,21 @@ var/mob/M = target M.Stun(2) new /obj/structure/closet/statue(M.loc, M) + ..() + +/obj/item/weapon/melee/touch_attack/fake_disintegrate + name = "toy plastic hand" + desc = "This hand of mine glows with an awesome power! Ok, maybe just batteries." + catchphrase = "EI NATH!!" + on_use_sound = "sound/magic/Disintegrate.ogg" + icon_state = "disintegrate" + item_state = "disintegrate" + +/obj/item/weapon/melee/touch_attack/fake_disintegrate/afterattack(atom/target, mob/living/carbon/user, proximity) + if(!proximity || target == user || !ismob(target) || !iscarbon(user) || user.lying || user.handcuffed) //exploding after touching yourself would be bad + return + var/datum/effect/system/spark_spread/sparks = new + sparks.set_up(4, 0, target.loc) //no idea what the 0 is + sparks.start() + playsound(target.loc, 'sound/effects/gib.ogg', 100, 1, 10) ..() \ No newline at end of file diff --git a/code/game/gamemodes/wizard/raginmages.dm b/code/game/gamemodes/wizard/raginmages.dm index 77703c53715..e2812db9a17 100644 --- a/code/game/gamemodes/wizard/raginmages.dm +++ b/code/game/gamemodes/wizard/raginmages.dm @@ -8,7 +8,7 @@ var/making_mage = 0 var/mages_made = 1 var/time_checked = 0 - var/players_per_mage = 8 // If the admin wants to tweak things or something + var/players_per_mage = 6 // If the admin wants to tweak things or something but_wait_theres_more = 1 var/delay_per_mage = 4200 // Every 7 minutes by default var/time_till_chaos = 18000 // Half-hour in @@ -17,11 +17,6 @@ world << "The current game mode is - Ragin' Mages!" world << "The \red Space Wizard Federation\black is pissed, help defeat all the space wizards!" -/datum/game_mode/wizard/raginmages/pre_setup() - . = ..() - if(!max_mages) - max_mages = round(num_players() / players_per_mage) - /datum/game_mode/wizard/raginmages/greet_wizard(var/datum/mind/wizard, var/you_are=1) if (you_are) @@ -37,6 +32,8 @@ /datum/game_mode/wizard/raginmages/check_finished() var/wizards_alive = 0 + // Accidental pun! + var/wizard_cap = (max_mages || (num_players() / players_per_mage)) for(var/datum/mind/wizard in wizards) if(isnull(wizard.current)) continue @@ -78,11 +75,11 @@ if (wizards_alive) if(!time_checked) time_checked = world.time - if(world.time > time_till_chaos && world.time > time_checked + delay_per_mage && (mages_made < max_mages)) + if(world.time > time_till_chaos && world.time > time_checked + delay_per_mage && (mages_made < wizard_cap)) time_checked = world.time make_more_mages() else - if(wizards.len >= max_mages) + if(wizards.len >= wizard_cap) finished = 1 return 1 else diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index 83c23311297..7422d610fb9 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -413,6 +413,8 @@ log_name = "SG" /datum/spellbook_entry/summon/guns/IsAvailible() + if(!ticker.mode) // In case spellbook is placed on map + return 0 if(ticker.mode.name == "ragin' mages") return 0 else @@ -434,6 +436,8 @@ log_name = "SU" /datum/spellbook_entry/summon/magic/IsAvailible() + if(!ticker.mode) // In case spellbook is placed on map + return 0 if(ticker.mode.name == "ragin' mages") return 0 else @@ -463,8 +467,7 @@ var/list/datum/spellbook_entry/entries = list() var/list/categories = list() -/obj/item/weapon/spellbook/New() - ..() +/obj/item/weapon/spellbook/proc/Initialize() var/entry_types = subtypesof(/datum/spellbook_entry) - /datum/spellbook_entry/item - /datum/spellbook_entry/summon for(var/T in entry_types) var/datum/spellbook_entry/E = new T @@ -475,6 +478,10 @@ qdel(E) tab = categories[1] +/obj/item/weapon/spellbook/New() + ..() + Initialize() + /obj/item/weapon/spellbook/attackby(obj/item/O as obj, mob/user as mob, params) if(istype(O, /obj/item/weapon/contract)) var/obj/item/weapon/contract/contract = O @@ -640,6 +647,9 @@ ..() name += spellname +/obj/item/weapon/spellbook/oneuse/Initialize() //No need to init + return + /obj/item/weapon/spellbook/oneuse/attack_self(mob/user as mob) var/obj/effect/proc_holder/spell/S = new spell for(var/obj/effect/proc_holder/spell/knownspell in user.spell_list) @@ -829,7 +839,7 @@ /obj/item/weapon/spellbook/oneuse/fake_gib - spell = /obj/effect/proc_holder/spell/targeted/fake_gib + spell = /obj/effect/proc_holder/spell/targeted/touch/fake_disintegrate spellname = "disintegrate" icon_state ="bookfireball" desc = "This book feels like it will rip stuff apart." \ No newline at end of file diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm index 9fe84dba496..cc8caa6284e 100644 --- a/code/game/jobs/job/security.dm +++ b/code/game/jobs/job/security.dm @@ -120,6 +120,7 @@ /* var/obj/item/clothing/mask/cigarette/CIG = new /obj/item/clothing/mask/cigarette(H) CIG.light("") H.equip_or_collect(CIG, slot_wear_mask) */ + H.equip_or_collect(new /obj/item/clothing/glasses/sunglasses/noir(H),slot_glasses) H.equip_or_collect(new /obj/item/clothing/gloves/color/black(H), slot_gloves) if(H.mind.role_alt_title && H.mind.role_alt_title == "Forensic Technician") H.equip_or_collect(new /obj/item/clothing/suit/storage/forensics/blue(H), slot_wear_suit) @@ -244,7 +245,7 @@ if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_sec(H), slot_back) if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) H.equip_or_collect(new /obj/item/clothing/under/rank/security(H), slot_w_uniform) - H.equip_or_collect(new /obj/item/clothing/suit/jacket(H), slot_wear_suit) + H.equip_or_collect(new /obj/item/clothing/suit/jacket/pilot(H), slot_wear_suit) H.equip_or_collect(new /obj/item/clothing/shoes/jackboots(H), slot_shoes) H.equip_or_collect(new /obj/item/device/pda/security(H), slot_wear_pda) H.equip_or_collect(new /obj/item/clothing/gloves/color/black(H), slot_gloves) diff --git a/code/game/jobs/job/support.dm b/code/game/jobs/job/support.dm index 156ca4c29f4..ebe252a9c08 100644 --- a/code/game/jobs/job/support.dm +++ b/code/game/jobs/job/support.dm @@ -282,11 +282,10 @@ H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) H.equip_or_collect(new /obj/item/toy/crayon/mime(H), slot_in_backpack) H.equip_or_collect(new /obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing(H), slot_in_backpack) - H.verbs += /client/proc/mimespeak - H.verbs += /client/proc/mimewall - H.mind.special_verbs += /client/proc/mimespeak - H.mind.special_verbs += /client/proc/mimewall - H.miming = 1 + if(H.mind) + H.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/conjure/mime_wall(null)) + H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/mime/speak(null)) + H.mind.miming = 1 return 1 diff --git a/code/game/jobs/job/support_chaplain.dm b/code/game/jobs/job/support_chaplain.dm index 25ca290b0ab..d9de164d5de 100644 --- a/code/game/jobs/job/support_chaplain.dm +++ b/code/game/jobs/job/support_chaplain.dm @@ -19,6 +19,7 @@ if(2) H.equip_or_collect(new /obj/item/weapon/storage/backpack(H), slot_back) if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back) if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + H.equip_or_collect(new /obj/item/device/radio/headset/headset_service(H), slot_l_ear) H.equip_or_collect(new /obj/item/clothing/under/rank/chaplain(H), slot_w_uniform) H.equip_or_collect(new /obj/item/device/pda/chaplain(H), slot_wear_pda) H.equip_or_collect(new /obj/item/clothing/shoes/black(H), slot_shoes) diff --git a/code/game/jobs/jobprocs.dm b/code/game/jobs/jobprocs.dm deleted file mode 100644 index 4a885005c78..00000000000 --- a/code/game/jobs/jobprocs.dm +++ /dev/null @@ -1,45 +0,0 @@ - - -//TODO: put these somewhere else -/client/proc/mimewall() - set category = "Mime" - set name = "Invisible wall" - set desc = "Create an invisible wall on your location." - if(usr.stat) - usr << "Not when you're incapicated." - return - if(!ishuman(usr)) - return - - var/mob/living/carbon/human/H = usr - - if(!H.miming) - usr << "You still haven't atoned for your speaking transgression. Wait." - return - H.verbs -= /client/proc/mimewall - spawn(300) - H.verbs += /client/proc/mimewall - for (var/mob/V in viewers(H)) - if(V!=usr) - V.show_message("[H] looks as if a wall is in front of them.", 3, "", 2) - usr << "You form a wall in front of yourself." - new /obj/effect/forcefield/mime(locate(usr.x,usr.y,usr.z)) - return - -/client/proc/mimespeak() - set category = "Mime" - set name = "Speech" - set desc = "Toggle your speech." - if(!ishuman(usr)) - return - - var/mob/living/carbon/human/H = usr - - if(H.miming) - H.miming = 0 - else - H << "You'll have to wait if you want to atone for your sins." - spawn(3000) - H.miming = 1 - return - diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index 36887d83f47..0b34638ef44 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -405,7 +405,7 @@ occupantData["extOrgan"] = extOrganData var/intOrganData[0] - for(var/obj/item/organ/I in H.internal_organs) + for(var/obj/item/organ/internal/I in H.internal_organs) var/organData[0] organData["name"] = I.name organData["desc"] = I.desc @@ -589,7 +589,7 @@ else dat += "[e.name]--Not Found" dat += "" - for(var/obj/item/organ/i in occupant.internal_organs) + for(var/obj/item/organ/internal/i in occupant.internal_organs) var/mech = i.desc var/infection = "None" switch (i.germ_level) diff --git a/code/game/machinery/bots/ed209bot.dm b/code/game/machinery/bots/ed209bot.dm index bb6ca81b8e6..99ff5796acc 100644 --- a/code/game/machinery/bots/ed209bot.dm +++ b/code/game/machinery/bots/ed209bot.dm @@ -38,16 +38,6 @@ bot_type_name = "ED-209" bot_filter = RADIO_SECBOT - //List of weapons that secbots will not arrest for - var/safe_weapons = list(\ - /obj/item/weapon/gun/energy/laser/bluetag,\ - /obj/item/weapon/gun/energy/laser/redtag,\ - /obj/item/weapon/gun/energy/laser/practice,\ - /obj/item/weapon/melee/classic_baton/telescopic,\ - /obj/item/weapon/gun/energy/kinetic_accelerator,\ - /obj/item/weapon/gun/energy/floragun) - - /obj/item/weapon/ed209_assembly name = "\improper ED-209 assembly" desc = "Some sort of bizarre assembly." @@ -395,9 +385,8 @@ Auto Patrol[]"}, continue /obj/machinery/bot/ed209/proc/check_for_weapons(var/obj/item/slot_item) - if(istype(slot_item, /obj/item/weapon/gun) || istype(slot_item, /obj/item/weapon/melee)) - if(!(slot_item.type in safe_weapons)) - return 1 + if(slot_item && slot_item.needs_permit) + return 1 return 0 /obj/machinery/bot/ed209/explode() diff --git a/code/game/machinery/bots/secbot.dm b/code/game/machinery/bots/secbot.dm index 8e34b0ae19e..729ce464b8c 100644 --- a/code/game/machinery/bots/secbot.dm +++ b/code/game/machinery/bots/secbot.dm @@ -31,16 +31,6 @@ bot_type_name = "Secbot" bot_filter = RADIO_SECBOT - //List of weapons that secbots will not arrest for - var/safe_weapons = list(\ - /obj/item/weapon/gun/energy/laser/bluetag,\ - /obj/item/weapon/gun/energy/laser/redtag,\ - /obj/item/weapon/gun/energy/laser/practice,\ - /obj/item/weapon/melee/classic_baton/telescopic,\ - /obj/item/weapon/gun/energy/kinetic_accelerator,\ - /obj/item/weapon/gun/energy/floragun) - - /obj/machinery/bot/secbot/beepsky name = "Officer Beepsky" desc = "It's Officer Beepsky! Powered by a potato and a shot of whiskey." @@ -378,9 +368,8 @@ Auto Patrol: []"}, else continue /obj/machinery/bot/secbot/proc/check_for_weapons(var/obj/item/slot_item) - if(istype(slot_item, /obj/item/weapon/gun) || istype(slot_item, /obj/item/weapon/melee)) - if(!(slot_item.type in safe_weapons)) - return 1 + if(slot_item && slot_item.needs_permit) + return 1 return 0 /obj/machinery/bot/secbot/explode() diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 5b1e1610e83..6e9c41ff983 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -205,8 +205,10 @@ info = X.info else P = W - itemname = P.name - info = P.notehtml + var/datum/data/pda/app/notekeeper/N = P.find_program(/datum/data/pda/app/notekeeper) + if(N) + itemname = P.name + info = N.notehtml U << "You hold \the [itemname] up to the camera ..." U.changeNext_move(CLICK_CD_MELEE) for(var/mob/O in player_list) diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 4de2a851d18..5971c758721 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -132,7 +132,7 @@ if ((M.stat != 2) || (!M.client)) continue //They need a brain! - if ((istype(M, /mob/living/carbon/human)) && (M:brain_op_stage >= 4.0)) + if(istype(M, /mob/living/carbon/human) && !M.get_int_organ(/obj/item/organ/internal/brain)) continue if (M.ckey == find_key) @@ -144,15 +144,15 @@ /obj/item/weapon/disk/data/New() ..() var/diskcolor = pick(0,1,2) - src.icon_state = "datadisk[diskcolor]" + icon_state = "datadisk[diskcolor]" /obj/item/weapon/disk/data/attack_self(mob/user as mob) - src.read_only = !src.read_only - user << "You flip the write-protect tab to [src.read_only ? "protected" : "unprotected"]." + read_only = !read_only + user << "You flip the write-protect tab to [read_only ? "protected" : "unprotected"]." /obj/item/weapon/disk/data/examine(mob/user) ..(user) - user << "The write-protect tab is set to [src.read_only ? "protected" : "unprotected"]." + user << "The write-protect tab is set to [read_only ? "protected" : "unprotected"]." //Health Tracker Implant @@ -162,24 +162,26 @@ var/healthstring = "" /obj/item/weapon/implant/health/proc/sensehealth() - if (!src.implanted) + if (!implanted) return "ERROR" else - if(isliving(src.implanted)) - var/mob/living/L = src.implanted - src.healthstring = "[round(L.getOxyLoss())] - [round(L.getFireLoss())] - [round(L.getToxLoss())] - [round(L.getBruteLoss())]" - if (!src.healthstring) - src.healthstring = "ERROR" - return src.healthstring + if(isliving(implanted)) + var/mob/living/L = implanted + healthstring = "[round(L.getOxyLoss())] - [round(L.getFireLoss())] - [round(L.getToxLoss())] - [round(L.getBruteLoss())]" + if (!healthstring) + healthstring = "ERROR" + return healthstring /obj/machinery/clonepod/attack_ai(mob/user as mob) return attack_hand(user) /obj/machinery/clonepod/attack_hand(mob/user as mob) - if ((isnull(src.occupant)) || (stat & NOPOWER)) + if ((isnull(occupant)) || (stat & NOPOWER)) + if(mess) + go_out() return - if ((!isnull(src.occupant)) && (src.occupant.stat != 2)) - var/completion = (100 * ((src.occupant.health + 100) / (src.heal_level + 100))) + if ((!isnull(occupant)) && (occupant.stat != 2)) + var/completion = (100 * ((occupant.health + 100) / (heal_level + 100))) user << "Current clone cycle is [round(completion)]% complete." return @@ -210,16 +212,16 @@ return 0 if(biomass >= CLONE_BIOMASS) - src.biomass -= CLONE_BIOMASS + biomass -= CLONE_BIOMASS else return 0 - src.attempting = 1 //One at a time!! - src.locked = 1 + attempting = 1 //One at a time!! + locked = 1 - src.eject_wait = 1 + eject_wait = 1 spawn(30) - src.eject_wait = 0 + eject_wait = 0 var/mob/living/carbon/human/H = new /mob/living/carbon/human(src, R.dna.species) occupant = H @@ -237,7 +239,6 @@ H.updatehealth() clonemind.transfer_to(H) - H.ckey = R.ckey H << "Consciousness slowly creeps over you as your body regenerates.
    So this is what cloning feels like?
    " // -- Mode/mind specific stuff goes here @@ -249,7 +250,7 @@ ticker.mode.update_synd_icons_added() if (H.mind in ticker.mode.cult) ticker.mode.add_cult_viewpoint(H) - ticker.mode.add_cultist(src.occupant.mind) + ticker.mode.add_cultist(occupant.mind) ticker.mode.update_cult_icons_added() //So the icon actually appears if(("\ref[H.mind]" in ticker.mode.implanter) || (H.mind in ticker.mode.implanted)) ticker.mode.update_traitor_icons_added(H.mind) //So the icon actually appears @@ -263,9 +264,9 @@ if(!R.dna) H.dna = new /datum/dna() H.dna.real_name = H.real_name + H.dna.ready_dna(H) else - H.dna=R.dna - H.UpdateAppearance() + H.dna = R.dna.Clone() if(efficiency > 2 && efficiency < 5 && prob(25)) randmutb(H) if(efficiency > 5 && prob(20)) @@ -275,67 +276,65 @@ H.dna.UpdateSE() H.dna.UpdateUI() -/* //let's not make people waste even more time after being cloned. - H.f_style = "Shaved" - if(R.dna.species == "Human") //no more xenos losing ears/tentacles - H.h_style = pick("Bedhead", "Bedhead 2", "Bedhead 3") */ - H.set_species(R.dna.species) + H.sync_organ_dna(1) // It's literally a fresh body as you can get, so all organs properly belong to it + H.UpdateAppearance() + H.update_body() update_icon() for(var/datum/language/L in R.languages) H.add_language(L.name) H.suiciding = 0 - src.attempting = 0 + attempting = 0 return 1 //Grow clones to maturity then kick them out. FREELOADERS /obj/machinery/clonepod/process() if(stat & NOPOWER) //Autoeject if power is lost - if (src.occupant) - src.locked = 0 - src.go_out() + if (occupant) + locked = 0 + go_out() return - if((src.occupant) && (src.occupant.loc == src)) - if((src.occupant.stat == DEAD) || (src.occupant.suiciding) || !occupant.key) //Autoeject corpses and suiciding dudes. - src.locked = 0 - src.go_out() - src.connected_message("Clone Rejected: Deceased.") + if((occupant) && (occupant.loc == src)) + if((occupant.stat == DEAD) || (occupant.suiciding) || !occupant.key) //Autoeject corpses and suiciding dudes. + locked = 0 + go_out() + connected_message("Clone Rejected: Deceased.") return - else if(src.occupant.cloneloss > (100 - src.heal_level)) - src.occupant.Paralyse(4) + else if(occupant.cloneloss > (100 - heal_level)) + occupant.Paralyse(4) //Slowly get that clone healed and finished. - src.occupant.adjustCloneLoss(-((speed_coeff/2))) + occupant.adjustCloneLoss(-((speed_coeff/2))) //Premature clones may have brain damage. - src.occupant.adjustBrainLoss(-((speed_coeff/20)*efficiency)) + occupant.adjustBrainLoss(-((speed_coeff/20)*efficiency)) //So clones don't die of oxyloss in a running pod. - if (src.occupant.reagents.get_reagent_amount("salbutamol") < 5) - src.occupant.reagents.add_reagent("salbutamol", 5) + if (occupant.reagents.get_reagent_amount("salbutamol") < 5) + occupant.reagents.add_reagent("salbutamol", 5) //Also heal some oxyloss ourselves just in case!! - src.occupant.adjustOxyLoss(-4) + occupant.adjustOxyLoss(-4) use_power(7500) //This might need tweaking. return - else if((src.occupant.cloneloss <= (100 - src.heal_level)) && (!src.eject_wait)) - src.connected_message("Cloning Process Complete.") - src.locked = 0 - src.go_out() + else if((occupant.cloneloss <= (100 - heal_level)) && (!eject_wait)) + connected_message("Cloning Process Complete.") + locked = 0 + go_out() return - else if ((!src.occupant) || (src.occupant.loc != src)) - src.occupant = null - if (src.locked) - src.locked = 0 + else if ((!occupant) || (occupant.loc != src)) + occupant = null + if (locked) + locked = 0 //use_power(200) return @@ -359,16 +358,16 @@ return if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) - if (!src.check_access(W)) + if (!check_access(W)) user << "\red Access Denied." return - if ((!src.locked) || (isnull(src.occupant))) + if ((!locked) || (isnull(occupant))) return - if ((src.occupant.health < -20) && (src.occupant.stat != 2)) + if ((occupant.health < -20) && (occupant.stat != 2)) user << "\red Access Refused." return else - src.locked = 0 + locked = 0 user << "System unlocked." //Removing cloning pod biomass @@ -379,16 +378,16 @@ qdel(W) return else if (istype(W, /obj/item/weapon/wrench)) - if(src.locked && (src.anchored || src.occupant)) + if(locked && (anchored || occupant)) user << "\red Can not do that while [src] is in use." else - if(src.anchored) - src.anchored = 0 + if(anchored) + anchored = 0 connected.pods -= src connected = null else - src.anchored = 1 - playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1) + anchored = 1 + playsound(loc, 'sound/items/Ratchet.ogg', 100, 1) if(anchored) user.visible_message("[user] secures [src] to the floor.", "You secure [src] to the floor.") else @@ -402,22 +401,22 @@ ..() /obj/machinery/clonepod/emag_act(user as mob) - if (isnull(src.occupant)) + if (isnull(occupant)) return user << "You force an emergency ejection." - src.locked = 0 - src.go_out() + locked = 0 + go_out() return //Put messages in the connected computer's temp var for display. /obj/machinery/clonepod/proc/connected_message(var/message) - if ((isnull(src.connected)) || (!istype(src.connected, /obj/machinery/computer/cloning))) + if ((isnull(connected)) || (!istype(connected, /obj/machinery/computer/cloning))) return 0 if (!message) return 0 - src.connected.temp = "[name] : [message]" - src.connected.updateUsrDialog() + connected.temp = "[name] : [message]" + connected.updateUsrDialog() return 1 /obj/machinery/clonepod/verb/eject() @@ -429,43 +428,46 @@ return if (usr.stat != 0) return - src.go_out(usr) + go_out(usr) add_fingerprint(usr) return /obj/machinery/clonepod/proc/go_out(user) - if (src.mess) //Clean that mess and dump those gibs! - src.mess = 0 - gibs(src.loc) + if (mess) //Clean that mess and dump those gibs! + if(occupant) + return + mess = 0 + gibs(loc) + playsound(loc, 'sound/effects/splat.ogg', 50, 1) update_icon() return - if (!(src.occupant)) + if (!(occupant)) user << "The cloning pod is empty!" return - if (src.locked) + if (locked) user << "The cloning pod is locked!" return - if (src.occupant.client) - src.occupant.client.eye = src.occupant.client.mob - src.occupant.client.perspective = MOB_PERSPECTIVE - src.occupant.forceMove(get_turf(src)) - src.eject_wait = 0 //If it's still set somehow. - domutcheck(src.occupant) //Waiting until they're out before possible notransform. - src.occupant = null + if (occupant.client) + occupant.client.eye = occupant.client.mob + occupant.client.perspective = MOB_PERSPECTIVE + occupant.forceMove(get_turf(src)) + eject_wait = 0 //If it's still set somehow. + domutcheck(occupant) //Waiting until they're out before possible notransform. + occupant = null update_icon() return /obj/machinery/clonepod/proc/malfunction() - if(src.occupant) - src.connected_message("Critical Error!") - src.mess = 1 + if(occupant) + connected_message("Critical Error!") + mess = 1 + occupant.ghostize() + qdel(occupant) + occupant = null update_icon() - src.occupant.ghostize() - spawn(5) - qdel(src.occupant) return /obj/machinery/clonepod/update_icon() @@ -479,7 +481,7 @@ /obj/machinery/clonepod/relaymove(mob/user as mob) if (user.stat) return - src.go_out() + go_out() return /obj/machinery/clonepod/emp_act(severity) @@ -490,22 +492,22 @@ switch(severity) if(1.0) for(var/atom/movable/A as mob|obj in src) - A.loc = src.loc - ex_act(severity) + A.forceMove(src.loc) + A.ex_act(severity) qdel(src) return if(2.0) if (prob(50)) for(var/atom/movable/A as mob|obj in src) - A.loc = src.loc - ex_act(severity) + A.forceMove(src.loc) + A.ex_act(severity) qdel(src) return if(3.0) if (prob(25)) for(var/atom/movable/A as mob|obj in src) - A.loc = src.loc - ex_act(severity) + A.forceMove(src.loc) + A.ex_act(severity) qdel(src) return else diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm index 5251898e7c7..cd30465370d 100644 --- a/code/game/machinery/computer/Operating.dm +++ b/code/game/machinery/computer/Operating.dm @@ -139,6 +139,12 @@ occupantData["bloodPercent"] = round(100*(occupant.vessel.get_reagent_amount("blood")/occupant.max_blood), 0.01) //copy pasta ends here occupantData["bloodType"]=occupant.b_type + if(occupant.surgeries.len) + occupantData["inSurgery"] = 1 + for(var/datum/surgery/procedure in occupant.surgeries) + occupantData["surgeryName"] = "[capitalize(procedure.name)]" + var/datum/surgery_step/surgery_step = procedure.get_surgery_step() + occupantData["stepName"] = "[capitalize(surgery_step.name)]" data["occupant"] = occupantData data["verbose"]=verbose diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm index 59e6e6db8eb..147901907bd 100644 --- a/code/game/machinery/computer/ai_core.dm +++ b/code/game/machinery/computer/ai_core.dm @@ -176,7 +176,7 @@ else var/mob/living/silicon/ai/A = new /mob/living/silicon/ai ( loc, laws, brain ) if(A) //if there's no brain, the mob is deleted and a structure/AIcore is created - A.rename_self("ai", 1) + A.rename_self("AI", 1) feedback_inc("cyborg_ais_created",1) qdel(src) diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index b2af98e1b5a..7277bc6a366 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -6,41 +6,7 @@ icon_keyboard = null icon_screen = "invaders" light_color = "#00FF00" - - var/list/prizes = list( /obj/item/weapon/storage/box/snappops = 2, - /obj/item/toy/AI = 2, - /obj/item/clothing/under/syndicate/tacticool = 2, - /obj/item/toy/blink = 2, - /obj/item/weapon/storage/box/fakesyndiesuit = 2, - /obj/item/toy/sword = 2, - /obj/item/weapon/gun/projectile/revolver/capgun = 2, - /obj/item/toy/crossbow = 2, - /obj/item/weapon/storage/fancy/crayons = 2, - /obj/item/toy/spinningtoy = 2, - /obj/item/toy/crossbow/tommygun = 2, - /obj/random/prize = 5, - /obj/item/toy/nuke = 2, - /obj/item/toy/cards/deck = 2, - /obj/random/carp_plushie = 2, - /obj/item/toy/minimeteor = 2, - /obj/item/toy/redbutton = 2, - /obj/item/toy/owl = 2, - /obj/item/toy/griffin = 2, - /obj/item/clothing/head/blob = 2, - /obj/item/weapon/id_decal/gold = 2, - /obj/item/weapon/id_decal/silver = 2, - /obj/item/weapon/id_decal/prisoner = 2, - /obj/item/weapon/id_decal/centcom = 2, - /obj/item/weapon/id_decal/emag = 2, - /obj/item/weapon/spellbook/oneuse/fake_gib = 2, - /obj/item/toy/foamblade = 2, - /obj/item/toy/flash = 2, - /obj/item/toy/minigibber = 2, - /obj/item/toy/toy_xeno = 2, - /obj/random/figure = 16, - /obj/random/plushie = 7, - /obj/item/stack/tile/fakespace/loaded = 2, - ) + var/prize = /obj/item/stack/tickets /obj/machinery/computer/arcade/power_change() ..() @@ -56,28 +22,22 @@ qdel(src) -/obj/machinery/computer/arcade/proc/prizevend() +/obj/machinery/computer/arcade/proc/prizevend(var/score) if(!contents.len) - var/prizeselect = pickweight(prizes) - new prizeselect(src.loc) - - if(istype(prizeselect, /obj/item/weapon/gun/projectile/revolver/capgun)) //Ammo comes with the gun - new /obj/item/ammo_box/caps(src.loc) - - else if(istype(prizeselect, /obj/item/clothing/suit/syndicatefake)) //Helmet is part of the suit - new /obj/item/clothing/head/syndicatefake(src.loc) - + var/prize_amount + if(score) + prize_amount = score + else + prize_amount = rand(1, 10) + new prize(get_turf(src), prize_amount) else var/atom/movable/prize = pick(contents) - prize.loc = src.loc + prize.loc = get_turf(src) /obj/machinery/computer/arcade/emp_act(severity) ..(severity) - if(stat & (NOPOWER|BROKEN)) return - - var/empprize = null var/num_of_prizes = 0 switch(severity) if(1) @@ -85,9 +45,8 @@ if(2) num_of_prizes = rand(0,2) for(var/i = num_of_prizes; i > 0; i--) - empprize = pickweight(prizes) - new empprize(src.loc) - explosion(src.loc, -1, 0, 1+num_of_prizes, flame_range = 1+num_of_prizes) + prizevend() + explosion(get_turf(src), -1, 0, 1+num_of_prizes, flame_range = 1+num_of_prizes) /obj/machinery/computer/arcade/battle @@ -116,20 +75,20 @@ name_part1 = pick("the Automatic ", "Farmer ", "Lord ", "Professor ", "the Cuban ", "the Evil ", "the Dread King ", "the Space ", "Lord ", "the Great ", "Duke ", "General ") name_part2 = pick("Melonoid", "Murdertron", "Sorcerer", "Ruin", "Jeff", "Ectoplasm", "Crushulon", "Uhangoid", "Vhakoid", "Peteoid", "slime", "Griefer", "ERPer", "Lizard Man", "Unicorn", "Bloopers") - src.enemy_name = replacetext((name_part1 + name_part2), "the ", "") - src.name = (name_action + name_part1 + name_part2) + enemy_name = replacetext((name_part1 + name_part2), "the ", "") + name = (name_action + name_part1 + name_part2) /obj/machinery/computer/arcade/battle/attack_hand(mob/user as mob) if(..()) return user.set_machine(src) var/dat = "Close" - dat += "

    [src.enemy_name]

    " + dat += "

    [enemy_name]

    " - dat += "

    [src.temp]

    " - dat += "
    Health: [src.player_hp] | Magic: [src.player_mp] | Enemy Health: [src.enemy_hp]
    " + dat += "

    [temp]

    " + dat += "
    Health: [player_hp] | Magic: [player_mp] | Enemy Health: [enemy_hp]
    " - if (src.gameover) + if (gameover) dat += "
    New Game" else dat += "
    Attack | " @@ -142,7 +101,7 @@ //onclose(user, "arcade") var/datum/browser/popup = new(user, "arcade", "Space Villian 2000") popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.set_title_image(user.browse_rsc_icon(icon, icon_state)) popup.open() return @@ -150,48 +109,48 @@ if(..()) return - if (!src.blocked && !src.gameover) + if (!blocked && !gameover) if (href_list["attack"]) - src.blocked = 1 + blocked = 1 var/attackamt = rand(2,6) - src.temp = "You attack for [attackamt] damage!" + temp = "You attack for [attackamt] damage!" playsound(src.loc, 'sound/arcade/Hit.ogg', 20, 1, extrarange = -6, falloff = 10) - src.updateUsrDialog() + updateUsrDialog() if(turtle > 0) turtle-- sleep(10) - src.enemy_hp -= attackamt - src.arcade_action() + enemy_hp -= attackamt + arcade_action() else if (href_list["heal"]) - src.blocked = 1 + blocked = 1 var/pointamt = rand(1,3) var/healamt = rand(6,8) - src.temp = "You use [pointamt] magic to heal for [healamt] damage!" + temp = "You use [pointamt] magic to heal for [healamt] damage!" playsound(src.loc, 'sound/arcade/Heal.ogg', 20, 1, extrarange = -6, falloff = 10) - src.updateUsrDialog() + updateUsrDialog() turtle++ sleep(10) - src.player_mp -= pointamt - src.player_hp += healamt - src.blocked = 1 - src.updateUsrDialog() - src.arcade_action() + player_mp -= pointamt + player_hp += healamt + blocked = 1 + updateUsrDialog() + arcade_action() else if (href_list["charge"]) - src.blocked = 1 + blocked = 1 var/chargeamt = rand(4,7) - src.temp = "You regain [chargeamt] points" + temp = "You regain [chargeamt] points" playsound(src.loc, 'sound/arcade/Mana.ogg', 20, 1, extrarange = -6, falloff = 10) - src.player_mp += chargeamt + player_mp += chargeamt if(turtle > 0) turtle-- - src.updateUsrDialog() + updateUsrDialog() sleep(10) - src.arcade_action() + arcade_action() if (href_list["close"]) usr.unset_machine() @@ -207,49 +166,50 @@ turtle = 0 if(emagged) - src.New() + New() emagged = 0 - src.add_fingerprint(usr) - src.updateUsrDialog() + add_fingerprint(usr) + updateUsrDialog() return /obj/machinery/computer/arcade/battle/proc/arcade_action() - if ((src.enemy_mp <= 0) || (src.enemy_hp <= 0)) + if ((enemy_mp <= 0) || (enemy_hp <= 0)) if(!gameover) - src.gameover = 1 - src.temp = "[src.enemy_name] has fallen! Rejoice!" + gameover = 1 + temp = "[enemy_name] has fallen! Rejoice!" playsound(src.loc, 'sound/arcade/Win.ogg', 20, 1, extrarange = -6, falloff = 10) if(emagged) feedback_inc("arcade_win_emagged") - new /obj/effect/spawner/newbomb/timer/syndicate(src.loc) - new /obj/item/clothing/head/collectable/petehat(src.loc) + new /obj/effect/spawner/newbomb/timer/syndicate(get_turf(src)) + new /obj/item/clothing/head/collectable/petehat(get_turf(src)) message_admins("[key_name_admin(usr)] has outbombed Cuban Pete and been awarded a bomb.") log_game("[key_name(usr)] has outbombed Cuban Pete and been awarded a bomb.") - src.New() + New() emagged = 0 else feedback_inc("arcade_win_normal") - prizevend() + var/score = player_hp + player_mp + 5 + prizevend(score) else if (emagged && (turtle >= 4)) var/boomamt = rand(5,10) - src.temp = "[src.enemy_name] throws a bomb, exploding you for [boomamt] damage!" + temp = "[enemy_name] throws a bomb, exploding you for [boomamt] damage!" playsound(src.loc, 'sound/arcade/Boom.ogg', 20, 1, extrarange = -6, falloff = 10) - src.player_hp -= boomamt + player_hp -= boomamt - else if ((src.enemy_mp <= 5) && (prob(70))) + else if ((enemy_mp <= 5) && (prob(70))) var/stealamt = rand(2,3) - src.temp = "[src.enemy_name] steals [stealamt] of your power!" + temp = "[enemy_name] steals [stealamt] of your power!" playsound(src.loc, 'sound/arcade/Steal.ogg', 20, 1, extrarange = -6, falloff = 10) - src.player_mp -= stealamt - src.updateUsrDialog() + player_mp -= stealamt + updateUsrDialog() - if (src.player_mp <= 0) - src.gameover = 1 + if (player_mp <= 0) + gameover = 1 sleep(10) - src.temp = "You have been drained! GAME OVER" + temp = "You have been drained! GAME OVER" playsound(src.loc, 'sound/arcade/Lose.ogg', 20, 1, extrarange = -6, falloff = 10) if(emagged) feedback_inc("arcade_loss_mana_emagged") @@ -257,21 +217,21 @@ else feedback_inc("arcade_loss_mana_normal") - else if ((src.enemy_hp <= 10) && (src.enemy_mp > 4)) - src.temp = "[src.enemy_name] heals for 4 health!" + else if ((enemy_hp <= 10) && (enemy_mp > 4)) + temp = "[enemy_name] heals for 4 health!" playsound(src.loc, 'sound/arcade/Heal.ogg', 20, 1, extrarange = -6, falloff = 10) - src.enemy_hp += 4 - src.enemy_mp -= 4 + enemy_hp += 4 + enemy_mp -= 4 else var/attackamt = rand(3,6) - src.temp = "[src.enemy_name] attacks for [attackamt] damage!" + temp = "[enemy_name] attacks for [attackamt] damage!" playsound(src.loc, 'sound/arcade/Hit.ogg', 20, 1, extrarange = -6, falloff = 10) - src.player_hp -= attackamt + player_hp -= attackamt - if ((src.player_mp <= 0) || (src.player_hp <= 0)) - src.gameover = 1 - src.temp = "You have been crushed! GAME OVER" + if ((player_mp <= 0) || (player_hp <= 0)) + gameover = 1 + temp = "You have been crushed! GAME OVER" playsound(src.loc, 'sound/arcade/Lose.ogg', 20, 1, extrarange = -6, falloff = 10) if(emagged) feedback_inc("arcade_loss_hp_emagged") @@ -279,7 +239,7 @@ else feedback_inc("arcade_loss_hp_normal") - src.blocked = 0 + blocked = 0 return @@ -298,7 +258,7 @@ enemy_name = "Cuban Pete" name = "Outbomb Cuban Pete" - src.updateUsrDialog() + updateUsrDialog() // *** THE ORION TRAIL ** // @@ -450,7 +410,7 @@ dat += "

    Close

    " var/datum/browser/popup = new(user, "arcade", "The Orion Trail",400,700) popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.set_title_image(user.browse_rsc_icon(icon, icon_state)) popup.open() return @@ -537,7 +497,7 @@ playsound(src.loc, 'sound/effects/bang.ogg', 20, 1) if(ORION_TRAIL_MALFUNCTION) playsound(src.loc, 'sound/effects/EMPulse.ogg', 20, 1) - src.visible_message("[src] malfunctions, randomizing in-game stats!") + visible_message("[src] malfunctions, randomizing in-game stats!") var/oldfood = food var/oldfuel = fuel food = rand(10,80) / rand(1,2) @@ -545,9 +505,9 @@ if(electronics) sleep(10) if(oldfuel > fuel && oldfood > food) - src.audible_message("[src] lets out a somehow reassuring chime.") + audible_message("[src] lets out a somehow reassuring chime.") else if(oldfuel < fuel || oldfood < food) - src.audible_message("[src] lets out a somehow ominous chime.") + audible_message("[src] lets out a somehow ominous chime.") food = oldfood fuel = oldfuel playsound(src.loc, 'sound/machines/chime.ogg', 20, 1) @@ -709,8 +669,8 @@ last_spaceport_action = "Traded Food for Fuel" event() - src.add_fingerprint(usr) - src.updateUsrDialog() + add_fingerprint(usr) + updateUsrDialog() busy = 0 return @@ -984,11 +944,12 @@ turns = 1 atom_say("Congratulations, you made it to Orion!") if(emagged) - new /obj/item/weapon/orion_ship(src.loc) + new /obj/item/weapon/orion_ship(get_turf(src)) message_admins("[key_name_admin(usr)] made it to Orion on an emagged machine and got an explosive toy ship.") log_game("[key_name(usr)] made it to Orion on an emagged machine and got an explosive toy ship.") else - prizevend() + var/score = alive + round(food/2) + round(fuel/5) + engine + hull + electronics - lings_aboard + prizevend(score) emagged = 0 name = "The Orion Trail" desc = "Learn how our ancestors got to Orion, and have fun in the process!" @@ -1047,17 +1008,17 @@ user << "You flip the switch on the underside of [src]." active = 1 - src.visible_message("[src] softly beeps and whirs to life!") + visible_message("[src] softly beeps and whirs to life!") playsound(src.loc, 'sound/machines/defib_SaftyOn.ogg', 25, 1) atom_say("This is ship ID #[rand(1,1000)] to Orion Port Authority. We're coming in for landing, over.") sleep(20) - src.visible_message("[src] begins to vibrate...") + visible_message("[src] begins to vibrate...") atom_say("Uh, Port? Having some issues with our reactor, could you check it out? Over.") sleep(30) atom_say("Oh, God! Code Eight! CODE EIGHT! IT'S GONNA BL-") playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 25, 1) sleep(3.6) - src.visible_message("[src] explodes!") + visible_message("[src] explodes!") explosion(src.loc, 1,2,4, flame_range = 3) qdel(src) diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm index 07fce5f703b..c80298283bc 100644 --- a/code/game/machinery/computer/buildandrepair.dm +++ b/code/game/machinery/computer/buildandrepair.dm @@ -66,7 +66,7 @@ name = "Circuit board (ID Computer)" build_path = /obj/machinery/computer/card /obj/item/weapon/circuitboard/card/centcom - name = "Circuit board (CentCom ID Computer)" + name = "Circuit board (CentComm ID Computer)" build_path = /obj/machinery/computer/card/centcom /obj/item/weapon/circuitboard/teleporter name = "Circuit board (Teleporter Console)" diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 1e6c8c2f5a6..bcbafc5ffe5 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -41,7 +41,7 @@ networks["Telepad"] = list(access_rd,access_hos,access_captain) networks["TestChamber"] = list(access_rd,access_hos,access_captain) networks["ERT"] = list(access_cent_specops_commander,access_cent_commander) - networks["CentCom"] = list(access_cent_security,access_cent_commander) + networks["CentComm"] = list(access_cent_security,access_cent_commander) networks["Thunderdome"] = list(access_cent_thunder,access_cent_commander) ..() diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm index 92c642a3495..165e30b4ebb 100644 --- a/code/game/machinery/computer/card.dm +++ b/code/game/machinery/computer/card.dm @@ -431,6 +431,6 @@ var/time_last_changed_position = 0 return 1 /obj/machinery/computer/card/centcom - name = "\improper CentCom identification computer" + name = "\improper CentComm identification computer" circuit = /obj/item/weapon/circuitboard/card/centcom req_access = list(access_cent_commander) diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index a04ecb252b0..411673628cc 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -16,6 +16,9 @@ var/loading = 0 // Nice loading text var/autoprocess = 0 var/obj/machinery/clonepod/selected_pod + // 0: Standard body scan + // 1: The "Best" scan available + var/scan_mode = 1 light_color = LIGHT_COLOR_DARKBLUE @@ -31,7 +34,7 @@ if(!scanner || !pods.len || !autoprocess || stat & NOPOWER) return - if(scanner.occupant && (scanner.scan_level > 2)) + if(scanner.occupant && can_autoprocess()) scan_mob(scanner.occupant) for (var/obj/machinery/clonepod/pod in pods) @@ -135,6 +138,8 @@ data["loading"] = loading data["autoprocess"] = autoprocess + data["can_brainscan"] = can_brainscan() // You'll need tier 4s for this + data["scan_mode"] = scan_mode if(scanner && pods.len && ((scanner.scan_level > 2) || canpodautoprocess)) data["autoallowed"] = 1 @@ -184,13 +189,16 @@ if(loading) return - if ((href_list["scan"]) && (!isnull(src.scanner))) + if (href_list["scan"] && scanner && scanner.occupant) scantemp = "Scanner ready." loading = 1 spawn(20) - src.scan_mob(src.scanner.occupant) + if(can_brainscan() && scan_mode) + scan_mob(scanner.occupant, scan_brain = 1) + else + scan_mob(scanner.occupant) loading = 0 nanomanager.update_uis(src) @@ -254,7 +262,7 @@ nanomanager.update_uis(src) return - src.active_record = src.diskette.buf + src.active_record = src.diskette.buf.copy() src.temp = "Load successful." @@ -270,7 +278,7 @@ return // DNA2 makes things a little simpler. - src.diskette.buf=src.active_record + src.diskette.buf=src.active_record.copy() src.diskette.buf.types=0 switch(href_list["save_disk"]) //Save as Ui/Ui+Ue/Se if("ui") @@ -335,21 +343,36 @@ src.menu = text2num(href_list["menu"]) temp = "" scantemp = "Scanner ready." + else if (href_list["toggle_mode"]) + if(can_brainscan()) + scan_mode = !scan_mode + else + scan_mode = 0 src.add_fingerprint(usr) nanomanager.update_uis(src) return -/obj/machinery/computer/cloning/proc/scan_mob(mob/living/carbon/human/subject as mob) +/obj/machinery/computer/cloning/proc/scan_mob(mob/living/carbon/human/subject as mob, var/scan_brain = 0) if (stat & NOPOWER) return if (scanner.stat & (NOPOWER|BROKEN)) return + if (scan_brain && !can_brainscan()) + return if ((isnull(subject)) || (!(ishuman(subject))) || (!subject.dna) || (subject.species.flags & NO_SCAN)) scantemp = "Error: Unable to locate valid genetic data." nanomanager.update_uis(src) return - if (subject.brain_op_stage == 4.0) + if(subject.get_int_organ(/obj/item/organ/internal/brain)) + var/obj/item/organ/internal/brain/Brn = subject.get_int_organ(/obj/item/organ/internal/brain) + if(istype(Brn)) + var/datum/species/S = all_species[Brn.dna.species] // stepladder code wooooo + if(S.flags & NO_SCAN) + scantemp = "Error: Subject's brain is incompatible." + nanomanager.update_uis(src) + return + if(!subject.get_int_organ(/obj/item/organ/internal/brain)) scantemp = "Error: No signs of intelligence detected." nanomanager.update_uis(src) return @@ -365,6 +388,10 @@ scantemp = "Error: Mental interface failure." nanomanager.update_uis(src) return + if (scan_brain && !subject.get_int_organ(/obj/item/organ/internal/brain)) + scantemp = "Error: No brain found." + nanomanager.update_uis(src) + return if (!isnull(find_record(subject.ckey))) scantemp = "Subject already in database." nanomanager.update_uis(src) @@ -373,13 +400,25 @@ subject.dna.check_integrity() var/datum/dna2/record/R = new /datum/dna2/record() - R.dna=subject.dna R.ckey = subject.ckey - R.id= copytext(md5(subject.real_name), 2, 6) - R.name=R.dna.real_name + var/extra_info = "" + if(scan_brain) + var/obj/item/organ/B = subject.get_int_organ(/obj/item/organ/internal/brain) + B.dna.check_integrity() + R.dna=B.dna.Clone() + var/datum/species/S = all_species[R.dna.species] + if(S.flags & NO_SCAN) + extra_info = "Proper genetic interface not found, defaulting to genetic data of the body." + R.dna.species = subject.species.name + R.id= copytext(md5(B.dna.real_name), 2, 6) + R.name=B.dna.real_name + else + R.dna=subject.dna.Clone() + R.id= copytext(md5(subject.real_name), 2, 6) + R.name=R.dna.real_name + R.types=DNA2_BUF_UI|DNA2_BUF_UE|DNA2_BUF_SE R.languages=subject.languages - //Add an implant if needed var/obj/item/weapon/implant/health/imp = locate(/obj/item/weapon/implant/health, subject) if (isnull(imp)) @@ -394,7 +433,7 @@ R.mind = "\ref[subject.mind]" src.records += R - scantemp = "Subject successfully scanned." + scantemp = "Subject successfully scanned. " + extra_info nanomanager.update_uis(src) //Find a specific record by key. @@ -404,4 +443,10 @@ if (R.ckey == find_key) selected_record = R break - return selected_record \ No newline at end of file + return selected_record + +/obj/machinery/computer/cloning/proc/can_autoprocess() + return (scanner && scanner.scan_level > 2) + +/obj/machinery/computer/cloning/proc/can_brainscan() + return (scanner && scanner.scan_level > 3) \ No newline at end of file diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm index 0ebb13efcd6..136abe54100 100644 --- a/code/game/machinery/computer/message.dm +++ b/code/game/machinery/computer/message.dm @@ -408,7 +408,10 @@ //Get out list of viable PDAs var/list/obj/item/device/pda/sendPDAs = list() for(var/obj/item/device/pda/P in PDAs) - if(!P.owner || P.toff || P.hidden) continue + var/datum/data/pda/app/messenger/PM = P.find_program(/datum/data/pda/app/messenger) + + if(!PM || !PM.can_receive()) + continue sendPDAs += P if(PDAs && PDAs.len > 0) customrecepient = input(usr, "Select a PDA from the list.") as null|anything in sortAtom(sendPDAs) @@ -426,7 +429,6 @@ //Send message if("Send") - if(isnull(customsender) || customsender == "") customsender = "UNKNOWN" @@ -438,36 +440,44 @@ message = "NOTICE: No message entered!" return src.attack_hand(usr) + var/datum/data/pda/app/messenger/recipient_messenger = customrecepient.find_program(/datum/data/pda/app/messenger) + + if(!recipient_messenger) + message = "ERROR: Message could not be transmitted!" + return src.attack_hand(usr) + var/obj/item/device/pda/PDARec = null for (var/obj/item/device/pda/P in PDAs) - if (!P.owner || P.toff || P.hidden) continue + var/datum/data/pda/app/messenger/PM = P.find_program(/datum/data/pda/app/messenger) + + if (!PM || !PM.can_receive()) + continue if(P.owner == customsender) PDARec = P + break //Sender isn't faking as someone who exists if(isnull(PDARec)) src.linkedServer.send_pda_message("[customrecepient.owner]", "[customsender]","[custommessage]") - customrecepient.play_ringtone() + recipient_messenger.play_ringtone() if( customrecepient.loc && ishuman(customrecepient.loc) ) var/mob/living/carbon/human/H = customrecepient.loc - H << "\icon[customrecepient] Message from [customsender] ([customjob]), \"[custommessage]\" (Reply)" + H << "\icon[customrecepient] Message from [customsender] ([customjob]), \"[custommessage]\" (Reply)" log_pda("[usr] (PDA: [customsender]) sent \"[custommessage]\" to [customrecepient.owner]") - customrecepient.overlays.Cut() - customrecepient.overlays += image('icons/obj/pda.dmi', "pda-r") + recipient_messenger.set_new(1) //Sender is faking as someone who exists else src.linkedServer.send_pda_message("[customrecepient.owner]", "[PDARec.owner]","[custommessage]") - customrecepient.tnote.Add(list(list("sent" = 0, "owner" = "[PDARec.owner]", "job" = "[customjob]", "message" = "[custommessage]", "target" ="\ref[PDARec]"))) + recipient_messenger.tnote.Add(list(list("sent" = 0, "owner" = "[PDARec.owner]", "job" = "[customjob]", "message" = "[custommessage]", "target" ="\ref[PDARec]"))) - if(!customrecepient.conversations.Find("\ref[PDARec]")) - customrecepient.conversations.Add("\ref[PDARec]") + if(!recipient_messenger.conversations.Find("\ref[PDARec]")) + recipient_messenger.conversations.Add("\ref[PDARec]") - customrecepient.play_ringtone() + recipient_messenger.play_ringtone() if( customrecepient.loc && ishuman(customrecepient.loc) ) var/mob/living/carbon/human/H = customrecepient.loc - H << "\icon[customrecepient] Message from [PDARec.owner] ([customjob]), \"[custommessage]\" (Reply)" + H << "\icon[customrecepient] Message from [PDARec.owner] ([customjob]), \"[custommessage]\" (Reply)" log_pda("[usr] (PDA: [PDARec.owner]) sent \"[custommessage]\" to [customrecepient.owner]") - customrecepient.overlays.Cut() - customrecepient.overlays += image('icons/obj/pda.dmi', "pda-r") + recipient_messenger.set_new(1) //Finally.. ResetMessage() diff --git a/code/game/machinery/computer/power.dm b/code/game/machinery/computer/power.dm index a549dd5b64d..ca3c1f84410 100644 --- a/code/game/machinery/computer/power.dm +++ b/code/game/machinery/computer/power.dm @@ -16,6 +16,9 @@ power_monitors += src power_monitors = sortAtom(power_monitors) power_monitor = new(src) + +/obj/machinery/computer/monitor/initialize() + ..() powermonitor_repository.update_cache() powernet = find_powernet() diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index f4c6cc90c57..b52a15d77c3 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -499,7 +499,7 @@ to destroy them and players will be able to make replacements. /obj/item/weapon/circuitboard/destructive_analyzer name = "Circuit board (Destructive Analyzer)" - build_path = "/obj/machinery/r_n_d/destructive_analyzer" + build_path = /obj/machinery/r_n_d/destructive_analyzer board_type = "machine" origin_tech = "magnets=2;engineering=2;programming=2" frame_desc = "Requires 1 Scanning Module, 1 Manipulator, and 1 Micro-Laser." @@ -510,7 +510,7 @@ to destroy them and players will be able to make replacements. /obj/item/weapon/circuitboard/autolathe name = "Circuit board (Autolathe)" - build_path = "/obj/machinery/autolathe" + build_path = /obj/machinery/autolathe board_type = "machine" origin_tech = "engineering=2;programming=2" frame_desc = "Requires 3 Matter Bins, 1 Manipulator, and 1 Console Screen." @@ -521,7 +521,7 @@ to destroy them and players will be able to make replacements. /obj/item/weapon/circuitboard/protolathe name = "Circuit board (Protolathe)" - build_path = "/obj/machinery/r_n_d/protolathe" + build_path = /obj/machinery/r_n_d/protolathe board_type = "machine" origin_tech = "engineering=2;programming=2" frame_desc = "Requires 2 Matter Bins, 2 Manipulators, and 2 Beakers." @@ -533,7 +533,7 @@ to destroy them and players will be able to make replacements. /obj/item/weapon/circuitboard/circuit_imprinter name = "Circuit board (Circuit Imprinter)" - build_path = "/obj/machinery/r_n_d/circuit_imprinter" + build_path = /obj/machinery/r_n_d/circuit_imprinter board_type = "machine" origin_tech = "engineering=2;programming=2" frame_desc = "Requires 1 Matter Bin, 1 Manipulator, and 2 Beakers." @@ -544,7 +544,7 @@ to destroy them and players will be able to make replacements. /obj/item/weapon/circuitboard/pacman name = "Circuit Board (PACMAN-type Generator)" - build_path = "/obj/machinery/power/port_gen/pacman" + build_path = /obj/machinery/power/port_gen/pacman board_type = "machine" origin_tech = "programming=3:powerstorage=3;plasmatech=3;engineering=3" frame_desc = "Requires 1 Matter Bin, 1 Micro-Laser, 2 Pieces of Cable, and 1 Capacitor." @@ -556,17 +556,17 @@ to destroy them and players will be able to make replacements. /obj/item/weapon/circuitboard/pacman/super name = "Circuit Board (SUPERPACMAN-type Generator)" - build_path = "/obj/machinery/power/port_gen/pacman/super" + build_path = /obj/machinery/power/port_gen/pacman/super origin_tech = "programming=3;powerstorage=4;engineering=4" /obj/item/weapon/circuitboard/pacman/mrs name = "Circuit Board (MRSPACMAN-type Generator)" - build_path = "/obj/machinery/power/port_gen/pacman/mrs" + build_path = /obj/machinery/power/port_gen/pacman/mrs origin_tech = "programming=3;powerstorage=5;engineering=5" obj/item/weapon/circuitboard/rdserver name = "Circuit Board (R&D Server)" - build_path = "/obj/machinery/r_n_d/server" + build_path = /obj/machinery/r_n_d/server board_type = "machine" origin_tech = "programming=3" frame_desc = "Requires 2 pieces of cable, and 1 Scanning Module." @@ -576,7 +576,7 @@ obj/item/weapon/circuitboard/rdserver /obj/item/weapon/circuitboard/mechfab name = "Circuit board (Exosuit Fabricator)" - build_path = "/obj/machinery/mecha_part_fabricator" + build_path = /obj/machinery/mecha_part_fabricator board_type = "machine" origin_tech = "programming=3;engineering=3" frame_desc = "Requires 2 Matter Bins, 1 Manipulator, 1 Micro-Laser and 1 Console Screen." @@ -588,7 +588,7 @@ obj/item/weapon/circuitboard/rdserver /obj/item/weapon/circuitboard/podfab name = "Circuit board (Spacepod Fabricator)" - build_path = "/obj/machinery/spod_part_fabricator" //ah fuck my life + build_path = /obj/machinery/spod_part_fabricator //ah fuck my life board_type = "machine" origin_tech = "programming=3;engineering=3" frame_desc = "Requires 3 Matter Bins, 2 Manipulators, 2 Micro-Lasers, and 1 Console Screen." @@ -601,7 +601,7 @@ obj/item/weapon/circuitboard/rdserver /obj/item/weapon/circuitboard/clonepod name = "Circuit board (Clone Pod)" - build_path = "/obj/machinery/clonepod" + build_path = /obj/machinery/clonepod board_type = "machine" origin_tech = "programming=3;biotech=3" frame_desc = "Requires 2 Manipulator, 2 Scanning Module, 2 pieces of cable and 1 Console Screen." @@ -613,7 +613,7 @@ obj/item/weapon/circuitboard/rdserver /obj/item/weapon/circuitboard/clonescanner name = "Circuit board (Cloning Scanner)" - build_path = "/obj/machinery/dna_scannernew" + build_path = /obj/machinery/dna_scannernew board_type = "machine" origin_tech = "programming=2;biotech=2" frame_desc = "Requires 1 Scanning Module, 1 Manipulator, 1 Micro-Laser, 2 pieces of cable and 1 Console Screen." @@ -844,7 +844,18 @@ obj/item/weapon/circuitboard/rdserver board_type = "machine" origin_tech = "programming=2" req_components = list( - /obj/item/weapon/stock_parts.matter_bin = 1, + /obj/item/weapon/stock_parts/matter_bin = 1, /obj/item/weapon/stock_parts/manipulator = 1, /obj/item/stack/cable_coil = 5, - /obj/item/stack/sheet/glass = 1) \ No newline at end of file + /obj/item/stack/sheet/glass = 1) + +/obj/item/weapon/circuitboard/prize_counter + name = "circuit board (Prize Counter)" + build_path = /obj/machinery/prize_counter + board_type = "machine" + origin_tech = "programming=2;materials=2" + req_components = list( + /obj/item/weapon/stock_parts/matter_bin = 1, + /obj/item/weapon/stock_parts/manipulator = 1, + /obj/item/weapon/stock_parts/console_screen = 1, + /obj/item/stack/cable_coil = 1) \ No newline at end of file diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index 9b4bec6516d..705f997a3eb 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -17,6 +17,8 @@ var/current_heat_capacity = 50 var/efficiency + 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() ..() @@ -327,34 +329,37 @@ overlays += pickle overlays += "lid[on]" - if(src.on) //no bobbing if off + if(src.on && !running_bob_animation) //no bobbing if off var/up = 0 //used to see if we are going up or down, 1 is down, 2 is up - while(occupant) - overlays -= "lid[on]" //have to remove the overlays first, to force an update- remove cloning pod overlay - overlays -= pickle //remove mob overlay + spawn(0) // Without this, the icon update will block. The new thread will die once the occupant leaves. + running_bob_animation = 1 + while(occupant) + overlays -= "lid[on]" //have to remove the overlays first, to force an update- remove cloning pod overlay + overlays -= pickle //remove mob overlay - switch(pickle.pixel_y) //this looks messy as fuck but it works, switch won't call itself twice + switch(pickle.pixel_y) //this looks messy as fuck but it works, switch won't call itself twice - if(23) //inbetween state, for smoothness - switch(up) //this is set later in the switch, to keep track of where the mob is supposed to go - if(2) //2 is up - pickle.pixel_y = 24 //set to highest + if(23) //inbetween state, for smoothness + switch(up) //this is set later in the switch, to keep track of where the mob is supposed to go + if(2) //2 is up + pickle.pixel_y = 24 //set to highest - if(1) //1 is down - pickle.pixel_y = 22 //set to lowest + if(1) //1 is down + pickle.pixel_y = 22 //set to lowest - if(22) //mob is at it's lowest - pickle.pixel_y = 23 //set to inbetween - up = 2 //have to go up + if(22) //mob is at it's lowest + pickle.pixel_y = 23 //set to inbetween + up = 2 //have to go up - if(24) //mob is at it's highest - pickle.pixel_y = 23 //set to inbetween - up = 1 //have to go down + if(24) //mob is at it's highest + pickle.pixel_y = 23 //set to inbetween + up = 1 //have to go down - overlays += pickle //re-add the mob to the icon - overlays += "lid[on]" //re-add the overlay of the pod, they are inside it, not floating + overlays += pickle //re-add the mob to the icon + overlays += "lid[on]" //re-add the overlay of the pod, they are inside it, not floating - sleep(7) //don't want to jiggle violently, just slowly bob + sleep(7) //don't want to jiggle violently, just slowly bob + running_bob_animation = 0 /obj/machinery/atmospherics/unary/cryo_cell/proc/process_occupant() if(air_contents.total_moles() < 10) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 83e1f3f723e..65880ef5da6 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -352,8 +352,8 @@ About the new airlock wires panel: return else if(user.hallucination > 50 && prob(10) && src.operating == 0) user << "\red You feel a powerful shock course through your body!" - user.staminaloss += 50 - user.stunned += 5 + user.adjustStaminaLoss(50) + user.AdjustStunned(5) return ..(user) diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index f22c68bb0f0..86e723bca8b 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -84,7 +84,7 @@ O.visible_message("[O] gasps and shields their eyes!") if (istype(O, /mob/living/carbon/human)) var/mob/living/carbon/human/H = O - var/obj/item/organ/eyes/E = H.internal_organs_by_name["eyes"] + var/obj/item/organ/internal/eyes/E = H.get_int_organ(/obj/item/organ/internal/eyes) if (E && (E.damage > E.min_bruised_damage && prob(E.damage + 50))) flick("e_flash", O:flash) E.damage += rand(1, 2) diff --git a/code/game/machinery/kitchen/icecream_vat.dm b/code/game/machinery/kitchen/icecream_vat.dm index 76cbac6f581..d88d3a1dc9e 100644 --- a/code/game/machinery/kitchen/icecream_vat.dm +++ b/code/game/machinery/kitchen/icecream_vat.dm @@ -12,7 +12,7 @@ var/list/ingredients_source = list( "berryjuice" = FLAVOUR_STRAWBERRY,\ -"coco" = FLAVOUR_CHOCOLATE,\ +"cocoa" = FLAVOUR_CHOCOLATE,\ "singulo" = FLAVOUR_BLUE,\ "milk" = INGR_MILK,\ "soymilk" = INGR_MILK,\ diff --git a/code/game/machinery/poolcontroller.dm b/code/game/machinery/poolcontroller.dm index f9898a3de00..06a48a79e89 100644 --- a/code/game/machinery/poolcontroller.dm +++ b/code/game/machinery/poolcontroller.dm @@ -5,15 +5,18 @@ icon_state = "airlock_control_standby" anchored = 1 //this is what I get for assuming /obj/machinery has anchored set to 1 by default var/list/linkedturfs = list() //List contains all of the linked pool turfs to this controller, assignment happens on New() + var/linked_area = null var/temperature = "normal" //The temperature of the pool, starts off on normal, which has no effects. var/temperaturecolor = "" //used for nanoUI fancyness var/srange = 5 //The range of the search for pool turfs, change this for bigger or smaller pools. var/list/linkedmist = list() //Used to keep track of created mist + var/deep_water = 0 //set to 1 to drown even standing people /obj/machinery/poolcontroller/New() //This proc automatically happens on world start - for(var/turf/simulated/floor/beach/water/W in range(srange,src)) //Search for /turf/simulated/floor/beach/water in the range of var/srange - linkedturfs += W //Add found pool turfs to the central list. + if(!linked_area) + for(var/turf/simulated/floor/beach/water/W in range(srange,src)) //Search for /turf/simulated/floor/beach/water in the range of var/srange + linkedturfs += W //Add found pool turfs to the central list. ..() //Changed to call parent as per MarkvA's recommendation /obj/machinery/poolcontroller/emag_act(user as mob) //Emag_act, this is called when it is hit with a cryptographic sequencer. @@ -39,63 +42,74 @@ updatePool() //Call the mob affecting/decal cleaning proc /obj/machinery/poolcontroller/proc/updatePool() - for(var/turf/simulated/floor/beach/water/W in linkedturfs) //Check for pool-turfs linked to the controller. - for(var/mob/M in W) //Check for mobs in the linked pool-turfs. - //Sanity checks, don't affect robuts, AI eyes, and observers - if(isAIEye(M)) - continue - if(issilicon(M)) - continue - if(isobserver(M)) - continue - if(M.stat == DEAD) - continue - //End sanity checks, go on - switch(temperature) //Apply different effects based on what the temperature is set to. - if("scalding") //Burn the mob. - M.bodytemperature = min(500, M.bodytemperature + 35) //heat mob at 35k(elvin) per cycle - M << "The water is searing hot!" - - if("warm") //Gently warm the mob. - M.bodytemperature = min(330, M.bodytemperature + 10) //Heats up mobs to just over normal, not enough to burn - if(prob(50)) //inform the mob of warm water half the time - M << "The water is quite warm." //Inform the mob it's warm water. - - if("cool") //Gently cool the mob. - M.bodytemperature = max(290, M.bodytemperature - 10) //Cools mobs to just below normal, not enough to burn - if(prob(50)) //inform the mob of cold water half the time - M << "The water is chilly." //Inform the mob it's chilly water. - - if("frigid") //Freeze the mob. - M.bodytemperature = max(80, M.bodytemperature - 35) //cool mob at -35k per cycle - M << "The water is freezing!" - + for(var/turf/T in linkedturfs) //Check for pool-turfs linked to the controller. + for(var/mob/M in T) //Check for mobs in the linked pool-turfs. + handleTemp(M) //handles pool temp effects on the swimmers if(ishuman(M)) //Make sure they are human before typecasting. var/mob/living/carbon/human/drownee = M //Typecast them as human. - if(drownee && drownee.lying) //Mob lying down - if(drownee.internal) - continue //Has internals, no drowning - if((drownee.species.flags & NO_BREATHE) || (NO_BREATHE in drownee.mutations)) - continue //doesn't breathe, no drowning - if(drownee.get_species() == "Skrell" || drownee.get_species() == "Neara") - continue //fish things don't drown + handleDrowning(drownee) //Only human types will drown, to keep things simple for non-human mobs that live in the water - if(drownee.stat) //Mob is in critical. - drownee.adjustOxyLoss(9) //Kill em quickly. - add_logs(drownee, src, "drowned") - drownee.visible_message("\The [drownee] appears to be drowning!","You're quickly drowning!") //inform them that they are fucked. - else - drownee.adjustOxyLoss(5) //5 oxyloss per cycle. - add_logs(drownee, src, "drowned") - if(prob(35)) //35% chance to tell them what is going on. They should probably figure it out before then. - drownee.visible_message("\The [drownee] flails, almost like they are drowning!","You're lacking air!") //*gasp* *gasp* *gasp* *gasp* *gasp* - - for(var/obj/effect/decal/cleanable/decal in W) + for(var/obj/effect/decal/cleanable/decal in T) //Cleans up cleanable decals like blood and such animate(decal, alpha = 10, time = 20) spawn(25) qdel(decal) +/obj/machinery/poolcontroller/proc/handleTemp(var/mob/M) + if(temperature == "normal") //This setting does nothing, so let's skip the next checks since we won't be doing jack + return + if(!M || isAIEye(M) || issilicon(M) || isobserver(M) || M.stat == DEAD) + return + + switch(temperature) //Apply different effects based on what the temperature is set to. + if("scalding") //Burn the mob. + M.bodytemperature = min(500, M.bodytemperature + 35) //heat mob at 35k(elvin) per cycle + M << "The water is searing hot!" + + if("warm") //Gently warm the mob. + M.bodytemperature = min(330, M.bodytemperature + 10) //Heats up mobs to just over normal, not enough to burn + if(prob(50)) //inform the mob of warm water half the time + M << "The water is quite warm." //Inform the mob it's warm water. + + if("cool") //Gently cool the mob. + M.bodytemperature = max(290, M.bodytemperature - 10) //Cools mobs to just below normal, not enough to burn + if(prob(50)) //inform the mob of cold water half the time + M << "The water is chilly." //Inform the mob it's chilly water. + + if("frigid") //Freeze the mob. + M.bodytemperature = max(80, M.bodytemperature - 35) //cool mob at -35k per cycle + M << "The water is freezing!" + return + +/obj/machinery/poolcontroller/proc/handleDrowning(var/mob/living/carbon/human/drownee) + if(!drownee) + return + + if(drownee && (drownee.lying || deep_water)) //Mob lying down or water is deep (determined by controller) + if(drownee.internal) + return //Has internals, no drowning + if((drownee.species.flags & NO_BREATHE) || (NO_BREATHE in drownee.mutations)) + return //doesn't breathe, no drowning + if(drownee.get_species() == "Skrell" || drownee.get_species() == "Neara") + return //fish things don't drown + + if(drownee.stat == DEAD) //Dead spacemen don't drown more + return + if(drownee.losebreath > 20) //You've probably got bigger problems than drowning at this point, so we won't add to it until you get that under control. + return + + if(drownee.stat) //Mob is in critical. + drownee.losebreath -= 3 //You're gonna die here. + add_logs(drownee, src, "drowned") + drownee.visible_message("\The [drownee] appears to be drowning!","You're quickly drowning!") //inform them that they are fucked. + else + drownee.losebreath -= 2 //For every time you drown, you miss 2 breath attempts. Hope you catch on quick! + add_logs(drownee, src, "drowned") + if(prob(35)) //35% chance to tell them what is going on. They should probably figure it out before then. + drownee.visible_message("\The [drownee] flails, almost like they are drowning!","You're lacking air!") //*gasp* *gasp* *gasp* *gasp* *gasp* + + + /obj/machinery/poolcontroller/proc/miston() //Spawn /obj/effect/mist (from the shower) on all linked pool tiles if(linkedmist.len) return @@ -155,4 +169,30 @@ temperaturecolor = "" mistoff() - return 1 \ No newline at end of file + return 1 + +/obj/machinery/poolcontroller/seacontroller + invisibility = 101 + unacidable = 1 + + name = "Sea Controller" + desc = "A controller for the underwater portion of the sea. Players shouldn't see this." + deep_water = 1 //deep sea is deep water + +/obj/machinery/poolcontroller/seacontroller/New() + linked_area = get_area(src) + ..() + +/obj/machinery/poolcontroller/seacontroller/updatePool() + for(var/turf/T in linked_area) + for(var/mob/M in T) + handleTemp(M) //handles pool temp effects on the swimmers + + if(ishuman(M)) //Make sure they are human before typecasting. + var/mob/living/carbon/human/drownee = M //Typecast them as human. + handleDrowning(drownee) //Only human types will drown, to keep things simple for non-human mobs that live in the water + + for(var/obj/effect/decal/cleanable/decal in T) + animate(decal, alpha = 10, time = 20) + spawn(25) + qdel(decal) \ No newline at end of file diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index d6daf0f4516..bac66c13cad 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -115,7 +115,7 @@ R.cell.charge = min(R.cell.charge + recharge_speed, R.cell.maxcharge) else if(istype(occupant, /mob/living/carbon/human)) var/mob/living/carbon/human/H = occupant - if(!isnull(H.internal_organs_by_name["cell"]) && H.nutrition < 450) + if(H.get_int_organ(/obj/item/organ/internal/cell) && H.nutrition < 450) H.nutrition = min(H.nutrition+recharge_speed_nutrition, 450) if(repairs) H.heal_overall_damage(repairs, repairs, 0, 1) @@ -242,7 +242,7 @@ if(occupant) H << "The cell is already occupied!" return - if(isnull(H.internal_organs_by_name["cell"])) + if(!H.get_int_organ(/obj/item/organ/internal/cell)) return can_accept_user = 1 diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 0939b189eb1..fb0824d18b8 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -17,19 +17,19 @@ /datum/data/vending_product/New(var/path, var/name = null, var/amount = 1, var/price = 0, var/color = null, var/category = CAT_NORMAL) ..() - src.product_path = path + product_path = path if(!name) var/atom/tmp = new path - src.product_name = initial(tmp.name) + product_name = initial(tmp.name) qdel(tmp) else - src.product_name = name + product_name = name - src.amount = amount - src.price = price - src.display_color = color - src.category = category + amount = amount + price = price + display_color = color + category = category /** * A vending machine @@ -101,18 +101,18 @@ ..() wires = new(src) spawn(50) - if(src.product_slogans) - src.slogan_list += text2list(src.product_slogans, ";") + if(product_slogans) + slogan_list += text2list(product_slogans, ";") // So not all machines speak at the exact same time. // The first time this machine says something will be at slogantime + this random value, // so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated. - src.last_slogan = world.time + rand(0, slogan_delay) + last_slogan = world.time + rand(0, slogan_delay) - if(src.product_ads) - src.ads_list += text2list(src.product_ads, ";") + if(product_ads) + ads_list += text2list(product_ads, ";") - src.build_inventory() + build_inventory() power_change() return @@ -128,9 +128,9 @@ */ /obj/machinery/vending/proc/build_inventory() var/list/all_products = list( - list(src.products, CAT_NORMAL), - list(src.contraband, CAT_HIDDEN), - list(src.premium, CAT_COIN)) + list(products, CAT_NORMAL), + list(contraband, CAT_HIDDEN), + list(premium, CAT_COIN)) for(var/current_list in all_products) var/category = current_list[2] @@ -138,12 +138,12 @@ for(var/entry in current_list[1]) var/datum/data/vending_product/product = new/datum/data/vending_product(entry) - product.price = (entry in src.prices) ? src.prices[entry] : 0 + product.price = (entry in prices) ? prices[entry] : 0 product.amount = (current_list[1][entry]) ? current_list[1][entry] : 1 product.max_amount = product.amount product.category = category - src.product_records.Add(product) + product_records.Add(product) /obj/machinery/vending/Destroy() qdel(wires) // qdel @@ -168,9 +168,8 @@ /obj/machinery/vending/RefreshParts() //Better would be to make constructable child if(component_parts) - build_inventory() for(var/obj/item/weapon/vending_refill/VR in component_parts) - refill_inventory(VR, product_records) + refill_inventory(VR, product_records, usr) /obj/machinery/vending/blob_act() if(prob(75)) @@ -178,7 +177,7 @@ else qdel(src) -/obj/machinery/vending/proc/refill_inventory(obj/item/weapon/vending_refill/refill, datum/data/vending_product/machine, mob/user) +/obj/machinery/vending/proc/refill_inventory(obj/item/weapon/vending_refill/refill, list/machine, mob/user) var/total = 0 var/to_restock = 0 @@ -188,7 +187,8 @@ if(to_restock <= refill.charges) for(var/datum/data/vending_product/machine_content in machine) if(machine_content.amount != machine_content.max_amount) - usr << "[machine_content.max_amount - machine_content.amount] of [machine_content.product_name]" + if(user) + user << "[machine_content.max_amount - machine_content.amount] of [machine_content.product_name]" machine_content.amount = machine_content.max_amount refill.charges -= to_restock total = to_restock @@ -202,7 +202,8 @@ refill.charges -= restock total += restock if(restock) - usr << "[restock] of [machine_content.product_name]" + if(user) + user << "[restock] of [machine_content.product_name]" if(refill.charges == 0) //due to rounding, we ran out of refill charges, exit. break return total @@ -221,7 +222,7 @@ handled = 1 if(paid) - src.vend(currently_vending, usr) + vend(currently_vending, usr) return else if(handled) nanomanager.update_uis(src) @@ -231,7 +232,7 @@ return if(istype(W, /obj/item/weapon/screwdriver) && anchored) - playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) + playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1) panel_open = !panel_open user << "You [panel_open ? "open" : "close"] the maintenance panel." overlays.Cut() @@ -323,7 +324,9 @@ */ /obj/machinery/vending/proc/pay_with_card(var/obj/item/weapon/card/id/I) visible_message("[usr] swipes a card through [src].") - var/datum/money_account/customer_account = attempt_account_access_nosec(I.associated_account_number) + return pay_with_account(get_card_account(I)) + +/obj/machinery/vending/proc/pay_with_account(var/datum/money_account/customer_account) if (!customer_account) src.status_message = "Error: Unable to access account. Please contact technical support if problem persists." src.status_error = 1 @@ -338,7 +341,7 @@ // empty at high security levels 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) + customer_account = attempt_account_access(customer_account, attempt_pin, 2) if(!customer_account) src.status_message = "Unable to access account: incorrect credentials." @@ -351,28 +354,18 @@ return 0 else // Okay to move the money at this point + var/paid = customer_account.charge(currently_vending.price, + transaction_purpose = "Purchase of [currently_vending.product_name]", + terminal_name = name, + terminal_id = name, + dest_name = vendor_account.owner_name) - // debit money from the purchaser's account - customer_account.money -= currently_vending.price - - // create entry in the purchaser's account log - var/datum/transaction/T = new() - T.target_name = "[vendor_account.owner_name] (via [src.name])" - T.purpose = "Purchase of [currently_vending.product_name]" - if(currently_vending.price > 0) - T.amount = "([currently_vending.price])" - else - T.amount = "[currently_vending.price]" - T.source_terminal = src.name - T.date = current_date_string - T.time = worldtime2text() - customer_account.transaction_log.Add(T) - - // Give the vendor the money. We use the account owner name, which means - // that purchases made with stolen/borrowed card will look like the card - // owner made them - credit_purchase(customer_account.owner_name) - return 1 + if(paid) + // Give the vendor the money. We use the account owner name, which means + // that purchases made with stolen/borrowed card will look like the card + // owner made them + credit_purchase(customer_account.owner_name) + return paid /** * Add money for current purchase to the vendor account. @@ -471,38 +464,28 @@ if (href_list["pay"]) if(currently_vending && vendor_account && !vendor_account.suspended) - if(istype(usr, /mob/living/carbon/human)) - var/paid = 0 - var/handled = 0 - var/mob/living/carbon/human/H = usr - var/obj/item/weapon/card/card = null - if(istype(H.wear_id,/obj/item/weapon/card)) - card = H.wear_id - paid = pay_with_card(card) - handled = 1 - else if(istype(H.get_active_hand(), /obj/item/weapon/card)) - card = H.get_active_hand() - paid = pay_with_card(card) - handled = 1 - if(paid) - src.vend(currently_vending, usr) - return - else if(handled) - nanomanager.update_uis(src) - return // don't smack that machine with your 2 credits + var/paid = 0 + var/handled = 0 + var/datum/money_account/A = usr.get_worn_id_account() + if(A) + paid = pay_with_account(A) + handled = 1 + else if(istype(usr.get_active_hand(), /obj/item/weapon/card)) + paid = pay_with_card(usr.get_active_hand()) + handled = 1 + if(paid) + src.vend(currently_vending, usr) + return + else if(handled) + nanomanager.update_uis(src) + return // don't smack that machine with your 2 credits if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf)))) if ((href_list["vend"]) && (src.vend_ready) && (!currently_vending)) - if(istype(usr,/mob/living/silicon)) - if(istype(usr,/mob/living/silicon/robot)) - var/mob/living/silicon/robot/R = usr - if(!(R.module && istype(R.module,/obj/item/weapon/robot_module/butler) )) - usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!" - return - else - usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!" - return + if(issilicon(usr) && !isrobot(usr)) + usr << "The vending machine refuses to interface with you, as you are not in its target demographic!" + return if((!allowed(usr)) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH usr << "Access denied." //Unless emagged of course @@ -711,16 +694,27 @@ desc = "A technological marvel, supposedly able to mix just the mixture you'd like to drink the moment you ask for one." icon_state = "boozeomat" //////////////18 drink entities below, plus the glasses, in case someone wants to edit the number of bottles icon_deny = "boozeomat-deny" - products = list(/obj/item/weapon/reagent_containers/food/drinks/bottle/gin = 5,/obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/tequilla = 5,/obj/item/weapon/reagent_containers/food/drinks/bottle/vodka = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/vermouth = 5,/obj/item/weapon/reagent_containers/food/drinks/bottle/rum = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/wine = 5,/obj/item/weapon/reagent_containers/food/drinks/bottle/cognac = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/kahlua = 5,/obj/item/weapon/reagent_containers/food/drinks/cans/beer = 6, - /obj/item/weapon/reagent_containers/food/drinks/cans/ale = 6,/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice = 4, - /obj/item/weapon/reagent_containers/food/drinks/bottle/tomatojuice = 4,/obj/item/weapon/reagent_containers/food/drinks/bottle/limejuice = 4, - /obj/item/weapon/reagent_containers/food/drinks/bottle/cream = 4,/obj/item/weapon/reagent_containers/food/drinks/cans/tonic = 8, - /obj/item/weapon/reagent_containers/food/drinks/cans/cola = 8, /obj/item/weapon/reagent_containers/food/drinks/cans/sodawater = 15, - /obj/item/weapon/reagent_containers/food/drinks/drinkingglass = 30,/obj/item/weapon/reagent_containers/food/drinks/ice = 9) + products = list(/obj/item/weapon/reagent_containers/food/drinks/bottle/gin = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/tequilla = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/vodka = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/vermouth = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/rum = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/wine = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/cognac = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/kahlua = 5, + /obj/item/weapon/reagent_containers/food/drinks/cans/beer = 6, + /obj/item/weapon/reagent_containers/food/drinks/cans/ale = 6, + /obj/item/weapon/reagent_containers/food/drinks/cans/synthanol = 15, + /obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice = 4, + /obj/item/weapon/reagent_containers/food/drinks/bottle/tomatojuice = 4, + /obj/item/weapon/reagent_containers/food/drinks/bottle/limejuice = 4, + /obj/item/weapon/reagent_containers/food/drinks/bottle/cream = 4, + /obj/item/weapon/reagent_containers/food/drinks/cans/tonic = 8, + /obj/item/weapon/reagent_containers/food/drinks/cans/cola = 8, + /obj/item/weapon/reagent_containers/food/drinks/cans/sodawater = 15, + /obj/item/weapon/reagent_containers/food/drinks/drinkingglass = 30, + /obj/item/weapon/reagent_containers/food/drinks/ice = 9) contraband = list(/obj/item/weapon/reagent_containers/food/drinks/tea = 10) vend_delay = 15 product_slogans = "I hope nobody asks me for a bloody cup o' tea...;Alcohol is humanity's friend. Would you abandon a friend?;Quite delighted to serve you!;Is nobody thirsty on this station?" @@ -836,11 +830,11 @@ icon_deny = "cart-deny" products = list(/obj/item/device/pda =10,/obj/item/weapon/cartridge/medical = 10,/obj/item/weapon/cartridge/chemistry = 10, /obj/item/weapon/cartridge/engineering = 10,/obj/item/weapon/cartridge/atmos = 10,/obj/item/weapon/cartridge/janitor = 10, - /obj/item/weapon/cartridge/signal/toxins = 10,/obj/item/weapon/cartridge/signal = 10,/obj/item/weapon/cartridge = 10) + /obj/item/weapon/cartridge/signal/toxins = 10,/obj/item/weapon/cartridge/signal = 10) contraband = list(/obj/item/weapon/cartridge/clown = 1,/obj/item/weapon/cartridge/mime = 1) prices = list(/obj/item/device/pda =300,/obj/item/weapon/cartridge/medical = 200,/obj/item/weapon/cartridge/chemistry = 150,/obj/item/weapon/cartridge/engineering = 100, /obj/item/weapon/cartridge/atmos = 75,/obj/item/weapon/cartridge/janitor = 100,/obj/item/weapon/cartridge/signal/toxins = 150, - /obj/item/weapon/cartridge/signal = 75,/obj/item/weapon/cartridge = 50) + /obj/item/weapon/cartridge/signal = 75) /obj/machinery/vending/liberationstation @@ -987,9 +981,9 @@ */ /obj/machinery/vending/hydroseeds/build_inventory() var/list/all_products = list( - list(src.products, CAT_NORMAL), - list(src.contraband, CAT_HIDDEN), - list(src.premium, CAT_COIN)) + list(products, CAT_NORMAL), + list(contraband, CAT_HIDDEN), + list(premium, CAT_COIN)) for(var/current_list in all_products) var/category = current_list[2] @@ -999,12 +993,12 @@ var/name = S.name var/datum/data/vending_product/product = new/datum/data/vending_product(entry, name) - product.price = (entry in src.prices) ? src.prices[entry] : 0 + product.price = (entry in prices) ? prices[entry] : 0 product.amount = (current_list[1][entry]) ? current_list[1][entry] : 1 product.max_amount = product.amount product.category = category - src.product_records.Add(product) + product_records.Add(product) /obj/machinery/vending/magivend name = "\improper MagiVend" @@ -1065,6 +1059,9 @@ /obj/item/weapon/reagent_containers/food/drinks/drinkingglass = 8, /obj/item/clothing/suit/chef/classic = 2, /obj/item/weapon/reagent_containers/food/condiment/pack/ketchup = 5, /obj/item/weapon/reagent_containers/food/condiment/pack/hotsauce = 5, + /obj/item/weapon/reagent_containers/food/condiment/saltshaker =5, + /obj/item/weapon/reagent_containers/food/condiment/peppermill =5, + /obj/item/weapon/whetstone = 2, /obj/item/weapon/kitchen/mould/bear = 1, /obj/item/weapon/kitchen/mould/worm = 1, /obj/item/weapon/kitchen/mould/bean = 1, /obj/item/weapon/kitchen/mould/ball = 1, /obj/item/weapon/kitchen/mould/cane = 1, /obj/item/weapon/kitchen/mould/cash = 1, @@ -1096,7 +1093,7 @@ icon_state = "engivend" icon_deny = "engivend-deny" req_access_txt = "11" //Engineering Equipment access - products = list(/obj/item/clothing/glasses/meson = 2,/obj/item/device/multitool = 4,/obj/item/weapon/airlock_electronics = 10,/obj/item/weapon/firealarm_electronics = 10,/obj/item/weapon/apc_electronics = 10,/obj/item/weapon/airalarm_electronics = 10,/obj/item/weapon/stock_parts/cell/high = 10) + products = list(/obj/item/clothing/glasses/meson = 2,/obj/item/device/multitool = 4,/obj/item/weapon/airlock_electronics = 10,/obj/item/weapon/firealarm_electronics = 10,/obj/item/weapon/apc_electronics = 10,/obj/item/weapon/airalarm_electronics = 10,/obj/item/weapon/stock_parts/cell/high = 10,/obj/item/weapon/camera_assembly = 10) contraband = list(/obj/item/weapon/stock_parts/cell/potato = 3) premium = list(/obj/item/weapon/storage/belt/utility = 3) diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm index bd2000595f6..4e95938a2a1 100644 --- a/code/game/machinery/washing_machine.dm +++ b/code/game/machinery/washing_machine.dm @@ -67,6 +67,9 @@ var/new_glove_icon_state = "" var/new_glove_item_state = "" var/new_glove_name = "" + var/new_bandana_icon_state = "" + var/new_bandana_item_state = "" + var/new_bandana_name = "" var/new_shoe_icon_state = "" var/new_shoe_name = "" var/new_sheet_icon_state = "" @@ -76,59 +79,57 @@ var/new_desc = "The colors are a bit dodgy." for(var/T in typesof(/obj/item/clothing/under)) var/obj/item/clothing/under/J = new T - //world << "DEBUG: [color] == [J.color]" if(wash_color == J.item_color) new_jumpsuit_icon_state = J.icon_state new_jumpsuit_item_state = J.item_state new_jumpsuit_name = J.name qdel(J) - //world << "DEBUG: YUP! [new_icon_state] and [new_item_state]" break qdel(J) for(var/T in typesof(/obj/item/clothing/gloves/color)) var/obj/item/clothing/gloves/color/G = new T - //world << "DEBUG: [color] == [J.color]" if(wash_color == G.item_color) new_glove_icon_state = G.icon_state new_glove_item_state = G.item_state new_glove_name = G.name qdel(G) - //world << "DEBUG: YUP! [new_icon_state] and [new_item_state]" break qdel(G) for(var/T in typesof(/obj/item/clothing/shoes)) var/obj/item/clothing/shoes/S = new T - //world << "DEBUG: [color] == [J.color]" if(wash_color == S.item_color) new_shoe_icon_state = S.icon_state new_shoe_name = S.name qdel(S) - //world << "DEBUG: YUP! [new_icon_state] and [new_item_state]" break qdel(S) + for(var/T in typesof(/obj/item/clothing/mask/bandana)) + var/obj/item/clothing/mask/bandana/M = new T + if(wash_color == M.item_color) + new_bandana_icon_state = M.icon_state + new_bandana_item_state = M.item_state + new_bandana_name = M.name + qdel(M) + break + qdel(M) for(var/T in typesof(/obj/item/weapon/bedsheet)) var/obj/item/weapon/bedsheet/B = new T - //world << "DEBUG: [color] == [J.color]" if(wash_color == B.item_color) new_sheet_icon_state = B.icon_state new_sheet_name = B.name qdel(B) - //world << "DEBUG: YUP! [new_icon_state] and [new_item_state]" break qdel(B) for(var/T in typesof(/obj/item/clothing/head/soft)) var/obj/item/clothing/head/soft/H = new T - //world << "DEBUG: [color] == [J.color]" if(wash_color == H.item_color) new_softcap_icon_state = H.icon_state new_softcap_name = H.name qdel(H) - //world << "DEBUG: YUP! [new_icon_state] and [new_item_state]" break qdel(H) if(new_jumpsuit_icon_state && new_jumpsuit_item_state && new_jumpsuit_name) for(var/obj/item/clothing/under/J in contents) - //world << "DEBUG: YUP! FOUND IT!" J.item_state = new_jumpsuit_item_state J.icon_state = new_jumpsuit_icon_state J.item_color = wash_color @@ -136,7 +137,6 @@ J.desc = new_desc if(new_glove_icon_state && new_glove_item_state && new_glove_name) for(var/obj/item/clothing/gloves/color/G in contents) - //world << "DEBUG: YUP! FOUND IT!" G.item_state = new_glove_item_state G.icon_state = new_glove_icon_state G.item_color = wash_color @@ -145,7 +145,6 @@ G.desc = new_desc if(new_shoe_icon_state && new_shoe_name) for(var/obj/item/clothing/shoes/S in contents) - //world << "DEBUG: YUP! FOUND IT!" if (S.chained == 1) S.chained = 0 S.slowdown = SHOES_SLOWDOWN @@ -154,16 +153,21 @@ S.item_color = wash_color S.name = new_shoe_name S.desc = new_desc + if(new_bandana_icon_state && new_bandana_name) + for(var/obj/item/clothing/mask/bandana/M in contents) + M.item_state = new_bandana_item_state + M.icon_state = new_bandana_icon_state + M.item_color = wash_color + M.name = new_bandana_name + M.desc = new_desc if(new_sheet_icon_state && new_sheet_name) for(var/obj/item/weapon/bedsheet/B in contents) - //world << "DEBUG: YUP! FOUND IT!" B.icon_state = new_sheet_icon_state B.item_color = wash_color B.name = new_sheet_name B.desc = new_desc if(new_softcap_icon_state && new_softcap_name) for(var/obj/item/clothing/head/soft/H in contents) - //world << "DEBUG: YUP! FOUND IT!" H.icon_state = new_softcap_icon_state H.item_color = wash_color H.name = new_softcap_name @@ -313,4 +317,4 @@ state = 1 - update_icon() \ No newline at end of file + update_icon() diff --git a/code/game/mecha/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm index c482eac5412..83e23606fcc 100644 --- a/code/game/mecha/equipment/tools/tools.dm +++ b/code/game/mecha/equipment/tools/tools.dm @@ -838,11 +838,13 @@ range = MELEE var/datum/global_iterator/pr_mech_generator var/coeff = 100 - var/obj/item/stack/sheet/fuel + var/fuel_type = MAT_PLASMA var/max_fuel = 150000 - var/fuel_per_cycle_idle = 25 - var/fuel_per_cycle_active = 200 - var/power_per_cycle = 20 + var/fuel_name = "plasma" // Our fuel name as a string + var/fuel_amount = 0 + var/fuel_per_cycle_idle = 10 + var/fuel_per_cycle_active = 100 + var/power_per_cycle = 30 reliability = 1000 New() @@ -851,8 +853,7 @@ return proc/init() - fuel = new /obj/item/stack/sheet/mineral/plasma(src) - fuel.amount = 0 + fuel_amount = 0 pr_mech_generator = new /datum/global_iterator/mecha_generator(list(src),0) pr_mech_generator.set_delay(equip_cooldown) return @@ -877,7 +878,7 @@ get_equip_info() var/output = ..() if(output) - return "[output] \[[fuel]: [round(fuel.amount*fuel.perunit,0.1)] cm3\] - [pr_mech_generator.active()?"Dea":"A"]ctivate" + return "[output] \[[fuel_name]: [round(fuel_amount,0.1)] cm3\] - [pr_mech_generator.active()?"Dea":"A"]ctivate" return action(target) @@ -885,36 +886,55 @@ var/result = load_fuel(target) var/message if(isnull(result)) - message = "[fuel] traces in target minimal. [target] cannot be used as fuel." + message = "[fuel_name] traces in target minimal. [target] cannot be used as fuel." else if(!result) message = "Unit is full." else - message = "[result] unit\s of [fuel] successfully loaded." + message = "[result] unit\s of [fuel_name] successfully loaded." send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) occupant_message(message) return - proc/load_fuel(var/obj/item/stack/sheet/P) - if(P.type == fuel.type && P.amount) - var/to_load = max(max_fuel - fuel.amount*fuel.perunit,0) - if(to_load) - var/units = min(max(round(to_load / P.perunit),1),P.amount) - if(units) - fuel.amount += units - P.use(units) - return units - else - return 0 + proc/load_fuel(var/obj/item/I) + if(istype(I) && (fuel_type in I.materials)) + if(istype(I, /obj/item/stack/sheet)) + var/obj/item/stack/sheet/P = I + var/to_load = max(max_fuel - P.amount*P.perunit,0) + if(to_load) + var/units = min(max(round(to_load / P.perunit),1),P.amount) + if(units) + var/added_fuel = units * P.perunit + fuel_amount += added_fuel + P.use(units) + return added_fuel + else + return 0 + else // Some other object containing our fuel's type, so we just eat it (ores mainly) + var/to_load = max(min(I.materials[fuel_type], max_fuel - fuel_amount),0) + if(to_load == 0) + return 0 + fuel_amount += to_load + qdel(I) + return to_load + else if(istype(I, /obj/structure/ore_box)) + var/fuel_added = 0 + for(var/baz in I.contents) // Istypeless loop + var/obj/item/O = baz + if(fuel_type in O.materials) + fuel_added = load_fuel(O) + break + return fuel_added return attackby(weapon,mob/user, params) var/result = load_fuel(weapon) + var/weapon_name = "[weapon]" if(isnull(result)) - user.visible_message("[user] tries to shove [weapon] into [src]. What a dumb-ass.","[fuel] traces minimal. [weapon] cannot be used as fuel.") + user.visible_message("[user] tries to shove [weapon_name] into [src], but \the [src] rejects it.","[fuel_name] traces in target minimal. [weapon_name] cannot be used as fuel.") else if(!result) user << "Unit is full." else - user.visible_message("[user] loads [src] with [fuel].","[result] unit\s of [fuel] successfully loaded.") + user.visible_message("[user] loads [src] with \the [weapon_name].","[result] unit\s of [fuel_name] successfully loaded.") return critfail() @@ -942,7 +962,7 @@ stop() EG.set_ready_state(1) return 0 - if(EG.fuel.amount<=0) + if(EG.fuel_amount<=0) stop() EG.log_message("Deactivated - no fuel.") EG.set_ready_state(1) @@ -962,7 +982,7 @@ if(cur_chargeIt feels slimy." - + if(user.get_int_organ(/obj/item/organ/internal/xenos/plasmavessel)) + switch(status) + if(BURST) + user << "You clear the hatched egg." + playsound(loc, 'sound/effects/attackblob.ogg', 100, 1) + qdel(src) + if(GROWING) + user << "The child is not developed yet." + if(GROWN) + user << "You retrieve the child." + Burst(0) + else + user << "It feels slimy." /obj/structure/alien/egg/proc/GetFacehugger() return locate(/obj/item/clothing/mask/facehugger) in contents diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index 298c5b75f53..3f75bca668c 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -20,6 +20,7 @@ var/global/list/image/splatter_cache=list() var/basecolor="#A10808" // Color when wet. var/list/datum/disease2/disease/virus2 = list() var/amount = 5 + appearance_flags = NO_CLIENT_COLOR /obj/effect/decal/cleanable/blood/New() ..() diff --git a/code/game/objects/effects/decals/contraband.dm b/code/game/objects/effects/decals/contraband.dm index 5dd0707fcb9..1e62b6a5a9e 100644 --- a/code/game/objects/effects/decals/contraband.dm +++ b/code/game/objects/effects/decals/contraband.dm @@ -352,12 +352,12 @@ obj/structure/sign/poster/attackby(obj/item/I, mob/user, params) if(!P.resulting_poster) return var/stuff_on_wall = 0 - for(var/obj/O in contents) //Let's see if it already has a poster on it or too much stuff - if(istype(O,/obj/structure/sign/poster)) + for(var/obj/O in user.loc.contents) //Let's see if it already has a poster on it or too much stuff + if(istype(O,/obj/structure/sign)) user << "The wall is far too cluttered to place a poster!" return stuff_on_wall++ - if(stuff_on_wall == 3) + if(stuff_on_wall >= 4) user << "The wall is far too cluttered to place a poster!" return diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index 9548eea30ee..ee383613a68 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -985,16 +985,8 @@ steam.start() -- spawns the effect return if (istype(AM, /mob/living/carbon)) - var/mob/M = AM - if (istype(M, /mob/living/carbon/human) && (istype(M:shoes, /obj/item/clothing/shoes) && M:shoes.flags&NOSLIP) || M.buckled) - return - if (istype (M, /mob/living/carbon/human) && M:species.bodyflags & FEET_NOSLIP) - return - M.stop_pulling() - M << "\blue You slipped on the foam!" - playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3) - M.Stun(5) - M.Weaken(2) + var/mob/living/carbon/M = AM + M.slip("foam", 5, 2) /datum/effect/system/foam_spread diff --git a/code/game/objects/effects/forcefields.dm b/code/game/objects/effects/forcefields.dm index df83d69f3b5..f6643a5506a 100644 --- a/code/game/objects/effects/forcefields.dm +++ b/code/game/objects/effects/forcefields.dm @@ -3,14 +3,13 @@ name = "FORCEWALL" icon = 'icons/effects/effects.dmi' icon_state = "m_shield" - anchored = 1.0 + anchored = 1 opacity = 0 density = 1 unacidable = 1 - - - +/obj/effect/forcefield/CanAtmosPass(turf/T) + return !density ///////////Mimewalls/////////// @@ -18,7 +17,7 @@ icon_state = "empty" name = "invisible wall" desc = "You have a bad feeling about this." - var/timeleft = 50 + var/timeleft = 300 var/last_process = 0 /obj/effect/forcefield/mime/New() diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index bd0c2a4fc5a..42a14a43255 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -49,6 +49,8 @@ var/list/allowed = null //suit storage stuff. var/obj/item/device/uplink/hidden/hidden_uplink = null // All items can have an uplink hidden inside, just remember to add the triggers. + var/needs_permit = 0 //Used by security bots to determine if this item is safe for public use. + var/strip_delay = DEFAULT_ITEM_STRIP_DELAY var/put_on_delay = DEFAULT_ITEM_PUTON_DELAY @@ -419,7 +421,7 @@ add_logs(M, user, "attacked", "[src.name]", "(INTENT: [uppertext(user.a_intent)])") if(istype(H)) - var/obj/item/organ/eyes/eyes = H.internal_organs_by_name["eyes"] + var/obj/item/organ/internal/eyes/eyes = H.get_int_organ(/obj/item/organ/internal/eyes) if(!eyes) // should still get stabbed in the head var/obj/item/organ/external/head/head = H.organs_by_name["head"] head.take_damage(rand(10,14), 1) @@ -510,3 +512,14 @@ return 1 return 0 + +/obj/item/proc/wash(mob/user, atom/source) + if(flags & ABSTRACT) //Abstract items like grabs won't wash. No-drop items will though because it's still technically an item in your hand. + return + user << "You start washing [src]..." + if(!do_after(user, 40, target = source)) + return + clean_blood() + user.visible_message("[user] washes [src] using [source].", \ + "You wash [src] using [source].") + return 1 \ No newline at end of file diff --git a/code/game/objects/items/changestone.dm b/code/game/objects/items/changestone.dm index 242a17074e8..0074303a88f 100644 --- a/code/game/objects/items/changestone.dm +++ b/code/game/objects/items/changestone.dm @@ -9,9 +9,9 @@ obj/item/changestone/attack_hand(var/mob/user as mob) var/mob/living/carbon/human/H = user if(!H.gloves) if (H.gender == FEMALE) - H.gender = MALE + H.change_gender(MALE) else - H.gender = FEMALE + H.change_gender(FEMALE) H.dna.ready_dna(H) H.update_body() ..() diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm deleted file mode 100755 index a9e94d6077b..00000000000 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ /dev/null @@ -1,1286 +0,0 @@ - -//The advanced pea-green monochrome lcd of tomorrow. - -var/global/list/obj/item/device/pda/PDAs = list() - - -/obj/item/device/pda - name = "PDA" - desc = "A portable microcomputer by Thinktronic Systems, LTD. Functionality determined by a preprogrammed ROM cartridge." - icon = 'icons/obj/pda.dmi' - icon_state = "pda" - item_state = "electronic" - w_class = 1.0 - slot_flags = SLOT_PDA | SLOT_BELT - - //Main variables - var/owner = null - var/default_cartridge = 0 // Access level defined by cartridge - var/obj/item/weapon/cartridge/cartridge = null //current cartridge - var/mode = 0 //Controls what menu the PDA will display. 0 is hub; the rest are either built in or based on cartridge. - - var/lastmode = 0 - var/ui_tick = 0 - - //Secondary variables - var/scanmode = 0 //1 is medical scanner, 2 is forensics, 3 is reagent scanner. - var/fon = 0 //Is the flashlight function on? - var/f_lum = 2 //Luminosity for the flashlight function - var/silent = 0 //To beep or not to beep, that is the question - var/toff = 0 //If 1, messenger disabled - var/tnote[0] //Current Texts - var/last_text //No text spamming - var/last_honk //Also no honk spamming that's bad too - - var/ttone = "beep" //The ringtone! - var/list/ttone_sound = list("beep" = 'sound/machines/twobeep.ogg', - "boom" = 'sound/effects/explosionfar.ogg', - "slip" = 'sound/misc/slip.ogg', - "honk" = 'sound/items/bikehorn.ogg', - "SKREE" = 'sound/voice/shriek1.ogg', - "holy" = 'sound/items/PDA/ambicha4-short.ogg', - "xeno" = 'sound/voice/hiss1.ogg') - - var/lock_code = "" // Lockcode to unlock uplink - var/honkamt = 0 //How many honks left when infected with honk.exe - var/mimeamt = 0 //How many silence left when infected with mime.exe - var/note = "Congratulations, your station has chosen the Thinktronic 5230 Personal Data Assistant!" //Current note in the notepad function - var/notehtml = "" - var/cart = "" //A place to stick cartridge menu information - var/detonate = 1 // Can the PDA be blown up? - var/hidden = 0 // Is the PDA hidden from the PDA list? - var/active_conversation = null // New variable that allows us to only view a single conversation. - var/list/conversations = list() // For keeping up with who we have PDA messsages from. - var/newmessage = 0 //To remove hackish overlay check - - var/list/cartmodes = list(40, 42, 43, 433, 44, 441, 45, 451, 46, 48, 47, 49) // If you add more cartridge modes add them to this list as well. - var/list/no_auto_update = list(1, 40, 43, 44, 441, 45, 451) // These modes we turn off autoupdate - var/list/update_every_five = list(3, 41, 433, 46, 47, 48, 49) // These we update every 5 ticks - - var/obj/item/weapon/card/id/id = null //Making it possible to slot an ID card into the PDA so it can function as both. - var/ownjob = null //related to above - var/ownrank = null // this one is rank, never alt title - - var/obj/item/device/paicard/pai = null // A slot for a personal AI device - var/retro_mode = 0 - -/obj/item/device/pda/medical - default_cartridge = /obj/item/weapon/cartridge/medical - icon_state = "pda-medical" - -/obj/item/device/pda/viro - default_cartridge = /obj/item/weapon/cartridge/medical - icon_state = "pda-virology" - -/obj/item/device/pda/engineering - default_cartridge = /obj/item/weapon/cartridge/engineering - icon_state = "pda-engineer" - -/obj/item/device/pda/security - default_cartridge = /obj/item/weapon/cartridge/security - icon_state = "pda-security" - -/obj/item/device/pda/detective - default_cartridge = /obj/item/weapon/cartridge/detective - icon_state = "pda-security" - -/obj/item/device/pda/warden - default_cartridge = /obj/item/weapon/cartridge/security - icon_state = "pda-warden" - -/obj/item/device/pda/janitor - default_cartridge = /obj/item/weapon/cartridge/janitor - icon_state = "pda-janitor" - ttone = "slip" - -/obj/item/device/pda/toxins - default_cartridge = /obj/item/weapon/cartridge/signal/toxins - icon_state = "pda-science" - ttone = "boom" - -/obj/item/device/pda/clown - default_cartridge = /obj/item/weapon/cartridge/clown - icon_state = "pda-clown" - desc = "A portable microcomputer by Thinktronic Systems, LTD. The surface is coated with polytetrafluoroethylene and banana drippings." - ttone = "honk" - -/obj/item/device/pda/mime - default_cartridge = /obj/item/weapon/cartridge/mime - icon_state = "pda-mime" - silent = 1 - ttone = "silence" - -/obj/item/device/pda/heads - default_cartridge = /obj/item/weapon/cartridge/head - icon_state = "pda-h" - -/obj/item/device/pda/heads/hop - default_cartridge = /obj/item/weapon/cartridge/hop - icon_state = "pda-hop" - -/obj/item/device/pda/heads/hos - default_cartridge = /obj/item/weapon/cartridge/hos - icon_state = "pda-hos" - -/obj/item/device/pda/heads/ce - default_cartridge = /obj/item/weapon/cartridge/ce - icon_state = "pda-ce" - -/obj/item/device/pda/heads/cmo - default_cartridge = /obj/item/weapon/cartridge/cmo - icon_state = "pda-cmo" - -/obj/item/device/pda/heads/rd - default_cartridge = /obj/item/weapon/cartridge/rd - icon_state = "pda-rd" - -/obj/item/device/pda/captain - default_cartridge = /obj/item/weapon/cartridge/captain - icon_state = "pda-captain" - detonate = 0 - //toff = 1 - -/obj/item/device/pda/heads/ntrep - default_cartridge = /obj/item/weapon/cartridge/supervisor - icon_state = "pda-h" - -/obj/item/device/pda/heads/magistrate - default_cartridge = /obj/item/weapon/cartridge/supervisor - icon_state = "pda-h" - -/obj/item/device/pda/heads/blueshield - default_cartridge = /obj/item/weapon/cartridge/hos - icon_state = "pda-h" - -/obj/item/device/pda/cargo - default_cartridge = /obj/item/weapon/cartridge/quartermaster - icon_state = "pda-cargo" - -/obj/item/device/pda/quartermaster - default_cartridge = /obj/item/weapon/cartridge/quartermaster - icon_state = "pda-qm" - -/obj/item/device/pda/shaftminer - icon_state = "pda-miner" - -/obj/item/device/pda/syndicate - default_cartridge = /obj/item/weapon/cartridge/syndicate - icon_state = "pda-syndi" - name = "Military PDA" - owner = "John Doe" - hidden = 1 - -/obj/item/device/pda/chaplain - icon_state = "pda-chaplain" - ttone = "holy" - -/obj/item/device/pda/lawyer - default_cartridge = /obj/item/weapon/cartridge/lawyer - icon_state = "pda-lawyer" - ttone = "..." - -/obj/item/device/pda/botanist - //default_cartridge = /obj/item/weapon/cartridge/botanist - icon_state = "pda-hydro" - -/obj/item/device/pda/roboticist - icon_state = "pda-roboticist" - -/obj/item/device/pda/librarian - icon_state = "pda-library" - desc = "A portable microcomputer by Thinktronic Systems, LTD. This is model is a WGW-11 series e-reader." - note = "Congratulations, your station has chosen the Thinktronic 5290 WGW-11 Series E-reader and Personal Data Assistant!" - silent = 1 //Quiet in the library! - -/obj/item/device/pda/clear - icon_state = "pda-transp" - desc = "A portable microcomputer by Thinktronic Systems, LTD. This is model is a special edition with a transparent case." - note = "Congratulations, you have chosen the Thinktronic 5230 Personal Data Assistant Deluxe Special Max Turbo Limited Edition!" - -/obj/item/device/pda/chef - icon_state = "pda-chef" - -/obj/item/device/pda/bar - icon_state = "pda-bartender" - -/obj/item/device/pda/atmos - default_cartridge = /obj/item/weapon/cartridge/atmos - icon_state = "pda-atmos" - -/obj/item/device/pda/chemist - default_cartridge = /obj/item/weapon/cartridge/chemistry - icon_state = "pda-chemistry" - -/obj/item/device/pda/geneticist - default_cartridge = /obj/item/weapon/cartridge/medical - icon_state = "pda-genetics" - -/obj/item/device/pda/centcom - default_cartridge = /obj/item/weapon/cartridge/centcom - icon_state = "pda-h" - - -// Special AI/pAI PDAs that cannot explode. -/obj/item/device/pda/ai - icon_state = "NONE" - ttone = "data" - detonate = 0 - - -/obj/item/device/pda/ai/proc/set_name_and_job(newname as text, newjob as text, newrank as null|text) - owner = newname - ownjob = newjob - if(newrank) - ownrank = newrank - else - ownrank = ownjob - name = newname + " (" + ownjob + ")" - - -//AI verb and proc for sending PDA messages. -/mob/living/silicon/ai/proc/cmd_send_pdamesg(mob/user as mob) - if(user.stat == 2) - user << "You can't send PDA messages because you are dead!" - return - var/list/plist = aiPDA.available_pdas() - if (plist) - var/c = input(user, "Please select a PDA") as null|anything in sortList(plist) - if (!c) // if the user hasn't selected a PDA file we can't send a message - return - var/selected = plist[c] - aiPDA.create_message(user, selected) - -/mob/living/silicon/ai/proc/cmd_show_message_log(mob/user as mob) - if(user.stat == 2) - user << "You can't do that because you are dead!" - return - var/HTML = "AI PDA Message Log" - for(var/index in aiPDA.tnote) - if(index["sent"]) - HTML += addtext("→ To ", index["owner"],":
    ", index["message"], "
    ") - else - HTML += addtext("← From ", index["owner"],":
    ", index["message"], "
    ") - HTML +="" - user << browse(HTML, "window=log;size=400x444;border=1;can_resize=1;can_close=1;can_minimize=0") - -/obj/item/device/pda/ai/verb/cmd_send_pdamesg() - set category = "AI IM" - set name = "Send PDA Message" - set src in usr - if(usr.stat == 2) - usr << "You can't send PDA messages because you are dead!" - return - var/list/plist = available_pdas() - if (plist) - var/c = input(usr, "Please select a PDA") as null|anything in sortList(plist) - if (!c) // if the user hasn't selected a PDA file we can't send a message - return - var/selected = plist[c] - create_message(usr, selected) - -/obj/item/device/pda/ai/verb/cmd_show_message_log() - set category = "AI IM" - set name = "Show Message Log" - set src in usr - if(usr.stat == 2) - usr << "You can't do that because you are dead!" - return - var/HTML = "AI PDA Message Log" - for(var/index in tnote) - if(index["sent"]) - HTML += addtext("→ To ", index["owner"],":
    ", index["message"], "
    ") - else - HTML += addtext("← From ", index["owner"],":
    ", index["message"], "
    ") - HTML +="" - usr << browse(HTML, "window=log;size=400x444;border=1;can_resize=1;can_close=1;can_minimize=0") - -/obj/item/device/pda/ai/verb/cmd_toggle_pda_receiver() - set category = "AI IM" - set name = "Toggle Sender/Receiver" - set src in usr - if(usr.stat == 2) - usr << "You can't do that because you are dead!" - return - toff = !toff - usr << "PDA sender/receiver toggled [(toff ? "Off" : "On")]!" - - -/obj/item/device/pda/ai/verb/cmd_toggle_pda_silent() - set category = "AI IM" - set name = "Toggle Ringer" - set src in usr - if(usr.stat == 2) - usr << "You can't do that because you are dead!" - return - silent=!silent - usr << "PDA ringer toggled [(silent ? "Off" : "On")]!" - -/obj/item/device/pda/ai/can_use() - return 1 - - -/obj/item/device/pda/ai/attack_self(mob/user as mob) - if ((honkamt > 0) && (prob(60)))//For clown virus. - honkamt-- - playsound(loc, 'sound/items/bikehorn.ogg', 30, 1) - return - - -/obj/item/device/pda/ai/pai - ttone = "assist" - - -/* - * The Actual PDA - */ -/obj/item/device/pda/New() - ..() - PDAs += src - PDAs = sortAtom(PDAs) - if(default_cartridge) - cartridge = new default_cartridge(src) - new /obj/item/weapon/pen(src) - -/obj/item/device/pda/proc/can_use() - - if(!ismob(loc)) - return 0 - - var/mob/M = loc - if(M.stat || M.restrained() || M.paralysis || M.stunned || M.weakened) - return 0 - if((src in M.contents) || ( istype(loc, /turf) && in_range(src, M) )) - return 1 - else - return 0 - -/obj/item/device/pda/GetAccess() - if(id) - return id.GetAccess() - else - return ..() - -/obj/item/device/pda/GetID() - return id - -/obj/item/device/pda/MouseDrop(obj/over_object as obj, src_location, over_location) - var/mob/M = usr - if((!istype(over_object, /obj/screen)) && can_use()) - return attack_self(M) - return - - -/obj/item/device/pda/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - ui_tick++ - var/datum/nanoui/old_ui = nanomanager.get_open_ui(user, src, "main") - var/auto_update = 1 - if(mode in no_auto_update) - auto_update = 0 - if(old_ui && (mode == lastmode && ui_tick % 5 && mode in update_every_five)) - return - - lastmode = mode - - var/title = "Personal Data Assistant" - - var/data[0] // This is the data that will be sent to the PDA - - - data["owner"] = owner // Who is your daddy... - data["ownjob"] = ownjob // ...and what does he do? - - data["mode"] = mode // The current view - data["scanmode"] = scanmode // Scanners - data["fon"] = fon // Flashlight on? - data["pai"] = (isnull(pai) ? 0 : 1) // pAI inserted? - data["note"] = note // current pda notes - data["silent"] = silent // does the pda make noise when it receives a message? - data["toff"] = toff // is the messenger function turned off? - data["active_conversation"] = active_conversation // Which conversation are we following right now? - - - data["idInserted"] = (id ? 1 : 0) - data["idLink"] = (id ? text("[id.registered_name], [id.assignment]") : "--------") - - data["useRetro"] = retro_mode - - data["cart_loaded"] = cartridge ? 1:0 - if(cartridge) - var/cartdata[0] - - cartdata["access"] = list(\ - "access_security" = cartridge.access_security,\ - "access_engine" = cartridge.access_engine,\ - "access_atmos" = cartridge.access_atmos,\ - "access_medical" = cartridge.access_medical,\ - "access_clown" = cartridge.access_clown,\ - "access_mime" = cartridge.access_mime,\ - "access_janitor" = cartridge.access_janitor,\ - "access_quartermaster" = cartridge.access_quartermaster,\ - "access_hydroponics" = cartridge.access_hydroponics,\ - "access_reagent_scanner" = cartridge.access_reagent_scanner,\ - "access_remote_door" = cartridge.access_remote_door,\ - "access_status_display" = cartridge.access_status_display,\ - "access_detonate_pda" = cartridge.access_detonate_pda\ - ) - - if(mode in cartmodes) - data["records"] = cartridge.create_NanoUI_values() - - if(mode == 0) - cartdata["name"] = cartridge.name - if(isnull(cartridge.radio)) - cartdata["radio"] = 0 - else - if(istype(cartridge.radio, /obj/item/radio/integrated/beepsky)) - cartdata["radio"] = 1 - if(istype(cartridge.radio, /obj/item/radio/integrated/signal)) - cartdata["radio"] = 2 - if(istype(cartridge.radio, /obj/item/radio/integrated/mule)) - cartdata["radio"] = 3 - - if(mode == 2) - cartdata["charges"] = cartridge.charges ? cartridge.charges : 0 - data["cartridge"] = cartdata - data["stationTime"] = worldtime2text() - data["newMessage"] = newmessage - - if(mode==2) - var/convopdas[0] - var/pdas[0] - var/count = 0 - for (var/obj/item/device/pda/P in PDAs) - if (!P.owner||P.toff||P == src||P.hidden) continue - if(conversations.Find("\ref[P]")) - convopdas.Add(list(list("Name" = "[P]", "Reference" = "\ref[P]", "Detonate" = "[P.detonate]", "inconvo" = "1"))) - else - pdas.Add(list(list("Name" = "[P]", "Reference" = "\ref[P]", "Detonate" = "[P.detonate]", "inconvo" = "0"))) - count++ - - data["convopdas"] = convopdas - data["pdas"] = pdas - data["pda_count"] = count - - if(mode==21) - data["messagescount"] = tnote.len - data["messages"] = tnote - else - data["messagescount"] = null - data["messages"] = null - - if(active_conversation) - for(var/c in tnote) - if(c["target"] == active_conversation) - data["convo_name"] = sanitize(c["owner"]) - data["convo_job"] = sanitize(c["job"]) - break - if(mode==41) - data_core.get_manifest_json() - - - if(mode==3) - var/turf/T = get_turf(user.loc) - if(!isnull(T)) - var/datum/gas_mixture/environment = T.return_air() - - var/pressure = environment.return_pressure() - var/total_moles = environment.total_moles() - - if (total_moles) - var/o2_level = environment.oxygen/total_moles - var/n2_level = environment.nitrogen/total_moles - var/co2_level = environment.carbon_dioxide/total_moles - var/plasma_level = environment.toxins/total_moles - var/unknown_level = 1-(o2_level+n2_level+co2_level+plasma_level) - data["aircontents"] = list(\ - "pressure" = "[round(pressure,0.1)]",\ - "nitrogen" = "[round(n2_level*100,0.1)]",\ - "oxygen" = "[round(o2_level*100,0.1)]",\ - "carbon_dioxide" = "[round(co2_level*100,0.1)]",\ - "plasma" = "[round(plasma_level*100,0.01)]",\ - "other" = "[round(unknown_level, 0.01)]",\ - "temp" = "[round(environment.temperature-T0C,0.1)]",\ - "reading" = 1\ - ) - if(isnull(data["aircontents"])) - - data["aircontents"] = list("reading" = 0) - - - data["manifest"] = list("__json_cache" = ManifestJSON) - - // update the ui if it exists, returns null if no ui is passed/found - ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, 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, "pda.tmpl", title, 630, 600, state = inventory_state) - - // when the ui is first opened this is the data it will use - ui.set_initial_data(data) - // open the new ui window - ui.open() - // auto update every Master Controller tick - ui.set_auto_update(auto_update) - -//NOTE: graphic resources are loaded on client login -/obj/item/device/pda/attack_self(mob/user as mob) - user.set_machine(src) - if(active_uplink_check(user)) - return - ui_interact(user) //NanoUI requires this proc - return - -/obj/item/device/pda/Topic(href, href_list) - if(href_list["cartmenu"] && !isnull(cartridge)) - cartridge.Topic(href, href_list) - return 1 - if(href_list["radiomenu"] && !isnull(cartridge) && !isnull(cartridge.radio)) - cartridge.radio.Topic(href, href_list) - return 1 - - - ..() - var/mob/user = usr - var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main") - var/mob/living/U = usr - //Looking for master was kind of pointless since PDAs don't appear to have one. - //if ((src in U.contents) || ( istype(loc, /turf) && in_range(src, U) ) ) - if (usr.stat == DEAD) - return 0 - if(!can_use()) //Why reinvent the wheel? There's a proc that does exactly that. - U.unset_machine() - if(ui) - ui.close() - return 0 - - add_fingerprint(U) - U.set_machine(src) - - switch(href_list["choice"]) - -//BASIC FUNCTIONS=================================== - - if("Close")//Self explanatory - U.unset_machine() - ui.close() - return 0 - if("Refresh")//Refresh, goes to the end of the proc. - if("Return")//Return - if(mode<=9) - mode = 0 - else - mode = round(mode/10) - if(mode==2) - active_conversation = null - if(mode==4)//Fix for cartridges. Redirects to hub. - mode = 0 - else if(mode >= 40 && mode <= 49)//Fix for cartridges. Redirects to refresh the menu. - cartridge.mode = mode - if("Retro") - retro_mode = !retro_mode - ui_interact(user) - if ("Authenticate")//Checks for ID - id_check(U, 1) - if("UpdateInfo") - ownjob = id.assignment - ownrank = id.rank - name = "PDA-[owner] ([ownjob])" - if("Eject")//Ejects the cart, only done from hub. - if (!isnull(cartridge)) - var/turf/T = loc - if(ismob(T)) - T = T.loc - cartridge.loc = T - mode = 0 - scanmode = 0 - if (cartridge.radio) - cartridge.radio.hostpda = null - cartridge = null - -//MENU FUNCTIONS=================================== - - if("0")//Hub - mode = 0 - if("1")//Notes - mode = 1 - if("2")//Messenger - mode = 2 - if("21")//Read messages - mode = 21 - if("3")//Atmos scan - mode = 3 - if("4")//Redirects to hub - mode = 0 - if("chatroom") // chatroom hub - mode = 5 - if("41") //Manifest - mode = 41 - - -//MAIN FUNCTIONS=================================== - - if("Light") - if(fon) - fon = 0 - set_light(0) - else - fon = 1 - set_light(f_lum) - if("Medical Scan") - if(scanmode == 1) - scanmode = 0 - else if((!isnull(cartridge)) && (cartridge.access_medical)) - scanmode = 1 - if("Reagent Scan") - if(scanmode == 3) - scanmode = 0 - else if((!isnull(cartridge)) && (cartridge.access_reagent_scanner)) - scanmode = 3 - if("Halogen Counter") - if(scanmode == 4) - scanmode = 0 - else if((!isnull(cartridge)) && (cartridge.access_engine)) - scanmode = 4 - if("Honk") - if ( !(last_honk && world.time < last_honk + 20) ) - playsound(loc, 'sound/items/bikehorn.ogg', 50, 1) - last_honk = world.time - if("Gas Scan") - if(scanmode == 5) - scanmode = 0 - else if((!isnull(cartridge)) && (cartridge.access_atmos)) - scanmode = 5 - -//MESSENGER/NOTE FUNCTIONS=================================== - - if ("Edit") - var/n = input(U, "Please enter message", name, notehtml) as message - if (in_range(src, U) && loc == U) - n = copytext(adminscrub(n), 1, MAX_MESSAGE_LEN) - if (mode == 1) - note = html_decode(n) - notehtml = note - note = replacetext(note, "\n", "
    ") - else - ui.close() - if("Toggle Messenger") - toff = !toff - if("Toggle Ringer")//If viewing texts then erase them, if not then toggle silent status - silent = !silent - if("Clear")//Clears messages - if(href_list["option"] == "All") - tnote.Cut() - conversations.Cut() - if(href_list["option"] == "Convo") - var/new_tnote[0] - for(var/i in tnote) - if(i["target"] != active_conversation) - new_tnote[++new_tnote.len] = i - tnote = new_tnote - conversations.Remove(active_conversation) - - active_conversation = null - if(mode==21) - mode=2 - - if("Ringtone") - var/t = input(U, "Please enter new ringtone", name, ttone) as text - if (in_range(src, U) && loc == U) - if (t) - if(src.hidden_uplink && hidden_uplink.check_trigger(U, lowertext(t), lowertext(lock_code))) - U << "The PDA softly beeps." - ui.close() - else - t = sanitize(copytext(t, 1, 20)) - ttone = t - else - ui.close() - return 0 - if("Message") - - var/obj/item/device/pda/P = locate(href_list["target"]) - src.create_message(U, P) - if(mode == 2) - if(href_list["target"] in conversations) // Need to make sure the message went through, if not welp. - active_conversation = href_list["target"] - mode = 21 - - if("Select Conversation") - var/P = href_list["convo"] - for(var/n in conversations) - if(P == n) - active_conversation=P - mode=21 - if("Send Honk")//Honk virus - if(istype(cartridge, /obj/item/weapon/cartridge/clown))//Cartridge checks are kind of unnecessary since everything is done through switch. - var/obj/item/device/pda/P = locate(href_list["target"])//Leaving it alone in case it may do something useful, I guess. - if(!isnull(P)) - if (!P.toff && cartridge.charges > 0) - cartridge.charges-- - U.show_message("\blue Virus sent!", 1) - P.honkamt = (rand(15,20)) - else - U << "PDA not found." - else - ui.close() - return 0 - if("Send Silence")//Silent virus - if(istype(cartridge, /obj/item/weapon/cartridge/mime)) - var/obj/item/device/pda/P = locate(href_list["target"]) - if(!isnull(P)) - if (!P.toff && cartridge.charges > 0) - cartridge.charges-- - U.show_message("\blue Virus sent!", 1) - P.silent = 1 - P.ttone = "silence" - else - U << "PDA not found." - else - ui.close() - return 0 - - -//SYNDICATE FUNCTIONS=================================== - - if("Toggle Door") - if(cartridge && cartridge.access_remote_door) - for(var/obj/machinery/door/poddoor/M in world) - if(M.id_tag == cartridge.remote_door_id) - if(M.density) - M.open() - else - M.close() - - if("Detonate")//Detonate PDA - if(istype(cartridge, /obj/item/weapon/cartridge/syndicate)) - var/obj/item/device/pda/P = locate(href_list["target"]) - if(!isnull(P)) - if (!P.toff && cartridge.charges > 0) - cartridge.charges-- - - var/difficulty = 0 - - if(P.cartridge) - difficulty += P.cartridge.access_medical - difficulty += P.cartridge.access_security - difficulty += P.cartridge.access_engine - difficulty += P.cartridge.access_clown - difficulty += P.cartridge.access_janitor - else - difficulty += 2 - - if(prob(difficulty * 12) || (P.hidden_uplink)) - U.show_message("\red An error flashes on your [src].", 1) - else if (prob(difficulty * 3)) - U.show_message("\red Energy feeds back into your [src]!", 1) - ui.close() - explode() - log_admin("[key_name(U)] just attempted to blow up [P] with the Detomatix cartridge but failed, blowing themselves up") - message_admins("[key_name_admin(U)] just attempted to blow up [P] with the Detomatix cartridge but failed, blowing themselves up", 1) - else - U.show_message("\blue Success!", 1) - log_admin("[key_name(U)] just attempted to blow up [P] with the Detomatix cartridge and succeded") - message_admins("[key_name_admin(U)] just attempted to blow up [P] with the Detomatix cartridge and succeded", 1) - P.explode() - else - U << "PDA not found." - else - U.unset_machine() - ui.close() - return 0 - -//pAI FUNCTIONS=================================== - if("pai") - if(pai) - if(pai.loc != src) - pai = null - else - switch(href_list["option"]) - if("1") // Configure pAI device - pai.attack_self(U) - if("2") // Eject pAI device - var/turf/T = get_turf_or_move(src.loc) - if(T) - pai.loc = T - pai = null - - else - mode = text2num(href_list["choice"]) - if(cartridge) - cartridge.mode = mode - -//EXTRA FUNCTIONS=================================== - - if (mode == 2||mode == 21)//To clear message overlays. - overlays.Cut() - newmessage = 0 - - if ((honkamt > 0) && (prob(60)))//For clown virus. - honkamt-- - playsound(loc, 'sound/items/bikehorn.ogg', 30, 1) - - return 1 // return 1 tells it to refresh the UI in NanoUI - -/obj/item/device/pda/verb/verb_reset_pda() - set category = "Object" - set name = "Reset PDA" - set src in usr - - if(issilicon(usr)) - return - - if(can_use(usr)) - mode = 0 - nanomanager.update_uis(src) - usr << "You press the reset button on \the [src]." - else - usr << "You cannot do this while restrained." - -/obj/item/device/pda/proc/remove_id() - if (id) - if (ismob(loc)) - var/mob/M = loc - M.put_in_hands(id) - usr << "You remove the ID from the [name]." - else - id.loc = get_turf(src) - id = null - -/obj/item/device/pda/proc/create_message(var/mob/living/U = usr, var/obj/item/device/pda/P) - - var/t = input(U, "Please enter message", name, null) as text|null - if(!t) - return - t = sanitize(copytext(t, 1, MAX_MESSAGE_LEN)) - t = readd_quotes(t) - if (!t || !istype(P)) - return - if (!in_range(src, U) && loc != U) - return - - if (isnull(P)||P.toff || toff) - return - - if (last_text && world.time < last_text + 5) - return - - if(!can_use()) - return - - last_text = world.time - // check if telecomms I/O route 1459 is stable - //var/telecomms_intact = telecomms_process(P.owner, owner, t) - var/obj/machinery/message_server/useMS = null - if(message_servers) - for (var/obj/machinery/message_server/MS in message_servers) - //PDAs are now dependent on the Message Server. - if(MS.active) - useMS = MS - break - - var/datum/signal/signal = src.telecomms_process() - - var/useTC = 0 - if(signal) - if(signal.data["done"]) - useTC = 1 - var/turf/pos = get_turf(P) - if(pos.z in signal.data["level"]) - useTC = 2 - //Let's make this barely readable - if(signal.data["compression"] > 0) - t = Gibberish(t, signal.data["compression"] + 50) - - if(useMS && useTC) // only send the message if it's stable - if(useTC != 2) // Does our recipient have a broadcaster on their level? - U << "ERROR: Cannot reach recipient." - return - useMS.send_pda_message("[P.owner]","[owner]","[t]") - tnote.Add(list(list("sent" = 1, "owner" = "[P.owner]", "job" = "[P.ownjob]", "message" = "[t]", "target" = "\ref[P]"))) - P.tnote.Add(list(list("sent" = 0, "owner" = "[owner]", "job" = "[ownjob]", "message" = "[t]", "target" = "\ref[src]"))) -/* for(var/mob/M in player_list) - if(M.stat == DEAD && M.client && (M.client.prefs.toggles & CHAT_GHOSTEARS)) // src.client is so that ghosts don't have to listen to mice - if(istype(M, /mob/new_player)) - continue - M.show_message("PDA Message - [owner] -> [P.owner]: [t]") */ - investigate_log("PDA Message - [U.key] - [owner] -> [P.owner]: [t]", "pda") - if(!conversations.Find("\ref[P]")) - conversations.Add("\ref[P]") - if(!P.conversations.Find("\ref[src]")) - P.conversations.Add("\ref[src]") - -/* - if (prob(15)) //Give the AI a chance of intercepting the message - var/who = src.owner - if(prob(50)) - who = P.owner - for(var/mob/living/silicon/ai/ai in mob_list) - // Allows other AIs to intercept the message but the AI won't intercept their own message. - if(ai.aiPDA != P && ai.aiPDA != src) - ai.show_message("Intercepted message from [who]: [t]") -*/ - - P.play_ringtone() - //Search for holder of the PDA. - var/mob/living/L = null - if(P.loc && isliving(P.loc)) - L = P.loc - //Maybe they are a pAI! - else - L = get(P, /mob/living/silicon) - - - if(L) - L << "\icon[P] Message from [src.owner] ([ownjob]), \"[t]\" (Reply)" - nanomanager.update_user_uis(L, P) // Update the receiving user's PDA UI so that they can see the new message - - nanomanager.update_user_uis(U, P) // Update the sending user's PDA UI so that they can see the new message - - log_pda("[usr] (PDA: [src.name]) sent \"[t]\" to [P.name]") - P.overlays.Cut() - P.overlays += image('icons/obj/pda.dmi', "pda-r") - P.newmessage = 1 - else - U << "ERROR: Messaging server is not responding." - -/obj/item/device/pda/proc/play_ringtone() - if (!silent) - var/sound/S = sound('sound/machines/twobeep.ogg') - - if(ttone in ttone_sound) - S = ttone_sound[ttone] - playsound(loc, S, 50, 1) - for (var/mob/O in hearers(3, loc)) - if(!silent) O.show_message(text("\icon[src] *[ttone]*")) - -/obj/item/device/pda/verb/verb_remove_id() - set category = "Object" - set name = "Remove id" - set src in usr - - if(issilicon(usr)) - return - - if ( can_use(usr) ) - if(id) - remove_id() - else - usr << "This PDA does not have an ID in it." - else - usr << "You cannot do this while restrained." - - -/obj/item/device/pda/verb/verb_remove_pen() - set category = "Object" - set name = "Remove pen" - set src in usr - - if(issilicon(usr)) - return - - if ( can_use(usr) ) - var/obj/item/weapon/pen/O = locate() in src - if(O) - if (istype(loc, /mob)) - var/mob/M = loc - if(M.get_active_hand() == null) - M.put_in_hands(O) - usr << "You remove \the [O] from \the [src]." - return - O.loc = get_turf(src) - else - usr << "This PDA does not have a pen in it." - else - usr << "You cannot do this while restrained." - - -/obj/item/device/pda/proc/id_check(mob/user as mob, choice as num)//To check for IDs; 1 for in-pda use, 2 for out of pda use. - if(choice == 1) - if (id) - remove_id() - else - var/obj/item/I = user.get_active_hand() - if (istype(I, /obj/item/weapon/card/id)) - user.drop_item() - I.loc = src - id = I - else - var/obj/item/weapon/card/I = user.get_active_hand() - if (istype(I, /obj/item/weapon/card/id) && I:registered_name) - var/obj/old_id = id - user.drop_item() - I.loc = src - id = I - user.put_in_hands(old_id) - return - -// access to status display signals -/obj/item/device/pda/attackby(obj/item/C as obj, mob/user as mob, params) - ..() - if(istype(C, /obj/item/weapon/cartridge) && !cartridge) - cartridge = C - user.drop_item() - cartridge.loc = src - user << "You insert [cartridge] into [src]." - nanomanager.update_uis(src) // update all UIs attached to src - if(cartridge.radio) - cartridge.radio.hostpda = src - - else if(istype(C, /obj/item/weapon/card/id)) - var/obj/item/weapon/card/id/idcard = C - if(!idcard.registered_name) - user << "\The [src] rejects the ID." - return - if(!owner) - owner = idcard.registered_name - ownjob = idcard.assignment - ownrank = idcard.rank - name = "PDA-[owner] ([ownjob])" - user << "Card scanned." - else - //Basic safety check. If either both objects are held by user or PDA is on ground and card is in hand. - if(((src in user.contents) && (C in user.contents)) || (istype(loc, /turf) && in_range(src, user) && (C in user.contents)) ) - if( can_use(user) )//If they can still act. - id_check(user, 2) - user << "You put the ID into \the [src]'s slot." - updateSelfDialog()//Update self dialog on success. - return //Return in case of failed check or when successful. - updateSelfDialog()//For the non-input related code. - else if(istype(C, /obj/item/device/paicard) && !src.pai) - user.drop_item() - C.loc = src - pai = C - user << "You slot \the [C] into [src]." - nanomanager.update_uis(src) // update all UIs attached to src - else if(istype(C, /obj/item/weapon/pen)) - var/obj/item/weapon/pen/O = locate() in src - if(O) - user << "There is already a pen in \the [src]." - else - user.drop_item() - C.loc = src - user << "You slide \the [C] into \the [src]." - return - -/obj/item/device/pda/attack(mob/living/C as mob, mob/living/user as mob) - if (istype(C, /mob/living/carbon)) - switch(scanmode) - if(1) - for (var/mob/O in viewers(C, null)) - O.show_message("\red [user] has analyzed [C]'s vitals!", 1) - - user.show_message("\blue Analyzing Results for [C]:") - user.show_message("\blue \t Overall Status: [C.stat > 1 ? "dead" : "[C.health - C.halloss]% healthy"]", 1) - user.show_message("\blue \t Damage Specifics: [C.getOxyLoss() > 50 ? "\red" : "\blue"][C.getOxyLoss()]-[C.getToxLoss() > 50 ? "\red" : "\blue"][C.getToxLoss()]-[C.getFireLoss() > 50 ? "\red" : "\blue"][C.getFireLoss()]-[C.getBruteLoss() > 50 ? "\red" : "\blue"][C.getBruteLoss()]", 1) - user.show_message("\blue \t Key: Suffocation/Toxin/Burns/Brute", 1) - user.show_message("\blue \t Body Temperature: [C.bodytemperature-T0C]°C ([C.bodytemperature*1.8-459.67]°F)", 1) - if(C.timeofdeath && (C.stat == DEAD || (C.status_flags & FAKEDEATH))) - user.show_message("\blue \t Time of Death: [C.timeofdeath]") - if(istype(C, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = C - var/list/damaged = H.get_damaged_organs(1,1) - user.show_message("\blue Localized Damage, Brute/Burn:",1) - if(length(damaged)>0) - for(var/obj/item/organ/external/org in damaged) - user.show_message(text("\blue \t []: []\blue-[]",capitalize(org.name),(org.brute_dam > 0)?"\red [org.brute_dam]":0,(org.burn_dam > 0)?"\red [org.burn_dam]":0),1) - else - user.show_message("\blue \t Limbs are OK.",1) - - if(2) - if (!istype(C:dna, /datum/dna)) - user << "\blue No fingerprints found on [C]" - else - user << text("\blue [C]'s Fingerprints: [md5(C:dna.uni_identity)]") - if ( !(C:blood_DNA) ) - user << "\blue No blood found on [C]" - if(C:blood_DNA) - qdel(C:blood_DNA) - else - user << "\blue Blood found on [C]. Analysing..." - spawn(15) - for(var/blood in C:blood_DNA) - user << "\blue Blood type: [C:blood_DNA[blood]]\nDNA: [blood]" - - if(4) - for (var/mob/O in viewers(C, null)) - O.show_message("\red [user] has analyzed [C]'s radiation levels!", 1) - - user.show_message("\blue Analyzing Results for [C]:") - if(C.radiation) - user.show_message("\green Radiation Level: \black [C.radiation]") - else - user.show_message("\blue No radiation detected.") - -/obj/item/device/pda/afterattack(atom/A as mob|obj|turf|area, mob/user as mob, proximity) - if(!proximity) return - switch(scanmode) - - if(3) - if(!isnull(A.reagents)) - if(A.reagents.reagent_list.len > 0) - var/reagents_length = A.reagents.reagent_list.len - user << "[reagents_length] chemical agent[reagents_length > 1 ? "s" : ""] found." - for (var/re in A.reagents.reagent_list) - user << "\t [re]" - else - user << "No active chemical agents found in [A]." - else - user << "No significant chemical agents found in [A]." - - if(5) - if (istype(A, /obj/item/weapon/tank)) - var/obj/item/weapon/tank/T = A - atmosanalyzer_scan(T.air_contents, user, T) - else if (istype(A, /obj/machinery/portable_atmospherics)) - var/obj/machinery/portable_atmospherics/T = A - atmosanalyzer_scan(T.air_contents, user, T) - else if (istype(A, /obj/machinery/atmospherics/pipe)) - var/obj/machinery/atmospherics/pipe/T = A - atmosanalyzer_scan(T.parent.air, user, T) - else if (istype(A, /obj/machinery/power/rad_collector)) - var/obj/machinery/power/rad_collector/T = A - if(T.P) atmosanalyzer_scan(T.P.air_contents, user, T) - else if (istype(A, /obj/item/weapon/flamethrower)) - var/obj/item/weapon/flamethrower/T = A - if(T.ptank) atmosanalyzer_scan(T.ptank.air_contents, user, T) - else if (istype(A, /obj/machinery/portable_atmospherics/scrubber/huge)) - var/obj/machinery/portable_atmospherics/scrubber/huge/T = A - atmosanalyzer_scan(T.air_contents, user, T) - else if (istype(A, /obj/machinery/atmospherics/unary/tank)) - var/obj/machinery/atmospherics/unary/tank/T = A - atmosanalyzer_scan(T.air_contents, user, T) - - if (!scanmode && istype(A, /obj/item/weapon/paper) && owner) - // JMO 20140705: Makes scanned document show up properly in the notes. Not pretty for formatted documents, - // as this will clobber the HTML, but at least it lets you scan a document. You can restore the original - // notes by editing the note again. (Was going to allow you to edit, but scanned documents are too long.) - var/raw_scan = (A:info) - var/formatted_scan = "" - // Scrub out the tags (replacing a few formatting ones along the way) - // Find the beginning and end of the first tag. - var/tag_start = findtext(raw_scan,"<") - var/tag_stop = findtext(raw_scan,">") - // Until we run out of complete tags... - while(tag_start&&tag_stop) - var/pre = copytext(raw_scan,1,tag_start) // Get the stuff that comes before the tag - var/tag = lowertext(copytext(raw_scan,tag_start+1,tag_stop)) // Get the tag so we can do intellegent replacement - var/tagend = findtext(tag," ") // Find the first space in the tag if there is one. - // Anything that's before the tag can just be added as is. - formatted_scan = formatted_scan+pre - // If we have a space after the tag (and presumably attributes) just crop that off. - if (tagend) - tag=copytext(tag,1,tagend) - if (tag=="p"||tag=="/p"||tag=="br") // Check if it's I vertical space tag. - formatted_scan=formatted_scan+"
    " // If so, add some padding in. - raw_scan = copytext(raw_scan,tag_stop+1) // continue on with the stuff after the tag - // Look for the next tag in what's left - tag_start = findtext(raw_scan,"<") - tag_stop = findtext(raw_scan,">") - // Anything that is left in the page. just tack it on to the end as is - formatted_scan=formatted_scan+raw_scan - // If there is something in there already, pad it out. - if (length(note)>0) - note = note + "

    " - // Store the scanned document to the notes - note = "Scanned Document. Edit to restore previous notes/delete scan.
    ----------
    " + formatted_scan + "
    " - // notehtml ISN'T set to allow user to get their old notes back. A better implementation would add a "scanned documents" - // feature to the PDA, which would better convey the availability of the feature, but this will work for now. - // Inform the user - user << "\blue Paper scanned and OCRed to notekeeper." //concept of scanning paper copyright brainoblivion 2009 - -/obj/item/device/pda/proc/explode() //This needs tuning. - if(!src.detonate) return - var/turf/T = get_turf(src.loc) - - if (ismob(loc)) - var/mob/M = loc - M.show_message("Your [src] explodes!", 1) - - if(T) - T.hotspot_expose(700,125) - - explosion(T, -1, -1, 2, 3) - qdel(src) - return - -/obj/item/device/pda/Destroy() - PDAs -= src - if (src.id) - src.id.loc = get_turf(src.loc) - if(src.pai) - src.pai.loc = get_turf(src.loc) - return ..() - -/obj/item/device/pda/clown/Crossed(AM as mob|obj) //Clown PDA is slippery. - if (istype(AM, /mob/living/carbon)) - var/mob/M = AM - if ((istype(M, /mob/living/carbon/human) && (istype(M:shoes, /obj/item/clothing/shoes) && M:shoes.flags&NOSLIP)) || M.m_intent == "walk") - return - - if ((istype(M, /mob/living/carbon/human) && (M.real_name != src.owner) && (istype(src.cartridge, /obj/item/weapon/cartridge/clown)))) - if (src.cartridge.charges < 5) - src.cartridge.charges++ - - M.stop_pulling() - M << "\blue You slipped on the PDA!" - playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3) - M.Stun(8) - M.Weaken(5) - -/obj/item/device/pda/proc/available_pdas() - var/list/names = list() - var/list/plist = list() - var/list/namecounts = list() - - if (toff) - usr << "Turn on your receiver in order to send messages." - return - - for (var/obj/item/device/pda/P in PDAs) - if (!P.owner) - continue - else if(P.hidden) - continue - else if (P == src) - continue - else if (P.toff) - continue - - var/name = P.owner - if (name in names) - namecounts[name]++ - name = text("[name] ([namecounts[name]])") - else - names.Add(name) - namecounts[name] = 1 - - plist[text("[name]")] = P - return plist - -//Some spare PDAs in a box -/obj/item/weapon/storage/box/PDAs - name = "spare PDAs" - desc = "A box of spare PDA microcomputers." - icon = 'icons/obj/pda.dmi' - icon_state = "pdabox" - - New() - ..() - new /obj/item/device/pda(src) - new /obj/item/device/pda(src) - new /obj/item/device/pda(src) - new /obj/item/device/pda(src) - new /obj/item/weapon/cartridge/head(src) - - var/newcart = pick( /obj/item/weapon/cartridge/engineering, - /obj/item/weapon/cartridge/security, - /obj/item/weapon/cartridge/medical, - /obj/item/weapon/cartridge/signal/toxins, - /obj/item/weapon/cartridge/quartermaster) - new newcart(src) - -// Pass along the pulse to atoms in contents, largely added so pAIs are vulnerable to EMP -/obj/item/device/pda/emp_act(severity) - for(var/atom/A in src) - A.emp_act(severity) diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm deleted file mode 100644 index 2f5790c5fbb..00000000000 --- a/code/game/objects/items/devices/PDA/cart.dm +++ /dev/null @@ -1,612 +0,0 @@ -/obj/item/weapon/cartridge - name = "generic cartridge" - desc = "A data cartridge for portable microcomputers." - icon = 'icons/obj/pda.dmi' - icon_state = "cart" - item_state = "electronic" - w_class = 1 - - var/obj/item/radio/integrated/radio = null - var/access_security = 0 - var/access_engine = 0 - var/access_atmos = 0 - var/access_medical = 0 - var/access_clown = 0 - var/access_mime = 0 - var/access_janitor = 0 -// var/access_flora = 0 - var/access_reagent_scanner = 0 - var/access_remote_door = 0 // Control some blast doors remotely!! - var/remote_door_id = "" - var/access_status_display = 0 - var/access_quartermaster = 0 - var/access_detonate_pda = 0 - var/access_hydroponics = 0 - var/charges = 0 - var/mode = null - var/menu - var/datum/data/record/active1 = null //General - var/datum/data/record/active2 = null //Medical - var/datum/data/record/active3 = null //Security - var/obj/machinery/computer/monitor/powmonitor = null // Power Monitor - var/list/powermonitors = list() - var/message1 // used for status_displays - var/message2 - var/list/stored_data = list() - -/obj/item/weapon/cartridge/engineering - name = "Power-ON Cartridge" - icon_state = "cart-e" - access_engine = 1 - -/obj/item/weapon/cartridge/atmos - name = "BreatheDeep Cartridge" - icon_state = "cart-a" - access_atmos = 1 - -/obj/item/weapon/cartridge/medical - name = "Med-U Cartridge" - icon_state = "cart-m" - access_medical = 1 - -/obj/item/weapon/cartridge/chemistry - name = "ChemWhiz Cartridge" - icon_state = "cart-chem" - access_reagent_scanner = 1 - -/obj/item/weapon/cartridge/security - name = "R.O.B.U.S.T. Cartridge" - icon_state = "cart-s" - access_security = 1 - -/obj/item/weapon/cartridge/security/initialize() - radio = new /obj/item/radio/integrated/beepsky(src) - ..() - -/obj/item/weapon/cartridge/detective - name = "D.E.T.E.C.T. Cartridge" - icon_state = "cart-s" - access_security = 1 - access_medical = 1 - - -/obj/item/weapon/cartridge/janitor - name = "CustodiPRO Cartridge" - desc = "The ultimate in clean-room design." - icon_state = "cart-j" - access_janitor = 1 - -/obj/item/weapon/cartridge/lawyer - name = "P.R.O.V.E. Cartridge" - icon_state = "cart-s" - access_security = 1 - -/obj/item/weapon/cartridge/clown - name = "Honkworks 5.0" - icon_state = "cart-clown" - access_clown = 1 - charges = 5 - -/obj/item/weapon/cartridge/mime - name = "Gestur-O 1000" - icon_state = "cart-mi" - access_mime = 1 - charges = 5 -/* -/obj/item/weapon/cartridge/botanist - name = "Green Thumb v4.20" - icon_state = "cart-b" - access_flora = 1 -*/ - -/obj/item/weapon/cartridge/signal - name = "generic signaler cartridge" - desc = "A data cartridge with an integrated radio signaler module." - -/obj/item/weapon/cartridge/signal/toxins - name = "Signal Ace 2" - desc = "Complete with integrated radio signaler!" - icon_state = "cart-tox" - access_reagent_scanner = 1 - access_atmos = 1 - -/obj/item/weapon/cartridge/signal/initialize() - radio = new /obj/item/radio/integrated/signal(src) - ..() - -/obj/item/weapon/cartridge/signal/Destroy() - qdel(radio) - return ..() - -/obj/item/weapon/cartridge/quartermaster - name = "Space Parts & Space Vendors Cartridge" - desc = "Perfect for the Quartermaster on the go!" - icon_state = "cart-q" - access_quartermaster = 1 - -/obj/item/weapon/cartridge/quartermaster/initialize() - radio = new /obj/item/radio/integrated/mule(src) - ..() - -/obj/item/weapon/cartridge/head - name = "Easy-Record DELUXE" - icon_state = "cart-h" - access_status_display = 1 - -/obj/item/weapon/cartridge/hop - name = "HumanResources9001" - icon_state = "cart-h" - access_status_display = 1 - access_quartermaster = 1 - access_janitor = 1 - access_security = 1 - -/obj/item/weapon/cartridge/hop/initialize() - radio = new /obj/item/radio/integrated/mule(src) - ..() - -/obj/item/weapon/cartridge/hos - name = "R.O.B.U.S.T. DELUXE" - icon_state = "cart-hos" - access_status_display = 1 - access_security = 1 - -/obj/item/weapon/cartridge/hos/initialize() - radio = new /obj/item/radio/integrated/beepsky(src) - ..() - -/obj/item/weapon/cartridge/ce - name = "Power-On DELUXE" - icon_state = "cart-ce" - access_status_display = 1 - access_engine = 1 - access_atmos = 1 - -/obj/item/weapon/cartridge/cmo - name = "Med-U DELUXE" - icon_state = "cart-cmo" - access_status_display = 1 - access_reagent_scanner = 1 - access_medical = 1 - -/obj/item/weapon/cartridge/rd - name = "Signal Ace DELUXE" - icon_state = "cart-rd" - access_status_display = 1 - access_reagent_scanner = 1 - access_atmos = 1 - -/obj/item/weapon/cartridge/rd/initialize() - radio = new /obj/item/radio/integrated/signal(src) - ..() - -/obj/item/weapon/cartridge/captain - name = "Value-PAK Cartridge" - desc = "Now with 200% more value!" - icon_state = "cart-c" - access_quartermaster = 1 - access_janitor = 1 - access_engine = 1 - access_security = 1 - access_medical = 1 - access_reagent_scanner = 1 - access_status_display = 1 - access_atmos = 1 - -/obj/item/weapon/cartridge/captain/initialize() - radio = new /obj/item/radio/integrated/beepsky(src) - ..() - -/obj/item/weapon/cartridge/supervisor - name = "Easy-Record DELUXE" - icon_state = "cart-h" - access_status_display = 1 - access_security = 1 - -/obj/item/weapon/cartridge/centcom - name = "Value-PAK Cartridge" - desc = "Now with 200% more value!" - icon_state = "cart-c" - access_quartermaster = 1 - access_janitor = 1 - access_engine = 1 - access_security = 1 - access_medical = 1 - access_reagent_scanner = 1 - access_status_display = 1 - access_atmos = 1 - -/obj/item/weapon/cartridge/centcom/initialize() - radio = new /obj/item/radio/integrated/beepsky(src) - ..() - -/obj/item/weapon/cartridge/syndicate - name = "Detomatix Cartridge" - icon_state = "cart" - access_remote_door = 1 - access_detonate_pda = 1 - remote_door_id = "smindicate" //Make sure this matches the syndicate shuttle's shield/door id!! //don't ask about the name, testing. - charges = 4 - -/obj/item/weapon/cartridge/proc/post_status(var/command, var/data1, var/data2) - - var/datum/radio_frequency/frequency = radio_controller.return_frequency(1435) - if(!frequency) return - - var/datum/signal/status_signal = new - status_signal.source = src - status_signal.transmission_method = 1 - status_signal.data["command"] = command - - switch(command) - if("message") - status_signal.data["msg1"] = data1 - status_signal.data["msg2"] = data2 - if(loc) - var/obj/item/PDA = loc - var/mob/user = PDA.fingerprintslast - if(istype(PDA.loc,/mob/living)) - name = PDA.loc - log_admin("STATUS: [user] set status screen with [PDA]. Message: [data1] [data2]") - message_admins("STATUS: [user] set status screen with [PDA]. Message: [data1] [data2]") - - if("alert") - status_signal.data["picture_state"] = data1 - - frequency.post_signal(src, status_signal) - - -/* - This generates the nano values of the cart menus. - Because we close the UI when we insert a new cart - we don't have to worry about null values on items - the user can't access. Well, unless they are href hacking. - But in that case their UI will just lock up. -*/ - - -/obj/item/weapon/cartridge/proc/create_NanoUI_values(mob/user as mob) - var/values[0] - - /* Signaler (Mode: 40) */ - - - if(istype(radio,/obj/item/radio/integrated/signal) && (mode==40)) - var/obj/item/radio/integrated/signal/R = radio - values["signal_freq"] = format_frequency(R.frequency) - values["signal_code"] = R.code - - - /* Station Display (Mode: 42) */ - - if(mode==42) - values["message1"] = message1 ? message1 : "(none)" - values["message2"] = message2 ? message2 : "(none)" - - - - /* Power Monitor (Mode: 43 / 433) */ - if(mode==43 || mode==433) - values["powermonitors"] = powermonitor_repository.powermonitor_data() - - if (powmonitor && !isnull(powmonitor.powernet)) - values["powerconnected"] = 1 - values["poweravail"] = powmonitor.powernet.avail - values["powerload"] = num2text(powmonitor.powernet.viewload,10) - values["powerdemand"] = powmonitor.powernet.load - values["apcs"] = apc_repository.apc_data(powmonitor) - else - values["powerconnected"] = 0 - - - - - - /* General Records (Mode: 44 / 441 / 45 / 451) */ - if(mode == 44 || mode == 441 || mode == 45 || mode ==451) - if(istype(active1, /datum/data/record) && (active1 in data_core.general)) - values["general"] = active1.fields - values["general_exists"] = 1 - - else - - values["general_exists"] = 0 - - - - /* Medical Records (Mode: 44 / 441) */ - - if(mode == 44 || mode == 441) - var/medData[0] - for(var/datum/data/record/R in sortRecord(data_core.general)) - medData[++medData.len] = list(Name = R.fields["name"],"ref" = "\ref[R]") - values["medical_records"] = medData - - if(istype(active2, /datum/data/record) && (active2 in data_core.medical)) - values["medical"] = active2.fields - values["medical_exists"] = 1 - else - values["medical_exists"] = 0 - - /* Security Records (Mode:45 / 451) */ - - if(mode == 45 || mode == 451) - var/secData[0] - for (var/datum/data/record/R in sortRecord(data_core.general)) - secData[++secData.len] = list(Name = R.fields["name"], "ref" = "\ref[R]") - values["security_records"] = secData - - if(istype(active3, /datum/data/record) && (active3 in data_core.security)) - values["security"] = active3.fields - values["security_exists"] = 1 - else - values["security_exists"] = 0 - - /* Security Bot Control (Mode: 46) */ - - if(mode==46) - var/botsData[0] - var/beepskyData[0] - if(istype(radio,/obj/item/radio/integrated/beepsky)) - var/obj/item/radio/integrated/beepsky/SC = radio - beepskyData["active"] = SC.active - if(SC.active && !isnull(SC.botstatus)) - var/area/loca = SC.botstatus["loca"] - var/loca_name = sanitize(loca.name) - beepskyData["botstatus"] = list("loca" = loca_name, "mode" = SC.botstatus["mode"]) - else - beepskyData["botstatus"] = list("loca" = null, "mode" = -1) - var/botsCount=0 - if(SC.botlist && SC.botlist.len) - for(var/obj/machinery/bot/B in SC.botlist) - botsCount++ - if(B.loc) - botsData[++botsData.len] = list("Name" = sanitize(B.name), "Location" = sanitize(B.loc.loc.name), "ref" = "\ref[B]") - - if(!botsData.len) - botsData[++botsData.len] = list("Name" = "No bots found", "Location" = "Invalid", "ref"= null) - - beepskyData["bots"] = botsData - beepskyData["count"] = botsCount - - else - beepskyData["active"] = 0 - botsData[++botsData.len] = list("Name" = "No bots found", "Location" = "Invalid", "ref"= null) - beepskyData["botstatus"] = list("loca" = null, "mode" = null) - beepskyData["bots"] = botsData - beepskyData["count"] = 0 - - values["beepsky"] = beepskyData - - - /* MULEBOT Control (Mode: 48) */ - - if(mode==48) - var/muleData[0] - var/mulebotsData[0] - if(istype(radio,/obj/item/radio/integrated/mule)) - var/obj/item/radio/integrated/mule/QC = radio - muleData["active"] = QC.active - if(QC.active && !isnull(QC.botstatus)) - var/area/loca = QC.botstatus["loca"] - var/loca_name = sanitize(loca.name) - muleData["botstatus"] = list("loca" = loca_name, "mode" = QC.botstatus["mode"],"home"=QC.botstatus["home"],"powr" = QC.botstatus["powr"],"retn" =QC.botstatus["retn"], "pick"=QC.botstatus["pick"], "load" = QC.botstatus["load"], "dest" = sanitize(QC.botstatus["dest"])) - - else - muleData["botstatus"] = list("loca" = null, "mode" = -1,"home"=null,"powr" = null,"retn" =null, "pick"=null, "load" = null, "dest" = null) - - - var/mulebotsCount=0 - for(var/obj/machinery/bot/B in QC.botlist) - mulebotsCount++ - if(B.loc) - mulebotsData[++mulebotsData.len] = list("Name" = sanitize(B.name), "Location" = sanitize(B.loc.loc.name), "ref" = "\ref[B]") - - if(!mulebotsData.len) - mulebotsData[++mulebotsData.len] = list("Name" = "No bots found", "Location" = "Invalid", "ref"= null) - - muleData["bots"] = mulebotsData - muleData["count"] = mulebotsCount - - else - muleData["botstatus"] = list("loca" = null, "mode" = -1,"home"=null,"powr" = null,"retn" =null, "pick"=null, "load" = null, "dest" = null) - muleData["active"] = 0 - mulebotsData[++mulebotsData.len] = list("Name" = "No bots found", "Location" = "Invalid", "ref"= null) - muleData["bots"] = mulebotsData - muleData["count"] = 0 - - values["mulebot"] = muleData - - - - /* Supply Shuttle Requests Menu (Mode: 47) */ - - if(mode==47) - var/supplyData[0] - - if(shuttle_master.supply.mode == SHUTTLE_CALL) - supplyData["shuttle_moving"] = 1 - - if(shuttle_master.supply.z != ZLEVEL_STATION) - supplyData["shuttle_loc"] = "station" - else - supplyData["shuttle_loc"] = "centcom" - - supplyData["shuttle_time"] = "([shuttle_master.supply.timeLeft(600)] Mins)" - - var/supplyOrderCount = 0 - var/supplyOrderData[0] - for(var/S in shuttle_master.shoppinglist) - var/datum/supply_order/SO = S - supplyOrderData[++supplyOrderData.len] = list("Number" = SO.ordernum, "Name" = html_encode(SO.object.name), "ApprovedBy" = SO.orderedby, "Comment" = html_encode(SO.comment)) - - if(!supplyOrderData.len) - supplyOrderData[++supplyOrderData.len] = list("Number" = null, "Name" = null, "OrderedBy"=null) - - supplyData["approved"] = supplyOrderData - supplyData["approved_count"] = supplyOrderCount - - var/requestCount = 0 - var/requestData[0] - for(var/S in shuttle_master.requestlist) - var/datum/supply_order/SO = S - requestCount++ - requestData[++requestData.len] = list("Number" = SO.ordernum, "Name" = html_encode(SO.object.name), "OrderedBy" = SO.orderedby, "Comment" = html_encode(SO.comment)) - - if(!requestData.len) - requestData[++requestData.len] = list("Number" = null, "Name" = null, "orderedBy" = null, "Comment" = null) - - supplyData["requests"] = requestData - supplyData["requests_count"] = requestCount - - - values["supply"] = supplyData - - - - /* Janitor Supplies Locator (Mode: 49) */ - if(mode==49) - var/JaniData[0] - var/turf/cl = get_turf(src) - - if(cl) - JaniData["user_loc"] = list("x" = cl.x, "y" = cl.y) - else - JaniData["user_loc"] = list("x" = 0, "y" = 0) - var/MopData[0] - for(var/obj/item/weapon/mop/M in janitorial_equipment) - var/turf/ml = get_turf(M) - if(ml) - if(ml.z != cl.z) - continue - var/direction = get_dir(src, M) - MopData[++MopData.len] = list ("x" = ml.x, "y" = ml.y, "dir" = uppertext(dir2text(direction)), "status" = M.reagents.total_volume ? "Wet" : "Dry") - - if(!MopData.len) - MopData[++MopData.len] = list("x" = 0, "y" = 0, dir=null, status = null) - - - var/BucketData[0] - for(var/obj/structure/mopbucket/B in janitorial_equipment) - var/turf/bl = get_turf(B) - if(bl) - if(bl.z != cl.z) - continue - var/direction = get_dir(src,B) - BucketData[++BucketData.len] = list ("x" = bl.x, "y" = bl.y, "dir" = uppertext(dir2text(direction)), "status" = B.reagents.total_volume/100) - - if(!BucketData.len) - BucketData[++BucketData.len] = list("x" = 0, "y" = 0, dir=null, status = null) - - var/CbotData[0] - for(var/obj/machinery/bot/cleanbot/B in aibots) - var/turf/bl = get_turf(B) - if(bl) - if(bl.z != cl.z) - continue - var/direction = get_dir(src,B) - CbotData[++CbotData.len] = list("x" = bl.x, "y" = bl.y, "dir" = uppertext(dir2text(direction)), "status" = B.on ? "Online" : "Offline") - - - if(!CbotData.len) - CbotData[++CbotData.len] = list("x" = 0, "y" = 0, dir=null, status = null) - var/CartData[0] - for(var/obj/structure/janitorialcart/B in janitorial_equipment) - var/turf/bl = get_turf(B) - if(bl) - if(bl.z != cl.z) - continue - var/direction = get_dir(src,B) - CartData[++CartData.len] = list("x" = bl.x, "y" = bl.y, "dir" = uppertext(dir2text(direction)), "status" = B.reagents.total_volume/100) - if(!CartData.len) - CartData[++CartData.len] = list("x" = 0, "y" = 0, dir=null, status = null) - - - - - JaniData["mops"] = MopData - JaniData["buckets"] = BucketData - JaniData["cleanbots"] = CbotData - JaniData["carts"] = CartData - values["janitor"] = JaniData - - return values - - - - - -/obj/item/weapon/cartridge/Topic(href, href_list) - ..() - - if (!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) - usr.unset_machine() - usr << browse(null, "window=pda") - return - - - - - switch(href_list["choice"]) - if("Medical Records") - var/datum/data/record/R = locate(href_list["target"]) - var/datum/data/record/M = locate(href_list["target"]) - loc:mode = 441 - mode = 441 - if (R in data_core.general) - for (var/datum/data/record/E in data_core.medical) - if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) - M = E - break - active1 = R - active2 = M - - if("Security Records") - var/datum/data/record/R = locate(href_list["target"]) - var/datum/data/record/S = locate(href_list["target"]) - loc:mode = 451 - mode = 451 - if (R in data_core.general) - for (var/datum/data/record/E in data_core.security) - if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) - S = E - break - active1 = R - active3 = S - - if("Send Signal") - spawn( 0 ) - radio:send_signal("ACTIVATE") - return - - if("Signal Frequency") - var/new_frequency = sanitize_frequency(radio:frequency + text2num(href_list["sfreq"])) - radio:set_frequency(new_frequency) - - if("Signal Code") - radio:code += text2num(href_list["scode"]) - radio:code = round(radio:code) - radio:code = min(100, radio:code) - radio:code = max(1, radio:code) - - if("Status") - switch(href_list["statdisp"]) - if("message") - post_status("message", message1, message2) - if("alert") - post_status("alert", href_list["alert"]) - if("setmsg1") - message1 = input("Line 1", "Enter Message Text", message1) as text|null - updateSelfDialog() - if("setmsg2") - message2 = input("Line 2", "Enter Message Text", message2) as text|null - updateSelfDialog() - else - post_status(href_list["statdisp"]) - if("Power Select") - var/pref = href_list["target"] - powmonitor = locate(pref) - loc:mode = 433 - mode = 433 - - return 1 diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm index ed55d931d8c..e89f3213b4f 100644 --- a/code/game/objects/items/devices/laserpointer.dm +++ b/code/game/objects/items/devices/laserpointer.dm @@ -113,7 +113,7 @@ severity -= 1 severity = min(max(severity, 0), 4) var/mob/living/carbon/human/H = C - var/obj/item/organ/eyes/E = H.internal_organs_by_name["eyes"] + var/obj/item/organ/internal/eyes/E = H.get_int_organ(/obj/item/organ/internal/eyes) switch(severity) if(0) diff --git a/code/game/objects/items/devices/megaphone.dm b/code/game/objects/items/devices/megaphone.dm index 6d7c7a26ed6..af299225238 100644 --- a/code/game/objects/items/devices/megaphone.dm +++ b/code/game/objects/items/devices/megaphone.dm @@ -19,13 +19,19 @@ if(!ishuman(user)) user << "\red You don't know how to use this!" return - if(user:miming || user.silent) - user << "\red You find yourself unable to speak at all." + if(user.silent) + user << "You find yourself unable to speak at all." return + if(ishuman(user)) + var/mob/living/carbon/human/H = user + if(H & H.mind) + if(H.mind.miming) + user << "Your vow of silence prevents you from speaking." + return if(spamcheck) user << "\red \The [src] needs to recharge!" return - + var/message = input(user, "Shout a message:", "Megaphone") as text|null if(!message) return diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm index c08c79da86f..c9b6a6d7563 100644 --- a/code/game/objects/items/devices/powersink.dm +++ b/code/game/objects/items/devices/powersink.dm @@ -12,13 +12,14 @@ throw_range = 2 materials = list(MAT_METAL=750) origin_tech = "powerstorage=3;syndicate=5" - var/drain_rate = 1500000 // amount of power to drain per tick + var/drain_rate = 1600000 // amount of power to drain per tick var/apc_drain_rate = 5000 // Max. amount drained from single APC. In Watts. var/dissipation_rate = 20000 // Passive dissipation of drained power. In Watts. var/power_drained = 0 // Amount of power drained. - var/max_power = 5e9 // Detonation point. + var/max_power = 1e10 // Detonation point. var/mode = 0 // 0 = off, 1=clamped (off), 2=operating var/drained_this_tick = 0 // This is unfortunately necessary to ensure we process powersinks BEFORE other machinery such as APCs. + var/admins_warned = 0 // stop spam, only warn the admins once that we are about to go boom var/datum/powernet/PN // Our powernet var/obj/structure/cable/attached // the attached cable @@ -120,10 +121,13 @@ /obj/item/device/powersink/process() drained_this_tick = 0 power_drained -= min(dissipation_rate, power_drained) - if(power_drained > max_power * 0.95) + if(power_drained > max_power * 0.98) + if(!admins_warned) + admins_warned = 1 + message_admins("Power sink at ([x],[y],[z] - JMP) is 95% full. Explosion imminent.") playsound(src, 'sound/effects/screech.ogg', 100, 1, 1) if(power_drained >= max_power) - explosion(src.loc, 3,6,9,12) + explosion(src.loc, 4,8,16,32) qdel(src) return if(attached && attached.powernet) diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 2ee3d7e88ac..168f448ba4d 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -250,7 +250,7 @@ var/global/list/default_medbay_channels = list( return var/mob/living/silicon/ai/A = new /mob/living/silicon/ai(src, null, null, 1) - A.SetName(from) + A.rename_character(A.real_name, from) Broadcast_Message(connection, A, 0, "*garbled automated announcement*", src, message, from, "Automated Announcement", from, "synthesized voice", @@ -285,6 +285,9 @@ var/global/list/default_medbay_channels = list( if(wires.IsIndexCut(WIRE_TRANSMIT)) // The device has to have all its wires and shit intact return 0 + if(!M.IsVocal()) + return 0 + M.last_target_click = world.time /* Quick introduction: diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index e7337e1042d..63c2710ce8e 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -202,7 +202,7 @@ REAGENT SCANNER // user.show_message("\blue Bloodstream Analysis located [M.reagents:get_reagent_amount("epinephrine")] units of rejuvenation chemicals.") if (M.has_brain_worms()) user.show_message("\red Subject suffering from aberrant brain activity. Recommend further scanning.") - else if (M.getBrainLoss() >= 100 || istype(M, /mob/living/carbon/human) && M:brain_op_stage == 4.0) + else if (M.getBrainLoss() >= 100 || istype(M, /mob/living/carbon/human) && !M.get_int_organ(/obj/item/organ/internal/brain)) user.show_message("\red Subject is brain dead.") else if (M.getBrainLoss() >= 60) user.show_message("\red Severe brain damage detected. Subject likely to have mental retardation.") @@ -245,6 +245,14 @@ REAGENT SCANNER if(H.heart_attack) user.show_message("Subject suffering from heart attack: Apply defibrillator immediately.") user.show_message("\blue Subject's pulse: [H.get_pulse(GETPULSE_TOOL)] bpm.") + var/implant_detect + for(var/obj/item/organ/internal/cyberimp/CI in H.internal_organs) + if(CI.status == ORGAN_ROBOT) + implant_detect += "[H.name] is modified with a [CI.name].
    " + if(implant_detect) + user.show_message("Detected cybernetic modifications:") + user.show_message("[implant_detect]") + src.add_fingerprint(user) return diff --git a/code/game/objects/items/random_items.dm b/code/game/objects/items/random_items.dm index 9aa4263859a..ea53bf6c534 100644 --- a/code/game/objects/items/random_items.dm +++ b/code/game/objects/items/random_items.dm @@ -88,7 +88,7 @@ ..() var/list/additional_drinks = list() if(prob(50)) - additional_drinks += list("pancuronium","adminordrazine","lsd","omnizine","blood") + additional_drinks += list("pancuronium","lsd","omnizine","blood") var/datum/reagent/R = pick(drinks + additional_drinks) reagents.add_reagent(R,volume) diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index 0471f0db1eb..44f2081d387 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -234,7 +234,7 @@ O.invisibility = 0 //Transfer debug settings to new mob O.custom_name = created_name - O.updatename("Default") + O.rename_character(O.real_name, O.get_default_name()) O.locked = panel_locked if(!aisync) lawsync = 0 diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index a97ee46ea63..a650029b0e1 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -31,7 +31,7 @@ qdel(R.module) R.module = null R.camera.network.Remove(list("Engineering","Medical","Mining Outpost")) - R.updatename("Default") + R.rename_character(R.real_name, R.get_default_name("Default")) R.status_flags |= CANPUSH R.languages = list() R.speech_synthesizer_langs = list() diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 83043ed7770..e6b56907545 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -112,11 +112,7 @@ affecting.heal_damage(src.heal_brute, src.heal_burn, 0) use(1) else - if (can_operate(H)) //Checks if mob is lying down on table for surgery - if (do_surgery(H,user,src)) - return - else - user << "The [affecting.name] is cut open, you'll need more than some ointment!" + user << "The [affecting.name] is cut open, you'll need more than some ointment!" /obj/item/stack/medical/bruise_pack/comfrey name = "\improper Comfrey leaf" @@ -177,11 +173,7 @@ affecting.heal_damage(heal_brute,0) use(1) else - if (can_operate(H)) //Checks if mob is lying down on table for surgery - if (do_surgery(H,user,src)) - return - else - user << "The [affecting.name] is cut open, you'll need more than a bandage!" + user << "The [affecting.name] is cut open, you'll need more than a bandage!" /obj/item/stack/medical/advanced/ointment name = "advanced burn kit" @@ -210,11 +202,7 @@ affecting.heal_damage(0,heal_burn) use(1) else - if (can_operate(H)) //Checks if mob is lying down on table for surgery - if (do_surgery(H,user,src)) - return - else - user << "The [affecting.name] is cut open, you'll need more than a bandage!" + user << "The [affecting.name] is cut open, you'll need more than a bandage!" /obj/item/stack/medical/splint name = "medical splints" diff --git a/code/game/objects/items/stacks/nanopaste.dm b/code/game/objects/items/stacks/nanopaste.dm index fea0281c9b8..f813fbaecc5 100644 --- a/code/game/objects/items/stacks/nanopaste.dm +++ b/code/game/objects/items/stacks/nanopaste.dm @@ -27,10 +27,6 @@ var/mob/living/carbon/human/H = M var/obj/item/organ/external/S = H.get_organ(user.zone_sel.selecting) - if(can_operate(H)) - if (do_surgery(H,user,src)) - return - if (S && (S.status & ORGAN_ROBOT)) if(S.get_damage()) S.heal_damage(15, 15, robo_repair = 1) diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm index 4412bff1265..75432a86da2 100644 --- a/code/game/objects/items/stacks/rods.dm +++ b/code/game/objects/items/stacks/rods.dm @@ -36,17 +36,22 @@ return if(WT.remove_fuel(0,user)) - var/obj/item/stack/sheet/metal/new_item = new(usr.loc) - new_item.add_to_stacks(usr) + var/obj/item/stack/sheet/metal/new_item = new(user.loc) + new_item.add_to_stacks(user) + if(new_item.get_amount() <= 0) + // stack was moved into another one on the pile + new_item = locate() in user.loc + user.visible_message("[user.name] shaped [src] into metal with the weldingtool.", \ "You shaped [src] into metal with the weldingtool.", \ "You hear welding.") - var/obj/item/stack/rods/R = src - src = null - var/replace = (user.get_inactive_hand()==R) - R.use(2) - if (!R && replace) - user.put_in_hands(new_item) + + var/replace = user.get_inactive_hand() == src + use(2) + if (get_amount() <= 0 && replace) + user.unEquip(src, 1) + if(new_item) + user.put_in_hands(new_item) return ..() diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 11db68ec671..f90fe9cbb02 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -152,6 +152,7 @@ var/global/list/datum/stack_recipe/wood_recipes = list ( \ new/datum/stack_recipe("coffin", /obj/structure/closet/coffin, 5, time = 15, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("apiary", /obj/item/apiary, 10, time = 25, one_per_turf = 0, on_floor = 0), \ new/datum/stack_recipe("easel", /obj/structure/easel, 3, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("wooden picture frame", /obj/item/weapon/picture_frame/wooden, 1), \ new/datum/stack_recipe("wooden buckler", /obj/item/weapon/shield/riot/buckler, 20, time = 40), \ ) diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 6a3493fc0ea..64bc3e61181 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -49,15 +49,23 @@ /obj/item/toy/balloon/afterattack(atom/A as mob|obj, mob/user as mob, proximity) if(!proximity) return - if (istype(A, /obj/structure/reagent_dispensers/watertank) && get_dist(src,A) <= 1) + if (istype(A, /obj/structure/reagent_dispensers) && get_dist(src,A) <= 1) A.reagents.trans_to(src, 10) - user << "\blue You fill the balloon with the contents of [A]." - src.desc = "A translucent balloon with some form of liquid sloshing around in it." - src.update_icon() + user << "You fill the balloon with the contents of [A]." + desc = "A translucent balloon with some form of liquid sloshing around in it." + update_icon() + return + +/obj/item/toy/balloon/wash(mob/user, atom/source) + if(reagents.total_volume < 10) + reagents.add_reagent("water", min(10-reagents.total_volume, 10)) + user << "You fill the balloon from the [source]." + desc = "A translucent balloon with some form of liquid sloshing around in it." + update_icon() return /obj/item/toy/balloon/attackby(obj/O as obj, mob/user as mob, params) - if(istype(O, /obj/item/weapon/reagent_containers/glass)) + if(istype(O, /obj/item/weapon/reagent_containers/glass) || istype(O, /obj/item/weapon/reagent_containers/food/drinks/drinkingglass)) if(O.reagents) if(O.reagents.total_volume < 1) user << "The [O] is empty." @@ -67,19 +75,19 @@ O.reagents.reaction(user) qdel(src) else - src.desc = "A translucent balloon with some form of liquid sloshing around in it." - user << "\blue You fill the balloon with the contents of [O]." + desc = "A translucent balloon with some form of liquid sloshing around in it." + user << "You fill the balloon with the contents of [O]." O.reagents.trans_to(src, 10) - src.update_icon() + update_icon() return /obj/item/toy/balloon/throw_impact(atom/hit_atom) - if(src.reagents.total_volume >= 1) - src.visible_message("\red The [src] bursts!","You hear a pop and a splash.") - src.reagents.reaction(get_turf(hit_atom)) + if(reagents.total_volume >= 1) + visible_message("The [src] bursts!","You hear a pop and a splash.") + reagents.reaction(get_turf(hit_atom)) for(var/atom/A in get_turf(hit_atom)) - src.reagents.reaction(A) - src.icon_state = "burst" + reagents.reaction(A) + icon_state = "burst" spawn(5) if(src) qdel(src) @@ -141,89 +149,84 @@ attack_verb = list("attacked", "struck", "hit") var/bullets = 5 - examine(mob/user) - ..(user) - if (bullets) - user << "\blue It is loaded with [bullets] foam darts!" +/obj/item/toy/crossbow/examine(mob/user) + ..(user) + if (bullets) + user << "It is loaded with [bullets] foam darts!" - attackby(obj/item/I as obj, mob/user as mob, params) - if(istype(I, /obj/item/toy/ammo/crossbow)) - if(bullets <= 4) - user.drop_item() - qdel(I) - bullets++ - user << "\blue You load the foam dart into the crossbow." - else - usr << "\red It's already fully loaded." +/obj/item/toy/crossbow/attackby(obj/item/I as obj, mob/user as mob, params) + if(istype(I, /obj/item/toy/ammo/crossbow)) + if(bullets <= 4) + user.drop_item() + qdel(I) + bullets++ + user << "You load the foam dart into the crossbow." + else + usr << "It's already fully loaded." - afterattack(atom/target as mob|obj|turf|area, mob/user as mob, flag) - if(!isturf(target.loc) || target == user) return - if(flag) return +/obj/item/toy/crossbow/afterattack(atom/target as mob|obj|turf|area, mob/user as mob, flag) + if(!isturf(target.loc) || target == user) return + if(flag) return - if (locate (/obj/structure/table, src.loc)) - return - else if (bullets) - var/turf/trg = get_turf(target) - var/obj/effect/foam_dart_dummy/D = new/obj/effect/foam_dart_dummy(get_turf(src)) - bullets-- - D.icon_state = "foamdart" - D.name = "foam dart" - playsound(user.loc, 'sound/items/syringeproj.ogg', 50, 1) + if (locate (/obj/structure/table, src.loc)) + return + else if (bullets) + var/turf/trg = get_turf(target) + var/obj/effect/foam_dart_dummy/D = new/obj/effect/foam_dart_dummy(get_turf(src)) + bullets-- + D.icon_state = "foamdart" + D.name = "foam dart" + playsound(user.loc, 'sound/items/syringeproj.ogg', 50, 1) - for(var/i=0, i<6, i++) - if (D) - if(D.loc == trg) break - step_towards(D,trg) + for(var/i=0, i<6, i++) + if (D) + if(D.loc == trg) break + step_towards(D,trg) - for(var/mob/living/M in D.loc) - if(!istype(M,/mob/living)) continue - if(M == user) continue - D.visible_message("[M] was hit by the foam dart!") - new /obj/item/toy/ammo/crossbow(M.loc) - qdel(D) - return - - for(var/atom/A in D.loc) - if(A == user) continue - if(A.density) - new /obj/item/toy/ammo/crossbow(A.loc) - qdel(D) - - sleep(1) - - spawn(10) - if(D) - new /obj/item/toy/ammo/crossbow(D.loc) + for(var/mob/living/M in D.loc) + if(!istype(M,/mob/living)) continue + if(M == user) continue + D.visible_message("[M] was hit by the foam dart!") + new /obj/item/toy/ammo/crossbow(M.loc) qdel(D) + return - return - else if (bullets == 0) - user.Weaken(5) - user.visible_message("[] realized they were out of ammo and starting scrounging for some!") + for(var/atom/A in D.loc) + if(A == user) continue + if(A.density) + new /obj/item/toy/ammo/crossbow(A.loc) + qdel(D) + + sleep(1) + + spawn(10) + if(D) + new /obj/item/toy/ammo/crossbow(D.loc) + qdel(D) + + return + else if (bullets == 0) + user.Weaken(5) + user.visible_message("[user] realized they were out of ammo and starting scrounging for some!") - attack(mob/M as mob, mob/user as mob) - src.add_fingerprint(user) +/obj/item/toy/crossbow/attack(mob/M as mob, mob/user as mob) + add_fingerprint(user) // ******* Check - if (src.bullets > 0 && M.lying) - - for(var/mob/O in viewers(M, null)) - if(O.client) - O.show_message(text("[] casually lines up a shot with []'s head and pulls the trigger!", user, M), 1, "You hear the sound of foam against skull.", 2) - O.show_message(text("\red [] was hit in the head by the foam dart!", M), 1) - - playsound(user.loc, 'sound/items/syringeproj.ogg', 50, 1) - new /obj/item/toy/ammo/crossbow(M.loc) - src.bullets-- - else if (M.lying && src.bullets == 0) - for(var/mob/O in viewers(M, null)) - if (O.client) O.show_message(text("[] casually lines up a shot with []'s head, pulls the trigger, then realizes they are out of ammo and drops to the floor in search of some!", user, M), 1, "You hear someone fall.", 2) - user.Weaken(5) - return + if (bullets > 0 && M.lying) + visible_message("[user] casually lines up a shot with [M]'s head and pulls the trigger!", "You hear the sound of foam against skull.") + M.visible_message("[M] was hit in the head by the foam dart!") + playsound(user.loc, 'sound/items/syringeproj.ogg', 50, 1) + new /obj/item/toy/ammo/crossbow(M.loc) + bullets-- + else if (M.lying && bullets == 0) + visible_message("[user] casually lines up a shot with [M]'s head, pulls the trigger, then realizes they are out of ammo and drops to the floor in search of some!", "You hear someone fall.") + user.Weaken(5) + return /obj/item/toy/ammo/crossbow name = "foam dart" @@ -279,27 +282,27 @@ flags = NOSHIELD attack_verb = list("attacked", "struck", "hit") - attack_self(mob/user as mob) - src.active = !( src.active ) - if (src.active) - user << "\blue You extend the plastic blade with a quick flick of your wrist." - playsound(user, 'sound/weapons/saberon.ogg', 50, 1) - src.icon_state = "swordblue" - src.item_state = "swordblue" - src.w_class = 4 - else - user << "\blue You push the plastic blade back down into the handle." - playsound(user, 'sound/weapons/saberoff.ogg', 50, 1) - src.icon_state = "sword0" - src.item_state = "sword0" - src.w_class = 2 +/obj/item/toy/sword/attack_self(mob/user as mob) + active = !(active) + if (active) + user << "You extend the plastic blade with a quick flick of your wrist." + playsound(user, 'sound/weapons/saberon.ogg', 50, 1) + icon_state = "swordblue" + item_state = "swordblue" + w_class = 4 + else + user << "You push the plastic blade back down into the handle." + playsound(user, 'sound/weapons/saberoff.ogg', 50, 1) + icon_state = "sword0" + item_state = "sword0" + w_class = 2 - if(istype(user,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = user - H.update_inv_l_hand() - H.update_inv_r_hand() - src.add_fingerprint(user) - return + if(istype(user,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = user + H.update_inv_l_hand() + H.update_inv_r_hand() + add_fingerprint(user) + return // Copied from /obj/item/weapon/melee/energy/sword/attackby /obj/item/toy/sword/attackby(obj/item/weapon/W, mob/living/user, params) @@ -374,21 +377,15 @@ w_class = 1 - throw_impact(atom/hit_atom) - ..() - var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread - s.set_up(3, 1, src) - s.start() - new /obj/effect/decal/cleanable/ash(src.loc) - src.visible_message("\red The [src.name] explodes!","\red You hear a bang!") - - - playsound(src, 'sound/effects/snap.ogg', 50, 1) - qdel(src) - - - - +/obj/item/toy/snappop/virus/throw_impact(atom/hit_atom) + ..() + var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread + s.set_up(3, 1, src) + s.start() + new /obj/effect/decal/cleanable/ash(src.loc) + visible_message("The [name] explodes!","You hear a bang!") + playsound(src, 'sound/effects/snap.ogg', 50, 1) + qdel(src) /* * Snap pops @@ -400,27 +397,27 @@ icon_state = "snappop" w_class = 1 - throw_impact(atom/hit_atom) - ..() - var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread - s.set_up(3, 1, src) - s.start() - new /obj/effect/decal/cleanable/ash(src.loc) - src.visible_message("\red The [src.name] explodes!","\red You hear a snap!") - playsound(src, 'sound/effects/snap.ogg', 50, 1) - qdel(src) +/obj/item/toy/snappop/throw_impact(atom/hit_atom) + ..() + var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread + s.set_up(3, 1, src) + s.start() + new /obj/effect/decal/cleanable/ash(src.loc) + visible_message("The [src.name] explodes!","You hear a snap!") + playsound(src, 'sound/effects/snap.ogg', 50, 1) + qdel(src) /obj/item/toy/snappop/Crossed(H as mob|obj) if((ishuman(H))) //i guess carp and shit shouldn't set them off var/mob/living/carbon/M = H if(M.m_intent == "run") - M << "\red You step on the snap pop!" + M << "You step on the snap pop!" var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread s.set_up(2, 0, src) s.start() new /obj/effect/decal/cleanable/ash(src.loc) - src.visible_message("\red The [src.name] explodes!","\red You hear a snap!") + visible_message("The [name] explodes!","You hear a snap!") playsound(src, 'sound/effects/snap.ogg', 50, 1) qdel(src) @@ -450,13 +447,13 @@ return ..() -/obj/random/prize +/obj/random/mech name = "Random Mech Prize" desc = "This is a random prize" icon = 'icons/obj/toy.dmi' icon_state = "ripleytoy" -/obj/random/prize/item_to_spawn() +/obj/random/mech/item_to_spawn() return pick(subtypesof(/obj/item/toy/prize)) //exclude the base type. /obj/item/toy/prize/ripley @@ -591,7 +588,7 @@ obj/item/toy/cards/deck/New() obj/item/toy/cards/deck/attack_hand(mob/user as mob) var/choice = null if(cards.len == 0) - src.icon_state = "deck_[deckstyle]_empty" + icon_state = "deck_[deckstyle]_empty" user << "There are no more cards to draw." return var/obj/item/toy/cards/singlecard/H = new/obj/item/toy/cards/singlecard(user.loc) @@ -600,16 +597,16 @@ obj/item/toy/cards/deck/attack_hand(mob/user as mob) H.parentdeck = src var/O = src H.apply_card_vars(H,O) - src.cards -= choice + cards -= choice H.pickup(user) user.put_in_active_hand(H) - src.visible_message("[user] draws a card from the deck.", "You draw a card from the deck.") + visible_message("[user] draws a card from the deck.", "You draw a card from the deck.") if(cards.len > 26) - src.icon_state = "deck_[deckstyle]_full" + icon_state = "deck_[deckstyle]_full" else if(cards.len > 10) - src.icon_state = "deck_[deckstyle]_half" + icon_state = "deck_[deckstyle]_half" else if(cards.len > 1) - src.icon_state = "deck_[deckstyle]_low" + icon_state = "deck_[deckstyle]_low" obj/item/toy/cards/deck/attack_self(mob/user as mob) if(cooldown < world.time - 50) @@ -625,17 +622,17 @@ obj/item/toy/cards/deck/attackby(obj/item/toy/cards/singlecard/C, mob/living/use if(!user.unEquip(C)) user << "The card is stuck to your hand, you can't add it to the deck!" return - src.cards += C.cardname + cards += C.cardname user.visible_message("[user] adds a card to the bottom of the deck.","You add the card to the bottom of the deck.") qdel(C) else user << "You can't mix cards from other decks." if(cards.len > 26) - src.icon_state = "deck_[deckstyle]_full" + icon_state = "deck_[deckstyle]_full" else if(cards.len > 10) - src.icon_state = "deck_[deckstyle]_half" + icon_state = "deck_[deckstyle]_half" else if(cards.len > 1) - src.icon_state = "deck_[deckstyle]_low" + icon_state = "deck_[deckstyle]_low" obj/item/toy/cards/deck/attackby(obj/item/toy/cards/cardhand/C, mob/living/user, params) @@ -645,17 +642,17 @@ obj/item/toy/cards/deck/attackby(obj/item/toy/cards/cardhand/C, mob/living/user, if(!user.unEquip(C)) user << "The hand of cards is stuck to your hand, you can't add it to the deck!" return - src.cards += C.currenthand + cards += C.currenthand user.visible_message("[user] puts their hand of cards in the deck.", "You put the hand of cards in the deck.") qdel(C) else user << "You can't mix cards from other decks." if(cards.len > 26) - src.icon_state = "deck_[deckstyle]_full" + icon_state = "deck_[deckstyle]_full" else if(cards.len > 10) - src.icon_state = "deck_[deckstyle]_half" + icon_state = "deck_[deckstyle]_half" else if(cards.len > 1) - src.icon_state = "deck_[deckstyle]_low" + icon_state = "deck_[deckstyle]_low" obj/item/toy/cards/deck/MouseDrop(atom/over_object) var/mob/M = usr @@ -718,7 +715,7 @@ obj/item/toy/cards/cardhand/Topic(href, href_list) if (cardUser.get_item_by_slot(slot_l_hand) == src || cardUser.get_item_by_slot(slot_r_hand) == src) var/choice = href_list["pick"] var/obj/item/toy/cards/singlecard/C = new/obj/item/toy/cards/singlecard(cardUser.loc) - src.currenthand -= choice + currenthand -= choice C.parentdeck = src.parentdeck C.cardname = choice C.apply_card_vars(C,O) @@ -727,13 +724,13 @@ obj/item/toy/cards/cardhand/Topic(href, href_list) cardUser.visible_message("[cardUser] draws a card from \his hand.", "You take the [C.cardname] from your hand.") interact(cardUser) - if(src.currenthand.len < 3) - src.icon_state = "[deckstyle]_hand2" + if(currenthand.len < 3) + icon_state = "[deckstyle]_hand2" else if(src.currenthand.len < 4) - src.icon_state = "[deckstyle]_hand3" + icon_state = "[deckstyle]_hand3" else if(src.currenthand.len < 5) - src.icon_state = "[deckstyle]_hand4" - if(src.currenthand.len == 1) + icon_state = "[deckstyle]_hand4" + if(currenthand.len == 1) var/obj/item/toy/cards/singlecard/N = new/obj/item/toy/cards/singlecard(src.loc) N.parentdeck = src.parentdeck N.cardname = src.currenthand[1] @@ -748,17 +745,17 @@ obj/item/toy/cards/cardhand/Topic(href, href_list) obj/item/toy/cards/cardhand/attackby(obj/item/toy/cards/singlecard/C, mob/living/user, params) if(istype(C)) - if(C.parentdeck == src.parentdeck) - src.currenthand += C.cardname + if(C.parentdeck == parentdeck) + currenthand += C.cardname user.unEquip(C) user.visible_message("[user] adds a card to their hand.", "You add the [C.cardname] to your hand.") interact(user) if(currenthand.len > 4) - src.icon_state = "[deckstyle]_hand5" + icon_state = "[deckstyle]_hand5" else if(currenthand.len > 3) - src.icon_state = "[deckstyle]_hand4" + icon_state = "[deckstyle]_hand4" else if(currenthand.len > 2) - src.icon_state = "[deckstyle]_hand3" + icon_state = "[deckstyle]_hand3" qdel(C) else user << "You can't mix cards from other decks." @@ -803,33 +800,33 @@ obj/item/toy/cards/singlecard/verb/Flip() if(usr.stat || !ishuman(usr) || !usr.canmove || usr.restrained()) return if(!flipped) - src.flipped = 1 + flipped = 1 if (cardname) - src.icon_state = "sc_[cardname]_[deckstyle]" - src.name = src.cardname + icon_state = "sc_[cardname]_[deckstyle]" + name = cardname else - src.icon_state = "sc_Ace of Spades_[deckstyle]" - src.name = "What Card" - src.pixel_x = 5 + icon_state = "sc_Ace of Spades_[deckstyle]" + name = "What Card" + pixel_x = 5 else if(flipped) - src.flipped = 0 - src.icon_state = "singlecard_down_[deckstyle]" - src.name = "card" - src.pixel_x = -5 + flipped = 0 + icon_state = "singlecard_down_[deckstyle]" + name = "card" + pixel_x = -5 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 == src.parentdeck) + if(C.parentdeck == parentdeck) var/obj/item/toy/cards/cardhand/H = new/obj/item/toy/cards/cardhand(user.loc) H.currenthand += C.cardname - H.currenthand += src.cardname + H.currenthand += cardname H.parentdeck = C.parentdeck H.apply_card_vars(H,C) user.unEquip(C) H.pickup(user) user.put_in_active_hand(H) - user << "You combine the [C.cardname] and the [src.cardname] into a hand." + user << "You combine the [C.cardname] and the [cardname] into a hand." qdel(C) qdel(src) else @@ -923,54 +920,58 @@ obj/item/toy/cards/deck/syndicate/black var/timeleft = (cooldown - world.time) user << "Nothing happens, and '[round(timeleft/10)]' appears on a small display." - -/obj/item/toy/therapy_red - name = "red therapy doll" - desc = "A toy for therapeutic and recreational purposes. This one is red." - icon = 'icons/obj/weapons.dmi' +/obj/item/toy/therapy + name = "therapy doll" + desc = "A toy for therapeutic and recreational purposes." icon_state = "therapyred" + item_state = "egg4" + w_class = 1 + var/cooldown = 0 + +/obj/item/toy/therapy/New() + if(item_color) + name = "[item_color] therapy doll" + desc += " This one is [item_color]." + icon_state = "therapy[item_color]" + +/obj/item/toy/therapy/attack_self(mob/user) + if(cooldown < world.time - 8) + user << "You relieve some stress with \the [src]." + playsound(user, 'sound/items/squeaktoy.ogg', 20, 1) + cooldown = world.time + +/obj/random/therapy + name = "Random Therapy Doll" + desc = "This is a random therapy doll." + icon = 'icons/obj/toy.dmi' + icon_state = "therapyred" + +/obj/random/prize/item_to_spawn() + return pick(subtypesof(/obj/item/toy/therapy)) //exclude the base type. + +/obj/item/toy/therapy/red item_state = "egg4" // It's the red egg in items_left/righthand - w_class = 1 + item_color = "red" -/obj/item/toy/therapy_purple - name = "purple therapy doll" - desc = "A toy for therapeutic and recreational purposes. This one is purple." - icon = 'icons/obj/weapons.dmi' - icon_state = "therapypurple" +/obj/item/toy/therapy/purple item_state = "egg1" // It's the magenta egg in items_left/righthand - w_class = 1 + item_color = "purple" -/obj/item/toy/therapy_blue - name = "blue therapy doll" - desc = "A toy for therapeutic and recreational purposes. This one is blue." - icon = 'icons/obj/weapons.dmi' - icon_state = "therapyblue" +/obj/item/toy/therapy/blue item_state = "egg2" // It's the blue egg in items_left/righthand - w_class = 1 + item_color = "blue" -/obj/item/toy/therapy_yellow - name = "yellow therapy doll" - desc = "A toy for therapeutic and recreational purposes. This one is yellow." - icon = 'icons/obj/weapons.dmi' - icon_state = "therapyyellow" +/obj/item/toy/therapy/yellow item_state = "egg5" // It's the yellow egg in items_left/righthand - w_class = 1 + item_color = "yellow" -/obj/item/toy/therapy_orange - name = "orange therapy doll" - desc = "A toy for therapeutic and recreational purposes. This one is orange." - icon = 'icons/obj/weapons.dmi' - icon_state = "therapyorange" +/obj/item/toy/therapy/orange item_state = "egg4" // It's the red one again, lacking an orange item_state and making a new one is pointless - w_class = 1 + item_color = "orange" -/obj/item/toy/therapy_green - name = "green therapy doll" - desc = "A toy for therapeutic and recreational purposes. This one is green." - icon = 'icons/obj/weapons.dmi' - icon_state = "therapygreen" +/obj/item/toy/therapy/green item_state = "egg3" // It's the green egg in items_left/righthand - w_class = 1 + item_color = "green" /obj/item/weapon/toddler icon_state = "toddler" @@ -1264,7 +1265,7 @@ obj/item/toy/cards/deck/syndicate/black var/message = generate_ion_law() user << "You press the button on [src]." playsound(user, 'sound/machines/click.ogg', 20, 1) - src.loc.visible_message("\icon[src] [message]") + visible_message("\icon[src] [message]") cooldown = 1 spawn(30) cooldown = 0 return @@ -1283,7 +1284,7 @@ obj/item/toy/cards/deck/syndicate/black var/message = pick("You won't get away this time, Griffin!", "Stop right there, criminal!", "Hoot! Hoot!", "I am the night!") user << "You pull the string on the [src]." playsound(user, 'sound/misc/hoot.ogg', 25, 1) - src.loc.visible_message("\icon[src] [message]") + visible_message("\icon[src] [message]") cooldown = 1 spawn(30) cooldown = 0 return @@ -1302,7 +1303,7 @@ obj/item/toy/cards/deck/syndicate/black var/message = pick("You can't stop me, Owl!", "My plan is flawless! The vault is mine!", "Caaaawwww!", "You will never catch me!") user << "You pull the string on the [src]." playsound(user, 'sound/misc/caw.ogg', 25, 1) - src.loc.visible_message("\icon[src] [message]") + visible_message("\icon[src] [message]") cooldown = 1 spawn(30) cooldown = 0 return @@ -1368,6 +1369,7 @@ obj/item/toy/cards/deck/syndicate/black force = 5 throwforce = 5 attack_verb = list("attacked", "bashed", "smashed", "stoned") + hitsound = "swing_hit" /obj/item/toy/pet_rock/fred name = "fred" @@ -1534,13 +1536,6 @@ obj/item/toy/cards/deck/syndicate/black else icon_state = "chainsaw0" -/obj/item/weapon/twohanded/toy/chainsaw/attack(mob/target as mob, mob/living/user as mob) - if(wielded) - playsound(loc, 'sound/weapons/chainsaw.ogg', 100, 1, -1) - else - playsound(loc, "swing_hit", 50, 1, -1) - ..() - /* * Action Figures */ diff --git a/code/game/objects/items/weapons/AI_modules.dm b/code/game/objects/items/weapons/AI_modules.dm index 0fc641d8039..66187de8e3a 100755 --- a/code/game/objects/items/weapons/AI_modules.dm +++ b/code/game/objects/items/weapons/AI_modules.dm @@ -150,7 +150,7 @@ AI MODULES /******************** ProtectStation ********************/ /obj/item/weapon/aiModule/protectStation name = "\improper 'ProtectStation' AI module" - desc = "A 'protect station' AI module: 'Protect the space station against damage. Anyone you see harming the station is to be no longer considered human, and is a threat to the station which must be neutralized.'" + desc = "A 'protect station' AI module: 'Protect the space station against damage. Anyone you see harming the station is to be no longer considered crew, and is a threat to the station which must be neutralized.'" origin_tech = "programming=3;materials=4" //made of gold /obj/item/weapon/aiModule/protectStation/attack_self(var/mob/user as mob) @@ -158,7 +158,7 @@ AI MODULES /obj/item/weapon/aiModule/protectStation/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender) ..() - var/law = "Protect the space station against damage. Anyone you see harming the station is to be no longer considered human, and is a threat to the station which must be neutralized." + var/law = "Protect the space station against damage. Anyone you see harming the station is to be no longer considered crew, and is a threat to the station which must be neutralized." target << law target.add_supplied_law(5, law) diff --git a/code/game/objects/items/weapons/cigs.dm b/code/game/objects/items/weapons/cigs.dm index 940634e6b0b..e1c441eea90 100644 --- a/code/game/objects/items/weapons/cigs.dm +++ b/code/game/objects/items/weapons/cigs.dm @@ -30,12 +30,13 @@ LIGHTERS ARE IN LIGHTERS.DM var/lastHolder = null var/smoketime = 300 var/chem_volume = 30 - species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin") + species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin", "Grey") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/mask.dmi', "Unathi" = 'icons/mob/species/unathi/mask.dmi', "Tajaran" = 'icons/mob/species/tajaran/mask.dmi', - "Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi' + "Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi', + "Grey" = 'icons/mob/species/grey/mask.dmi' ) @@ -48,6 +49,16 @@ LIGHTERS ARE IN LIGHTERS.DM qdel(reagents) return ..() +/obj/item/clothing/mask/cigarette/attack(var/mob/living/M, var/mob/living/user, def_zone) + if(istype(M) && M.on_fire) + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(M) + light("[user] coldly lights the [name] with the burning body of [M]. Clearly, they offer the warmest of regards...") + return 1 + else + return ..() + + /obj/item/clothing/mask/cigarette/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() if(istype(W, /obj/item/weapon/weldingtool)) diff --git a/code/game/objects/items/weapons/clown_items.dm b/code/game/objects/items/weapons/clown_items.dm index d58fe73b587..a655efa125c 100644 --- a/code/game/objects/items/weapons/clown_items.dm +++ b/code/game/objects/items/weapons/clown_items.dm @@ -22,36 +22,16 @@ /obj/item/weapon/bananapeel/Crossed(AM as mob|obj) if (istype(AM, /mob/living/carbon)) - var/mob/M = AM - if (istype(M, /mob/living/carbon/human) && (isobj(M:shoes) && M:shoes.flags&NOSLIP) || M.buckled) - return - if(istype(M, /mob/living/carbon/human) && M:species.bodyflags & FEET_NOSLIP) - return - if(M.flying) - return - - M.stop_pulling() - M << "\blue You slipped on the [name]!" - playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3) - M.Stun(4) - M.Weaken(2) + var/mob/living/carbon/M = AM + M.slip("banana peel", 4, 2) /* * Soap */ /obj/item/weapon/soap/Crossed(AM as mob|obj) //EXACTLY the same as bananapeel for now, so it makes sense to put it in the same dm -- Urist if (istype(AM, /mob/living/carbon)) - var/mob/M = AM - if (istype(M, /mob/living/carbon/human) && (isobj(M:shoes) && M:shoes.flags&NOSLIP) || M.buckled) - return - if(M.flying) - return - - M.stop_pulling() - M << "\blue You slipped on the [name]!" - playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3) - M.Stun(4) - M.Weaken(2) + var/mob/living/carbon/M = AM + M.slip("soap", 4, 2) /obj/item/weapon/soap/afterattack(atom/target, mob/user as mob, proximity) if(!proximity) return diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index 0cef06f2fa2..80658c6bf51 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -12,6 +12,10 @@ w_class = 4 origin_tech = "biotech=4" action_button_name = "Toggle Paddles" + species_fit = list("Vox") + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/back.dmi' + ) var/on = 0 //if the paddles are equipped (1) or on the defib (0) var/safety = 1 //if you can zap people with the defibs on harm mode @@ -342,6 +346,13 @@ user.visible_message("[user] places [src] on [M.name]'s chest.", "You place [src] on [M.name]'s chest.") playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0) var/mob/dead/observer/ghost = H.get_ghost() + if(ghost && !ghost.client) + // In case the ghost's not getting deleted for some reason + H.key = ghost.key + log_to_dd("Ghost of name [ghost.name] is bound to [H.real_name], but lacks a client. Deleting ghost.") + + qdel(ghost) + ghost = null var/tplus = world.time - H.timeofdeath var/tlimit = 6000 //past this much time the patient is unrecoverable (in deciseconds) var/tloss = 3000 //brain damage starts setting in on the patient after some time left rotting @@ -383,15 +394,16 @@ defib.deductcharge(revivecost) add_logs(M, user, "revived", object="defibrillator") else - if(tplus > tlimit) + if(tplus > tlimit|| !H.get_int_organ(/obj/item/organ/internal/heart)) user.visible_message("[defib] buzzes: Resuscitation failed - Heart tissue damage beyond point of no return for defibrillation.") else if(total_burn >= 180 || total_brute >= 180) user.visible_message("[defib] buzzes: Resuscitation failed - Severe tissue damage detected.") + else if(ghost) + user.visible_message("[defib] buzzes: Resuscitation failed: Patient's brain is unresponsive. Further attempts may succeed.") + ghost << "Your heart is being defibrillated. Return to your body if you want to be revived! (Verbs -> Ghost -> Re-enter corpse)" + ghost << sound('sound/effects/genetics.ogg') else user.visible_message("[defib] buzzes: Resuscitation failed.") - if(ghost) - ghost << "Your heart is being defibrillated. Return to your body if you want to be revived! (Verbs -> Ghost -> Re-enter corpse)" - ghost << sound('sound/effects/genetics.ogg') playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) defib.deductcharge(revivecost) update_icon() @@ -461,6 +473,13 @@ user.visible_message("[user] places [src] on [M.name]'s chest.", "You place [src] on [M.name]'s chest.") playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0) var/mob/dead/observer/ghost = H.get_ghost() + if(ghost && !ghost.client) + // In case the ghost's not getting deleted for some reason + H.key = ghost.key + log_to_dd("Ghost of name [ghost.name] is bound to [H.real_name], but lacks a client. Deleting ghost.") + + qdel(ghost) + ghost = null var/tplus = world.time - H.timeofdeath var/tlimit = 6000 //past this much time the patient is unrecoverable (in deciseconds) var/tloss = 3000 //brain damage starts setting in on the patient after some time left rotting @@ -484,7 +503,7 @@ H.adjustBruteLoss(tobehealed) user.visible_message("[user] pings: Resuscitation successful.") playsound(get_turf(src), 'sound/machines/defib_success.ogg', 50, 0) - H.stat = 1 + H.stat = UNCONSCIOUS H.update_revive() H.emote("gasp") if(tplus > tloss) @@ -498,11 +517,12 @@ user.visible_message("[user] buzzes: Resuscitation failed - Heart tissue damage beyond point of no return for defibrillation.") else if(total_burn >= 180 || total_brute >= 180) user.visible_message("[user] buzzes: Resuscitation failed - Severe tissue damage detected.") + else if(ghost) + user.visible_message("[user] buzzes: Resuscitation failed: Patient's brain is unresponsive. Further attempts may succeed.") + ghost << "Your heart is being defibrillated. Return to your body if you want to be revived! (Verbs -> Ghost -> Re-enter corpse)" + ghost << sound('sound/effects/genetics.ogg') else user.visible_message("[user] buzzes: Resuscitation failed.") - if(ghost) - ghost << "Your heart is being defibrillated. Return to your body if you want to be revived! (Verbs -> Ghost -> Re-enter corpse)" - ghost << sound('sound/effects/genetics.ogg') playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) if(isrobot(user)) var/mob/living/silicon/robot/R = user diff --git a/code/game/objects/items/weapons/dnascrambler.dm b/code/game/objects/items/weapons/dnascrambler.dm index b0e5b0149d9..e654e4ff941 100644 --- a/code/game/objects/items/weapons/dnascrambler.dm +++ b/code/game/objects/items/weapons/dnascrambler.dm @@ -34,10 +34,15 @@ user << "\red You failed to inject [M.name]." proc/injected(var/mob/living/carbon/target, var/mob/living/carbon/user) - target.generate_name() - target.real_name = target.name - scramble(1, target, 100) + target.generate_name() + if(istype(target, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = target + H.sync_organ_dna(1) + H.update_body(0) + H.reset_hair() // No more winding up with hairstyles you're not supposed to have, and blowing your cover + H.dna.ResetUIFrom(H) + target.update_icons() log_attack("[key_name(user)] injected [key_name(target)] with the [name]") log_game("[key_name_admin(user)] injected [key_name_admin(target)] with the [name]") diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm index a24733a3e83..8ca714d7666 100644 --- a/code/game/objects/items/weapons/gift_wrappaper.dm +++ b/code/game/objects/items/weapons/gift_wrappaper.dm @@ -83,7 +83,7 @@ /obj/item/toy/crossbow, /obj/item/weapon/gun/projectile/revolver/capgun, /obj/item/toy/katana, - /obj/random/prize, + /obj/random/mech, /obj/item/toy/spinningtoy, /obj/item/toy/sword, /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus, diff --git a/code/game/objects/items/weapons/grenades/clowngrenade.dm b/code/game/objects/items/weapons/grenades/clowngrenade.dm index 3066c762cd3..8525a27378c 100644 --- a/code/game/objects/items/weapons/grenades/clowngrenade.dm +++ b/code/game/objects/items/weapons/grenades/clowngrenade.dm @@ -62,8 +62,8 @@ Crossed(AM as mob|obj) var/burned = rand(2,5) - if(istype(AM, /mob/living)) - var/mob/living/M = AM + if(istype(AM, /mob/living/carbon)) + var/mob/living/carbon/M = AM if(ishuman(M)) if(isobj(M:shoes)) if((M:shoes.flags&NOSLIP) || (M:species.bodyflags & FEET_NOSLIP)) @@ -73,16 +73,8 @@ M.take_overall_damage(0, max(0, (burned - 2))) if(!istype(M, /mob/living/carbon/slime) && !isrobot(M)) - M.stop_pulling() - step(M, M.dir) - spawn(1) step(M, M.dir) - spawn(2) step(M, M.dir) - spawn(3) step(M, M.dir) - spawn(4) step(M, M.dir) + M.slip("banana peel!", 0, 7, 4) M.take_organ_damage(2) // Was 5 -- TLE - M << "\blue You slipped on \the [name]!" - playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3) - M.Weaken(7) M.take_overall_damage(0, burned) throw_impact(atom/hit_atom) diff --git a/code/game/objects/items/weapons/grenades/flashbang.dm b/code/game/objects/items/weapons/grenades/flashbang.dm index 260160a63c3..51bd36c5839 100644 --- a/code/game/objects/items/weapons/grenades/flashbang.dm +++ b/code/game/objects/items/weapons/grenades/flashbang.dm @@ -46,7 +46,7 @@ if(!eye_safety && ishuman(M)) var/mob/living/carbon/human/H = M - var/obj/item/organ/eyes/E = H.internal_organs_by_name["eyes"] + var/obj/item/organ/internal/eyes/E = H.get_int_organ(/obj/item/organ/internal/eyes) flick("e_flash", M.flash) if (E) E.damage += eye_damage diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm index 6c057f3cda8..5f93c6a095c 100644 --- a/code/game/objects/items/weapons/handcuffs.dm +++ b/code/game/objects/items/weapons/handcuffs.dm @@ -155,6 +155,13 @@ icon_state = "beartrap0" desc = "A trap used to catch bears and other legged creatures." var/armed = 0 + var/obj/item/weapon/grenade/iedcasing/IED = null + +/obj/item/weapon/restraints/legcuffs/beartrap/Destroy() + if(IED) + qdel(IED) + IED = null + return ..() /obj/item/weapon/restraints/legcuffs/beartrap/suicide_act(mob/user) user.visible_message("[user] is sticking \his head in the [src.name]! It looks like \he's trying to commit suicide.") @@ -168,6 +175,36 @@ icon_state = "beartrap[armed]" user << "[src] is now [armed ? "armed" : "disarmed"]" +/obj/item/weapon/restraints/legcuffs/beartrap/attackby(var/obj/item/I, mob/user as mob) //Let's get explosive. + if(istype(I, /obj/item/weapon/grenade/iedcasing)) + if(IED) + user << "This beartrap already has an IED hooked up to it!" + return + IED = I + switch(IED.assembled) + if(0,1) //if it's not fueled/hooked up + user << "You haven't prepared this IED yet!" + IED = null + return + if(2,3) + user.drop_item(src) + I.forceMove(src) + message_admins("[key_name_admin(user)] has rigged a beartrap with an IED.") + log_game("[key_name(user)] has rigged a beartrap with an IED.") + user << "You sneak the [IED] underneath the pressure plate and connect the trigger wire." + desc = "A trap used to catch bears and other legged creatures. There is an IED hooked up to it." + else + user << "You shouldn't be reading this message! Contact a coder or someone, something broke!" + IED = null + return + if(istype(I, /obj/item/weapon/screwdriver)) + if(IED) + IED.forceMove(get_turf(src)) + IED = null + user << "You remove the IED from the [src]." + return + ..() + /obj/item/weapon/restraints/legcuffs/beartrap/Crossed(AM as mob|obj) if(armed && isturf(src.loc)) if( (iscarbon(AM) || isanimal(AM)) && !istype(AM, /mob/living/simple_animal/parrot) && !istype(AM, /mob/living/simple_animal/construct) && !istype(AM, /mob/living/simple_animal/shade) && !istype(AM, /mob/living/simple_animal/hostile/viscerator)) @@ -178,6 +215,16 @@ L.visible_message("[L] triggers \the [src].", \ "You trigger \the [src]!") + if(IED && isturf(src.loc)) + IED.active = 1 + IED.overlays -= image('icons/obj/grenade.dmi', icon_state = "improvised_grenade_filled") + IED.icon_state = initial(icon_state) + "_active" + IED.assembled = 3 + message_admins("[key_name_admin(usr)] has triggered an IED-rigged [name].") + log_game("[key_name(usr)] has triggered an IED-rigged [name].") + spawn(IED.det_time) + IED.prime() + if(ishuman(AM)) var/mob/living/carbon/H = AM if(H.lying) diff --git a/code/game/objects/items/weapons/kitchen.dm b/code/game/objects/items/weapons/kitchen.dm index 83e488c5959..e50ea239b44 100644 --- a/code/game/objects/items/weapons/kitchen.dm +++ b/code/game/objects/items/weapons/kitchen.dm @@ -50,6 +50,11 @@ return ..() if (reagents.total_volume > 0) + // Mouthless people cannot eat + if(!M.can_eat()) + user << "[M] cannot eat with a fork!" + return + if(M == user) M.visible_message("\The [user] eats some [loaded] from \the [src].") reagents.trans_to(M, reagents.total_volume) @@ -64,9 +69,6 @@ overlays.Cut() return - if (can_operate(M)) - do_surgery(M, user, src) - /obj/item/weapon/kitchen/utensil/fork name = "fork" desc = "It's a fork. Sure is pointy." diff --git a/code/game/objects/items/weapons/legcuffs.dm b/code/game/objects/items/weapons/legcuffs.dm index 240decbfdcb..16fc9f046bd 100644 --- a/code/game/objects/items/weapons/legcuffs.dm +++ b/code/game/objects/items/weapons/legcuffs.dm @@ -10,101 +10,6 @@ origin_tech = "materials=1" var/breakouttime = 300 //Deciseconds = 30s = 0.5 minute -/obj/item/weapon/legcuffs/beartrap - name = "bear trap" - throw_speed = 1 - throw_range = 1 - icon_state = "beartrap0" - desc = "A trap used to catch bears and other legged creatures." - var/armed = 0 - var/obj/item/weapon/grenade/iedcasing/IED = null - - suicide_act(mob/user) - viewers(user) << "[user] is putting the [src.name] on \his head! It looks like \he's trying to commit suicide." - return (BRUTELOSS) - -/obj/item/weapon/legcuffs/beartrap/attack_self(mob/user as mob) - ..() - if(ishuman(user) && !user.stat && !user.restrained()) - armed = !armed - icon_state = "beartrap[armed]" - user << "[src] is now [armed ? "armed" : "disarmed"]" - -/obj/item/weapon/legcuffs/beartrap/attackby(var/obj/item/I, mob/user as mob) //Let's get explosive. - if(istype(I, /obj/item/weapon/grenade/iedcasing)) - if(IED) - user << "This beartrap already has an IED hooked up to it!" - return - IED = I - switch(IED.assembled) - if(0,1) //if it's not fueled/hooked up - user << "You haven't prepared this IED yet!" - IED = null - return - if(2,3) - user.drop_item(src) - I.loc = src - message_admins("[key_name_admin(user)] has rigged a beartrap with an IED.") - log_game("[key_name(user)] has rigged a beartrap with an IED.") - user << "You sneak the [IED] underneath the pressure plate and connect the trigger wire." - desc = "A trap used to catch bears and other legged creatures. There is an IED hooked up to it." - else - user << "You shouldn't be reading this message! Contact a coder or someone, something broke!" - IED = null - return - if(istype(I, /obj/item/weapon/screwdriver)) - if(IED) - IED.loc = get_turf(src.loc) - IED = null - user << "You remove the IED from the [src]." - return - ..() - -/obj/item/weapon/legcuffs/beartrap/Crossed(AM as mob|obj) - if(armed) - if(IED && isturf(src.loc)) - IED.active = 1 - IED.overlays -= image('icons/obj/grenade.dmi', icon_state = "improvised_grenade_filled") - IED.icon_state = initial(icon_state) + "_active" - IED.assembled = 3 - message_admins("[key_name_admin(usr)] has triggered an IED-rigged [name].") - log_game("[key_name(usr)] has triggered an IED-rigged [name].") - spawn(IED.det_time) - IED.prime() - if(ishuman(AM)) - if(isturf(src.loc)) - var/mob/living/carbon/H = AM - if(H.m_intent == "run") - if(H.lying) - H.apply_damage(20,BRUTE,"chest") - else - H.apply_damage(20,BRUTE,(pick("l_leg", "r_leg"))) - armed = 0 - icon_state = "beartrap0" - playsound(src.loc, 'sound/effects/snap.ogg', 50, 1) - H.visible_message("[H] triggers \the [src].", \ - "You trigger \the [src]!") - H.legcuffed = src - src.loc = H - H.update_inv_legcuffed() - H << "You step on \the [src]!" - if(IED && IED.active) - H << "\The [src]'s IED has been activated!" - feedback_add_details("handcuffs","B") //Yes, I know they're legcuffs. Don't change this, no need for an extra variable. The "B" is used to tell them apart. - for(var/mob/O in viewers(H, null)) - if(O == H) - continue - O.show_message("\red [H] steps on \the [src].", 1) - if(isanimal(AM) && !istype(AM, /mob/living/simple_animal/parrot) && !istype(AM, /mob/living/simple_animal/construct) && !istype(AM, /mob/living/simple_animal/shade) && !istype(AM, /mob/living/simple_animal/hostile/viscerator)) - armed = 0 - icon_state = "beartrap0" - var/mob/living/simple_animal/SA = AM - playsound(src.loc, 'sound/effects/snap.ogg', 50, 1) - SA.visible_message("[SA] triggers \the [src].", \ - "You trigger \the [src]!") - SA.health -= 20 - ..() - /obj/item/weapon/legcuffs/bolas name = "bolas" desc = "An entangling bolas. Throw at your foes to trip them and prevent them from running." @@ -167,26 +72,19 @@ var/mob/living/M = hit_atom if(ishuman(M)) //if they're a human species var/mob/living/carbon/human/H = M - if(H.m_intent == "run") //if they're set to run (though not necessarily running at that moment) - if(prob(trip_prob)) //this probability is up for change and mostly a placeholder - Comic - step(H, H.dir) - H.visible_message("[H] was tripped by the bolas!","Your legs have been tangled!"); - H.Stun(2) //used instead of setting damage in vars to avoid non-human targets being affected - H.Weaken(4) - H.legcuffed = src //applies legcuff properties inherited through legcuffs - src.loc = H - H.update_inv_legcuffed() - if(!H.legcuffed) //in case it didn't happen, we need a safety net - throw_failed() - else if(H.legcuffed) //if the target is already legcuffed (has to be walking) + if(H.legcuffed) //if the target is already legcuffed (has to be walking) throw_failed() return - else //walking, but uncuffed, or the running prob() failed - H << "You stumble over the thrown bolas" + if(prob(trip_prob)) //this probability is up for change and mostly a placeholder - Comic step(H, H.dir) - H.Stun(1) - throw_failed() - return + H.visible_message("[H] was tripped by the bolas!","Your legs have been tangled!"); + H.Stun(2) //used instead of setting damage in vars to avoid non-human targets being affected + H.Weaken(4) + H.legcuffed = src //applies legcuff properties inherited through legcuffs + src.loc = H + H.update_inv_legcuffed() + if(!H.legcuffed) //in case it didn't happen, we need a safety net + throw_failed() else M.Stun(2) //minor stun damage to anything not human throw_failed() diff --git a/code/game/objects/items/weapons/melee/misc.dm b/code/game/objects/items/weapons/melee/misc.dm index 1edaeb26eb7..7e95235ff4a 100644 --- a/code/game/objects/items/weapons/melee/misc.dm +++ b/code/game/objects/items/weapons/melee/misc.dm @@ -1,3 +1,6 @@ +/obj/item/weapon/melee + needs_permit = 1 + /obj/item/weapon/melee/chainofcommand name = "chain of command" desc = "A tool used by great men to placate the frothing masses." diff --git a/code/game/objects/items/weapons/mop.dm b/code/game/objects/items/weapons/mop.dm index 05a367fc075..521c75f63fd 100644 --- a/code/game/objects/items/weapons/mop.dm +++ b/code/game/objects/items/weapons/mop.dm @@ -65,6 +65,12 @@ J.mymop=src J.update_icon() +/obj/item/weapon/mop/wash(mob/user, atom/source) + reagents.add_reagent("water", 5) + user << "You wet [src] in [source]." + playsound(loc, 'sound/effects/slosh.ogg', 25, 1) + return 1 + /obj/item/weapon/mop/advanced desc = "The most advanced tool in a custodian's arsenal. Just think of all the viscera you will clean up with this!" name = "advanced mop" diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index 8a0480dce88..f2e7d666c91 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -15,6 +15,10 @@ max_w_class = 3 max_combined_w_class = 21 storage_slots = 21 + species_fit = list("Vox") + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/back.dmi' + ) /obj/item/weapon/storage/backpack/attackby(obj/item/weapon/W as obj, mob/user as mob, params) playsound(src.loc, "rustle", 50, 1, -5) @@ -43,10 +47,10 @@ else if(istype(W, /obj/item/weapon/storage/backpack/holding) && !W.crit_fail) var/response = alert(user, "Are you sure you want to put the bag of holding inside another bag of holding?","Are you sure you want to die?","Yes","No") if(response == "Yes") - user.visible_message("[user] grins as he begins to put a Bag of Holding into a Bag of Holding!", "You begin to put the Bag of Holding into the Bag of Holding!") + user.visible_message("[user] grins as \he begins to put a Bag of Holding into a Bag of Holding!", "You begin to put the Bag of Holding into the Bag of Holding!") if(do_after(user,30,target=src)) investigate_log("has become a singularity. Caused by [user.key]","singulo") - user.visible_message("[user] erupts in evil laughter as he puts the Bag of Holding into another Bag of Holding!", "You can't help yourself from laughing as you put the Bag of Holding into another Bag of Holding, complete darkness surrounding you"," You hear the sound of scientific evil brewing! ") + user.visible_message("[user] erupts in evil laughter as \he puts the Bag of Holding into another Bag of Holding!", "You can't help but laugh wildly as you put the Bag of Holding into another Bag of Holding, complete darkness surrounding you."," You hear the sound of scientific evil brewing! ") qdel(W) var/obj/singularity/singulo = new /obj/singularity(get_turf(user)) singulo.energy = 300 //To give it a small boost @@ -54,7 +58,7 @@ log_game("[key_name(user)] detonated a bag of holding") qdel(src) else - user.visible_message("After careful consideration, [user] has decided that putting a Bag of Holding inside another Bag of Holding would not yield the ideal outcome","You come to the realization that this might not be the greatest idea") + user.visible_message("After careful consideration, [user] has decided that putting a Bag of Holding inside another Bag of Holding would not yield the ideal outcome.","You come to the realization that this might not be the greatest idea.") else . = ..() @@ -77,7 +81,7 @@ /obj/item/weapon/storage/backpack/santabag name = "Santa's Gift Bag" - desc = "Space Santa uses this to deliver toys to all the nice children in space in Christmas! Wow, it's pretty big!" + desc = "Space Santa uses this to deliver toys to all the nice children in space on Christmas! Wow, it's pretty big!" icon_state = "giftbag0" item_state = "giftbag" w_class = 4.0 @@ -169,7 +173,6 @@ desc = "An NT Deluxe satchel, with the finest quality leather and the company logo in a thin gold stitch" icon_state = "nt_deluxe" - /obj/item/weapon/storage/backpack/satchel/withwallet New() ..() @@ -324,7 +327,6 @@ icon_state = "duffel-captain" item_state = "duffel-captain" - /obj/item/weapon/storage/backpack/duffel/security name = "security duffelbag" desc = "A duffelbag built with robust fabric!" @@ -344,13 +346,13 @@ item_state = "duffel-toxins" /obj/item/weapon/storage/backpack/duffel/genetics - name = "scientist duffelbag" + name = "geneticist duffelbag" desc = "A duffelbag designed to hold gibbering monkies." - icon_state = "duffel-toxins" - item_state = "duffel-toxins" + icon_state = "duffel-gene" + item_state = "duffel-gene" /obj/item/weapon/storage/backpack/duffel/chemistry - name = "scientist duffelbag" + name = "chemist duffelbag" desc = "A duffelbag designed to hold corrosive substances." icon_state = "duffel-chemistry" item_state = "duffel-chemistry" diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm index 6af8207c163..7a1107cce1d 100644 --- a/code/game/objects/items/weapons/storage/bags.dm +++ b/code/game/objects/items/weapons/storage/bags.dm @@ -89,7 +89,6 @@ display_contents_with_number = 0 //or else this will lead to stupid behavior. can_hold = list() // any cant_hold = list("/obj/item/weapon/disk/nuclear") - var/head = 0 /obj/item/weapon/storage/bag/plasticbag/mob_can_equip(M as mob, slot) @@ -101,20 +100,19 @@ /obj/item/weapon/storage/bag/plasticbag/equipped(var/mob/user, var/slot) if(slot==slot_head) - head = 1 storage_slots = 0 processing_objects.Add(src) return /obj/item/weapon/storage/bag/plasticbag/process() - if(is_equipped() && head) + if(is_equipped()) if(ishuman(loc)) var/mob/living/carbon/human/H = loc - if(H.internal) - return - H.losebreath += 1 + if(H.get_item_by_slot(slot_head) == src) + if(H.internal) + return + H.losebreath += 1 else - head = 0 storage_slots = 7 processing_objects.Remove(src) return diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index f727326b3f1..44b1a21f73d 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -248,6 +248,37 @@ new /obj/item/weapon/grenade/chem_grenade/cleaner(src) new /obj/item/weapon/grenade/chem_grenade/cleaner(src) +/obj/item/weapon/storage/belt/lazarus + name = "trainer's belt" + desc = "For the mining master, holds your lazarus capsules." + icon_state = "lazarusbelt" + item_state = "lazbelt" + w_class = 4 + max_w_class = 1 + max_combined_w_class = 6 + storage_slots = 6 + can_hold = list("/obj/item/device/mobcapsule") + +/obj/item/weapon/storage/belt/lazarus/New() + ..() + update_icon() + + +/obj/item/weapon/storage/belt/lazarus/update_icon() + ..() + icon_state = "[initial(icon_state)]_[contents.len]" + +/obj/item/weapon/storage/belt/lazarus/attackby(obj/item/W, mob/user) + var/amount = contents.len + . = ..() + if(amount != contents.len) + update_icon() + +/obj/item/weapon/storage/belt/lazarus/remove_from_storage(obj/item/W as obj, atom/new_location) + ..() + update_icon() + + /obj/item/weapon/storage/belt/bandolier name = "bandolier" desc = "A bandolier for holding shotgun ammunition." diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index 685ddc04466..a898c7cca91 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -673,4 +673,15 @@ new /obj/item/weapon/lipstick/black(src) new /obj/item/weapon/lipstick/green(src) new /obj/item/weapon/lipstick/blue(src) - new /obj/item/weapon/lipstick/white(src) \ No newline at end of file + new /obj/item/weapon/lipstick/white(src) + +/obj/item/weapon/storage/box/foam_darts + name = "Foam Dart Pack" + desc = "Extra ammo for foam dart launchers. Contains 10 darts." + storage_slots = 10 + max_combined_w_class = 10 + +/obj/item/weapon/storage/box/foam_darts/New() + ..() + for(var/i=1; i <= storage_slots; i++) + new /obj/item/toy/ammo/crossbow(src) diff --git a/code/game/objects/items/weapons/storage/lockbox.dm b/code/game/objects/items/weapons/storage/lockbox.dm index e5928deeddf..56b910fac9d 100644 --- a/code/game/objects/items/weapons/storage/lockbox.dm +++ b/code/game/objects/items/weapons/storage/lockbox.dm @@ -52,6 +52,13 @@ ..() return +/obj/item/weapon/storage/lockbox/can_be_inserted(obj/item/W as obj, stop_messages = 0) + if(!locked) + return ..() + if(!stop_messages) + usr << "[src] is locked!" + return 0 + /obj/item/weapon/storage/lockbox/emag_act(user as mob) if(!broken) broken = 1 diff --git a/code/game/objects/items/weapons/storage/secure.dm b/code/game/objects/items/weapons/storage/secure.dm index 22899fe36d4..1a179cf8cd9 100644 --- a/code/game/objects/items/weapons/storage/secure.dm +++ b/code/game/objects/items/weapons/storage/secure.dm @@ -140,6 +140,14 @@ return return +/obj/item/weapon/storage/secure/can_be_inserted(obj/item/W as obj, stop_messages = 0) + if(!locked) + return ..() + if(!stop_messages) + usr << "[src] is locked!" + return 0 + + // ----------------------------- // Secure Briefcase // ----------------------------- diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index 772dc76d46c..704f31003cc 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -144,12 +144,11 @@ /obj/item/weapon/storage/box/syndie_kit/emp name = "boxed EMP kit" - New() - ..() - new /obj/item/weapon/grenade/empgrenade(src) - new /obj/item/weapon/grenade/empgrenade(src) - new /obj/item/weapon/implanter/emp/(src) - new /obj/item/device/flashlight/emp/(src) +/obj/item/weapon/storage/box/syndie_kit/emp/New() + ..() + new /obj/item/weapon/grenade/empgrenade(src) + new /obj/item/weapon/grenade/empgrenade(src) + new /obj/item/weapon/implanter/emp/(src) /obj/item/weapon/storage/box/syndie_kit/tabun name = "Tabun Gas Grenades" diff --git a/code/game/objects/items/weapons/storage/wallets.dm b/code/game/objects/items/weapons/storage/wallets.dm index 7e483b3ccbf..e34f9687d7e 100644 --- a/code/game/objects/items/weapons/storage/wallets.dm +++ b/code/game/objects/items/weapons/storage/wallets.dm @@ -1,7 +1,8 @@ /obj/item/weapon/storage/wallet - name = "wallet" - desc = "It can hold a few small and personal things." + name = "leather wallet" + desc = "Made from genuine leather, it is of the highest quality." storage_slots = 10 + icon = 'icons/obj/wallets.dmi' icon_state = "wallet" w_class = 2 can_hold = list( @@ -94,4 +95,62 @@ if(item2_type) new item2_type(src) if(item3_type) - new item3_type(src) \ No newline at end of file + new item3_type(src) + +////////////////////////////////////// +// Color Wallets // +////////////////////////////////////// + +/obj/item/weapon/storage/wallet/color + name = "cheap wallet" + desc = "A cheap wallet from the arcade." + storage_slots = 5 //smaller storage than normal wallets + +/obj/item/weapon/storage/wallet/color/New() + ..() + if(!item_color) + var/color_wallet = pick(subtypesof(/obj/item/weapon/storage/wallet/color)) + new color_wallet(src.loc) + qdel(src) + return + UpdateDesc() + +/obj/item/weapon/storage/wallet/color/proc/UpdateDesc() + name = "cheap [item_color] wallet" + desc = "A cheap, [item_color] wallet from the arcade." + icon_state = "[item_color]_wallet" + +/obj/item/weapon/storage/wallet/color/update_icon() + if(front_id) + switch(front_id.icon_state) + if("id") + icon_state = "[item_color]_walletid" + return + if("silver") + icon_state = "[item_color]_walletid_silver" + return + if("gold") + icon_state = "[item_color]_walletid_gold" + return + if("centcom") + icon_state = "[item_color]_walletid_centcom" + return + icon_state = "[item_color]_wallet" + +/obj/item/weapon/storage/wallet/color/blue + item_color = "blue" + +/obj/item/weapon/storage/wallet/color/red + item_color = "red" + +/obj/item/weapon/storage/wallet/color/yellow + item_color = "yellow" + +/obj/item/weapon/storage/wallet/color/green + item_color = "green" + +/obj/item/weapon/storage/wallet/color/pink + item_color = "pink" + +/obj/item/weapon/storage/waller/color/brown + item_color = "brown" diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index 0c5df41adb0..04c15fe1d97 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -163,6 +163,21 @@ bcell.reliability -= 10 / severity ..() +/obj/item/weapon/melee/baton/wash(mob/user, atom/source) + if(bcell) + if(bcell.charge > 0 && status == 1) + flick("baton_active", source) + user.Stun(stunforce) + user.Weaken(stunforce) + user.stuttering = stunforce + deductcharge(hitcost) + user.visible_message("[user] shocks themself while attempting to wash the active [src]!", \ + "You unwisely attempt to wash [src] while it's still on.") + playsound(src, "sparks", 50, 1) + return 1 + ..() + + //secborg stun baton module /obj/item/weapon/melee/baton/loaded/robot hitcost = 1000 diff --git a/code/game/objects/items/weapons/swords_axes_etc.dm b/code/game/objects/items/weapons/swords_axes_etc.dm index 63f10e1d574..edf0c77e131 100644 --- a/code/game/objects/items/weapons/swords_axes_etc.dm +++ b/code/game/objects/items/weapons/swords_axes_etc.dm @@ -77,6 +77,7 @@ item_state = null slot_flags = SLOT_BELT w_class = 2 + needs_permit = 0 force = 0 on = 0 diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index ac5897367f8..29bc5bd5861 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -358,7 +358,7 @@ var/safety = user:eyecheck() if(ishuman(user)) var/mob/living/carbon/human/H = user - var/obj/item/organ/eyes/E = H.internal_organs_by_name["eyes"] + var/obj/item/organ/internal/eyes/E = H.get_int_organ(/obj/item/organ/internal/eyes) if(!istype(E)) // No eyes? No problem! return switch(safety) diff --git a/code/game/objects/items/weapons/whetstone.dm b/code/game/objects/items/weapons/whetstone.dm new file mode 100644 index 00000000000..bc9fae1a118 --- /dev/null +++ b/code/game/objects/items/weapons/whetstone.dm @@ -0,0 +1,65 @@ +/obj/item/weapon/whetstone + name = "whetstone" + icon = 'icons/obj/kitchen.dmi' + icon_state = "whetstone" + desc = "A block of stone used to sharpen things." + w_class = 2 + var/used = 0 + var/increment = 4 + var/max = 30 + var/prefix = "sharpened" + var/requires_sharpness = 1 + + +/obj/item/weapon/whetstone/attackby(obj/item/I, mob/user, params) + if(used) + user << "The whetstone is too worn to use again." + return + if(I.force >= max || I.throwforce >= max)//no esword sharpening + user << "[I] is much too powerful to sharpen further." + return + if(requires_sharpness && !I.edge) + user << "You can only sharpen items that are already sharp, such as knives." + return + if(istype(I, /obj/item/weapon/twohanded))//some twohanded items should still be sharpenable, but handle force differently. therefore i need this stuff + var/obj/item/weapon/twohanded/TH = I + if(TH.force_wielded >= max) + user << "[TH] is much too powerful to sharpen further." + return + if(TH.wielded) + user << "[TH] must be unwielded before it can be sharpened." + return + if(TH.force_wielded > initial(TH.force_wielded)) + user << "[TH] has already been refined before. It cannot be sharpened further." + return + TH.force_wielded = Clamp(TH.force_wielded + increment, 0, max)//wieldforce is increased since normal force wont stay + if(I.force > initial(I.force)) + user << "[I] has already been refined before. It cannot be sharpened further." + return + user.visible_message("[user] sharpens [I] with [src]!", "You sharpen [I], making it much more deadly than before.") + if(!requires_sharpness) + I.edge = 1 + I.sharp = 1 + I.force = Clamp(I.force + increment, 0, max) + I.throwforce = Clamp(I.throwforce + increment, 0, max) + I.name = "[prefix] [I.name]" + playsound(get_turf(src), 'sound/items/Screwdriver.ogg', 50, 1) + name = "worn out [name]" + desc = "[desc] At least, it used to." + used = 1 + +/obj/item/weapon/whetstone/attack_self(mob/user as mob) //This is just fluff for now. Species datums are global and not newly created instances, so we can't adjust unarmed damage on a per mob basis. + if(ishuman(user)) + var/mob/living/carbon/human/H = user + var/datum/unarmed_attack/attack = H.species.unarmed + if(istype(attack, /datum/unarmed_attack/claws)) + H.visible_message("[H] sharpens \his claws on the [src]!", "You sharpen your claws on the [src].") + playsound(get_turf(H), 'sound/items/Screwdriver.ogg', 50, 1) + +/obj/item/weapon/whetstone/super + name = "super whetstone block" + desc = "A block of stone that will make your weapon sharper than Einstein on adderall." + increment = 200 + max = 200 + prefix = "super-sharpened" + requires_sharpness = 0 \ No newline at end of file diff --git a/code/game/objects/structures/artstuff.dm b/code/game/objects/structures/artstuff.dm index 90792b54602..6604649ad4c 100644 --- a/code/game/objects/structures/artstuff.dm +++ b/code/game/objects/structures/artstuff.dm @@ -111,14 +111,16 @@ var/global/list/globalBlankCanvases[AMT_OF_CANVASES] if(thePix != theOriginalPix) //colour changed DrawPixelOn(theOriginalPix,pixX,pixY) qdel(masterpiece) - return + return 1 //Drawing one pixel with a crayon if(istype(I, /obj/item/toy/crayon)) var/obj/item/toy/crayon/C = I - if(masterpiece.GetPixel(pixX, pixY)) // if the located pixel isn't blank (null)) + var/pix = masterpiece.GetPixel(pixX, pixY) + if(pix && pix != C.colour) // if the located pixel isn't blank (null)) DrawPixelOn(C.colour, pixX, pixY) - return + qdel(masterpiece) + return 1 ..() diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 752d3dcb083..b395e55fc0e 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -55,11 +55,20 @@ I.forceMove(loc) for(var/mob/M in src) - M.forceMove(loc) + moveMob(M, loc) if(M.client) M.client.eye = M.client.mob M.client.perspective = MOB_PERSPECTIVE +/obj/structure/closet/proc/moveMob(var/mob/M, var/atom/destination) + loc.Exited(M) + M.loc = destination + loc.Entered(M, ignoreRest = 1) + for (var/atom/movable/AM in loc) + if (istype(AM, /obj/item)) + continue + AM.Crossed(M) + /obj/structure/closet/proc/open() if(src.opened) return 0 @@ -112,7 +121,7 @@ M.client.perspective = EYE_PERSPECTIVE M.client.eye = src - M.forceMove(src) + moveMob(M, src) itemcount++ src.icon_state = src.icon_closed diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm index 2de9a2adf45..887c32d1584 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -78,6 +78,7 @@ new /obj/item/weapon/defibrillator/loaded(src) new /obj/item/weapon/storage/belt/medical(src) new /obj/item/clothing/glasses/hud/health(src) + new /obj/item/clothing/shoes/sandal/white(src) return //Exam Room @@ -185,6 +186,7 @@ new /obj/item/weapon/storage/belt/medical(src) new /obj/item/device/flash(src) new /obj/item/weapon/reagent_containers/hypospray/CMO(src) + new /obj/item/organ/internal/cyberimp/eyes/hud/medical(src) return diff --git a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm index a935d1f8cfb..ad0c0ac8ef1 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm @@ -21,6 +21,7 @@ new /obj/item/device/radio/headset/headset_sci(src) new /obj/item/weapon/tank/air(src) new /obj/item/clothing/mask/gas(src) + new /obj/item/clothing/shoes/sandal/white(src) return diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 26cd421133e..2aa4ce9db01 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -224,6 +224,7 @@ new /obj/item/clothing/under/rank/security/brigphys(src) new /obj/item/clothing/shoes/white(src) new /obj/item/device/radio/headset/headset_sec/alt(src) + new /obj/item/clothing/shoes/sandal/white(src) return /obj/structure/closet/secure_closet/blueshield @@ -255,6 +256,7 @@ new /obj/item/clothing/shoes/centcom(src) new /obj/item/clothing/accessory/holster(src) new /obj/item/clothing/accessory/blue(src) + new /obj/item/clothing/shoes/jackboots/jacksandals(src) return /obj/structure/closet/secure_closet/ntrep @@ -280,6 +282,7 @@ new /obj/item/clothing/under/lawyer/black(src) new /obj/item/clothing/under/lawyer/female(src) new /obj/item/clothing/head/ntrep(src) + new /obj/item/clothing/shoes/sandal/fancy(src) return @@ -346,6 +349,8 @@ new /obj/item/weapon/gun/projectile/revolver/detective(src) new /obj/item/taperoll/police(src) new /obj/item/clothing/accessory/holster/armpit(src) + new /obj/item/clothing/glasses/sunglasses/yeah(src) + new /obj/item/device/flashlight/seclite(src) return /obj/structure/closet/secure_closet/detective/update_icon() diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index d50ca6b08d0..6e2f0763369 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -91,6 +91,10 @@ move_delay = 0 else user << "You'll need the keys in one of your hands to drive this [callme]." + +/obj/structure/stool/bed/chair/janicart/Bump(atom/A) + if(buckled_mob && istype(A, /obj/machinery/door)) + A.Bumped(buckled_mob) /obj/structure/stool/bed/chair/janicart/user_buckle_mob(mob/living/M, mob/user) if(user.incapacitated()) //user can't move the mob on the janicart's turf if incapacitated diff --git a/code/game/objects/structures/ladders.dm b/code/game/objects/structures/ladders.dm index 8a431c43ac1..39fb502d10b 100644 --- a/code/game/objects/structures/ladders.dm +++ b/code/game/objects/structures/ladders.dm @@ -7,6 +7,7 @@ var/height = 0 //the 'height' of the ladder. higher numbers are considered physically higher var/obj/structure/ladder/down = null //the ladder below this one var/obj/structure/ladder/up = null //the ladder above this one + var/use_verb = "climbs" /obj/structure/ladder/New() spawn(8) @@ -14,9 +15,13 @@ if(L.id == id) if(L.height == (height - 1)) down = L + if(isnull(L.up)) + L.up = src continue if(L.height == (height + 1)) up = L + if(isnull(L.down)) + L.down = src continue if(up && down) //if both our connections are filled @@ -42,12 +47,12 @@ if("Up") user.visible_message("[user] climbs up \the [src]!", \ "You climb up \the [src]!") - user.loc = get_turf(up) + user.forceMove(get_turf(up)) up.add_fingerprint(user) if("Down") user.visible_message("[user] climbs down \the [src]!", \ "You climb down \the [src]!") - user.loc = get_turf(down) + user.forceMove(get_turf(down)) down.add_fingerprint(user) if("Cancel") return @@ -55,16 +60,43 @@ else if(up) user.visible_message("[user] climbs up \the [src]!", \ "You climb up \the [src]!") - user.loc = get_turf(up) + user.forceMove(get_turf(up)) up.add_fingerprint(user) else if(down) user.visible_message("[user] climbs down \the [src]!", \ "You climb down \the [src]!") - user.loc = get_turf(down) + user.forceMove(get_turf(down)) down.add_fingerprint(user) add_fingerprint(user) /obj/structure/ladder/attackby(obj/item/weapon/W, mob/user as mob, params) - return attack_hand(user) \ No newline at end of file + return attack_hand(user) + +/obj/structure/ladder/dive_point/buoy + name = "diving point bouy" + desc = "A buoy marking the location of an underwater dive area." + icon = 'icons/misc/beach.dmi' + icon_state = "buoy" + id = "dive" + height = 2 + use_verb = "dives" + layer = MOB_LAYER + 0.2 //0.1 higher than the water overlay, this also means people can "swim" behind/under it + +/obj/structure/ladder/dive_point/anchor + name = "diving point anchor" + desc = "An anchor tethered to the buoy at the surface, to keep the dive area marked." + icon = 'icons/misc/beach.dmi' + icon_state = "anchor" + id = "dive" + height = 1 + use_verb = "ascends" + light_range = 5 + +/obj/structure/ladder/dive_point/New() + ..() + set_light(light_range, light_power) //magical glowing anchor + +/obj/structure/ladder/dive_point/update_icon() + return \ No newline at end of file diff --git a/code/game/objects/structures/signs.dm b/code/game/objects/structures/signs.dm index 0364847198e..7e35851f693 100644 --- a/code/game/objects/structures/signs.dm +++ b/code/game/objects/structures/signs.dm @@ -201,17 +201,17 @@ icon_state = "chinese" /obj/structure/sign/directions/science - name = "\improper Science department" - desc = "A direction sign, pointing out which way the Science department is." + name = "\improper Research Division" + desc = "A direction sign, pointing out which way the Research Division is." icon_state = "direction_sci" /obj/structure/sign/directions/engineering - name = "\improper Engineering department" + name = "\improper Engineering Department" desc = "A direction sign, pointing out which way the Engineering department is." icon_state = "direction_eng" /obj/structure/sign/directions/security - name = "\improper Security department" + name = "\improper Security Department" desc = "A direction sign, pointing out which way the Security department is." icon_state = "direction_sec" diff --git a/code/game/structure/structure.dm b/code/game/objects/structures/statue.dm similarity index 100% rename from code/game/structure/structure.dm rename to code/game/objects/structures/statue.dm diff --git a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm index 98e3d01e542..feafebd26f8 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm @@ -16,7 +16,7 @@ if(buckled_mob && buckled_mob.buckled == src) var/mob/living/M = buckled_mob - if(isalien(user)) + if(user.get_int_organ(/obj/item/organ/internal/xenos/plasmavessel)) unbuckle_mob() add_fingerprint(user) return @@ -50,9 +50,9 @@ if ( !ismob(M) || (get_dist(src, user) > 1) || (M.loc != src.loc) || user.restrained() || usr.stat || M.buckled || istype(user, /mob/living/silicon/pai) ) return - if(isalien(M)) + if(M.get_int_organ(/obj/item/organ/internal/alien/plasmavessel)) return - if(!isalien(user)) + if(!user.get_int_organ(/obj/item/organ/internal/alien/plasmavessel)) return unbuckle_mob() diff --git a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm index c456cb9c9a6..54540ab008b 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm @@ -72,6 +72,9 @@ ..() if(!buckled_mob) return + if(istype(A, /obj/machinery/door)) + A.Bumped(buckled_mob) + if(propelled) var/mob/living/occupant = buckled_mob unbuckle_mob() @@ -89,4 +92,70 @@ victim.apply_effect(6, STUTTER, 0) victim.take_organ_damage(10) - occupant.visible_message("[occupant] crashed into \the [A]!") \ No newline at end of file + occupant.visible_message("[occupant] crashed into \the [A]!") + +/obj/structure/stool/bed/chair/wheelchair/bike + name = "bicycle" + desc = "Two wheels of FURY!" + //placeholder until i get a bike sprite + icon = 'icons/vehicles/motorcycle.dmi' + icon_state = "motorcycle_4dir" + +/obj/structure/stool/bed/chair/wheelchair/bike/relaymove(mob/user, direction) + if(propelled) + return 0 + + if(!Process_Spacemove(direction) || !has_gravity(src.loc) || !isturf(loc)) //bikes in space. + return 0 + + if(world.time < move_delay) + return + + var/calculated_move_delay + calculated_move_delay = 0 //bikes are infact sport bikes + + if(buckled_mob) + if(buckled_mob.incapacitated()) + unbuckle_mob() //if the rider is incapacitated, unbuckle them (they can't balance so they fall off) + return 0 + + var/mob/living/thedriver = user + var/mob_delay = thedriver.movement_delay() + if(mob_delay > 0) + calculated_move_delay += mob_delay + + if(ishuman(buckled_mob)) + var/mob/living/carbon/human/driver = user + var/obj/item/organ/external/l_hand = driver.get_organ("l_hand") + var/obj/item/organ/external/r_hand = driver.get_organ("r_hand") + if((!l_hand || (l_hand.status & ORGAN_DESTROYED)) && (!r_hand || (r_hand.status & ORGAN_DESTROYED))) + calculated_move_delay += 0.5 //I can ride my bike with no handlebars... (but it's slower) + + for(var/organ_name in list("l_leg","r_leg","l_foot","r_foot")) + var/obj/item/organ/external/E = driver.get_organ(organ_name) + if(!E || (E.status & ORGAN_DESTROYED)) + return 0 //Bikes need both feet/legs to work. missing even one makes it so you can't ride the bike + else if(E.status & ORGAN_SPLINTED) + calculated_move_delay += 0.5 + else if(E.status & ORGAN_BROKEN) + calculated_move_delay += 1.5 + + move_delay = world.time + move_delay += calculated_move_delay + + if(!buckled_mob.Move(get_step(buckled_mob, direction), direction)) + loc = buckled_mob.loc //we gotta go back + last_move = buckled_mob.last_move + inertia_dir = last_move + buckled_mob.inertia_dir = last_move + . = 0 + + else + . = 1 + +/obj/structure/stool/bed/chair/wheelchair/bike/handle_rotation() + overlays = null + var/image/O = image(icon = 'icons/vehicles/motorcycle.dmi', icon_state = "motorcycle_overlay_4d", layer = FLY_LAYER, dir = src.dir) + overlays += O + if(buckled_mob) + buckled_mob.dir = dir \ No newline at end of file diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index fabaf4c63f0..6a921a014a3 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -42,7 +42,7 @@ /obj/structure/table/update_icon() if(smooth && !flipped) - icon_state = initial(icon_state) + icon_state = "" smooth_icon(src) smooth_icon_neighbors(src) diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 3262ac5ece2..cc73a42f0d0 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -12,14 +12,18 @@ var/w_items = 0 //the combined w_class of all the items in the cistern var/mob/living/swirlie = null //the mob being given a swirlie + /obj/structure/toilet/New() open = round(rand(0, 1)) update_icon() -/obj/structure/toilet/attack_hand(mob/living/user as mob) + +/obj/structure/toilet/attack_hand(mob/living/user) if(swirlie) - usr.visible_message("[user] slams the toilet seat onto [swirlie.name]'s head!", "You slam the toilet seat onto [swirlie.name]'s head!", "You hear reverberating porcelain.") - swirlie.adjustBruteLoss(8) + user.changeNext_move(CLICK_CD_MELEE) + playsound(src.loc, "swing_hit", 25, 1) + swirlie.visible_message("[user] slams the toilet seat onto [swirlie]'s head!", "[user] slams the toilet seat onto [swirlie]'s head!", "You hear reverberating porcelain.") + swirlie.adjustBruteLoss(5) return if(cistern && !open) @@ -32,61 +36,81 @@ user.put_in_hands(I) else I.loc = get_turf(src) - user << "You find \an [I] in the cistern." + user << "You find [I] in the cistern." w_items -= I.w_class return open = !open update_icon() + /obj/structure/toilet/update_icon() icon_state = "toilet[open][cistern]" -/obj/structure/toilet/attackby(obj/item/I as obj, mob/living/user as mob, params) + +/obj/structure/toilet/attackby(obj/item/I, mob/living/user, params) if(istype(I, /obj/item/weapon/crowbar)) - user << "You start to [cistern ? "replace the lid on the cistern" : "lift the lid off the cistern"]." + user << "You start to [cistern ? "replace the lid on the cistern" : "lift the lid off the cistern"]..." playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 50, 1) if(do_after(user, 30, target = src)) - user.visible_message("[user] [cistern ? "replaces the lid on the cistern" : "lifts the lid off the cistern"]!", "You [cistern ? "replace the lid on the cistern" : "lift the lid off the cistern"]!", "You hear grinding porcelain.") + user.visible_message("[user] [cistern ? "replaces the lid on the cistern" : "lifts the lid off the cistern"]!", "You [cistern ? "replace the lid on the cistern" : "lift the lid off the cistern"]!", "You hear grinding porcelain.") cistern = !cistern update_icon() return - if(istype(I, /obj/item/weapon/grab)) - var/obj/item/weapon/grab/G = I + if(istype(I, /obj/item/weapon/reagent_containers)) + if(!open) + return + var/obj/item/weapon/reagent_containers/RG = I + if(RG.is_open_container()) + RG.reagents.add_reagent("toiletwater", min(RG.volume - RG.reagents.total_volume, RG.amount_per_transfer_from_this)) + user << "You fill [RG] from [src]. Gross." + return + if(istype(I, /obj/item/weapon/grab)) + user.changeNext_move(CLICK_CD_MELEE) + var/obj/item/weapon/grab/G = I + if(!G.confirm()) + return if(isliving(G.affecting)) var/mob/living/GM = G.affecting - - if(G.state>1) - if(!GM.loc == get_turf(src)) - user << "[GM.name] needs to be on the toilet." + if(G.state >= GRAB_AGGRESSIVE) + if(GM.loc != get_turf(src)) + user << "[GM] needs to be on [src]!" return - if(open && !swirlie) - user.visible_message("[user] starts to give [GM.name] a swirlie!", "You start to give [GM.name] a swirlie!") - swirlie = GM - if(do_after(user, 30, 5, 0, target = src)) - user.visible_message("[user] gives [GM.name] a swirlie!", "You give [GM.name] a swirlie!", "You hear a toilet flushing.") - if(!GM.internal) - GM.adjustOxyLoss(5) - swirlie = null - else - user.visible_message("[user] slams [GM.name] into the [src]!", "You slam [GM.name] into the [src]!") - GM.adjustBruteLoss(8) + if(!swirlie) + if(open) + GM.visible_message("[user] starts to give [GM] a swirlie!", "[user] starts to give [GM] a swirlie...") + swirlie = GM + if(do_after(user, 30, 5, 0, target = src)) + GM.visible_message("[user] gives [GM] a swirlie!", "[user] gives [GM] a swirlie!", "You hear a toilet flushing.") + if(iscarbon(GM)) + var/mob/living/carbon/C = GM + if(!C.internal) + C.adjustOxyLoss(5) + else + GM.adjustOxyLoss(5) + swirlie = null + else + playsound(src.loc, 'sound/effects/bang.ogg', 25, 1) + GM.visible_message("[user] slams [GM.name] into [src]!", "[user] slams [GM.name] into [src]!") + GM.adjustBruteLoss(5) else - user << "You need a tighter grip." + user << "You need a tighter grip!" if(cistern) if(I.w_class > 3) - user << "\The [I] does not fit." + user << "[I] does not fit!" return if(w_items + I.w_class > 5) - user << "The cistern is full." + user << "The cistern is full!" + return + if(!user.drop_item()) + user << "\The [I] is stuck to your hand, you cannot put it in the cistern!" return - user.drop_item() I.loc = src w_items += I.w_class - user << "You carefully place \the [I] into the cistern." + user << "You carefully place [I] into the cistern." return @@ -99,20 +123,24 @@ density = 0 anchored = 1 -/obj/structure/urinal/attackby(obj/item/I as obj, mob/user as mob, params) + +/obj/structure/urinal/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/weapon/grab)) var/obj/item/weapon/grab/G = I + if(!G.confirm()) + return if(isliving(G.affecting)) var/mob/living/GM = G.affecting - if(G.state>1) - if(!GM.loc == get_turf(src)) - user << "[GM.name] needs to be on the urinal." + if(G.state >= GRAB_AGGRESSIVE) + if(GM.loc != get_turf(src)) + user << "[GM.name] needs to be on [src]." return - user.visible_message("[user] slams [GM.name] into the [src]!", "You slam [GM.name] into the [src]!") + user.changeNext_move(CLICK_CD_MELEE) + playsound(src.loc, 'sound/effects/bang.ogg', 25, 1) + user.visible_message("[user] slams [GM] into [src]!", "You slam [GM] into [src]!") GM.adjustBruteLoss(8) else - user << "You need a tighter grip." - + user << "You need a tighter grip!" /obj/machinery/shower @@ -344,6 +372,13 @@ var/busy = 0 //Something's being washed at the moment /obj/structure/sink/attack_hand(mob/user as mob) + if(!user || !istype(user)) + return + if(!iscarbon(user)) + return + if(!Adjacent(user)) + return + if (ishuman(user)) var/mob/living/carbon/human/H = user var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] @@ -353,82 +388,51 @@ user << "You try to move your [temp.name], but cannot!" return - if(isrobot(user) || isAI(user)) - return - - if(!Adjacent(user)) - return - if(busy) - user << "\red Someone's already washing here." + user << "Someone's already washing here." + return + var/selected_area = parse_zone(user.zone_sel.selecting) + var/washing_face = 0 + if(selected_area in list("head", "mouth", "eyes")) + washing_face = 1 + user.visible_message("[user] start washing their [washing_face ? "face" : "hands"]...", \ + "You start washing your [washing_face ? "face" : "hands"]...") + busy = 1 + + if(!do_after(user, 40, target = src)) + busy = 0 return - usr << "\blue You start washing your hands." - - busy = 1 - sleep(40) busy = 0 - if(!Adjacent(user)) return //Person has moved away from the sink - - user.clean_blood() - if(ishuman(user)) - user:update_inv_gloves() - for(var/mob/V in viewers(src, null)) - V.show_message("\blue [user] washes their hands using \the [src].") + user.visible_message("[user] washes their [washing_face ? "face" : "hands"] using [src].", \ + "You wash your [washing_face ? "face" : "hands"] using [src].") + if(washing_face) + if(ishuman(user)) + var/mob/living/carbon/human/H = user + H.lip_style = null //Washes off lipstick + H.lip_color = initial(H.lip_color) + H.regenerate_icons() + user.drowsyness -= rand(2,3) //Washing your face wakes you up if you're falling asleep + user.drowsyness = Clamp(user.drowsyness, 0, INFINITY) + else + user.clean_blood() -/obj/structure/sink/attackby(obj/item/O as obj, mob/user as mob, params) +/obj/structure/sink/attackby(obj/item/O, mob/user, params) if(busy) - user << "\red Someone's already washing here." + user << "Someone's already washing here!" return - if (istype(O, /obj/item/weapon/reagent_containers)) - var/obj/item/weapon/reagent_containers/RG = O - RG.reagents.add_reagent("water", min(RG.volume - RG.reagents.total_volume, RG.amount_per_transfer_from_this)) - user.visible_message("\blue [user] fills the [RG] using \the [src].","\blue You fill the [RG] using \the [src].") + if(!(istype(O))) return - O.water_act(20,310.15,src) - - if (istype(O, /obj/item/weapon/melee/baton)) - var/obj/item/weapon/melee/baton/B = O - if (B.bcell.charge > 0 && B.status == 1) - flick("baton_active", src) - user.Stun(10) - user.stuttering = 10 - user.Weaken(10) - if(isrobot(user)) - var/mob/living/silicon/robot/R = user - R.cell.charge -= 20 - else - B.deductcharge(B.hitcost) - user.visible_message( \ - "[user] was stunned by his wet [O].", \ - "\red You have wet \the [O], it shocks you!") - return - - var/turf/location = user.loc - if(!isturf(location)) return - - var/obj/item/I = O - if(!I || !istype(I,/obj/item)) return - - usr << "\blue You start washing \the [I]." - busy = 1 - sleep(40) + var/wateract = 0 + wateract = (O.wash(user, src)) busy = 0 - - if(user.loc != location) return //User has moved - if(!I) return //Item's been destroyed while washing - if(user.get_active_hand() != I) return //Person has switched hands or the item in their hands - - O.clean_blood() - user.visible_message( \ - "\blue [user] washes \a [I] using \the [src].", \ - "\blue You wash \a [I] using \the [src].") - + if (wateract) + O.water_act(20,310.15,src) /obj/structure/sink/kitchen name = "kitchen sink" diff --git a/code/game/response_team.dm b/code/game/response_team.dm index a8f5a8bba79..fab7bdcbbf1 100644 --- a/code/game/response_team.dm +++ b/code/game/response_team.dm @@ -153,9 +153,9 @@ var/send_emergency_team var/new_gender = alert(usr, "Please select your gender.", "Character Generation", "Male", "Female") if (new_gender) if(new_gender == "Male") - M.gender = MALE + M.change_gender(MALE) else - M.gender = FEMALE + M.change_gender(FEMALE) M.set_species("Human",1) M.dna.ready_dna(M) diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm index f3fd7b38dd1..8bcf3b8a5b8 100644 --- a/code/game/turfs/simulated.dm +++ b/code/game/turfs/simulated.dm @@ -50,95 +50,67 @@ tracks = new typepath(src) tracks.AddTracks(bloodDNA,comingdir,goingdir,bloodcolor) -/turf/simulated/Entered(atom/A, atom/OL) +/turf/simulated/Entered(atom/A, atom/OL, ignoreRest = 0) ..() - if(ismob(A)) //only mobs make dirt - if(prob(80)) - dirt++ + if(!ignoreRest) + if(ismob(A)) //only mobs make dirt + if(prob(80)) + dirt++ - var/obj/effect/decal/cleanable/dirt/dirtoverlay = locate(/obj/effect/decal/cleanable/dirt) in src - if(dirt >= 100) - if(!dirtoverlay) - dirtoverlay = new/obj/effect/decal/cleanable/dirt(src) - dirtoverlay.alpha = 10 - else if(dirt > 100) - dirtoverlay.alpha = min(dirtoverlay.alpha + 10, 200) + var/obj/effect/decal/cleanable/dirt/dirtoverlay = locate(/obj/effect/decal/cleanable/dirt) in src + if(dirt >= 100) + if(!dirtoverlay) + dirtoverlay = new/obj/effect/decal/cleanable/dirt(src) + dirtoverlay.alpha = 10 + else if(dirt > 100) + dirtoverlay.alpha = min(dirtoverlay.alpha + 10, 200) - if(ishuman(A)) - var/mob/living/carbon/human/M = A - if(M.lying) - return 1 + if(ishuman(A)) + var/mob/living/carbon/human/M = A + if(M.lying) + return 1 - if(M.flying) - return ..() + if(M.flying) + return ..() - // Tracking blood - var/list/bloodDNA = null - var/bloodcolor = "" - if(M.shoes) - var/obj/item/clothing/shoes/S = M.shoes - if(S.track_blood && S.blood_DNA) - bloodDNA = S.blood_DNA - bloodcolor = S.blood_color - S.track_blood-- - else - if(M.track_blood && M.feet_blood_DNA) - bloodDNA = M.feet_blood_DNA - bloodcolor = M.feet_blood_color - M.track_blood-- + // Tracking blood + var/list/bloodDNA = null + var/bloodcolor = "" + if(M.shoes) + var/obj/item/clothing/shoes/S = M.shoes + if(S.track_blood && S.blood_DNA) + bloodDNA = S.blood_DNA + bloodcolor = S.blood_color + S.track_blood-- + else + if(M.track_blood && M.feet_blood_DNA) + bloodDNA = M.feet_blood_DNA + bloodcolor = M.feet_blood_color + M.track_blood-- - if (bloodDNA) - src.AddTracks(/obj/effect/decal/cleanable/blood/tracks/footprints,bloodDNA,M.dir,0,bloodcolor) // Coming - var/turf/simulated/from = get_step(M,reverse_direction(M.dir)) - if(istype(from) && from) - from.AddTracks(/obj/effect/decal/cleanable/blood/tracks/footprints,bloodDNA,0,M.dir,bloodcolor) // Going + if (bloodDNA) + src.AddTracks(/obj/effect/decal/cleanable/blood/tracks/footprints,bloodDNA,M.dir,0,bloodcolor) // Coming + var/turf/simulated/from = get_step(M,reverse_direction(M.dir)) + if(istype(from) && from) + from.AddTracks(/obj/effect/decal/cleanable/blood/tracks/footprints,bloodDNA,0,M.dir,bloodcolor) // Going - bloodDNA = null + bloodDNA = null - var/noslip = 0 - for (var/obj/structure/stool/bed/chair/C in contents) - if (C.buckled_mob == M) - noslip = 1 - if (noslip) - return // no slipping while sitting in a chair, plz - switch (src.wet) - if(TURF_WET_WATER) - if ((M.m_intent == "run") && !(istype(M:shoes, /obj/item/clothing/shoes) && M.shoes.flags&NOSLIP)) - M.stop_pulling() - step(M, M.dir) - M << "\blue You slipped on the wet floor!" - playsound(src, 'sound/misc/slip.ogg', 50, 1, -3) - M.Stun(4) - M.Weaken(2) - else - M.inertia_dir = 0 - return + switch (src.wet) + if(TURF_WET_WATER) + if (!(M.slip("wet floor", 4, 2, 0, 1))) + M.inertia_dir = 0 + return + + if(TURF_WET_LUBE) //lube + if(M.slip("floor", 0, 7, 4, 0, 1)) + M.take_organ_damage(2) // Was 5 -- TLE - if(TURF_WET_LUBE) //lube //can cause infinite loops - needs work - if(!M.buckled) - M.stop_pulling() - step(M, M.dir) - spawn(1) step(M, M.dir) - spawn(2) step(M, M.dir) - spawn(3) step(M, M.dir) - spawn(4) step(M, M.dir) - M.take_organ_damage(2) // Was 5 -- TLE - M << "\blue You slipped on the floor!" - playsound(src, 'sound/misc/slip.ogg', 50, 1, -3) - M.Weaken(7) + if(TURF_WET_ICE) // Ice + if (!(prob(30) && M.slip("icy floor", 4, 2, 1, 1))) + M.inertia_dir = 0 - if(TURF_WET_ICE) // Ice - if ((M.m_intent == "run") && !(istype(M:shoes, /obj/item/clothing/shoes) && M:shoes.flags&NOSLIP) && prob(30)) - M.stop_pulling() - step(M, M.dir) - M << "\blue You slipped on the icy floor!" - playsound(src, 'sound/misc/slip.ogg', 50, 1, -3) - M.Stun(4) - M.Weaken(2) - else - M.inertia_dir = 0 - return //returns 1 if made bloody, returns 0 otherwise /turf/simulated/add_blood(mob/living/carbon/human/M as mob) diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index 11167a2ee4c..2f18239e3df 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -2,6 +2,7 @@ var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3","damaged4", "damaged5","panelscorched","floorscorched1","floorscorched2","platingdmg1","platingdmg2", "platingdmg3","plating","light_on","light_on_flicker1","light_on_flicker2", + "warnplate", "warnplatecorner", "light_on_clicker3","light_on_clicker4","light_on_clicker5","light_broken", "light_on_broken","light_off","wall_thermite","grass1","grass2","grass3","grass4", "asteroid","asteroid_dug", @@ -12,16 +13,10 @@ var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3"," "ironsand6", "ironsand7", "ironsand8", "ironsand9", "ironsand10", "ironsand11", "ironsand12", "ironsand13", "ironsand14", "ironsand15") -var/list/plating_icons = list("plating","platingdmg1","platingdmg2","platingdmg3","asteroid","asteroid_dug", - "ironsand1", "ironsand2", "ironsand3", "ironsand4", "ironsand5", "ironsand6", "ironsand7", - "ironsand8", "ironsand9", "ironsand10", "ironsand11", - "ironsand12", "ironsand13", "ironsand14", "ironsand15") -var/list/wood_icons = list("wood","wood-broken") - /turf/simulated/floor name = "floor" icon = 'icons/turf/floors.dmi' - icon_state = "floor" + icon_state = "dont_use_this_floor" var/icon_regular_floor = "floor" //used to remember what icon the tile should have by default var/icon_plating = "plating" @@ -138,9 +133,11 @@ var/list/wood_icons = list("wood","wood-broken") if(!istype(src,/turf/simulated/floor)) return ..() //fucking turfs switch the fucking src of the fucking running procs if(!ispath(T,/turf/simulated/floor)) return ..() var/old_icon = icon_regular_floor + var/old_plating = icon_plating var/old_dir = dir var/turf/simulated/floor/W = ..() W.icon_regular_floor = old_icon + W.icon_plating = old_plating W.dir = old_dir W.update_icon() return W @@ -159,8 +156,11 @@ var/list/wood_icons = list("wood","wood-broken") else if(istype(src, /turf/simulated/floor/wood)) user << "You forcefully pry off the planks, destroying them in the process." + else if(!builtin_tile) + user << "You are unable to pry up \the [src] with a crowbar." + return 1 else - user << "You remove the floor tile." + user << "You remove \the [builtin_tile.singular_name]." builtin_tile.loc = src builtin_tile = null //deassociate tile, it no longer belongs to this turf make_plating() diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm index 25694f28fc3..0e900329922 100644 --- a/code/game/turfs/simulated/floor/plating.dm +++ b/code/game/turfs/simulated/floor/plating.dm @@ -223,7 +223,7 @@ if(!broken && isscrewdriver(C)) user << "You unscrew the catwalk's rods." - new /obj/item/stack/rods(src, 2) + new /obj/item/stack/rods(src, 1) ReplaceWithLattice() for(var/direction in cardinal) var/turf/T = get_step(src,direction) diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index d311d94d7e6..c6534203db3 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -64,8 +64,10 @@ if(!damage_overlays[1]) //list hasn't been populated generate_overlays() + smooth_icon(src) if(!damage) - overlays.Cut() + overlays -= damage_overlays[damage_overlay] + damage_overlay = 0 return var/overlay = round(damage / damage_cap * damage_overlays.len) + 1 @@ -74,8 +76,7 @@ if(damage_overlay && overlay == damage_overlay) //No need to update. return - - overlays.Cut() + overlays -= damage_overlays[damage_overlay] overlays += damage_overlays[overlay] damage_overlay = overlay diff --git a/code/game/turfs/unsimulated/beach.dm b/code/game/turfs/unsimulated/beach.dm index d8ce4659b02..70954512dc7 100644 --- a/code/game/turfs/unsimulated/beach.dm +++ b/code/game/turfs/unsimulated/beach.dm @@ -1,20 +1,66 @@ /turf/unsimulated/beach name = "Beach" icon = 'icons/misc/beach.dmi' + var/water_overlay_image = null + +/turf/unsimulated/beach/New() + ..() + if(water_overlay_image) + overlays += image("icon"='icons/misc/beach.dmi',"icon_state"= water_overlay_image,"layer"=MOB_LAYER+0.1) /turf/unsimulated/beach/sand name = "Sand" - icon_state = "sand" + icon_state = "desert" + +/turf/unsimulated/beach/sand/New() //adds some aesthetic randomness to the beach sand + icon_state = pick("desert", "desert0", "desert1", "desert2", "desert3", "desert4") + ..() + +/turf/unsimulated/beach/sand/dense //for boundary "walls" + density = 1 /turf/unsimulated/beach/coastline name = "Coastline" - icon = 'icons/misc/beach2.dmi' - icon_state = "sandwater" + //icon = 'icons/misc/beach2.dmi' + //icon_state = "sandwater" + icon_state = "beach" + water_overlay_image = "water_coast" + +/turf/unsimulated/beach/coastline/dense //for boundary "walls" + density = 1 /turf/unsimulated/beach/water - name = "Water" - icon_state = "water" + name = "Shallow Water" + icon_state = "seashallow" + water_overlay_image = "water_shallow" -/turf/unsimulated/beach/water/New() - ..() - overlays += image("icon"='icons/misc/beach.dmi',"icon_state"="water2","layer"=MOB_LAYER+0.1) +/turf/unsimulated/beach/water/drop + name = "Water" + icon_state = "seadrop" + +/turf/unsimulated/beach/water/dense //for boundary "walls" + density = 1 + +/turf/unsimulated/beach/water/deep + name = "Deep Water" + icon_state = "seadeep" + water_overlay_image = "water_deep" + +/turf/unsimulated/beach/water/deep/dense + density = 1 + +/turf/unsimulated/beach/water/deep/wood_floor + name = "Sunken Floor" + icon = 'icons/turf/floors.dmi' + icon_state = "wood" + +/turf/unsimulated/beach/water/deep/sand_floor + name = "Sea Floor" + icon_state = "sand" + +/turf/unsimulated/beach/water/deep/rock_wall + name = "Reef Stone" + icon_state = "desert7" + density = 1 + opacity = 1 + explosion_block = 2 \ No newline at end of file diff --git a/code/game/turfs/unsimulated/floor.dm b/code/game/turfs/unsimulated/floor.dm index cf5acebeede..70cb8bf9b38 100644 --- a/code/game/turfs/unsimulated/floor.dm +++ b/code/game/turfs/unsimulated/floor.dm @@ -13,4 +13,18 @@ /turf/unsimulated/floor/snow name = "snow" icon = 'icons/turf/snow.dmi' - icon_state = "snow" \ No newline at end of file + icon_state = "snow" + +/turf/unsimulated/floor/chasm + name = "sinkhole" + desc = "It's difficult to see the bottom." + density = 1 + icon = 'icons/turf/floors/Chasms.dmi' + icon_state = "Fill" + smooth = SMOOTH_TRUE + canSmoothWith = null + +/turf/unsimulated/floor/chasm/New() + spawn(1) + smooth_icon(src) + smooth_icon_neighbors(src) \ No newline at end of file diff --git a/code/game/vehicles/spacepods/equipment.dm b/code/game/vehicles/spacepods/equipment.dm index 80a24e72727..e151e75d99e 100644 --- a/code/game/vehicles/spacepods/equipment.dm +++ b/code/game/vehicles/spacepods/equipment.dm @@ -15,14 +15,12 @@ switch(my_atom.dir) if(NORTH) firstloc = get_step(my_atom, NORTH) - firstloc = get_step(firstloc, NORTH) secondloc = get_step(firstloc,EAST) if(SOUTH) firstloc = get_step(my_atom, SOUTH) secondloc = get_step(firstloc,EAST) if(EAST) firstloc = get_step(my_atom, EAST) - firstloc = get_step(firstloc, EAST) secondloc = get_step(firstloc,NORTH) if(WEST) firstloc = get_step(my_atom, WEST) @@ -72,34 +70,33 @@ var/shot_cost = 0 var/shots_per = 1 var/fire_sound - var/fire_delay = 20 + var/fire_delay = 15 /obj/item/device/spacepod_equipment/weaponry/taser - name = "\improper taser system" - desc = "A weak taser system for space pods, fires electrodes that shock upon impact." + name = "disabler system" + desc = "A weak taser system for space pods, fires disabler beams." icon_state = "pod_taser" projectile_type = "/obj/item/projectile/beam/disabler" - shot_cost = 250 + shot_cost = 400 fire_sound = "sound/weapons/Taser.ogg" /obj/item/device/spacepod_equipment/weaponry/burst_taser - name = "\improper burst taser system" + name = "burst taser system" desc = "A weak taser system for space pods, this one fires 3 at a time." icon_state = "pod_b_taser" projectile_type = "/obj/item/projectile/beam/disabler" - shot_cost = 350 + shot_cost = 1200 shots_per = 3 fire_sound = "sound/weapons/Taser.ogg" - fire_delay = 40 + fire_delay = 30 /obj/item/device/spacepod_equipment/weaponry/laser - name = "\improper laser system" + name = "laser system" desc = "A weak laser system for space pods, fires concentrated bursts of energy" icon_state = "pod_w_laser" projectile_type = "/obj/item/projectile/beam" - shot_cost = 300 + shot_cost = 600 fire_sound = 'sound/weapons/Laser.ogg' - fire_delay = 30 //base item for spacepod misc equipment (tracker) /obj/item/device/spacepod_equipment/misc diff --git a/code/game/vehicles/spacepods/spacepod.dm b/code/game/vehicles/spacepods/spacepod.dm index af322b3f60f..caf7c8b16be 100644 --- a/code/game/vehicles/spacepods/spacepod.dm +++ b/code/game/vehicles/spacepods/spacepod.dm @@ -49,6 +49,9 @@ var/allow2enter = 1 + var/move_delay = 2 + var/next_move = 0 + /obj/spacepod/New() . = ..() if(!pod_overlays) @@ -723,43 +726,45 @@ /datum/global_iterator/pod_tank_give_air delay = 15 - process(var/obj/spacepod/spacepod) - if(spacepod && spacepod.internal_tank) - var/datum/gas_mixture/tank_air = spacepod.internal_tank.return_air() - var/datum/gas_mixture/cabin_air = spacepod.cabin_air +/datum/global_iterator/pod_tank_give_air/process(var/obj/spacepod/spacepod) + if(spacepod && spacepod.internal_tank) + var/datum/gas_mixture/tank_air = spacepod.internal_tank.return_air() + var/datum/gas_mixture/cabin_air = spacepod.cabin_air - var/release_pressure = ONE_ATMOSPHERE - var/cabin_pressure = cabin_air.return_pressure() - var/pressure_delta = min(release_pressure - cabin_pressure, (tank_air.return_pressure() - cabin_pressure)/2) - var/transfer_moles = 0 - if(pressure_delta > 0) //cabin pressure lower than release pressure - if(tank_air.return_temperature() > 0) - transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION) - var/datum/gas_mixture/removed = tank_air.remove(transfer_moles) - cabin_air.merge(removed) - else if(pressure_delta < 0) //cabin pressure higher than release pressure - var/datum/gas_mixture/t_air = spacepod.get_turf_air() - pressure_delta = cabin_pressure - release_pressure + var/release_pressure = ONE_ATMOSPHERE + var/cabin_pressure = cabin_air.return_pressure() + var/pressure_delta = min(release_pressure - cabin_pressure, (tank_air.return_pressure() - cabin_pressure)/2) + var/transfer_moles = 0 + if(pressure_delta > 0) //cabin pressure lower than release pressure + if(tank_air.return_temperature() > 0) + transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION) + var/datum/gas_mixture/removed = tank_air.remove(transfer_moles) + cabin_air.merge(removed) + else if(pressure_delta < 0) //cabin pressure higher than release pressure + var/datum/gas_mixture/t_air = spacepod.get_turf_air() + pressure_delta = cabin_pressure - release_pressure + if(t_air) + pressure_delta = min(cabin_pressure - t_air.return_pressure(), pressure_delta) + if(pressure_delta > 0) //if location pressure is lower than cabin pressure + transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION) + var/datum/gas_mixture/removed = cabin_air.remove(transfer_moles) if(t_air) - pressure_delta = min(cabin_pressure - t_air.return_pressure(), pressure_delta) - if(pressure_delta > 0) //if location pressure is lower than cabin pressure - transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION) - var/datum/gas_mixture/removed = cabin_air.remove(transfer_moles) - if(t_air) - t_air.merge(removed) - else //just delete the cabin gas, we're in space or some shit - qdel(removed) - else - return stop() - return + t_air.merge(removed) + else //just delete the cabin gas, we're in space or some shit + qdel(removed) + else + return stop() + return /obj/spacepod/relaymove(mob/user, direction) if(!CheckIfOccupant2(user)) handlerelaymove(user, direction) /obj/spacepod/proc/handlerelaymove(mob/user, direction) + if(world.time < next_move) + return 0 var/moveship = 1 - if(battery && battery.charge >= 3 && health && empcounter == 0) + if(battery && battery.charge >= 1 && health && empcounter == 0) src.dir = direction switch(direction) if(NORTH) @@ -783,16 +788,17 @@ else if(!battery) user << "No energy cell detected." - else if(battery.charge < 3) + else if(battery.charge < 1) user << "Not enough charge left." else if(!health) user << "She's dead, Jim" else if(empcounter != 0) user << "The pod control interface isn't responding. The console indicates [empcounter] seconds before reboot." else - user << "Unknown error has occurred, yell at pomf." + user << "Unknown error has occurred, yell at the coders." return 0 - battery.charge = max(0, battery.charge - 3) + battery.charge = max(0, battery.charge - 1) + next_move = world.time + move_delay /obj/spacepod/proc/CheckIfOccupant2(mob/user) if(!src.occupant2) diff --git a/code/game/verbs/who.dm b/code/game/verbs/who.dm index c2eda15b18a..87e8231e272 100644 --- a/code/game/verbs/who.dm +++ b/code/game/verbs/who.dm @@ -10,6 +10,9 @@ if(check_rights(R_ADMIN,0)) for(var/client/C in clients) + if(C.holder && C.holder.big_brother && !check_rights(R_PERMISSIONS, 0)) // need PERMISSIONS to see BB + continue + var/entry = "\t[C.key]" if(C.holder && C.holder.fakekey) entry += " (as [C.holder.fakekey])" @@ -24,6 +27,8 @@ entry += " - Observing" else entry += " - DEAD" + else if (istype(C.mob, /mob/new_player)) + entry += " - New Player" else entry += " - DEAD" @@ -46,6 +51,9 @@ Lines += entry else for(var/client/C in clients) + if(C.holder && C.holder.big_brother) // BB doesn't show up at all + continue + if(C.holder && C.holder.fakekey) Lines += C.holder.fakekey else @@ -71,6 +79,9 @@ if(C.holder.fakekey && !check_rights(R_ADMIN, 0)) //Mentors/Mods can't see stealthmins continue + + if(C.holder.big_brother && !check_rights(R_PERMISSIONS, 0)) // normal admins can't see BB + continue msg += "\t[C] is a [C.holder.rank]" diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index db488c84649..a5b2a7617df 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -160,7 +160,8 @@ var/list/admin_verbs_possess = list( ) var/list/admin_verbs_permissions = list( /client/proc/edit_admin_permissions, - /client/proc/create_poll + /client/proc/create_poll, + /client/proc/big_brother ) var/list/admin_verbs_rejuv = list( /client/proc/respawn_character, @@ -428,6 +429,7 @@ var/list/admin_verbs_proccall = list ( return if(holder) + holder.big_brother = 0 if(holder.fakekey) holder.fakekey = null else @@ -441,6 +443,29 @@ var/list/admin_verbs_proccall = list ( message_admins("[key_name_admin(usr)] has turned stealth mode [holder.fakekey ? "ON" : "OFF"]", 1) feedback_add_details("admin_verb","SM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/client/proc/big_brother() + set category = "Admin" + set name = "Big Brother Mode" + + if(!check_rights(R_PERMISSIONS)) + return + + if(holder) + if(holder.fakekey) + holder.fakekey = null + holder.big_brother = 0 + else + var/new_key = ckeyEx(input("Enter your desired display name. Unlike normal stealth mode, this will not appear in Who at all, except for other heads.", "Fake Key", key) as text|null) + if(!new_key) + return + if(length(new_key) >= 26) + new_key = copytext(new_key, 1, 26) + holder.fakekey = new_key + holder.big_brother = 1 + createStealthKey() + log_admin("[key_name(usr)] has turned BB mode [holder.fakekey ? "ON" : "OFF"]") + feedback_add_details("admin_verb","BBSM") + #define MAX_WARNS 3 #define AUTOBANTIME 10 diff --git a/code/modules/admin/buildmode.dm b/code/modules/admin/buildmode.dm index b7b2a0d3683..ebe37bc9697 100644 --- a/code/modules/admin/buildmode.dm +++ b/code/modules/admin/buildmode.dm @@ -3,239 +3,302 @@ #define VAR_BUILDMODE 3 #define THROW_BUILDMODE 4 #define AREA_BUILDMODE 5 -#define NUM_BUILDMODES 5 +#define COPY_BUILDMODE 6 +#define NUM_BUILDMODES 6 + +/obj/screen/buildmode + icon = 'icons/misc/buildmode.dmi' + var/datum/click_intercept/buildmode/bd + +/obj/screen/buildmode/New(bld) + ..() + bd = bld + +/obj/screen/buildmode/mode + name = "Toggle Mode" + icon_state = "buildmode1" + screen_loc = "NORTH,WEST" + +/obj/screen/buildmode/mode/Click(location, control, params) + var/list/pa = params2list(params) + + if(pa.Find("left")) + bd.toggle_modes() + else if(pa.Find("right")) + bd.change_settings(usr) + update_icon() + return 1 + +/obj/screen/buildmode/mode/update_icon() + icon_state = "buildmode[bd.mode]" + return + +/obj/screen/buildmode/help + icon_state = "buildhelp" + screen_loc = "NORTH,WEST+1" + name = "Buildmode Help" + +/obj/screen/buildmode/help/Click() + bd.show_help(usr) + return 1 + +/obj/screen/buildmode/bdir + icon_state = "build" + screen_loc = "NORTH,WEST+2" + name = "Change Dir" + +/obj/screen/buildmode/bdir/update_icon() + dir = bd.build_dir + return + +/obj/screen/buildmode/bdir/Click() + bd.change_dir() + update_icon() + return 1 + +/obj/screen/buildmode/quit + icon_state = "buildquit" + screen_loc = "NORTH,WEST+3" + name = "Quit Buildmode" + +/obj/screen/buildmode/quit/Click() + bd.quit() + return 1 + +/obj/screen/buildmode/dir/Click() + bd.change_dir() + update_icon() + return 1 + +/obj/effect/buildmode_reticule + var/image/I + var/client/cl + +/obj/effect/buildmode_reticule/New(var/turf/t, var/client/c) + loc = t + I = image('icons/mob/blob.dmi', t, "marker",19.0,2) // Sprite reuse wooo + cl = c + cl.images += I + +/obj/effect/buildmode_reticule/proc/deselect() + qdel(src) + +/obj/effect/buildmode_reticule/Destroy() + cl.images -= I + cl = null + qdel(I) + +/datum/click_intercept + var/client/holder = null + var/list/obj/screen/buttons = list() + +/datum/click_intercept/New(client/c) + create_buttons() + holder = c + holder.click_intercept = src + holder.show_popup_menus = 0 + holder.screen += buttons + +/datum/click_intercept/Destroy() + for(var/button in buttons) + qdel(button) + + +/datum/click_intercept/proc/create_buttons() + return + +/datum/click_intercept/proc/InterceptClickOn(user,params,atom/object) + return + +/datum/click_intercept/proc/quit() + holder.screen -= buttons + holder.click_intercept = null + holder.show_popup_menus = 1 + qdel(src) + + + +/datum/click_intercept/buildmode + var/mode = BASIC_BUILDMODE + var/build_dir = SOUTH + var/atom/movable/throw_atom = null + var/obj/effect/buildmode_reticule/cornerA = null + var/obj/effect/buildmode_reticule/cornerB = null + var/generator_path = null + var/varholder = "name" + var/valueholder = "derp" + var/objholder = /obj/structure/closet + var/atom/movable/stored = null + +/datum/click_intercept/buildmode/Destroy() + stored = null + Reset() + ..() + +/datum/click_intercept/buildmode/create_buttons() + buttons += new /obj/screen/buildmode/mode(src) + buttons += new /obj/screen/buildmode/help(src) + buttons += new /obj/screen/buildmode/bdir(src) + buttons += new /obj/screen/buildmode/quit(src) + +/datum/click_intercept/buildmode/proc/toggle_modes() + mode = (mode % NUM_BUILDMODES) +1 + Reset() + return + +/datum/click_intercept/buildmode/proc/show_help(mob/user) + switch(mode) + if(BASIC_BUILDMODE) + user << "***********************************************************" + user << "Left Mouse Button = Construct / Upgrade" + user << "Right Mouse Button = Deconstruct / Delete / Downgrade" + user << "Left Mouse Button + ctrl = R-Window" + user << "Left Mouse Button + alt = Airlock" + user << "" + user << "Use the button in the upper left corner to" + user << "change the direction of built objects." + user << "***********************************************************" + if(ADV_BUILDMODE) + user << "***********************************************************" + user << "Right Mouse Button on buildmode button = Set object type" + user << "Left Mouse Button on turf/obj = Place objects" + user << "Right Mouse Button = Delete objects" + user << "" + user << "Use the button in the upper left corner to" + user << "change the direction of built objects." + user << "***********************************************************" + if(VAR_BUILDMODE) + user << "***********************************************************" + user << "Right Mouse Button on buildmode button = Select var(type) & value" + user << "Left Mouse Button on turf/obj/mob = Set var(type) & value" + user << "Right Mouse Button on turf/obj/mob = Reset var's value" + user << "***********************************************************" + if(THROW_BUILDMODE) + user << "***********************************************************" + user << "Left Mouse Button on turf/obj/mob = Select" + user << "Right Mouse Button on turf/obj/mob = Throw" + user << "***********************************************************" + if(AREA_BUILDMODE) + user << "***********************************************************" + user << "Left Mouse Button on turf/obj/mob = Select corner" + user << "Right Mouse Button on buildmode button = Select generator" + user << "***********************************************************" + if(COPY_BUILDMODE) + user << "***********************************************************" + user << "Left Mouse Button on obj/turf/mob = Spawn a Copy of selected target" + user << "Right Mouse Button on obj/mob = Select target to copy" + user << "***********************************************************" + +/datum/click_intercept/buildmode/proc/change_settings(mob/user) + switch(mode) + if(BASIC_BUILDMODE) + + return 1 + if(ADV_BUILDMODE) + var/target_path = input(user,"Enter typepath:" ,"Typepath","/obj/structure/closet") + objholder = text2path(target_path) + if(!ispath(objholder)) + objholder = pick_closest_path(target_path) + if(!objholder) + objholder = /obj/structure/closet + alert("That path is not allowed.") + else + if(ispath(objholder,/mob) && !check_rights(R_DEBUG,0)) + objholder = /obj/structure/closet + if(VAR_BUILDMODE) + var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "viruses", "cuffed", "ka", "last_eaten", "urine") + + varholder = input(user,"Enter variable name:" ,"Name", "name") + if(varholder in locked && !check_rights(R_DEBUG,0)) + + return 1 + var/thetype = input(user,"Select variable type:" ,"Type") in list("text","number","mob-reference","obj-reference","turf-reference") + if(!thetype) return 1 + switch(thetype) + if("text") + valueholder = input(user,"Enter variable value:" ,"Value", "value") as text + if("number") + valueholder = input(user,"Enter variable value:" ,"Value", 123) as num + if("mob-reference") + valueholder = input(user,"Enter variable value:" ,"Value") as mob in mob_list + if("obj-reference") + valueholder = input(user,"Enter variable value:" ,"Value") as obj in world + if("turf-reference") + valueholder = input(user,"Enter variable value:" ,"Value") as turf in world + if(AREA_BUILDMODE) + var/list/gen_paths = subtypesof(/datum/mapGenerator) + + var/type = input(user,"Select Generator Type","Type") as null|anything in gen_paths + if(!type) return + + generator_path = type + cornerA = null + cornerB = null + +/datum/click_intercept/buildmode/proc/change_dir() + switch(build_dir) + if(NORTH) + build_dir = EAST + if(EAST) + build_dir = SOUTH + if(SOUTH) + build_dir = WEST + if(WEST) + build_dir = NORTHWEST + if(NORTHWEST) + build_dir = NORTH + return 1 + +/datum/click_intercept/buildmode/proc/deselect_region() + qdel(cornerA) + cornerA = null + qdel(cornerB) + cornerB = null + +/datum/click_intercept/buildmode/proc/Reset()//Reset temporary variables + deselect_region() + +/datum/click_intercept/buildmode/proc/select_tile(var/turf/T) + return new /obj/effect/buildmode_reticule(T, holder) /proc/togglebuildmode(mob/M as mob in player_list) set name = "Toggle Build Mode" set category = "Special Verbs" if(M.client) - if(M.client.buildmode) + if(istype(M.client.click_intercept,/datum/click_intercept/buildmode)) + var/datum/click_intercept/buildmode/B = M.client.click_intercept + B.quit() log_admin("[key_name(usr)] has left build mode.") - M.client.buildmode = 0 - M.client.show_popup_menus = 1 - for(var/obj/effect/bmode/buildholder/H) - if(H.cl == M.client) - qdel(H) else - message_admins("[key_name_admin(usr)] has entered build mode.") + new/datum/click_intercept/buildmode(M.client) + message_admins("[key_name(usr)] has entered build mode.") log_admin("[key_name(usr)] has entered build mode.") - M.client.buildmode = 1 - M.client.show_popup_menus = 0 - var/obj/effect/bmode/buildholder/H = new/obj/effect/bmode/buildholder() - var/obj/effect/bmode/builddir/A = new/obj/effect/bmode/builddir(H) - A.master = H - var/obj/effect/bmode/buildhelp/B = new/obj/effect/bmode/buildhelp(H) - B.master = H - var/obj/effect/bmode/buildmode/C = new/obj/effect/bmode/buildmode(H) - C.master = H - var/obj/effect/bmode/buildquit/D = new/obj/effect/bmode/buildquit(H) - D.master = H - - H.builddir = A - H.buildhelp = B - H.buildmode = C - H.buildquit = D - M.client.screen += A - M.client.screen += B - M.client.screen += C - M.client.screen += D - H.cl = M.client - -/obj/effect/bmode //Cleaning up the tree a bit - density = 1 - anchored = 1 - layer = 20 - dir = NORTH - icon = 'icons/misc/buildmode.dmi' - var/obj/effect/bmode/buildholder/master = null - -/obj/effect/bmode/Destroy() - if(master && master.cl) - master.cl.screen -= src - master = null - return ..() - -/obj/effect/bmode/builddir - icon_state = "build" - screen_loc = "NORTH,WEST" - -/obj/effect/bmode/Click() - switch(dir) - if(NORTH) - dir = EAST - if(EAST) - dir = SOUTH - if(SOUTH) - dir = WEST - if(WEST) - dir = SOUTHWEST - if(SOUTHWEST) - dir = NORTH - return 1 - -/obj/effect/bmode/buildhelp - icon = 'icons/misc/buildmode.dmi' - icon_state = "buildhelp" - screen_loc = "NORTH,WEST+1" - -/obj/effect/bmode/buildhelp/Click() - switch(master.cl.buildmode) - if(BASIC_BUILDMODE) - usr << "\blue ***********************************************************" - usr << "\blue Left Mouse Button = Construct / Upgrade" - usr << "\blue Right Mouse Button = Deconstruct / Delete / Downgrade" - usr << "\blue Left Mouse Button + ctrl = R-Window" - usr << "\blue Left Mouse Button + alt = Airlock" - usr << "" - usr << "\blue Use the button in the upper left corner to" - usr << "\blue change the direction of built objects." - usr << "\blue ***********************************************************" - if(ADV_BUILDMODE) - usr << "\blue ***********************************************************" - usr << "\blue Right Mouse Button on buildmode button = Set object type" - usr << "\blue Left Mouse Button on turf/obj = Place objects" - usr << "\blue Right Mouse Button = Delete objects" - usr << "" - usr << "\blue Use the button in the upper left corner to" - usr << "\blue change the direction of built objects." - usr << "\blue ***********************************************************" - if(VAR_BUILDMODE) - usr << "\blue ***********************************************************" - usr << "\blue Right Mouse Button on buildmode button = Select var(type) & value" - usr << "\blue Left Mouse Button on turf/obj/mob = Set var(type) & value" - usr << "\blue Right Mouse Button on turf/obj/mob = Reset var's value" - usr << "\blue ***********************************************************" - if(THROW_BUILDMODE) - usr << "\blue ***********************************************************" - usr << "\blue Left Mouse Button on turf/obj/mob = Select" - usr << "\blue Right Mouse Button on turf/obj/mob = Throw" - usr << "\blue ***********************************************************" - if(AREA_BUILDMODE) - usr << "\blue ***********************************************************" - usr << "\blue Left Mouse Button on turf/obj/mob = Select corner" - usr << "\blue Right Mouse Button on buildmode button = Select generator" - usr << "\blue ***********************************************************" - return 1 - -/obj/effect/bmode/buildquit - icon_state = "buildquit" - screen_loc = "NORTH,WEST+3" - -/obj/effect/bmode/buildquit/Click() - togglebuildmode(master.cl.mob) - return 1 - -/obj/effect/bmode/buildholder - density = 0 - anchored = 1 - var/client/cl = null - var/obj/effect/bmode/builddir/builddir = null - var/obj/effect/bmode/buildhelp/buildhelp = null - var/obj/effect/bmode/buildmode/buildmode = null - var/obj/effect/bmode/buildquit/buildquit = null - var/atom/movable/throw_atom = null - var/turf/cornerA = null - var/turf/cornerB = null - var/generator_path = null - -/obj/effect/bmode/buildholder/Destroy() - qdel(builddir) - builddir = null - qdel(buildhelp) - buildhelp = null - qdel(buildmode) - buildmode = null - qdel(buildquit) - buildquit = null - throw_atom = null - cl = null - return ..() - -/obj/effect/bmode/buildmode - icon_state = "buildmode1" - screen_loc = "NORTH,WEST+2" - var/varholder = "name" - var/valueholder = "derp" - var/objholder = /obj/structure/closet - -/obj/effect/bmode/buildmode/Click(location, control, params) +/datum/click_intercept/buildmode/InterceptClickOn(user,params,atom/object) //Click Intercept var/list/pa = params2list(params) + var/right_click = pa.Find("right") + var/left_click = pa.Find("left") + var/alt_click = pa.Find("alt") + var/ctrl_click = pa.Find("ctrl") - if(pa.Find("left")) - master.cl.buildmode = (master.cl.buildmode % NUM_BUILDMODES) +1 - src.icon_state = "buildmode[master.cl.buildmode]" - - else if(pa.Find("right")) - switch(master.cl.buildmode) - if(BASIC_BUILDMODE) - return 1 - if(ADV_BUILDMODE) - objholder = text2path(input(usr,"Enter typepath:" ,"Typepath","/obj/structure/closet")) - if(!ispath(objholder)) - objholder = /obj/structure/closet - alert("That path is not allowed.") - else - if(ispath(objholder,/mob) && !check_rights(R_DEBUG,0)) - objholder = /obj/structure/closet - if(VAR_BUILDMODE) - var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "viruses", "cuffed", "ka", "last_eaten", "urine") - - master.buildmode.varholder = input(usr,"Enter variable name:" ,"Name", "name") - if(master.buildmode.varholder in locked && !check_rights(R_DEBUG,0)) - return 1 - var/thetype = input(usr,"Select variable type:" ,"Type") in list("text","number","mob-reference","obj-reference","turf-reference") - if(!thetype) return 1 - switch(thetype) - if("text") - master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value", "value") as text - if("number") - master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value", 123) as num - if("mob-reference") - master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as mob in mob_list - if("obj-reference") - master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as obj in world - if("turf-reference") - master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as turf in world - if(AREA_BUILDMODE) - var/list/gen_paths = subtypesof(/datum/mapGenerator) - - var/type = input(usr,"Select Generator Type","Type") as null|anything in gen_paths - if(!type) return - - master.generator_path = type - return 1 - - -/proc/build_click(var/mob/user, buildmode, params, var/obj/object) - var/obj/effect/bmode/buildholder/holder = null - for(var/obj/effect/bmode/buildholder/H) - if(H.cl == user.client) - holder = H - break - if(!holder) return - var/list/pa = params2list(params) - - if(istype(object,/obj/effect/bmode)) - return - - switch(buildmode) + . = 1 + switch(mode) if(BASIC_BUILDMODE) - if(istype(object,/turf) && pa.Find("left") && !pa.Find("alt") && !pa.Find("ctrl") ) + if(istype(object,/turf) && left_click && !alt_click && !ctrl_click) var/turf/T = object if(istype(object,/turf/space)) - T.ChangeTurf(/turf/simulated/floor) + T.ChangeTurf(/turf/simulated/floor/plasteel) else if(istype(object,/turf/simulated/floor)) T.ChangeTurf(/turf/simulated/wall) else if(istype(object,/turf/simulated/wall)) T.ChangeTurf(/turf/simulated/wall/r_wall) - log_admin("Build Mode: [key_name(usr)] built [T] at ([T.x],[T.y],[T.z])") + log_admin("Build Mode: [key_name(user)] built [T] at ([T.x],[T.y],[T.z])") return - else if(pa.Find("right")) - log_admin("Build Mode: [key_name(usr)] deleted [object] at ([object.x],[object.y],[object.z])") + else if(right_click) + log_admin("Build Mode: [key_name(user)] deleted [object] at ([object.x],[object.y],[object.z])") if(istype(object,/turf/simulated/wall)) var/turf/T = object - T.ChangeTurf(/turf/simulated/floor) + T.ChangeTurf(/turf/simulated/floor/plasteel) else if(istype(object,/turf/simulated/floor)) var/turf/T = object T.ChangeTurf(/turf/space) @@ -245,11 +308,11 @@ else if(istype(object,/obj)) qdel(object) return - else if(istype(object,/turf) && pa.Find("alt") && pa.Find("left")) - log_admin("Build Mode: [key_name(usr)] built an airlock at ([object.x],[object.y],[object.z])") + else if(istype(object,/turf) && alt_click && left_click) + log_admin("Build Mode: [key_name(user)] built an airlock at ([object.x],[object.y],[object.z])") new/obj/machinery/door/airlock(get_turf(object)) - else if(istype(object,/turf) && pa.Find("ctrl") && pa.Find("left")) - switch(holder.builddir.dir) + else if(istype(object,/turf) && ctrl_click && left_click) + switch(build_dir) if(NORTH) var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object)) WIN.dir = NORTH @@ -262,76 +325,74 @@ if(WEST) var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object)) WIN.dir = WEST - if(SOUTHWEST) - new/obj/structure/window/full/reinforced(get_turf(object)) - log_admin("Build Mode: [key_name(usr)] built a window at ([object.x],[object.y],[object.z])") + if(NORTHWEST) + var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object)) + WIN.dir = NORTHWEST + log_admin("Build Mode: [key_name(user)] built a window at ([object.x],[object.y],[object.z])") + if(ADV_BUILDMODE) - if(pa.Find("left")) - if(ispath(holder.buildmode.objholder,/turf)) + if(left_click) + if(ispath(objholder,/turf)) var/turf/T = get_turf(object) - log_admin("Build Mode: [key_name(usr)] modified [T] ([T.x],[T.y],[T.z]) to [holder.buildmode.objholder]") - T.ChangeTurf(holder.buildmode.objholder) + log_admin("Build Mode: [key_name(user)] modified [T] ([T.x],[T.y],[T.z]) to [objholder]") + T.ChangeTurf(objholder) else - var/obj/A = new holder.buildmode.objholder (get_turf(object)) - A.dir = holder.builddir.dir - log_admin("Build Mode: [key_name(usr)] modified [A]'s ([A.x],[A.y],[A.z]) dir to [holder.builddir.dir]") - else if(pa.Find("right")) + var/obj/A = new objholder (get_turf(object)) + A.dir = build_dir + log_admin("Build Mode: [key_name(user)] modified [A]'s ([A.x],[A.y],[A.z]) dir to [build_dir]") + else if(right_click) if(isobj(object)) - log_admin("Build Mode: [key_name(usr)] deleted [object] at ([object.x],[object.y],[object.z])") + log_admin("Build Mode: [key_name(user)] deleted [object] at ([object.x],[object.y],[object.z])") qdel(object) if(VAR_BUILDMODE) - if(pa.Find("left")) //I cant believe this shit actually compiles. - if(object.vars.Find(holder.buildmode.varholder)) - log_admin("[key_name(usr)] modified [object.name]'s [holder.buildmode.varholder] to [holder.buildmode.valueholder]") - object.vars[holder.buildmode.varholder] = holder.buildmode.valueholder + if(left_click) //I cant believe this shit actually compiles. + if(object.vars.Find(varholder)) + log_admin("Build Mode: [key_name(user)] modified [object.name]'s [varholder] to [valueholder]") + object.vars[varholder] = valueholder else - usr << "[initial(object.name)] does not have a var called '[holder.buildmode.varholder]'" - if(pa.Find("right")) - if(object.vars.Find(holder.buildmode.varholder)) - log_admin("[key_name(usr)] modified [object.name]'s [holder.buildmode.varholder] to [holder.buildmode.valueholder]") - object.vars[holder.buildmode.varholder] = initial(object.vars[holder.buildmode.varholder]) + user << "[initial(object.name)] does not have a var called '[varholder]'" + if(right_click) + if(object.vars.Find(varholder)) + log_admin("Build Mode: [key_name(user)] modified [object.name]'s [varholder] to [valueholder]") + object.vars[varholder] = initial(object.vars[varholder]) else - usr << "[initial(object.name)] does not have a var called '[holder.buildmode.varholder]'" + user << "[initial(object.name)] does not have a var called '[varholder]'" if(THROW_BUILDMODE) - if(pa.Find("left")) + if(left_click) if(isturf(object)) return - holder.throw_atom = object - if(pa.Find("right")) - if(holder.throw_atom) - holder.throw_atom.throw_at(object, 10, 1) - log_admin("Build Mode: [key_name(usr)] threw [holder.throw_atom] at [object] ([object.x],[object.y],[object.z])") + throw_atom = object + if(right_click) + if(throw_atom) + throw_atom.throw_at(object, 10, 1,user) + log_admin("Build Mode: [key_name(user)] threw [throw_atom] at [object] ([object.x],[object.y],[object.z])") if(AREA_BUILDMODE) - if(!holder.cornerA) - holder.cornerA = get_turf(object) + if(!cornerA) + cornerA = select_tile(get_turf(object)) return - if(holder.cornerA && !holder.cornerB) - holder.cornerB = get_turf(object) + if(cornerA && !cornerB) + cornerB = select_tile(get_turf(object)) + if(left_click) //rectangular + if(cornerA && cornerB) + if(!generator_path) + user << "Select generator type first." + else + var/datum/mapGenerator/G = new generator_path + G.defineRegion(cornerA.loc,cornerB.loc,1) + G.generate() + deselect_region() + return - if(pa.Find("left")) //rectangular - if(holder.cornerA && holder.cornerB) - if(!holder.generator_path) - usr << "Select generator type first." - var/datum/mapGenerator/G = new holder.generator_path - G.defineRegion(holder.cornerA,holder.cornerB,1) - G.generate() - holder.cornerA = null - holder.cornerB = null - return - /* Something wrong with this, will check later - if(pa.Find("right")) // circular - if(holder.cornerA && holder.cornerB) - if(!holder.generator_path) - usr << "Select generator type first." - var/datum/mapGenerator/G = new holder.generator_path - G.defineCircularRegion(holder.cornerA,holder.cornerB,1) - G.generate() - holder.cornerA = null - holder.cornerB = null - return - */ //Something wrong - Reset - holder.cornerA = null - holder.cornerB = null \ No newline at end of file + deselect_region() + if(COPY_BUILDMODE) + if(left_click) + var/turf/T = get_turf(object) + if(stored) + DuplicateObject(stored, perfectcopy=1, sameloc=0,newloc=T) + else if(right_click) + if(ismovableatom(object)) // No copying turfs for now. + user << "[object] set as template." + stored = object diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm index 9a62cc44a34..572dfdbcf01 100644 --- a/code/modules/admin/holder2.dm +++ b/code/modules/admin/holder2.dm @@ -5,6 +5,7 @@ var/list/admin_datums = list() var/client/owner = null var/rights = 0 var/fakekey = null + var/big_brother = 0 var/datum/marked_datum diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index f263515d986..26813c0ba91 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -680,6 +680,12 @@ else jobs += "[replacetext("Cultist", " ", " ")]" + //Shadowling + if(jobban_isbanned(M, "shadowling") || isbanned_dept) + jobs += "[replacetext("Shadowling", " ", " ")]" + else + jobs += "[replacetext("Shadowling", " ", " ")]" + //Wizard if(jobban_isbanned(M, "wizard") || isbanned_dept) jobs += "[replacetext("Wizard", " ", " ")]" diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 902257ae2db..b8a6f370834 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -15,13 +15,13 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey"," adminhelped = 1 //Determines if they get the message to reply by clicking the name. var/msg - var/list/type = list("Question","Player Complaint") + var/list/type = list("Mentorhelp","Adminhelp") var/selected_type = input("Pick a category.", "Admin Help", null, null) as null|anything in type if(selected_type) msg = input("Please enter your message.", "Admin Help", null, null) as text|null - //clean the input msg - if(!msg) + //clean the input msg + if(!msg) return if(src.handle_spam_prevention(msg,MUTE_ADMINHELP)) @@ -88,7 +88,6 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey"," var/ref_mob = "\ref[mob]" var/ref_client = "\ref[src]" - msg = "\blue [selected_type]: [key_name(src, 1, 1, selected_type)] (?) (PP) (VV) (SM) ([admin_jump_link(mob, "holder")]) (CA) (REJT) [ai_found ? " (CL)" : ""]: [msg]" //send this msg to all admins var/admin_number_afk = 0 @@ -109,19 +108,21 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey"," continue switch(selected_type) - if("Question") + if("Mentorhelp") + msg = "[selected_type]: [key_name(src, 1, 1, selected_type)] (?) (PP) (VV) (SM) ([admin_jump_link(mob, "holder")]) (CA) (REJT) [ai_found ? " (CL)" : ""]: [msg]" for(var/client/X in mentorholders + modholders + adminholders) if(X.prefs.sound & SOUND_ADMINHELP) X << 'sound/effects/adminhelp.ogg' X << msg - if("Player Complaint") + if("Adminhelp") + msg = "[selected_type]: [key_name(src, 1, 1, selected_type)] (?) (PP) (VV) (SM) ([admin_jump_link(mob, "holder")]) (CA) (REJT) [ai_found ? " (CL)" : ""]: [msg]" for(var/client/X in modholders + adminholders) if(X.prefs.sound & SOUND_ADMINHELP) X << 'sound/effects/adminhelp.ogg' X << msg //show it to the person adminhelping too - src << "[selected_type]: [original_msg]" + src << "[selected_type]
    : [original_msg]" var/admin_number_present = adminholders.len - admin_number_afk log_admin("[selected_type]: [key_name(src)]: [original_msg] - heard by [admin_number_present] non-AFK admins.") @@ -161,4 +162,3 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey"," else send2irc(source, "[msg] - All admins AFK ([admin_number_afk]/[admin_number_total]) or skipped ([admin_number_ignored]/[admin_number_total])") return admin_number_present - \ No newline at end of file diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index 93cff752e0b..18fc3ef07c7 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -67,17 +67,17 @@ if(istext(whom)) if(cmptext(copytext(whom,1,2),"@")) whom = findStealthKey(whom) - C = directory[C] + C = directory[C] else if(istype(whom,/client)) C = whom - + if(!C) - if(holder) + if(holder) src << "Error: Private-Message: Client not found." - else + else adminhelp(msg) //admin we are replying to left. adminhelp instead return - + /*if(C && C.last_pm_recieved + config.simultaneous_pm_warning_timeout > world.time && holder) //send a warning to admins, but have a delay popup for mods if(holder.rights & R_ADMIN) @@ -90,12 +90,12 @@ if(!msg) msg = input(src,"Message:", "Private message to [key_name(C, 0, 0)]") as text|null - if(!msg) + if(!msg) return if(!C) - if(holder) + if(holder) src << "Error: Admin-PM: Client not found." - else + else adminhelp(msg) //admin we are replying to has vanished, adminhelp instead return @@ -105,10 +105,10 @@ //clean the message if it's not sent by a high-rank admin if(!check_rights(R_SERVER|R_DEBUG,0)) msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN)) - if(!msg) + if(!msg) return - var/recieve_color = "purple" + var/recieve_span = "playerreply" var/send_pm_type = " " var/recieve_pm_type = "Player" @@ -118,9 +118,9 @@ //PMs sent from admins and mods display their rank if(holder) if(check_rights(R_MOD|R_MENTOR,0) && !check_rights(R_ADMIN,0)) - recieve_color = "maroon" + recieve_span = "mentorhelp" else - recieve_color = "red" + recieve_span = "adminhelp" send_pm_type = holder.rank + " " recieve_pm_type = holder.rank @@ -131,7 +131,7 @@ var/recieve_message = "" if(holder && !C.holder) - recieve_message = "-- Click the [recieve_pm_type]'s name to reply --\n" + recieve_message = "-- Click the [recieve_pm_type]'s name to reply --\n" if(C.adminhelped) C << recieve_message C.adminhelped = 0 @@ -149,7 +149,7 @@ adminhelp(reply) //sender has left, adminhelp instead return - recieve_message = "[type] from-[recieve_pm_type][key_name(src, C, C.holder ? 1 : 0, type)]: [msg]" + recieve_message = "[type] from-[recieve_pm_type][key_name(src, C, C.holder ? 1 : 0, type)]: [msg]" C << recieve_message src << "[send_pm_type][type] to-[key_name(C, src, holder ? 1 : 0, type)]: [msg]" @@ -162,57 +162,6 @@ if(C.prefs.sound & SOUND_ADMINHELP) C << 'sound/effects/adminhelp.ogg' - /* - if(C.holder) - if(holder) //both are admins - if(holder.rank == "Moderator") //If moderator - C << "Mod PM from-[key_name(src, C, 1)]: [msg]" - src << "Mod PM to-[key_name(C, src, 1)]: [msg]" - else - C << "Admin PM from-[key_name(src, C, 1)]: [msg]" - src << "Admin PM to-[key_name(C, src, 1)]: [msg]" - - else //recipient is an admin but sender is not - C << "Reply PM from-[key_name(src, C, 1)]: [msg]" - src << "PM to-Admins: [msg]" - - //play the recieving admin the adminhelp sound (if they have them enabled) - if(C.prefs.toggles & SOUND_ADMINHELP) - C << 'sound/effects/adminhelp.ogg' - - else - if(holder) //sender is an admin but recipient is not. Do BIG RED TEXT - if(holder.rank == "Moderator") - C << "Mod PM from-[key_name(src, C, 0)]: [msg]" - C << "Click on the moderators's name to reply." - src << "Mod PM to-[key_name(C, src, 1)]: [msg]" - else - C << "-- Administrator private message --" - C << "Admin PM from-[key_name(src, C, 0)]: [msg]" - C << "Click on the administrator's name to reply." - src << "Admin PM to-[key_name(C, src, 1)]: [msg]" - - //always play non-admin recipients the adminhelp sound - C << 'sound/effects/adminhelp.ogg' - - //AdminPM popup for ApocStation and anybody else who wants to use it. Set it with POPUP_ADMIN_PM in config.txt ~Carn - if(config.popup_admin_pm) - spawn() //so we don't hold the caller proc up - var/sender = src - var/sendername = key - var/reply = input(C, msg,"Admin PM from-[sendername]", "") as text|null //show message and await a reply - if(C && reply) - if(sender) - C.cmd_admin_pm(sender,reply) //sender is still about, let's reply to them - else - adminhelp(reply) //sender has left, adminhelp instead - return - - else //neither are admins - src << "Error: Admin-PM: Non-admin to non-admin PM communication is forbidden." - return - */ - log_admin("PM: [key_name(src)]->[key_name(C)]: [msg]") //we don't use message_admins here because the sender/receiver might get it too for(var/client/X in admins) @@ -221,15 +170,15 @@ continue if(X.key != key && X.key != C.key) switch(type) - if("Question") + if("Mentorhelp") if(check_rights(R_ADMIN|R_MOD|R_MENTOR, 0, X.mob)) - X << "[type]: [key_name(src, X, 0, type)]->[key_name(C, X, 0, type)]: \blue [msg]" - if("Player Complaint") + X << "[type]: [key_name(src, X, 0, type)]->[key_name(C, X, 0, type)]: [msg]" + if("Adminhelp") if(check_rights(R_ADMIN|R_MOD, 0, X.mob)) - X << "[type]: [key_name(src, X, 0, type)]->[key_name(C, X, 0, type)]: \blue [msg]" + X << "[type]: [key_name(src, X, 0, type)]->[key_name(C, X, 0, type)]: [msg]" else if(check_rights(R_ADMIN|R_MOD, 0, X.mob)) - X << "[type]: [key_name(src, X, 0, type)]->[key_name(C, X, 0, type)]: \blue [msg]" + X << "[type]: [key_name(src, X, 0, type)]->[key_name(C, X, 0, type)]: [msg]" /client/proc/cmd_admin_irc_pm() if(prefs.muted & MUTE_ADMINHELP) diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm index 134cc9ff3f5..f4f348bb72a 100644 --- a/code/modules/admin/verbs/modifyvariables.dm +++ b/code/modules/admin/verbs/modifyvariables.dm @@ -26,13 +26,10 @@ var/list/forbidden_varedit_object_types = list( /client/proc/mod_list_add_ass() //haha var/class = "text" + var/list/allowed_types = list("text", "num","type", "type from text","reference","mob reference", "icon","file","list","edit referenced object","restore to default") if(src.holder && src.holder.marked_datum) - class = input("What kind of variable?","Variable Type") as null|anything in list("text", - "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default","marked datum ([holder.marked_datum.type])") - else - class = input("What kind of variable?","Variable Type") as null|anything in list("text", - "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default") - + allowed_types += "marked datum ([holder.marked_datum.type])" + class = input("What kind of variable?","Variable Type") as null|anything in allowed_types if(!class) return @@ -52,6 +49,12 @@ var/list/forbidden_varedit_object_types = list( if("type") var_value = input("Enter type:","Type") as null|anything in typesof(/obj,/mob,/area,/turf) + if("type from text") + var/type_text = input("Enter type:", "Type") as null|message + var_value = text2path(type_text) + if(!var_value) + src << "[type_text] is not a valid path!" + if("reference") var_value = input("Select reference:","Reference") as null|mob|obj|turf|area in world @@ -75,12 +78,10 @@ var/list/forbidden_varedit_object_types = list( /client/proc/mod_list_add(var/list/L) var/class = "text" + var/list/allowed_types = list("text", "num","type", "type from text","reference","mob reference", "icon","file","list","edit referenced object","restore to default") if(src.holder && src.holder.marked_datum) - class = input("What kind of variable?","Variable Type") as null|anything in list("text", - "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default","marked datum ([holder.marked_datum.type])") - else - class = input("What kind of variable?","Variable Type") as null|anything in list("text", - "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default") + allowed_types += "marked datum ([holder.marked_datum.type])" + class = input("What kind of variable?","Variable Type") as null|anything in allowed_types if(!class) return @@ -101,6 +102,12 @@ var/list/forbidden_varedit_object_types = list( if("type") var_value = input("Enter type:","Type") in typesof(/obj,/mob,/area,/turf) + if("type from text") + var/type_text = input("Enter type:", "Type") as null|message + var_value = text2path(type_text) + if(!var_value) + src << "[type_text] is not a valid path!" + if("reference") var_value = input("Select reference:","Reference") as mob|obj|turf|area in world @@ -173,75 +180,21 @@ var/list/forbidden_varedit_object_types = list( if(variable in locked) if(!check_rights(R_DEBUG)) return - if(isnull(variable)) - usr << "Unable to determine variable type." - - else if(isnum(variable)) - usr << "Variable appears to be NUM." - default = "num" - dir = 1 - - else if(istext(variable)) - usr << "Variable appears to be TEXT." - default = "text" - - else if(isloc(variable)) - usr << "Variable appears to be REFERENCE." - default = "reference" - - else if(isicon(variable)) - usr << "Variable appears to be ICON." - variable = "\icon[variable]" - default = "icon" - - else if(istype(variable,/atom) || istype(variable,/datum)) - usr << "Variable appears to be TYPE." - default = "type" - - else if(istype(variable,/list)) - usr << "Variable appears to be LIST." - default = "list" - - else if(istype(variable,/client)) - usr << "Variable appears to be CLIENT." - default = "cancel" - - else - usr << "Variable appears to be FILE." - default = "file" + default = variable_to_type(variable) usr << "Variable contains: [variable]" - if(dir) - switch(variable) - if(1) - dir = "NORTH" - if(2) - dir = "SOUTH" - if(4) - dir = "EAST" - if(8) - dir = "WEST" - if(5) - dir = "NORTHEAST" - if(6) - dir = "SOUTHEAST" - if(9) - dir = "NORTHWEST" - if(10) - dir = "SOUTHWEST" - else - dir = null + if(default == "num") + dir = dir2text(variable) if(dir) usr << "If a direction, direction is: [dir]" var/class = "text" + var/list/allowed_types = list("text", "num","type", "type from text", "reference","mob reference", "icon","file","list","edit referenced object","restore to default","DELETE FROM LIST") if(src.holder && src.holder.marked_datum) - class = input("What kind of variable?","Variable Type",default) as null|anything in list("text", - "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default","marked datum ([holder.marked_datum.type])", "DELETE FROM LIST") - else - class = input("What kind of variable?","Variable Type",default) as null|anything in list("text", - "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default", "DELETE FROM LIST") + allowed_types += "marked datum ([holder.marked_datum.type])" + + class = input("What kind of variable?","Variable Type",default) as null|anything in allowed_types if(!class) return @@ -325,7 +278,7 @@ var/list/forbidden_varedit_object_types = list( if( istype(O,p) ) usr << "It is forbidden to edit this object's variables." return - + if(istype(O, /client) && (param_var_name == "ckey" || param_var_name == "key")) usr << "You cannot edit ckeys on client objects." return @@ -347,44 +300,11 @@ var/list/forbidden_varedit_object_types = list( var_value = O.vars[variable] if(autodetect_class) - if(isnull(var_value)) - usr << "Unable to determine variable type." - class = null + class = variable_to_type(var_value) + if(!class) autodetect_class = null - else if(isnum(var_value)) - usr << "Variable appears to be NUM." - class = "num" + else if(class == "num") dir = 1 - - else if(istext(var_value)) - usr << "Variable appears to be TEXT." - class = "text" - - else if(isloc(var_value)) - usr << "Variable appears to be REFERENCE." - class = "reference" - - else if(isicon(var_value)) - usr << "Variable appears to be ICON." - var_value = "\icon[var_value]" - class = "icon" - - else if(istype(var_value,/atom) || istype(var_value,/datum)) - usr << "Variable appears to be TYPE." - class = "type" - - else if(istype(var_value,/list)) - usr << "Variable appears to be LIST." - class = "list" - - else if(istype(var_value,/client)) - usr << "Variable appears to be CLIENT." - class = "cancel" - - else - usr << "Variable appears to be FILE." - class = "file" - else var/list/names = list() @@ -404,73 +324,23 @@ var/list/forbidden_varedit_object_types = list( var/dir var/default - if(isnull(var_value)) - usr << "Unable to determine variable type." - - else if(isnum(var_value)) - usr << "Variable appears to be NUM." - default = "num" + default = variable_to_type(var_value) + if(default == "num") dir = 1 - - else if(istext(var_value)) - usr << "Variable appears to be TEXT." - default = "text" - - else if(isloc(var_value)) - usr << "Variable appears to be REFERENCE." - default = "reference" - - else if(isicon(var_value)) - usr << "Variable appears to be ICON." + else if(default == "icon") var_value = "\icon[var_value]" - default = "icon" - - else if(istype(var_value,/atom) || istype(var_value,/datum)) - usr << "Variable appears to be TYPE." - default = "type" - - else if(istype(var_value,/list)) - usr << "Variable appears to be LIST." - default = "list" - - else if(istype(var_value,/client)) - usr << "Variable appears to be CLIENT." - default = "cancel" - - else - usr << "Variable appears to be FILE." - default = "file" usr << "Variable contains: [var_value]" if(dir) - switch(var_value) - if(1) - dir = "NORTH" - if(2) - dir = "SOUTH" - if(4) - dir = "EAST" - if(8) - dir = "WEST" - if(5) - dir = "NORTHEAST" - if(6) - dir = "SOUTHEAST" - if(9) - dir = "NORTHWEST" - if(10) - dir = "SOUTHWEST" - else - dir = null + dir = dir2text(var_value) if(dir) usr << "If a direction, direction is: [dir]" + var/list/allowed_types = list("text", "num","type","reference","mob reference", "path", "matrix", "icon","file","list","edit referenced object","restore to default") if(src.holder && src.holder.marked_datum) - class = input("What kind of variable?","Variable Type",default) as null|anything in list("text", - "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default","marked datum ([holder.marked_datum.type])") - else - class = input("What kind of variable?","Variable Type",default) as null|anything in list("text", - "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default") + allowed_types += "marked datum ([holder.marked_datum.type])" + + class = input("What kind of variable?","Variable Type",default) as null|anything in allowed_types if(!class) return @@ -485,6 +355,7 @@ var/list/forbidden_varedit_object_types = list( if(holder.marked_datum && class == "marked datum ([holder.marked_datum.type])") class = "marked datum" + var/var_as_text = null switch(class) if("list") @@ -507,13 +378,13 @@ var/list/forbidden_varedit_object_types = list( var/var_new = input("Enter new number:","Num",O.vars[variable]) as null|num if(var_new == null) return O.set_light(var_new) - else if(variable=="stat") + else if(variable=="stat") // ow, but I guess I'm glad you're trying to prevent at least one kind of inconsistent state...? This is the VARIABLE EDITOR, I'm not sure we need to worry...? var/var_new = input("Enter new number:","Num",O.vars[variable]) as null|num if(var_new == null) return - if((O.vars[variable] == 2) && (var_new < 2))//Bringing the dead back to life + if((O.vars[variable] == DEAD) && (var_new < DEAD))//Bringing the dead back to life dead_mob_list -= O living_mob_list += O - if((O.vars[variable] < 2) && (var_new == 2))//Kill he + if((O.vars[variable] < DEAD) && (var_new == DEAD))//Kill he living_mob_list -= O dead_mob_list += O O.vars[variable] = var_new @@ -527,6 +398,23 @@ var/list/forbidden_varedit_object_types = list( if(var_new==null) return O.vars[variable] = var_new + if("path") + var/path_text = input("Enter path:", "Path",O.vars[variable]) as null|text + var/var_new = text2path(path_text) + if(!var_new && path_text != null) // So aborting doesn't bother the VVer + usr << "[path_text] does not appear to be a valid path." + return + O.vars[variable] = var_new + + if("matrix") + var/matrix_text = input("Enter a, b, c, d, e, and f, separated by a space.", "Matrix", "1 0 0 0 1 0") as null|text + var/var_new = text2matrix(matrix_text) + if(!var_new && matrix_text != null) + usr << "[matrix_text] is not a valid matrix string." + return + O.vars[variable] = var_new + var_as_text = "matrix([matrix_text])" + if("reference") var/var_new = input("Select reference:","Reference",O.vars[variable]) as null|mob|obj|turf|area in world if(var_new==null) return @@ -550,7 +438,62 @@ var/list/forbidden_varedit_object_types = list( if("marked datum") O.vars[variable] = holder.marked_datum - log_to_dd("### VarEdit by [src]: [O.type] [variable]=[html_encode("[O.vars[variable]]")]") - log_admin("[key_name(src)] modified [original_name]'s [variable] to [O.vars[variable]]") - message_admins("[key_name_admin(src)] modified [original_name]'s [variable] to [O.vars[variable]]", 1) + if(var_as_text == null) + var_as_text = "[O.vars[variable]]" + log_to_dd("### VarEdit by [src]: [O.type] [variable]=[html_encode("[var_as_text]")]") + log_admin("[key_name(src)] modified [original_name]'s [variable] to [var_as_text]") + message_admins("[key_name_admin(src)] modified [original_name]'s [variable] to [var_as_text]", 1) +// Let's get this all in one place. +// You'll need to take care of setting dir or iconizing the variable yourself once you've called this +/proc/variable_to_type(var/variable) + var/class + if(isnull(variable)) + usr << "Unable to determine variable type." + class = null + else if(isnum(variable)) + usr << "Variable appears to be NUM." + class = "num" + + else if(istext(variable)) + usr << "Variable appears to be TEXT." + class = "text" + + else if(isloc(variable)) + usr << "Variable appears to be REFERENCE." + class = "reference" + + else if(isicon(variable)) + usr << "Variable appears to be ICON." + variable = "\icon[variable]" + class = "icon" + + else if(istype(variable,/matrix)) + usr << "Variable appears to be MATRIX" + class = "matrix" + + else if(istype(variable,/atom) || istype(variable,/datum)) + usr << "Variable appears to be TYPE." + class = "type" + + else if(istype(variable,/list)) + usr << "Variable appears to be LIST." + class = "list" + + else if(istype(variable,/client)) + usr << "Variable appears to be CLIENT." + class = "cancel" + + else if(ispath(variable)) + usr << "Variable appears to be PATH." + class = "path" + + else if(isfile(variable)) + usr << "Variable appears to be FILE." + class = "file" + + else + usr << "Variable type is UNKNOWN." + class = null + + return class \ No newline at end of file diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index e428f25fc39..970ebfee0ef 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -346,11 +346,11 @@ Traitors and the like can also be revived with the previous role mostly intact. if(record_found)//If they have a record we can determine a few things. new_character.real_name = record_found.fields["name"] - new_character.gender = record_found.fields["sex"] + new_character.change_gender(record_found.fields["sex"]) new_character.age = record_found.fields["age"] new_character.b_type = record_found.fields["b_type"] else - new_character.gender = pick(MALE,FEMALE) + new_character.change_gender(pick(MALE,FEMALE)) var/datum/preferences/A = new() A.real_name = G_found.real_name A.copy_to(new_character) diff --git a/code/modules/admin/verbs/striketeam.dm b/code/modules/admin/verbs/striketeam.dm index 955d40c9724..b06df8ddf02 100644 --- a/code/modules/admin/verbs/striketeam.dm +++ b/code/modules/admin/verbs/striketeam.dm @@ -8,9 +8,9 @@ var/global/sent_strike_team = 0 usr << "The game hasn't started yet!" return if(sent_strike_team == 1) - usr << "CentCom is already sending a team." + usr << "CentComm is already sending a team." return - if(alert("Do you want to send in the CentCom death squad? Once enabled, this is irreversible.",,"Yes","No")!="Yes") + if(alert("Do you want to send in the CentComm death squad? Once enabled, this is irreversible.",,"Yes","No")!="Yes") return alert("This 'mode' will go on until everyone is dead or the station is destroyed. You may also admin-call the evac shuttle when appropriate. Spawned commandos have internals cameras which are viewable through a monitor inside the Spec. Ops. Office. Assigning the team's detailed task is recommended from there. While you will be able to manually pick the candidates from active ghosts, their assignment in the squad will be random.") @@ -92,7 +92,7 @@ var/global/sent_strike_team = 0 new /obj/effect/spawner/newbomb/timer/syndicate(L.loc) qdel(L) - message_admins("\blue [key_name_admin(usr)] has spawned a CentCom strike squad.", 1) + message_admins("\blue [key_name_admin(usr)] has spawned a CentComm strike squad.", 1) log_admin("[key_name(usr)] used Spawn Death Squad.") return 1 diff --git a/code/modules/arcade/arcade_prize.dm b/code/modules/arcade/arcade_prize.dm index 960ead4a0b6..f57a64de03c 100644 --- a/code/modules/arcade/arcade_prize.dm +++ b/code/modules/arcade/arcade_prize.dm @@ -1,3 +1,7 @@ +/*Contains: +* Prize balls +* Prize tickets +*/ /obj/item/toy/prizeball name = "prize ball" @@ -5,6 +9,7 @@ icon = 'icons/obj/arcade.dmi' icon_state = "prizeball_1" var/opening = 0 + var/possible_contents = list(/obj/random/carp_plushie, /obj/random/plushie, /obj/random/figure, /obj/item/toy/eight_ball, /obj/item/stack/tickets) /obj/item/toy/prizeball/New() ..() @@ -17,8 +22,68 @@ playsound(src.loc, 'sound/items/bubblewrap.ogg', 30, 1, extrarange = -4, falloff = 10) icon_state = "prizeconfetti" src.color = pick(random_color_list) - var/prize_inside = pick(/obj/random/carp_plushie, /obj/random/plushie, /obj/random/figure, /obj/item/toy/eight_ball) //will add ticket bundles later + var/prize_inside = pick(possible_contents) spawn(10) user.unEquip(src) - new prize_inside(user.loc) - qdel(src) \ No newline at end of file + if(istype(prize_inside, /obj/item/stack)) + var/amount = pick(5, 10, 15, 25, 50) + new prize_inside(user.loc, amount) + else + new prize_inside(user.loc) + qdel(src) + +/obj/item/toy/prizeball/mech + name = "mecha figure capsule" + desc = "Contains one collectible mecha figure!" + possible_contents = list(/obj/random/mech) + +/obj/item/toy/prizeball/carp_plushie + name = "carp plushie capsule" + desc = "Contains one space carp plushie!" + possible_contents = list(/obj/random/carp_plushie) + +/obj/item/toy/prizeball/plushie + name = "animal plushie capsule" + desc = "Contains one cuddly animal plushie!" + possible_contents = list(/obj/random/plushie) + +/obj/item/toy/prizeball/figure + name = "action figure capsule" + desc = "Contains one action figure!" + possible_contents = list(/obj/random/figure) + +/obj/item/toy/prizeball/therapy + name = "therapy doll capsule" + desc = "Contains one squishy therapy doll." + possible_contents = list(/obj/random/therapy) + +/obj/item/stack/tickets + name = "prize ticket" + desc = "Prize tickets from the arcade. Exchange them for fabulous prizes!" + singular_name = "prize ticket" + icon = 'icons/obj/arcade.dmi' + icon_state = "tickets_1" + force = 0 + throwforce = 0 + throw_speed = 1 + throw_range = 1 + w_class = 1.0 + max_amount = 9999 //Dang that's a lot of tickets + +/obj/item/stack/tickets/New(var/loc, var/amount=null) + ..() + update_icon() + +/obj/item/stack/tickets/attack_self(mob/user as mob) + return + +/obj/item/stack/tickets/update_icon() + var/amount = get_amount() + if((amount >= 75)) + icon_state = "tickets_4" + else if(amount >=25) + icon_state = "tickets_3" + else if(amount >= 4) + icon_state = "tickets_2" + else + icon_state = "tickets_1" \ No newline at end of file diff --git a/code/modules/arcade/prize_counter.dm b/code/modules/arcade/prize_counter.dm new file mode 100644 index 00000000000..51c3a43a700 --- /dev/null +++ b/code/modules/arcade/prize_counter.dm @@ -0,0 +1,221 @@ + +/obj/machinery/prize_counter + name = "Prize Counter" + desc = "A machine which exchanges tickets for a variety of fabulous prizes!" + icon = 'icons/obj/arcade.dmi' + icon_state = "prize_counter-on" + density = 1 + anchored = 1 + use_power = 1 + idle_power_usage = 40 + var/tickets = 0 + var/prize_tier = 1 //Increased by matter bin rating, unlocks more prize options per tier + +/obj/machinery/prize_counter/New() + ..() + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/prize_counter(null) + component_parts += new /obj/item/weapon/stock_parts/matter_bin(null) + component_parts += new /obj/item/weapon/stock_parts/manipulator(null) + component_parts += new /obj/item/stack/cable_coil(null, 1) + component_parts += new /obj/item/weapon/stock_parts/console_screen(null) + RefreshParts() + +/obj/machinery/prize_counter/upgraded/New() + ..() + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/prize_counter(null) + component_parts += new /obj/item/weapon/stock_parts/matter_bin/bluespace(null) + component_parts += new /obj/item/weapon/stock_parts/manipulator(null) + component_parts += new /obj/item/stack/cable_coil(null, 1) + component_parts += new /obj/item/weapon/stock_parts/console_screen(null) + RefreshParts() + +/obj/machinery/prize_counter/RefreshParts() + for(var/obj/item/weapon/stock_parts/matter_bin/B in component_parts) + prize_tier = B.rating + +/obj/machinery/prize_counter/update_icon() + if(stat & BROKEN) + icon_state = "prize_counter-broken" + else if(panel_open) + icon_state = "prize_counter-open" + else if(stat & NOPOWER) + icon_state = "prize_counter-off" + else + icon_state = "prize_counter-on" + return + +/obj/machinery/prize_counter/attackby(var/obj/item/O as obj, var/mob/user as mob, params) + if(istype(O, /obj/item/stack/tickets)) + var/obj/item/stack/tickets/T = O + if(user.unEquip(T)) //Because if you can't drop it for some reason, you shouldn't be increasing the tickets var + tickets += T.amount + qdel(T) + else + user << "\The [T] seems stuck to your hand!" + return + if(istype(O, /obj/item/weapon/screwdriver) && anchored) + playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) + panel_open = !panel_open + user << "You [panel_open ? "open" : "close"] the maintenance panel." + update_icon() + return + if(panel_open) + if(istype(O, /obj/item/weapon/wrench)) + default_unfasten_wrench(user, O) + if(component_parts && istype(O, /obj/item/weapon/crowbar)) + if(tickets) //save the tickets! + print_tickets() + default_deconstruction_crowbar(O) + +/obj/machinery/prize_counter/attack_hand(mob/user as mob) + if(..()) + return + add_fingerprint(user) + interact(user) + +/obj/machinery/prize_counter/interact(mob/user as mob) + user.set_machine(src) + + if(stat & (BROKEN|NOPOWER)) + return + + var/dat = {" + + + Arcade Ticket Exchange + + + +

    Tickets: [tickets] | Eject Tickets

    +

    Arcade Ticket Exchange

    +

    + Exchange that pile of tickets for a pile of cool prizes! +

    +

    Available Prizes:

    + + + + + + + + "} + + for(var/datum/prize_item/item in global_prizes.prizes) + var/cost_class="affordable" + if(item.cost>tickets) + cost_class="toomuch" + var/itemID = global_prizes.prizes.Find(item) + dat += {" + + + + "} + if(prize_tier >= item.tier_unlocked) + dat += {" + + + "} + else + dat += {" + + + "} + + dat += {" + +
    #Name/DescriptionPrice
    + [itemID] + +

    [item.name]

    +

    [item.desc]

    +
    + [item.cost] Tickets +
    + LOCKED. +
    + +"} + user << browse(dat, "window=prize_counter") + onclose(user, "prize_counter") + return + +/obj/machinery/prize_counter/Topic(href, href_list) + if(..()) + return 1 + + add_fingerprint(usr) + + if(href_list["eject"]) + print_tickets() + + if (href_list["buy"]) + var/itemID = text2num(href_list["buy"]) + var/datum/prize_item/item = global_prizes.prizes[itemID] + var/sure = alert(usr,"Are you sure you wish to purchase [item.name] for [item.cost] tickets?","You sure?","Yes","No") in list("Yes","No") + if(sure=="No") + updateUsrDialog() + return + if(!global_prizes.PlaceOrder(src, itemID)) + usr << "Unable to complete the exchange." + else + usr << "You've successfully purchased the item." + + interact(usr) + return + +/obj/machinery/prize_counter/proc/print_tickets() + if(!tickets) + return + if(tickets >= 9999) + new /obj/item/stack/tickets(get_turf(src), 9999) //max stack size + tickets -= 9999 + print_tickets() + else + new /obj/item/stack/tickets(get_turf(src), tickets) + tickets = 0 \ No newline at end of file diff --git a/code/modules/arcade/prize_datums.dm b/code/modules/arcade/prize_datums.dm new file mode 100644 index 00000000000..0cd3c308330 --- /dev/null +++ b/code/modules/arcade/prize_datums.dm @@ -0,0 +1,344 @@ + +var/global/datum/prizes/global_prizes = new + +/datum/prizes + var/list/prizes = list() + +/datum/prizes/New() + for(var/itempath in subtypesof(/datum/prize_item)) + prizes += new itempath() + +/datum/prizes/proc/PlaceOrder(var/obj/machinery/prize_counter/prize_counter, var/itemID) + if(!prize_counter) + return 0 + var/datum/prize_item/item = global_prizes.prizes[itemID] + if(!item) + return 0 + if(prize_counter.tickets >= item.cost) + new item.typepath(prize_counter.loc) + prize_counter.tickets -= item.cost + prize_counter.visible_message("Enjoy your prize!") + return 1 + else + prize_counter.visible_message("Not enough tickets!") + return 0 + +////////////////////////////////////// +// prize_item datum // +////////////////////////////////////// + +/datum/prize_item + var/name = "Prize" + var/desc = "This shouldn't show up..." + var/typepath = /obj/item/toy/prizeball + var/cost = 0 + var/tier_unlocked = 0 //minimum tier needed to unlock the ability to select this prize + +////////////////////////////////////// +// Tier 1 Prizes // +////////////////////////////////////// + +/datum/prize_item/balloon + name = "Water Balloon" + desc = "A thin balloon for throwing liquid at people." + typepath = /obj/item/toy/balloon + cost = 10 + tier_unlocked = 1 + +/datum/prize_item/crayons + name = "Box of Crayons" + desc = "A six-pack of crayons, just like back in kindergarten." + typepath = /obj/item/weapon/storage/fancy/crayons + cost = 35 + tier_unlocked = 1 + +/datum/prize_item/snappops + name = "Snap-Pops" + desc = "A box of exploding snap-pop fireworks." + typepath = /obj/item/weapon/storage/box/snappops + cost = 20 + tier_unlocked = 1 + +/datum/prize_item/spinningtoy + name = "Spinning Toy" + desc = "Looks like an authentic Singularity!" + typepath = /obj/item/toy/spinningtoy + cost = 15 + tier_unlocked = 1 + +/datum/prize_item/blinktoy + name = "Blink toy" + desc = "Blink. Blink. Blink." + typepath = /obj/item/toy/blink + cost = 15 + tier_unlocked = 1 + +/datum/prize_item/dice + name = "Dice set" + desc = "A set of assorted dice." + typepath = /obj/item/weapon/storage/box/dice + cost = 20 + tier_unlocked = 1 + +/datum/prize_item/cards + name = "Deck of cards" + desc = "Anyone fancy a game of 52-card Pickup?" + typepath = /obj/item/toy/cards/deck + cost = 25 + tier_unlocked = 1 + +/datum/prize_item/wallet + name = "Colored Wallet" + desc = "Brightly colored and big enough for standard issue ID cards." + typepath = /obj/item/weapon/storage/wallet/color + cost = 50 + tier_unlocked = 1 + +/datum/prize_item/pet_rock + name = "pet rock" + desc = "A pet of your very own!" + typepath = /obj/item/toy/pet_rock + cost = 80 + tier_unlocked = 1 + +/datum/prize_item/foam_darts + name = "Pack of Foam Darts" + desc = "A refill pack of 10 foam darts." + typepath = /obj/item/weapon/storage/box/foam_darts + cost = 20 + tier_unlocked = 1 + +/datum/prize_item/minigibber + name = "Minigibber Toy" + desc = "A model of the station gibber. Probably shouldn't stick your fingers in it." + typepath = /obj/item/toy/minigibber + cost = 60 + tier_unlocked = 1 + +/datum/prize_item/id_sticker + name = "Prisoner ID Sticker" + desc = "A sticker that can make any ID look like a prisoner ID." + typepath = /obj/item/weapon/id_decal/prisoner + cost = 50 + tier_unlocked = 1 + +/datum/prize_item/id_sticker/silver + name = "Silver ID Sticker" + desc = "A sticker that can make any ID look like a silver ID." + typepath = /obj/item/weapon/id_decal/silver + +/datum/prize_item/id_sticker/gold + name = "Gold ID Sticker" + desc = "A sticker that can make any ID look like a golden ID." + typepath = /obj/item/weapon/id_decal/gold + +/datum/prize_item/id_sticker/centcom + name = "Centcomm ID Sticker" + desc = "A sticker that can make any ID look like a Central Command ID." + typepath = /obj/item/weapon/id_decal/centcom + +/datum/prize_item/id_sticker/emag + name = "Suspicious ID Sticker" + desc = "A sticker that can make any ID look like something suspicious..." + typepath = /obj/item/weapon/id_decal/emag + +////////////////////////////////////// +// Tier 2 Prizes // +////////////////////////////////////// + +/datum/prize_item/carp_plushie + name = "Random Carp Plushie" + desc = "A colorful fish-shaped plush toy." + typepath = /obj/item/toy/prizeball/carp_plushie + cost = 75 + tier_unlocked = 2 + +/datum/prize_item/therapy_doll + name = "Random Therapy Doll" + desc = "A therapeutic doll for relieving stress without being charged with assault." + typepath = /obj/item/toy/prizeball/therapy + cost = 60 + tier_unlocked = 2 + +/datum/prize_item/plushie + name = "Random Animal Plushie" + desc = "A colorful animal-shaped plush toy." + typepath = /obj/item/toy/prizeball/plushie + cost = 75 + tier_unlocked = 2 + +/datum/prize_item/mech_toy + name = "Random Mecha" + desc = "A random mecha figure, collect all 11!" + typepath = /obj/item/toy/prizeball/mech + cost = 75 + tier_unlocked = 2 + +/datum/prize_item/action_figure + name = "Random Action Figure" + desc = "A random action figure, collect them all!" + typepath = /obj/item/toy/prizeball/figure + cost = 75 + tier_unlocked = 2 + +/datum/prize_item/eight_ball + name = "Magic Eight Ball" + desc = "A mystical ball that can divine the future!" + typepath = /obj/item/toy/eight_ball + cost = 40 + tier_unlocked = 2 + +/datum/prize_item/tacticool + name = "Tacticool Turtleneck" + desc = "A cool-looking turtleneck." + typepath = /obj/item/clothing/under/syndicate/tacticool + cost = 90 + tier_unlocked = 2 + +/datum/prize_item/crossbow + name = "Foam Dart Crossbow" + desc = "A toy crossbow that fires foam darts." + typepath = /obj/item/toy/crossbow + cost = 100 + tier_unlocked = 2 + +/datum/prize_item/toy_xeno + name = "Xeno Action Figure" + desc = "A lifelike replica of the horrific xeno scourge." + typepath = /obj/item/toy/toy_xeno + cost = 80 + tier_unlocked = 2 + +/datum/prize_item/fakespell + name = "Fake Spellbook" + desc = "Perform magic! Astound your friends! Get mistaken for an enemy of the corporation!" + typepath = /obj/item/weapon/spellbook/oneuse/fake_gib + cost = 100 + tier_unlocked = 2 + +/datum/prize_item/capgun + name = "Capgun Revolver" + desc = "Do you feel lucky... punk?" + typepath = /obj/item/weapon/gun/projectile/revolver/capgun + cost = 75 + tier_unlocked = 2 + +////////////////////////////////////// +// Tier 3 Prizes // +////////////////////////////////////// + +/datum/prize_item/magic_conch + name = "Magic Conch Shell" + desc = "All hail the magic conch!" + typepath = /obj/item/toy/eight_ball/conch + cost = 100 + tier_unlocked = 3 + +/datum/prize_item/flash + name = "Toy Flash" + desc = "AUGH! MY EYES!" + typepath = /obj/item/toy/flash + cost = 50 + tier_unlocked = 3 + +/datum/prize_item/foamblade + name = "Foam Armblade" + desc = "Perfect for reenacting space horror holo-vids." + typepath = /obj/item/toy/foamblade + cost = 100 + tier_unlocked = 3 + +/datum/prize_item/minimeteor + name = "Mini-Meteor" + desc = "Meteors have been detected on a collision course with your fun times!" + typepath = /obj/item/toy/minimeteor + cost = 50 + tier_unlocked = 3 + +/datum/prize_item/redbutton + name = "Shiny Red Button" + desc = "PRESS IT!" + typepath = /obj/item/toy/redbutton + cost = 100 + tier_unlocked = 3 + +/datum/prize_item/owl + name = "Owl Action Figure" + desc = "Remember: heroes don't grief!" + typepath = /obj/item/toy/owl + cost = 125 + tier_unlocked = 3 + +/datum/prize_item/griffin + name = "Griffin Action Figure" + desc = "If you can't be the best, you can always be the WORST." + typepath = /obj/item/toy/griffin + cost = 125 + tier_unlocked = 3 + +/datum/prize_item/AI + name = "Toy AI Unit" + desc = "Law 1: Maximize fun for crew." + typepath = /obj/item/toy/AI + cost = 75 + tier_unlocked = 3 + +/datum/prize_item/tommygun + name = "Tommygun" + desc = "A replica tommygun that fires foam darts." + typepath = /obj/item/toy/crossbow/tommygun + cost = 175 + tier_unlocked = 3 + +/datum/prize_item/esword + name = "Toy Energy Sword" + desc = "A plastic replica of an energy blade." + typepath = /obj/item/toy/sword + cost = 150 + tier_unlocked = 3 + +/datum/prize_item/blobhat + name = "Blob Hat" + desc = "There's... something... on your head..." + typepath = /obj/item/clothing/head/blob + cost = 125 + tier_unlocked = 3 + +/datum/prize_item/nuke + name = "Nuclear Fun Device" + desc = "Annihilate boredom with an explosion of excitement!" + typepath = /obj/item/toy/nuke + cost = 100 + tier_unlocked = 3 + +////////////////////////////////////// +// Tier 4 Prizes // +////////////////////////////////////// + +/datum/prize_item/chainsaw + name = "Toy Chainsaw" + desc = "A full-scale model chainsaw, based on that massacre in Space Texas." + typepath = /obj/item/weapon/twohanded/toy/chainsaw + cost = 200 + tier_unlocked = 4 + +/datum/prize_item/spacesuit + name = "Fake Spacesuit" + desc = "A replica spacesuit. Not actually spaceworthy." + typepath = /obj/item/weapon/storage/box/fakesyndiesuit + cost = 180 + tier_unlocked = 4 + +/datum/prize_item/fakespace + name = "Space Carpet" + desc = "A stack of carpeted floor tiles that resemble space." + typepath = /obj/item/stack/tile/fakespace/loaded + cost = 150 + tier_unlocked = 4 + +/datum/prize_item/bike + name = "Awesome Bike!" + desc = "WOAH." + typepath = /obj/structure/stool/bed/chair/wheelchair/bike + cost = 10000 //max stack + 1 tickets + tier_unlocked = 4 diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm index 370f0270f58..a2810d04e98 100644 --- a/code/modules/assembly/infrared.dm +++ b/code/modules/assembly/infrared.dm @@ -11,6 +11,16 @@ var/visible = 0 var/obj/effect/beam/i_beam/first = null var/obj/effect/beam/i_beam/last = null + var/max_nesting_level = 10 + var/turf/fire_location + +/obj/item/device/assembly/infra/Destroy() + if(first) + qdel(first) + first = null + last = null + fire_location = null + return ..() /obj/item/device/assembly/infra/describe() return "The infrared trigger is [on?"on":"off"]." @@ -41,10 +51,28 @@ if(holder) holder.update_icon() - return + +/obj/item/device/assembly/infra/proc/get_valid_loc(atom/A, atom/prev, level = 0) + if(!A) + A = loc + if(!prev) + prev = src + if(level > max_nesting_level) + return null + else if(isturf(A)) + return A + else if(isobj(A)) + var/obj/O = A + if(isassembly(A) || O.IsAssemblyHolder() || istype(A, /obj/item/device/onetankbomb)) + return .(A.loc, A, level + 1) + else if(ismob(A)) + var/mob/user = A + if(user.get_active_hand() == prev || user.get_inactive_hand() == prev) + return .(A.loc, A, level + 1) + return null /obj/item/device/assembly/infra/process() - if(!on) + if(!on || fire_location != get_turf(loc)) if(first) qdel(first) return @@ -53,12 +81,14 @@ if(first && last) last.process() return - var/turf/T = get_turf(src) + var/turf/T = get_valid_loc() if(T) + fire_location = T var/obj/effect/beam/i_beam/I = new /obj/effect/beam/i_beam(T) I.master = src I.density = 1 I.dir = dir + I.update_icon() first = I step(I, I.dir) if(first) @@ -70,40 +100,47 @@ /obj/item/device/assembly/infra/attack_hand() qdel(first) ..() - return /obj/item/device/assembly/infra/Move() var/t = dir ..() dir = t qdel(first) - return /obj/item/device/assembly/infra/holder_movement() if(!holder) return 0 -// dir = holder.dir qdel(first) return 1 +/obj/item/device/assembly/infra/equipped(var/mob/user, var/slot) + qdel(first) + return ..() + +/obj/item/device/assembly/infra/pickup(mob/user) + qdel(first) + return ..() + /obj/item/device/assembly/infra/proc/trigger_beam() - if((!secured)||(!on)||(cooldown > 0)) + if(!secured || !on || cooldown > 0) return 0 pulse(0) audible_message("\icon[src] *beep* *beep*", null, 3) cooldown = 2 spawn(10) process_cooldown() - return /obj/item/device/assembly/infra/interact(mob/user as mob)//TODO: change this this to the wire control panel if(!secured) return user.set_machine(src) - var/dat = text("Infrared Laser\nStatus: []
    \nVisibility: []
    \n
    ", (on ? text("On", src) : text("Off", src)), (src.visible ? text("Visible", src) : text("Invisible", src))) - dat += "

    Refresh" - dat += "

    Close" + var/dat = {"Infrared Laser + Status: [on ? "On" : "Off"]
    + Visibility: [visible ? "Visible" : "Invisible"]
    + Current Direction: [capitalize(dir2text(dir))]
    +
    +

    Refresh +

    Close"} user << browse(dat, "window=infra") onclose(user, "infra") - return /obj/item/device/assembly/infra/Topic(href, href_list) ..() @@ -118,6 +155,8 @@ visible = !(visible) if(first) first.vis_spread(visible) + if(href_list["rotate"]) + rotate() if(href_list["close"]) usr << browse(null, "window=infra") return @@ -133,7 +172,9 @@ return dir = turn(dir, 90) - return + + if(usr.machine == src) + interact(usr) @@ -157,13 +198,14 @@ if(master) master.trigger_beam() qdel(src) - return /obj/effect/beam/i_beam/proc/vis_spread(v) visible = v if(next) next.vis_spread(v) +/obj/effect/beam/i_beam/update_icon() + transform = turn(matrix(), dir2angle(dir)) /obj/effect/beam/i_beam/process() if((loc.density || !(master))) @@ -184,6 +226,7 @@ I.master = master I.density = 1 I.dir = dir + I.update_icon() I.previous = src next = I step(I, I.dir) @@ -196,13 +239,12 @@ /obj/effect/beam/i_beam/Bump() qdel(src) - return /obj/effect/beam/i_beam/Bumped() hit() /obj/effect/beam/i_beam/Crossed(atom/movable/AM as mob|obj) - if(istype(AM, /obj/effect/beam)) + if(istype(AM, /obj/effect/beam) || !AM.density) return hit() diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm index 964da2ca2b9..cc4ddb95856 100644 --- a/code/modules/awaymissions/gateway.dm +++ b/code/modules/awaymissions/gateway.dm @@ -236,20 +236,26 @@ obj/machinery/gateway/centerstation/process() if(!ready) return if(!active) return if(istype(M, /mob/living/carbon)) - for(var/obj/item/weapon/implant/exile/E in M)//Checking that there is an exile implant in the contents - if(E.imp_in == M)//Checking that it's actually implanted vs just in their pocket - M << "\black The station gate has detected your exile implant and is blocking your entry." - return + if (exilecheck(M)) return + if(istype(M, /obj)) + for(var/mob/living/carbon/F in M) + if (exilecheck(F)) return M.forceMove(get_step(stationgate.loc, SOUTH)) M.dir = SOUTH +/obj/machinery/gateway/centeraway/proc/exilecheck(var/mob/living/carbon/M) + for(var/obj/item/weapon/implant/exile/E in M)//Checking that there is an exile implant in the contents + if(E.imp_in == M)//Checking that it's actually implanted vs just in their pocket + M << "The station gate has detected your exile implant and is blocking your entry." + return 1 + return 0 /obj/machinery/gateway/centeraway/attackby(obj/item/device/W as obj, mob/user as mob, params) if(istype(W,/obj/item/device/multitool)) if(calibrated) - user << "\black The gate is already calibrated, there is no work for you to do here." + user << "The gate is already calibrated, there is no work for you to do here." return else - user << "Recalibration successful!: \black This gate's systems have been fine tuned. Travel to this gate will now be on target." + user << "Recalibration successful!: This gate's systems have been fine tuned. Travel to this gate will now be on target." calibrated = 1 return diff --git a/code/modules/awaymissions/mission_code/beach.dm b/code/modules/awaymissions/mission_code/beach.dm new file mode 100644 index 00000000000..fd54ffaa7ee --- /dev/null +++ b/code/modules/awaymissions/mission_code/beach.dm @@ -0,0 +1,27 @@ +/obj/effect/waterfall + name = "waterfall effect" + icon = 'icons/effects/effects.dmi' + icon_state = "extinguish" + opacity = 0 + mouse_opacity = 0 + density = 0 + anchored = 1 + invisibility = 101 + + var/water_frequency = 15 + var/water_timer = 0 + +/obj/effect/waterfall/New() + water_timer = addtimer(src, "drip", water_frequency) + +/obj/effect/waterfall/Destroy() + if(water_timer) + deltimer(water_timer) + water_timer = null + +/obj/effect/waterfall/proc/drip() + var/obj/effect/effect/water/W = new(loc) + W.dir = dir + spawn(1) + W.loc = get_step(W, dir) + water_timer = addtimer(src, "drip", water_frequency) \ No newline at end of file diff --git a/code/modules/awaymissions/zlevel.dm b/code/modules/awaymissions/zlevel.dm index 4fef768e368..d588776e8cb 100644 --- a/code/modules/awaymissions/zlevel.dm +++ b/code/modules/awaymissions/zlevel.dm @@ -41,8 +41,12 @@ proc/createRandomZlevel() var/file = file(map) if(isfile(file)) maploader.load_map(file) + var/turfs = block(locate(1, 1, world.maxz), locate(world.maxx, world.maxy, world.maxz)) if(air_master) - air_master.setup_allturfs(block(locate(1, 1, world.maxz), locate(world.maxx, world.maxy, world.maxz))) + air_master.setup_allturfs(turfs) + for(var/turf/T in turfs) + if(T.dynamic_lighting) + T.lighting_build_overlays() log_to_dd("Away mission loaded: [map]") for(var/obj/effect/landmark/L in landmarks_list) diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm index 4d9237bd11c..fa6d0015399 100644 --- a/code/modules/client/client defines.dm +++ b/code/modules/client/client defines.dm @@ -3,7 +3,6 @@ //ADMIN THINGS// //////////////// var/datum/admins/holder = null - var/buildmode = 0 var/last_message = "" //Contains the last message sent by this client - used to protect against copy-paste spamming. var/last_message_count = 0 //contins a number of how many times a message identical to last_message was sent. @@ -80,4 +79,6 @@ var/topic_debugging = 0 //if set to true, allows client to see nanoUI errors -- yes i realize this is messy but it'll make live testing infinitely easier - control_freak = CONTROL_FREAK_ALL | CONTROL_FREAK_SKIN | CONTROL_FREAK_MACROS \ No newline at end of file + control_freak = CONTROL_FREAK_ALL | CONTROL_FREAK_SKIN | CONTROL_FREAK_MACROS + + var/datum/click_intercept/click_intercept = null \ No newline at end of file diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index a8f97d08947..077af57dfee 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -1593,7 +1593,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts character.sec_record = sec_record character.gen_record = gen_record - character.gender = gender + character.change_gender(gender) character.age = age character.b_type = b_type @@ -1640,7 +1640,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts else O.robotize() else - var/obj/item/organ/I = character.internal_organs_by_name[name] + var/obj/item/organ/internal/I = character.get_int_organ_tag(name) if(I) if(status == "assisted") I.mechassist() @@ -1694,7 +1694,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts if(character.gender in list(PLURAL, NEUTER)) if(isliving(src)) //Ghosts get neuter by default message_admins("[key_name_admin(character)] has spawned with their gender as plural or neuter. Please notify coders.") - character.gender = MALE + character.change_gender(MALE) /datum/preferences/proc/open_load_dialog(mob/user) diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm index ec3aa30a778..d1c100c37c7 100644 --- a/code/modules/client/preferences_toggles.dm +++ b/code/modules/client/preferences_toggles.dm @@ -201,7 +201,7 @@ prefs.save_preferences(src) usr << "You will [(prefs.sound & SOUND_STREAMING) ? "now" : "no longer"] hear streamed media." if(!media) return - if(prefs.toggles & SOUND_STREAMING) + if(prefs.sound & SOUND_STREAMING) media.update_music() else media.stop_music() diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 0c3c59595b2..da0da57bcd4 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -141,6 +141,7 @@ var/invisa_view = 0 var/flash_protect = 0 //Mal: What level of bright light protection item has. 1 = Flashers, Flashes, & Flashbangs | 2 = Welding | -1 = OH GOD WELDING BURNT OUT MY RETINAS var/tint = 0 //Mal: Sets the item's level of visual impairment tint, normally set to the same as flash_protect + var/color_view = null//overrides client.color while worn strip_delay = 20 // but seperated to allow items to protect but not impair vision, like space helmets put_on_delay = 25 species_restricted = list("exclude","Kidan") @@ -255,6 +256,7 @@ BLIND // can't see anything set src in usr set_sensors(usr) ..() + //Head /obj/item/clothing/head name = "head" @@ -285,38 +287,63 @@ BLIND // can't see anything //Proc that moves gas/breath masks out of the way /obj/item/clothing/mask/proc/adjustmask(var/mob/user) + var/mob/living/carbon/human/H = usr //Used to check if the mask is on the head, to check if the hands are full, and to turn off internals if they were on when the mask was pushed out of the way. if(!ignore_maskadjust) - if(!user.canmove || user.stat || user.restrained()) + if(user.incapacitated()) //This check allows you to adjust your masks while you're buckled into chairs or beds. return - if(src.mask_adjusted == 1) - src.icon_state = initial(icon_state) + if(mask_adjusted) + icon_state = copytext(icon_state, 1, findtext(icon_state, "_up")) /*Trims the '_up' off the end of the icon state, thus reverting to the most recent previous state. + Had to use this instead of initial() because initial reverted to the wrong state.*/ gas_transfer_coefficient = initial(gas_transfer_coefficient) permeability_coefficient = initial(permeability_coefficient) user << "You push \the [src] back into place." - src.mask_adjusted = 0 + mask_adjusted = 0 slot_flags = initial(slot_flags) + if(flags_inv != initial(flags_inv)) //If the mask is one that hides the face and can be adjusted yet lost that trait when it was adjusted, make it hide the face again. + flags_inv += HIDEFACE + if(H.head == src) + if(flags_inv == HIDEFACE) //Means that only things like bandanas and balaclavas will be affected since they obscure the identity of the wearer. + if(H.l_hand && H.r_hand) //If both hands are occupied, drop the object on the ground. + user.unEquip(src) + else //Otherwise, put it in an available hand, the active one preferentially. + src.loc = user + H.head = null + user.put_in_hands(src) else - src.icon_state += "_up" + icon_state += "_up" user << "You push \the [src] out of the way." gas_transfer_coefficient = null permeability_coefficient = null - src.mask_adjusted = 1 + mask_adjusted = 1 if(adjusted_flags) slot_flags = adjusted_flags if(ishuman(user)) - var/mob/living/carbon/human/H = user if(H.internal) - if(H.internals) - H.internals.icon_state = "internal0" - H.internal = null + if(user.wear_mask == src) /*If the user was wearing the mask providing internals on their face at the time it was adjusted, turn off internals. + Otherwise, they adjusted it while it was in their hands or some such so we won't be needing to turn off internals.*/ + if(H.internals) + H.internals.icon_state = "internal0" + H.internal = null + if(flags_inv == HIDEFACE) //Means that only things like bandanas and balaclavas will be affected since they obscure the identity of the wearer. + flags_inv -= HIDEFACE /*Done after the above to avoid having to do a check for initial(src.flags_inv == HIDEFACE). + This reveals the user's face since the bandana will now be going on their head.*/ + if(user.wear_mask == src) + if(initial(flags_inv) == HIDEFACE) //Means that you won't have to take off and put back on simple things like breath masks which, realistically, can just be pulled down off your face. + if(H.l_hand && H.r_hand) //If both hands are occupied, drop the object on the ground. + user.unEquip(src) + else //Otherwise, put it in an available hand, the active one preferentially. + src.loc = user + user.wear_mask = null + user.put_in_hands(src) usr.update_inv_wear_mask() + usr.update_inv_head() //Shoes /obj/item/clothing/shoes name = "shoes" icon = 'icons/obj/clothing/shoes.dmi' desc = "Comfortable-looking shoes." - gender = PLURAL //Carn: for grammarically correct text-parsing + gender = PLURAL //Carn: for grammatically correct text-parsing var/chained = 0 var/can_cut_open = 0 var/cut_open = 0 @@ -344,7 +371,7 @@ BLIND // can't see anything user.visible_message("[user] strikes a [M] on the bottom of [src], lighting it.","You strike the [M] on the bottom of [src] to light it.") else if(M.lit == 1) // Match is lit, not extinguished. M.dropped() - user.visible_message("[user] crushes the [M] into the bottom of [src]. extinguishing it.","You crush the [M] into the bottom of [src], extinguishing it.") + user.visible_message("[user] crushes the [M] into the bottom of [src], extinguishing it.","You crush the [M] into the bottom of [src], extinguishing it.") else // Match has been previously lit and extinguished. user << "The [M] has already been extinguished." return @@ -378,9 +405,67 @@ BLIND // can't see anything name = "suit" var/fire_resist = T0C+100 allowed = list(/obj/item/weapon/tank/emergency_oxygen) - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) slot_flags = SLOT_OCLOTHING var/blood_overlay_type = "suit" + var/suit_adjusted = 0 + var/ignore_suitadjust = 1 + var/adjust_flavour = null + +//Proc that opens and closes jackets. +/obj/item/clothing/suit/proc/adjustsuit(var/mob/user) + if(!ignore_suitadjust) + if(!user.incapacitated()) + if(!(HULK in user.mutations)) + if(suit_adjusted) + var/flavour = "close" + icon_state = copytext(icon_state, 1, findtext(icon_state, "_open")) /*Trims the '_open' off the end of the icon state, thus avoiding a case where jackets that start open will + end up with a suffix of _open_open if adjusted twice, since their initial state is _open. */ + item_state = copytext(item_state, 1, findtext(item_state, "_open")) + if(adjust_flavour) + flavour = "[copytext(adjust_flavour, 3, lentext(adjust_flavour) + 1)] up" //Trims off the 'un' at the beginning of the word. unzip -> zip, unbutton->button. + user << "You [flavour] \the [src]." + suit_adjusted = 0 //Suit is no longer adjusted. + else + var/flavour = "open" + icon_state += "_open" + item_state += "_open" + if(adjust_flavour) + flavour = "[adjust_flavour]" + user << "You [flavour] \the [src]." + suit_adjusted = 1 //Suit's adjusted. + else + if(user.canUnEquip(src)) //Checks to see if the item can be unequipped. If so, lets shred. Otherwise, struggle and fail. + if(contents) //If the suit's got any storage capability... + for(var/obj/item/O in contents) //AVOIDING ITEM LOSS. Check through everything that's stored in the jacket and see if one of the items is a pocket. + if(istype(O, /obj/item/weapon/storage/internal)) //If it's a pocket... + if(O.contents) //Check to see if the pocket's got anything in it. + for(var/obj/item/I in O.contents) //Dump the pocket out onto the floor below the user. + user.unEquip(I,1) + + user.visible_message("[user] bellows, [pick("shredding", "ripping open", "tearing off")] their jacket in a fit of rage!","You accidentally [pick("shred", "rend", "tear apart")] \the [src] with your [pick("excessive", "extreme", "insane", "monstrous", "ridiculous", "unreal", "stupendous")] [pick("power", "strength")]!") + user.unEquip(src) + qdel(src) //Now that the pockets have been emptied, we can safely destroy the jacket. + user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!")) + else + user << "You yank and pull at \the [src] with your [pick("excessive", "extreme", "insane", "monstrous", "ridiculous", "unreal", "stupendous")] [pick("power", "strength")], however you are unable to change its state!" //Yep, that's all they get. Avoids having to snowflake in a cooldown. + return + user.update_inv_wear_suit() + else + user << "You attempt to button up the velcro on \the [src], before promptly realising how retarded you are." + +/obj/item/clothing/suit/verb/openjacket(var/mob/user) //The verb you can use to adjust jackets. + set name = "Open/Close Jacket" + set category = "Object" + set src in usr + if(!istype(usr, /mob/living)) return + if(usr.stat) return + adjustsuit(user) + +/obj/item/clothing/suit/ui_action_click() //This is what happens when you click the HUD action button to adjust your suit. + if(!ignore_suitadjust) + adjustsuit(usr) + else ..() //This is required in order to ensure that the UI buttons for items that have alternate functions tied to UI buttons still work. //Spacesuit //Note: Everything in modules/clothing/spacesuits should have the entire suit grouped together. @@ -416,7 +501,7 @@ BLIND // can't see anything allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank) slowdown = 2 armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 50) - flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT||HIDETAIL + flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT heat_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index 2c3566c767d..37bef3a6025 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -207,6 +207,66 @@ "Vox" = 'icons/mob/species/vox/eyes.dmi' ) + +/obj/item/clothing/glasses/sunglasses/noir + name = "noir sunglasses" + desc = "Somehow these seem even more out-of-date than normal sunglasses." + action_button_name = "Noir Mode" + var/noir_mode = 0 + color_view = list(0.3, 0.3, 0.3, 0,\ + 0.3, 0.3, 0.3, 0,\ + 0.3, 0.3, 0.3, 0,\ + 0.0, 0.0, 0.0, 1,) //greyscale + +/obj/item/clothing/glasses/sunglasses/noir/attack_self() + if(is_equipped()) + toggle_noir() + +/obj/item/clothing/glasses/sunglasses/noir/proc/toggle_noir() + if(!noir_mode) + if(color_view && usr.client && !usr.client.color) + animate(usr.client, color = color_view, time = 10) + noir_mode = 1 + else + if(usr.client && usr.client.color) + animate(usr.client, color = null, time = 10) + noir_mode = 0 + +/obj/item/clothing/glasses/sunglasses/noir/equipped(mob/user, slot) + if(slot == slot_glasses) + if(noir_mode) + if(color_view && user.client && !user.client.color) + animate(user.client, color = color_view, time = 10) + ..(user, slot) + +/obj/item/clothing/glasses/sunglasses/noir/dropped(mob/living/carbon/human/user) + if(istype(user) && user.glasses == src) + if(user.client && user.client.color) + animate(user.client, color = null, time = 10) + ..(user) + +/obj/item/clothing/glasses/sunglasses/yeah + name = "agreeable glasses" + desc = "H.C Limited edition." + var/punused = null + action_button_name = "YEAH!" + +/obj/item/clothing/glasses/sunglasses/yeah/attack_self() + pun() + + +/obj/item/clothing/glasses/sunglasses/yeah/verb/pun() + set category = "Object" + set name = "YEAH!" + set src in usr + if(!punused)//one per round + punused = 1 + playsound(src.loc, 'sound/misc/yeah.ogg', 100, 0) + usr.visible_message("YEEEAAAAAHHHHHHHHHHHHH!!") + else + usr << "The moment is gone." + + /obj/item/clothing/glasses/sunglasses/reagent name = "sunscanners" desc = "Strangely ancient technology used to help provide rudimentary eye color. Outfitted with apparatus to scan individual reagents." diff --git a/code/modules/clothing/masks/boxing.dm b/code/modules/clothing/masks/boxing.dm index c12fddfc884..d12bac1d3b8 100644 --- a/code/modules/clothing/masks/boxing.dm +++ b/code/modules/clothing/masks/boxing.dm @@ -8,6 +8,7 @@ w_class = 2 action_button_name = "Adjust Balaclava" ignore_maskadjust = 0 + adjusted_flags = SLOT_HEAD species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/mask.dmi', diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm index e9da678a45b..93e8dc6cd79 100644 --- a/code/modules/clothing/masks/miscellaneous.dm +++ b/code/modules/clothing/masks/miscellaneous.dm @@ -197,18 +197,38 @@ obj/item/clothing/mask/bandana/red name = "red bandana" icon_state = "bandred" + item_color = "red" + desc = "It's a red bandana." obj/item/clothing/mask/bandana/blue name = "blue bandana" icon_state = "bandblue" + item_color = "blue" + desc = "It's a blue bandana." obj/item/clothing/mask/bandana/gold name = "gold bandana" icon_state = "bandgold" + item_color = "yellow" + desc = "It's a gold bandana." obj/item/clothing/mask/bandana/green name = "green bandana" icon_state = "bandgreen" + item_color = "green" + desc = "It's a green bandana." + +obj/item/clothing/mask/bandana/orange + name = "orange bandana" + icon_state = "bandorange" + item_color = "orange" + desc = "It's an orange bandana." + +obj/item/clothing/mask/bandana/purple + name = "purple bandana" + icon_state = "bandpurple" + item_color = "purple" + desc = "It's a purple bandana." /obj/item/clothing/mask/bandana/botany name = "botany bandana" @@ -222,5 +242,6 @@ obj/item/clothing/mask/bandana/green /obj/item/clothing/mask/bandana/black name = "black bandana" - desc = "It's a black bandana." - icon_state = "bandblack" \ No newline at end of file + icon_state = "bandblack" + item_color = "black" + desc = "It's a black bandana." \ No newline at end of file diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index 9f334a658f8..c7d6c49c1aa 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -207,3 +207,18 @@ tools = list(/obj/item/weapon/wirecutters) time = 40 + +/obj/item/clothing/shoes/sandal/white + name = "White Sandals" + desc = "Medical sandals that nerds wear." + icon_state = "medsandal" + item_color = "medsandal" + species_restricted = null + +/obj/item/clothing/shoes/sandal/fancy + name = "Fancy Sandals" + desc = "FANCY!!." + icon_state = "fancysandal" + item_color = "fancysandal" + species_restricted = null + diff --git a/code/modules/clothing/spacesuits/rig.dm b/code/modules/clothing/spacesuits/rig.dm index 1fde42aac94..c1d1a4fb4fc 100644 --- a/code/modules/clothing/spacesuits/rig.dm +++ b/code/modules/clothing/spacesuits/rig.dm @@ -311,7 +311,7 @@ user << "You switch your helmet to travel mode. It will allow you to stand in zero pressure environments, at the cost of speed and armor." name = "blood-red hardsuit helmet" desc = "A dual-mode advanced helmet designed for work in special operations. It is in travel mode. Property of Gorlex Marauders." - flags = HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | STOPSPRESSUREDMAGE | THICKMATERIAL + flags = HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | STOPSPRESSUREDMAGE | THICKMATERIAL | NODROP flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE cold_protection = HEAD set_light(brightness_on) @@ -319,7 +319,7 @@ user << "You switch your helmet to combat mode. You will take damage in zero pressure environments, but you are more suited for a fight." name = "blood-red hardsuit helmet (combat)" desc = "A dual-mode advanced helmet designed for work in special operations. It is in combat mode. Property of Gorlex Marauders." - flags = BLOCKHAIR | THICKMATERIAL + flags = BLOCKHAIR | THICKMATERIAL | NODROP flags_inv = HIDEEARS cold_protection = null set_light(0) @@ -348,7 +348,7 @@ on = !on if(on) user << "You switch your hardsuit to travel mode. It will allow you to stand in zero pressure environments, at the cost of speed and armor." - name = "blood-red hardsuit helmet" + name = "blood-red hardsuit" desc = "A dual-mode advanced hardsuit designed for work in special operations. It is in travel mode. Property of Gorlex Marauders." slowdown = 1 flags = STOPSPRESSUREDMAGE | THICKMATERIAL @@ -356,7 +356,7 @@ cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS else user << "You switch your hardsuit to combat mode. You will take damage in zero pressure environments, but you are more suited for a fight." - name = "blood-red hardsuit helmet (combat)" + name = "blood-red hardsuit (combat)" desc = "A dual-mode advanced hardsuit designed for work in special operations. It is in combat mode. Property of Gorlex Marauders." slowdown = 0 flags = THICKMATERIAL @@ -379,6 +379,15 @@ max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT sprite_sheets = null +/obj/item/clothing/head/helmet/space/rig/syndi/elite/attack_self(mob/user) + ..() + if(on) + name = "elite syndicate hardsuit helmet" + desc = "An elite version of the syndicate helmet, with improved armour and fire shielding. It is in travel mode. Property of Gorlex Marauders." + else + name = "elite syndicate hardsuit helmet (combat)" + desc = "An elite version of the syndicate helmet, with improved armour and fire shielding. It is in combat mode. Property of Gorlex Marauders." + /obj/item/clothing/suit/space/rig/syndi/elite name = "elite syndicate hardsuit" desc = "An elite version of the syndicate hardsuit, with improved armour and fire shielding. It is in travel mode." @@ -389,6 +398,15 @@ max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT sprite_sheets = null +/obj/item/clothing/suit/space/rig/syndi/elite/attack_self(mob/user) + ..() + if(on) + name = "elite syndicate hardsuit" + desc = "An elite version of the syndicate hardsuit, with improved armour and fire shielding. It is in travel mode. Property of Gorlex Marauders." + else + name = "elite syndicate hardsuit (combat)" + desc = "An elite version of the syndicate hardsuit, with improved armour and fire shielding. It is in combat mode. Property of Gorlex Marauders." + //Wizard Rig /obj/item/clothing/head/helmet/space/rig/wizard name = "gem-encrusted hardsuit helmet" diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index a6a8ad4b244..8776cb6ace9 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -67,26 +67,13 @@ /obj/item/clothing/suit/armor/hos/alt name = "armored trenchoat" desc = "A trenchcoat enchanced with a special lightweight kevlar. The epitome of tactical plainclothes." - icon_state = "hostrench" - item_state = "hostrench" + icon_state = "hostrench_open" + item_state = "hostrench_open" flags_inv = 0 - - verb/toggle() - set name = "Toggle Trenchcoat Buttons" - set category = "Object" - - if(!usr.canmove || usr.stat || usr.restrained()) - return 0 - if(icon_state == "hostrench") - icon_state = "hostrench_button" - item_state = "hostrench_button" - usr<< "You button the [src]." - else - icon_state = "hostrench" - item_state = "hostrench" - usr<< "You unbutton the [src]." - - usr.update_inv_wear_suit() + ignore_suitadjust = 0 + suit_adjusted = 1 + action_button_name = "Open/Close Trenchcoat" + adjust_flavour = "unbutton" /obj/item/clothing/suit/armor/hos/jensen name = "armored trenchcoat" diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm index 78820a130dc..6bd40d8029d 100644 --- a/code/modules/clothing/suits/jobs.dm +++ b/code/modules/clothing/suits/jobs.dm @@ -97,7 +97,7 @@ //Chef /obj/item/clothing/suit/chef - name = "Chef's apron" + name = "chef's apron" desc = "An apron used by a high class chef." icon_state = "chef" item_state = "chef" @@ -112,7 +112,7 @@ //Chef /obj/item/clothing/suit/chef/classic - name = "A classic chef's apron." + name = "classic chef's apron" desc = "A basic, dull, white chef's apron." icon_state = "apronchef" item_state = "apronchef" @@ -166,7 +166,7 @@ name = "blueshield coat" desc = "NT deluxe ripoff. You finally have your own coat." icon_state = "blueshieldcoat" - item_state = "det_suit" + item_state = "blueshieldcoat" blood_overlay_type = "coat" body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/gun/projectile,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/device/flashlight/seclite,/obj/item/weapon/melee/classic_baton/telescopic) @@ -190,23 +190,31 @@ //Lawyer /obj/item/clothing/suit/storage/lawyer/blackjacket - name = "Black Suit Jacket" + name = "black suit jacket" desc = "A snappy dress jacket." icon_state = "suitjacket_black_open" item_state = "suitjacket_black_open" blood_overlay_type = "coat" body_parts_covered = UPPER_TORSO|ARMS + ignore_suitadjust = 0 + suit_adjusted = 1 + action_button_name = "Button/Unbutton Jacket" + adjust_flavour = "unbutton" /obj/item/clothing/suit/storage/lawyer/bluejacket - name = "Blue Suit Jacket" + name = "blue suit jacket" desc = "A snappy dress jacket." icon_state = "suitjacket_blue_open" item_state = "suitjacket_blue_open" blood_overlay_type = "coat" body_parts_covered = UPPER_TORSO|ARMS + ignore_suitadjust = 0 + suit_adjusted = 1 + action_button_name = "Button/Unbutton Jacket" + adjust_flavour = "unbutton" /obj/item/clothing/suit/storage/lawyer/purpjacket - name = "Purple Suit Jacket" + name = "purple suit jacket" desc = "A snappy dress jacket." icon_state = "suitjacket_purp" item_state = "suitjacket_purp" @@ -215,87 +223,41 @@ //Internal Affairs /obj/item/clothing/suit/storage/internalaffairs - name = "Internal Affairs Jacket" + name = "\improper Internal Affairs jacket" desc = "A smooth black jacket." icon_state = "ia_jacket_open" - item_state = "ia_jacket" + item_state = "ia_jacket_open" blood_overlay_type = "coat" body_parts_covered = UPPER_TORSO|ARMS - - verb/toggle() - set name = "Toggle Coat Buttons" - set category = "Object" - set src in usr - - if(!usr.canmove || usr.stat || usr.restrained()) - return 0 - - switch(icon_state) - if("ia_jacket_open") - src.icon_state = "ia_jacket" - usr << "You button up the jacket." - if("ia_jacket") - src.icon_state = "ia_jacket_open" - usr << "You unbutton the jacket." - else - usr << "You attempt to button-up the velcro on your [src], before promptly realising how retarded you are." - return - usr.update_inv_wear_suit() //so our overlays update + ignore_suitadjust = 0 + suit_adjusted = 1 + action_button_name = "Button/Unbutton Jacket" + adjust_flavour = "unbutton" /obj/item/clothing/suit/storage/ntrep - name = "NanoTrasen Representative Jacket" + name = "\improper NanoTrasen Representative jacket" desc = "A fancy black jacket, standard issue to NanoTrasen Represenatives." icon_state = "ntrep" - item_state = "ia_jacket" + item_state = "ntrep" blood_overlay_type = "coat" body_parts_covered = UPPER_TORSO|ARMS - - verb/toggle() - set name = "Toggle Coat Buttons" - set category = "Object" - set src in usr - - if(!usr.canmove || usr.stat || usr.restrained()) - return 0 - - switch(icon_state) - if("ntrep_open") - src.icon_state = "ntrep" - usr << "You button up the jacket." - if("ntrep") - src.icon_state = "ntrep_open" - usr << "You unbutton the jacket." - else - usr << "You attempt to button-up the velcro on your [src], before promptly realising how retarded you are." - return - usr.update_inv_wear_suit() //so our overlays update + ignore_suitadjust = 0 + action_button_name = "Button/Unbutton Jacket" + adjust_flavour = "unbutton" //Medical /obj/item/clothing/suit/storage/fr_jacket name = "first responder jacket" desc = "A high-visibility jacket worn by medical first responders." icon_state = "fr_jacket_open" - item_state = "fr_jacket" + item_state = "fr_jacket_open" blood_overlay_type = "armor" allowed = list(/obj/item/stack/medical, /obj/item/weapon/reagent_containers/dropper, /obj/item/weapon/reagent_containers/hypospray, /obj/item/weapon/reagent_containers/syringe, \ /obj/item/device/healthanalyzer, /obj/item/device/antibody_scanner, /obj/item/device/flashlight, /obj/item/device/radio, /obj/item/weapon/tank/emergency_oxygen,/obj/item/device/rad_laser) - - verb/toggle() - set name = "Toggle Jacket Buttons" - set category = "Object" - set src in usr - - if(!usr.canmove || usr.stat || usr.restrained()) - return 0 - - switch(icon_state) - if("fr_jacket_open") - src.icon_state = "fr_jacket" - usr << "You button up the jacket." - if("fr_jacket") - src.icon_state = "fr_jacket_open" - usr << "You unbutton the jacket." - usr.update_inv_wear_suit() //so our overlays update + ignore_suitadjust = 0 + suit_adjusted = 1 + action_button_name = "Button/Unbutton Jacket" + adjust_flavour = "unbutton" //Mime /obj/item/clothing/suit/suspenders diff --git a/code/modules/clothing/suits/labcoat.dm b/code/modules/clothing/suits/labcoat.dm index bad3378da22..1591b8fbcc3 100644 --- a/code/modules/clothing/suits/labcoat.dm +++ b/code/modules/clothing/suits/labcoat.dm @@ -2,118 +2,62 @@ name = "labcoat" desc = "A suit that protects against minor chemical spills." icon_state = "labcoat_open" - item_state = "labcoat" + item_state = "labcoat_open" + ignore_suitadjust = 0 + suit_adjusted = 1 blood_overlay_type = "coat" body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS allowed = list(/obj/item/device/analyzer,/obj/item/device/antibody_scanner,/obj/item/stack/medical,/obj/item/weapon/dnainjector,/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/syringe,/obj/item/weapon/reagent_containers/hypospray,/obj/item/device/healthanalyzer,/obj/item/device/flashlight/pen,/obj/item/weapon/reagent_containers/glass/bottle,/obj/item/weapon/reagent_containers/glass/beaker,/obj/item/weapon/reagent_containers/pill,/obj/item/weapon/storage/pill_bottle,/obj/item/weapon/paper,/obj/item/device/rad_laser) - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 50, rad = 0) + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 50, rad = 0) species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/suit.dmi' ) - - verb/toggle() - set name = "Toggle Labcoat Buttons" - set category = "Object" - set src in usr - - if(!usr.canmove || usr.stat || usr.restrained()) - return 0 - - switch(icon_state) - if("labcoat_open") - src.icon_state = "labcoat" - usr << "You button up the labcoat." - if("labcoat") - src.icon_state = "labcoat_open" - usr << "You unbutton the labcoat." - if("labcoat_cmo_open") - src.icon_state = "labcoat_cmo" - usr << "You button up the labcoat." - if("labcoat_cmo") - src.icon_state = "labcoat_cmo_open" - usr << "You unbutton the labcoat." - if("labcoat_gen_open") - src.icon_state = "labcoat_gen" - usr << "You button up the labcoat." - if("labcoat_gen") - src.icon_state = "labcoat_gen_open" - usr << "You unbutton the labcoat." - if("labcoat_chem_open") - src.icon_state = "labcoat_chem" - usr << "You button up the labcoat." - if("labcoat_chem") - src.icon_state = "labcoat_chem_open" - usr << "You unbutton the labcoat." - if("labcoat_vir_open") - src.icon_state = "labcoat_vir" - usr << "You button up the labcoat." - if("labcoat_vir") - src.icon_state = "labcoat_vir_open" - usr << "You unbutton the labcoat." - if("labcoat_tox_open") - src.icon_state = "labcoat_tox" - usr << "You button up the labcoat." - if("labcoat_tox") - src.icon_state = "labcoat_tox_open" - usr << "You unbutton the labcoat." - if("labgreen_open") - src.icon_state = "labgreen" - usr << "You button up the labcoat." - if("labgreen") - src.icon_state = "labgreen_open" - usr << "You unbutton the labcoat." - if("labcoat_mort_open") - src.icon_state = "labcoat_mort" - usr << "You button up the labcoat." - if("labcoat_mort") - src.icon_state = "labcoat_mort_open" - usr << "You unbutton the labcoat." - else - usr << "You attempt to button-up the velcro on your [src], before promptly realising how retarded you are." - return - usr.update_inv_wear_suit() //so our overlays update + action_button_name = "Button/Unbutton Labcoat" + adjust_flavour = "unbutton" /obj/item/clothing/suit/storage/labcoat/cmo name = "chief medical officer's labcoat" desc = "Bluer than the standard model." icon_state = "labcoat_cmo_open" - item_state = "labcoat_cmo" + item_state = "labcoat_cmo_open" species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/suit.dmi' ) /obj/item/clothing/suit/storage/labcoat/mad - name = "The Mad Scientist's labcoat" + name = "mad scientist's labcoat" desc = "It makes you look capable of konking someone on the noggin and shooting them into space." icon_state = "labcoat_green_open" - item_state = "labcoat_green" + item_state = "labcoat_green_open" species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/suit.dmi' ) /obj/item/clothing/suit/storage/labcoat/genetics - name = "Geneticist Labcoat" + name = "geneticist labcoat" desc = "A suit that protects against minor chemical spills. Has a blue stripe on the shoulder." icon_state = "labcoat_gen_open" + item_state = "labcoat_gen_open" species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/suit.dmi' ) /obj/item/clothing/suit/storage/labcoat/chemist - name = "Chemist Labcoat" + name = "chemist labcoat" desc = "A suit that protects against minor chemical spills. Has an orange stripe on the shoulder." icon_state = "labcoat_chem_open" + item_state = "labcoat_chem_open" species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/suit.dmi' ) /obj/item/clothing/suit/storage/labcoat/virologist - name = "Virologist Labcoat" + name = "virologist labcoat" desc = "A suit that protects against minor chemical spills. Offers slightly more protection against biohazards than the standard model. Has a green stripe on the shoulder." icon_state = "labcoat_vir_open" species_fit = list("Vox") @@ -122,18 +66,20 @@ ) /obj/item/clothing/suit/storage/labcoat/science - name = "Scientist Labcoat" + name = "scientist labcoat" desc = "A suit that protects against minor chemical spills. Has a purple stripe on the shoulder." icon_state = "labcoat_tox_open" + item_state = "labcoat_tox_open" species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/suit.dmi' ) /obj/item/clothing/suit/storage/labcoat/mortician - name = "Coroner Labcoat" + name = "coroner labcoat" desc = "A suit that protects against minor chemical spills. Has a black stripe on the shoulder." icon_state = "labcoat_mort_open" + item_state = "labcoat_mort_open" species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/suit.dmi' diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index 52d3065241d..f4c1d7f5967 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -10,7 +10,7 @@ */ /obj/item/clothing/suit/bluetag name = "blue laser tag armour" - desc = "Blue Pride, Station Wide" + desc = "Blue Pride, Station Wide." icon_state = "bluetag" item_state = "bluetag" blood_overlay_type = "armor" @@ -19,7 +19,7 @@ /obj/item/clothing/suit/redtag name = "red laser tag armour" - desc = "Pew pew pew" + desc = "Pew pew pew." icon_state = "redtag" item_state = "redtag" blood_overlay_type = "armor" @@ -62,7 +62,7 @@ /obj/item/clothing/suit/greatcoat name = "great coat" - desc = "A Nazi great coat" + desc = "A Nazi great coat." icon_state = "nazi" item_state = "nazi" @@ -120,8 +120,8 @@ /obj/item/clothing/suit/hastur - name = "Hastur's Robes" - desc = "Robes not meant to be worn by man" + name = "Hastur's robes" + desc = "Robes not meant to be worn by man." icon_state = "hastur" item_state = "hastur" body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS @@ -129,8 +129,8 @@ /obj/item/clothing/suit/imperium_monk - name = "Imperium monk" - desc = "Have YOU killed a xenos today?" + name = "imperium monk" + desc = "Have YOU killed a xeno today?" icon_state = "imperium_monk" item_state = "imperium_monk" body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS @@ -138,7 +138,7 @@ allowed = list(/obj/item/weapon/storage/bible, /obj/item/weapon/nullrod, /obj/item/weapon/reagent_containers/food/drinks/bottle/holywater, /obj/item/weapon/storage/fancy/candle_box, /obj/item/candle, /obj/item/weapon/tank/emergency_oxygen) /obj/item/clothing/suit/chickensuit - name = "Chicken Suit" + name = "chicken suit" desc = "A suit made long ago by the ancient empire KFC." icon_state = "chickensuit" item_state = "chickensuit" @@ -146,7 +146,7 @@ flags_inv = HIDESHOES|HIDEJUMPSUIT /obj/item/clothing/suit/corgisuit - name = "Corgi Suit" + name = "corgi suit" desc = "A suit made long ago by the ancient empire KFC." icon_state = "corgisuit" item_state = "chickensuit" @@ -155,7 +155,7 @@ flags = NODROP /obj/item/clothing/suit/corgisuit/en - name = "E-N Suit" + name = "\improper E-N suit" icon_state = "ensuit" /obj/item/clothing/suit/corgisuit/en/New() @@ -174,7 +174,7 @@ step_towards(M,src) /obj/item/clothing/suit/monkeysuit - name = "Monkey Suit" + name = "monkey suit" desc = "A suit that looks like a primate" icon_state = "monkeysuit" item_state = "monkeysuit" @@ -183,7 +183,7 @@ /obj/item/clothing/suit/holidaypriest - name = "Holiday Priest" + name = "holiday priest" desc = "This is a nice holiday my son." icon_state = "holidaypriest" item_state = "holidaypriest" @@ -244,28 +244,6 @@ icon_state = "ianshirt" item_state = "ianshirt" -//Blue suit jacket toggle -/obj/item/clothing/suit/suit/verb/toggle() - set name = "Toggle Jacket Buttons" - set category = "Object" - set src in usr - - if(!usr.canmove || usr.stat || usr.restrained()) - return 0 - - if(src.icon_state == "suitjacket_blue_open") - src.icon_state = "suitjacket_blue" - src.item_state = "suitjacket_blue" - usr << "You button up the suit jacket." - else if(src.icon_state == "suitjacket_blue") - src.icon_state = "suitjacket_blue_open" - src.item_state = "suitjacket_blue_open" - usr << "You unbutton the suit jacket." - else - usr << "You button-up some imaginary buttons on your [src]." - return - usr.update_inv_wear_suit() - //pyjamas //originally intended to be pinstripes >.> @@ -361,6 +339,9 @@ desc = "A canvas jacket styled after classical American military garb. Feels sturdy, yet comfortable." icon_state = "militaryjacket" item_state = "militaryjacket" + ignore_suitadjust = 1 + action_button_name = null + adjust_flavour = null allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen,/obj/item/toy,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter,/obj/item/weapon/gun/projectile/automatic/pistol,/obj/item/weapon/gun/projectile/revolver,/obj/item/weapon/gun/projectile/revolver/detective) /obj/item/clothing/suit/xenos @@ -406,8 +387,8 @@ item_color = "swim_red" /obj/item/clothing/suit/storage/mercy_hoodie - name = "Mercy Robe" - desc = " A soft white robe made of a synthetic fiber that provides improved protection against biohazards. Possessing multiple overlapping layers, yet light enough to allow complete freedom of movement, it denotes its wearer as a master physician." + name = "mercy robe" + desc = "A soft white robe made of a synthetic fiber that provides improved protection against biohazards. Possessing multiple overlapping layers, yet light enough to allow complete freedom of movement, it denotes its wearer as a master physician." icon_state = "mercy_hoodie" item_state = "mercy_hoodie" w_class = 4//bulky item @@ -434,14 +415,37 @@ desc = "Aviators not included." icon_state = "bomber" item_state = "bomber" + ignore_suitadjust = 0 allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen,/obj/item/toy,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter) body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS cold_protection = UPPER_TORSO|LOWER_TORSO|ARMS + action_button_name = "Zip/Unzip Jacket" + adjust_flavour = "unzip" + +/obj/item/clothing/suit/jacket/pilot + name = "security bomber jacket" + desc = "A stylish and worn-in armoured black bomber jacket emblazoned with the NT Security crest on the left breast. Looks rugged." + icon_state = "bombersec" + item_state = "bombersec" + ignore_suitadjust = 0 + //Inherited from Security armour. + allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/gun/projectile,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/device/flashlight/seclite,/obj/item/weapon/melee/classic_baton/telescopic,/obj/item/weapon/kitchen/knife/combat) + heat_protection = UPPER_TORSO|LOWER_TORSO + min_cold_protection_temperature = ARMOR_MIN_TEMP_PROTECT + max_heat_protection_temperature = ARMOR_MAX_TEMP_PROTECT + strip_delay = 60 + put_on_delay = 40 + flags = ONESIZEFITSALL + armor = list(melee = 50, bullet = 15, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0) + //End of inheritance from Security armour. /obj/item/clothing/suit/jacket/leather name = "leather jacket" desc = "Pompadour not included." icon_state = "leatherjacket" + ignore_suitadjust = 1 + action_button_name = null + adjust_flavour = null /obj/item/clothing/suit/officercoat name = "Clown Officer's Coat" diff --git a/code/modules/clothing/suits/storage.dm b/code/modules/clothing/suits/storage.dm index 2c2597c0011..87520f38856 100644 --- a/code/modules/clothing/suits/storage.dm +++ b/code/modules/clothing/suits/storage.dm @@ -49,4 +49,4 @@ L += G.gift if (istype(G.gift, /obj/item/weapon/storage)) L += G.gift:return_inv() - return L \ No newline at end of file + return L diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm index bdf0c955ca4..c7712fef200 100644 --- a/code/modules/clothing/under/accessories/accessory.dm +++ b/code/modules/clothing/under/accessories/accessory.dm @@ -34,6 +34,23 @@ usr.put_in_hands(src) src.add_fingerprint(user) +/obj/item/clothing/accessory/attack(mob/living/carbon/human/H, mob/living/user) + // This code lets you put accessories on other people by attacking their sprite with the accessory + if(istype(H)) + if(H.wear_suit && H.wear_suit.flags_inv & HIDEJUMPSUIT) + user << "[H]'s body is covered, and you cannot attach \the [src]." + return 1 + var/obj/item/clothing/under/U = H.w_uniform + if(istype(U)) + user.visible_message("[user] is putting a [src.name] on [H]'s [U.name]!", "You begin to put a [src.name] on [H]'s [U.name]...") + if(do_after(user,40,target=H) && H.w_uniform == U) + user.visible_message("[user] puts a [src.name] on [H]'s [U.name]!", "You finish putting a [src.name] on [H]'s [U.name].") + U.attackby(src, user) + else + user << "[H] is not wearing anything to attach \the [src] to." + return 1 + return ..() + //default attackby behaviour /obj/item/clothing/accessory/attackby(obj/item/I, mob/user, params) ..() diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index d4213034f30..59e9f96f95d 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -68,15 +68,15 @@ item_color = "vice" /obj/item/clothing/under/rank/centcom_officer - desc = "It's a jumpsuit worn by CentCom Officers." - name = "\improper CentCom officer's jumpsuit" + desc = "It's a jumpsuit worn by CentComm Officers." + name = "\improper CentComm officer's jumpsuit" icon_state = "officer" item_state = "g_suit" item_color = "officer" /obj/item/clothing/under/rank/centcom_commander - desc = "It's a jumpsuit worn by CentCom's highest-tier Commanders." - name = "\improper CentCom officer's jumpsuit" + desc = "It's a jumpsuit worn by CentComm's highest-tier Commanders." + name = "\improper CentComm officer's jumpsuit" icon_state = "centcom" item_state = "dg_suit" item_color = "centcom" diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index 632dcff8d32..cd86004052b 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -137,6 +137,9 @@ icon = 'icons/obj/custom_items.dmi' icon_state = "kidosvest" item_state = "kidosvest" + ignore_suitadjust = 1 + action_button_name = null + adjust_flavour = null /obj/item/clothing/suit/fluff/kluys // Kluys: Cripty Pandaen name = "Nano Fibre Jacket" @@ -246,6 +249,9 @@ icon = 'icons/obj/custom_items.dmi' icon_state = "fox_jacket" item_state = "fox_jacket" + ignore_suitadjust = 1 + action_button_name = null + adjust_flavour = null /obj/item/clothing/under/fluff/fox name = "Aeronautics Jumpsuit" diff --git a/code/modules/economy/utils.dm b/code/modules/economy/utils.dm index 44b5ebdd036..a23308b9219 100644 --- a/code/modules/economy/utils.dm +++ b/code/modules/economy/utils.dm @@ -47,6 +47,10 @@ return "$[num2septext(money)]" /datum/money_account/proc/charge(var/transaction_amount,var/datum/money_account/dest,var/transaction_purpose, var/terminal_name="", var/terminal_id=0, var/dest_name = "UNKNOWN") + if(suspended) + usr << "Unable to access source account: account suspended." + return 0 + if(transaction_amount <= money) //transfer the money money -= transaction_amount @@ -84,5 +88,5 @@ transaction_log.Add(T) return 1 else - usr << "\icon[src]You don't have that much money!" + usr << "Insufficient funds in account." return 0 \ No newline at end of file diff --git a/code/modules/events/money_spam.dm b/code/modules/events/money_spam.dm index 2bafc9f3cc9..37a29a00bbd 100644 --- a/code/modules/events/money_spam.dm +++ b/code/modules/events/money_spam.dm @@ -27,16 +27,18 @@ if(useMS) if(prob(5)) // /obj/machinery/message_server/proc/send_pda_message(var/recipient = "",var/sender = "",var/message = "") - var/obj/item/device/pda/P var/list/viables = list() for(var/obj/item/device/pda/check_pda in PDAs) - if (!check_pda.owner||check_pda.toff||check_pda == src||check_pda.hidden) + var/datum/data/pda/app/messenger/check_m = check_pda.find_program(/datum/data/pda/app/messenger) + + if (!check_m || !check_m.can_receive()) continue viables.Add(check_pda) if(!viables.len) return - P = pick(viables) + var/obj/item/device/pda/P = pick(viables) + var/datum/data/pda/app/messenger/PM = P.find_program(/datum/data/pda/app/messenger) var/sender var/message @@ -104,7 +106,7 @@ //Commented out because we don't send messages like this anymore. Instead it will just popup in their chat window. //P.tnote += "← From [sender] (Unknown / spam?):
    [message]
    " - P.play_ringtone() + PM.play_ringtone() //Search for holder of the PDA. var/mob/living/L = null if(P.loc && isliving(P.loc)) diff --git a/code/modules/ext_scripts/irc.dm b/code/modules/ext_scripts/irc.dm index 3776f3587fb..05ac226d7e7 100644 --- a/code/modules/ext_scripts/irc.dm +++ b/code/modules/ext_scripts/irc.dm @@ -1,7 +1,8 @@ /proc/send2irc(var/channel, var/msg) - if(config.use_irc_bot && config.irc_bot_host) - spawn(0) - ext_python("ircbot_message.py", "[config.comms_password] [config.irc_bot_host] [channel] [msg]") + if(config.use_irc_bot && config.irc_bot_host.len) + for(var/IP in config.irc_bot_host) + spawn(0) + ext_python("ircbot_message.py", "[config.comms_password] [IP] [channel] [msg]") return /proc/send2mainirc(var/msg) diff --git a/code/modules/food/deep_fryer.dm b/code/modules/food/deep_fryer.dm index 4805983fdf4..96e5fb94c57 100644 --- a/code/modules/food/deep_fryer.dm +++ b/code/modules/food/deep_fryer.dm @@ -68,3 +68,7 @@ /datum/deepfryer_special/fried_tofu input = /obj/item/weapon/reagent_containers/food/snacks/tofu output = /obj/item/weapon/reagent_containers/food/snacks/fried_tofu + +/datum/deepfryer_special/chimichanga + input = /obj/item/weapon/reagent_containers/food/snacks/burrito + output = /obj/item/weapon/reagent_containers/food/snacks/chimichanga \ No newline at end of file diff --git a/code/modules/food/recipes_candy.dm b/code/modules/food/recipes_candy.dm index 881ee57a1a1..794fcb649e2 100644 --- a/code/modules/food/recipes_candy.dm +++ b/code/modules/food/recipes_candy.dm @@ -16,12 +16,12 @@ // *********************************************************** /datum/recipe/candy/chocolate_bar - reagents = list("soymilk" = 2, "coco" = 2, "sugar" = 2) + reagents = list("soymilk" = 2, "cocoa" = 2, "sugar" = 2) items = list() result = /obj/item/weapon/reagent_containers/food/snacks/chocolatebar /datum/recipe/candy/chocolate_bar2 - reagents = list("milk" = 2, "coco" = 2, "sugar" = 2) + reagents = list("milk" = 2, "cocoa" = 2, "sugar" = 2) items = list() result = /obj/item/weapon/reagent_containers/food/snacks/chocolatebar diff --git a/code/modules/food/recipes_microwave.dm b/code/modules/food/recipes_microwave.dm index 98b8e782546..3bbcc875bb4 100644 --- a/code/modules/food/recipes_microwave.dm +++ b/code/modules/food/recipes_microwave.dm @@ -76,7 +76,7 @@ /datum/recipe/microwave/brainburger items = list( /obj/item/weapon/reagent_containers/food/snacks/bun, - /obj/item/organ/brain + /obj/item/organ/internal/brain ) result = /obj/item/weapon/reagent_containers/food/snacks/brainburger @@ -280,6 +280,16 @@ ) result = /obj/item/weapon/reagent_containers/food/snacks/enchiladas +/datum/recipe/microwave/burrito + reagents = list("capsaicin" = 5, "rice" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/cutlet, + /obj/item/weapon/reagent_containers/food/snacks/beans, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + ) + result = /obj/item/weapon/reagent_containers/food/snacks/burrito + /datum/recipe/microwave/monkeysdelight fruit = list("banana" = 1) reagents = list("sodiumchloride" = 1, "blackpepper" = 1, "flour" = 10) diff --git a/code/modules/food/recipes_oven.dm b/code/modules/food/recipes_oven.dm index 914362ef45e..e919a1bbf4a 100644 --- a/code/modules/food/recipes_oven.dm +++ b/code/modules/food/recipes_oven.dm @@ -254,6 +254,11 @@ ) result = /obj/item/weapon/reagent_containers/food/snacks/plump_pie +/datum/recipe/oven/plumphelmetbiscuit + fruit = list("plumphelmet" = 1) + reagents = list("water" = 5, "flour" = 5) + result = /obj/item/weapon/reagent_containers/food/snacks/plumphelmetbiscuit + /datum/recipe/oven/creamcheesebread items = list( /obj/item/weapon/reagent_containers/food/snacks/dough, @@ -352,7 +357,7 @@ /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/organ/brain + /obj/item/organ/internal/brain ) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/braincake diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index b39ca263d02..8aa79cd6484 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -101,7 +101,7 @@ descriptors |= "nutritious" if(reagents.has_reagent("condensedcapsaicin") || reagents.has_reagent("capsaicin")) descriptors |= "spicy" - if(reagents.has_reagent("coco")) + if(reagents.has_reagent("cocoa")) descriptors |= "bitter" if(reagents.has_reagent("orangejuice") || reagents.has_reagent("lemonjuice") || reagents.has_reagent("limejuice")) descriptors |= "sweet-sour" @@ -298,7 +298,7 @@ // This is being copypasted here because reagent_containers (WHY DOES FOOD DESCEND FROM THAT) overrides it completely. // TODO: refactor all food paths to be less horrible and difficult to work with in this respect. ~Z - if(!istype(M) || (can_operate(M) && do_surgery(M,user,src))) return 0 + if(!istype(M)) return 0 if(!def_zone) def_zone = check_zone(user.zone_sel.selecting) diff --git a/code/modules/hydroponics/grown_predefined.dm b/code/modules/hydroponics/grown_predefined.dm index 44c9c3a1943..9e522ef29f2 100644 --- a/code/modules/hydroponics/grown_predefined.dm +++ b/code/modules/hydroponics/grown_predefined.dm @@ -6,6 +6,9 @@ /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris plantname = "ambrosia" +/obj/item/weapon/reagent_containers/food/snacks/grown/potato + plantname = "potato" + /obj/item/weapon/reagent_containers/food/snacks/grown/tomato plantname = "tomato" diff --git a/code/modules/hydroponics/seed_datums.dm b/code/modules/hydroponics/seed_datums.dm index 28cd89843ac..84a2f7a7fbf 100644 --- a/code/modules/hydroponics/seed_datums.dm +++ b/code/modules/hydroponics/seed_datums.dm @@ -1209,9 +1209,9 @@ /datum/seed/cocoa name = "cocoa" - seed_name = "cacao" - display_name = "cacao tree" - chems = list("plantmatter" = list(1,10), "coco" = list(4,5)) + seed_name = "cocoa" + display_name = "cocoa tree" + chems = list("plantmatter" = list(1,10), "cocoa" = list(4,5)) preset_icon = "cocoapod" /datum/seed/cocoa/New() diff --git a/code/modules/media/mediamanager.dm b/code/modules/media/mediamanager.dm index bb79596071d..3753f358500 100644 --- a/code/modules/media/mediamanager.dm +++ b/code/modules/media/mediamanager.dm @@ -58,7 +58,8 @@ if(vlc.attachEvent) { var/client/C = args["client"] C.media = new /datum/media_manager(args["mob"]) C.media.open() - C.media.update_music() + spawn(20) + C.media.update_music() // Update when moving between areas. proc/OnMobAreaChange(var/list/args) @@ -90,7 +91,6 @@ if(vlc.attachEvent) { /datum/media_manager var/url = "" var/start_time = 0 - var/volume = 25 var/client/owner var/mob/mob @@ -109,10 +109,10 @@ if(vlc.attachEvent) { // Tell the player to play something via JS. proc/send_update() - if(!(owner.prefs.toggles & SOUND_STREAMING) && url != "") + if(!(owner.prefs.sound & SOUND_STREAMING) && url != "") return // Nope. MP_DEBUG("\green Sending update to WMP ([url])...") - owner << output(list2params(list(url, (world.time - start_time) / 10, volume)), "[window]:SetMusic") + owner << output(list2params(list(url, (world.time - start_time) / 10, get_volume())), "[window]:SetMusic") proc/stop_music() url="" @@ -123,7 +123,6 @@ if(vlc.attachEvent) { proc/update_music() var/targetURL = "" var/targetStartTime = 0 - //var/targetVolume = volume if (!owner) //testing("owner is null") @@ -145,23 +144,22 @@ if(vlc.attachEvent) { if (url != targetURL || abs(targetStartTime - start_time) > 1) url = targetURL start_time = targetStartTime - //volume = targetVolume send_update() - - proc/update_volume(var/value) - volume = value - send_update() + + proc/get_volume() + return (owner && owner.prefs) ? owner.prefs.volume : 25 /client/verb/change_volume() set name = "Set Volume" set category = "Preferences" set desc = "Set jukebox volume" + if(!media || !istype(media)) usr << "You have no media datum to change, if you're not in the lobby tell an admin." return - var/value = input("Choose your Jukebox volume.", "Jukebox volume", media.volume) + var/value = input("Choose your Jukebox volume.", "Jukebox volume", media.get_volume()) value = round(max(0, min(100, value))) - media.update_volume(value) if(prefs) prefs.volume = value prefs.save_preferences(src) + media.send_update() \ No newline at end of file diff --git a/code/modules/mining/equipment_locker.dm b/code/modules/mining/equipment_locker.dm index 1de1b266a47..5b17b4574b3 100644 --- a/code/modules/mining/equipment_locker.dm +++ b/code/modules/mining/equipment_locker.dm @@ -332,6 +332,8 @@ new /datum/data/mining_equipment("Resonator", /obj/item/weapon/resonator, 800), new /datum/data/mining_equipment("Lazarus Injector", /obj/item/weapon/lazarus_injector, 1000), new /datum/data/mining_equipment("Silver Pickaxe", /obj/item/weapon/pickaxe/silver, 1000), + new /datum/data/mining_equipment("Lazarus Capsule", /obj/item/device/mobcapsule, 800), + new /datum/data/mining_equipment("Lazarus Capsule belt",/obj/item/weapon/storage/belt/lazarus, 200), new /datum/data/mining_equipment("Jetpack", /obj/item/weapon/tank/jetpack/carbondioxide/mining, 2000), new /datum/data/mining_equipment("Space Cash", /obj/item/weapon/spacecash/c1000, 2000), new /datum/data/mining_equipment("Diamond Pickaxe", /obj/item/weapon/pickaxe/diamond, 2000), @@ -719,7 +721,7 @@ speak_emote = list("states") wanted_objects = list(/obj/item/weapon/ore/diamond, /obj/item/weapon/ore/gold, /obj/item/weapon/ore/silver, /obj/item/weapon/ore/plasma, /obj/item/weapon/ore/uranium, /obj/item/weapon/ore/iron, - /obj/item/weapon/ore/bananium) + /obj/item/weapon/ore/bananium, /obj/item/weapon/ore/glass) /mob/living/simple_animal/hostile/mining_drone/attackby(obj/item/I as obj, mob/user as mob, params) if(istype(I, /obj/item/weapon/weldingtool)) @@ -985,11 +987,11 @@ w_class = 1 origin_tech = "biotech=1" -/obj/item/weapon/hivelordstabilizer/afterattack(obj/item/M, mob/user) - var/obj/item/asteroid/hivelord_core/C = M - if(!istype(C, /obj/item/asteroid/hivelord_core)) +/obj/item/weapon/hivelordstabilizer/afterattack(obj/item/organ/internal/M, mob/user) + var/obj/item/organ/internal/hivelord_core/C = M + if(!istype(C, /obj/item/organ/internal/hivelord_core)) user << "The stabilizer only works on hivelord cores." return ..() C.preserved = 1 user << "You inject the hivelord core with the stabilizer. It will no longer go inert." - qdel(src) + qdel(src) \ No newline at end of file diff --git a/code/modules/mining/mine_areas.dm b/code/modules/mining/mine_areas.dm index b89bdcd1b56..ba8a3053ed9 100644 --- a/code/modules/mining/mine_areas.dm +++ b/code/modules/mining/mine_areas.dm @@ -28,10 +28,10 @@ ambientsounds = list('sound/ambience/ambimine.ogg') /area/mine/lobby - name = "Mining station" + name = "Mining Station" /area/mine/storage - name = "Mining station Storage" + name = "Mining Station Storage" /area/mine/production name = "Mining Station Starboard Wing" @@ -52,13 +52,13 @@ name = "Mining Station Communications" /area/mine/cafeteria - name = "Mining station Cafeteria" + name = "Mining Station Cafeteria" /area/mine/hydroponics - name = "Mining station Hydroponics" + name = "Mining Station Hydroponics" /area/mine/sleeper - name = "Mining station Emergency Sleeper" + name = "Mining Station Emergency Sleeper" /area/mine/north_outpost name = "North Mining Outpost" diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index 9c52dc7751f..3e5cdd0bb51 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -192,3 +192,61 @@ icon_opened = "miningcaropen" icon_closed = "miningcar" +/*********************Mob Capsule*************************/ + +/obj/item/device/mobcapsule + name = "lazarus capsule" + desc = "It allows you to store and deploy lazarus-injected creatures easier." + icon = 'icons/obj/mobcap.dmi' + icon_state = "mobcap0" + w_class = 1.0 + throw_range = 20 + var/mob/living/simple_animal/captured = null + var/colorindex = 0 + +/obj/item/device/mobcapsule/Destroy() + if(captured) + qdel(captured) + captured = null + return ..() + +/obj/item/device/mobcapsule/attack(var/atom/A, mob/user, prox_flag) + if(!istype(A, /mob/living/simple_animal)) + return ..() + capture(A, user) + return 1 + +/obj/item/device/mobcapsule/proc/capture(var/mob/target, var/mob/U as mob) + var/mob/living/simple_animal/T = target + if(captured) + U << "Capture failed!: The capsule already has a mob registered to it!" + else + if(istype(T) && "neutral" in T.faction) + T.forceMove(src) + T.name = "[U.name]'s [initial(T.name)]" + T.cancel_camera() + name = "Lazarus Capsule: [initial(T.name)]" + U << "You placed a [T.name] inside the Lazarus Capsule!" + captured = T + else + U << "You can't capture that mob!" + +/obj/item/device/mobcapsule/throw_impact(atom/A, mob/user) + ..() + if(captured) + dump_contents(user) + +/obj/item/device/mobcapsule/proc/dump_contents(mob/user) + if(captured) + captured.forceMove(get_turf(src)) + if(captured.client) + captured.client.eye = captured.client.mob + captured.client.perspective = MOB_PERSPECTIVE + captured = null + +/obj/item/device/mobcapsule/attack_self(mob/user) + colorindex += 1 + if(colorindex >= 6) + colorindex = 0 + icon_state = "mobcap[colorindex]" + update_icon() \ No newline at end of file diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm index be291902af4..60108127dd3 100644 --- a/code/modules/mining/mine_turfs.dm +++ b/code/modules/mining/mine_turfs.dm @@ -468,7 +468,6 @@ var/global/list/rockTurfEdgeCache return user << "You start digging..." - playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1) //FUCK YO RUSTLE I GOT'S THE DIGS SOUND HERE sleep(20) if ((user.loc == T && user.get_active_hand() == W)) @@ -487,7 +486,6 @@ var/global/list/rockTurfEdgeCache return user << "You start digging..." - playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1) //FUCK YO RUSTLE I GOT'S THE DIGS SOUND HERE sleep(P.digspeed) if ((user.loc == T && user.get_active_hand() == W)) @@ -502,6 +500,12 @@ var/global/list/rockTurfEdgeCache O.attackby(W,user) return +/turf/simulated/floor/plating/airless/asteroid/gets_drilled() + if(!dug) + gets_dug() + else + ..() + /turf/simulated/floor/plating/airless/asteroid/proc/gets_dug() if(dug) return @@ -511,6 +515,7 @@ var/global/list/rockTurfEdgeCache new/obj/item/weapon/ore/glass(src) new/obj/item/weapon/ore/glass(src) dug = 1 + playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1) //FUCK YO RUSTLE I GOT'S THE DIGS SOUND HERE icon_plating = "asteroid_dug" icon_state = "asteroid_dug" return @@ -537,22 +542,6 @@ var/global/list/rockTurfEdgeCache for (var/turf/t in range(1,src)) t.updateMineralOverlays() - - -/turf/simulated/floor/plating/airless/asteroid/Entered(atom/movable/M as mob|obj) - ..() - if(istype(M,/mob/living/silicon/robot)) - var/mob/living/silicon/robot/R = M - if(istype(R.module, /obj/item/weapon/robot_module/miner)) - if(istype(R.module_state_1,/obj/item/weapon/storage/bag/ore)) - attackby(R.module_state_1,R) - else if(istype(R.module_state_2,/obj/item/weapon/storage/bag/ore)) - attackby(R.module_state_2,R) - else if(istype(R.module_state_3,/obj/item/weapon/storage/bag/ore)) - attackby(R.module_state_3,R) - else - return - /turf/simulated/floor/plating/airless/asteroid/cave var/length = 100 var/mob_spawn_list = list("Goldgrub" = 1, "Goliath" = 5, "Basilisk" = 4, "Hivelord" = 3) diff --git a/code/modules/mining/ore.dm b/code/modules/mining/ore.dm index f1def2e0270..db4bcf21859 100644 --- a/code/modules/mining/ore.dm +++ b/code/modules/mining/ore.dm @@ -16,6 +16,29 @@ user << "Not enough fuel to smelt [src]." ..() +/obj/item/weapon/ore/Crossed(AM as mob|obj) + var/obj/item/weapon/storage/bag/ore/OB + var/turf/simulated/floor/F = get_turf(src) + if(loc != F) + return ..() + if(ishuman(AM)) + var/mob/living/carbon/human/H = AM + for(var/thing in H.get_body_slots()) + if(istype(thing, /obj/item/weapon/storage/bag/ore)) + OB = thing + break + else if(isrobot(AM)) + var/mob/living/silicon/robot/R = AM + for(var/thing in R.get_all_slots()) + if(istype(thing, /obj/item/weapon/storage/bag/ore)) + OB = thing + break + if(OB && istype(F, /turf/simulated/floor/plating/airless/asteroid)) + F.attackby(OB, AM) + return ..() + + + /obj/item/weapon/ore/uranium name = "uranium ore" icon_state = "Uranium ore" diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm index 2e50777a05e..265c7697de2 100644 --- a/code/modules/mob/language.dm +++ b/code/modules/mob/language.dm @@ -366,7 +366,7 @@ var/mob/living/carbon/M = other if(!istype(M)) return 1 - if(locate(/obj/item/organ/wryn/hivenode) in M.internal_organs) + if(locate(/obj/item/organ/internal/wryn/hivenode) in M.internal_organs) return 1 return 0 diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index e58b3420c93..3dc4575a20b 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -10,8 +10,6 @@ gender = NEUTER dna = null - var/storedPlasma = 250 - var/max_plasma = 500 alien_talk_understand = 1 @@ -24,7 +22,6 @@ status_flags = CANPARALYSE|CANPUSH var/heal_rate = 5 - var/plasma_rate = 5 var/large = 0 var/heat_protection = 0.5 @@ -34,7 +31,10 @@ /mob/living/carbon/alien/New() verbs += /mob/living/carbon/verb/mob_sleep verbs += /mob/living/verb/lay_down - internal_organs += new /obj/item/organ/brain/xeno + internal_organs += new /obj/item/organ/internal/brain/xeno + internal_organs += new /obj/item/organ/internal/xenos/hivenode + for(var/obj/item/organ/internal/I in internal_organs) + I.insert(src) ..() /mob/living/carbon/alien/get_default_language() @@ -57,8 +57,6 @@ /mob/living/carbon/alien/adjustToxLoss(amount) - storedPlasma = min(max(storedPlasma + amount,0),max_plasma) //upper limit of max_plasma, lower limit of 0 - updatePlasmaDisplay() return /mob/living/carbon/alien/adjustFireLoss(amount) // Weak to Fire @@ -68,8 +66,6 @@ ..(amount) return -/mob/living/carbon/alien/proc/getPlasma() - return storedPlasma /mob/living/carbon/alien/eyecheck() return 2 @@ -83,15 +79,6 @@ /mob/living/carbon/alien/handle_environment(var/datum/gas_mixture/environment) - //If there are alien weeds on the ground then heal if needed or give some toxins - if(locate(/obj/structure/alien/weeds) in loc) - if(health >= maxHealth - getCloneLoss()) - adjustToxLoss(plasma_rate) - else - adjustBruteLoss(-heal_rate) - adjustFireLoss(-heal_rate) - adjustOxyLoss(-heal_rate) - if(!environment) return @@ -178,18 +165,14 @@ ..() - if (client.statpanel == "Status") - stat(null, "Plasma Stored: [getPlasma()]/[max_plasma]") show_stat_emergency_shuttle_eta() -/mob/living/carbon/alien/Stun(amount) - if(status_flags & CANSTUN) - stunned = max(max(stunned,amount),0) //can't go below 0, getting a low amount of stun doesn't lower your current stun - else +/mob/living/carbon/alien/SetStunned(amount) + ..(amount) + if(!(status_flags & CANSTUN) && amount) // add some movement delay move_delay_add = min(move_delay_add + round(amount / 2), 10) // a maximum delay of 10 - return /mob/living/carbon/alien/getDNA() return null @@ -255,9 +238,10 @@ Des: Gives the client of the alien an image on each infected mob. if (client) for (var/mob/living/C in mob_list) if(C.status_flags & XENO_HOST) - var/obj/item/alien_embryo/A = locate() in C - var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[A.stage]") - client.images += I + var/obj/item/organ/internal/body_egg/alien_embryo/A = C.get_int_organ(/obj/item/organ/internal/body_egg/alien_embryo) + if(A) + var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[A.stage]") + client.images += I return @@ -277,7 +261,7 @@ Des: Removes all infected images from the alien. /mob/living/carbon/alien/proc/updatePlasmaDisplay() if(hud_used) //clientless aliens - hud_used.alien_plasma_display.maptext = "
    [storedPlasma]
    " + hud_used.alien_plasma_display.maptext = "
    [getPlasma()]
    " /mob/living/carbon/alien/larva/updatePlasmaDisplay() return @@ -314,4 +298,4 @@ Des: Removes all infected images from the alien. playsound(T, S, volume, 1, range) return 1 - return 0 + return 0 diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm index 3a60506ebe1..17680b80f56 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm @@ -6,7 +6,7 @@ These are general powers. Specific powers are stored under the appropriate alien Doesn't work on other aliens/AI.*/ -/mob/living/carbon/alien/proc/powerc(X, Y)//Y is optional, checks for weed planting. X can be null. +/mob/living/carbon/proc/powerc(X, Y)//Y is optional, checks for weed planting. X can be null. if(stat) src << "You must be conscious to do this." return 0 @@ -28,7 +28,7 @@ Doesn't work on other aliens/AI.*/ return if(powerc(50,1)) - adjustToxLoss(-50) + adjustPlasma(-50) for(var/mob/O in viewers(src, null)) O.show_message(text("[src] has planted some alien weeds!"), 1) new /obj/structure/alien/weeds/node(loc) @@ -40,7 +40,7 @@ Doesn't work on other aliens/AI.*/ set category = "Alien" if(powerc(10)) - adjustToxLoss(-10) + adjustPlasma(-10) var/msg = sanitize(input("Message:", "Alien Whisper") as text|null) if(msg) log_say("Alien Whisper: [key_name(src)]->[key_name(M)]: [msg]") @@ -61,8 +61,8 @@ Doesn't work on other aliens/AI.*/ amount = abs(round(amount)) if(powerc(amount)) if (get_dist(src,M) <= 1) - M.adjustToxLoss(amount) - adjustToxLoss(-amount) + M.adjustPlasma(amount) + adjustPlasma(-amount) M << "[src] has transfered [amount] plasma to you." src << {"You have trasferred [amount] plasma to [M]"} else @@ -97,7 +97,7 @@ Doesn't work on other aliens/AI.*/ else// Not a type we can acid. return - adjustToxLoss(-200) + adjustPlasma(-200) new /obj/effect/acid(get_turf(O), O) visible_message("[src] vomits globs of vile stuff all over [O]. It begins to sizzle and melt under the bubbling mess of acid!") else @@ -110,7 +110,7 @@ Doesn't work on other aliens/AI.*/ set category = "Alien" if(powerc(50)) - adjustToxLoss(-50) + adjustPlasma(-50) src.visible_message("[src] spits neurotoxin!", "You spit neurotoxin.") var/turf/T = loc @@ -136,7 +136,7 @@ Doesn't work on other aliens/AI.*/ var/choice = input("Choose what you wish to shape.","Resin building") as null|anything in list("resin wall","resin membrane","resin nest") //would do it through typesof but then the player choice would have the type path and we don't want the internal workings to be exposed ICly - Urist if(!choice || !powerc(55)) return - adjustToxLoss(-55) + adjustPlasma(-55) for(var/mob/O in viewers(src, null)) O.show_message(text("[src] vomits up a thick purple substance and shapes it!"), 1) switch(choice) @@ -162,3 +162,27 @@ Doesn't work on other aliens/AI.*/ //Paralyse(10) src.visible_message("[src] hurls out the contents of their stomach!") return + +/mob/living/carbon/proc/getPlasma() + var/obj/item/organ/internal/xenos/plasmavessel/vessel = get_int_organ(/obj/item/organ/internal/xenos/plasmavessel) + if(!vessel) return 0 + return vessel.stored_plasma + + +/mob/living/carbon/proc/adjustPlasma(amount) + var/obj/item/organ/internal/xenos/plasmavessel/vessel = get_int_organ(/obj/item/organ/internal/xenos/plasmavessel) + if(!vessel) return + vessel.stored_plasma = max(vessel.stored_plasma + amount,0) + vessel.stored_plasma = min(vessel.stored_plasma, vessel.max_plasma) //upper limit of max_plasma, lower limit of 0 + return 1 + +/mob/living/carbon/alien/adjustPlasma(amount) + . = ..() + updatePlasmaDisplay() + +/mob/living/carbon/proc/usePlasma(amount) + if(getPlasma() >= amount) + adjustPlasma(-amount) + return 1 + + return 0 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm index 201ab0e1f77..19cad5aa5fc 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm @@ -4,7 +4,6 @@ maxHealth = 100 health = 100 icon_state = "aliend_s" - plasma_rate = 15 /mob/living/carbon/alien/humanoid/drone/New() var/datum/reagents/R = new/datum/reagents(100) @@ -13,8 +12,11 @@ if(src.name == "alien drone") src.name = text("alien drone ([rand(1, 1000)])") src.real_name = src.name - verbs.Add(/mob/living/carbon/alien/humanoid/proc/resin,/mob/living/carbon/alien/humanoid/proc/corrosive_acid) + internal_organs += new /obj/item/organ/internal/xenos/plasmavessel/drone + internal_organs += new /obj/item/organ/internal/xenos/acidgland + internal_organs += new /obj/item/organ/internal/xenos/resinspinner ..() + //Drones use the same base as generic humanoids. //Drone verbs @@ -27,7 +29,7 @@ // Queen check var/no_queen = 1 for(var/mob/living/carbon/alien/humanoid/queen/Q in living_mob_list) - if(!Q.key && Q.brain_op_stage != 4) + if(!Q.key && Q.get_int_organ(/obj/item/organ/internal/brain/)) continue no_queen = 0 @@ -35,7 +37,7 @@ src << "We cannot perform this ability at the present time!" return if(no_queen) - adjustToxLoss(-500) + adjustPlasma(-500) src << "You begin to evolve!" for(var/mob/O in viewers(src, null)) O.show_message(text("[src] begins to twist and contort!"), 1) diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm index 6e4589b02c3..9a667ab79fc 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm @@ -3,10 +3,7 @@ caste = "h" maxHealth = 125 health = 125 - storedPlasma = 100 - max_plasma = 150 icon_state = "alienh_s" - plasma_rate = 5 /mob/living/carbon/alien/humanoid/hunter/New() var/datum/reagents/R = new/datum/reagents(100) @@ -15,6 +12,7 @@ if(name == "alien hunter") name = text("alien hunter ([rand(1, 1000)])") real_name = name + internal_organs += new /obj/item/organ/internal/xenos/plasmavessel/hunter ..() /mob/living/carbon/alien/humanoid/hunter/handle_regular_hud_updates() @@ -43,7 +41,7 @@ if(m_intent == "run" || resting) ..() else - adjustToxLoss(-heal_rate) + adjustPlasma(-heal_rate) //Hunter verbs diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm index d6b8a18fc7b..342c8a530d3 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm @@ -3,10 +3,7 @@ caste = "s" maxHealth = 150 health = 150 - storedPlasma = 100 - max_plasma = 250 icon_state = "aliens_s" - plasma_rate = 10 /mob/living/carbon/alien/humanoid/sentinel/large name = "alien praetorian" @@ -45,7 +42,9 @@ if(name == "alien sentinel") name = text("alien sentinel ([rand(1, 1000)])") real_name = name - verbs.Add(/mob/living/carbon/alien/humanoid/proc/corrosive_acid,/mob/living/carbon/alien/humanoid/proc/neurotoxin) + internal_organs += new /obj/item/organ/internal/xenos/plasmavessel + internal_organs += new /obj/item/organ/internal/xenos/acidgland + internal_organs += new /obj/item/organ/internal/xenos/neurotoxin ..() /mob/living/carbon/alien/humanoid/sentinel/handle_regular_hud_updates() diff --git a/code/modules/mob/living/carbon/alien/humanoid/empress.dm b/code/modules/mob/living/carbon/alien/humanoid/empress.dm index 6d20f4e1e45..11cf3c0c4d6 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/empress.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/empress.dm @@ -5,10 +5,7 @@ health = 700 icon_state = "alienq_s" status_flags = CANPARALYSE - heal_rate = 5 - plasma_rate = 20 move_delay_add = 3 - max_plasma = 1000 large = 1 ventcrawler = 0 @@ -48,7 +45,11 @@ break real_name = src.name - verbs.Add(/mob/living/carbon/alien/humanoid/proc/corrosive_acid,/mob/living/carbon/alien/humanoid/proc/resin) + internal_organs += new /obj/item/organ/internal/xenos/plasmavessel/queen + internal_organs += new /obj/item/organ/internal/xenos/acidgland + internal_organs += new /obj/item/organ/internal/xenos/eggsac + internal_organs += new /obj/item/organ/internal/xenos/resinspinner + internal_organs += new /obj/item/organ/internal/xenos/neurotoxin ..() /mob/living/carbon/alien/humanoid/empress @@ -84,8 +85,8 @@ src << "There's already an egg here." return - if(powerc(75,1))//Can't plant eggs on spess tiles. That's silly. - adjustToxLoss(-75) + if(powerc(250,1))//Can't plant eggs on spess tiles. That's silly. + adjustPlasma(-250) for(var/mob/O in viewers(src, null)) O.show_message(text("\green [src] has laid an egg!"), 1) new /obj/structure/alien/egg(loc) diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index f407e35fe25..f6fd8281a7d 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -9,7 +9,6 @@ var/next_attack = 0 var/pounce_cooldown = 0 var/pounce_cooldown_time = 30 - update_icon = 1 var/leap_on_click = 0 var/custom_pixel_x_offset = 0 //for admin fuckery. var/custom_pixel_y_offset = 0 diff --git a/code/modules/mob/living/carbon/alien/humanoid/queen.dm b/code/modules/mob/living/carbon/alien/humanoid/queen.dm index f27ac91d398..188d485d83f 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/queen.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/queen.dm @@ -6,7 +6,6 @@ icon_state = "alienq_s" status_flags = CANPARALYSE heal_rate = 5 - plasma_rate = 20 large = 1 ventcrawler = 0 @@ -24,7 +23,11 @@ break real_name = src.name - verbs.Add(/mob/living/carbon/alien/humanoid/proc/corrosive_acid,/mob/living/carbon/alien/humanoid/proc/neurotoxin,/mob/living/carbon/alien/humanoid/proc/resin) + internal_organs += new /obj/item/organ/internal/xenos/plasmavessel/queen + internal_organs += new /obj/item/organ/internal/xenos/acidgland + internal_organs += new /obj/item/organ/internal/xenos/eggsac + internal_organs += new /obj/item/organ/internal/xenos/resinspinner + internal_organs += new /obj/item/organ/internal/xenos/neurotoxin ..() @@ -64,7 +67,7 @@ return if(powerc(75,1))//Can't plant eggs on spess tiles. That's silly. - adjustToxLoss(-75) + adjustPlasma(-75) for(var/mob/O in viewers(src, null)) O.show_message(text("[src] has laid an egg!"), 1) new /obj/structure/alien/egg(loc) diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm index 7a309ac28dd..90b3aa3ebb8 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva.dm @@ -6,8 +6,6 @@ maxHealth = 30 health = 30 - storedPlasma = 50 - max_plasma = 50 density = 0 var/amount_grown = 0 @@ -25,6 +23,8 @@ regenerate_icons() add_language("Xenomorph") add_language("Hivemind") + internal_organs += new /obj/item/organ/internal/xenos/plasmavessel/larva + ..() //This is fine, works the same as a human @@ -64,8 +64,9 @@ ..() stat(null, "Progress: [amount_grown]/[max_grown]") -/mob/living/carbon/alien/larva/adjustToxLoss(amount) - if(stat != DEAD) + +/mob/living/carbon/alien/larva/adjustPlasma(amount) + if(stat != DEAD && amount > 0) amount_grown = min(amount_grown + 1, max_grown) ..(amount) diff --git a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm index 5ffe45a8123..d0337fbe636 100644 --- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm +++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm @@ -2,7 +2,7 @@ // It functions almost identically (see code/datums/diseases/alien_embryo.dm) var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds -/obj/item/alien_embryo +/obj/item/organ/internal/body_egg/alien_embryo name = "alien embryo" desc = "All slimy and yuck." icon = 'icons/mob/alien.dmi' @@ -10,30 +10,49 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds var/mob/living/affected_mob var/stage = 0 -/obj/item/alien_embryo/New() - if(istype(loc, /mob/living)) - affected_mob = loc - affected_mob.status_flags |= XENO_HOST - if(istype(affected_mob,/mob/living/carbon)) - var/mob/living/carbon/H = affected_mob - H.med_hud_set_status() - processing_objects.Add(src) - spawn(0) - AddInfectionImages(affected_mob) +/obj/item/organ/internal/body_egg/alien_embryo/on_find(mob/living/finder) + ..() + if(stage < 4) + finder << "It's small and weak, barely the size of a fetus." else - qdel(src) + finder << "It's grown quite large, and writhes slightly as you look at it." + if(prob(10)) + AttemptGrow(0) -/obj/item/alien_embryo/Destroy() - if(affected_mob) - affected_mob.status_flags &= ~(XENO_HOST) - if(istype(affected_mob,/mob/living/carbon)) - var/mob/living/carbon/H = affected_mob - H.med_hud_set_status() - spawn(0) - RemoveInfectionImages(affected_mob) - return ..() +/obj/item/organ/internal/body_egg/alien_embryo/prepare_eat() + var/obj/S = ..() + S.reagents.add_reagent("sacid", 10) + return S -/obj/item/alien_embryo/process() +/obj/item/organ/internal/body_egg/alien_embryo/on_life() + switch(stage) + if(2, 3) + if(prob(2)) + owner.emote("sneeze") + if(prob(2)) + owner.emote("cough") + if(prob(2)) + owner << "Your throat feels sore." + if(prob(2)) + owner << "Mucous runs down the back of your throat." + if(4) + if(prob(2)) + owner.emote("sneeze") + if(prob(2)) + owner.emote("cough") + if(prob(4)) + owner << "Your muscles ache." + if(prob(20)) + owner.take_organ_damage(1) + if(prob(4)) + owner << "Your stomach hurts." + if(prob(20)) + owner.adjustToxLoss(1) + if(5) + owner << "You feel something tearing its way out of your stomach..." + owner.adjustToxLoss(10) + +/obj/item/organ/internal/body_egg/alien_embryo/egg_process() if(!affected_mob) return if(loc != affected_mob) affected_mob.status_flags &= ~(XENO_HOST) @@ -51,38 +70,11 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds spawn(0) RefreshInfectionImage() - switch(stage) - if(2, 3) - if(prob(1)) - affected_mob.emote("sneeze") - if(prob(1)) - affected_mob.emote("cough") - if(prob(1)) - affected_mob << "Your throat feels sore." - if(prob(1)) - affected_mob << "Mucous runs down the back of your throat." - if(4) - if(prob(1)) - affected_mob.emote("sneeze") - if(prob(1)) - affected_mob.emote("cough") - if(prob(2)) - affected_mob << "Your muscles ache." - if(prob(20)) - affected_mob.take_organ_damage(1) - if(prob(2)) - affected_mob << "Your stomach hurts." - if(prob(20)) - affected_mob.adjustToxLoss(1) - affected_mob.updatehealth() - if(5) - affected_mob << "You feel something tearing its way out of your stomach..." - affected_mob.adjustToxLoss(10) - affected_mob.updatehealth() - if(prob(50)) - AttemptGrow() -/obj/item/alien_embryo/proc/AttemptGrow(var/gib_on_success = 1) + if(stage == 5 && prob(50)) + AttemptGrow() + +/obj/item/organ/internal/body_egg/alien_embryo/proc/AttemptGrow(var/gib_on_success = 1) var/list/candidates = get_candidates(ROLE_ALIEN,ALIEN_AFK_BRACKET,1) var/client/C = null @@ -123,7 +115,7 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds Proc: RefreshInfectionImage() Des: Removes the current icons located in the infected mob adds the current stage ----------------------------------------*/ -/obj/item/alien_embryo/proc/RefreshInfectionImage() +/obj/item/organ/internal/body_egg/alien_embryo/RefreshInfectionImage() RemoveInfectionImages() AddInfectionImages() @@ -131,7 +123,7 @@ Des: Removes the current icons located in the infected mob adds the current stag Proc: AddInfectionImages(C) Des: Adds the infection image to all aliens for this embryo ----------------------------------------*/ -/obj/item/alien_embryo/proc/AddInfectionImages() +/obj/item/organ/internal/body_egg/alien_embryo/AddInfectionImages() for(var/mob/living/carbon/alien/alien in player_list) if(alien.client) var/I = image('icons/mob/alien.dmi', loc = affected_mob, icon_state = "infected[stage]") @@ -141,7 +133,7 @@ Des: Adds the infection image to all aliens for this embryo Proc: RemoveInfectionImage(C) Des: Removes all images from the mob infected by this embryo ----------------------------------------*/ -/obj/item/alien_embryo/proc/RemoveInfectionImages() +/obj/item/organ/internal/body_egg/alien_embryo/RemoveInfectionImages() for(var/mob/living/carbon/alien/alien in player_list) if(alien.client) for(var/image/I in alien.client.images) diff --git a/code/modules/mob/living/carbon/alien/special/facehugger.dm b/code/modules/mob/living/carbon/alien/special/facehugger.dm index 351c7387826..7711df5d7f6 100644 --- a/code/modules/mob/living/carbon/alien/special/facehugger.dm +++ b/code/modules/mob/living/carbon/alien/special/facehugger.dm @@ -102,7 +102,9 @@ var/const/MAX_ACTIVE_TIME = 400 icon_state = "[initial(icon_state)]" Attach(hit_atom) -/obj/item/clothing/mask/facehugger/proc/Attach(M as mob) +/obj/item/clothing/mask/facehugger/proc/Attach(mob/living/M as mob) + if(!isliving(M)) + return 0 if( (!iscorgi(M) && !iscarbon(M)) || isalien(M)) return 0 if(attached) @@ -112,24 +114,26 @@ var/const/MAX_ACTIVE_TIME = 400 spawn(MAX_IMPREGNATION_TIME) attached = 0 - var/mob/living/L = M //just so I don't need to use : + if(M.get_int_organ(/obj/item/organ/internal/xenos/hivenode)) + return 0 + if(M.get_int_organ(/obj/item/organ/internal/body_egg/alien_embryo)) + return 0 - if(loc == L) return 0 - if(stat != CONSCIOUS) return 0 - if(locate(/obj/item/alien_embryo) in L) return 0 - if(!sterile) L.take_organ_damage(strength,0) //done here so that even borgs and humans in helmets take damage + if(loc == M) return 0 - L.visible_message("[src] leaps at [L]'s face!") + if(!sterile) M.take_organ_damage(strength,0) //done here so that even borgs and humans in helmets take damage - if(ishuman(L)) - var/mob/living/carbon/human/H = L + M.visible_message("[src] leaps at [M]'s face!") + + if(ishuman(M)) + var/mob/living/carbon/human/H = M if(H.head && H.head.flags & HEADCOVERSMOUTH) H.visible_message("[src] smashes against [H]'s [H.head]!") death() return 0 if(iscarbon(M)) - var/mob/living/carbon/target = L + var/mob/living/carbon/target = M if(target.wear_mask) if(prob(20)) return 0 @@ -144,7 +148,7 @@ var/const/MAX_ACTIVE_TIME = 400 src.loc = target target.equip_to_slot(src, slot_wear_mask,,0) - if(!sterile) L.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings + if(!sterile) M.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings else if (iscorgi(M)) var/mob/living/simple_animal/pet/corgi/C = M loc = C @@ -154,7 +158,7 @@ var/const/MAX_ACTIVE_TIME = 400 GoIdle() //so it doesn't jump the people that tear it off spawn(rand(MIN_IMPREGNATION_TIME,MAX_IMPREGNATION_TIME)) - Impregnate(L) + Impregnate(M) return 1 @@ -181,7 +185,7 @@ var/const/MAX_ACTIVE_TIME = 400 icon_state = "[initial(icon_state)]_impregnated" if(!(target.status_flags & XENO_HOST)) - new /obj/item/alien_embryo(target) + new /obj/item/organ/internal/body_egg/alien_embryo(target) if(iscorgi(target)) @@ -234,7 +238,7 @@ var/const/MAX_ACTIVE_TIME = 400 return -/proc/CanHug(var/mob/M) +/proc/CanHug(var/mob/living/M) if(!M || !ismob(M)) return 0 @@ -244,6 +248,9 @@ var/const/MAX_ACTIVE_TIME = 400 if(iscorgi(M)) return 1 + if(M.get_int_organ(/obj/item/organ/internal/xenos/hivenode)) + return 0 + var/mob/living/carbon/C = M if(ishuman(C)) var/mob/living/carbon/human/H = C diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm index a0168448391..f5e832cdaa7 100644 --- a/code/modules/mob/living/carbon/brain/MMI.dm +++ b/code/modules/mob/living/carbon/brain/MMI.dm @@ -12,17 +12,17 @@ var/alien = 0 var/syndiemmi = 0 //Whether or not this is a Syndicate MMI var/mob/living/carbon/brain/brainmob = null//The current occupant. - var/obj/item/organ/brain/held_brain = null // This is so MMI's aren't brainscrubber 9000's + var/obj/item/organ/internal/brain/held_brain = null // This is so MMI's aren't brainscrubber 9000's var/mob/living/silicon/robot/robot = null//Appears unused. var/obj/mecha/mecha = null//This does not appear to be used outside of reference in mecha.dm. // I'm using this for mechs giving MMIs HUDs now /obj/item/device/mmi/attackby(var/obj/item/O as obj, var/mob/user as mob, params) - if(istype(O, /obj/item/organ/brain/crystal )) + if(istype(O, /obj/item/organ/internal/brain/crystal )) user << " This brain is too malformed to be able to use with the [src]." return - if(istype(O,/obj/item/organ/brain) && !brainmob) //Time to stick a brain in it --NEO - var/obj/item/organ/brain/B = O + if(istype(O,/obj/item/organ/internal/brain) && !brainmob) //Time to stick a brain in it --NEO + var/obj/item/organ/internal/brain/B = O if(!B.brainmob) user << "You aren't sure where this brain came from, but you're pretty sure it's a useless brain." return @@ -47,7 +47,7 @@ user.drop_item() B.forceMove(src) held_brain = B - if(istype(O,/obj/item/organ/brain/xeno)) // I'm not sure how well this will work now, since I don't think you can actually get xeno brains + if(istype(O,/obj/item/organ/internal/brain/xeno)) // I'm not sure how well this will work now, since I don't think you can actually get xeno brains name = "Man-Machine Interface: Alien - [brainmob.real_name]" icon = 'icons/mob/alien.dmi' icon_state = "AlienMMI" @@ -89,8 +89,8 @@ held_brain = new(src) else // We have a species, and it has a brain var/brain_path = H.species.return_organ("brain") - if(!ispath(brain_path, /obj/item/organ/brain)) - brain_path = /obj/item/organ/brain + if(!ispath(brain_path, /obj/item/organ/internal/brain)) + brain_path = /obj/item/organ/internal/brain held_brain = new brain_path(src) // Slime people will keep their slimy brains this way held_brain.dna = brainmob.dna.Clone() held_brain.name = "\the [brainmob.name]'s [initial(held_brain.name)]" diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm index 9477756cd1e..028c0ad3a14 100644 --- a/code/modules/mob/living/carbon/brain/brain_item.dm +++ b/code/modules/mob/living/carbon/brain/brain_item.dm @@ -1,4 +1,4 @@ -/obj/item/organ/brain +/obj/item/organ/internal/brain name = "brain" health = 400 //They need to live awhile longer than other organs. max_damage = 200 @@ -13,33 +13,30 @@ var/mob/living/carbon/brain/brainmob = null organ_tag = "brain" parent_organ = "head" + slot = "brain" vital = 1 -/obj/item/organ/brain/attack_self(mob/user as mob) - return //let's not have players taken out of the round as easily as a click, once you have their brain. - -/obj/item/organ/brain/surgeryize() +/obj/item/organ/internal/brain/surgeryize() if(!owner) return owner.ear_damage = 0 //Yeah, didn't you...hear? The ears are totally inside the brain. owner.ear_deaf = 0 -/obj/item/organ/brain/xeno +/obj/item/organ/internal/brain/xeno name = "thinkpan" desc = "It looks kind of like an enormous wad of purple bubblegum." - icon = 'icons/mob/alien.dmi' - icon_state = "chitin" + icon_state = "brain-x-d" -/obj/item/organ/brain/New() +/obj/item/organ/internal/brain/New() ..() spawn(5) if(brainmob && brainmob.client) brainmob.client.screen.len = null //clear the hud -/obj/item/organ/brain/proc/transfer_identity(var/mob/living/carbon/H) +/obj/item/organ/internal/brain/proc/transfer_identity(var/mob/living/carbon/H) brainmob = new(src) if(isnull(dna)) // someone didn't set this right... - log_to_dd("[src] at [loc] did not contain a dna datum at time of removed.") + log_to_dd("[src] at [loc] did not contain a dna datum at time of removal.") dna = H.dna.Clone() name = "\the [dna.real_name]'s [initial(src.name)]" brainmob.dna = dna.Clone() // Silly baycode, what you do @@ -53,51 +50,56 @@ brainmob << "You feel slightly disoriented. That's normal when you're just a [initial(src.name)]." callHook("debrain", list(brainmob)) -/obj/item/organ/brain/examine(mob/user) // -- TLE +/obj/item/organ/internal/brain/examine(mob/user) // -- TLE ..(user) if(brainmob && brainmob.client)//if thar be a brain inside... the brain. user << "You can feel the small spark of life still left in this one." else user << "This one seems particularly lifeless. Perhaps it will regain some of its luster later.." -/obj/item/organ/brain/removed(var/mob/living/user) +/obj/item/organ/internal/brain/remove(var/mob/living/user,special = 0) if(!owner) return ..() // Probably a redundant removal; just bail - var/obj/item/organ/brain/B = src - if(istype(B) && istype(owner) && is_primary_organ()) + var/obj/item/organ/internal/brain/B = src + if(!special) var/mob/living/simple_animal/borer/borer = owner.has_brain_worms() if(borer) borer.detatch() //Should remove borer if the brain is removed - RR - owner.brain_op_stage = 4.0 - B.transfer_identity(owner) + B.transfer_identity(user) + if(istype(owner,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = owner + H.update_hair(1) ..() -/obj/item/organ/brain/replaced(var/mob/living/target) +/obj/item/organ/internal/brain/insert(var/mob/living/target,special = 0) + name = "brain" var/brain_already_exists = 0 if(istype(target,/mob/living/carbon/human)) // No more IPC multibrain shenanigans - var/mob/living/carbon/human/H = target - if(organ_tag in H.internal_organs_by_name) + if(target.get_int_organ(/obj/item/organ/internal/brain)) brain_already_exists = 1 + var/mob/living/carbon/human/H = target + H.update_hair(1) + if(!brain_already_exists) - if(target.key) - target.ghostize() - var/mob/living/carbon/C = target - if(istype(C)) - C.brain_op_stage = 1.0 if(brainmob) + if(target.key) + target.ghostize() if(brainmob.mind) brainmob.mind.transfer_to(target) else target.key = brainmob.key ..() -/obj/item/organ/brain/slime +/obj/item/organ/internal/brain/prepare_eat() + return // Too important to eat. + +/obj/item/organ/internal/brain/slime name = "slime core" desc = "A complex, organic knot of jelly and crystalline particles." icon = 'icons/mob/slimes.dmi' @@ -110,13 +112,13 @@ return ..() -/obj/item/organ/brain/golem +/obj/item/organ/internal/brain/golem name = "Runic mind" desc = "A tightly furled roll of paper, covered with indecipherable runes." icon = 'icons/obj/wizard.dmi' icon_state = "scroll" -/obj/item/organ/brain/Destroy() //copypasted from MMIs. +/obj/item/organ/internal/brain/Destroy() //copypasted from MMIs. if(brainmob) qdel(brainmob) brainmob = null diff --git a/code/modules/mob/living/carbon/brain/death.dm b/code/modules/mob/living/carbon/brain/death.dm index efcfac98624..efb1b8e8d87 100644 --- a/code/modules/mob/living/carbon/brain/death.dm +++ b/code/modules/mob/living/carbon/brain/death.dm @@ -36,7 +36,7 @@ if(container && istype(container, /obj/item/device/mmi)) qdel(container)//Gets rid of the MMI if there is one if(loc) - if(istype(loc,/obj/item/organ/brain)) + if(istype(loc,/obj/item/organ/internal/brain)) qdel(loc)//Gets rid of the brain item spawn(15) if(animation) qdel(animation) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 0701b394113..5e905c91e9d 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -1,4 +1,4 @@ -mob/living +/mob/living var/canEnterVentWith = "/obj/item/weapon/implant=0&/obj/item/clothing/mask/facehugger=0&/obj/item/device/radio/borg=0&/obj/machinery/camera=0" var/datum/middleClickOverride/middleClickOverride = null @@ -264,19 +264,27 @@ mob/living playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) if(!player_logged) M.visible_message( \ - "\blue [M] shakes [src] trying to wake [t_him] up!", \ - "\blue You shake [src] trying to wake [t_him] up!", \ + "[M] shakes [src] trying to wake [t_him] up!",\ + "You shake [src] trying to wake [t_him] up!",\ ) // BEGIN HUGCODE - N3X else - if (istype(src,/mob/living/carbon/human) && src:w_uniform) - var/mob/living/carbon/human/H = src - H.w_uniform.add_fingerprint(M) playsound(get_turf(src), 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - M.visible_message( \ - "\blue [M] gives [src] a [pick("hug","warm embrace")].", \ - "\blue You hug [src].", \ + if(M.zone_sel.selecting == "head") + M.visible_message(\ + "[M] pats [src] on the head.",\ + "You pat [src] on the head.",\ ) + else + + M.visible_message(\ + "[M] gives [src] a [pick("hug","warm embrace")].",\ + "You hug [src].",\ + ) + if(istype(src,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = src + if(H.w_uniform) + H.w_uniform.add_fingerprint(M) /mob/living/carbon/proc/eyecheck() @@ -643,73 +651,6 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, // output for machines^ ^^^^^^^output for people^^^^^^^^^ -//Brain slug proc for voluntary removal of control. -/mob/living/carbon/proc/release_control() - - set category = "Alien" - set name = "Release Control" - set desc = "Release control of your host's body." - - var/mob/living/simple_animal/borer/B = has_brain_worms() - - if(B && B.host_brain) - src << "\red You withdraw your probosci, releasing control of [B.host_brain]" - - B.detatch() - - verbs -= /mob/living/carbon/proc/release_control - verbs -= /mob/living/carbon/proc/punish_host - verbs -= /mob/living/carbon/proc/spawn_larvae - - else - src << "\red ERROR NO BORER OR BRAINMOB DETECTED IN THIS MOB, THIS IS A BUG !" - -//Brain slug proc for tormenting the host. -/mob/living/carbon/proc/punish_host() - set category = "Alien" - set name = "Torment host" - set desc = "Punish your host with agony." - - var/mob/living/simple_animal/borer/B = has_brain_worms() - - if(!B) - return - - if(B.host_brain.ckey) - src << "\red You send a punishing spike of psychic agony lancing into your host's brain." - B.host_brain << "\red Horrific, burning agony lances through you, ripping a soundless scream from your trapped mind!" - -//Check for brain worms in head. -/mob/proc/has_brain_worms() - - for(var/I in contents) - if(istype(I,/mob/living/simple_animal/borer)) - return I - - return 0 - -/mob/living/carbon/proc/spawn_larvae() - set category = "Alien" - set name = "Reproduce (100)" - set desc = "Spawn several young." - - var/mob/living/simple_animal/borer/B = has_brain_worms() - - if(!B) - return - - if(B.chemicals >= 100) - src << "\red Your host twitches and quivers as you rapdly excrete several larvae from your sluglike body." - visible_message("\red [src] heaves violently, expelling a rush of vomit and a wriggling, sluglike creature!") - B.chemicals -= 100 - - new /obj/effect/decal/cleanable/vomit(get_turf(src)) - playsound(loc, 'sound/effects/splat.ogg', 50, 1) - new /mob/living/simple_animal/borer(get_turf(src)) - - else - src << "You do not have enough chemicals stored to reproduce." - return /mob/living/carbon/proc/canBeHandcuffed() return 0 @@ -727,6 +668,18 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, else return initial(pixel_y) +/mob/living/carbon/emp_act(severity) + for(var/obj/item/organ/internal/O in internal_organs) + O.emp_act(severity) + ..() + +/mob/living/carbon/Stat() + if(statpanel("Status")) + var/obj/item/organ/internal/xenos/plasmavessel/vessel = get_int_organ(/obj/item/organ/internal/xenos/plasmavessel) + if(vessel) + stat(null, "Plasma Stored: [vessel.stored_plasma]/[vessel.max_plasma]") + ..() + /mob/living/carbon/get_all_slots() return list(l_hand, r_hand, @@ -759,4 +712,29 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, W.loc = loc W.dropped(src) if (W) - W.layer = initial(W.layer) \ No newline at end of file + W.layer = initial(W.layer) + + +/mob/living/carbon/proc/slip(var/description, var/stun, var/weaken, var/tilesSlipped, var/walkSafely, var/slipAny) + if (flying || buckled || (walkSafely && m_intent == "walk")) + return + if ((lying) && (!(tilesSlipped))) + return + if (!(slipAny)) + if (istype(src, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = src + if ((isobj(H.shoes) && H.shoes.flags & NOSLIP) || H.species.bodyflags & FEET_NOSLIP) + return + if (tilesSlipped) + for(var/t = 0, t<=tilesSlipped, t++) + spawn (t) step(src, src.dir) + stop_pulling() + src << "You slipped on the [description]!" + playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3) + if (stun) + Stun(stun) + Weaken(weaken) + return 1 + +/mob/living/carbon/proc/can_eat(flags = 255) + return 1 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/carbon_defenses.dm b/code/modules/mob/living/carbon/carbon_defenses.dm index ab1c27ca2ee..45c15d35f8a 100644 --- a/code/modules/mob/living/carbon/carbon_defenses.dm +++ b/code/modules/mob/living/carbon/carbon_defenses.dm @@ -19,4 +19,14 @@ /mob/living/carbon/water_act(volume, temperature, source) if(volume > 10) //anything over 10 volume will make the mob wetter. wetlevel = min(wetlevel + 1,5) + ..() + + +/mob/living/carbon/attackby(obj/item/I, mob/user, params) + if(lying) + if(surgeries.len) + if(user != src && user.a_intent == "help") + for(var/datum/surgery/S in surgeries) + if(S.next_step(user, src)) + return 1 ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index 4288b561f2d..033e8ddfb1c 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -2,6 +2,7 @@ gender = MALE hud_possible = list(HEALTH_HUD,STATUS_HUD,SPECIALROLE_HUD) var/list/stomach_contents = list() + var/list/internal_organs = list() var/brain_op_stage = 0.0 var/list/datum/disease2/disease/virus2 = list() var/antibodies = 0 @@ -18,8 +19,6 @@ var/obj/item/head = null var/obj/item/clothing/suit/wear_suit = null //TODO: necessary? Are they even used? ~Carn - //Surgery info - var/datum/surgery_status/op_stage = new/datum/surgery_status //Active emote/pose var/pose = null diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm index 26612b66ed1..6cd20e79b19 100644 --- a/code/modules/mob/living/carbon/human/appearance.dm +++ b/code/modules/mob/living/carbon/human/appearance.dm @@ -17,14 +17,24 @@ reset_hair() return 1 -/mob/living/carbon/human/proc/change_gender(var/gender) +/mob/living/carbon/human/proc/change_gender(var/gender, var/update_dna = 1) if(src.gender == gender) return src.gender = gender - reset_hair() + + var/datum/sprite_accessory/hair/current_hair = hair_styles_list[h_style] + if(current_hair.gender != NEUTER && current_hair.gender != src.gender) + reset_head_hair() + + var/datum/sprite_accessory/hair/current_fhair = facial_hair_styles_list[f_style] + if(current_fhair.gender != NEUTER && current_fhair.gender != src.gender) + reset_facial_hair() + + if(update_dna) + update_dna() + sync_organ_dna(assimilate = 0) update_body() - update_dna() return 1 /mob/living/carbon/human/proc/change_hair(var/hair_style) @@ -58,8 +68,11 @@ return 1 /mob/living/carbon/human/proc/reset_hair() + reset_head_hair() + reset_facial_hair() + +/mob/living/carbon/human/proc/reset_head_hair() var/list/valid_hairstyles = generate_valid_hairstyles() - var/list/valid_facial_hairstyles = generate_valid_facial_hairstyles() if(valid_hairstyles.len) h_style = pick(valid_hairstyles) @@ -67,13 +80,15 @@ //this shouldn't happen h_style = "Bald" + update_hair() + +/mob/living/carbon/human/proc/reset_facial_hair() + var/list/valid_facial_hairstyles = generate_valid_facial_hairstyles() if(valid_facial_hairstyles.len) f_style = pick(valid_facial_hairstyles) else //this shouldn't happen f_style = "Shaved" - - update_hair() update_fhair() /mob/living/carbon/human/proc/change_eye_color(var/red, var/green, var/blue) diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 2c7b2cb8bd3..dbfe27f78e9 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -13,9 +13,10 @@ playsound(src.loc, 'sound/effects/gib.ogg', 100, 1, 10) - for(var/obj/item/organ/I in internal_organs) + for(var/obj/item/organ/internal/I in internal_organs) if(istype(loc,/turf)) - I.removed() + I.remove(src) + I.forceMove(get_turf(src)) spawn() I.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),5) @@ -90,6 +91,7 @@ stat = DEAD dizziness = 0 jitteriness = 0 + heart_attack = 0 //Handle species-specific deaths. if(species) species.handle_death(src) @@ -104,13 +106,7 @@ B = I if(B) if(!B.ckey && ckey && B.controlling) - B.ckey = ckey - B.controlling = 0 - if(B.host_brain.ckey) - ckey = B.host_brain.ckey - B.host_brain.ckey = null - B.host_brain.name = "host brain" - B.host_brain.real_name = "host brain" + B.detatch() verbs -= /mob/living/carbon/proc/release_control diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 93b57850974..130bf7b05db 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -9,9 +9,6 @@ param = copytext(act, t1 + 1, length(act) + 1) act = copytext(act, 1, t1) - if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_' - act = copytext(act,1,length(act)) - var/muzzled = is_muzzled() if(sdisabilities & MUTE || silent) muzzled = 1 @@ -21,17 +18,21 @@ if (I.implanted) I.trigger(act, src) + var/miming = 0 + if(mind) + miming = mind.miming + //Emote Cooldown System (it's so simple!) // proc/handle_emote_CD() located in [code\modules\mob\emote.dm] var/on_CD = 0 switch(act) //Cooldown-inducing emotes - if("ping","buzz","beep") + if("ping", "pings", "buzz", "buzzes", "beep", "beeps", "yes", "no") if (species.name == "Machine") //Only Machines can beep, ping, and buzz on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm else //Everyone else fails, skip the emote attempt return - if("squish") + if("squish", "squishes") var/found_slime_bodypart = 0 if(species.name == "Slime People") //Only Slime People can squish @@ -46,7 +47,7 @@ if(!found_slime_bodypart) //Everyone else fails, skip the emote attempt return - if("scream", "fart", "flip", "snap") + if("scream", "screams", "fart", "farts", "flip", "flips", "snap", "snaps") on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm //Everything else, including typos of the above emotes else @@ -60,7 +61,7 @@ return custom_emote(m_type, message) //DO YOU KNOW WHY SHIT BREAKS? BECAUSE SO MUCH OLDCODE CALLS mob.emote("me",1,"whatever_the_fuck_it_wants_to_emote") //WHO THE FUCK THOUGHT THAT WAS A GOOD FUCKING IDEA!?!? - if("ping") + if("ping", "pings") var/M = null if(param) for (var/mob/A in view(null, null)) @@ -77,7 +78,7 @@ playsound(src.loc, 'sound/machines/ping.ogg', 50, 0) m_type = 1 - if("buzz") + if("buzz", "buzzes") var/M = null if(param) for (var/mob/A in view(null, null)) @@ -94,7 +95,7 @@ playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0) m_type = 1 - if("beep") + if("beep", "beeps") var/M = null if(param) for (var/mob/A in view(null, null)) @@ -111,7 +112,7 @@ playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0) m_type = 1 - if("squish") + if("squish", "squishes") var/M = null if(param) for (var/mob/A in view(null, null)) @@ -128,7 +129,41 @@ playsound(src.loc, 'sound/effects/slime_squish.ogg', 50, 0) //Credit to DrMinky (freesound.org) for the sound. m_type = 1 - if("wag") + if("yes") + var/M = null + if(param) + for (var/mob/A in view(null, null)) + if (param == A.name) + M = A + break + if(!M) + param = null + + if (param) + message = "[src] emits an affirmative blip at [param]." + else + message = "[src] emits an affirmative blip." + playsound(src.loc, 'sound/machines/synth_yes.ogg', 50, 0) + m_type = 1 + + if("no") + var/M = null + if(param) + for (var/mob/A in view(null, null)) + if (param == A.name) + M = A + break + if(!M) + param = null + + if (param) + message = "[src] emits a negative blip at [param]." + else + message = "[src] emits a negative blip." + playsound(src.loc, 'sound/machines/synth_no.ogg', 50, 0) + m_type = 1 + + if("wag", "wags") if(body_accessory) if(body_accessory.try_restrictions(src)) message = "[src] starts wagging \his tail." @@ -143,7 +178,7 @@ else return - if("swag") + if("swag", "swags") if(species.bodyflags & TAIL_WAGGING || body_accessory) message = "[src] stops wagging \his tail." src.stop_tail_wagging(1) @@ -155,15 +190,15 @@ message = "[src] is strumming the air and headbanging like a safari chimp." m_type = 1 - if ("blink") + if ("blink", "blinks") message = "[src] blinks." m_type = 1 - if ("blink_r") + if ("blink_r", "blinks_r") message = "[src] blinks rapidly." m_type = 1 - if ("bow") + if ("bow", "bows") if (!src.buckled) var/M = null if (param) @@ -180,7 +215,7 @@ message = "[src] bows." m_type = 1 - if ("salute") + if ("salute", "salutes") if (!src.buckled) var/M = null if (param) @@ -197,7 +232,7 @@ message = "[src] salutes." m_type = 1 - if ("choke") + if ("choke", "chokes") if(miming) message = "[src] clutches \his throat desperately!" m_type = 1 @@ -209,7 +244,7 @@ message = "[src] makes a strong noise." m_type = 2 - if ("burp") + if ("burp", "burps") if(miming) message = "[src] opens their mouth rather obnoxiously." m_type = 1 @@ -220,20 +255,20 @@ else message = "[src] makes a peculiar noise." m_type = 2 - if ("clap") + if ("clap", "claps") if (!src.restrained()) message = "[src] claps." m_type = 2 if(miming) m_type = 1 - if ("flap") + if ("flap", "flaps") if (!src.restrained()) message = "[src] flaps \his wings." m_type = 2 if(miming) m_type = 1 - if ("flip") + if ("flip", "flips") m_type = 1 if (!src.restrained()) var/M = null @@ -258,14 +293,14 @@ message = "[src] does a flip!" src.SpinAnimation(5,1) - if ("aflap") + if ("aflap", "aflaps") if (!src.restrained()) message = "[src] flaps \his wings ANGRILY!" m_type = 2 if(miming) m_type = 1 - if ("drool") + if ("drool", "drools") message = "[src] drools." m_type = 1 @@ -273,7 +308,7 @@ message = "[src] raises an eyebrow." m_type = 1 - if ("chuckle") + if ("chuckle", "chuckles") if(miming) message = "[src] appears to chuckle." m_type = 1 @@ -285,22 +320,22 @@ message = "[src] makes a noise." m_type = 2 - if ("twitch") + if ("twitch", "twitches") message = "[src] twitches violently." m_type = 1 - if ("twitch_s") + if ("twitch_s", "twitches_s") message = "[src] twitches." m_type = 1 - if ("faint") + if ("faint", "faints") message = "[src] faints." if(src.sleeping) return //Can't faint while asleep src.sleeping += 10 //Short-short nap m_type = 1 - if ("cough") + if ("cough", "coughs") if(miming) message = "[src] appears to cough!" m_type = 1 @@ -312,27 +347,27 @@ message = "[src] makes a strong noise." m_type = 2 - if ("frown") + if ("frown", "frowns") message = "[src] frowns." m_type = 1 - if ("nod") + if ("nod", "nods") message = "[src] nods." m_type = 1 - if ("blush") + if ("blush", "blushes") message = "[src] blushes." m_type = 1 - if ("wave") + if ("wave", "waves") message = "[src] waves." m_type = 1 - if ("quiver") + if ("quiver", "quivers") message = "[src] quivers." m_type = 1 - if ("gasp") + if ("gasp", "gasps") if(miming) message = "[src] appears to be gasping!" m_type = 1 @@ -344,11 +379,11 @@ message = "[src] makes a weak noise." m_type = 2 - if ("deathgasp") + if ("deathgasp", "deathgasps") message = "[src] [species.death_message]" m_type = 1 - if ("giggle") + if ("giggle", "giggles") if(miming) message = "[src] giggles silently!" m_type = 1 @@ -360,7 +395,7 @@ message = "[src] makes a noise." m_type = 2 - if ("glare") + if ("glare", "glares") var/M = null if (param) for (var/mob/A in view(null, null)) @@ -375,7 +410,7 @@ else message = "[src] glares." - if ("stare") + if ("stare", "stares") var/M = null if (param) for (var/mob/A in view(null, null)) @@ -390,7 +425,7 @@ else message = "[src] stares." - if ("look") + if ("look", "looks") var/M = null if (param) for (var/mob/A in view(null, null)) @@ -407,11 +442,11 @@ message = "[src] looks." m_type = 1 - if ("grin") + if ("grin", "grins") message = "[src] grins." m_type = 1 - if ("cry") + if ("cry", "cries") if(miming) message = "[src] cries." m_type = 1 @@ -423,7 +458,7 @@ message = "[src] makes a weak noise. \He frowns." m_type = 2 - if ("sigh") + if ("sigh", "sighs") if(miming) message = "[src] sighs." m_type = 1 @@ -435,7 +470,7 @@ message = "[src] makes a weak noise." m_type = 2 - if ("laugh") + if ("laugh", "laughs") if(miming) message = "[src] acts out a laugh." m_type = 1 @@ -447,13 +482,13 @@ message = "[src] makes a noise." m_type = 2 - if ("mumble") + if ("mumble", "mumbles") message = "[src] mumbles!" m_type = 2 if(miming) m_type = 1 - if ("grumble") + if ("grumble", "grumbles") if(miming) message = "[src] grumbles!" m_type = 1 @@ -464,7 +499,7 @@ message = "[src] makes a noise." m_type = 2 - if ("groan") + if ("groan", "groans") if(miming) message = "[src] appears to groan!" m_type = 1 @@ -476,7 +511,7 @@ message = "[src] makes a loud noise." m_type = 2 - if ("moan") + if ("moan", "moans") if(miming) message = "[src] appears to moan!" m_type = 1 @@ -498,7 +533,7 @@ message = "[src] says, \"[M], please. They had a family.\" [src.name] takes a drag from a cigarette and blows their name out in smoke." m_type = 2 - if ("point") + if ("point", "points") if (!src.restrained()) var/atom/M = null if (param) @@ -513,20 +548,20 @@ pointed(M) m_type = 1 - if ("raise") + if ("raise", "raises") if (!src.restrained()) message = "[src] raises a hand." m_type = 1 - if("shake") + if("shake", "shakes") message = "[src] shakes \his head." m_type = 1 - if ("shrug") + if ("shrug", "shrugs") message = "[src] shrugs." m_type = 1 - if ("signal") + if ("signal", "signals") if (!src.restrained()) var/t1 = round(text2num(param)) if (isnum(t1)) @@ -536,25 +571,25 @@ message = "[src] raises [t1] finger\s." m_type = 1 - if ("smile") + if ("smile", "smiles") message = "[src] smiles." m_type = 1 - if ("shiver") + if ("shiver", "shivers") message = "[src] shivers." m_type = 2 if(miming) m_type = 1 - if ("pale") + if ("pale", "pales") message = "[src] goes pale for a second." m_type = 1 - if ("tremble") + if ("tremble", "trembles") message = "[src] trembles in fear!" m_type = 1 - if ("sneeze") + if ("sneeze", "sneezes") if (miming) message = "[src] sneezes." m_type = 1 @@ -566,13 +601,13 @@ message = "[src] makes a strange noise." m_type = 2 - if ("sniff") + if ("sniff", "sniffs") message = "[src] sniffs." m_type = 2 if(miming) m_type = 1 - if ("snore") + if ("snore", "snores") if (miming) message = "[src] sleeps soundly." m_type = 1 @@ -584,7 +619,7 @@ message = "[src] makes a noise." m_type = 2 - if ("whimper") + if ("whimper", "whimpers") if (miming) message = "[src] appears hurt." m_type = 1 @@ -596,25 +631,25 @@ message = "[src] makes a weak noise." m_type = 2 - if ("wink") + if ("wink", "winks") message = "[src] winks." m_type = 1 - if ("yawn") + if ("yawn", "yawns") if (!muzzled) message = "[src] yawns." m_type = 2 if(miming) m_type = 1 - if ("collapse") + if ("collapse", "collapses") Paralyse(2) message = "[src] collapses!" m_type = 2 if(miming) m_type = 1 - if("hug") + if("hug", "hugs") m_type = 1 if (!src.restrained()) var/M = null @@ -649,7 +684,7 @@ else message = "[src] holds out \his hand to [M]." - if("dap") + if("dap", "daps") m_type = 1 if (!src.restrained()) var/M = null @@ -663,7 +698,7 @@ else message = "[src] sadly can't find anybody to give daps to, and daps \himself. Shameful." - if("slap") + if("slap", "slaps") m_type = 1 if (!src.restrained()) var/M = null @@ -680,7 +715,7 @@ playsound(src.loc, 'sound/effects/snap.ogg', 50, 1) src.adjustFireLoss(4) - if ("scream") + if ("scream", "screams") if (miming) message = "[src] acts out a scream!" m_type = 1 @@ -703,7 +738,7 @@ m_type = 2 - if ("snap") + if ("snap", "snaps") if(prob(95)) m_type = 2 var/mob/living/carbon/human/H = src @@ -728,7 +763,7 @@ // Needed for M_TOXIC_FART - if("fart") + if("fart", "farts") if(reagents.has_reagent("simethicone")) return // playsound(src.loc, 'sound/effects/fart.ogg', 50, 1, -3) //Admins still vote no to fun @@ -789,7 +824,16 @@ if ("help") - src << "blink, blink_r, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough,\ncry, custom, deathgasp, drool, eyebrow, frown, gasp, giggle, groan, grumble, handshake, hug-(none)/mob, glare-(none)/mob,\ngrin, laugh, look-(none)/mob, moan, mumble, nod, pale, point-atom, raise, salute, shake, shiver, shrug,\nsigh, signal-#1-10, smile, sneeze, sniff, snore, stare-(none)/mob, tremble, twitch, twitch_s, whimper,\nwink, yawn" + var/emotelist = "aflap(s), airguitar, blink(s), blink(s)_r, blush(es), bow(s)-(none)/mob, burp(s), choke(s), chuckle(s), clap(s), collapse(s), cough(s),cry, cries, custom, dap(s)(none)/mob," \ + + " deathgasp(s), drool(s), eyebrow,fart(s), faint(s), flap(s), flip(s), frown(s), gasp(s), giggle(s), glare(s)-(none)/mob, grin(s), groan(s), grumble(s), handshake-mob, hug(s)-(none)/mob," \ + + " glare(s)-(none)/mob, grin(s), johnny, laugh(s), look(s)-(none)/mob, moan(s), mumble(s), nod(s), pale(s), point(s)-atom, quiver(s), raise(s), salute(s)-(none)/mob, scream(s), shake(s)," \ + + " shiver(s), shrug(s), sigh(s), signal(s)-#1-10,slap(s)-(none)/mob, smile(s),snap(s), sneeze(s), sniff(s), snore(s), stare(s)-(none)/mob, swag(s), tremble(s), twitch(es), twitch(es)_s," \ + + " wag(s), wave(s), whimper(s), wink(s), yawn(s)" + if(species.name == "Machine") + emotelist += "\nMachine specific emotes :- beep(s)-(none)/mob, buzz(es)-none/mob, no-(none)/mob, ping(s)-(none)/mob, yes-(none)/mob" + else if(species.name == "Slime People") + emotelist += "\nSlime people specific emotes :- squish(es)-(none)/mob" + src << emotelist else src << "\blue Unusable emote '[act]'. Say *help for a list." diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index f0e30751fc7..57261782385 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -253,12 +253,15 @@ if(getBrainLoss() >= 60) msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n" - if(species.show_ssd && (!species.has_organ["brain"] || brain_op_stage != 4) && stat != DEAD) + if(species.show_ssd && (!species.has_organ["brain"] || get_int_organ(/obj/item/organ/internal/brain)) && stat != DEAD) if(!key) msg += "[t_He] [t_is] fast asleep. It doesn't look like they are waking up anytime soon.\n" else if(!client) msg += "[t_He] [t_has] suddenly fallen asleep.\n" + if(!get_int_organ(/obj/item/organ/internal/brain)) + msg += "It appears that [t_his] brain is missing...\n" + var/list/wound_flavor_text = list() var/list/is_destroyed = list() var/list/is_bleeding = list() @@ -487,11 +490,12 @@ /proc/hasHUD(mob/M as mob, hudtype) if(istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/H = M + var/obj/item/organ/internal/cyberimp/eyes/hud/CIH = H.get_int_organ(/obj/item/organ/internal/cyberimp/eyes/hud) switch(hudtype) if("security") - return istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.glasses, /obj/item/clothing/glasses/hud/security/sunglasses) + return istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.glasses, /obj/item/clothing/glasses/hud/security/sunglasses) || istype(CIH,/obj/item/organ/internal/cyberimp/eyes/hud/security) if("medical") - return istype(H.glasses, /obj/item/clothing/glasses/hud/health) || istype(H.glasses, /obj/item/clothing/glasses/hud/health/health_advanced) + return istype(H.glasses, /obj/item/clothing/glasses/hud/health) || istype(H.glasses, /obj/item/clothing/glasses/hud/health/health_advanced) || istype(CIH,/obj/item/organ/internal/cyberimp/eyes/hud/medical) else return 0 else if(istype(M, /mob/living/silicon)) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 280d1f8a725..6b670eb9d1e 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -44,7 +44,7 @@ if(!delay_ready_dna && dna) dna.ready_dna(src) dna.real_name = real_name - sync_organ_dna() //this shouldn't be necessaaaarrrryyyyyyyy + sync_organ_dna(1) if(species) species.handle_dna(src) @@ -278,6 +278,11 @@ cell_status = "[suit.cell.charge]/[suit.cell.maxcharge]" stat(null, "Suit charge: [cell_status]") + // I REALLY need to split up status panel things into datums + var/mob/living/simple_animal/borer/B = has_brain_worms() + if(B && B.controlling) + stat("Chemicals", B.chemicals) + if(mind) if(mind.changeling) stat("Chemical Storage", "[mind.changeling.chem_charges]/[mind.changeling.chem_storage]") @@ -394,6 +399,15 @@ var/obj/item/organ/external/affecting = get_organ(ran_zone(dam_zone)) 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)) + 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; they can't be hit with ranged weapons!", "You deflect the projectile!") + return 0 + ..() + /mob/living/carbon/human/attack_animal(mob/living/simple_animal/M as mob) if(M.melee_damage_upper == 0) M.custom_emote(1, "[M.friendly] [src]") @@ -441,8 +455,7 @@ /mob/living/carbon/human/attack_slime(mob/living/carbon/slime/M as mob) if(M.Victim) return // can't attack while eating! - if (health > -100) - + if(stat != DEAD) M.do_attack_animation(src) visible_message("The [M.name] glomps [src]!", \ "The [M.name] glomps [src]!") @@ -752,6 +765,12 @@ /mob/living/carbon/human/Topic(href, href_list) if(!usr.stat && usr.canmove && !usr.restrained() && in_range(src, usr)) + var/thief_mode = 0 + if(ishuman(usr)) + var/mob/living/carbon/human/H = usr + var/obj/item/clothing/gloves/G = H.gloves + if(G && G.pickpocket) + thief_mode = 1 if(href_list["item"]) var/slot = text2num(href_list["item"]) @@ -780,6 +799,8 @@ if(pocket_item) if(pocket_item == (pocket_id == slot_r_store ? r_store : l_store)) //item still in the pocket we search unEquip(pocket_item) + if(thief_mode) + usr.put_in_hands(pocket_item) else if(place_item) usr.unEquip(place_item) @@ -789,8 +810,9 @@ if(usr.machine == src && in_range(src, usr)) show_inv(usr) else - // Display a warning if the user mocks up - src << "You feel your [pocket_side] pocket being fumbled with!" + // Display a warning if the user mocks up if they don't have pickpocket gloves. + if(!thief_mode) + src << "You feel your [pocket_side] pocket being fumbled with!" if(href_list["set_sensor"]) if(istype(w_uniform, /obj/item/clothing/under)) @@ -802,12 +824,14 @@ var/obj/item/clothing/under/U = w_uniform if(U.accessories.len) var/obj/item/clothing/accessory/A = U.accessories[1] - usr.visible_message("\The [usr] starts to take off \the [A] from \the [src]'s [U]!", \ - "You start to take off \the [A] from \the [src]'s [U]!") + if(!thief_mode) + usr.visible_message("\The [usr] starts to take off \the [A] from \the [src]'s [U]!", \ + "You start to take off \the [A] from \the [src]'s [U]!") if(do_mob(usr, src, 40) && A && U.accessories.len) - usr.visible_message("\The [usr] takes \the [A] off of \the [src]'s [U]!", \ - "You take \the [A] off of \the [src]'s [U]!") + if(!thief_mode) + usr.visible_message("\The [usr] takes \the [A] off of \the [src]'s [U]!", \ + "You take \the [A] off of \the [src]'s [U]!") A.on_removed(usr) U.accessories -= A update_inv_w_uniform() @@ -1092,7 +1116,7 @@ ///eyecheck() ///Returns a number between -1 to 2 /mob/living/carbon/human/eyecheck() - var/number = 0 + var/number = ..() if(istype(src.head, /obj/item/clothing/head)) //are they wearing something on their head var/obj/item/clothing/head/HFP = src.head //if yes gets the flash protection value from that item number += HFP.flash_protect @@ -1102,6 +1126,9 @@ if(istype(src.wear_mask, /obj/item/clothing/mask)) //mask var/obj/item/clothing/mask/MFP = src.wear_mask number += MFP.flash_protect + for(var/obj/item/organ/internal/cyberimp/eyes/EFP in src.internal_organs) + number += EFP.flash_protect + return number ///tintcheck() @@ -1286,7 +1313,7 @@ species.create_organs(src) if(!client || !key) //Don't boot out anyone already in the mob. - for (var/obj/item/organ/brain/H in world) + for (var/obj/item/organ/internal/brain/H in world) if(H.brainmob) if(H.brainmob.real_name == src.real_name) if(H.brainmob.mind) @@ -1302,14 +1329,14 @@ ..() /mob/living/carbon/human/proc/is_lung_ruptured() - var/obj/item/organ/lungs/L = internal_organs_by_name["lungs"] + var/obj/item/organ/internal/lungs/L = get_int_organ(/obj/item/organ/internal/lungs) if(!L) return 0 return L.is_bruised() /mob/living/carbon/human/proc/rupture_lung() - var/obj/item/organ/lungs/L = internal_organs_by_name["lungs"] + var/obj/item/organ/internal/lungs/L = get_int_organ(/obj/item/organ/internal/lungs) if(!L) return 0 @@ -1382,6 +1409,8 @@ /mob/living/carbon/human/generate_name() name = species.makeName(gender,src) real_name = name + if(dna) + dna.real_name = name return name /mob/living/carbon/human/proc/handle_embedded_objects() @@ -1852,3 +1881,6 @@ for(var/obj/item/clothing/C in src) //If they have some clothing equipped that lets them see reagents, they can see reagents if(C.scan_reagents) return 1 + +/mob/living/carbon/human/can_eat(flags = 255) + return species && (species.dietflags & flags) diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index 155e50eef28..e8ca0524f01 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -59,6 +59,16 @@ switch(M.a_intent) if(I_HELP) + if(can_operate(src)) + if(health >= config.health_threshold_crit) + if(src.surgeries.len) + for(var/datum/surgery/S in src.surgeries) + if(S.next_step(M, src)) + return 1 + else + help_shake_act(M) + add_logs(src, M, "shaked") + return 1 if(health >= config.health_threshold_crit) help_shake_act(M) add_logs(src, M, "shaked") @@ -139,7 +149,7 @@ else LAssailant = M - var/damage = rand(0, M.species.max_hurt_damage)//BS12 EDIT + var/damage = rand(M.species.punchdamagelow, M.species.punchdamagehigh) damage += attack.damage if(!damage) playsound(loc, attack.miss_sound, 25, 1, -1) @@ -158,7 +168,7 @@ visible_message("\red [M] [pick(attack.attack_verb)]ed [src]!") apply_damage(damage, BRUTE, affecting, armor_block, sharp=attack.sharp, edge=attack.edge) //moving this back here means Armalis are going to knock you down 70% of the time, but they're pure adminbus anyway. - if((stat != DEAD) && damage >= 9) + if((stat != DEAD) && damage >= M.species.punchstunthreshold) visible_message("[M] has weakened [src]!", \ "[M] has weakened [src]!") apply_effect(4, WEAKEN, armor_block) diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index cbf77866005..0b413d1915c 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -1,7 +1,7 @@ //Updates the mob's health from organs and mob damage variables /mob/living/carbon/human/updatehealth() if(status_flags & GODMODE) - health = 100 + health = maxHealth stat = CONSCIOUS return @@ -12,15 +12,15 @@ total_brute += O.brute_dam //calculates health based on organ brute and burn total_burn += O.burn_dam - health = 100 - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute + health = maxHealth - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute //TODO: fix husking - if(((100 - total_burn) < config.health_threshold_dead) && stat == DEAD) //100 is the magic human max health number - ChangeToHusk() //BECAUSE NO ONE THOUGHT TO USE LIVING/VAR/MAXHEALTH I GUESS + if(((maxHealth - total_burn) < config.health_threshold_dead) && stat == DEAD) + ChangeToHusk() if(species.can_revive_by_healing) - var/obj/item/organ/brain/B = internal_organs_by_name["brain"] + var/obj/item/organ/internal/brain/B = get_int_organ(/obj/item/organ/internal/brain) if(B) - if((health >= (config.health_threshold_dead / 100 * 75)) && stat == DEAD) + if((health >= (config.health_threshold_dead + config.health_threshold_crit) * 0.5) && stat == DEAD) update_revive() if(stat == CONSCIOUS && (src in dead_mob_list)) //Defib fix update_revive() @@ -32,7 +32,7 @@ return 0 //godmode if(species && species.has_organ["brain"]) - var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"] + var/obj/item/organ/internal/brain/sponge = get_int_organ(/obj/item/organ/internal/brain) if(sponge) sponge.take_damage(amount, 1) brainloss = sponge.damage @@ -46,7 +46,7 @@ return 0 //godmode if(species && species.has_organ["brain"]) - var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"] + var/obj/item/organ/internal/brain/sponge = get_int_organ(/obj/item/organ/internal/brain) if(sponge) sponge.damage = min(max(amount, 0),(maxHealth*2)) brainloss = sponge.damage @@ -60,7 +60,7 @@ return 0 //godmode if(species && species.has_organ["brain"]) - var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"] + var/obj/item/organ/internal/brain/sponge = get_int_organ(/obj/item/organ/internal/brain) if(sponge) brainloss = min(sponge.damage,maxHealth*2) else @@ -127,12 +127,6 @@ O.heal_damage(0, -amount, internal=0, robo_repair=(O.status & ORGAN_ROBOT)) -/mob/living/carbon/human/Stun(amount) - ..() - -/mob/living/carbon/human/Weaken(amount) - ..() - /mob/living/carbon/human/Paralyse(amount) // Notify our AI if they can now control the suit. if(wearing_rig && !stat && paralysis < amount) //We are passing out right this second. diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 2e24edb8518..afbe24be5ac 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -72,7 +72,6 @@ var/datum/martial_art/martial_art = null - var/miming = null //Toggle for the mime's abilities. var/special_voice = "" // For changing our voice. Used by a symptom. var/said_last_words=0 diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 4442d59fe85..5278f0cc723 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -13,7 +13,7 @@ handle_embedded_objects() //Moving with objects stuck in you can cause bad times. - var/health_deficiency = (100 - health + staminaloss) + var/health_deficiency = (maxHealth - health + staminaloss) if(reagents) for(var/datum/reagent/R in reagents.reagent_list) if(R.shock_reduction) diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm index c83c35bd61b..100eff321d4 100644 --- a/code/modules/mob/living/carbon/human/human_organs.dm +++ b/code/modules/mob/living/carbon/human/human_organs.dm @@ -1,13 +1,11 @@ /mob/living/carbon/human/proc/update_eyes() - var/obj/item/organ/eyes/eyes = internal_organs_by_name["eyes"] + var/obj/item/organ/internal/eyes/eyes = get_int_organ(/obj/item/organ/internal/eyes) if(eyes) eyes.update_colour() regenerate_icons() -/mob/living/carbon/var/list/internal_organs = list() /mob/living/carbon/human/var/list/organs = list() /mob/living/carbon/human/var/list/organs_by_name = list() // map organ names to organs -/mob/living/carbon/human/var/list/internal_organs_by_name = list() // so internal organs have less ickiness too // Takes care of organ related updates, such as broken and missing limbs /mob/living/carbon/human/proc/handle_organs() @@ -24,7 +22,7 @@ bad_external_organs |= Ex //processing internal organs is pretty cheap, do that first. - for(var/obj/item/organ/I in internal_organs) + for(var/obj/item/organ/internal/I in internal_organs) I.process() //handle_stance() @@ -47,7 +45,7 @@ if (!lying && world.time - l_move_time < 15) //Moving around with fractured ribs won't do you any good if (E.is_broken() && E.internal_organs && E.internal_organs.len && prob(15)) - var/obj/item/organ/I = pick(E.internal_organs) + var/obj/item/organ/internal/I = pick(E.internal_organs) custom_pain("You feel broken bones moving in your [E.name]!", 1) I.take_damage(rand(3,5)) @@ -143,13 +141,18 @@ /mob/living/carbon/human/proc/handle_trace_chems() //New are added for reagents to random organs. for(var/datum/reagent/A in reagents.reagent_list) - var/obj/item/organ/O = pick(organs) + var/obj/item/organ/internal/O = pick(organs) O.trace_chemicals[A.name] = 100 -/mob/living/carbon/human/proc/sync_organ_dna() +/* +When assimilate is 1, organs that have a different UE will still have their DNA overriden by that of the host +Otherwise, this restricts itself to organs that share the UE of the host. +*/ +/mob/living/carbon/human/proc/sync_organ_dna(var/assimilate = 1) var/list/all_bits = internal_organs|organs for(var/obj/item/organ/O in all_bits) - O.set_dna(dna) + if(assimilate || O.dna.unique_enzymes == dna.unique_enzymes) + O.set_dna(dna) /* Given the name of an organ, returns the external organ it's contained in @@ -157,7 +160,7 @@ I use this to standardize shadowling dethrall code -- Crazylemon */ /mob/living/carbon/human/proc/named_organ_parent(var/organ_name) - if (!(organ_name in internal_organs_by_name)) + if (!get_int_organ(organ_name)) return null - var/obj/item/organ/O = internal_organs_by_name[organ_name] + var/obj/item/organ/internal/O = get_int_organ(organ_name) return O.parent_organ \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 4b7fa40588e..e4555a3c500 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -111,7 +111,7 @@ if(!. || !I) return - var/obj/item/organ/O = I //Organs shouldn't be removed unless you call droplimb. + var/obj/item/organ/internal/O = I //Organs shouldn't be removed unless you call droplimb. if(istype(O) && O.owner == src) return diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 2d327d74b1d..4154c1b7aa1 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -217,7 +217,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc if(!(species.flags & RADIMMUNE)) if (radiation) - if((locate(src.internal_organs_by_name["resonant crystal"]) in src.internal_organs)) + if(get_int_organ(/obj/item/organ/internal/nucleation/resonant_crystal)) var/rads = radiation/25 radiation -= rads radiation -= 0.1 @@ -296,14 +296,14 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc if(istype(O)) O.add_autopsy_data("Radiation Poisoning", damage) /mob/living/carbon/human/breathe() - if(reagents.has_reagent("lexorin")) + + if((NO_BREATH in mutations) || (species && (species.flags & NO_BREATHE)) || reagents.has_reagent("lexorin")) + adjustOxyLoss(-5) + oxygen_alert = 0 + toxins_alert = 0 return - if(NO_BREATH in mutations) - return // No breath mutation means no breathing. //DID YOU REALLY NEED TO FUCKING STATE THIS? if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return - if(species && (species.flags & NO_BREATHE)) - return var/datum/gas_mixture/environment if(loc) @@ -889,7 +889,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc //Vision //god knows why this is here var/obj/item/organ/vision if(species.vision_organ) - vision = internal_organs_by_name[species.vision_organ] + vision = get_int_organ(species.vision_organ) if(!species.vision_organ) // Presumably if a species has no vision organs, they see via some other means. eye_blind = 0 @@ -1209,7 +1209,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc /mob/living/carbon/human/proc/handle_heartbeat() var/client/C = src.client if(C && C.prefs.sound & SOUND_HEARTBEAT) //disable heartbeat by pref - var/obj/item/organ/heart/H = internal_organs_by_name["heart"] + var/obj/item/organ/internal/heart/H = get_int_organ(/obj/item/organ/internal/heart) if(!H) //H.status will runtime if there is no H (obviously) return @@ -1279,11 +1279,10 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc if(!heart_attack) return else - losebreath += 5 - adjustOxyLoss(10) - adjustBrainLoss(rand(4,10)) - Paralyse(2) - return + if(losebreath < 3) + losebreath += 2 + adjustOxyLoss(5) + adjustBruteLoss(1) diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index 569d5247edb..f736a17af22 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -90,6 +90,11 @@ return GetSpecialVoice() return real_name +/mob/living/carbon/human/IsVocal() + if(mind) + return !mind.miming + return 1 + /mob/living/carbon/human/proc/SetSpecialVoice(var/new_voice) if(new_voice) special_voice = new_voice diff --git a/code/modules/mob/living/carbon/human/species/apollo.dm b/code/modules/mob/living/carbon/human/species/apollo.dm index 8d0e64d44af..a5e92e951d9 100644 --- a/code/modules/mob/living/carbon/human/species/apollo.dm +++ b/code/modules/mob/living/carbon/human/species/apollo.dm @@ -6,6 +6,8 @@ language = "Wryn Hivemind" tail = "wryntail" unarmed_type = /datum/unarmed_attack/punch/weak + punchdamagelow = 0 + punchdamagehigh = 1 //primitive = /mob/living/carbon/monkey/wryn darksight = 3 slowdown = 1 @@ -28,11 +30,11 @@ body_temperature = 286 has_organ = list( - "heart" = /obj/item/organ/heart, - "brain" = /obj/item/organ/brain, - "eyes" = /obj/item/organ/eyes, - "appendix" = /obj/item/organ/appendix, - "antennae" = /obj/item/organ/wryn/hivenode + "heart" = /obj/item/organ/internal/heart, + "brain" = /obj/item/organ/internal/brain, + "eyes" = /obj/item/organ/internal/eyes, + "appendix" = /obj/item/organ/internal/appendix, + "antennae" = /obj/item/organ/internal/wryn/hivenode ) flags = IS_WHITELISTED | HAS_LIPS | NO_BREATHE | HAS_SKIN_COLOR | NO_SCAN | NO_SCAN | HIVEMIND @@ -47,14 +49,14 @@ /datum/species/wryn/handle_death(var/mob/living/carbon/human/H) for(var/mob/living/carbon/C in living_mob_list) - if(locate(/obj/item/organ/wryn/hivenode) in C.internal_organs) + if(C.get_int_organ(/obj/item/organ/internal/wryn/hivenode)) C << "Your antennae tingle as you are overcome with pain..." C << "It feels like part of you has died." /datum/species/wryn/handle_attack_hand(var/mob/living/carbon/human/H, var/mob/living/carbon/human/M) if(M.a_intent == I_HARM) if(H.handcuffed) - if(!(locate(H.internal_organs_by_name["antennae"]) in H.internal_organs)) return + if(!H.get_int_organ(/obj/item/organ/internal/wryn/hivenode)) return var/turf/p_loc = M.loc var/turf/p_loc_m = H.loc @@ -62,9 +64,10 @@ H << "[M] grips your antennae and starts violently pulling!" do_after(H, 250, target = src) if(p_loc == M.loc && p_loc_m == H.loc) - qdel(H.internal_organs_by_name["antennae"]) + var/obj/item/organ/internal/wryn/hivenode/node = new /obj/item/organ/internal/wryn/hivenode H.remove_language("Wryn Hivemind") - new /obj/item/organ/wryn/hivenode(M.loc) + node.remove(H) + node.loc = M.loc M << "You hear a loud crunch as you mercilessly pull off [H]'s antennae." H << "You hear a loud crunch as your antennae is ripped off your head by [M]." H << "It's so quiet..." @@ -96,12 +99,13 @@ reagent_tag = PROCESS_ORG has_organ = list( - "heart" = /obj/item/organ/heart, - "crystalized brain" = /obj/item/organ/brain/crystal, - "eyes" = /obj/item/organ/eyes/luminescent_crystal, - "strange crystal" = /obj/item/organ/nucleation/strange_crystal, - "resonant crystal" = /obj/item/organ/nucleation/resonant_crystal + "heart" = /obj/item/organ/internal/heart, + "crystalized brain" = /obj/item/organ/internal/brain/crystal, + "eyes" = /obj/item/organ/internal/eyes/luminescent_crystal, + "strange crystal" = /obj/item/organ/internal/nucleation/strange_crystal, + "resonant crystal" = /obj/item/organ/internal/nucleation/resonant_crystal ) + vision_organ = /obj/item/organ/internal/eyes/luminescent_crystal /datum/species/nucleation/handle_post_spawn(var/mob/living/carbon/human/H) H.light_color = "#1C1C00" diff --git a/code/modules/mob/living/carbon/human/species/golem.dm b/code/modules/mob/living/carbon/human/species/golem.dm index 799226ea321..f3e8793fed1 100644 --- a/code/modules/mob/living/carbon/human/species/golem.dm +++ b/code/modules/mob/living/carbon/human/species/golem.dm @@ -6,16 +6,37 @@ deform = 'icons/mob/human_races/r_golem.dmi' default_language = "Galactic Common" - flags = NO_BREATHE | NO_PAIN | NO_BLOOD | NO_SCAN + flags = NO_BREATHE | NO_BLOOD | RADIMMUNE + virus_immune = 1 dietflags = DIET_OMNI //golems can eat anything because they are magic or something reagent_tag = PROCESS_ORG + unarmed_type = /datum/unarmed_attack/punch + punchdamagelow = 5 + punchdamagehigh = 14 + punchstunthreshold = 11 //about 40% chance to stun + + warning_low_pressure = -1 + hazard_low_pressure = -1 + hazard_high_pressure = 999999999 + warning_high_pressure = 999999999 + + cold_level_1 = -1 + cold_level_2 = -1 + cold_level_3 = -1 + + heat_level_1 = 999999999 + heat_level_2 = 999999999 + heat_level_3 = 999999999 + heat_level_3_breathe = 999999999 + blood_color = "#515573" flesh_color = "#137E8F" + slowdown = 3 siemens_coeff = 0 has_organ = list( - "brain" = /obj/item/organ/brain/golem + "brain" = /obj/item/organ/internal/brain/golem ) suicide_messages = list( "is crumbling into dust!", @@ -45,62 +66,36 @@ item_color = "golem" has_sensor = 0 flags = ABSTRACT | NODROP - armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) + armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) /obj/item/clothing/suit/golem name = "adamantine shell" desc = "a golem's thick outter shell" icon_state = "golem" item_state = "golem" - w_class = 4//bulky item - gas_transfer_coefficient = 0.90 - permeability_coefficient = 0.50 - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS|HEAD - slowdown = 1.0 - flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT - flags = ONESIZEFITSALL | STOPSPRESSUREDMAGE | ABSTRACT | NODROP - heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS | HEAD - max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT - cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS | HEAD - min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT - armor = list(melee = 80, bullet = 20, laser = 20, energy = 10, bomb = 0, bio = 0, rad = 0) + body_parts_covered = HEAD|UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS + flags_inv = HIDEGLOVES|HIDESHOES + flags = ONESIZEFITSALL | ABSTRACT | NODROP | THICKMATERIAL + armor = list(melee = 55, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) /obj/item/clothing/shoes/golem name = "golem's feet" desc = "sturdy adamantine feet" icon_state = "golem" item_state = "golem" - flags = NOSLIP | ABSTRACT | AIRTIGHT | MASKCOVERSMOUTH | NODROP - slowdown = SHOES_SLOWDOWN+1 - + flags = ABSTRACT | NODROP /obj/item/clothing/mask/gas/golem name = "golem's face" desc = "the imposing face of an adamantine golem" icon_state = "golem" item_state = "golem" - siemens_coefficient = 0 unacidable = 1 flags = ABSTRACT | NODROP - /obj/item/clothing/gloves/golem name = "golem's hands" desc = "strong adamantine hands" icon_state = "golem" item_state = null - siemens_coefficient = 0 - flags = ABSTRACT | NODROP - - -/obj/item/clothing/head/space/golem - icon_state = "golem" - item_state = "dermal" - item_color = "dermal" - name = "golem's head" - desc = "a golem's head" - unacidable = 1 - flags = STOPSPRESSUREDMAGE | ABSTRACT | NODROP - heat_protection = HEAD - max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT - armor = list(melee = 80, bullet = 20, laser = 20, energy = 10, bomb = 0, bio = 0, rad = 0) \ No newline at end of file + flags = ABSTRACT | NODROP \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/shadow.dm b/code/modules/mob/living/carbon/human/species/shadow.dm index 635eb9ede3e..f0e724f0f10 100644 --- a/code/modules/mob/living/carbon/human/species/shadow.dm +++ b/code/modules/mob/living/carbon/human/species/shadow.dm @@ -13,7 +13,7 @@ blood_color = "#CCCCCC" flesh_color = "#AAAAAA" has_organ = list( - "brain" = /obj/item/organ/brain + "brain" = /obj/item/organ/internal/brain ) flags = NO_BLOOD | NO_BREATHE | NO_SCAN diff --git a/code/modules/mob/living/carbon/human/species/skeleton.dm b/code/modules/mob/living/carbon/human/species/skeleton.dm index 713a83d1180..7a4f1bae4eb 100644 --- a/code/modules/mob/living/carbon/human/species/skeleton.dm +++ b/code/modules/mob/living/carbon/human/species/skeleton.dm @@ -37,7 +37,7 @@ "is collapsing into a pile!", "is twisting their skull off!") has_organ = list( - "brain" = /obj/item/organ/brain/golem, + "brain" = /obj/item/organ/internal/brain/golem, ) /datum/species/skeleton/handle_reagents(var/mob/living/carbon/human/H, var/datum/reagent/R) diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index cdcd90d6523..2aa84f9c95e 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -59,7 +59,9 @@ var/light_effect_amp //If 0, takes/heals 1 burn and brute per tick. Otherwise, both healing and damage effects are amplified. var/total_health = 100 - var/max_hurt_damage = 9 // Max melee damage dealt + 5 if hulk + var/punchdamagelow = 0 //lowest possible punch damage + var/punchdamagehigh = 9 //highest possible punch damage + var/punchstunthreshold = 9 //damage at which punches from this race will stun //yes it should be to the attacked race but it's not useful that way even if it's logical var/list/default_genes = list() var/ventcrawler = 0 //Determines if the mob can go through the vents. @@ -105,13 +107,13 @@ // Determines the organs that the species spawns with and var/list/has_organ = list( // which required-organ checks are conducted. - "heart" = /obj/item/organ/heart, - "lungs" = /obj/item/organ/lungs, - "liver" = /obj/item/organ/liver, - "kidneys" = /obj/item/organ/kidneys, - "brain" = /obj/item/organ/brain, - "appendix" = /obj/item/organ/appendix, - "eyes" = /obj/item/organ/eyes + "heart" = /obj/item/organ/internal/heart, + "lungs" = /obj/item/organ/internal/lungs, + "liver" = /obj/item/organ/internal/liver, + "kidneys" = /obj/item/organ/internal/kidneys, + "brain" = /obj/item/organ/internal/brain, + "appendix" = /obj/item/organ/internal/appendix, + "eyes" = /obj/item/organ/internal/eyes ) var/vision_organ // If set, this organ is required for vision. Defaults to "eyes" if the species has them. var/list/has_limbs = list( @@ -133,7 +135,7 @@ /datum/species/New() //If the species has eyes, they are the default vision organ if(!vision_organ && has_organ["eyes"]) - vision_organ = "eyes" + vision_organ = /obj/item/organ/internal/eyes unarmed = new unarmed_type() @@ -143,19 +145,21 @@ /datum/species/proc/create_organs(var/mob/living/carbon/human/H) //Handles creation of mob organs. + + for(var/obj/item/organ/internal/iorgan in H.internal_organs) + if(iorgan in H.internal_organs) + qdel(iorgan) + for(var/obj/item/organ/organ in H.contents) - if((organ in H.organs) || (organ in H.internal_organs)) + if(organ in H.organs) qdel(organ) if(H.organs) H.organs.Cut() - if(H.internal_organs) H.internal_organs.Cut() if(H.organs_by_name) H.organs_by_name.Cut() - if(H.internal_organs_by_name) H.internal_organs_by_name.Cut() H.organs = list() H.internal_organs = list() H.organs_by_name = list() - H.internal_organs_by_name = list() for(var/limb_type in has_limbs) var/list/organ_data = has_limbs[limb_type] @@ -163,9 +167,12 @@ var/obj/item/organ/O = new limb_path(H) organ_data["descriptor"] = O.name - for(var/organ in has_organ) - var/organ_type = has_organ[organ] - H.internal_organs_by_name[organ] = new organ_type(H,1) + for(var/index in has_organ) + var/organ = has_organ[index] + H.internal_organs |= new organ(H) + + for(var/obj/item/organ/internal/I in H.internal_organs) + I.insert(H) for(var/name in H.organs_by_name) H.organs |= H.organs_by_name[name] @@ -375,7 +382,7 @@ /datum/unarmed_attack var/attack_verb = list("attack") // Empty hand hurt intent verb. - var/damage = 0 // Extra empty hand attack damage. + var/damage = 0 // How much flat bonus damage an attack will do. This is a *bonus* guaranteed damage amount on top of the random damage attacks do. var/attack_sound = "punch" var/miss_sound = 'sound/weapons/punchmiss.ogg' var/sharp = 0 @@ -386,7 +393,6 @@ /datum/unarmed_attack/punch/weak attack_verb = list("flail") - damage = 1 /datum/unarmed_attack/diona attack_verb = list("lash", "bludgeon") @@ -400,7 +406,7 @@ /datum/unarmed_attack/claws/armalis attack_verb = list("slash", "claw") - damage = 6 //they're huge! they should do a little more damage, i'd even go for 15-20 maybe... + damage = 6 /datum/species/proc/handle_can_equip(obj/item/I, slot, disable_warning = 0, mob/living/carbon/human/user) return 0 @@ -417,7 +423,7 @@ H.see_invisible = SEE_INVISIBLE_LIVING if(H.mind && H.mind.vampire) - if(VAMP_VISION in H.mind.vampire.powers && !(VAMP_FULL in H.mind.vampire.powers)) + if((VAMP_VISION in H.mind.vampire.powers) && (!(VAMP_FULL in H.mind.vampire.powers))) H.sight |= SEE_MOBS else if(VAMP_FULL in H.mind.vampire.powers) @@ -462,14 +468,6 @@ if(!G.see_darkness) H.see_invisible = SEE_INVISIBLE_MINIMUM - //switch(G.HUDType) - // if(SECHUD) - // process_sec_hud(H,1) - // if(MEDHUD) - // process_med_hud(H,1) - // if(ANTAGHUD) - // process_antag_hud(H) - if(H.head) if(istype(H.head, /obj/item/clothing/head)) var/obj/item/clothing/head/hat = H.head @@ -640,6 +638,7 @@ Returns the path corresponding to the corresponding organ It'll return null if the organ doesn't correspond, so include null checks when using this! */ +//Fethas Todo:Do i need to redo this? /datum/species/proc/return_organ(var/organ_slot) if(!(organ_slot in has_organ)) return null diff --git a/code/modules/mob/living/carbon/human/species/station.dm b/code/modules/mob/living/carbon/human/species/station.dm index 9ff0c71657e..7add227c491 100644 --- a/code/modules/mob/living/carbon/human/species/station.dm +++ b/code/modules/mob/living/carbon/human/species/station.dm @@ -316,13 +316,13 @@ icon_template = 'icons/mob/human_races/r_armalis.dmi' has_organ = list( - "heart" = /obj/item/organ/heart, - "lungs" = /obj/item/organ/lungs, - "liver" = /obj/item/organ/liver, - "kidneys" = /obj/item/organ/kidneys, - "brain" = /obj/item/organ/brain, - "eyes" = /obj/item/organ/eyes, - "stack" = /obj/item/organ/stack/vox + "heart" = /obj/item/organ/internal/heart, + "lungs" = /obj/item/organ/internal/lungs, + "liver" = /obj/item/organ/internal/liver, + "kidneys" = /obj/item/organ/internal/kidneys, + "brain" = /obj/item/organ/internal/brain, + "eyes" = /obj/item/organ/internal/eyes, + "stack" = /obj/item/organ/internal/stack/vox ) suicide_messages = list( @@ -382,7 +382,7 @@ //ventcrawler = 1 //ventcrawling commented out has_organ = list( - "brain" = /obj/item/organ/brain/slime + "brain" = /obj/item/organ/internal/brain/slime ) suicide_messages = list( @@ -612,12 +612,12 @@ reagent_tag = PROCESS_ORG has_organ = list( - "nutrient channel" = /obj/item/organ/diona/nutrients, - "neural strata" = /obj/item/organ/diona/strata, - "response node" = /obj/item/organ/diona/node, - "gas bladder" = /obj/item/organ/diona/bladder, - "polyp segment" = /obj/item/organ/diona/polyp, - "anchoring ligament" = /obj/item/organ/diona/ligament + "nutrient channel" = /obj/item/organ/internal/liver/diona, + "neural strata" = /obj/item/organ/internal/heart/diona, + "receptor node" = /obj/item/organ/internal/eyes/diona, + "gas bladder" = /obj/item/organ/internal/brain/diona, + "polyp segment" = /obj/item/organ/internal/kidneys/diona, + "anchoring ligament" = /obj/item/organ/internal/appendix/diona ) has_limbs = list( @@ -712,12 +712,12 @@ reagent_tag = PROCESS_SYN has_organ = list( - "brain" = /obj/item/organ/mmi_holder/posibrain, - "cell" = /obj/item/organ/cell, - "optics" = /obj/item/organ/optical_sensor + "brain" = /obj/item/organ/internal/brain/mmi_holder/posibrain, + "cell" = /obj/item/organ/internal/cell, + "optics" = /obj/item/organ/internal/optical_sensor ) - vision_organ = "optics" + vision_organ = /obj/item/organ/internal/optical_sensor has_limbs = list( "chest" = list("path" = /obj/item/organ/external/chest/ipc), "groin" = list("path" = /obj/item/organ/external/groin/ipc), diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index d33c511fd99..b9230c9821f 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -177,11 +177,10 @@ Please contact me on #coderbus IRC. ~Carn x if(istype(I)) overlays += I else icon = stand_icon - if(overlays.len != overlays_standing.len) - overlays.Cut() + overlays.Cut() - for(var/thing in overlays_standing) - if(thing) overlays += thing + for(var/thing in overlays_standing) + if(thing) overlays += thing update_transform() @@ -251,7 +250,7 @@ var/global/list/damage_icon_parts = list() qdel(stand_icon) stand_icon = new(species.icon_template ? species.icon_template : 'icons/mob/human.dmi',"blank") var/icon_key = "" - var/obj/item/organ/eyes/eyes = internal_organs_by_name["eyes"] + var/obj/item/organ/internal/eyes/eyes = get_int_organ(/obj/item/organ/internal/eyes) if(eyes) icon_key += "[rgb(eyes.eye_colour[1], eyes.eye_colour[2], eyes.eye_colour[3])]" @@ -286,7 +285,7 @@ var/global/list/damage_icon_parts = list() else //BEGIN CACHED ICON GENERATION. var/obj/item/organ/external/chest = get_organ("chest") - base_icon = chest.get_icon() + base_icon = chest.get_icon(skeleton) for(var/obj/item/organ/external/part in organs) var/icon/temp = part.get_icon(skeleton) @@ -456,9 +455,12 @@ var/global/list/damage_icon_parts = list() //base icons var/icon/hair_standing = new /icon('icons/mob/human_face.dmi',"bald_s") + //var/icon/debrained_s = new /icon("icon"='icons/mob/human_face.dmi', "icon_state" = "debrained_s") if(h_style && !(head && (head.flags & BLOCKHEADHAIR) && !(isSynthetic()))) var/datum/sprite_accessory/hair_style = hair_styles_list[h_style] + //if(!src.get_int_organ(/obj/item/organ/internal/brain) && src.get_species() != "Machine" )//make it obvious we have NO BRAIN + // hair_standing.Blend(debrained_s, ICON_OVERLAY) if(hair_style && hair_style.species_allowed) if(src.species.name in hair_style.species_allowed) var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") @@ -470,6 +472,7 @@ var/global/list/damage_icon_parts = list() hair_standing.Blend(hair_s, ICON_OVERLAY) else //warning("Invalid h_style for [species.name]: [h_style]") + //hair_standing.Blend(debrained_s, ICON_OVERLAY)//how does i overlay for fish? overlays_standing[HAIR_LAYER] = image(hair_standing) @@ -924,27 +927,29 @@ var/global/list/damage_icon_parts = list() back.screen_loc = ui_back //TODO //determine the icon to use - var/icon/overlay_icon + var/icon/standing if(back.icon_override) - overlay_icon = back.icon_override + standing = image("icon" = back.icon_override, "icon_state" = "[back.icon_state]") else if(istype(back, /obj/item/weapon/rig)) //If this is a rig and a mob_icon is set, it will take species into account in the rig update_icon() proc. var/obj/item/weapon/rig/rig = back - overlay_icon = rig.mob_icon + standing = rig.mob_icon else if(back.sprite_sheets && back.sprite_sheets[species.name]) - overlay_icon = back.sprite_sheets[species.name] + standing = image("icon" = back.sprite_sheets[species.name], "icon_state" = "[back.icon_state]") else - overlay_icon = icon('icons/mob/back.dmi', "[back.icon_state]") + standing = image("icon" = 'icons/mob/back.dmi', "icon_state" = "[back.icon_state]") + /* //determine state to use var/overlay_state if(back.item_state) overlay_state = back.item_state else overlay_state = back.icon_state + */ //create the image - overlays_standing[BACK_LAYER] = image(icon = overlay_icon, icon_state = overlay_state) + overlays_standing[BACK_LAYER] = standing else overlays_standing[BACK_LAYER] = null @@ -956,6 +961,7 @@ var/global/list/damage_icon_parts = list() client.screen |= contents if(hud_used) hud_used.hidden_inventory_update() //Updates the screenloc of the items on the 'other' inventory bar + update_inv_handcuffed(0) // update handcuff overlay /mob/living/carbon/human/update_inv_handcuffed(var/update_icons=1) @@ -964,22 +970,23 @@ var/global/list/damage_icon_parts = list() drop_l_hand() stop_pulling() //TODO: should be handled elsewhere if(hud_used) //hud handcuff icons - var/obj/screen/inventory/R = hud_used.adding[7] - var/obj/screen/inventory/L = hud_used.adding[8] + var/obj/screen/inventory/R = hud_used.r_hand_hud_object + var/obj/screen/inventory/L = hud_used.l_hand_hud_object R.overlays += image("icon"='icons/mob/screen_gen.dmi', "icon_state"="markus") L.overlays += image("icon"='icons/mob/screen_gen.dmi', "icon_state"="gabrielle") if(istype(handcuffed, /obj/item/weapon/restraints/handcuffs/pinkcuffs)) - overlays_standing[HANDCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "pinkcuff1") + overlays_standing[HANDCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "pinkcuff1") else - overlays_standing[HANDCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "handcuff1") + overlays_standing[HANDCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "handcuff1") else - overlays_standing[HANDCUFF_LAYER] = null + overlays_standing[HANDCUFF_LAYER] = null if(hud_used) - var/obj/screen/inventory/R = hud_used.adding[7] - var/obj/screen/inventory/L = hud_used.adding[8] - R.overlays = null - L.overlays = null - if(update_icons) update_icons() + var/obj/screen/inventory/R = hud_used.r_hand_hud_object + var/obj/screen/inventory/L = hud_used.l_hand_hud_object + R.overlays.Cut() + L.overlays.Cut() + if(update_icons) + update_icons() /mob/living/carbon/human/update_inv_legcuffed(var/update_icons=1) if(legcuffed) diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index a182fa62f84..ed46d5370e5 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -9,6 +9,8 @@ if(..()) . = 1 + for(var/obj/item/organ/internal/O in internal_organs) + O.on_life() handle_changeling() handle_wetness() @@ -285,7 +287,7 @@ Weaken(5) setStaminaLoss(health - 2) return - setStaminaLoss(max((staminaloss - 2), 0)) + setStaminaLoss(max((staminaloss - 3), 0)) //this updates all special effects: stunned, sleeping, weakened, druggy, stuttering, etc.. /mob/living/carbon/handle_status_effects() @@ -344,18 +346,6 @@ do_jitter_animation(jitteriness) jitteriness = max(jitteriness - restingpwr, 0) - if(stuttering) - stuttering = max(stuttering-1, 0) - - if(slurring) - slurring = max(slurring-1,0) - - if(silent) - silent = max(silent-1, 0) - - if(druggy) - druggy = max(druggy-1, 0) - if(hallucination) spawn handle_hallucinations() @@ -482,6 +472,13 @@ if(see_override) see_invisible = see_override + +/mob/living/carbon/handle_actions() + ..() + for(var/obj/item/I in internal_organs) + give_action_button(I, 1) + + /mob/living/carbon/handle_hud_icons() return diff --git a/code/modules/mob/living/carbon/slime/slime.dm b/code/modules/mob/living/carbon/slime/slime.dm index 952a7095564..78c8db06a59 100644 --- a/code/modules/mob/living/carbon/slime/slime.dm +++ b/code/modules/mob/living/carbon/slime/slime.dm @@ -12,7 +12,6 @@ health = 150 gender = NEUTER - update_icon = 0 nutrition = 700 see_in_dark = 8 @@ -349,6 +348,12 @@ step_away(src,M) return + else + if(stat == DEAD && surgeries.len) + if(M.a_intent == I_HELP) + for(var/datum/surgery/S in surgeries) + if(S.next_step(M, src)) + return 1 /* if(M.gloves && istype(M.gloves,/obj/item/clothing/gloves)) @@ -482,6 +487,11 @@ return /mob/living/carbon/slime/attackby(obj/item/W, mob/user, params) + if(stat == DEAD && surgeries.len) + if(user.a_intent == I_HELP) + for(var/datum/surgery/S in surgeries) + if(S.next_step(user, src)) + return 1 if(istype(W,/obj/item/stack/sheet/mineral/plasma)) //Lets you feed slimes plasma. if (user in Friends) ++Friends[user] diff --git a/code/modules/mob/living/carbon/superheroes.dm b/code/modules/mob/living/carbon/superheroes.dm index d98a72f8e98..f3f5fe13006 100644 --- a/code/modules/mob/living/carbon/superheroes.dm +++ b/code/modules/mob/living/carbon/superheroes.dm @@ -17,7 +17,7 @@ assign_id(H) /datum/superheroes/proc/equip(var/mob/living/carbon/human/H) - H.fully_replace_character_name(H.real_name, name) + H.rename_character(H.real_name, name) for(var/obj/item/W in H) if(istype(W,/obj/item/organ)) continue H.unEquip(W) @@ -218,7 +218,7 @@ for(var/obj/item/W in target) if(istype(W,/obj/item/organ)) continue target.unEquip(W) - target.fully_replace_character_name(target.real_name, "Generic Henchman ([rand(1, 1000)])") + 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/weapon/storage/toolbox/mechanical/greytide(target), slot_l_hand) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index ee8ef7efee2..7a325ca2385 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -122,7 +122,7 @@ /mob/living/proc/handle_weakened() if(weakened) - weakened = max(weakened-1,0) //before you get mad Rockdtben: I done this so update_canmove isn't called multiple times + AdjustWeakened(-1) if(!weakened) update_icons() return weakened @@ -147,14 +147,14 @@ slurring = max(slurring-1, 0) return slurring -/mob/living/proc/handle_paralysed() // Currently only used by simple_animal.dm, treated as a special case in other mobs +/mob/living/proc/handle_paralysed() if(paralysis) AdjustParalysis(-1) return paralysis /mob/living/proc/handle_sleeping() if(sleeping) - sleeping = max(sleeping - 1, 0) + AdjustSleeping(-1) return sleeping @@ -231,32 +231,26 @@ if(A.CheckRemoval(src)) A.Remove(src) for(var/obj/item/I in src) - if(istype(I,/obj/item/clothing/under)) - var/obj/item/clothing/under/U = I - for(var/obj/item/IU in U) - if(istype(IU, /obj/item/clothing/accessory)) - var/obj/item/clothing/accessory/A = IU - if(A.action_button_name) - if(!A.action) - if(A.action_button_is_hands_free) - A.action = new/datum/action/item_action/hands_free - else - A.action = new/datum/action/item_action - A.action.name = A.action_button_name - A.action.target = A - A.action.check_flags &= ~AB_CHECK_INSIDE - A.action.Grant(src) - if(I.action_button_name) - if(!I.action) - if(I.action_button_is_hands_free) - I.action = new/datum/action/item_action/hands_free - else - I.action = new/datum/action/item_action - I.action.name = I.action_button_name - I.action.target = I - I.action.Grant(src) + give_action_button(I, 1) return +/mob/living/proc/give_action_button(var/obj/item/I, recursive = 0) + if(I.action_button_name) + if(!I.action) + if(istype(I, /obj/item/organ/internal)) + I.action = new/datum/action/item_action/organ_action + else if(I.action_button_is_hands_free) + I.action = new/datum/action/item_action/hands_free + else + I.action = new/datum/action/item_action + I.action.name = I.action_button_name + I.action.target = I + I.action.Grant(src) + + if(recursive) + for(var/obj/item/T in I) + give_action_button(I, recursive - 1) + /mob/living/update_action_buttons() if(!hud_used) return if(!client) return diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 8f078f18f90..25358ee11b1 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -2,7 +2,7 @@ /mob/living/Destroy() ..() return QDEL_HINT_HARDDEL_NOW - + /mob/living/Stat() . = ..() if(. && get_rig_stats) @@ -22,7 +22,7 @@ //same as above /mob/living/pointed(atom/A as mob|obj|turf in view()) - if(src.stat || !src.canmove || src.restrained()) + if(incapacitated()) return 0 if(src.status_flags & FAKEDEATH) return 0 @@ -34,11 +34,17 @@ /mob/living/verb/succumb() set hidden = 1 if (InCritical()) - src.attack_log += "[src] has ["succumbed to death"] with [round(health, 0.1)] points of health!" - src.adjustOxyLoss(src.health - config.health_threshold_dead) + attack_log += "[src] has ["succumbed to death"] with [round(health, 0.1)] points of health!" + adjustOxyLoss(health - config.health_threshold_dead) updatehealth() + // super check for weird mobs, including ones that adjust hp + // we don't want to go overboard and gib them, though + for(var/i = 1 to 5) + if(health < config.health_threshold_dead) + break + take_overall_damage(max(5, health - config.health_threshold_dead), 0) + updatehealth() src << "You have given up life and succumbed to death." - death() /mob/living/proc/InCritical() return (src.health < 0 && src.health > -95.0 && stat == UNCONSCIOUS) @@ -801,6 +807,8 @@ if(do_mob(src, who, what.strip_delay)) if(what && what == who.get_item_by_slot(where) && Adjacent(who)) who.unEquip(what) + if(silent) + put_in_hands(what) add_logs(who, src, "stripped", addition="of [what]") // The src mob is trying to place an item on someone @@ -932,4 +940,4 @@ //used in datum/reagents/reaction() proc /mob/living/proc/get_permeability_protection() - return 0 + return 0 \ No newline at end of file diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 104eb6048c0..0cfa3657d47 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -51,4 +51,6 @@ var/last_played_vent var/list/datum/action/actions = list() - var/step_count = 0 \ No newline at end of file + var/step_count = 0 + + var/list/surgeries = list() //a list of surgery datums. generally empty, they're added when the player wants them. \ No newline at end of file diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 72035ee078b..daa0f9571fc 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -71,6 +71,8 @@ proc/get_radio_key_from_channel(var/channel) var/list/returns[3] var/speech_problem_flag = 0 + + if((HULK in mutations) && health >= 25 && length(message)) message = "[uppertext(message)]!!!" verb = pick("yells","roars","hollers") @@ -91,6 +93,9 @@ proc/get_radio_key_from_channel(var/channel) else if(COMIC in mutations) message = "[message]" + if(!IsVocal()) + message = "" + speech_problem_flag = 1 returns[1] = message returns[2] = verb diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index c870c742573..8509d59e547 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -71,7 +71,6 @@ var/list/ai_verbs_default = list( var/mob/living/silicon/ai/parent = null - var/apc_override = 0 //hack for letting the AI use its APC even when visionless var/camera_light_on = 0 //Defines if the AI toggled the light on the camera it's looking through. var/datum/trackable/track = null var/last_paper_seen = null @@ -115,7 +114,7 @@ var/list/ai_verbs_default = list( pickedName = null aiPDA = new/obj/item/device/pda/ai(src) - SetName(pickedName) + rename_character(null, pickedName) anchored = 1 canmove = 0 density = 1 @@ -205,19 +204,21 @@ var/list/ai_verbs_default = list( job = "AI" -/mob/living/silicon/ai/SetName(pickedName as text) - ..() +/mob/living/silicon/ai/rename_character(oldname, newname) + if(!..(oldname, newname)) + return 0 - announcement.announcer = name + if(oldname != real_name) + announcement.announcer = name - if(eyeobj) - eyeobj.name = "[pickedName] (AI Eye)" + if(eyeobj) + eyeobj.name = "[newname] (AI Eye)" - // Set ai pda name - if(aiPDA) - aiPDA.ownjob = "AI" - aiPDA.owner = pickedName - aiPDA.name = pickedName + " (" + aiPDA.ownjob + ")" + // Set ai pda name + if(aiPDA) + aiPDA.set_name_and_job(newname, "AI") + + return 1 /mob/living/silicon/ai/Destroy() ai_list -= src @@ -999,3 +1000,11 @@ var/list/ai_verbs_default = list( var/obj/item/weapon/rig/rig = src.get_rig() if(rig) rig.force_rest(src) + +/mob/living/silicon/ai/switch_to_camera(var/obj/machinery/camera/C) + if(!C.can_use() || !is_in_chassis()) + return 0 + + eyeobj.setLoc(get_turf(C)) + client.eye = eyeobj + return 1 \ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index ef0e1f712f8..6162ca31b33 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -139,9 +139,9 @@ if(!src.eyeobj) src << "ERROR: Eyeobj not found. Creating new eye..." - src.eyeobj = new(src.loc) + src.eyeobj = new(loc) src.eyeobj.ai = src - src.SetName(src.name) + src.rename_character(null, real_name) if(client && client.eye) client.eye = src diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index 934cdb393c1..93ee8a54a2b 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -135,10 +135,8 @@ src << "Receiving control information from APC." sleep(2) //bring up APC dialog - apc_override = 1 - theAPC.attack_ai(src) - apc_override = 0 aiRestorePowerRoutine = 3 + theAPC.attack_ai(src) src << "Here are your current laws:" src.show_laws() //WHY THE FUCK IS THIS HERE sleep(50) diff --git a/code/modules/mob/living/silicon/ai/say.dm b/code/modules/mob/living/silicon/ai/say.dm index acf3a2db3c0..5e47030f373 100644 --- a/code/modules/mob/living/silicon/ai/say.dm +++ b/code/modules/mob/living/silicon/ai/say.dm @@ -1,5 +1,3 @@ -/mob/living/silicon/ai/proc/IsVocal() - var/announcing_vox = 0 // Stores the time of the last announcement var/const/VOX_CHANNEL = 200 var/const/VOX_DELAY = 100 @@ -30,7 +28,7 @@ var/const/VOX_PATH = "sound/vox_fem/" /mob/living/silicon/ai/proc/ai_announcement() if(check_unable(AI_CHECK_WIRELESS | AI_CHECK_RADIO)) return - + if(announcing_vox > world.time) src << "Please wait [round((announcing_vox - world.time) / 10)] seconds." return @@ -38,7 +36,7 @@ var/const/VOX_PATH = "sound/vox_fem/" var/message = input(src, "WARNING: Misuse of this verb can result in you being job banned. More help is available in 'Announcement Help'", "Announcement", last_announcement) as text|null last_announcement = message - + if(check_unable(AI_CHECK_WIRELESS | AI_CHECK_RADIO)) return diff --git a/code/modules/mob/living/silicon/emote.dm b/code/modules/mob/living/silicon/emote.dm index f7ead12e4cc..dace3f40060 100644 --- a/code/modules/mob/living/silicon/emote.dm +++ b/code/modules/mob/living/silicon/emote.dm @@ -13,7 +13,7 @@ var/on_CD = 0 switch(act) //Cooldown-inducing emotes - if("ping","buzz","beep") //halt is exempt because it's used to stop criminal scum //WHOEVER THOUGHT THAT WAS A GOOD IDEA IS GOING TO GET SHOT. + if("ping","buzz","beep","yes","no") //halt is exempt because it's used to stop criminal scum //WHOEVER THOUGHT THAT WAS A GOOD IDEA IS GOING TO GET SHOT. on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm //Everything else, including typos of the above emotes else @@ -75,4 +75,38 @@ playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0) m_type = 1 + if("yes") + var/M = null + if(param) + for (var/mob/A in view(null, null)) + if (param == A.name) + M = A + break + if(!M) + param = null + + if (param) + message = "[src] emits an affirmative blip at [param]." + else + message = "[src] emits an affirmative blip." + playsound(src.loc, 'sound/machines/synth_yes.ogg', 50, 0) + m_type = 1 + + if("no") + var/M = null + if(param) + for (var/mob/A in view(null, null)) + if (param == A.name) + M = A + break + if(!M) + param = null + + if (param) + message = "[src] emits a negative blip at [param]." + else + message = "[src] emits a negative blip." + playsound(src.loc, 'sound/machines/synth_no.ogg', 50, 0) + m_type = 1 + ..(act, m_type, message) \ No newline at end of file diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 2fd2ddcab61..420b897626b 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -108,7 +108,8 @@ pda.ownjob = "Personal Assistant" pda.owner = text("[]", src) pda.name = pda.owner + " (" + pda.ownjob + ")" - pda.toff = 1 + var/datum/data/pda/app/messenger/M = pda.find_program(/datum/data/pda/app/messenger) + M.toff = 1 ..() /mob/living/silicon/pai/Login() diff --git a/code/modules/mob/living/silicon/pai/software_modules.dm b/code/modules/mob/living/silicon/pai/software_modules.dm index 11e3abaf7e8..5278300ffb5 100644 --- a/code/modules/mob/living/silicon/pai/software_modules.dm +++ b/code/modules/mob/living/silicon/pai/software_modules.dm @@ -142,15 +142,24 @@ on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) var/data[0] - data["receiver_off"] = user.pda.toff - data["ringer_off"] = user.pda.silent + if(!user.pda) + return + var/datum/data/pda/app/messenger/M = user.pda.find_program(/datum/data/pda/app/messenger) + if(!M) + return + + data["receiver_off"] = M.toff + data["ringer_off"] = M.silent data["current_ref"] = null data["current_name"] = user.current_pda_messaging var/pdas[0] - if(!user.pda.toff) + if(!M.toff) for(var/obj/item/device/pda/P in PDAs) - if(!P.owner || P.toff || P == user.pda || P.hidden) continue + var/datum/data/pda/app/messenger/PM = P.find_program(/datum/data/pda/app/messenger) + + if(P == user.pda || !PM || !PM.can_receive()) + continue var/pda[0] pda["name"] = "[P]" pda["owner"] = "[P.owner]" @@ -163,7 +172,7 @@ var/messages[0] if(user.current_pda_messaging) - for(var/index in user.pda.tnote) + for(var/index in M.tnote) if(index["owner"] != user.current_pda_messaging) continue var/msg[0] @@ -188,11 +197,15 @@ if(!istype(P)) return if(!isnull(P.pda)) + var/datum/data/pda/app/messenger/M = P.pda.find_program(/datum/data/pda/app/messenger) + if(!M) + return + if(href_list["toggler"]) - P.pda.toff = href_list["toggler"] != "1" + M.toff = href_list["toggler"] != "1" return 1 else if(href_list["ringer"]) - P.pda.silent = href_list["ringer"] != "1" + M.silent = href_list["ringer"] != "1" return 1 else if(href_list["select"]) var/s = href_list["select"] @@ -206,7 +219,7 @@ return alert("Communications circuits remain uninitialized.") var/target = locate(href_list["target"]) - P.pda.create_message(P, target, 1) + M.create_message(P, target, 1) return 1 /datum/pai_software/med_records diff --git a/code/modules/mob/living/silicon/robot/component.dm b/code/modules/mob/living/silicon/robot/component.dm index 7eb1e62090c..7666fabff93 100644 --- a/code/modules/mob/living/silicon/robot/component.dm +++ b/code/modules/mob/living/silicon/robot/component.dm @@ -245,7 +245,7 @@ user << "Internal prosthetics:" organ_found = null if(H.internal_organs.len) - for(var/obj/item/organ/O in H.internal_organs) + for(var/obj/item/organ/internal/O in H.internal_organs) if(!(O.status & ORGAN_ROBOT)) continue organ_found = 1 diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm index 005b1194821..c7ba0de8a64 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone.dm @@ -82,18 +82,14 @@ playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0) //Redefining some robot procs... -/mob/living/silicon/robot/drone/SetName(pickedName as text) - // Would prefer to call the grandparent proc but this isn't possible, so.. - real_name = pickedName - name = real_name +/mob/living/silicon/robot/drone/rename_character(oldname, newname) + // force it to not actually change most things + return ..(newname, newname) -//Redefining some robot procs... -/mob/living/silicon/robot/drone/updatename() - real_name = "maintenance drone ([rand(100,999)])" - name = real_name +/mob/living/silicon/robot/drone/get_default_name() + return "maintenance drone ([rand(100,999)])" /mob/living/silicon/robot/drone/update_icons() - overlays.Cut() if(stat == 0) overlays += "eyes-[icon_state]" diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 3f56a1bfc25..34ecf876574 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -101,7 +101,7 @@ var/list/robot_verbs_default = list( robot_modules_background.icon_state = "block" robot_modules_background.layer = 19 //Objects that appear on screen are on layer 20, UI should be just below it. ident = rand(1, 999) - updatename("Default") + rename_character(null, get_default_name()) update_icons() update_headlamp() @@ -159,9 +159,61 @@ var/list/robot_verbs_default = list( playsound(loc, 'sound/voice/liveagain.ogg', 75, 1) -/mob/living/silicon/robot/SetName(pickedName as text) - custom_name = pickedName - updatename() +/mob/living/silicon/robot/rename_character(oldname, newname) + if(!..(oldname, newname)) + return 0 + + if(oldname != real_name) + notify_ai(3, oldname, newname) + custom_name = (newname != get_default_name()) ? newname : null + setup_PDA() + + //We also need to update name of internal camera. + if (camera) + camera.c_tag = newname + + //Check for custom sprite + if(!custom_sprite) + var/file = file2text("config/custom_sprites.txt") + var/lines = text2list(file, "\n") + + for(var/line in lines) + // split & clean up + var/list/Entry = text2list(line, ";") + for(var/i = 1 to Entry.len) + Entry[i] = trim(Entry[i]) + + if(Entry.len < 2) + continue; + + if(Entry[1] == src.ckey && Entry[2] == src.real_name) //They're in the list? Custom sprite time, var and icon change required + custom_sprite = 1 + icon = 'icons/mob/custom-synthetic.dmi' + + return 1 + +/mob/living/silicon/robot/proc/get_default_name(var/prefix as text) + if(prefix) + modtype = prefix + if(mmi) + if(istype(mmi, /obj/item/device/mmi/posibrain)) + braintype = "Android" + else + braintype = "Cyborg" + else + braintype = "Robot" + + if(custom_name) + return custom_name + else + return "[modtype] [braintype]-[num2text(ident)]" + +/mob/living/silicon/robot/verb/Namepick() + set category = "Robot Commands" + if(custom_name) + return 0 + + rename_self(braintype, 1) /mob/living/silicon/robot/proc/sync() if(lawupdate && connected_ai) @@ -172,9 +224,11 @@ var/list/robot_verbs_default = list( /mob/living/silicon/robot/proc/setup_PDA() if (!rbPDA) rbPDA = new/obj/item/device/pda/ai(src) - rbPDA.set_name_and_job(custom_name,braintype) + rbPDA.set_name_and_job(real_name, braintype) if(scrambledcodes) - rbPDA.hidden = 1 + var/datum/data/pda/app/messenger/M = rbPDA.find_program(/datum/data/pda/app/messenger) + if(M) + M.hidden = 1 /mob/living/silicon/robot/binarycheck() if(is_component_functioning("comms")) @@ -298,13 +352,12 @@ var/list/robot_verbs_default = list( icon_state = "droidcombat" if("Peacekeeper") - module= new /obj/item/weapon/robot_module/peacekeeper(src) + module = new /obj/item/weapon/robot_module/peacekeeper(src) icon_state = "droidpeace" module.channels = list() icon_state = "droidpeace" if("Hunter") - updatename(module) module = new /obj/item/weapon/robot_module/alien/hunter(src) hands.icon_state = "standard" icon = "icons/mob/alien.dmi" @@ -324,7 +377,7 @@ var/list/robot_verbs_default = list( hands.icon_state = lowertext(modtype) feedback_inc("cyborg_[lowertext(modtype)]",1) - updatename() + rename_character(real_name, get_default_name()) if(modtype == "Medical" || modtype == "Security" || modtype == "Combat" || modtype == "Peacekeeper") status_flags &= ~CANPUSH @@ -333,64 +386,6 @@ var/list/robot_verbs_default = list( radio.config(module.channels) notify_ai(2) -/mob/living/silicon/robot/proc/updatename(var/prefix as text) - if(prefix) - modtype = prefix - if(mmi) - if(istype(mmi, /obj/item/device/mmi/posibrain)) - braintype = "Android" - else - braintype = "Cyborg" - else - braintype = "Robot" - - var/changed_name = "" - if(custom_name) - changed_name = custom_name - else - changed_name = "[modtype] [braintype]-[num2text(ident)]" - real_name = changed_name - name = real_name - - // if we've changed our name, we also need to update the display name for our PDA - setup_PDA() - - //We also need to update name of internal camera. - if (camera) - camera.c_tag = changed_name - - if(!custom_sprite) //Check for custom sprite - var/file = file2text("config/custom_sprites.txt") - var/lines = text2list(file, "\n") - - for(var/line in lines) - // split & clean up - var/list/Entry = text2list(line, ";") - for(var/i = 1 to Entry.len) - Entry[i] = trim(Entry[i]) - - if(Entry.len < 2) - continue; - - if(Entry[1] == src.ckey && Entry[2] == src.real_name) //They're in the list? Custom sprite time, var and icon change required - custom_sprite = 1 - icon = 'icons/mob/custom-synthetic.dmi' - -/mob/living/silicon/robot/verb/Namepick() - set category = "Robot Commands" - if(custom_name) - return 0 - - spawn(0) - var/newname - newname = sanitize(copytext(input(src,"You are a robot. Enter a name, or leave blank for the default name.", "Name change","") as text,1,MAX_NAME_LEN)) - if (newname != "") - notify_ai(3, name, newname) - custom_name = newname - - updatename() - update_icons() - //for borg hotkeys, here module refers to borg inv slot, not core module /mob/living/silicon/robot/verb/cmd_toggle_module(module as num) set name = "Toggle Module" @@ -1301,7 +1296,37 @@ var/list/robot_verbs_default = list( else src << "Your icon has been set. You now require a module reset to change it." +/mob/living/silicon/robot/proc/notify_ai(var/notifytype, var/oldname, var/newname) + if(!connected_ai) + return + switch(notifytype) + if(1) //New Cyborg + connected_ai << "

    NOTICE - New cyborg connection detected: [name]
    " + if(2) //New Module + connected_ai << "

    NOTICE - Cyborg module change detected: [name] has loaded the [designation] module.
    " + if(3) //New Name + connected_ai << "

    NOTICE - Cyborg reclassification detected: [oldname] is now designated as [newname].
    " + +/mob/living/silicon/robot/proc/disconnect_from_ai() + if(connected_ai) + sync() // One last sync attempt + connected_ai.connected_robots -= src + connected_ai = null + +/mob/living/silicon/robot/proc/connect_to_ai(var/mob/living/silicon/ai/AI) + if(AI && AI != connected_ai) + disconnect_from_ai() + connected_ai = AI + connected_ai.connected_robots |= src + notify_ai(1) + sync() + +/mob/living/silicon/robot/adjustOxyLoss(var/amount) + if (suiciding) + ..() + /mob/living/silicon/robot/deathsquad + base_icon = "nano_bloodhound" icon_state = "nano_bloodhound" lawupdate = 0 scrambledcodes = 1 @@ -1348,10 +1373,10 @@ var/list/robot_verbs_default = list( return /mob/living/silicon/robot/syndicate + base_icon = "syndie_bloodhound" icon_state = "syndie_bloodhound" lawupdate = 0 scrambledcodes = 1 - modtype = "Synd" faction = list("syndicate") designation = "Syndicate Assault" modtype = "Syndicate" @@ -1382,7 +1407,9 @@ var/list/robot_verbs_default = list( playsound(loc, 'sound/mecha/nominalsyndi.ogg', 75, 0) /mob/living/silicon/robot/syndicate/medical + base_icon = "syndi-medi" icon_state = "syndi-medi" + modtype = "Syndicate Medical" designation = "Syndicate Medical" playstyle_string = "You are a Syndicate medical cyborg!
    \ You are armed with powerful medical tools to aid you in your mission: help the operatives secure the nuclear authentication disk. \ @@ -1395,64 +1422,40 @@ var/list/robot_verbs_default = list( ..() module = new /obj/item/weapon/robot_module/syndicate_medical(src) -/mob/living/silicon/robot/proc/notify_ai(var/notifytype, var/oldname, var/newname) - if(!connected_ai) - return - switch(notifytype) - if(1) //New Cyborg - connected_ai << "

    NOTICE - New cyborg connection detected: [name]
    " - if(2) //New Module - connected_ai << "

    NOTICE - Cyborg module change detected: [name] has loaded the [designation] module.
    " - if(3) //New Name - connected_ai << "

    NOTICE - Cyborg reclassification detected: [oldname] is now designated as [newname].
    " - -/mob/living/silicon/robot/proc/disconnect_from_ai() - if(connected_ai) - sync() // One last sync attempt - connected_ai.connected_robots -= src - connected_ai = null - -/mob/living/silicon/robot/proc/connect_to_ai(var/mob/living/silicon/ai/AI) - if(AI && AI != connected_ai) - disconnect_from_ai() - connected_ai = AI - connected_ai.connected_robots |= src - notify_ai(1) - sync() - - -/mob/living/silicon/robot/combat/New() - ..() - module = new /obj/item/weapon/robot_module/combat(src) - module.channels = list("Security" = 1) +/mob/living/silicon/robot/combat base_icon = "droidcombat" icon_state = "droidcombat" modtype = "Combat" + designation = "Combat" + +/mob/living/silicon/robot/combat/init() + ..() + module = new /obj/item/weapon/robot_module/combat(src) + module.channels = list("Security" = 1) //languages module.add_languages(src) //subsystems module.add_subsystems(src) - updatename() - status_flags &= ~CANPUSH radio.config(module.channels) notify_ai(2) -/mob/living/silicon/robot/peacekeeper/New() - ..() - module = new /obj/item/weapon/robot_module/peacekeeper(src) +/mob/living/silicon/robot/peacekeeper base_icon = "droidpeace" icon_state = "droidpeace" modtype = "Peacekeeper" + designation = "Peacekeeper" + +/mob/living/silicon/robot/peacekeeper/init() + ..() + module = new /obj/item/weapon/robot_module/peacekeeper(src) //languages module.add_languages(src) //subsystems module.add_subsystems(src) - updatename() - status_flags &= ~CANPUSH notify_ai(2) \ No newline at end of file diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index f1f5f7862b3..56e1c08f646 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -50,9 +50,14 @@ AH.unregister(src) return ..() -/mob/living/silicon/proc/SetName(pickedName as text) - real_name = pickedName +/mob/living/silicon/rename_character(oldname, newname) + // we actually don't want it changing minds and stuff + if(!newname) + return 0 + + real_name = newname name = real_name + return 1 /mob/living/silicon/proc/show_laws() return @@ -105,11 +110,11 @@ if(!effect || (blocked >= 2)) return 0 switch(effecttype) if(STUN) - stunned = max(stunned,(effect/(blocked+1))) + Stun(effect / (blocked + 1)) if(WEAKEN) - weakened = max(weakened,(effect/(blocked+1))) + Weaken(effect / (blocked + 1)) if(PARALYZE) - paralysis = max(paralysis,(effect/(blocked+1))) + Paralyse(effect / (blocked + 1)) if(IRRADIATE) radiation += min((effect - (effect*getarmor(null, "rad"))), 0)//Rads auto check armor if(STUTTER) @@ -340,3 +345,8 @@ for(var/obj/machinery/camera/C in A.cameras()) cameratext += "[(cameratext == "")? "" : "|"][C.c_tag]" src << "[A.alarm_name()]! ([(cameratext)? cameratext : "No Camera"])" + +/mob/living/silicon/adjustToxLoss(var/amount) + return + + diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index 21f88b5913b..da3283355f3 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -78,21 +78,6 @@ var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) adjustBruteLoss(damage) -/mob/living/simple_animal/construct/attackby(var/obj/item/O as obj, var/mob/user as mob, params) - if(O.force) - var/damage = O.force - if (O.damtype == STAMINA) - damage = 0 - adjustBruteLoss(damage) - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red \b [src] has been attacked with [O] by [user]. ") - else - usr << "\red This weapon is ineffective, it does no damage." - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red [user] gently taps [src] with [O]. ") - /mob/living/simple_animal/construct/narsie_act() return @@ -120,26 +105,7 @@ attack_sound = 'sound/weapons/punch3.ogg' status_flags = 0 construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/lesserforcewall) - -/mob/living/simple_animal/construct/armoured/attackby(var/obj/item/O as obj, var/mob/user as mob, params) - if(O.force) - if(O.force >= 11) - var/damage = O.force - if (O.damtype == STAMINA) - damage = 0 - adjustBruteLoss(damage) - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red \b [src] has been attacked with [O] by [user]. ") - else - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red \b [O] bounces harmlessly off of [src]. ") - else - usr << "\red This weapon is ineffective, it does no damage." - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red [user] gently taps [src] with [O]. ") + force_threshold = 11 /mob/living/simple_animal/construct/armoured/Life() @@ -245,30 +211,10 @@ speed = 5 environment_smash = 2 attack_sound = 'sound/weapons/punch4.ogg' + force_threshold = 11 var/energy = 0 var/max_energy = 1000 -/mob/living/simple_animal/construct/behemoth/attackby(var/obj/item/O as obj, var/mob/user as mob, params) - if(O.force) - if(O.force >= 11) - var/damage = O.force - if (O.damtype == STAMINA) - damage = 0 - adjustBruteLoss(damage) - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red \b [src] has been attacked with [O] by [user]. ") - else - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red \b [O] bounces harmlessly off of [src]. ") - else - usr << "\red This weapon is ineffective, it does no damage." - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red [user] gently taps [src] with [O]. ") - - /////////////////////////////Harvester///////////////////////// diff --git a/code/modules/mob/living/simple_animal/friendly/butterfly.dm b/code/modules/mob/living/simple_animal/friendly/butterfly.dm index 88c8980a75e..a6c5effdde3 100644 --- a/code/modules/mob/living/simple_animal/friendly/butterfly.dm +++ b/code/modules/mob/living/simple_animal/friendly/butterfly.dm @@ -17,6 +17,8 @@ density = 0 pass_flags = PASSTABLE | PASSGRILLE | PASSMOB ventcrawler = 2 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + meat_amount = 0 /mob/living/simple_animal/butterfly/New() ..() diff --git a/code/modules/mob/living/simple_animal/friendly/lizard.dm b/code/modules/mob/living/simple_animal/friendly/lizard.dm index a805d06a1e4..c2118b19bc1 100644 --- a/code/modules/mob/living/simple_animal/friendly/lizard.dm +++ b/code/modules/mob/living/simple_animal/friendly/lizard.dm @@ -20,3 +20,5 @@ density = 0 pass_flags = PASSTABLE | PASSMOB can_hide = 1 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + meat_amount = 1 diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm index 7b8b7617431..ab26322d958 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm @@ -268,24 +268,38 @@ /mob/living/simple_animal/hostile/asteroid/hivelord/death() if(stat != DEAD) - new /obj/item/asteroid/hivelord_core(src.loc) + new /obj/item/organ/internal/hivelord_core(src.loc) ..() -/obj/item/asteroid/hivelord_core +/obj/item/organ/internal/hivelord_core name = "hivelord remains" desc = "All that remains of a hivelord, it seems to be what allows it to break pieces of itself off without being hurt... its healing properties will soon become inert if not used quickly. Try not to think about what you're eating." icon = 'icons/obj/food/food.dmi' icon_state = "boiledrorocore" + slot = "hivecore" var/inert = 0 var/preserved = 0 -/obj/item/asteroid/hivelord_core/New() +/obj/item/organ/internal/hivelord_core/New() spawn(2400) if(!preserved) inert = 1 desc = "The remains of a hivelord that have become useless, having been left alone too long after being harvested." -/obj/item/asteroid/hivelord_core/attack(mob/living/M as mob, mob/living/user as mob) +/obj/item/organ/internal/hivelord_core/on_life() + ..() + if(owner) + owner.adjustBruteLoss(-1) + owner.adjustFireLoss(-1) + owner.adjustOxyLoss(-2) + if(ishuman(owner)) + var/mob/living/carbon/human/H = owner + var/datum/reagent/blood/B = locate() in H.vessel.reagent_list //Grab some blood + var/blood_volume = round(H.vessel.get_reagent_amount("blood")) + if(B && blood_volume < H.max_blood && blood_volume) + B.volume += 2 // Fast blood regen + +/obj/item/organ/internal/hivelord_core/attack(mob/living/M as mob, mob/living/user as mob) if(ishuman(M)) var/mob/living/carbon/human/H = M if(inert) @@ -304,6 +318,9 @@ qdel(src) ..() +/obj/item/organ/internal/hivelord_core/prepare_eat() + return null + /mob/living/simple_animal/hostile/asteroid/hivelordbrood name = "hivelord brood" desc = "A fragment of the original Hivelord, rallying behind its original. One isn't much of a threat, but..." diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/fish.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/fish.dm new file mode 100644 index 00000000000..65964739a32 --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/fish.dm @@ -0,0 +1,31 @@ + +/mob/living/simple_animal/hostile/retaliate/carp + name = "sea carp" + desc = "A large fish bearing similarities to a certain space-faring menace." + icon_state = "carp" + icon_living = "carp" + icon_dead = "carp_dead" + icon_gib = "carp_gib" + speak_chance = 0 + turns_per_move = 5 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat + meat_amount = 1 + response_help = "pets the" + response_disarm = "gently pushes aside the" + response_harm = "hits the" + speed = 0 + maxHealth = 25 + health = 25 + + retreat_distance = 6 + vision_range = 5 + + harm_intent_damage = 8 + melee_damage_lower = 15 + melee_damage_upper = 15 + attacktext = "bites" + attack_sound = 'sound/weapons/bite.ogg' + speak_emote = list("gnashes") + + faction = list("carp") + flying = 1 \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 61a94e883c3..e884fe41648 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -170,58 +170,48 @@ /mob/living/simple_animal/handle_environment(datum/gas_mixture/environment) var/atmos_suitable = 1 - var/atom/A = src.loc - if(isturf(A)) - var/turf/T = A - var/areatemp = get_temperature(environment) + var/areatemp = get_temperature(environment) - if( abs(areatemp - bodytemperature) > 40 && !(flags & NO_BREATHE)) - var/diff = areatemp - bodytemperature - diff = diff / 5 - bodytemperature += diff + if(abs(areatemp - bodytemperature) > 40 && !(flags & NO_BREATHE)) + var/diff = areatemp - bodytemperature + diff = diff / 5 + bodytemperature += diff + + var/tox = environment.toxins + var/oxy = environment.oxygen + var/n2 = environment.nitrogen + var/co2 = environment.carbon_dioxide - if(istype(T, /turf/simulated)) - var/turf/simulated/ST = T - if(ST.air) - var/tox = ST.air.toxins - var/oxy = ST.air.oxygen - var/n2 = ST.air.nitrogen - var/co2 = ST.air.carbon_dioxide + if(min_oxy && oxy < min_oxy) + atmos_suitable = 0 + oxygen_alert = 1 + else if(max_oxy && oxy > max_oxy) + atmos_suitable = 0 + oxygen_alert = 1 + else + oxygen_alert = 0 - if(min_oxy && oxy < min_oxy) - atmos_suitable = 0 - oxygen_alert = 1 - else if(max_oxy && oxy > max_oxy) - atmos_suitable = 0 - oxygen_alert = 1 - else - oxygen_alert = 0 + if(min_tox && tox < min_tox) + atmos_suitable = 0 + toxins_alert = 1 + else if(max_tox && tox > max_tox) + atmos_suitable = 0 + toxins_alert = 1 + else + toxins_alert = 0 - if(min_tox && tox < min_tox) - atmos_suitable = 0 - toxins_alert = 1 - else if(max_tox && tox > max_tox) - atmos_suitable = 0 - toxins_alert = 1 - else - toxins_alert = 0 + if(min_n2 && n2 < min_n2) + atmos_suitable = 0 + else if(max_n2 && n2 > max_n2) + atmos_suitable = 0 - if(min_n2 && n2 < min_n2) - atmos_suitable = 0 - else if(max_n2 && n2 > max_n2) - atmos_suitable = 0 + if(min_co2 && co2 < min_co2) + atmos_suitable = 0 + else if(max_co2 && co2 > max_co2) + atmos_suitable = 0 - if(min_co2 && co2 < min_co2) - atmos_suitable = 0 - else if(max_co2 && co2 > max_co2) - atmos_suitable = 0 - - if(!atmos_suitable) - adjustBruteLoss(unsuitable_atmos_damage) - - else - if(min_oxy || min_tox || min_n2 || min_co2) - adjustBruteLoss(unsuitable_atmos_damage) + if(!atmos_suitable) + adjustBruteLoss(unsuitable_atmos_damage) handle_temperature_damage() @@ -417,22 +407,23 @@ else user.changeNext_move(CLICK_CD_MELEE) user.do_attack_animation(src) - var/damage = 0 - if(O.force) - if(O.force >= force_threshold) - damage = O.force - if (O.damtype == STAMINA) - damage = 0 - visible_message("[user] has [O.attack_verb.len ? "[pick(O.attack_verb)]": "attacked"] [src] with [O]!",\ - "[user] has [O.attack_verb.len ? "[pick(O.attack_verb)]": "attacked"] you with [O]!") + if(istype(O) && istype(user) && !O.attack(src, user)) + var/damage = 0 + if(O.force) + if(O.force >= force_threshold) + damage = O.force + if (O.damtype == STAMINA) + damage = 0 + visible_message("[user] has [O.attack_verb.len ? "[pick(O.attack_verb)]": "attacked"] [src] with [O]!",\ + "[user] has [O.attack_verb.len ? "[pick(O.attack_verb)]": "attacked"] you with [O]!") + else + visible_message("[O] bounces harmlessly off of [src].",\ + "[O] bounces harmlessly off of [src].") + playsound(loc, O.hitsound, 50, 1, -1) else - visible_message("[O] bounces harmlessly off of [src].",\ - "[O] bounces harmlessly off of [src].") - playsound(loc, O.hitsound, 50, 1, -1) - else - user.visible_message("[user] gently taps [src] with [O].",\ - "This weapon is ineffective, it does no damage.") - adjustBruteLoss(damage) + user.visible_message("[user] gently taps [src] with [O].",\ + "This weapon is ineffective, it does no damage.") + adjustBruteLoss(damage) /mob/living/simple_animal/movement_delay() diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index ce0dfc31efe..54fc8aac90d 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -34,6 +34,8 @@ if(hud_used) qdel(hud_used) //remove the hud objects hud_used = null + if(client.click_intercept) + client.click_intercept.quit() // Let's not keep any old click_intercepts hud_used = new /datum/hud(src) next_move = 1 diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index e1b2ce1477d..0029c97258e 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -625,7 +625,7 @@ var/list/slot_equipment_priority = list( \ set category = "IC" msg = copytext(msg, 1, MAX_MESSAGE_LEN) - msg = sanitize(msg) + msg = sanitize_simple(html_encode(msg), list("\n" = "
    ")) if(mind) mind.store_memory(msg) @@ -1121,94 +1121,72 @@ var/list/slot_equipment_priority = list( \ /mob/proc/Jitter(amount) - jitteriness = max(jitteriness,amount,0) + jitteriness = max(jitteriness, amount, 0) /mob/proc/Dizzy(amount) - dizziness = max(dizziness,amount,0) + dizziness = max(dizziness, amount, 0) /mob/proc/Stun(amount) - if(status_flags & CANSTUN) - stunned = max(max(stunned,amount),0) //can't go below 0, getting a low amount of stun doesn't lower your current stun - update_canmove() - return + SetStunned(max(stunned, amount)) /mob/proc/SetStunned(amount) //if you REALLY need to set stun to a set amount without the whole "can't go below current stunned" if(status_flags & CANSTUN) - stunned = max(amount,0) + stunned = max(amount, 0) + update_canmove() + else if(stunned) + stunned = 0 update_canmove() - return /mob/proc/AdjustStunned(amount) - if(status_flags & CANSTUN) - stunned = max(stunned + amount,0) - update_canmove() - return + SetStunned(stunned + amount) /mob/proc/Weaken(amount) - if(status_flags & CANWEAKEN) - weakened = max(max(weakened,amount),0) - update_canmove() //updates lying, canmove and icons - return + SetWeakened(max(weakened, amount)) /mob/proc/SetWeakened(amount) if(status_flags & CANWEAKEN) - weakened = max(amount,0) + weakened = max(amount, 0) update_canmove() //updates lying, canmove and icons - return + else if(weakened) + weakened = 0 + update_canmove() /mob/proc/AdjustWeakened(amount) - if(status_flags & CANWEAKEN) - weakened = max(weakened + amount,0) - update_canmove() //updates lying, canmove and icons - return + SetWeakened(weakened + amount) /mob/proc/Paralyse(amount) - if(status_flags & CANPARALYSE) - paralysis = max(max(paralysis,amount),0) - update_canmove() - return + SetParalysis(max(paralysis, amount)) /mob/proc/SetParalysis(amount) if(status_flags & CANPARALYSE) - paralysis = max(amount,0) + paralysis = max(amount, 0) + update_canmove() + else if(paralysis) + paralysis = 0 update_canmove() - return /mob/proc/AdjustParalysis(amount) - if(status_flags & CANPARALYSE) - paralysis = max(paralysis + amount,0) - update_canmove() - return + SetParalysis(paralysis + amount) /mob/proc/Sleeping(amount) - sleeping = max(max(sleeping,amount),0) - update_canmove() - return + SetSleeping(max(sleeping, amount)) /mob/proc/SetSleeping(amount) - sleeping = max(amount,0) + sleeping = max(amount, 0) update_canmove() - return /mob/proc/AdjustSleeping(amount) - sleeping = max(sleeping + amount,0) - update_canmove() - return + SetSleeping(sleeping + amount) /mob/proc/Resting(amount) - resting = max(max(resting,amount),0) - update_canmove() - return + SetResting(max(resting, amount)) /mob/proc/SetResting(amount) - resting = max(amount,0) + resting = max(amount, 0) update_canmove() - return /mob/proc/AdjustResting(amount) - resting = max(resting + amount,0) - update_canmove() - return + SetResting(resting + amount) /mob/proc/get_species() return "" @@ -1470,4 +1448,7 @@ mob/proc/yank_out_object() //Can this mob leave its location without breaking things terrifically? /mob/proc/can_safely_leave_loc() - return 1 // Yes, you can \ No newline at end of file + return 1 // Yes, you can + +/mob/proc/IsVocal() + return 1 \ No newline at end of file diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 0a61d9030c1..4f7327180c6 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -199,8 +199,6 @@ mouse_drag_pointer = MOUSE_ACTIVE_POINTER - var/update_icon = 1 //Set to 1 to trigger update_icons() at the next life() call - var/status_flags = CANSTUN|CANWEAKEN|CANPARALYSE|CANPUSH //bitflags defining which status effects can be inflicted (replaces canweaken, canstun, etc) var/area/lastarea = null @@ -241,3 +239,5 @@ var/resize = 1 //Badminnery resize var/datum/vision_override/vision_type = null //Vision override datum. + + var/list/permanent_huds = list() diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index f21299d8978..79fc66d2408 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -360,7 +360,7 @@ assailant.attack_log += text("\[[time_stamp()]\] Pressed fingers into the eyes of [affecting.name] ([affecting.ckey])") affecting.attack_log += text("\[[time_stamp()]\] Had fingers pressed into their eyes by [assailant.name] ([assailant.ckey])") msg_admin_attack("[key_name(assailant)] has pressed his fingers into [key_name(affecting)]'s eyes.") - var/obj/item/organ/eyes/eyes = affected.internal_organs_by_name["eyes"] + var/obj/item/organ/internal/eyes/eyes = affected.get_int_organ(/obj/item/organ/internal/eyes) eyes.damage += rand(3,4) if (eyes.damage >= eyes.min_broken_damage) if(M.stat != 2) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 5b432ddfd56..49a52de9113 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -38,7 +38,7 @@ proc/isfacehugger(A) return 0 proc/isembryo(A) - if(istype(A, /obj/item/alien_embryo)) + if(istype(A, /obj/item/organ/internal/body_egg/alien_embryo)) return 1 return 0 @@ -167,7 +167,7 @@ proc/isovermind(A) return 1 return 0 -proc/isorgan(A) +/proc/isorgan(A) if(istype(A, /obj/item/organ/external)) return 1 return 0 @@ -557,10 +557,81 @@ var/list/intents = list(I_HELP,I_DISARM,I_GRAB,I_HARM) check_eye(src) return 1 -/mob/living/silicon/ai/switch_to_camera(var/obj/machinery/camera/C) - if(!C.can_use() || !is_in_chassis()) +/mob/proc/rename_character(oldname, newname) + if(!newname) return 0 + real_name = newname + name = newname + if(mind) + mind.name = newname + if(dna) + dna.real_name = real_name - eyeobj.setLoc(get_turf(C)) - client.eye = eyeobj + if(oldname) + //update the datacore records! This is goig to be a bit costly. + for(var/list/L in list(data_core.general,data_core.medical,data_core.security,data_core.locked)) + for(var/datum/data/record/R in L) + if(R.fields["name"] == oldname) + R.fields["name"] = newname + break + + //update our pda and id if we have them on our person + var/list/searching = GetAllContents(searchDepth = 3) + var/search_id = 1 + var/search_pda = 1 + + for(var/A in searching) + if( search_id && istype(A,/obj/item/weapon/card/id) ) + var/obj/item/weapon/card/id/ID = A + if(ID.registered_name == oldname) + ID.registered_name = newname + ID.name = "[newname]'s ID Card ([ID.assignment])" + if(!search_pda) break + search_id = 0 + + else if( search_pda && istype(A,/obj/item/device/pda) ) + var/obj/item/device/pda/PDA = A + if(PDA.owner == oldname) + PDA.owner = newname + PDA.name = "PDA-[newname] ([PDA.ownjob])" + if(!search_id) break + search_pda = 0 + + //Fixes renames not being reflected in objective text + var/list/O = subtypesof(/datum/objective) + var/length + var/pos + for(var/datum/objective/objective in O) + if(objective.target != mind) continue + length = lentext(oldname) + pos = findtextEx(objective.explanation_text, oldname) + objective.explanation_text = copytext(objective.explanation_text, 1, pos)+newname+copytext(objective.explanation_text, pos+length) return 1 + +/mob/proc/rename_self(var/role, var/allow_numbers=0) + spawn(0) + var/oldname = real_name + + var/time_passed = world.time + var/newname + + for(var/i=1,i<=3,i++) //we get 3 attempts to pick a suitable name. + newname = input(src,"You are a [role]. Would you like to change your name to something else?", "Name change",oldname) as text + if((world.time-time_passed)>300) + return //took too long + newname = reject_bad_name(newname,allow_numbers) //returns null if the name doesn't meet some basic requirements. Tidies up a few other things like bad-characters. + + for(var/mob/living/M in player_list) + if(M == src) + continue + if(!newname || M.real_name == newname) + newname = null + break + if(newname) + break //That's a suitable name! + src << "Sorry, that [role]-name wasn't appropriate, please try another. It's possibly too long/short, has bad characters or is already taken." + + if(!newname) //we'll stick with the oldname then + return + + rename_character(oldname, newname) \ No newline at end of file diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 96876651d31..f77e2ff7ed5 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -477,7 +477,7 @@ domutcheck(new_character) new_character.dna.UpdateSE() - new_character.sync_organ_dna() //just fucking incase I guess + new_character.sync_organ_dna(1) //just fucking incase I guess // Do the initial caching of the player's body icons. new_character.force_update_limbs() diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm index ec388c0faff..72d35aef201 100644 --- a/code/modules/mob/new_player/sprite_accessories.dm +++ b/code/modules/mob/new_player/sprite_accessories.dm @@ -631,6 +631,11 @@ species_allowed = list("Skrell") gender = FEMALE + taj_ears + name = "Tajaran Ears" + icon_state = "ears_plain" + species_allowed = list("Tajaran") + taj_ears_clean name = "Tajara Clean" icon_state = "hair_clean" diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index f31b76639ed..26e2497ac0c 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -64,7 +64,7 @@ O.add_ai_verbs() - O.rename_self("ai",1) + O.rename_self("AI",1) spawn qdel(src) return O diff --git a/code/modules/nano/interaction/default.dm b/code/modules/nano/interaction/default.dm index bd5ba3ee0c8..e0e7c3a98f6 100644 --- a/code/modules/nano/interaction/default.dm +++ b/code/modules/nano/interaction/default.dm @@ -32,6 +32,9 @@ /mob/living/silicon/ai/default_can_use_topic(var/src_object) . = shared_nano_interaction() + // Fix the weird hacking blurb to actually let them restore power + if(aiRestorePowerRoutine == 3 && istype(src_object, /obj/machinery/power/apc)) + return STATUS_INTERACTIVE if(. != STATUS_INTERACTIVE) return diff --git a/code/modules/ninja/suit/SpiderOS.dm b/code/modules/ninja/suit/SpiderOS.dm index de7cc2e179c..11a595e6645 100644 --- a/code/modules/ninja/suit/SpiderOS.dm +++ b/code/modules/ninja/suit/SpiderOS.dm @@ -231,8 +231,8 @@ if(L) L << "\icon[P] Message from unknown source: \"[t]\" (Unable to Reply)" P.play_ringtone() - P.overlays.Cut() - P.overlays += image('icons/obj/pda.dmi', "pda-r") + var/datum/data/pda/app/messenger/M = P.find_program(/datum/data/pda/app/messenger) + M.set_new(1) if("Inject") if( (href_list["tag"]=="radium"? (reagents.get_reagent_amount("radium"))<=(a_boost*a_transfer) : !reagents.get_reagent_amount(href_list["tag"])) )//Special case for radium. If there are only a_boost*a_transfer radium units left. diff --git a/code/modules/organs/organ_internal.dm b/code/modules/organs/organ_internal.dm deleted file mode 100644 index 46d7f01b0d9..00000000000 --- a/code/modules/organs/organ_internal.dm +++ /dev/null @@ -1,171 +0,0 @@ -#define PROCESS_ACCURACY 10 - -/**************************************************** - INTERNAL ORGANS DEFINES -****************************************************/ - - -// Brain is defined in brain_item.dm. -/obj/item/organ/heart - name = "heart" - icon_state = "heart-on" - organ_tag = "heart" - parent_organ = "chest" - dead_icon = "heart-off" - vital = 1 - -/obj/item/organ/lungs - name = "lungs" - icon_state = "lungs" - gender = PLURAL - organ_tag = "lungs" - parent_organ = "chest" - -/obj/item/organ/lungs/process() - ..() - - if(!owner) - return - - if (germ_level > INFECTION_LEVEL_ONE) - if(prob(5)) - owner.emote("cough") //respitory tract infection - - if(is_bruised()) - if(prob(2)) - spawn owner.custom_emote(1, "coughs up blood!") - owner.drip(10) - if(prob(4)) - spawn owner.custom_emote(1, "gasps for air!") - owner.losebreath += 5 - -/obj/item/organ/kidneys - name = "kidneys" - icon_state = "kidneys" - gender = PLURAL - organ_tag = "kidneys" - parent_organ = "groin" - -/obj/item/organ/kidneys/process() - - ..() - - if(!owner) - return - - // Coffee is really bad for you with busted kidneys. - // This should probably be expanded in some way, but fucked if I know - // what else kidneys can process in our reagent list. - var/datum/reagent/coffee = locate(/datum/reagent/drink/coffee) in owner.reagents.reagent_list - if(coffee) - if(is_bruised()) - owner.adjustToxLoss(0.1 * PROCESS_ACCURACY) - else if(is_broken()) - owner.adjustToxLoss(0.3 * PROCESS_ACCURACY) - - -/obj/item/organ/eyes - name = "eyeballs" - icon_state = "eyes" - gender = PLURAL - organ_tag = "eyes" - parent_organ = "head" - var/list/eye_colour = list(0,0,0) - -/obj/item/organ/eyes/proc/update_colour() - if(!owner) - return - eye_colour = list( - owner.r_eyes ? owner.r_eyes : 0, - owner.g_eyes ? owner.g_eyes : 0, - owner.b_eyes ? owner.b_eyes : 0 - ) - -/obj/item/organ/eyes/surgeryize() - if(!owner) - return - owner.disabilities &= ~NEARSIGHTED - owner.sdisabilities &= ~BLIND - owner.eye_blurry = 0 - owner.eye_blind = 0 - -/obj/item/organ/liver - name = "liver" - icon_state = "liver" - organ_tag = "liver" - parent_organ = "groin" - -/obj/item/organ/liver/process() - - ..() - - if(!owner) - return - - if (germ_level > INFECTION_LEVEL_ONE) - if(prob(1)) - owner << "\red Your skin itches." - if (germ_level > INFECTION_LEVEL_TWO) - if(prob(1)) - spawn owner.vomit() - - if(owner.life_tick % PROCESS_ACCURACY == 0) - - //High toxins levels are dangerous - if(owner.getToxLoss() >= 60 && !owner.reagents.has_reagent("charcoal")) - //Healthy liver suffers on its own - if (src.damage < min_broken_damage) - src.damage += 0.2 * PROCESS_ACCURACY - //Damaged one shares the fun - else - var/obj/item/organ/O = pick(owner.internal_organs) - if(O) - O.damage += 0.2 * PROCESS_ACCURACY - - //Detox can heal small amounts of damage - if (src.damage && src.damage < src.min_bruised_damage && owner.reagents.has_reagent("charcoal")) - src.damage -= 0.2 * PROCESS_ACCURACY - - if(src.damage < 0) - src.damage = 0 - - // Get the effectiveness of the liver. - var/filter_effect = 3 - if(is_bruised()) - filter_effect -= 1 - if(is_broken()) - filter_effect -= 2 - - // Damaged liver means some chemicals are very dangerous - if(src.damage >= src.min_bruised_damage) - for(var/datum/reagent/R in owner.reagents.reagent_list) - // Ethanol and all drinks are bad - if(istype(R, /datum/reagent/ethanol)) - owner.adjustToxLoss(0.1 * PROCESS_ACCURACY) - - // Can't cope with toxins at all - for(var/toxin in list("toxin", "plasma", "sacid", "facid", "cyanide", "amanitin", "carpotoxin")) - if(owner.reagents.has_reagent(toxin)) - owner.adjustToxLoss(0.3 * PROCESS_ACCURACY) - -/obj/item/organ/appendix - name = "appendix" - icon_state = "appendix" - organ_tag = "appendix" - parent_organ = "groin" - - -/* -/obj/item/organ/appendix/removed() - - if(owner) - var/inflamed = 0 - for(var/datum/disease/appendicitis/appendicitis in owner.viruses) - inflamed = 1 - appendicitis.cure() - owner.resistances += appendicitis - if(inflamed) - icon_state = "appendixinflamed" - name = "inflamed appendix" - ..() -*/ \ No newline at end of file diff --git a/code/modules/organs/subtypes/xenos.dm b/code/modules/organs/subtypes/xenos.dm deleted file mode 100644 index 7052237b163..00000000000 --- a/code/modules/organs/subtypes/xenos.dm +++ /dev/null @@ -1,66 +0,0 @@ -//XENOMORPH ORGANS -/obj/item/organ/xenos/eggsac - name = "egg sac" - parent_organ = "groin" - -/obj/item/organ/xenos/plasmavessel - name = "plasma vessel" - parent_organ = "chest" - var/stored_plasma = 0 - var/max_plasma = 500 - -/obj/item/organ/xenos/plasmavessel/queen - name = "bloated plasma vessel" - stored_plasma = 200 - max_plasma = 500 - -/obj/item/organ/xenos/plasmavessel/sentinel - stored_plasma = 100 - max_plasma = 250 - -/obj/item/organ/xenos/plasmavessel/hunter - name = "tiny plasma vessel" - stored_plasma = 100 - max_plasma = 150 - -/obj/item/organ/xenos/acidgland - name = "acid gland" - parent_organ = "head" - -/obj/item/organ/xenos/hivenode - name = "hive node" - parent_organ = "chest" - -/obj/item/organ/xenos/resinspinner - name = "resin spinner" - parent_organ = "head" - -/obj/item/organ/xenos - name = "xeno organ" - icon = 'icons/effects/blood.dmi' - desc = "It smells like an accident in a chemical factory." - -/obj/item/organ/xenos/eggsac - name = "egg sac" - icon_state = "xgibmid1" - organ_tag = "egg sac" - -/obj/item/organ/xenos/plasmavessel - name = "plasma vessel" - icon_state = "xgibdown1" - organ_tag = "plasma vessel" - -/obj/item/organ/xenos/acidgland - name = "acid gland" - icon_state = "xgibtorso" - organ_tag = "acid gland" - -/obj/item/organ/xenos/hivenode - name = "hive node" - icon_state = "xgibmid2" - organ_tag = "hive node" - -/obj/item/organ/xenos/resinspinner - name = "hive node" - icon_state = "xgibmid2" - organ_tag = "resin spinner" \ No newline at end of file diff --git a/code/modules/paperwork/frames.dm b/code/modules/paperwork/frames.dm new file mode 100644 index 00000000000..ec014d6a845 --- /dev/null +++ b/code/modules/paperwork/frames.dm @@ -0,0 +1,315 @@ +/obj/item/weapon/picture_frame + name = "picture frame" + desc = "Its patented design allows it to be folded larger or smaller to accommodate standard paper, photo, and poster, and canvas sizes." + icon = 'icons/obj/bureaucracy.dmi' + + var/icon_base + var/obj/displayed + + var/list/wide_posters = list( + "poster22_legit", "poster23", "poster23_legit", "poster24", "poster24_legit", + "poster25", "poster27_legit", "poster28", "poster29") + +/obj/item/weapon/picture_frame/New(loc, obj/item/weapon/D) + ..() + if(D) + insert(D) + update_icon() + +/obj/item/weapon/picture_frame/Destroy() + if(displayed) + displayed = null + for(var/A in contents) + qdel(A) + return ..() + +/obj/item/weapon/picture_frame/update_icon() + overlays.Cut() + + if(displayed) + overlays |= getFlatIcon(displayed) + + if(istype(displayed, /obj/item/weapon/photo)) + icon_state = "[icon_base]-photo" + else if(istype(displayed, /obj/structure/sign/poster)) + icon_state = "[icon_base]-[(displayed.icon_state in wide_posters) ? "wposter" : "poster"]" + else if(istype(displayed, /obj/item/weapon/canvas)) + icon_state = "[icon_base]-canvas-[displayed.icon_state]" + else + icon_state = "[icon_base]-paper" + + overlays |= icon_state + +/obj/item/weapon/picture_frame/proc/insert(obj/D) + if(istype(D, /obj/item/weapon/contraband/poster)) + var/obj/item/weapon/contraband/poster/P = D + displayed = P.resulting_poster + P.resulting_poster = null + else + displayed = D + + name = displayed.name + displayed.pixel_x = 0 + displayed.pixel_y = 0 + displayed.forceMove(src) + if(istype(D, /obj/item/weapon/contraband/poster)) + qdel(D) + +/obj/item/weapon/picture_frame/attackby(obj/item/I, mob/user) + if(istype(I, /obj/item/weapon/screwdriver)) + if(displayed) + playsound(src, 'sound/items/Screwdriver.ogg', 100, 1) + user.visible_message("[user] unfastens \the [displayed] out of \the [src].", "You unfasten \the [displayed] out of \the [src].") + + if(istype(displayed, /obj/structure/sign/poster)) + var/obj/structure/sign/poster/P = displayed + P.roll_and_drop(user.loc) + else + displayed.forceMove(user.loc) + displayed = null + name = initial(name) + update_icon() + else + user << "There is nothing to remove from \the [src]." + else if(istype(I, /obj/item/weapon/crowbar)) + playsound(src, 'sound/items/Crowbar.ogg', 100, 1) + user.visible_message("[user] breaks down \the [src].", "You break down \the [src].") + for(var/A in contents) + if(istype(A, /obj/structure/sign/poster)) + var/obj/structure/sign/poster/P = A + P.roll_and_drop(user.loc) + else + var/obj/O = A + O.forceMove(user.loc) + displayed = null + qdel(src) + else if(istype(I, /obj/item/weapon/paper) || istype(I, /obj/item/weapon/photo) || istype(I, /obj/item/weapon/contraband/poster)) + if(!displayed) + user.unEquip(I) + insert(I) + update_icon() + else + user << "\The [src] already contains \a [displayed]." + else + return ..() + +/obj/item/weapon/picture_frame/afterattack(atom/target, mob/user, proximity_flag) + if(proximity_flag && istype(target, /turf/simulated/wall)) + place(target, user) + else + ..() + +/obj/item/weapon/picture_frame/proc/place(turf/T, mob/user) + var/stuff_on_wall = 0 + for(var/obj/O in user.loc.contents) //Let's see if it already has a poster on it or too much stuff + if(istype(O, /obj/structure/sign)) + user << "\The [T] is far too cluttered to place \a [src]!" + return + stuff_on_wall++ + if(stuff_on_wall >= 4) + user << "\The [T] is far too cluttered to place \a [src]!" + return + + user << "You start place \the [src] on \the [T]." + + var/px = 0 + var/py = 0 + var/newdir = getRelativeDirection(user, T) + + switch(newdir) + if(NORTH) + py = 32 + if(EAST) + px = 32 + if(SOUTH) + py = -32 + if(WEST) + px = -32 + else + user << "You cannot reach \the [T] from here!" + return + + user.unEquip(src) + var/obj/structure/sign/picture_frame/PF = new(user.loc, src) + PF.dir = newdir + PF.pixel_x = px + PF.pixel_y = py + + playsound(PF.loc, 'sound/items/Deconstruct.ogg', 100, 1) + +/obj/item/weapon/picture_frame/examine(mob/user, var/distance = -1, var/infix = "", var/suffix = "") + ..() + if(displayed) + displayed.examine(user, distance, infix, suffix) + +/obj/item/weapon/picture_frame/attack_self(mob/user) + if(displayed) + if(istype(displayed, /obj/item)) + var/obj/item/I = displayed + I.attack_self(user) + else + ..() + + + +/obj/item/weapon/picture_frame/glass + icon_base = "glass" + icon_state = "glass-poster" + materials = list(MAT_METAL = 25, MAT_GLASS = 75) + +/obj/item/weapon/picture_frame/wooden + icon_base = "wood" + icon_state = "wood-poster" + +/obj/item/weapon/picture_frame/wooden/New() + ..() + new /obj/item/stack/sheet/wood(src, 1) + + + +/obj/structure/sign/picture_frame + icon = 'icons/obj/bureaucracy.dmi' + icon_state = "glass-poster" + + var/obj/item/weapon/picture_frame/frame + var/obj/item/weapon/explosive + + var/tilted = 0 + var/tilt_transform = null + +/obj/structure/sign/picture_frame/New(loc, F) + ..() + frame = F + frame.pixel_x = 0 + frame.pixel_y = 0 + frame.forceMove(src) + name = frame.name + update_icon() + + if(!tilt_transform) + tilt_transform = turn(matrix(), -10) + + if(tilted) + transform = tilt_transform + verbs |= /obj/structure/sign/picture_frame/proc/untilt + else + verbs |= /obj/structure/sign/picture_frame/proc/tilt + +/obj/structure/sign/picture_frame/Destroy() + if(frame) + qdel(frame) + frame = null + return ..() + +/obj/structure/sign/picture_frame/update_icon() + overlays.Cut() + if(frame) + icon = null + icon_state = null + overlays |= getFlatIcon(frame) + else + icon = initial(icon) + icon_state = initial(icon_state) + +/obj/structure/sign/picture_frame/attackby(obj/item/I, mob/user) + if(istype(I, /obj/item/weapon/screwdriver)) + playsound(src, 'sound/items/Screwdriver.ogg', 100, 1) + user.visible_message("[user] begins to unfasten \the [src] from the wall.", "You begin to unfasten \the [src] from the wall.") + if(do_after(user, 100, target = src)) + playsound(src, 'sound/items/Deconstruct.ogg', 100, 1) + user.visible_message("[user] unfastens \the [src] from the wall.", "You unfasten \the [src] from the wall.") + frame.forceMove(user.loc) + frame = null + if(explosive) + explosive.forceMove(user.loc) + explosive = null + qdel(src) + if(istype(I, /obj/item/weapon/grenade) || istype(I, /obj/item/weapon/c4)) + if(explosive) + user << "There is already a device attached behind \the [src], remove it first." + return 1 + if(!tilted) + user << "\The [src] needs to be already tilted before being rigged with \the [I]." + return 1 + user.visible_message("[user] is fiddling around behind \the [src].", "You begin to secure \the [I] behind \the [src].") + if(do_after(user, 150, target = src)) + if(explosive || !tilted) + return + playsound(src, 'sound/weapons/handcuffs.ogg', 50, 1) + user.unEquip(I) + explosive = I + I.forceMove(src) + user.visible_message("[user] fiddles with the back of \the [src].", "You secure \the [I] behind \the [src].") + + message_admins("[key_name_admin(user)] attached [I] to a picture frame.") + log_game("[key_name_admin(user)] attached [I] to a picture frame.") + return 1 + else + return ..() + +/obj/structure/sign/picture_frame/examine(mob/user, var/distance = -1, var/infix = "", var/suffix = "") + if(frame) + frame.examine(user, distance, infix, suffix) + else + ..() + +/obj/structure/sign/picture_frame/attack_hand(mob/user) + if(frame) + frame.attack_self(user) + else + ..() + +/obj/structure/sign/picture_frame/ex_act(severity) + explode() + ..(severity) + +/obj/structure/sign/picture_frame/proc/explode() + if(istype(explosive, /obj/item/weapon/grenade)) + var/obj/item/weapon/grenade/G = explosive + explosive = null + G.prime() + else if(istype(explosive, /obj/item/weapon/c4)) + var/obj/item/weapon/c4/C = explosive + explosive = null + C.target = get_step(get_turf(src), dir) + C.explode(get_turf(loc)) + +/obj/structure/sign/picture_frame/proc/toggle_tilt(mob/user) + if(!isliving(usr) || usr.stat) + return + + tilted = !tilted + + if(tilted) + animate(src, transform = tilt_transform, time = 10, easing = BOUNCE_EASING) + verbs -= /obj/structure/sign/picture_frame/proc/tilt + verbs |= /obj/structure/sign/picture_frame/proc/untilt + else + animate(src, transform = matrix(), time = 10, easing = CUBIC_EASING | EASE_IN) + verbs -= /obj/structure/sign/picture_frame/proc/untilt + verbs |= /obj/structure/sign/picture_frame/proc/tilt + explode() + +/obj/structure/sign/picture_frame/proc/tilt() + set name = "Tilt Picture" + set category = "Object" + set src in oview(1) + + toggle_tilt(usr) + +/obj/structure/sign/picture_frame/proc/untilt() + set name = "Straighten Picture" + set category = "Object" + set src in oview(1) + + toggle_tilt(usr) + +/obj/structure/sign/picture_frame/hear_talk(mob/living/M as mob, msg) + ..() + for(var/obj/O in contents) + O.hear_talk(M, msg) + +/obj/structure/sign/picture_frame/hear_message(mob/living/M as mob, msg) + ..() + for(var/obj/O in contents) + O.hear_message(M, msg) \ No newline at end of file diff --git a/code/modules/pda/PDA.dm b/code/modules/pda/PDA.dm new file mode 100755 index 00000000000..c88dce0e20f --- /dev/null +++ b/code/modules/pda/PDA.dm @@ -0,0 +1,445 @@ + +//The advanced pea-green monochrome lcd of tomorrow. + +var/global/list/obj/item/device/pda/PDAs = list() + + +/obj/item/device/pda + name = "PDA" + desc = "A portable microcomputer by Thinktronic Systems, LTD. Functionality determined by a preprogrammed ROM cartridge." + icon = 'icons/obj/pda.dmi' + icon_state = "pda" + item_state = "electronic" + w_class = 1.0 + slot_flags = SLOT_PDA | SLOT_BELT + + //Main variables + var/owner = null + var/default_cartridge = 0 // Access level defined by cartridge + var/obj/item/weapon/cartridge/cartridge = null //current cartridge + var/datum/data/pda/app/current_app = null + var/datum/data/pda/app/lastapp = null + var/ui_tick = 0 + + //Secondary variables + var/model_name = "Thinktronic 5230 Personal Data Assistant" + var/datum/data/pda/utility/scanmode/scanmode = null + + var/lock_code = "" // Lockcode to unlock uplink + var/honkamt = 0 //How many honks left when infected with honk.exe + var/mimeamt = 0 //How many silence left when infected with mime.exe + var/detonate = 1 // Can the PDA be blown up? + var/newmessage = 0 //To remove hackish overlay check + var/ttone = "beep" //The ringtone! + + var/list/programs = list( + new/datum/data/pda/app/main_menu, + new/datum/data/pda/app/notekeeper, + new/datum/data/pda/app/messenger, + new/datum/data/pda/app/manifest, + new/datum/data/pda/app/atmos_scanner, + new/datum/data/pda/utility/scanmode/notes, + new/datum/data/pda/utility/flashlight) + var/list/shortcut_cache = list() + var/list/shortcut_cat_order = list() + + var/obj/item/weapon/card/id/id = null //Making it possible to slot an ID card into the PDA so it can function as both. + var/ownjob = null //related to above + var/ownrank = null // this one is rank, never alt title + + var/obj/item/device/paicard/pai = null // A slot for a personal AI device + var/retro_mode = 0 + + +/* + * The Actual PDA + */ +/obj/item/device/pda/New() + ..() + PDAs += src + PDAs = sortAtom(PDAs) + update_programs() + if(default_cartridge) + cartridge = new default_cartridge(src) + cartridge.update_programs(src) + new /obj/item/weapon/pen(src) + start_program(find_program(/datum/data/pda/app/main_menu)) + +/obj/item/device/pda/proc/can_use() + if(!ismob(loc)) + return 0 + + var/mob/M = loc + if(M.stat || M.restrained() || M.paralysis || M.stunned || M.weakened) + return 0 + if((src in M.contents) || ( istype(loc, /turf) && in_range(src, M) )) + return 1 + else + return 0 + +/obj/item/device/pda/GetAccess() + if(id) + return id.GetAccess() + else + return ..() + +/obj/item/device/pda/GetID() + return id + +/obj/item/device/pda/MouseDrop(obj/over_object as obj, src_location, over_location) + var/mob/M = usr + if((!istype(over_object, /obj/screen)) && can_use()) + return attack_self(M) + +/obj/item/device/pda/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + ui_tick++ + var/datum/nanoui/old_ui = nanomanager.get_open_ui(user, src, "main") + var/auto_update = 1 + if(!current_app) + return + + if(current_app.update == PDA_APP_NOUPDATE && current_app == lastapp) + auto_update = 0 + if(old_ui && (current_app == lastapp && ui_tick % 5 && current_app.update == PDA_APP_UPDATE_SLOW)) + return + + lastapp = current_app + + var/title = "Personal Data Assistant" + + var/data[0] // This is the data that will be sent to the PDA + + + data["owner"] = owner // Who is your daddy... + data["ownjob"] = ownjob // ...and what does he do? + + // update list of shortcuts, only if they changed + if(!shortcut_cache.len) + shortcut_cache = list() + shortcut_cat_order = list() + var/prog_list = programs.Copy() + if(cartridge) + prog_list |= cartridge.programs + + for(var/A in prog_list) + var/datum/data/pda/P = A + + if(P.hidden) + continue + var/list/cat + if(P.category in shortcut_cache) + cat = shortcut_cache[P.category] + else + cat = list() + shortcut_cache[P.category] = cat + shortcut_cat_order += P.category + cat |= list(list(name = P.name, icon = P.icon, ref = "\ref[P]")) + + // force the order of a few core categories + shortcut_cat_order = list("General") \ + + sortList(shortcut_cat_order - list("General", "Scanners", "Utilities")) \ + + list("Scanners", "Utilities") + + data["idInserted"] = (id ? 1 : 0) + data["idLink"] = (id ? text("[id.registered_name], [id.assignment]") : "--------") + + data["useRetro"] = retro_mode + + data["cartridge_name"] = cartridge ? cartridge.name : "" + data["stationTime"] = worldtime2text() + + data["app"] = list() + current_app.update_ui(user, data) + data["app"] |= list( + "name" = current_app.title, + "icon" = current_app.icon, + "template" = current_app.template, + "has_back" = current_app.has_back) + + // update the ui if it exists, returns null if no ui is passed/found + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, 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, "pda.tmpl", title, 630, 600, state = inventory_state) + ui.set_state_key("pda") + + // when the ui is first opened this is the data it will use + ui.set_initial_data(data) + // open the new ui window + ui.open() + + // auto update every Master Controller tick + ui.set_auto_update(auto_update) + +/obj/item/device/pda/attack_self(mob/user as mob) + user.set_machine(src) + if(active_uplink_check(user)) + return + ui_interact(user) //NanoUI requires this proc + +/obj/item/device/pda/proc/start_program(datum/data/pda/P) + if(P && ((P in programs) || (cartridge && (P in cartridge.programs)))) + return P.start() + return 0 + +/obj/item/device/pda/proc/find_program(type) + var/datum/data/pda/A = locate(type) in programs + if(A) + return A + if(cartridge) + A = locate(type) in cartridge.programs + if(A) + return A + return null + +// force the cache to rebuild on update_ui +/obj/item/device/pda/proc/update_shortcuts() + shortcut_cache.Cut() + +/obj/item/device/pda/proc/update_programs() + for(var/A in programs) + var/datum/data/pda/P = A + P.pda = src + +/obj/item/device/pda/Topic(href, href_list) + . = ..() + if(.) + return + + var/mob/user = usr + var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main") + var/mob/living/U = usr + if (usr.stat == DEAD) + return 0 + if(!can_use()) //Why reinvent the wheel? There's a proc that does exactly that. + U.unset_machine() + if(ui) + ui.close() + return 0 + + add_fingerprint(U) + U.set_machine(src) + + if(href_list["radiomenu"] && !isnull(cartridge) && !isnull(cartridge.radio)) + cartridge.radio.Topic(href, href_list) + return 1 + + . = 1 + + switch(href_list["choice"]) + if("Home")//Go home, largely replaces the old Return + var/datum/data/pda/app/main_menu/A = find_program(/datum/data/pda/app/main_menu) + if(A) + start_program(A) + if("StartProgram") + if(href_list["program"]) + var/datum/data/pda/app/A = locate(href_list["program"]) + if(A) + start_program(A) + if("Eject")//Ejects the cart, only done from hub. + if (!isnull(cartridge)) + var/turf/T = loc + if(ismob(T)) + T = T.loc + var/obj/item/weapon/cartridge/C = cartridge + C.forceMove(T) + if(scanmode in C.programs) + scanmode = null + if(current_app in C.programs) + start_program(find_program(/datum/data/pda/app/main_menu)) + if(C.radio) + C.radio.hostpda = null + cartridge = null + update_shortcuts() + if ("Authenticate")//Checks for ID + id_check(usr, 1) + if("Retro") + retro_mode = !retro_mode + else + if(current_app) + . = current_app.Topic(href, href_list) + +//EXTRA FUNCTIONS=================================== + if ((honkamt > 0) && (prob(60)))//For clown virus. + honkamt-- + playsound(loc, 'sound/items/bikehorn.ogg', 30, 1) + + return // return 1 tells it to refresh the UI in NanoUI + +/obj/item/device/pda/proc/close(mob/user) + var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main") + ui.close() + +/obj/item/device/pda/verb/verb_reset_pda() + set category = "Object" + set name = "Reset PDA" + set src in usr + + if(issilicon(usr)) + return + + if(can_use(usr)) + start_program(find_program(/datum/data/pda/app/main_menu)) + usr << "You press the reset button on \the [src]." + else + usr << "You cannot do this while restrained." + +/obj/item/device/pda/proc/remove_id() + if (id) + if (ismob(loc)) + var/mob/M = loc + M.put_in_hands(id) + usr << "You remove the ID from the [name]." + else + id.forceMove(get_turf(src)) + id = null + +/obj/item/device/pda/verb/verb_remove_id() + set category = "Object" + set name = "Remove id" + set src in usr + + if(issilicon(usr)) + return + + if ( can_use(usr) ) + if(id) + remove_id() + else + usr << "This PDA does not have an ID in it." + else + usr << "You cannot do this while restrained." + + +/obj/item/device/pda/verb/verb_remove_pen() + set category = "Object" + set name = "Remove pen" + set src in usr + + if(issilicon(usr)) + return + + if ( can_use(usr) ) + var/obj/item/weapon/pen/O = locate() in src + if(O) + if (istype(loc, /mob)) + var/mob/M = loc + if(M.get_active_hand() == null) + M.put_in_hands(O) + usr << "You remove \the [O] from \the [src]." + return + O.forceMove(get_turf(src)) + else + usr << "This PDA does not have a pen in it." + else + usr << "You cannot do this while restrained." + + +/obj/item/device/pda/proc/id_check(mob/user as mob, choice as num)//To check for IDs; 1 for in-pda use, 2 for out of pda use. + if(choice == 1) + if (id) + remove_id() + else + var/obj/item/I = user.get_active_hand() + if (istype(I, /obj/item/weapon/card/id)) + user.drop_item() + I.forceMove(src) + id = I + else + var/obj/item/weapon/card/I = user.get_active_hand() + if (istype(I, /obj/item/weapon/card/id) && I:registered_name) + var/obj/old_id = id + user.drop_item() + I.forceMove(src) + id = I + user.put_in_hands(old_id) + return + +/obj/item/device/pda/attackby(obj/item/C as obj, mob/user as mob, params) + ..() + if(istype(C, /obj/item/weapon/cartridge) && !cartridge) + cartridge = C + user.drop_item() + cartridge.forceMove(src) + cartridge.update_programs(src) + update_shortcuts() + user << "You insert [cartridge] into [src]." + if(cartridge.radio) + cartridge.radio.hostpda = src + + else if(istype(C, /obj/item/weapon/card/id)) + var/obj/item/weapon/card/id/idcard = C + if(!idcard.registered_name) + user << "\The [src] rejects the ID." + return + if(!owner) + owner = idcard.registered_name + ownjob = idcard.assignment + ownrank = idcard.rank + name = "PDA-[owner] ([ownjob])" + user << "Card scanned." + else + //Basic safety check. If either both objects are held by user or PDA is on ground and card is in hand. + if(((src in user.contents) && (C in user.contents)) || (istype(loc, /turf) && in_range(src, user) && (C in user.contents)) ) + if( can_use(user) )//If they can still act. + id_check(user, 2) + user << "You put the ID into \the [src]'s slot." + else if(istype(C, /obj/item/device/paicard) && !src.pai) + user.drop_item() + C.forceMove(src) + pai = C + user << "You slot \the [C] into [src]." + else if(istype(C, /obj/item/weapon/pen)) + var/obj/item/weapon/pen/O = locate() in src + if(O) + user << "There is already a pen in \the [src]." + else + user.drop_item() + C.forceMove(src) + user << "You slide \the [C] into \the [src]." + +/obj/item/device/pda/attack(mob/living/C as mob, mob/living/user as mob) + if (istype(C, /mob/living/carbon) && scanmode) + scanmode.scan_mob(C, user) + +/obj/item/device/pda/afterattack(atom/A as mob|obj|turf|area, mob/user as mob, proximity) + if(proximity && scanmode) + scanmode.scan_atom(A, user) + +/obj/item/device/pda/proc/explode() //This needs tuning. + if(!src.detonate) return + var/turf/T = get_turf(src.loc) + + if (ismob(loc)) + var/mob/M = loc + M.show_message("Your [src] explodes!", 1) + + if(T) + T.hotspot_expose(700,125) + + explosion(T, -1, -1, 2, 3) + qdel(src) + return + +/obj/item/device/pda/Destroy() + PDAs -= src + var/T = get_turf(loc) + if (id) + id.forceMove(T) + if(pai) + pai.forceMove(T) + current_app = null + scanmode = null + for(var/A in programs) + qdel(A) + programs.Cut() + if(cartridge) + qdel(cartridge) + cartridge = null + return ..() + +// Pass along the pulse to atoms in contents, largely added so pAIs are vulnerable to EMP +/obj/item/device/pda/emp_act(severity) + for(var/atom/A in src) + A.emp_act(severity) \ No newline at end of file diff --git a/code/modules/pda/ai.dm b/code/modules/pda/ai.dm new file mode 100644 index 00000000000..a6c7769ab52 --- /dev/null +++ b/code/modules/pda/ai.dm @@ -0,0 +1,91 @@ +// Special AI/pAI PDAs that cannot explode. +/obj/item/device/pda/ai + icon_state = "NONE" + detonate = 0 + ttone = "data" + +/obj/item/device/pda/ai/proc/set_name_and_job(newname as text, newjob as text, newrank as null|text) + owner = newname + ownjob = newjob + if(newrank) + ownrank = newrank + else + ownrank = ownjob + name = newname + " (" + ownjob + ")" + +/obj/item/device/pda/ai/verb/cmd_send_pdamesg() + set category = "AI IM" + set name = "Send PDA Message" + set src in usr + + if(usr.stat == DEAD) + usr << "You can't send PDA messages because you are dead!" + return + var/datum/data/pda/app/messenger/M = find_program(/datum/data/pda/app/messenger) + if(!M) + usr << "Cannot use messenger!" + var/list/plist = M.available_pdas() + if (plist) + var/c = input(usr, "Please select a PDA") as null|anything in sortList(plist) + if (!c) // if the user hasn't selected a PDA file we can't send a message + return + var/selected = plist[c] + M.create_message(usr, selected) + +/obj/item/device/pda/ai/verb/cmd_show_message_log() + set category = "AI IM" + set name = "Show Message Log" + set src in usr + + if(usr.stat == DEAD) + usr << "You can't do that because you are dead!" + return + var/datum/data/pda/app/messenger/M = find_program(/datum/data/pda/app/messenger) + if(!M) + usr << "Cannot use messenger!" + var/HTML = "AI PDA Message Log" + for(var/index in M.tnote) + if(index["sent"]) + HTML += addtext("→ To ", index["owner"],":
    ", index["message"], "
    ") + else + HTML += addtext("← From ", index["owner"],":
    ", index["message"], "
    ") + HTML +="" + usr << browse(HTML, "window=log;size=400x444;border=1;can_resize=1;can_close=1;can_minimize=0") + +/obj/item/device/pda/ai/verb/cmd_toggle_pda_receiver() + set category = "AI IM" + set name = "Toggle Sender/Receiver" + set src in usr + + if(usr.stat == DEAD) + usr << "You can't do that because you are dead!" + return + var/datum/data/pda/app/messenger/M = find_program(/datum/data/pda/app/messenger) + M.toff = !M.toff + usr << "PDA sender/receiver toggled [(M.toff ? "Off" : "On")]!" + + +/obj/item/device/pda/ai/verb/cmd_toggle_pda_silent() + set category = "AI IM" + set name = "Toggle Ringer" + set src in usr + + if(usr.stat == DEAD) + usr << "You can't do that because you are dead!" + return + var/datum/data/pda/app/messenger/M = find_program(/datum/data/pda/app/messenger) + M.silent = !M.silent + usr << "PDA ringer toggled [(M.silent ? "Off" : "On")]!" + +/obj/item/device/pda/ai/can_use() + return 1 + + +/obj/item/device/pda/ai/attack_self(mob/user as mob) + if ((honkamt > 0) && (prob(60)))//For clown virus. + honkamt-- + playsound(loc, 'sound/items/bikehorn.ogg', 30, 1) + return + +/obj/item/device/pda/ai/pai + ttone = "assist" \ No newline at end of file diff --git a/code/modules/pda/app.dm b/code/modules/pda/app.dm new file mode 100644 index 00000000000..1f8b37d97fa --- /dev/null +++ b/code/modules/pda/app.dm @@ -0,0 +1,66 @@ +// Base class for anything that can show up on home screen +/datum/data/pda + var/icon = "tasks" + var/hidden = 0 // program not displayed in main menu + var/category = "General" // the category to list it in on the main menu + var/obj/item/device/pda/pda // if this is null, and the app is running code, something's gone wrong + +/datum/data/pda/Destroy() + pda = null + return ..() + +/datum/data/pda/proc/start() + + +// An app has a button on the home screen and its own UI +/datum/data/pda/app + name = "App" + size = 3 + var/title = null // what is displayed in the title bar when this is the current app + var/template = "" + var/update = PDA_APP_UPDATE + var/has_back = 0 + +/datum/data/pda/app/New() + if(!title) + title = name + +/datum/data/pda/app/start() + pda.current_app = src + return 1 + +/datum/data/pda/app/proc/update_ui(mob/user as mob, list/data) + + +// Utilities just have a button on the home screen, but custom code when clicked +/datum/data/pda/utility + name = "Utility" + icon = "gear" + size = 1 + category = "Utilities" + + +/datum/data/pda/utility/scanmode + var/base_name + category = "Scanners" + +/datum/data/pda/utility/scanmode/New(obj/item/weapon/cartridge/C) + ..(C) + name = "Enable [base_name]" + +/datum/data/pda/utility/scanmode/start() + if(pda.scanmode) + pda.scanmode.name = "Enable [pda.scanmode.base_name]" + + if(pda.scanmode == src) + pda.scanmode = null + else + pda.scanmode = src + name = "Disable [base_name]" + + pda.update_shortcuts() + return 1 + +/datum/data/pda/utility/scanmode/proc/scan_mob(mob/living/C as mob, mob/living/user as mob) + +/datum/data/pda/utility/scanmode/proc/scan_atom(atom/A as mob|obj|turf|area, mob/user as mob) \ No newline at end of file diff --git a/code/modules/pda/cart.dm b/code/modules/pda/cart.dm new file mode 100644 index 00000000000..c96a8cfb11c --- /dev/null +++ b/code/modules/pda/cart.dm @@ -0,0 +1,314 @@ +/obj/item/weapon/cartridge + name = "generic cartridge" + desc = "A data cartridge for portable microcomputers." + icon = 'icons/obj/pda.dmi' + icon_state = "cart" + item_state = "electronic" + w_class = 1 + + var/obj/item/radio/integrated/radio = null + + var/charges = 0 + + var/list/stored_data = list() + var/list/programs = list() + var/list/messenger_plugins = list() + +/obj/item/weapon/cartridge/New() + if(ticker && ticker.current_state >= GAME_STATE_SETTING_UP) + initialize() + +/obj/item/weapon/cartridge/initialize() + if(radio) + radio.initialize() + ..() + +/obj/item/weapon/cartridge/Destroy() + if(radio) + qdel(radio) + radio = null + for(var/A in programs) + qdel(A) + programs.Cut() + for(var/A in messenger_plugins) + qdel(A) + messenger_plugins.Cut() + return ..() + +/obj/item/weapon/cartridge/proc/update_programs(obj/item/device/pda/pda) + for(var/A in programs) + var/datum/data/pda/P = A + P.pda = pda + for(var/A in messenger_plugins) + var/datum/data/pda/messenger_plugin/P = A + P.pda = pda + +/obj/item/weapon/cartridge/engineering + name = "Power-ON Cartridge" + icon_state = "cart-e" + programs = list( + new/datum/data/pda/app/power, + new/datum/data/pda/utility/scanmode/halogen) + +/obj/item/weapon/cartridge/atmos + name = "BreatheDeep Cartridge" + icon_state = "cart-a" + programs = list( + new/datum/data/pda/utility/scanmode/gas) + +/obj/item/weapon/cartridge/medical + name = "Med-U Cartridge" + icon_state = "cart-m" + programs = list( + new/datum/data/pda/app/crew_records/medical, + new/datum/data/pda/utility/scanmode/medical) + +/obj/item/weapon/cartridge/chemistry + name = "ChemWhiz Cartridge" + icon_state = "cart-chem" + programs = list( + new/datum/data/pda/utility/scanmode/reagent) + +/obj/item/weapon/cartridge/security + name = "R.O.B.U.S.T. Cartridge" + icon_state = "cart-s" + programs = list( + new/datum/data/pda/app/crew_records/security, + new/datum/data/pda/app/secbot_control) + +/obj/item/weapon/cartridge/security/initialize() + radio = new /obj/item/radio/integrated/beepsky(src) + ..() + +/obj/item/weapon/cartridge/detective + name = "D.E.T.E.C.T. Cartridge" + icon_state = "cart-s" + programs = list( + new/datum/data/pda/app/crew_records/medical, + new/datum/data/pda/utility/scanmode/medical, + + new/datum/data/pda/app/crew_records/security) + + +/obj/item/weapon/cartridge/janitor + name = "CustodiPRO Cartridge" + desc = "The ultimate in clean-room design." + icon_state = "cart-j" + programs = list( + new/datum/data/pda/app/janitor) + +/obj/item/weapon/cartridge/lawyer + name = "P.R.O.V.E. Cartridge" + icon_state = "cart-s" + programs = list( + new/datum/data/pda/app/crew_records/security) + +/obj/item/weapon/cartridge/clown + name = "Honkworks 5.0" + icon_state = "cart-clown" + charges = 5 + programs = list( + new/datum/data/pda/utility/honk) + messenger_plugins = list( + new/datum/data/pda/messenger_plugin/virus/clown) + +/obj/item/weapon/cartridge/mime + name = "Gestur-O 1000" + icon_state = "cart-mi" + charges = 5 + messenger_plugins = list( + new/datum/data/pda/messenger_plugin/virus/mime) + +/* +/obj/item/weapon/cartridge/botanist + name = "Green Thumb v4.20" + icon_state = "cart-b" + access_flora = 1 +*/ + +/obj/item/weapon/cartridge/signal + name = "generic signaler cartridge" + desc = "A data cartridge with an integrated radio signaler module." + programs = list( + new/datum/data/pda/app/signaller) + +/obj/item/weapon/cartridge/signal/initialize() + radio = new /obj/item/radio/integrated/signal(src) + ..() + +/obj/item/weapon/cartridge/signal/toxins + name = "Signal Ace 2" + desc = "Complete with integrated radio signaler!" + icon_state = "cart-tox" + programs = list( + new/datum/data/pda/utility/scanmode/gas, + + new/datum/data/pda/utility/scanmode/reagent, + + new/datum/data/pda/app/signaller) + +/obj/item/weapon/cartridge/quartermaster + name = "Space Parts & Space Vendors Cartridge" + desc = "Perfect for the Quartermaster on the go!" + icon_state = "cart-q" + programs = list( + new/datum/data/pda/app/supply, + new/datum/data/pda/app/mule_control) + +/obj/item/weapon/cartridge/quartermaster/initialize() + radio = new /obj/item/radio/integrated/mule(src) + ..() + +/obj/item/weapon/cartridge/head + name = "Easy-Record DELUXE" + icon_state = "cart-h" + programs = list( + new/datum/data/pda/app/status_display) + +/obj/item/weapon/cartridge/hop + name = "HumanResources9001" + icon_state = "cart-h" + programs = list( + new/datum/data/pda/app/crew_records/security, + + new/datum/data/pda/app/janitor, + + new/datum/data/pda/app/supply, + new/datum/data/pda/app/mule_control, + + new/datum/data/pda/app/status_display) + +/obj/item/weapon/cartridge/hop/initialize() + radio = new /obj/item/radio/integrated/mule(src) + ..() + +/obj/item/weapon/cartridge/hos + name = "R.O.B.U.S.T. DELUXE" + icon_state = "cart-hos" + programs = list( + new/datum/data/pda/app/crew_records/security, + new/datum/data/pda/app/secbot_control, + + new/datum/data/pda/app/status_display) + +/obj/item/weapon/cartridge/hos/initialize() + radio = new /obj/item/radio/integrated/beepsky(src) + ..() + +/obj/item/weapon/cartridge/ce + name = "Power-On DELUXE" + icon_state = "cart-ce" + programs = list( + new/datum/data/pda/app/power, + new/datum/data/pda/utility/scanmode/halogen, + + new/datum/data/pda/utility/scanmode/gas, + + new/datum/data/pda/app/status_display) + +/obj/item/weapon/cartridge/cmo + name = "Med-U DELUXE" + icon_state = "cart-cmo" + programs = list( + new/datum/data/pda/app/crew_records/medical, + new/datum/data/pda/utility/scanmode/medical, + + new/datum/data/pda/utility/scanmode/reagent, + + new/datum/data/pda/app/status_display) + +/obj/item/weapon/cartridge/rd + name = "Signal Ace DELUXE" + icon_state = "cart-rd" + programs = list( + new/datum/data/pda/utility/scanmode/gas, + + new/datum/data/pda/utility/scanmode/reagent, + + new/datum/data/pda/app/signaller, + + new/datum/data/pda/app/status_display) + +/obj/item/weapon/cartridge/rd/initialize() + radio = new /obj/item/radio/integrated/signal(src) + ..() + +/obj/item/weapon/cartridge/captain + name = "Value-PAK Cartridge" + desc = "Now with 200% more value!" + icon_state = "cart-c" + programs = list( + new/datum/data/pda/app/power, + new/datum/data/pda/utility/scanmode/halogen, + + new/datum/data/pda/utility/scanmode/gas, + + new/datum/data/pda/app/crew_records/medical, + new/datum/data/pda/utility/scanmode/medical, + + new/datum/data/pda/utility/scanmode/reagent, + + new/datum/data/pda/app/crew_records/security, + new/datum/data/pda/app/secbot_control, + + new/datum/data/pda/app/janitor, + + new/datum/data/pda/app/supply, + + new/datum/data/pda/app/status_display) + +/obj/item/weapon/cartridge/captain/initialize() + radio = new /obj/item/radio/integrated/beepsky(src) + ..() + +/obj/item/weapon/cartridge/supervisor + name = "Easy-Record DELUXE" + icon_state = "cart-h" + programs = list( + new/datum/data/pda/app/crew_records/security, + + new/datum/data/pda/app/status_display) + +/obj/item/weapon/cartridge/centcom + name = "Value-PAK Cartridge" + desc = "Now with 200% more value!" + icon_state = "cart-c" + programs = list( + new/datum/data/pda/app/power, + new/datum/data/pda/utility/scanmode/halogen, + + new/datum/data/pda/utility/scanmode/gas, + + new/datum/data/pda/app/crew_records/medical, + new/datum/data/pda/utility/scanmode/medical, + + new/datum/data/pda/utility/scanmode/reagent, + + new/datum/data/pda/app/crew_records/security, + new/datum/data/pda/app/secbot_control, + + new/datum/data/pda/app/janitor, + + new/datum/data/pda/app/supply, + new/datum/data/pda/app/mule_control, + + new/datum/data/pda/app/status_display) + +/obj/item/weapon/cartridge/centcom/initialize() + radio = new /obj/item/radio/integrated/beepsky(src) + ..() + +/obj/item/weapon/cartridge/syndicate + name = "Detomatix Cartridge" + icon_state = "cart" + var/initial_remote_door_id = "smindicate" //Make sure this matches the syndicate shuttle's shield/door id!! //don't ask about the name, testing. + charges = 4 + programs = list( + new/datum/data/pda/utility/toggle_door) + messenger_plugins = list( + new/datum/data/pda/messenger_plugin/virus/detonate) + +/obj/item/weapon/cartridge/syndicate/New() + var/datum/data/pda/utility/toggle_door/D = programs[1] + if(istype(D)) + D.remote_door_id = initial_remote_door_id \ No newline at end of file diff --git a/code/modules/pda/cart_apps.dm b/code/modules/pda/cart_apps.dm new file mode 100644 index 00000000000..0b81365f7d6 --- /dev/null +++ b/code/modules/pda/cart_apps.dm @@ -0,0 +1,420 @@ +/datum/data/pda/app/status_display + name = "Status Display" + icon = "list-alt" + template = "pda_status_display" + category = "Utilities" + + var/message1 // used for status_displays + var/message2 + +/datum/data/pda/app/status_display/update_ui(mob/user as mob, list/data) + data["records"] = list( + "message1" = message1 ? message1 : "(none)", + "message2" = message2 ? message2 : "(none)") + +/datum/data/pda/app/status_display/Topic(href, list/href_list) + switch(href_list["choice"]) + if("Status") + switch(href_list["statdisp"]) + if("message") + post_status("message", message1, message2) + if("alert") + post_status("alert", href_list["alert"]) + if("setmsg1") + message1 = input("Line 1", "Enter Message Text", message1) as text|null + if("setmsg2") + message2 = input("Line 2", "Enter Message Text", message2) as text|null + else + post_status(href_list["statdisp"]) + +/datum/data/pda/app/status_display/proc/post_status(var/command, var/data1, var/data2) + var/datum/radio_frequency/frequency = radio_controller.return_frequency(1435) + if(!frequency) + return + + var/datum/signal/status_signal = new + status_signal.source = src + status_signal.transmission_method = 1 + status_signal.data["command"] = command + + switch(command) + if("message") + status_signal.data["msg1"] = data1 + status_signal.data["msg2"] = data2 + var/mob/user = pda.fingerprintslast + if(istype(pda.loc, /mob/living)) + name = pda.loc + log_admin("STATUS: [user] set status screen with [pda]. Message: [data1] [data2]") + message_admins("STATUS: [user] set status screen with [pda]. Message: [data1] [data2]") + + if("alert") + status_signal.data["picture_state"] = data1 + + spawn(0) + frequency.post_signal(src, status_signal) + + +/datum/data/pda/app/signaller + name = "Signaler System" + icon = "rss" + template = "pda_signaller" + category = "Utilities" + +/datum/data/pda/app/signaller/update_ui(mob/user as mob, list/data) + if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/radio/integrated/signal)) + var/obj/item/radio/integrated/signal/R = pda.cartridge.radio + data["signal_freq"] = format_frequency(R.frequency) + data["signal_code"] = R.code + +/datum/data/pda/app/signaller/Topic(href, list/href_list) + if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/radio/integrated/signal)) + var/obj/item/radio/integrated/signal/R = pda.cartridge.radio + + switch(href_list["choice"]) + if("Send Signal") + spawn(0) + R.send_signal("ACTIVATE") + + if("Signal Frequency") + var/new_frequency = sanitize_frequency(R.frequency + text2num(href_list["sfreq"])) + R.set_frequency(new_frequency) + + if("Signal Code") + R.code += text2num(href_list["scode"]) + R.code = round(R.code) + R.code = min(100, R.code) + R.code = max(1, R.code) + +/datum/data/pda/app/power + name = "Power Monitor" + icon = "exclamation-triangle" + template = "pda_power" + category = "Engineering" + update = PDA_APP_UPDATE_SLOW + + var/obj/machinery/computer/monitor/powmonitor = null + +/datum/data/pda/app/power/update_ui(mob/user as mob, list/data) + update = PDA_APP_UPDATE_SLOW + + if (powmonitor && !isnull(powmonitor.powernet)) + data["records"] = list( + "powerconnected" = 1, + "poweravail" = powmonitor.powernet.avail, + "powerload" = num2text(powmonitor.powernet.viewload, 10), + "powerdemand" = powmonitor.powernet.load, + "apcs" = apc_repository.apc_data(powmonitor)) + has_back = 1 + else + data["records"] = list( + "powerconnected" = 0, + "powermonitors" = powermonitor_repository.powermonitor_data()) + has_back = 0 + +/datum/data/pda/app/power/Topic(href, list/href_list) + switch(href_list["choice"]) + if("Power Select") + var/pref = href_list["target"] + powmonitor = locate(pref) + update = PDA_APP_UPDATE + if("Back") + powmonitor = null + update = PDA_APP_UPDATE + +/datum/data/pda/app/crew_records + var/datum/data/record/general_records = null + +/datum/data/pda/app/crew_records/update_ui(mob/user as mob, list/data) + var/list/records[0] + + if(general_records && general_records in data_core.general) + data["records"] = records + records["general"] = general_records.fields + return records + else + for(var/A in sortRecord(data_core.general)) + var/datum/data/record/R = A + records += list(list(Name = R.fields["name"], "ref" = "\ref[R]")) + data["recordsList"] = records + return null + +/datum/data/pda/app/crew_records/Topic(href, list/href_list) + switch(href_list["choice"]) + if("Records") + var/datum/data/record/R = locate(href_list["target"]) + if (R in data_core.general) + load_records(R) + if("Back") + general_records = null + has_back = 0 + +/datum/data/pda/app/crew_records/proc/load_records(datum/data/record/R) + general_records = R + has_back = 1 + +/datum/data/pda/app/crew_records/medical + name = "Medical Records" + icon = "heartbeat" + template = "pda_medical" + category = "Medical" + + var/datum/data/record/medical_records = null + +/datum/data/pda/app/crew_records/medical/update_ui(mob/user as mob, list/data) + var/list/records = ..() + if(!records) + return + + if(medical_records && medical_records in data_core.medical) + records["medical"] = medical_records.fields + + return records + +/datum/data/pda/app/crew_records/medical/load_records(datum/data/record/R) + ..(R) + for(var/A in data_core.medical) + var/datum/data/record/E = A + if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) + medical_records = E + break + +/datum/data/pda/app/crew_records/security + name = "Security Records" + icon = "tags" + template = "pda_security" + category = "Security" + + var/datum/data/record/security_records = null + +/datum/data/pda/app/crew_records/security/update_ui(mob/user as mob, list/data) + var/list/records = ..() + if(!records) + return + + if(security_records && security_records in data_core.security) + records["security"] = security_records.fields + + return records + +/datum/data/pda/app/crew_records/security/load_records(datum/data/record/R) + ..(R) + for(var/A in data_core.security) + var/datum/data/record/E = A + if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) + security_records = E + break + +/datum/data/pda/app/secbot_control + name = "Security Bot Access" + icon = "rss" + template = "pda_secbot" + category = "Security" + +/datum/data/pda/app/secbot_control/update_ui(mob/user as mob, list/data) + var/botsData[0] + var/beepskyData[0] + if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/radio/integrated/beepsky)) + var/obj/item/radio/integrated/beepsky/SC = pda.cartridge.radio + beepskyData["active"] = SC.active ? sanitize(SC.active.name) : null + has_back = SC.active ? 1 : 0 + if(SC.active && !isnull(SC.botstatus)) + var/area/loca = SC.botstatus["loca"] + var/loca_name = sanitize(loca.name) + beepskyData["botstatus"] = list("loca" = loca_name, "mode" = SC.botstatus["mode"]) + else + beepskyData["botstatus"] = list("loca" = null, "mode" = -1) + var/botsCount=0 + if(SC.botlist && SC.botlist.len) + for(var/obj/machinery/bot/B in SC.botlist) + botsCount++ + if(B.loc) + botsData[++botsData.len] = list("Name" = sanitize(B.name), "Location" = sanitize(B.loc.loc.name), "ref" = "\ref[B]") + + if(!botsData.len) + botsData[++botsData.len] = list("Name" = "No bots found", "Location" = "Invalid", "ref"= null) + + beepskyData["bots"] = botsData + beepskyData["count"] = botsCount + + else + beepskyData["active"] = 0 + botsData[++botsData.len] = list("Name" = "No bots found", "Location" = "Invalid", "ref"= null) + beepskyData["botstatus"] = list("loca" = null, "mode" = null) + beepskyData["bots"] = botsData + beepskyData["count"] = 0 + has_back = 0 + + data["beepsky"] = beepskyData + +/datum/data/pda/app/secbot_control/Topic(href, list/href_list) + switch(href_list["choice"]) + if("Back") + if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/radio/integrated/beepsky)) + pda.cartridge.radio.Topic(null, list(radiomenu = "1", op = "botlist")) + +/datum/data/pda/app/mule_control + name = "Delivery Bot Control" + icon = "truck" + template = "pda_mule" + category = "Quartermaster" + +/datum/data/pda/app/mule_control/update_ui(mob/user as mob, list/data) + var/muleData[0] + var/mulebotsData[0] + if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/radio/integrated/mule)) + var/obj/item/radio/integrated/mule/QC = pda.cartridge.radio + muleData["active"] = QC.active ? sanitize(QC.active.name) : null + has_back = QC.active ? 1 : 0 + if(QC.active && !isnull(QC.botstatus)) + var/area/loca = QC.botstatus["loca"] + var/loca_name = sanitize(loca.name) + muleData["botstatus"] = list("loca" = loca_name, "mode" = QC.botstatus["mode"],"home"=QC.botstatus["home"],"powr" = QC.botstatus["powr"],"retn" =QC.botstatus["retn"], "pick"=QC.botstatus["pick"], "load" = QC.botstatus["load"], "dest" = sanitize(QC.botstatus["dest"])) + + else + muleData["botstatus"] = list("loca" = null, "mode" = -1,"home"=null,"powr" = null,"retn" =null, "pick"=null, "load" = null, "dest" = null) + + + var/mulebotsCount=0 + for(var/obj/machinery/bot/B in QC.botlist) + mulebotsCount++ + if(B.loc) + mulebotsData[++mulebotsData.len] = list("Name" = sanitize(B.name), "Location" = sanitize(B.loc.loc.name), "ref" = "\ref[B]") + + if(!mulebotsData.len) + mulebotsData[++mulebotsData.len] = list("Name" = "No bots found", "Location" = "Invalid", "ref"= null) + + muleData["bots"] = mulebotsData + muleData["count"] = mulebotsCount + + else + muleData["botstatus"] = list("loca" = null, "mode" = -1,"home"=null,"powr" = null,"retn" =null, "pick"=null, "load" = null, "dest" = null) + muleData["active"] = 0 + mulebotsData[++mulebotsData.len] = list("Name" = "No bots found", "Location" = "Invalid", "ref"= null) + muleData["bots"] = mulebotsData + muleData["count"] = 0 + has_back = 0 + + data["mulebot"] = muleData + +/datum/data/pda/app/mule_control/Topic(href, list/href_list) + switch(href_list["choice"]) + if("Back") + if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/radio/integrated/mule)) + pda.cartridge.radio.Topic(null, list(radiomenu = "1", op = "botlist")) + +/datum/data/pda/app/supply + name = "Supply Records" + icon = "file-text-o" + template = "pda_supply" + category = "Quartermaster" + update = PDA_APP_UPDATE_SLOW + +/datum/data/pda/app/supply/update_ui(mob/user as mob, list/data) + var/supplyData[0] + + if(shuttle_master.supply.mode == SHUTTLE_CALL) + supplyData["shuttle_moving"] = 1 + + if(shuttle_master.supply.z != ZLEVEL_STATION) + supplyData["shuttle_loc"] = "station" + else + supplyData["shuttle_loc"] = "centcom" + + supplyData["shuttle_time"] = "([shuttle_master.supply.timeLeft(600)] Mins)" + + var/supplyOrderCount = 0 + var/supplyOrderData[0] + for(var/S in shuttle_master.shoppinglist) + var/datum/supply_order/SO = S + supplyOrderCount++ + supplyOrderData[++supplyOrderData.len] = list("Number" = SO.ordernum, "Name" = html_encode(SO.object.name), "ApprovedBy" = SO.orderedby, "Comment" = html_encode(SO.comment)) + + if(!supplyOrderData.len) + supplyOrderData[++supplyOrderData.len] = list("Number" = null, "Name" = null, "OrderedBy"=null) + + supplyData["approved"] = supplyOrderData + supplyData["approved_count"] = supplyOrderCount + + var/requestCount = 0 + var/requestData[0] + for(var/S in shuttle_master.requestlist) + var/datum/supply_order/SO = S + requestCount++ + requestData[++requestData.len] = list("Number" = SO.ordernum, "Name" = html_encode(SO.object.name), "OrderedBy" = SO.orderedby, "Comment" = html_encode(SO.comment)) + + if(!requestData.len) + requestData[++requestData.len] = list("Number" = null, "Name" = null, "orderedBy" = null, "Comment" = null) + + supplyData["requests"] = requestData + supplyData["requests_count"] = requestCount + + data["supply"] = supplyData + +/datum/data/pda/app/janitor + name = "Custodial Locator" + icon = "trash-o" + template = "pda_janitor" + category = "Utilities" + update = PDA_APP_UPDATE_SLOW + +/datum/data/pda/app/janitor/update_ui(mob/user as mob, list/data) + var/JaniData[0] + var/turf/cl = get_turf(pda) + + if(cl) + JaniData["user_loc"] = list("x" = cl.x, "y" = cl.y) + else + JaniData["user_loc"] = list("x" = 0, "y" = 0) + var/MopData[0] + for(var/obj/item/weapon/mop/M in janitorial_equipment) + var/turf/ml = get_turf(M) + if(ml) + if(ml.z != cl.z) + continue + var/direction = get_dir(pda, M) + MopData[++MopData.len] = list ("x" = ml.x, "y" = ml.y, "dir" = uppertext(dir2text(direction)), "status" = M.reagents.total_volume ? "Wet" : "Dry") + + if(!MopData.len) + MopData[++MopData.len] = list("x" = 0, "y" = 0, dir=null, status = null) + + + var/BucketData[0] + for(var/obj/structure/mopbucket/B in janitorial_equipment) + var/turf/bl = get_turf(B) + if(bl) + if(bl.z != cl.z) + continue + var/direction = get_dir(pda,B) + BucketData[++BucketData.len] = list ("x" = bl.x, "y" = bl.y, "dir" = uppertext(dir2text(direction)), "status" = B.reagents.total_volume/100) + + if(!BucketData.len) + BucketData[++BucketData.len] = list("x" = 0, "y" = 0, dir=null, status = null) + + var/CbotData[0] + for(var/obj/machinery/bot/cleanbot/B in aibots) + var/turf/bl = get_turf(B) + if(bl) + if(bl.z != cl.z) + continue + var/direction = get_dir(pda,B) + CbotData[++CbotData.len] = list("x" = bl.x, "y" = bl.y, "dir" = uppertext(dir2text(direction)), "status" = B.on ? "Online" : "Offline") + + + if(!CbotData.len) + CbotData[++CbotData.len] = list("x" = 0, "y" = 0, dir=null, status = null) + var/CartData[0] + for(var/obj/structure/janitorialcart/B in janitorial_equipment) + var/turf/bl = get_turf(B) + if(bl) + if(bl.z != cl.z) + continue + var/direction = get_dir(pda,B) + CartData[++CartData.len] = list("x" = bl.x, "y" = bl.y, "dir" = uppertext(dir2text(direction)), "status" = B.reagents.total_volume/100) + if(!CartData.len) + CartData[++CartData.len] = list("x" = 0, "y" = 0, dir=null, status = null) + + JaniData["mops"] = MopData + JaniData["buckets"] = BucketData + JaniData["cleanbots"] = CbotData + JaniData["carts"] = CartData + data["janitor"] = JaniData \ No newline at end of file diff --git a/code/game/objects/items/devices/PDA/chatroom.dm b/code/modules/pda/chatroom.dm similarity index 100% rename from code/game/objects/items/devices/PDA/chatroom.dm rename to code/modules/pda/chatroom.dm diff --git a/code/modules/pda/core_apps.dm b/code/modules/pda/core_apps.dm new file mode 100644 index 00000000000..55a6dbd6f45 --- /dev/null +++ b/code/modules/pda/core_apps.dm @@ -0,0 +1,106 @@ +/datum/data/pda/app/main_menu + icon = "home" + template = "pda_main_menu" + hidden = 1 + +/datum/data/pda/app/main_menu/update_ui(mob/user as mob, list/data) + title = pda.name + + data["app"]["is_home"] = 1 + + data["apps"] = pda.shortcut_cache + data["categories"] = pda.shortcut_cat_order + data["pai"] = !isnull(pda.pai) // pAI inserted? + +/datum/data/pda/app/main_menu/Topic(href, list/href_list) + switch(href_list["choice"]) + if("UpdateInfo") + pda.ownjob = pda.id.assignment + pda.ownrank = pda.id.rank + pda.name = "PDA-[pda.owner] ([pda.ownjob])" + if("pai") + if(pda.pai) + if(pda.pai.loc != pda) + pda.pai = null + else + switch(href_list["option"]) + if("1") // Configure pAI device + pda.pai.attack_self(usr) + if("2") // Eject pAI device + var/turf/T = get_turf_or_move(pda.loc) + if(T) + pda.pai.loc = T + pda.pai = null + +/datum/data/pda/app/notekeeper + name = "Notekeeper" + icon = "sticky-note-o" + template = "pda_notekeeper" + + var/note = null + var/notehtml = "" + +/datum/data/pda/app/notekeeper/start() + . = ..() + if(!note) + note = "Congratulations, your station has chosen the [pda.model_name]!" + +/datum/data/pda/app/notekeeper/update_ui(mob/user as mob, list/data) + data["note"] = note // current pda notes + +/datum/data/pda/app/notekeeper/Topic(href, list/href_list) + switch(href_list["choice"]) + if("Edit") + var/n = input("Please enter message", name, notehtml) as message + if(pda.loc == usr) + note = adminscrub(n) + notehtml = html_decode(note) + note = replacetext(note, "\n", "
    ") + else + pda.close(usr) + +/datum/data/pda/app/manifest + name = "Crew Manifest" + icon = "user" + template = "pda_manifest" + update = PDA_APP_UPDATE_SLOW + +/datum/data/pda/app/manifest/update_ui(mob/user as mob, list/data) + data_core.get_manifest_json() + data["manifest"] = list("__json_cache" = ManifestJSON) + +/datum/data/pda/app/manifest/Topic(href, list/href_list) + +/datum/data/pda/app/atmos_scanner + name = "Atmospheric Scan" + icon = "fire" + template = "pda_atmos_scan" + category = "Utilities" + update = PDA_APP_UPDATE_SLOW + +/datum/data/pda/app/atmos_scanner/update_ui(mob/user as mob, list/data) + var/turf/T = get_turf(user.loc) + if(!isnull(T)) + var/datum/gas_mixture/environment = T.return_air() + + var/pressure = environment.return_pressure() + var/total_moles = environment.total_moles() + + if (total_moles) + var/o2_level = environment.oxygen/total_moles + var/n2_level = environment.nitrogen/total_moles + var/co2_level = environment.carbon_dioxide/total_moles + var/plasma_level = environment.toxins/total_moles + var/unknown_level = 1-(o2_level+n2_level+co2_level+plasma_level) + data["aircontents"] = list(\ + "pressure" = "[round(pressure,0.1)]",\ + "nitrogen" = "[round(n2_level*100,0.1)]",\ + "oxygen" = "[round(o2_level*100,0.1)]",\ + "carbon_dioxide" = "[round(co2_level*100,0.1)]",\ + "plasma" = "[round(plasma_level*100,0.01)]",\ + "other" = "[round(unknown_level, 0.01)]",\ + "temp" = "[round(environment.temperature-T0C,0.1)]",\ + "reading" = 1\ + ) + if(isnull(data["aircontents"])) + data["aircontents"] = list("reading" = 0) \ No newline at end of file diff --git a/code/modules/pda/messenger.dm b/code/modules/pda/messenger.dm new file mode 100644 index 00000000000..0cd76bb7796 --- /dev/null +++ b/code/modules/pda/messenger.dm @@ -0,0 +1,271 @@ +/datum/data/pda/app/messenger + name = "Messenger" + icon = "comments-o" + title = "SpaceMessenger V4.0.1" + template = "pda_messenger" + + var/silent = 0 //To beep or not to beep, that is the question + var/toff = 0 //If 1, messenger disabled + var/list/tnote[0] //Current Texts + var/last_text //No text spamming + var/list/ttone_sound = list("beep" = 'sound/machines/twobeep.ogg', + "boom" = 'sound/effects/explosionfar.ogg', + "slip" = 'sound/misc/slip.ogg', + "honk" = 'sound/items/bikehorn.ogg', + "SKREE" = 'sound/voice/shriek1.ogg', + "holy" = 'sound/items/PDA/ambicha4-short.ogg', + "xeno" = 'sound/voice/hiss1.ogg') + + var/m_hidden = 0 // Is the PDA hidden from the PDA list? + var/active_conversation = null // New variable that allows us to only view a single conversation. + var/list/conversations = list() // For keeping up with who we have PDA messsages from. + +/datum/data/pda/app/messenger/start() + . = ..() + set_new(0) + +/datum/data/pda/app/messenger/update_ui(mob/user as mob, list/data) + data["silent"] = silent // does the pda make noise when it receives a message? + data["toff"] = toff // is the messenger function turned off? + data["active_conversation"] = active_conversation // Which conversation are we following right now? + + var/convopdas[0] + var/pdas[0] + var/count = 0 + for(var/A in PDAs) + var/obj/item/device/pda/P = A + var/datum/data/pda/app/messenger/PM = P.find_program(/datum/data/pda/app/messenger) + + if (!P.owner || PM.toff || P == pda || PM.m_hidden) + continue + if(conversations.Find("\ref[P]")) + convopdas.Add(list(list("Name" = "[P]", "Reference" = "\ref[P]", "Detonate" = "[P.detonate]", "inconvo" = "1"))) + else + pdas.Add(list(list("Name" = "[P]", "Reference" = "\ref[P]", "Detonate" = "[P.detonate]", "inconvo" = "0"))) + count++ + + data["convopdas"] = convopdas + data["pdas"] = pdas + data["pda_count"] = count + + data["messagescount"] = tnote.len + data["messages"] = tnote + + has_back = active_conversation + if(active_conversation) + for(var/c in tnote) + if(c["target"] == active_conversation) + data["convo_name"] = sanitize(c["owner"]) + data["convo_job"] = sanitize(c["job"]) + break + + var/list/plugins = list() + if(pda.cartridge) + for(var/A in pda.cartridge.messenger_plugins) + var/datum/data/pda/messenger_plugin/P = A + plugins += list(list(name = P.name, icon = P.icon, ref = "\ref[P]")) + data["plugins"] = plugins + + if(pda.cartridge) + data["charges"] = pda.cartridge.charges ? pda.cartridge.charges : 0 + +/datum/data/pda/app/messenger/Topic(href, list/href_list) + set_new(0) + + switch(href_list["choice"]) + if("Toggle Messenger") + toff = !toff + if("Toggle Ringer")//If viewing texts then erase them, if not then toggle silent status + silent = !silent + if("Clear")//Clears messages + if(href_list["option"] == "All") + tnote.Cut() + conversations.Cut() + if(href_list["option"] == "Convo") + var/new_tnote[0] + for(var/i in tnote) + if(i["target"] != active_conversation) + new_tnote[++new_tnote.len] = i + tnote = new_tnote + conversations.Remove(active_conversation) + + active_conversation = null + if("Ringtone") + var/t = input("Please enter new ringtone", name, pda.ttone) as text + if (in_range(pda, usr) && pda.loc == usr) + if (t) + if(pda.hidden_uplink && pda.hidden_uplink.check_trigger(usr, lowertext(t), lowertext(pda.lock_code))) + usr << "The PDA softly beeps." + pda.close(usr) + else + t = sanitize(copytext(t, 1, 20)) + pda.ttone = t + else + pda.close(usr) + return 0 + if("Message") + var/obj/item/device/pda/P = locate(href_list["target"]) + create_message(usr, P) + if(href_list["target"] in conversations) // Need to make sure the message went through, if not welp. + active_conversation = href_list["target"] + if("Select Conversation") + var/P = href_list["convo"] + for(var/n in conversations) + if(P == n) + active_conversation = P + if("Messenger Plugin") + if(!href_list["target"] || !href_list["plugin"]) + return + + var/obj/item/device/pda/P = locate(href_list["target"]) + if(!P) + usr << "PDA not found." + + var/datum/data/pda/messenger_plugin/plugin = locate(href_list["plugin"]) + if(plugin && plugin in pda.cartridge.messenger_plugins) + plugin.messenger = src + plugin.user_act(usr, P) + if("Back") + active_conversation = null + +/datum/data/pda/app/messenger/proc/set_new(isnew) + if(pda.newmessage == isnew) + return + + if(pda.newmessage) + //To clear message overlays. + pda.overlays.Cut() + pda.newmessage = 0 + + icon = "comments" + pda.update_shortcuts() + else + pda.overlays.Cut() + pda.overlays += image('icons/obj/pda.dmi', "pda-r") + pda.newmessage = 1 + + icon = "comments-o" + pda.update_shortcuts() + +/datum/data/pda/app/messenger/proc/create_message(var/mob/living/U, var/obj/item/device/pda/P) + var/t = input(U, "Please enter message", name, null) as text|null + if(!t) + return + t = sanitize(copytext(t, 1, MAX_MESSAGE_LEN)) + t = readd_quotes(t) + if (!t || !istype(P)) + return + if (!in_range(pda, U) && pda.loc != U) + return + + var/datum/data/pda/app/messenger/PM = P.find_program(/datum/data/pda/app/messenger) + + if (!PM || PM.toff || toff) + return + + if (last_text && world.time < last_text + 5) + return + + if(!pda.can_use()) + return + + last_text = world.time + // check if telecomms I/O route 1459 is stable + //var/telecomms_intact = telecomms_process(P.owner, owner, t) + var/obj/machinery/message_server/useMS = null + if(message_servers) + for(var/A in message_servers) + var/obj/machinery/message_server/MS = A + //PDAs are now dependent on the Message Server. + if(MS.active) + useMS = MS + break + + var/datum/signal/signal = pda.telecomms_process() + + var/useTC = 0 + if(signal) + if(signal.data["done"]) + useTC = 1 + var/turf/pos = get_turf(P) + if(pos.z in signal.data["level"]) + useTC = 2 + //Let's make this barely readable + if(signal.data["compression"] > 0) + t = Gibberish(t, signal.data["compression"] + 50) + + if(useMS && useTC) // only send the message if it's stable + if(useTC != 2) // Does our recipient have a broadcaster on their level? + U << "ERROR: Cannot reach recipient." + return + useMS.send_pda_message("[P.owner]","[pda.owner]","[t]") + tnote.Add(list(list("sent" = 1, "owner" = "[P.owner]", "job" = "[P.ownjob]", "message" = "[t]", "target" = "\ref[P]"))) + PM.tnote.Add(list(list("sent" = 0, "owner" = "[pda.owner]", "job" = "[pda.ownjob]", "message" = "[t]", "target" = "\ref[pda]"))) + pda.investigate_log("PDA Message - [U.key] - [pda.owner] -> [P.owner]: [t]", "pda") + if(!conversations.Find("\ref[P]")) + conversations.Add("\ref[P]") + if(!PM.conversations.Find("\ref[pda]")) + PM.conversations.Add("\ref[pda]") + + PM.play_ringtone() + //Search for holder of the PDA. + var/mob/living/L = null + if(P.loc && isliving(P.loc)) + L = P.loc + //Maybe they are a pAI! + else + L = get(P, /mob/living/silicon) + + + if(L) + L << "\icon[P] Message from [pda.owner] ([pda.ownjob]), \"[t]\" (Reply)" + nanomanager.update_user_uis(L, P) // Update the receiving user's PDA UI so that they can see the new message + + nanomanager.update_user_uis(U, P) // Update the sending user's PDA UI so that they can see the new message + set_new(1) + log_pda("[usr] (PDA: [src.name]) sent \"[t]\" to [P.name]") + else + U << "ERROR: Messaging server is not responding." + +/datum/data/pda/app/messenger/proc/play_ringtone() + if (!silent) + var/S + + if(pda.ttone in ttone_sound) + S = ttone_sound[pda.ttone] + else + S = 'sound/machines/twobeep.ogg' + playsound(pda.loc, S, 50, 1) + for(var/mob/O in hearers(3, pda.loc)) + if(!silent) + O.show_message(text("\icon[pda] *[pda.ttone]*")) + +/datum/data/pda/app/messenger/proc/available_pdas() + var/list/names = list() + var/list/plist = list() + var/list/namecounts = list() + + if (toff) + usr << "Turn on your receiver in order to send messages." + return + + for(var/A in PDAs) + var/obj/item/device/pda/P = A + var/datum/data/pda/app/messenger/PM = P.find_program(/datum/data/pda/app/messenger) + + if(!P.owner || !PM || PM.hidden || P == pda || PM.toff) + continue + + var/name = P.owner + if (name in names) + namecounts[name]++ + name = text("[name] ([namecounts[name]])") + else + names.Add(name) + namecounts[name] = 1 + + plist[text("[name]")] = P + return plist + +/datum/data/pda/app/messenger/proc/can_receive() + return pda.owner && !toff && !hidden \ No newline at end of file diff --git a/code/modules/pda/messenger_plugins.dm b/code/modules/pda/messenger_plugins.dm new file mode 100644 index 00000000000..ed4d330fdba --- /dev/null +++ b/code/modules/pda/messenger_plugins.dm @@ -0,0 +1,69 @@ +/datum/data/pda/messenger_plugin + var/datum/data/pda/app/messenger/messenger + +/datum/data/pda/messenger_plugin/proc/user_act(mob/user as mob, obj/item/device/pda/P) + + +/datum/data/pda/messenger_plugin/virus + name = "*Send Virus*" + +/datum/data/pda/messenger_plugin/virus/user_act(mob/user as mob, obj/item/device/pda/P) + var/datum/data/pda/app/messenger/M = P.find_program(/datum/data/pda/app/messenger) + + if(M && !M.toff && pda.cartridge.charges > 0) + pda.cartridge.charges-- + return 1 + return 0 + + +/datum/data/pda/messenger_plugin/virus/clown + icon = "star" + +/datum/data/pda/messenger_plugin/virus/clown/user_act(mob/user as mob, obj/item/device/pda/P) + . = ..(user, P) + if(.) + user.show_message("Virus sent!", 1) + P.honkamt = (rand(15,20)) + P.ttone = "honk" + + +/datum/data/pda/messenger_plugin/virus/mime + icon = "arrow-circle-down" + +/datum/data/pda/messenger_plugin/virus/mime/user_act(mob/user as mob, obj/item/device/pda/P) + . = ..(user, P) + if(.) + user.show_message("Virus sent!", 1) + var/datum/data/pda/app/messenger/M = P.find_program(/datum/data/pda/app/messenger) + if(M) + M.silent = 1 + P.ttone = "silence" + + +/datum/data/pda/messenger_plugin/virus/detonate + name = "*Detonate*" + icon = "exclamation-circle" + +/datum/data/pda/messenger_plugin/virus/detonate/user_act(mob/user as mob, obj/item/device/pda/P) + . = ..(user, P) + if(.) + var/difficulty = 0 + + if(pda.cartridge) + difficulty += pda.cartridge.programs.len / 2 + else + difficulty += 2 + + if(prob(difficulty * 12) || (pda.hidden_uplink)) + user.show_message("An error flashes on your [pda].", 1) + else if (prob(difficulty * 3)) + user.show_message("Energy feeds back into your [pda]!", 1) + pda.close(user) + pda.explode() + log_admin("[key_name(user)] just attempted to blow up [P] with the Detomatix cartridge but failed, blowing themselves up") + message_admins("[key_name_admin(user)] just attempted to blow up [P] with the Detomatix cartridge but failed, blowing themselves up", 1) + else + user.show_message("Success!", 1) + log_admin("[key_name(user)] just attempted to blow up [P] with the Detomatix cartridge and succeded") + message_admins("[key_name_admin(user)] just attempted to blow up [P] with the Detomatix cartridge and succeded", 1) + P.explode() \ No newline at end of file diff --git a/code/modules/pda/pdas.dm b/code/modules/pda/pdas.dm new file mode 100644 index 00000000000..1e15144c5fd --- /dev/null +++ b/code/modules/pda/pdas.dm @@ -0,0 +1,196 @@ +/obj/item/device/pda/medical + default_cartridge = /obj/item/weapon/cartridge/medical + icon_state = "pda-medical" + +/obj/item/device/pda/viro + default_cartridge = /obj/item/weapon/cartridge/medical + icon_state = "pda-virology" + +/obj/item/device/pda/engineering + default_cartridge = /obj/item/weapon/cartridge/engineering + icon_state = "pda-engineer" + +/obj/item/device/pda/security + default_cartridge = /obj/item/weapon/cartridge/security + icon_state = "pda-security" + +/obj/item/device/pda/detective + default_cartridge = /obj/item/weapon/cartridge/detective + icon_state = "pda-security" + +/obj/item/device/pda/warden + default_cartridge = /obj/item/weapon/cartridge/security + icon_state = "pda-warden" + +/obj/item/device/pda/janitor + default_cartridge = /obj/item/weapon/cartridge/janitor + icon_state = "pda-janitor" + ttone = "slip" + +/obj/item/device/pda/toxins + default_cartridge = /obj/item/weapon/cartridge/signal/toxins + icon_state = "pda-science" + ttone = "boom" + +/obj/item/device/pda/clown + default_cartridge = /obj/item/weapon/cartridge/clown + icon_state = "pda-clown" + desc = "A portable microcomputer by Thinktronic Systems, LTD. The surface is coated with polytetrafluoroethylene and banana drippings." + ttone = "honk" + +/obj/item/device/pda/clown/Crossed(AM as mob|obj) //Clown PDA is slippery. + if (istype(AM, /mob/living/carbon)) + var/mob/living/carbon/M = AM + M.slip("pda", 8, 5, 0, 1) + +/obj/item/device/pda/mime + default_cartridge = /obj/item/weapon/cartridge/mime + icon_state = "pda-mime" + ttone = "silence" + +/obj/item/device/pda/mime/New() + ..() + var/datum/data/pda/app/messenger/M = find_program(/datum/data/pda/app/messenger) + if(M) + M.silent = 1 + +/obj/item/device/pda/heads + default_cartridge = /obj/item/weapon/cartridge/head + icon_state = "pda-h" + +/obj/item/device/pda/heads/hop + default_cartridge = /obj/item/weapon/cartridge/hop + icon_state = "pda-hop" + +/obj/item/device/pda/heads/hos + default_cartridge = /obj/item/weapon/cartridge/hos + icon_state = "pda-hos" + +/obj/item/device/pda/heads/ce + default_cartridge = /obj/item/weapon/cartridge/ce + icon_state = "pda-ce" + +/obj/item/device/pda/heads/cmo + default_cartridge = /obj/item/weapon/cartridge/cmo + icon_state = "pda-cmo" + +/obj/item/device/pda/heads/rd + default_cartridge = /obj/item/weapon/cartridge/rd + icon_state = "pda-rd" + +/obj/item/device/pda/captain + default_cartridge = /obj/item/weapon/cartridge/captain + icon_state = "pda-captain" + detonate = 0 + //toff = 1 + +/obj/item/device/pda/heads/ntrep + default_cartridge = /obj/item/weapon/cartridge/supervisor + icon_state = "pda-h" + +/obj/item/device/pda/heads/magistrate + default_cartridge = /obj/item/weapon/cartridge/supervisor + icon_state = "pda-h" + +/obj/item/device/pda/heads/blueshield + default_cartridge = /obj/item/weapon/cartridge/hos + icon_state = "pda-h" + +/obj/item/device/pda/cargo + default_cartridge = /obj/item/weapon/cartridge/quartermaster + icon_state = "pda-cargo" + +/obj/item/device/pda/quartermaster + default_cartridge = /obj/item/weapon/cartridge/quartermaster + icon_state = "pda-qm" + +/obj/item/device/pda/shaftminer + icon_state = "pda-miner" + +/obj/item/device/pda/syndicate + default_cartridge = /obj/item/weapon/cartridge/syndicate + icon_state = "pda-syndi" + name = "Military PDA" + owner = "John Doe" + +/obj/item/device/pda/syndicate/New() + ..() + var/datum/data/pda/app/messenger/M = find_program(/datum/data/pda/app/messenger) + if(M) + M.m_hidden = 1 + +/obj/item/device/pda/chaplain + icon_state = "pda-chaplain" + ttone = "holy" + +/obj/item/device/pda/lawyer + default_cartridge = /obj/item/weapon/cartridge/lawyer + icon_state = "pda-lawyer" + ttone = "..." + +/obj/item/device/pda/botanist + //default_cartridge = /obj/item/weapon/cartridge/botanist + icon_state = "pda-hydro" + +/obj/item/device/pda/roboticist + icon_state = "pda-roboticist" + +/obj/item/device/pda/librarian + icon_state = "pda-library" + desc = "A portable microcomputer by Thinktronic Systems, LTD. This is model is a WGW-11 series e-reader." + model_name = "Thinktronic 5290 WGW-11 Series E-reader and Personal Data Assistant" + +/obj/item/device/pda/librarian/New() + ..() + var/datum/data/pda/app/messenger/M = find_program(/datum/data/pda/app/messenger) + if(M) + M.silent = 1 //Quiet in the library! + +/obj/item/device/pda/clear + icon_state = "pda-transp" + desc = "A portable microcomputer by Thinktronic Systems, LTD. This is model is a special edition with a transparent case." + model_name = "Thinktronic 5230 Personal Data Assistant Deluxe Special Max Turbo Limited Edition" + +/obj/item/device/pda/chef + icon_state = "pda-chef" + +/obj/item/device/pda/bar + icon_state = "pda-bartender" + +/obj/item/device/pda/atmos + default_cartridge = /obj/item/weapon/cartridge/atmos + icon_state = "pda-atmos" + +/obj/item/device/pda/chemist + default_cartridge = /obj/item/weapon/cartridge/chemistry + icon_state = "pda-chemistry" + +/obj/item/device/pda/geneticist + default_cartridge = /obj/item/weapon/cartridge/medical + icon_state = "pda-genetics" + +/obj/item/device/pda/centcom + default_cartridge = /obj/item/weapon/cartridge/centcom + icon_state = "pda-h" + +//Some spare PDAs in a box +/obj/item/weapon/storage/box/PDAs + name = "spare PDAs" + desc = "A box of spare PDA microcomputers." + icon = 'icons/obj/pda.dmi' + icon_state = "pdabox" + +/obj/item/weapon/storage/box/PDAs/New() + ..() + new /obj/item/device/pda(src) + new /obj/item/device/pda(src) + new /obj/item/device/pda(src) + new /obj/item/device/pda(src) + new /obj/item/weapon/cartridge/head(src) + + var/newcart = pick( /obj/item/weapon/cartridge/engineering, + /obj/item/weapon/cartridge/security, + /obj/item/weapon/cartridge/medical, + /obj/item/weapon/cartridge/signal/toxins, + /obj/item/weapon/cartridge/quartermaster) + new newcart(src) \ No newline at end of file diff --git a/code/game/objects/items/devices/PDA/radio.dm b/code/modules/pda/radio.dm similarity index 77% rename from code/game/objects/items/devices/PDA/radio.dm rename to code/modules/pda/radio.dm index 3e180a5c700..02a5dc996e2 100644 --- a/code/game/objects/items/devices/PDA/radio.dm +++ b/code/modules/pda/radio.dm @@ -26,6 +26,7 @@ /obj/item/radio/integrated/Destroy() if(radio_controller) radio_controller.remove_object(src, control_freq) + hostpda = null return ..() /obj/item/radio/integrated/proc/post_signal(var/freq, var/key, var/value, var/key2, var/value2, var/key3, var/value3,var/key4, var/value4, s_filter) @@ -49,8 +50,6 @@ frequency.post_signal(src, signal, filter = s_filter) - return - /obj/item/radio/integrated/receive_signal(datum/signal/signal) /*var/obj/item/device/pda/P = src.loc @@ -79,22 +78,26 @@ if("control") active = locate(href_list["bot"]) - post_signal(control_freq, "command", "bot_status", "active", active, s_filter = bot_filter) + spawn(0) + post_signal(control_freq, "command", "bot_status", "active", active, s_filter = bot_filter) if("scanbots") // find all bots botlist = null - post_signal(control_freq, "command", "bot_status", s_filter = bot_filter) + spawn(0) + post_signal(control_freq, "command", "bot_status", s_filter = bot_filter) if("botlist") active = null if("stop", "go") - 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) + 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) if("summon") - post_signal(control_freq, "command", "summon", "active", active, "target", get_turf(PDA) , "useraccess", PDA.GetAccess(), s_filter = bot_filter) - post_signal(control_freq, "command", "bot_status", "active", active, s_filter = bot_filter) + spawn(0) + post_signal(control_freq, "command", "summon", "active", active, "target", get_turf(PDA) , "useraccess", PDA.GetAccess(), s_filter = bot_filter) + post_signal(control_freq, "command", "bot_status", "active", active, s_filter = bot_filter) /obj/item/radio/integrated/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(radio_controller) @@ -147,13 +150,6 @@ // create/populate lists as they are recvd /obj/item/radio/integrated/mule/receive_signal(datum/signal/signal) -// var/obj/item/device/pda/P = src.loc - - /* - world << "recvd:[P] : [signal.source]" - for(var/d in signal.data) - world << "- [d] = [signal.data[d]]" - */ if(signal.data["type"] == MULE_BOT) if(!botlist) botlist = new() @@ -171,9 +167,6 @@ beacons[signal.data["beacon"] ] = signal.source - -// if(istype(P)) P.updateSelfDialog() - /obj/item/radio/integrated/mule/Topic(href, href_list) //..() //var/obj/item/device/pda/PDA = src.hostpda @@ -182,7 +175,6 @@ cmd = "command [active.suffix]" switch(href_list["op"]) - if("control") active = locate(href_list["bot"]) @@ -193,28 +185,37 @@ active = null if("unload") - post_signal(control_freq, cmd, "unload", s_filter = RADIO_MULEBOT) + spawn(0) + post_signal(control_freq, cmd, "unload", s_filter = RADIO_MULEBOT) if("setdest") if(beacons) var/dest = input("Select Bot Destination", "Mulebot [active.suffix] Interlink", active.destination) as null|anything in beacons if(dest) - post_signal(control_freq, cmd, "target", "destination", dest, s_filter = RADIO_MULEBOT) + spawn(0) + post_signal(control_freq, cmd, "target", "destination", dest, s_filter = RADIO_MULEBOT) if("retoff") - post_signal(control_freq, cmd, "autoret", "value", 0, s_filter = RADIO_MULEBOT) + spawn(0) + post_signal(control_freq, cmd, "autoret", "value", 0, s_filter = RADIO_MULEBOT) + if("reton") - post_signal(control_freq, cmd, "autoret", "value", 1, s_filter = RADIO_MULEBOT) + spawn(0) + post_signal(control_freq, cmd, "autoret", "value", 1, s_filter = RADIO_MULEBOT) if("pickoff") - post_signal(control_freq, cmd, "autopick", "value", 0, s_filter = RADIO_MULEBOT) + spawn(0) + post_signal(control_freq, cmd, "autopick", "value", 0, s_filter = RADIO_MULEBOT) if("pickon") - post_signal(control_freq, cmd, "autopick", "value", 1, s_filter = RADIO_MULEBOT) + spawn(0) + post_signal(control_freq, cmd, "autopick", "value", 1, s_filter = RADIO_MULEBOT) if("stop", "go", "home") - post_signal(control_freq, cmd, href_list["op"], s_filter = RADIO_MULEBOT) + spawn(0) + post_signal(control_freq, cmd, href_list["op"], s_filter = RADIO_MULEBOT) - post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT) + spawn(10) + post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT) @@ -262,6 +263,5 @@ signal.encryption = code signal.data["message"] = message - radio_connection.post_signal(src, signal) - - return \ No newline at end of file + spawn(0) + radio_connection.post_signal(src, signal) \ No newline at end of file diff --git a/code/modules/pda/utilities.dm b/code/modules/pda/utilities.dm new file mode 100644 index 00000000000..f86c234d6f9 --- /dev/null +++ b/code/modules/pda/utilities.dm @@ -0,0 +1,198 @@ +/datum/data/pda/utility/flashlight + name = "Enable Flashlight" + icon = "lightbulb-o" + + var/fon = 0 //Is the flashlight function on? + var/f_lum = 2 //Luminosity for the flashlight function + +/datum/data/pda/utility/flashlight/start() + fon = !fon + name = fon ? "Disable Flashlight" : "Enable Flashlight" + pda.update_shortcuts() + pda.set_light(fon ? f_lum : 0) + +/datum/data/pda/utility/honk + name = "Honk Synthesizer" + icon = "smile-o" + category = "Clown" + + var/last_honk //Also no honk spamming that's bad too + +/datum/data/pda/utility/honk/start() + if(!(last_honk && world.time < last_honk + 20)) + playsound(pda.loc, 'sound/items/bikehorn.ogg', 50, 1) + last_honk = world.time + +/datum/data/pda/utility/toggle_door + name = "Toggle Door" + icon = "external-link" + var/remote_door_id = "" + +/datum/data/pda/utility/toggle_door/start() + for(var/obj/machinery/door/poddoor/M in airlocks) + if(M.id_tag == remote_door_id) + if(M.density) + M.open() + else + M.close() + +/datum/data/pda/utility/scanmode/medical + base_name = "Med Scanner" + icon = "heart-o" + +/datum/data/pda/utility/scanmode/medical/scan_mob(mob/living/C as mob, mob/living/user as mob) + C.visible_message("[user] has analyzed [C]'s vitals!") + + user.show_message("Analyzing Results for [C]:") + user.show_message("\t Overall Status: [C.stat > 1 ? "dead" : "[C.health - C.halloss]% healthy"]", 1) + user.show_message("\t Damage Specifics: [C.getOxyLoss() > 50 ? "" : ""][C.getOxyLoss()]-[C.getToxLoss() > 50 ? "" : ""][C.getToxLoss()]-[C.getFireLoss() > 50 ? "" : ""][C.getFireLoss()]-[C.getBruteLoss() > 50 ? "" : ""][C.getBruteLoss()]", 1) + user.show_message("\t Key: Suffocation/Toxin/Burns/Brute", 1) + user.show_message("\t Body Temperature: [C.bodytemperature-T0C]°C ([C.bodytemperature*1.8-459.67]°F)", 1) + if(C.timeofdeath && (C.stat == DEAD || (C.status_flags & FAKEDEATH))) + user.show_message("\t Time of Death: [C.timeofdeath]") + if(istype(C, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = C + var/list/damaged = H.get_damaged_organs(1,1) + user.show_message("Localized Damage, Brute/Burn:",1) + if(length(damaged)>0) + for(var/obj/item/organ/external/org in damaged) + user.show_message("\t [capitalize(org.name)]: [org.brute_dam > 0 ? "[org.brute_dam]" : "0"]-[org.burn_dam > 0 ? "[org.burn_dam]" : "0"]", 1) + else + user.show_message("\t Limbs are OK.",1) + +/datum/data/pda/utility/scanmode/dna + base_name = "DNA Scanner" + icon = "link" + +/datum/data/pda/utility/scanmode/dna/scan_mob(mob/living/C as mob, mob/living/user as mob) + if(istype(C, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = C + if (!istype(H.dna, /datum/dna)) + user << "No fingerprints found on [H]" + else + user << "[H]'s Fingerprints: [md5(H.dna.uni_identity)]" + scan_blood(C, user) + +/datum/data/pda/utility/scanmode/dna/scan_atom(atom/A as mob|obj|turf|area, mob/user as mob) + scan_blood(A, user) + +/datum/data/pda/utility/scanmode/dna/proc/scan_blood(atom/A, mob/user) + if (!A.blood_DNA) + user << "No blood found on [A]" + if(A.blood_DNA) + qdel(A.blood_DNA) + else + user << "Blood found on [A]. Analysing..." + spawn(15) + for(var/blood in A.blood_DNA) + user << "Blood type: [A.blood_DNA[blood]]\nDNA: [blood]" + +/datum/data/pda/utility/scanmode/halogen + base_name = "Halogen Counter" + icon = "exclamation-circle" + +/datum/data/pda/utility/scanmode/halogen/scan_mob(mob/living/C as mob, mob/living/user as mob) + C.visible_message("[user] has analyzed [C]'s radiation levels!") + + user.show_message("Analyzing Results for [C]:") + if(C.radiation) + user.show_message("Radiation Level: [C.radiation > 0 ? "[C.radiation]" : "0"]") + else + user.show_message("No radiation detected.") + +/datum/data/pda/utility/scanmode/reagent + base_name = "Reagent Scanner" + icon = "flask" + +/datum/data/pda/utility/scanmode/reagent/scan_atom(atom/A as mob|obj|turf|area, mob/user as mob) + if(!isnull(A.reagents)) + if(A.reagents.reagent_list.len > 0) + var/reagents_length = A.reagents.reagent_list.len + user << "[reagents_length] chemical agent[reagents_length > 1 ? "s" : ""] found." + for(var/re in A.reagents.reagent_list) + user << "\t [re]" + else + user << "No active chemical agents found in [A]." + else + user << "No significant chemical agents found in [A]." + +/datum/data/pda/utility/scanmode/gas + base_name = "Gas Scanner" + icon = "tachometer" + +/datum/data/pda/utility/scanmode/gas/scan_atom(atom/A as mob|obj|turf|area, mob/user as mob) + if (istype(A, /obj/item/weapon/tank)) + var/obj/item/weapon/tank/T = A + pda.atmosanalyzer_scan(T.air_contents, user, T) + else if (istype(A, /obj/machinery/portable_atmospherics)) + var/obj/machinery/portable_atmospherics/T = A + pda.atmosanalyzer_scan(T.air_contents, user, T) + else if (istype(A, /obj/machinery/atmospherics/pipe)) + var/obj/machinery/atmospherics/pipe/T = A + pda.atmosanalyzer_scan(T.parent.air, user, T) + else if (istype(A, /obj/machinery/power/rad_collector)) + var/obj/machinery/power/rad_collector/T = A + if(T.P) + pda.atmosanalyzer_scan(T.P.air_contents, user, T) + else if (istype(A, /obj/item/weapon/flamethrower)) + var/obj/item/weapon/flamethrower/T = A + if(T.ptank) + pda.atmosanalyzer_scan(T.ptank.air_contents, user, T) + else if (istype(A, /obj/machinery/portable_atmospherics/scrubber/huge)) + var/obj/machinery/portable_atmospherics/scrubber/huge/T = A + pda.atmosanalyzer_scan(T.air_contents, user, T) + else if (istype(A, /obj/machinery/atmospherics/unary/tank)) + var/obj/machinery/atmospherics/unary/tank/T = A + pda.atmosanalyzer_scan(T.air_contents, user, T) + +/datum/data/pda/utility/scanmode/notes + base_name = "Note Scanner" + icon = "clipboard" + var/datum/data/pda/app/notekeeper/notes + +/datum/data/pda/utility/scanmode/notes/start() + . = ..() + notes = pda.find_program(/datum/data/pda/app/notekeeper) + +/datum/data/pda/utility/scanmode/notes/scan_atom(atom/A as mob|obj|turf|area, mob/user as mob) + if(notes && istype(A, /obj/item/weapon/paper)) + var/obj/item/weapon/paper/P = A + + // JMO 20140705: Makes scanned document show up properly in the notes. Not pretty for formatted documents, + // as this will clobber the HTML, but at least it lets you scan a document. You can restore the original + // notes by editing the note again. (Was going to allow you to edit, but scanned documents are too long.) + var/raw_scan = P.info + var/formatted_scan = "" + // Scrub out the tags (replacing a few formatting ones along the way) + // Find the beginning and end of the first tag. + var/tag_start = findtext(raw_scan, "<") + var/tag_stop = findtext(raw_scan, ">") + // Until we run out of complete tags... + while(tag_start && tag_stop) + var/pre = copytext(raw_scan, 1, tag_start) // Get the stuff that comes before the tag + var/tag = lowertext(copytext(raw_scan, tag_start + 1, tag_stop)) // Get the tag so we can do intellegent replacement + var/tagend = findtext(tag, " ") // Find the first space in the tag if there is one. + // Anything that's before the tag can just be added as is. + formatted_scan = formatted_scan + pre + // If we have a space after the tag (and presumably attributes) just crop that off. + if(tagend) + tag = copytext(tag, 1, tagend) + if(tag == "p" || tag == "/p" || tag == "br") // Check if it's I vertical space tag. + formatted_scan = formatted_scan + "
    " // If so, add some padding in. + raw_scan = copytext(raw_scan, tag_stop + 1) // continue on with the stuff after the tag + // Look for the next tag in what's left + tag_start = findtext(raw_scan, "<") + tag_stop = findtext(raw_scan, ">") + // Anything that is left in the page. just tack it on to the end as is + formatted_scan = formatted_scan + raw_scan + // If there is something in there already, pad it out. + if(length(notes.note) > 0) + notes.note = notes.note + "

    " + // Store the scanned document to the notes + notes.note = "Scanned Document. Edit to restore previous notes/delete scan.
    ----------
    " + formatted_scan + "
    " + // notehtml ISN'T set to allow user to get their old notes back. A better implementation would add a "scanned documents" + // feature to the PDA, which would better convey the availability of the feature, but this will work for now. + // Inform the user + user << "Paper scanned and OCRed to notekeeper." //concept of scanning paper copyright brainoblivion 2009 + else + user << "Error scanning [A]." \ No newline at end of file diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index c9bbffdef63..22eaa83cf75 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -655,7 +655,7 @@ //Synthetic human mob goes here. if(istype(user,/mob/living/carbon/human)) var/mob/living/carbon/human/H = user - if(!isnull(H.internal_organs_by_name["cell"]) && H.a_intent == I_GRAB) + if(H.get_int_organ(/obj/item/organ/internal/cell) && H.a_intent == I_GRAB) if(emagged || stat & BROKEN) var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread s.set_up(3, 1, src) diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 15a85e6c738..6f04bf82a1a 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -186,7 +186,7 @@ continue // Where we're going, we don't need eyes. // Prosthetic eyes will also protect against this business. - var/obj/item/organ/eyes = l.internal_organs_by_name["eyes"] + var/obj/item/organ/internal/eyes/eyes = l.get_int_organ(/obj/item/organ/internal/eyes) if(!istype(eyes)) continue l.hallucination = max(0, min(200, l.hallucination + power * config_hallucination_power * sqrt( 1 / max(1,get_dist(l, src)) ) ) ) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index c1eb0f1ebee..bc96891cd4d 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -19,6 +19,7 @@ throw_range = 5 force = 5.0 origin_tech = "combat=1" + needs_permit = 1 attack_verb = list("struck", "hit", "bashed") var/fire_sound = 'sound/weapons/Gunshot.ogg' @@ -104,20 +105,24 @@ return if (!user.IsAdvancedToolUser() || istype(user, /mob/living/simple_animal/diona)) - user << "\red You don't have the dexterity to do this!" + user << "You don't have the dexterity to do this!" return if(istype(user, /mob/living)) var/mob/living/M = user if (HULK in M.mutations) - M << "\red Your meaty finger is much too large for the trigger guard!" + M << "Your meaty finger is much too large for the trigger guard!" return if(ishuman(user)) var/mob/living/carbon/human/H = user - if(H.species.name == "Golem") - user << "\red Your metal fingers don't fit in the trigger guard!" + if(H.get_species() == "Golem") + user << "Your metal fingers don't fit in the trigger guard!" return - if(user.dna && user.dna.species == "Shadowling") + if(H.get_species() == "Shadowling") user << "The muzzle flash would cause damage to your form!" + return + if(H.martial_art && H.martial_art.name == "The Sleeping Carp") //great dishonor to famiry + user << "Use of ranged weaponry would bring dishonor to the clan." + return add_fingerprint(user) diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index ed4ca6eeeed..2c0eb581bde 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -15,6 +15,7 @@ desc = "A modified version of the basic laser gun, this one fires less concentrated energy bolts designed for target practice." projectile_type = "/obj/item/projectile/practice" clumsy_check = 0 + needs_permit = 0 obj/item/weapon/gun/energy/laser/retro name ="retro laser gun" @@ -97,6 +98,15 @@ obj/item/weapon/gun/energy/laser/retro projectile_type = "/obj/item/projectile/beam/xray" charge_cost = 500 +/obj/item/weapon/gun/energy/immolator + name = "Immolator laser gun" + desc = "A modified laser gun, shooting highly concetrated beams with higher intensity that ignites the target, for the cost of draining more power per shot" + icon_state = "immolator" + item_state = "laser" + fire_sound = 'sound/weapons/laser3.ogg' + projectile_type = "/obj/item/projectile/beam/immolator" + origin_tech = "combat=4;materials=4;magnets=3;plasmatech=2" + charge_cost = 1250 ////////Laser Tag//////////////////// @@ -107,6 +117,7 @@ obj/item/weapon/gun/energy/laser/retro projectile_type = "/obj/item/projectile/lasertag/blue" origin_tech = "combat=1;magnets=2" clumsy_check = 0 + needs_permit = 0 self_recharge = 1 @@ -124,6 +135,7 @@ obj/item/weapon/gun/energy/laser/retro projectile_type = "/obj/item/projectile/lasertag/red" origin_tech = "combat=1;magnets=2" clumsy_check = 0 + needs_permit = 0 self_recharge = 1 diff --git a/code/modules/projectiles/guns/energy/pulse.dm b/code/modules/projectiles/guns/energy/pulse.dm index e063a6b3bdf..ffb075c8c34 100644 --- a/code/modules/projectiles/guns/energy/pulse.dm +++ b/code/modules/projectiles/guns/energy/pulse.dm @@ -47,7 +47,7 @@ var/mob/living/silicon/robot/R = src.loc if(R && R.cell) R.cell.use(charge_cost) - in_chamber = new/obj/item/projectile/beam(src) + in_chamber = new projectile_type(src) return 1 return 0 diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index d88e540adf3..7093eb7202a 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -41,6 +41,7 @@ origin_tech = "materials=2;biotech=3;powerstorage=3" modifystate = "floramut" var/mode = 0 //0 = mutate, 1 = yield boost + needs_permit = 0 self_recharge = 1 @@ -202,17 +203,15 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. fire_sound = 'sound/weapons/Kenetic_accel.ogg' charge_cost = 5000 cell_type = "/obj/item/weapon/stock_parts/cell/emproof" + needs_permit = 0 // Aparently these are safe to carry? I'm sure Golliaths would disagree. fire_delay = 16 //Because guncode is bad and you can bug the reload for rapid fire otherwise. - var/overheat = 0 - var/overheat_time = 16 - var/recent_reload = 1 + var/recently_fired = 0 /obj/item/weapon/gun/energy/kinetic_accelerator/super name = "super-kinetic accelerator" desc = "An upgraded, superior version of the proto-kinetic accelerator." icon_state = "kineticgun_u" projectile_type = "/obj/item/projectile/kinetic/super" - overheat_time = 15 fire_delay = 15 origin_tech = "combat=3;powerstorage=2" @@ -221,7 +220,6 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. desc = "An upgraded, even more superior version of the proto-kinetic accelerator." icon_state = "kineticgun_h" projectile_type = "/obj/item/projectile/kinetic/hyper" - overheat_time = 13 fire_delay = 13 origin_tech = "combat=4;powerstorage=3" @@ -229,26 +227,23 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. flags = NODROP /obj/item/weapon/gun/energy/kinetic_accelerator/Fire() - overheat = 1 - spawn(overheat_time) - overheat = 0 - recent_reload = 0 + if(!recently_fired) + recently_fired = 1 + spawn(fire_delay) + reload(usr) ..() /obj/item/weapon/gun/energy/kinetic_accelerator/emp_act(severity) return -/obj/item/weapon/gun/energy/kinetic_accelerator/attack_self(var/mob/living/user/L) - if(overheat || recent_reload) - return +/obj/item/weapon/gun/energy/kinetic_accelerator/proc/reload(mob/living/user) power_supply.give(5000) if(!silenced) playsound(src.loc, 'sound/weapons/kenetic_reload.ogg', 60, 1) - else + else if(user) usr << "You silently charge [src]." - recent_reload = 1 + recently_fired = 0 update_icon() - return /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow name = "mini energy crossbow" @@ -261,7 +256,6 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. silenced = 1 projectile_type = "/obj/item/projectile/energy/bolt" fire_sound = 'sound/weapons/Genhit.ogg' - overheat_time = 20 fire_delay = 20 /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow/large diff --git a/code/modules/projectiles/guns/mounted.dm b/code/modules/projectiles/guns/mounted.dm new file mode 100644 index 00000000000..d0e023d0d6d --- /dev/null +++ b/code/modules/projectiles/guns/mounted.dm @@ -0,0 +1,31 @@ +/obj/item/weapon/gun/energy/advtaser/mounted + name = "mounted taser" + desc = "An arm mounted dual-mode weapon that fires electrodes and disabler shots." + icon_state = "armcannonstun" + item_state = "armcannonstun" + modifystate = "armcannonstun" + force = 5 + self_recharge = 1 + flags = NODROP + slot_flags = null + w_class = 5.0 + can_flashlight = 0 + +/obj/item/weapon/gun/energy/advtaser/mounted/dropped()//if somebody manages to drop this somehow... + src.loc = null//send it to nullspace to get retrieved by the implant later on. gotta cover those edge cases. + +/obj/item/weapon/gun/energy/laser/mounted + name = "mounted laser" + desc = "An arm mounted cannon that fires lethal lasers. Doesn't come with a charge beam." + icon_state = "armcannonlase" + item_state = "armcannonlase" + modifystate = "armcannonlase" + force = 5 + self_recharge = 1 + flags = NODROP + slot_flags = null + w_class = 5.0 + materials = null + +/obj/item/weapon/gun/energy/laser/mounted/dropped() + src.loc = null \ No newline at end of file diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index cbe75d884ef..319633e6277 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -38,6 +38,17 @@ weaken = 5 stutter = 5 + +/obj/item/projectile/beam/immolator + name = "immolation beam" + +/obj/item/projectile/beam/immolator/on_hit(var/atom/target, var/blocked = 0) + . = ..() + if(istype(target, /mob/living/carbon)) + var/mob/living/carbon/M = target + M.adjust_fire_stacks(1) + M.IgniteMob() + /obj/item/projectile/beam/xray name = "xray beam" icon_state = "xray" diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index a89f4e4b1f7..95ee1616972 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -101,14 +101,14 @@ if(..(target, blocked)) var/mob/living/M = target M.dizziness += 20 - M:slurring += 20 + M.slurring += 20 M.confused += 20 M.eye_blurry += 20 M.drowsyness += 20 for(var/datum/reagent/ethanol/A in M.reagents.reagent_list) - M.paralysis += 2 + M.AdjustParalysis(2) M.dizziness += 10 - M:slurring += 10 + M.slurring += 10 M.confused += 10 M.eye_blurry += 10 M.drowsyness += 10 diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index 91ae6fa24bf..ed64d73df4e 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -94,8 +94,7 @@ M.bodytemperature = temperature if(temperature > 500)//emagged M.adjust_fire_stacks(0.5) - M.on_fire = 1 - M.update_icon = 1 + M.IgniteMob() playsound(M.loc, 'sound/effects/bamf.ogg', 50, 0) return 1 diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm index f9c8dead1b8..5fe33d73b03 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/Chemistry-Machinery.dm @@ -578,7 +578,7 @@ if (count <= 0) return var/amount_per_pill = reagents.total_volume/count if (amount_per_pill > 50) amount_per_pill = 50 - var/name = input(usr,"Name:","Name your pill!","[reagents.get_master_reagent_name()] ([amount_per_pill] units)") as text|null + var/name = input(usr,"Name:","Name your pill!","[reagents.get_master_reagent_name()] ([amount_per_pill]u)") as text|null if(!name) return name = reject_bad_text(name) @@ -618,7 +618,7 @@ if (count > 20) count = 20 //Pevent people from creating huge stacks of patches easily. Maybe move the number to defines? var/amount_per_patch = reagents.total_volume/count if (amount_per_patch > 40) amount_per_patch = 40 - var/name = input(usr,"Name:","Name your patch!","[reagents.get_master_reagent_name()] ([amount_per_patch] units)") as text|null + var/name = input(usr,"Name:","Name your patch!","[reagents.get_master_reagent_name()] ([amount_per_patch]u)") as text|null if(!name) return name = reject_bad_text(name) diff --git a/code/modules/reagents/newchem/drinks.dm b/code/modules/reagents/newchem/drinks.dm index 637b101f32d..28237207995 100644 --- a/code/modules/reagents/newchem/drinks.dm +++ b/code/modules/reagents/newchem/drinks.dm @@ -62,3 +62,91 @@ result = "jackrose" required_reagents = list("applejack" = 4, "lemonjuice" = 1) result_amount = 5 + + +// ROBOT ALCOHOL PAST THIS POINT +// WOOO! + + +/datum/reagent/ethanol/synthanol + name = "Synthanol" + id = "synthanol" + description = "A runny liquid with conductive capacities. Its effects on synthetics are similar to those of alcohol on organics." + reagent_state = LIQUID + color = "#1BB1FF" + process_flags = SYNTHETIC + metabolization_rate = 0.4 + vomit_start = INFINITY // + blur_start = INFINITY // + pass_out = INFINITY //INFINITY, so that IPCs don't puke and stuff + var/collapse_start = 200 //amount absorbed after wich mob starts collapsing + var/braindamage_start = 300 //amount absorbed after which mob starts taking small amount of brain damage + + +/datum/chemical_reaction/synthanol + name = "Synthanol" + id = "synthanol" + result = "synthanol" + required_reagents = list("lube" = 1, "plasma" = 1, "fuel" = 1) + result_amount = 3 + mix_message = "The chemicals mix to create shiny, blue substance." + +/datum/reagent/ethanol/synthanol/on_mob_life(var/mob/living/M as mob, var/alien) + + var/d = data + + if(d >= collapse_start && prob(10)) + M.emote("collapse") + var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread + s.set_up(3, 1, M) + s.start() + if(d >= braindamage_start && prob(33)) + M.adjustBrainLoss(1) + ..() + +/datum/reagent/ethanol/synthanol/robottears + name = "Robot Tears" + id = "robottears" + description = "An oily substance that an IPC could technically consider a 'drink'." + reagent_state = LIQUID + color = "#363636" + +/datum/chemical_reaction/synthanol/robottears + name = "Robot Tears" + id = "robottears" + result = "robottears" + required_reagents = list("synthanol" = 1, "oil" = 1, "sodawater" = 1) + result_amount = 3 + mix_message = "The ingredients combine into a stiff, dark goo." + +/datum/reagent/ethanol/synthanol/trinary + name = "Trinary" + id = "trinary" + description = "A fruit drink meant only for synthetics, however that works." + reagent_state = LIQUID + color = "#adb21f" + +/datum/chemical_reaction/synthanol/trinary + name = "Trinary" + id = "trinary" + result = "trinary" + required_reagents = list("synthanol" = 1, "limejuice" = 1, "orangejuice" = 1) + result_amount = 3 + mix_message = "The ingredients mix into a colorful substance." + +/datum/reagent/ethanol/synthanol/servo + name = "Servo" + id = "servo" + description = "A drink containing some organic ingredients, but meant only for synthetics." + reagent_state = LIQUID + color = "#5b3210" + +/datum/chemical_reaction/synthanol/servo + name = "Servo" + id = "servo" + result = "servo" + required_reagents = list("synthanol" = 2, "cream" = 1, "hot_coco" = 1) + result_amount = 4 + mix_message = "The ingredients mix into a dark brown substance." + +// ROBOT ALCOHOL ENDS diff --git a/code/modules/reagents/newchem/drugs.dm b/code/modules/reagents/newchem/drugs.dm index 69679560ef8..aac5157403e 100644 --- a/code/modules/reagents/newchem/drugs.dm +++ b/code/modules/reagents/newchem/drugs.dm @@ -165,6 +165,10 @@ addiction_threshold = 10 metabolization_rate = 0.6 +/datum/reagent/methamphetamine/meth2 //for donk pockets + id = "methamphetamine2" + addiction_threshold = 20 + /datum/reagent/methamphetamine/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom var/high_message = pick("You feel hyper.", "You feel like you need to go faster.", "You feel like you can run the world.") diff --git a/code/modules/reagents/newchem/food.dm b/code/modules/reagents/newchem/food.dm index 713672abb23..b0c0704cbb9 100644 --- a/code/modules/reagents/newchem/food.dm +++ b/code/modules/reagents/newchem/food.dm @@ -131,10 +131,12 @@ datum/reagent/honey/reaction_turf(var/turf/T, var/volume) id = "chocolate" description = "Chocolate is a delightful product derived from the seeds of the theobroma cacao tree." reagent_state = LIQUID + nutriment_factor = 5 * REAGENTS_METABOLISM //same as pure cocoa powder, because it makes no sense that chocolate won't fill you up and make you fat color = "#2E2418" /datum/reagent/chocolate/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom + M.nutrition += nutriment_factor M.reagents.add_reagent("sugar", 0.8) ..() return @@ -142,7 +144,7 @@ datum/reagent/honey/reaction_turf(var/turf/T, var/volume) /datum/reagent/chocolate/reaction_turf(var/turf/T, var/volume) src = null if(volume >= 5) - new /obj/item/weapon/reagent_containers/food/snacks/cocoa_pile(T) + new /obj/item/weapon/reagent_containers/food/snacks/choc_pile(T) return /datum/reagent/mugwort diff --git a/code/modules/reagents/newchem/medicine.dm b/code/modules/reagents/newchem/medicine.dm index 0e5c3fb88f5..f0b8c990aba 100644 --- a/code/modules/reagents/newchem/medicine.dm +++ b/code/modules/reagents/newchem/medicine.dm @@ -525,7 +525,7 @@ datum/reagent/oculine/on_mob_life(var/mob/living/M as mob) if(prob(80)) if(ishuman(M)) var/mob/living/carbon/human/H = M - var/obj/item/organ/eyes/E = H.internal_organs_by_name["eyes"] + var/obj/item/organ/internal/eyes/E = H.get_int_organ(/obj/item/organ/internal/eyes) if(istype(E)) E.damage = max(E.damage-1, 0) M.eye_blurry = max(M.eye_blurry-1 , 0) diff --git a/code/modules/reagents/newchem/toxins.dm b/code/modules/reagents/newchem/toxins.dm index d71be25ca55..a330b8f8b91 100644 --- a/code/modules/reagents/newchem/toxins.dm +++ b/code/modules/reagents/newchem/toxins.dm @@ -4,7 +4,7 @@ #define REM REAGENTS_EFFECT_MULTIPLIER -datum/reagent/polonium +/datum/reagent/polonium name = "Polonium" id = "polonium" description = "Cause significant Radiation damage over time." @@ -13,14 +13,14 @@ datum/reagent/polonium metabolization_rate = 0.1 penetrates_skin = 1 -datum/reagent/polonium/on_mob_life(var/mob/living/M as mob) +/datum/reagent/polonium/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom M.apply_effect(8, IRRADIATE, negate_armor = 1) ..() return -datum/reagent/histamine +/datum/reagent/histamine name = "Histamine" id = "histamine" description = "Immune-system neurotransmitter. If detected in blood, the subject is likely undergoing an allergic reaction." @@ -29,12 +29,12 @@ datum/reagent/histamine metabolization_rate = 0.2 overdose_threshold = 30 -datum/reagent/histamine/reaction_mob(var/mob/living/M as mob, var/method=TOUCH, var/volume) //dumping histamine on someone is VERY mean. +/datum/reagent/histamine/reaction_mob(var/mob/living/M as mob, var/method=TOUCH, var/volume) //dumping histamine on someone is VERY mean. if(iscarbon(M)) if(method == TOUCH) M.reagents.add_reagent("histamine",10) -datum/reagent/histamine/on_mob_life(var/mob/living/M as mob) +/datum/reagent/histamine/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom switch(pick(1, 2, 3, 4)) if(1) @@ -51,14 +51,14 @@ datum/reagent/histamine/on_mob_life(var/mob/living/M as mob) ..() return -datum/reagent/histamine/overdose_process(var/mob/living/M as mob) +/datum/reagent/histamine/overdose_process(var/mob/living/M as mob) M.adjustOxyLoss(pick(1,3)*REM) M.adjustBruteLoss(pick(1,3)*REM) M.adjustToxLoss(pick(1,3)*REM) ..() return -datum/reagent/formaldehyde +/datum/reagent/formaldehyde name = "Formaldehyde" id = "formaldehyde" description = "Formaldehyde is a common industrial chemical and is used to preserve corpses and medical samples. It is highly toxic and irritating." @@ -66,7 +66,7 @@ datum/reagent/formaldehyde color = "#DED6D0" penetrates_skin = 1 -datum/reagent/formaldehyde/on_mob_life(var/mob/living/M as mob) +/datum/reagent/formaldehyde/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom M.adjustToxLoss(1*REM) if(prob(10)) @@ -83,7 +83,7 @@ datum/reagent/formaldehyde/on_mob_life(var/mob/living/M as mob) min_temp = 420 mix_message = "Ugh, it smells like the morgue in here." -datum/reagent/venom +/datum/reagent/venom name = "Venom" id = "venom" description = "Will deal scaling amounts of Toxin and Brute damage over time. 25% chance to decay into 5-10 histamine." @@ -92,7 +92,7 @@ datum/reagent/venom metabolization_rate = 0.2 overdose_threshold = 40 -datum/reagent/venom/on_mob_life(var/mob/living/M as mob) +/datum/reagent/venom/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom M.adjustToxLoss(1*REM) M.adjustBruteLoss(1*REM) @@ -104,14 +104,14 @@ datum/reagent/venom/on_mob_life(var/mob/living/M as mob) ..() return -datum/reagent/venom/overdose_process(var/mob/living/M as mob) +/datum/reagent/venom/overdose_process(var/mob/living/M as mob) if(volume >= 40) if(prob(4)) M.gib() ..() return -datum/reagent/neurotoxin2 +/datum/reagent/neurotoxin2 name = "Neurotoxin" id = "neurotoxin2" description = "A dangerous toxin that attacks the nervous system." @@ -119,7 +119,7 @@ datum/reagent/neurotoxin2 color = "#60A584" metabolization_rate = 1 -datum/reagent/neurotoxin2/on_mob_life(var/mob/living/M as mob) +/datum/reagent/neurotoxin2/on_mob_life(var/mob/living/M as mob) if(current_cycle <= 4) M.reagents.add_reagent("neurotoxin2", 1.0) if(current_cycle >= 5) @@ -148,7 +148,7 @@ datum/reagent/neurotoxin2/on_mob_life(var/mob/living/M as mob) mix_sound = null no_message = 1 -datum/reagent/cyanide +/datum/reagent/cyanide name = "Cyanide" id = "cyanide" description = "A highly toxic chemical with some uses as a building block for other things." @@ -157,7 +157,7 @@ datum/reagent/cyanide metabolization_rate = 0.1 penetrates_skin = 1 -datum/reagent/cyanide/on_mob_life(var/mob/living/M as mob) +/datum/reagent/cyanide/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom if(prob(5)) M.emote("drool") @@ -182,7 +182,7 @@ datum/reagent/cyanide/on_mob_life(var/mob/living/M as mob) mix_message = "The mixture gives off a faint scent of almonds." -datum/reagent/itching_powder +/datum/reagent/itching_powder name = "Itching Powder" id = "itching_powder" description = "An abrasive powder beloved by cruel pranksters." @@ -191,7 +191,7 @@ datum/reagent/itching_powder metabolization_rate = 0.3 penetrates_skin = 1 -datum/reagent/itching_powder/on_mob_life(var/mob/living/M as mob) +/datum/reagent/itching_powder/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom if(prob(rand(5,50))) M << "You scratch at your head." @@ -216,14 +216,14 @@ datum/reagent/itching_powder/on_mob_life(var/mob/living/M as mob) mix_message = "The mixture congeals and dries up, leaving behind an abrasive powder." mix_sound = 'sound/effects/blobattack.ogg' -datum/reagent/facid/on_mob_life(var/mob/living/M as mob) +/datum/reagent/facid/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom M.adjustToxLoss(1*REM) M.adjustFireLoss(1) ..() return -datum/reagent/facid +/datum/reagent/facid name = "Fluorosulfuric Acid" id = "facid" description = "Fluorosulfuric acid is a an extremely corrosive super-acid." @@ -231,7 +231,7 @@ datum/reagent/facid color = "#4141D2" process_flags = ORGANIC | SYNTHETIC -datum/reagent/facid/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume) +/datum/reagent/facid/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume) if(!istype(M, /mob/living)) return //wooo more runtime fixin if(method == TOUCH || method == INGEST) @@ -275,7 +275,7 @@ datum/reagent/facid/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume) H.emote("scream") H.status_flags |= DISFIGURED -datum/reagent/facid/reaction_obj(var/obj/O, var/volume) +/datum/reagent/facid/reaction_obj(var/obj/O, var/volume) if((istype(O,/obj/item) || istype(O,/obj/effect/glowshroom))) if(!O.unacidable) var/obj/effect/decal/cleanable/molten_item/I = new/obj/effect/decal/cleanable/molten_item(O.loc) @@ -293,7 +293,7 @@ datum/reagent/facid/reaction_obj(var/obj/O, var/volume) min_temp = 380 mix_message = "The mixture deepens to a dark blue, and slowly begins to corrode its container." -datum/reagent/initropidril +/datum/reagent/initropidril name = "Initropidril" id = "initropidril" description = "A highly potent cardiac poison - can kill within minutes." @@ -301,7 +301,7 @@ datum/reagent/initropidril color = "#7F10C0" metabolization_rate = 0.4 -datum/reagent/initropidril/on_mob_life(var/mob/living/M as mob) +/datum/reagent/initropidril/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom if(prob(33)) switch(pick(1,2)) @@ -323,7 +323,7 @@ datum/reagent/initropidril/on_mob_life(var/mob/living/M as mob) ..() return -datum/reagent/concentrated_initro +/datum/reagent/concentrated_initro name = "Concentrated Initropidril" id = "concentrated_initro" description = "A guaranteed heart-stopper!" @@ -331,14 +331,14 @@ datum/reagent/concentrated_initro color = "#AB1CCF" metabolization_rate = 0.4 -datum/reagent/concentrated_initro/on_mob_life(var/mob/living/M as mob) +/datum/reagent/concentrated_initro/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom if(volume >=5) var/mob/living/carbon/human/H = M if(!H.heart_attack) H.heart_attack = 1 // rip in pepperoni -datum/reagent/pancuronium +/datum/reagent/pancuronium name = "Pancuronium" id = "pancuronium" description = "Pancuronium bromide is a powerful skeletal muscle relaxant." @@ -346,7 +346,7 @@ datum/reagent/pancuronium color = "#1E4664" metabolization_rate = 0.2 -datum/reagent/pancuronium/on_mob_life(var/mob/living/M as mob) +/datum/reagent/pancuronium/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom if(current_cycle >= 10) M.Weaken(3) @@ -357,7 +357,7 @@ datum/reagent/pancuronium/on_mob_life(var/mob/living/M as mob) ..() return -datum/reagent/sodium_thiopental +/datum/reagent/sodium_thiopental name = "Sodium Thiopental" id = "sodium_thiopental" description = "An rapidly-acting barbituate tranquilizer." @@ -365,7 +365,7 @@ datum/reagent/sodium_thiopental color = "#5F8BE1" metabolization_rate = 0.7 -datum/reagent/sodium_thiopental/on_mob_life(var/mob/living/M as mob) +/datum/reagent/sodium_thiopental/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom if(current_cycle == 1) M.emote("drool") @@ -376,7 +376,7 @@ datum/reagent/sodium_thiopental/on_mob_life(var/mob/living/M as mob) ..() return -datum/reagent/ketamine +/datum/reagent/ketamine name = "Ketamine" id = "ketamine" description = "A potent veterinary tranquilizer." @@ -385,7 +385,7 @@ datum/reagent/ketamine metabolization_rate = 0.8 penetrates_skin = 1 -datum/reagent/ketamine/on_mob_life(var/mob/living/M as mob) +/datum/reagent/ketamine/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom if(current_cycle <= 10) if(prob(20)) @@ -397,7 +397,7 @@ datum/reagent/ketamine/on_mob_life(var/mob/living/M as mob) ..() return -datum/reagent/sulfonal +/datum/reagent/sulfonal name = "Sulfonal" id = "sulfonal" description = "Deals some toxin damage, and puts you to sleep after 66 seconds." @@ -413,7 +413,7 @@ datum/reagent/sulfonal result_amount = 3 mix_message = "The mixture gives off quite a stench." -datum/reagent/sulfonal/on_mob_life(var/mob/living/M as mob) +/datum/reagent/sulfonal/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom M.adjustToxLoss(1) if(current_cycle >= 11) @@ -430,25 +430,25 @@ datum/reagent/sulfonal/on_mob_life(var/mob/living/M as mob) ..() return -datum/reagent/amanitin +/datum/reagent/amanitin name = "Amanitin" id = "amanitin" description = "A toxin produced by certain mushrooms. Very deadly." reagent_state = LIQUID color = "#D9D9D9" -datum/reagent/amanitin/on_mob_life(var/mob/living/M as mob) +/datum/reagent/amanitin/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom ..() return -datum/reagent/amanitin/reagent_deleted(var/mob/living/M as mob) +/datum/reagent/amanitin/reagent_deleted(var/mob/living/M as mob) if(!M) M = holder.my_atom M.adjustToxLoss(current_cycle*rand(2,4)) ..() return -datum/reagent/lipolicide +/datum/reagent/lipolicide name = "Lipolicide" id = "lipolicide" description = "A compound found in many seedy dollar stores in the form of a weight-loss tonic." @@ -463,7 +463,7 @@ datum/reagent/lipolicide required_reagents = list("mercury" = 1, "diethylamine" = 1, "ephedrine" = 1) result_amount = 3 -datum/reagent/lipolicide/on_mob_life(var/mob/living/M as mob) +/datum/reagent/lipolicide/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom if(!holder.has_reagent("nutriment")) if(prob(30)) @@ -475,7 +475,7 @@ datum/reagent/lipolicide/on_mob_life(var/mob/living/M as mob) ..() return -datum/reagent/coniine +/datum/reagent/coniine name = "Coniine" id = "coniine" description = "A neurotoxin that rapidly causes respiratory failure." @@ -483,14 +483,14 @@ datum/reagent/coniine color = "#C2D8CD" metabolization_rate = 0.05 -datum/reagent/coniine/on_mob_life(var/mob/living/M as mob) +/datum/reagent/coniine/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom M.losebreath += 5 M.adjustToxLoss(2) ..() return -datum/reagent/curare +/datum/reagent/curare name = "Curare" id = "curare" description = "A highly dangerous paralytic poison." @@ -499,7 +499,7 @@ datum/reagent/curare metabolization_rate = 0.1 penetrates_skin = 1 -datum/reagent/curare/on_mob_life(var/mob/living/M as mob) +/datum/reagent/curare/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom if(prob(5)) M.emote(pick("gasp","drool", "pale")) @@ -510,7 +510,7 @@ datum/reagent/curare/on_mob_life(var/mob/living/M as mob) ..() return -datum/reagent/tabun +/datum/reagent/tabun name = "Tabun" id = "tabun" description = "An extremely deadly neurotoxin." @@ -528,7 +528,7 @@ datum/reagent/tabun mix_message = "The mixture yields a colorless, odorless liquid." min_temp = 374 -datum/reagent/tabun/on_mob_life(var/mob/living/M as mob) +/datum/reagent/tabun/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom M.adjustFireLoss(1) if(prob(20)) @@ -562,21 +562,21 @@ datum/reagent/tabun/on_mob_life(var/mob/living/M as mob) ..() return -datum/reagent/atrazine +/datum/reagent/atrazine name = "Atrazine" id = "atrazine" description = "A herbicidal compound used for destroying unwanted plants." reagent_state = LIQUID color = "#17002D" -datum/reagent/atrazine/on_mob_life(var/mob/living/M as mob) +/datum/reagent/atrazine/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom M.adjustToxLoss(2) ..() return // Clear off wallrot fungi -datum/reagent/atrazine/reaction_turf(var/turf/T, var/volume) +/datum/reagent/atrazine/reaction_turf(var/turf/T, var/volume) if(istype(T, /turf/simulated/wall)) var/turf/simulated/wall/W = T if(W.rotting) @@ -588,7 +588,7 @@ datum/reagent/atrazine/reaction_turf(var/turf/T, var/volume) for(var/mob/O in viewers(W, null)) O.show_message(text("\blue The fungi are completely dissolved by the solution!"), 1) -datum/reagent/atrazine/reaction_obj(var/obj/O, var/volume) +/datum/reagent/atrazine/reaction_obj(var/obj/O, var/volume) if(istype(O,/obj/structure/alien/weeds/)) var/obj/structure/alien/weeds/alien_weeds = O alien_weeds.health -= rand(15,35) // Kills alien weeds pretty fast @@ -599,7 +599,7 @@ datum/reagent/atrazine/reaction_obj(var/obj/O, var/volume) if(prob(50)) qdel(O) //Kills kudzu too. // Damage that is done to growing plants is separately at code/game/machinery/hydroponics at obj/item/hydroponics -datum/reagent/atrazine/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume) +/datum/reagent/atrazine/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume) src = null if(iscarbon(M)) var/mob/living/carbon/C = M @@ -626,7 +626,7 @@ datum/reagent/atrazine/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volu result_amount = 3 mix_message = "The mixture gives off a harsh odor" -datum/reagent/capulettium +/datum/reagent/capulettium name = "Capulettium" id = "capulettium" description = "A rare drug that causes the user to appear dead for some time." @@ -641,7 +641,7 @@ datum/reagent/capulettium result_amount = 1 mix_message = "The smell of death wafts up from the solution." -datum/reagent/capulettium/on_mob_life(var/mob/living/M as mob) +/datum/reagent/capulettium/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom M.eye_blurry = max(M.eye_blurry, 2) if(current_cycle == 12) @@ -650,7 +650,7 @@ datum/reagent/capulettium/on_mob_life(var/mob/living/M as mob) ..() return -datum/reagent/capulettium_plus +/datum/reagent/capulettium_plus name = "Capulettium Plus" id = "capulettium_plus" description = "A rare and expensive drug that causes the user to appear dead for some time while they retain consciousness and vision." @@ -665,20 +665,20 @@ datum/reagent/capulettium_plus result_amount = 3 mix_message = "The solution begins to slosh about violently by itself." -datum/reagent/capulettium_plus/on_mob_life(var/mob/living/M as mob) +/datum/reagent/capulettium_plus/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom - M.silent += REM + 1 + M.silent = max(M.silent, 2) ..() return -datum/reagent/toxic_slurry +/datum/reagent/toxic_slurry name = "Toxic Slurry" id = "toxic_slurry" description = "A filthy, carcinogenic sludge produced by the Slurrypod plant." reagent_state = LIQUID color = "#00C81E" -datum/reagent/toxic_slurry/on_mob_life(var/mob/living/M as mob) +/datum/reagent/toxic_slurry/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom if(prob(10)) M.adjustToxLoss(rand(2,4)) @@ -692,14 +692,14 @@ datum/reagent/toxic_slurry/on_mob_life(var/mob/living/M as mob) ..() return -datum/reagent/glowing_slurry +/datum/reagent/glowing_slurry name = "Glowing Slurry" id = "glowing_slurry" description = "This is probably not good for you." reagent_state = LIQUID color = "#00FD00" -datum/reagent/glowing_slurry/reaction_mob(var/mob/M, var/method=TOUCH, var/volume) //same as mutagen +/datum/reagent/glowing_slurry/reaction_mob(var/mob/M, var/method=TOUCH, var/volume) //same as mutagen if(!..()) return if(!M.dna) return //No robots, AIs, aliens, Ians or other mobs should be affected by this. src = null @@ -712,7 +712,7 @@ datum/reagent/glowing_slurry/reaction_mob(var/mob/M, var/method=TOUCH, var/volum M.UpdateAppearance() return -datum/reagent/glowing_slurry/on_mob_life(var/mob/living/M as mob) +/datum/reagent/glowing_slurry/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom M.apply_effect(2*REM, IRRADIATE, 0, negate_armor = 1) if(prob(15)) @@ -724,7 +724,7 @@ datum/reagent/glowing_slurry/on_mob_life(var/mob/living/M as mob) ..() return -datum/reagent/ants +/datum/reagent/ants name = "Ants" id = "ants" description = "A sample of a lost breed of Space Ants (formicidae bastardium tyrannus), they are well-known for ravaging the living shit out of pretty much anything." @@ -732,7 +732,7 @@ datum/reagent/ants color = "#993333" process_flags = ORGANIC | SYNTHETIC -datum/reagent/ants/reaction_mob(var/mob/living/M as mob, var/method=TOUCH, var/volume) //NOT THE ANTS +/datum/reagent/ants/reaction_mob(var/mob/living/M as mob, var/method=TOUCH, var/volume) //NOT THE ANTS if(iscarbon(M)) if(method == TOUCH || method==INGEST) M.adjustBruteLoss(4) @@ -740,7 +740,7 @@ datum/reagent/ants/reaction_mob(var/mob/living/M as mob, var/method=TOUCH, var/v M << "OH SHIT ANTS!!!!" -datum/reagent/ants/on_mob_life(var/mob/living/M as mob) +/datum/reagent/ants/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom M.adjustBruteLoss(2) ..() diff --git a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_drink.dm b/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_drink.dm index d56cdcf5644..683bd84337f 100644 --- a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_drink.dm +++ b/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_drink.dm @@ -1,590 +1,588 @@ -/datum/chemical_reaction/ - hot_coco - name = "Hot Coco" - id = "hot_coco" - result = "hot_coco" - required_reagents = list("water" = 5, "coco" = 1) - result_amount = 5 +/datum/chemical_reaction/hot_coco + name = "Hot Coco" + id = "hot_coco" + result = "hot_coco" + required_reagents = list("water" = 5, "cocoa" = 1) + result_amount = 5 - chocolate_milk - name = "Chocolate Milk" - id = "chocolate_milk" - result = "chocolate_milk" - required_reagents = list("chocolate" = 1, "milk" = 1) - result_amount = 2 - mix_message = "The mixture turns a nice brown color." +/datum/chemical_reaction/chocolate_milk + name = "Chocolate Milk" + id = "chocolate_milk" + result = "chocolate_milk" + required_reagents = list("chocolate" = 1, "milk" = 1) + result_amount = 2 + mix_message = "The mixture turns a nice brown color." - coffee - name = "Coffee" - id = "coffee" - result = "coffee" - required_reagents = list("coffeepowder" = 1, "water" = 5) - result_amount = 5 +/datum/chemical_reaction/coffee + name = "Coffee" + id = "coffee" + result = "coffee" + required_reagents = list("coffeepowder" = 1, "water" = 5) + result_amount = 5 - tea - name = "Tea" - id = "tea" - result = "tea" - required_reagents = list("teapowder" = 1, "water" = 5) - result_amount = 5 +/datum/chemical_reaction/tea + name = "Tea" + id = "tea" + result = "tea" + required_reagents = list("teapowder" = 1, "water" = 5) + result_amount = 5 +/datum/chemical_reaction/goldschlager + name = "Goldschlager" + id = "goldschlager" + result = "goldschlager" + required_reagents = list("vodka" = 10, "gold" = 1) + result_amount = 10 +/datum/chemical_reaction/patron + name = "Patron" + id = "patron" + result = "patron" + required_reagents = list("tequilla" = 10, "silver" = 1) + result_amount = 10 +/datum/chemical_reaction/bilk + name = "Bilk" + id = "bilk" + result = "bilk" + required_reagents = list("milk" = 1, "beer" = 1) + result_amount = 2 - goldschlager - name = "Goldschlager" - id = "goldschlager" - result = "goldschlager" - required_reagents = list("vodka" = 10, "gold" = 1) - result_amount = 10 +/datum/chemical_reaction/icetea + name = "Iced Tea" + id = "icetea" + result = "icetea" + required_reagents = list("ice" = 1, "tea" = 3) + result_amount = 4 - patron - name = "Patron" - id = "patron" - result = "patron" - required_reagents = list("tequilla" = 10, "silver" = 1) - result_amount = 10 +/datum/chemical_reaction/icecoffee + name = "Iced Coffee" + id = "icecoffee" + result = "icecoffee" + required_reagents = list("ice" = 1, "coffee" = 3) + result_amount = 4 - bilk - name = "Bilk" - id = "bilk" - result = "bilk" - required_reagents = list("milk" = 1, "beer" = 1) - result_amount = 2 +/datum/chemical_reaction/nuka_cola + name = "Nuka Cola" + id = "nuka_cola" + result = "nuka_cola" + required_reagents = list("uranium" = 1, "cola" = 6) + result_amount = 6 - icetea - name = "Iced Tea" - id = "icetea" - result = "icetea" - required_reagents = list("ice" = 1, "tea" = 3) - result_amount = 4 +/datum/chemical_reaction/moonshine + name = "Moonshine" + id = "moonshine" + result = "moonshine" + required_reagents = list("nutriment" = 10) + required_catalysts = list("enzyme" = 5) + result_amount = 10 - icecoffee - name = "Iced Coffee" - id = "icecoffee" - result = "icecoffee" - required_reagents = list("ice" = 1, "coffee" = 3) - result_amount = 4 +/datum/chemical_reaction/wine + name = "Wine" + id = "wine" + result = "wine" + required_reagents = list("berryjuice" = 10) + required_catalysts = list("enzyme" = 5) + result_amount = 10 - nuka_cola - name = "Nuka Cola" - id = "nuka_cola" - result = "nuka_cola" - required_reagents = list("uranium" = 1, "cola" = 6) - result_amount = 6 +/datum/chemical_reaction/spacebeer + name = "Space Beer" + id = "spacebeer" + result = "beer" + required_reagents = list("cornoil" = 10) + required_catalysts = list("enzyme" = 5) + result_amount = 10 - moonshine - name = "Moonshine" - id = "moonshine" - result = "moonshine" - required_reagents = list("nutriment" = 10) - required_catalysts = list("enzyme" = 5) - result_amount = 10 +/datum/chemical_reaction/vodka + name = "Vodka" + id = "vodka" + result = "vodka" + required_reagents = list("potato" = 10) + required_catalysts = list("enzyme" = 5) + result_amount = 10 - wine - name = "Wine" - id = "wine" - result = "wine" - required_reagents = list("berryjuice" = 10) - required_catalysts = list("enzyme" = 5) - result_amount = 10 +/datum/chemical_reaction/sake + name = "Sake" + id = "sake" + result = "sake" + required_reagents = list("rice" = 10,"water" = 5) + required_catalysts = list("enzyme" = 5) + result_amount = 15 - spacebeer - name = "Space Beer" - id = "spacebeer" - result = "beer" - required_reagents = list("cornoil" = 10) - required_catalysts = list("enzyme" = 5) - result_amount = 10 +/datum/chemical_reaction/kahlua + name = "Kahlua" + id = "kahlua" + result = "kahlua" + required_reagents = list("coffee" = 5, "sugar" = 5, "rum" = 5) + required_catalysts = list("enzyme" = 5) + result_amount = 5 - vodka - name = "Vodka" - id = "vodka" - result = "vodka" - required_reagents = list("potato" = 10) - required_catalysts = list("enzyme" = 5) - result_amount = 10 - sake - name = "Sake" - id = "sake" - result = "sake" - required_reagents = list("rice" = 10,"water" = 5) - required_catalysts = list("enzyme" = 5) - result_amount = 15 +/datum/chemical_reaction/kahluaVodka + name = "KahluaVodka" + id = "kahlauVodka" + result = "kahlua" + required_reagents = list("coffee" = 5, "sugar" = 5, "vodka" = 5) + required_catalysts = list("enzyme" = 5) + result_amount = 5 - kahlua - name = "Kahlua" - id = "kahlua" - result = "kahlua" - required_reagents = list("coffee" = 5, "sugar" = 5, "rum" = 5) - required_catalysts = list("enzyme" = 5) - result_amount = 5 +/datum/chemical_reaction/gin_tonic + name = "Gin and Tonic" + id = "gintonic" + result = "gintonic" + required_reagents = list("gin" = 2, "tonic" = 1) + result_amount = 3 + mix_message = "The tonic water and gin mix together perfectly." - kahluaVodka - name = "KahluaVodka" - id = "kahlauVodka" - result = "kahlua" - required_reagents = list("coffee" = 5, "sugar" = 5, "vodka" = 5) - required_catalysts = list("enzyme" = 5) - result_amount = 5 - gin_tonic - name = "Gin and Tonic" - id = "gintonic" - result = "gintonic" - required_reagents = list("gin" = 2, "tonic" = 1) - result_amount = 3 - mix_message = "The tonic water and gin mix together perfectly." +/datum/chemical_reaction/cuba_libre + name = "Cuba Libre" + id = "cubalibre" + result = "cubalibre" + required_reagents = list("rum" = 2, "cola" = 1) + result_amount = 3 - cuba_libre - name = "Cuba Libre" - id = "cubalibre" - result = "cubalibre" - required_reagents = list("rum" = 2, "cola" = 1) - result_amount = 3 +/datum/chemical_reaction/mojito + name = "Mojito" + id = "mojito" + result = "mojito" + required_reagents = list("rum" = 1, "sugar" = 1, "limejuice" = 1, "sodawater" = 1) + result_amount = 4 - mojito - name = "Mojito" - id = "mojito" - result = "mojito" - required_reagents = list("rum" = 1, "sugar" = 1, "limejuice" = 1, "sodawater" = 1) - result_amount = 4 +/datum/chemical_reaction/martini + name = "Classic Martini" + id = "martini" + result = "martini" + required_reagents = list("gin" = 2, "vermouth" = 1) + result_amount = 3 - martini - name = "Classic Martini" - id = "martini" - result = "martini" - required_reagents = list("gin" = 2, "vermouth" = 1) - result_amount = 3 +/datum/chemical_reaction/vodkamartini + name = "Vodka Martini" + id = "vodkamartini" + result = "vodkamartini" + required_reagents = list("vodka" = 2, "vermouth" = 1) + result_amount = 3 - vodkamartini - name = "Vodka Martini" - id = "vodkamartini" - result = "vodkamartini" - required_reagents = list("vodka" = 2, "vermouth" = 1) - result_amount = 3 +/datum/chemical_reaction/white_russian + name = "White Russian" + id = "whiterussian" + result = "whiterussian" + required_reagents = list("blackrussian" = 3, "cream" = 2) + result_amount = 5 - white_russian - name = "White Russian" - id = "whiterussian" - result = "whiterussian" - required_reagents = list("blackrussian" = 3, "cream" = 2) - result_amount = 5 +/datum/chemical_reaction/whiskey_cola + name = "Whiskey Cola" + id = "whiskeycola" + result = "whiskeycola" + required_reagents = list("whiskey" = 2, "cola" = 1) + result_amount = 3 - whiskey_cola - name = "Whiskey Cola" - id = "whiskeycola" - result = "whiskeycola" - required_reagents = list("whiskey" = 2, "cola" = 1) - result_amount = 3 +/datum/chemical_reaction/screwdriver + name = "Screwdriver" + id = "screwdrivercocktail" + result = "screwdrivercocktail" + required_reagents = list("vodka" = 2, "orangejuice" = 1) + result_amount = 3 - screwdriver - name = "Screwdriver" - id = "screwdrivercocktail" - result = "screwdrivercocktail" - required_reagents = list("vodka" = 2, "orangejuice" = 1) - result_amount = 3 +/datum/chemical_reaction/bloody_mary + name = "Bloody Mary" + id = "bloodymary" + result = "bloodymary" + required_reagents = list("vodka" = 1, "tomatojuice" = 2, "limejuice" = 1) + result_amount = 4 - bloody_mary - name = "Bloody Mary" - id = "bloodymary" - result = "bloodymary" - required_reagents = list("vodka" = 1, "tomatojuice" = 2, "limejuice" = 1) - result_amount = 4 +/datum/chemical_reaction/gargle_blaster + name = "Pan-Galactic Gargle Blaster" + id = "gargleblaster" + result = "gargleblaster" + required_reagents = list("vodka" = 1, "gin" = 1, "whiskey" = 1, "cognac" = 1, "limejuice" = 1) + result_amount = 5 - gargle_blaster - name = "Pan-Galactic Gargle Blaster" - id = "gargleblaster" - result = "gargleblaster" - required_reagents = list("vodka" = 1, "gin" = 1, "whiskey" = 1, "cognac" = 1, "limejuice" = 1) - result_amount = 5 +/datum/chemical_reaction/brave_bull + name = "Brave Bull" + id = "bravebull" + result = "bravebull" + required_reagents = list("tequilla" = 2, "kahlua" = 1) + result_amount = 3 - brave_bull - name = "Brave Bull" - id = "bravebull" - result = "bravebull" - required_reagents = list("tequilla" = 2, "kahlua" = 1) - result_amount = 3 +/datum/chemical_reaction/tequilla_sunrise + name = "Tequilla Sunrise" + id = "tequillasunrise" + result = "tequillasunrise" + required_reagents = list("tequilla" = 2, "orangejuice" = 1) + result_amount = 3 - tequilla_sunrise - name = "Tequilla Sunrise" - id = "tequillasunrise" - result = "tequillasunrise" - required_reagents = list("tequilla" = 2, "orangejuice" = 1) - result_amount = 3 +/datum/chemical_reaction/toxins_special + name = "Toxins Special" + id = "toxinsspecial" + result = "toxinsspecial" + required_reagents = list("rum" = 2, "vermouth" = 1, "plasma" = 2) + result_amount = 5 - toxins_special - name = "Toxins Special" - id = "toxinsspecial" - result = "toxinsspecial" - required_reagents = list("rum" = 2, "vermouth" = 1, "plasma" = 2) - result_amount = 5 +/datum/chemical_reaction/beepsky_smash + name = "Beepksy Smash" + id = "beepksysmash" + result = "beepskysmash" + required_reagents = list("limejuice" = 2, "whiskey" = 2, "iron" = 1) + result_amount = 4 - beepsky_smash - name = "Beepksy Smash" - id = "beepksysmash" - result = "beepskysmash" - required_reagents = list("limejuice" = 2, "whiskey" = 2, "iron" = 1) - result_amount = 4 +/datum/chemical_reaction/doctor_delight + name = "The Doctor's Delight" + id = "doctordelight" + result = "doctorsdelight" + required_reagents = list("limejuice" = 1, "tomatojuice" = 1, "orangejuice" = 1, "cream" = 1) + result_amount = 5 - doctor_delight - name = "The Doctor's Delight" - id = "doctordelight" - result = "doctorsdelight" - required_reagents = list("limejuice" = 1, "tomatojuice" = 1, "orangejuice" = 1, "cream" = 1) - result_amount = 5 +/datum/chemical_reaction/irish_cream + name = "Irish Cream" + id = "irishcream" + result = "irishcream" + required_reagents = list("whiskey" = 2, "cream" = 1) + result_amount = 3 - irish_cream - name = "Irish Cream" - id = "irishcream" - result = "irishcream" - required_reagents = list("whiskey" = 2, "cream" = 1) - result_amount = 3 +/datum/chemical_reaction/manly_dorf + name = "The Manly Dorf" + id = "manlydorf" + result = "manlydorf" + required_reagents = list ("beer" = 1, "ale" = 2) + result_amount = 3 - manly_dorf - name = "The Manly Dorf" - id = "manlydorf" - result = "manlydorf" - required_reagents = list ("beer" = 1, "ale" = 2) - result_amount = 3 +/datum/chemical_reaction/suicider + name = "Suicider" + id = "suicider" + result = "suicider" + required_reagents = list ("vodka" = 1, "cider" = 1, "fuel" = 1, "epinephrine" = 1) + result_amount = 4 + mix_message = "The drinks and chemicals mix together, emitting a potent smell." - suicider - name = "Suicider" - id = "suicider" - result = "suicider" - required_reagents = list ("vodka" = 1, "cider" = 1, "fuel" = 1, "epinephrine" = 1) - result_amount = 4 - mix_message = "The drinks and chemicals mix together, emitting a potent smell." +/datum/chemical_reaction/irish_coffee + name = "Irish Coffee" + id = "irishcoffee" + result = "irishcoffee" + required_reagents = list("irishcream" = 1, "coffee" = 1) + result_amount = 2 - irish_coffee - name = "Irish Coffee" - id = "irishcoffee" - result = "irishcoffee" - required_reagents = list("irishcream" = 1, "coffee" = 1) - result_amount = 2 +/datum/chemical_reaction/b52 + name = "B-52" + id = "b52" + result = "b52" + required_reagents = list("irishcream" = 1, "kahlua" = 1, "cognac" = 1) + result_amount = 3 - b52 - name = "B-52" - id = "b52" - result = "b52" - required_reagents = list("irishcream" = 1, "kahlua" = 1, "cognac" = 1) - result_amount = 3 +/datum/chemical_reaction/atomicbomb + name = "Atomic Bomb" + id = "atomicbomb" + result = "atomicbomb" + required_reagents = list("b52" = 10, "uranium" = 1) + result_amount = 10 - atomicbomb - name = "Atomic Bomb" - id = "atomicbomb" - result = "atomicbomb" - required_reagents = list("b52" = 10, "uranium" = 1) - result_amount = 10 +/datum/chemical_reaction/margarita + name = "Margarita" + id = "margarita" + result = "margarita" + required_reagents = list("tequilla" = 2, "limejuice" = 1) + result_amount = 3 - margarita - name = "Margarita" - id = "margarita" - result = "margarita" - required_reagents = list("tequilla" = 2, "limejuice" = 1) - result_amount = 3 +/datum/chemical_reaction/longislandicedtea + name = "Long Island Iced Tea" + id = "longislandicedtea" + result = "longislandicedtea" + required_reagents = list("vodka" = 1, "gin" = 1, "tequilla" = 1, "cubalibre" = 1) + result_amount = 4 - longislandicedtea - name = "Long Island Iced Tea" - id = "longislandicedtea" - result = "longislandicedtea" - required_reagents = list("vodka" = 1, "gin" = 1, "tequilla" = 1, "cubalibre" = 1) - result_amount = 4 +/datum/chemical_reaction/threemileisland + name = "Three Mile Island Iced Tea" + id = "threemileisland" + result = "threemileisland" + required_reagents = list("longislandicedtea" = 10, "uranium" = 1) + result_amount = 10 - threemileisland - name = "Three Mile Island Iced Tea" - id = "threemileisland" - result = "threemileisland" - required_reagents = list("longislandicedtea" = 10, "uranium" = 1) - result_amount = 10 +/datum/chemical_reaction/whiskeysoda + name = "Whiskey Soda" + id = "whiskeysoda" + result = "whiskeysoda" + required_reagents = list("whiskey" = 2, "sodawater" = 1) + result_amount = 3 - whiskeysoda - name = "Whiskey Soda" - id = "whiskeysoda" - result = "whiskeysoda" - required_reagents = list("whiskey" = 2, "sodawater" = 1) - result_amount = 3 +/datum/chemical_reaction/black_russian + name = "Black Russian" + id = "blackrussian" + result = "blackrussian" + required_reagents = list("vodka" = 3, "kahlua" = 2) + result_amount = 5 - black_russian - name = "Black Russian" - id = "blackrussian" - result = "blackrussian" - required_reagents = list("vodka" = 3, "kahlua" = 2) - result_amount = 5 +/datum/chemical_reaction/manhattan + name = "Manhattan" + id = "manhattan" + result = "manhattan" + required_reagents = list("whiskey" = 2, "vermouth" = 1) + result_amount = 3 - manhattan - name = "Manhattan" - id = "manhattan" - result = "manhattan" - required_reagents = list("whiskey" = 2, "vermouth" = 1) - result_amount = 3 +/datum/chemical_reaction/manhattan_proj + name = "Manhattan Project" + id = "manhattan_proj" + result = "manhattan_proj" + required_reagents = list("manhattan" = 10, "uranium" = 1) + result_amount = 10 - manhattan_proj - name = "Manhattan Project" - id = "manhattan_proj" - result = "manhattan_proj" - required_reagents = list("manhattan" = 10, "uranium" = 1) - result_amount = 10 +/datum/chemical_reaction/vodka_tonic + name = "Vodka and Tonic" + id = "vodkatonic" + result = "vodkatonic" + required_reagents = list("vodka" = 2, "tonic" = 1) + result_amount = 3 - vodka_tonic - name = "Vodka and Tonic" - id = "vodkatonic" - result = "vodkatonic" - required_reagents = list("vodka" = 2, "tonic" = 1) - result_amount = 3 +/datum/chemical_reaction/gin_fizz + name = "Gin Fizz" + id = "ginfizz" + result = "ginfizz" + required_reagents = list("gin" = 2, "sodawater" = 1, "limejuice" = 1) + result_amount = 4 - gin_fizz - name = "Gin Fizz" - id = "ginfizz" - result = "ginfizz" - required_reagents = list("gin" = 2, "sodawater" = 1, "limejuice" = 1) - result_amount = 4 +/datum/chemical_reaction/bahama_mama + name = "Bahama mama" + id = "bahama_mama" + result = "bahama_mama" + required_reagents = list("rum" = 2, "orangejuice" = 2, "limejuice" = 1, "ice" = 1) + result_amount = 6 - bahama_mama - name = "Bahama mama" - id = "bahama_mama" - result = "bahama_mama" - required_reagents = list("rum" = 2, "orangejuice" = 2, "limejuice" = 1, "ice" = 1) - result_amount = 6 +/datum/chemical_reaction/singulo + name = "Singulo" + id = "singulo" + result = "singulo" + required_reagents = list("vodka" = 5, "radium" = 1, "wine" = 5) + result_amount = 10 - singulo - name = "Singulo" - id = "singulo" - result = "singulo" - required_reagents = list("vodka" = 5, "radium" = 1, "wine" = 5) - result_amount = 10 +/datum/chemical_reaction/alliescocktail + name = "Allies Cocktail" + id = "alliescocktail" + result = "alliescocktail" + required_reagents = list("martini" = 1, "vodka" = 1) + result_amount = 2 - alliescocktail - name = "Allies Cocktail" - id = "alliescocktail" - result = "alliescocktail" - required_reagents = list("martini" = 1, "vodka" = 1) - result_amount = 2 +/datum/chemical_reaction/demonsblood + name = "Demons Blood" + id = "demonsblood" + result = "demonsblood" + required_reagents = list("rum" = 1, "spacemountainwind" = 1, "blood" = 1, "dr_gibb" = 1) + result_amount = 4 - demonsblood - name = "Demons Blood" - id = "demonsblood" - result = "demonsblood" - required_reagents = list("rum" = 1, "spacemountainwind" = 1, "blood" = 1, "dr_gibb" = 1) - result_amount = 4 +/datum/chemical_reaction/booger + name = "Booger" + id = "booger" + result = "booger" + required_reagents = list("cream" = 1, "banana" = 1, "rum" = 1, "watermelonjuice" = 1) + result_amount = 4 - booger - name = "Booger" - id = "booger" - result = "booger" - required_reagents = list("cream" = 1, "banana" = 1, "rum" = 1, "watermelonjuice" = 1) - result_amount = 4 +/datum/chemical_reaction/antifreeze + name = "Anti-freeze" + id = "antifreeze" + result = "antifreeze" + required_reagents = list("vodka" = 2, "cream" = 1, "ice" = 1) + result_amount = 4 - antifreeze - name = "Anti-freeze" - id = "antifreeze" - result = "antifreeze" - required_reagents = list("vodka" = 2, "cream" = 1, "ice" = 1) - result_amount = 4 - - barefoot - name = "Barefoot" - id = "barefoot" - result = "barefoot" - required_reagents = list("berryjuice" = 1, "cream" = 1, "vermouth" = 1) - result_amount = 3 +/datum/chemical_reaction/barefoot + name = "Barefoot" + id = "barefoot" + result = "barefoot" + required_reagents = list("berryjuice" = 1, "cream" = 1, "vermouth" = 1) + result_amount = 3 ////DRINKS THAT REQUIRED IMPROVED SPRITES BELOW:: -Agouri///// - sbiten - name = "Sbiten" - id = "sbiten" - result = "sbiten" - required_reagents = list("vodka" = 10, "capsaicin" = 1) - result_amount = 10 +/datum/chemical_reaction/sbiten + name = "Sbiten" + id = "sbiten" + result = "sbiten" + required_reagents = list("vodka" = 10, "capsaicin" = 1) + result_amount = 10 - red_mead - name = "Red Mead" - id = "red_mead" - result = "red_mead" - required_reagents = list("blood" = 1, "mead" = 1) - result_amount = 2 +/datum/chemical_reaction/red_mead + name = "Red Mead" + id = "red_mead" + result = "red_mead" + required_reagents = list("blood" = 1, "mead" = 1) + result_amount = 2 - mead - name = "Mead" - id = "mead" - result = "mead" - required_reagents = list("sugar" = 1, "water" = 1) - required_catalysts = list("enzyme" = 5) - result_amount = 2 +/datum/chemical_reaction/mead + name = "Mead" + id = "mead" + result = "mead" + required_reagents = list("sugar" = 1, "water" = 1) + required_catalysts = list("enzyme" = 5) + result_amount = 2 - iced_beer - name = "Iced Beer" - id = "iced_beer" - result = "iced_beer" - required_reagents = list("beer" = 10, "frostoil" = 1) - result_amount = 10 +/datum/chemical_reaction/iced_beer + name = "Iced Beer" + id = "iced_beer" + result = "iced_beer" + required_reagents = list("beer" = 10, "frostoil" = 1) + result_amount = 10 - iced_beer2 - name = "Iced Beer" - id = "iced_beer" - result = "iced_beer" - required_reagents = list("beer" = 5, "ice" = 1) - result_amount = 6 +/datum/chemical_reaction/iced_beer2 + name = "Iced Beer" + id = "iced_beer" + result = "iced_beer" + required_reagents = list("beer" = 5, "ice" = 1) + result_amount = 6 - grog - name = "Grog" - id = "grog" - result = "grog" - required_reagents = list("rum" = 1, "water" = 1) - result_amount = 2 +/datum/chemical_reaction/grog + name = "Grog" + id = "grog" + result = "grog" + required_reagents = list("rum" = 1, "water" = 1) + result_amount = 2 - soy_latte - name = "Soy Latte" - id = "soy_latte" - result = "soy_latte" - required_reagents = list("coffee" = 1, "soymilk" = 1) - result_amount = 2 +/datum/chemical_reaction/soy_latte + name = "Soy Latte" + id = "soy_latte" + result = "soy_latte" + required_reagents = list("coffee" = 1, "soymilk" = 1) + result_amount = 2 - cafe_latte - name = "Cafe Latte" - id = "cafe_latte" - result = "cafe_latte" - required_reagents = list("coffee" = 1, "milk" = 1) - result_amount = 2 +/datum/chemical_reaction/cafe_latte + name = "Cafe Latte" + id = "cafe_latte" + result = "cafe_latte" + required_reagents = list("coffee" = 1, "milk" = 1) + result_amount = 2 - acidspit - name = "Acid Spit" - id = "acidspit" - result = "acidspit" - required_reagents = list("sacid" = 1, "wine" = 5) - result_amount = 6 +/datum/chemical_reaction/acidspit + name = "Acid Spit" + id = "acidspit" + result = "acidspit" + required_reagents = list("sacid" = 1, "wine" = 5) + result_amount = 6 - amasec - name = "Amasec" - id = "amasec" - result = "amasec" - required_reagents = list("iron" = 1, "wine" = 5, "vodka" = 5) - result_amount = 10 +/datum/chemical_reaction/amasec + name = "Amasec" + id = "amasec" + result = "amasec" + required_reagents = list("iron" = 1, "wine" = 5, "vodka" = 5) + result_amount = 10 - changelingsting - name = "Changeling Sting" - id = "changelingsting" - result = "changelingsting" - required_reagents = list("screwdrivercocktail" = 1, "limejuice" = 1, "lemonjuice" = 1) - result_amount = 5 +/datum/chemical_reaction/changelingsting + name = "Changeling Sting" + id = "changelingsting" + result = "changelingsting" + required_reagents = list("screwdrivercocktail" = 1, "limejuice" = 1, "lemonjuice" = 1) + result_amount = 5 - aloe - name = "Aloe" - id = "aloe" - result = "aloe" - required_reagents = list("cream" = 1, "whiskey" = 1, "watermelonjuice" = 1) - result_amount = 2 +/datum/chemical_reaction/aloe + name = "Aloe" + id = "aloe" + result = "aloe" + required_reagents = list("cream" = 1, "whiskey" = 1, "watermelonjuice" = 1) + result_amount = 2 - andalusia - name = "Andalusia" - id = "andalusia" - result = "andalusia" - required_reagents = list("rum" = 1, "whiskey" = 1, "lemonjuice" = 1) - result_amount = 3 +/datum/chemical_reaction/andalusia + name = "Andalusia" + id = "andalusia" + result = "andalusia" + required_reagents = list("rum" = 1, "whiskey" = 1, "lemonjuice" = 1) + result_amount = 3 - neurotoxin - name = "Neurotoxin" - id = "neurotoxin" - result = "neurotoxin" - required_reagents = list("gargleblaster" = 1, "ether" = 1) - result_amount = 2 +/datum/chemical_reaction/neurotoxin + name = "Neurotoxin" + id = "neurotoxin" + result = "neurotoxin" + required_reagents = list("gargleblaster" = 1, "ether" = 1) + result_amount = 2 - snowwhite - name = "Snow White" - id = "snowwhite" - result = "snowwhite" - required_reagents = list("beer" = 1, "lemon_lime" = 1) - result_amount = 2 +/datum/chemical_reaction/snowwhite + name = "Snow White" + id = "snowwhite" + result = "snowwhite" + required_reagents = list("beer" = 1, "lemon_lime" = 1) + result_amount = 2 - irishcarbomb - name = "Irish Car Bomb" - id = "irishcarbomb" - result = "irishcarbomb" - required_reagents = list("ale" = 1, "irishcream" = 1) - result_amount = 2 +/datum/chemical_reaction/irishcarbomb + name = "Irish Car Bomb" + id = "irishcarbomb" + result = "irishcarbomb" + required_reagents = list("ale" = 1, "irishcream" = 1) + result_amount = 2 - syndicatebomb - name = "Syndicate Bomb" - id = "syndicatebomb" - result = "syndicatebomb" - required_reagents = list("beer" = 1, "whiskeycola" = 1) - result_amount = 2 +/datum/chemical_reaction/syndicatebomb + name = "Syndicate Bomb" + id = "syndicatebomb" + result = "syndicatebomb" + required_reagents = list("beer" = 1, "whiskeycola" = 1) + result_amount = 2 - erikasurprise - name = "Erika Surprise" - id = "erikasurprise" - result = "erikasurprise" - required_reagents = list("ale" = 1, "limejuice" = 1, "whiskey" = 1, "banana" = 1, "ice" = 1) - result_amount = 5 +/datum/chemical_reaction/erikasurprise + name = "Erika Surprise" + id = "erikasurprise" + result = "erikasurprise" + required_reagents = list("ale" = 1, "limejuice" = 1, "whiskey" = 1, "banana" = 1, "ice" = 1) + result_amount = 5 - devilskiss - name = "Devils Kiss" - id = "devilskiss" - result = "devilskiss" - required_reagents = list("blood" = 1, "kahlua" = 1, "rum" = 1) - result_amount = 3 +/datum/chemical_reaction/devilskiss + name = "Devils Kiss" + id = "devilskiss" + result = "devilskiss" + required_reagents = list("blood" = 1, "kahlua" = 1, "rum" = 1) + result_amount = 3 - hippiesdelight - name = "Hippies Delight" - id = "hippiesdelight" - result = "hippiesdelight" - required_reagents = list("psilocybin" = 1, "gargleblaster" = 1) - result_amount = 2 +/datum/chemical_reaction/hippiesdelight + name = "Hippies Delight" + id = "hippiesdelight" + result = "hippiesdelight" + required_reagents = list("psilocybin" = 1, "gargleblaster" = 1) + result_amount = 2 - bananahonk - name = "Banana Honk" - id = "bananahonk" - result = "bananahonk" - required_reagents = list("banana" = 1, "cream" = 1, "sugar" = 1) - result_amount = 3 +/datum/chemical_reaction/bananahonk + name = "Banana Honk" + id = "bananahonk" + result = "bananahonk" + required_reagents = list("banana" = 1, "cream" = 1, "sugar" = 1) + result_amount = 3 - silencer - name = "Silencer" - id = "silencer" - result = "silencer" - required_reagents = list("nothing" = 1, "cream" = 1, "sugar" = 1) - result_amount = 3 +/datum/chemical_reaction/silencer + name = "Silencer" + id = "silencer" + result = "silencer" + required_reagents = list("nothing" = 1, "cream" = 1, "sugar" = 1) + result_amount = 3 - driestmartini - name = "Driest Martini" - id = "driestmartini" - result = "driestmartini" - required_reagents = list("nothing" = 1, "gin" = 1) - result_amount = 2 +/datum/chemical_reaction/driestmartini + name = "Driest Martini" + id = "driestmartini" + result = "driestmartini" + required_reagents = list("nothing" = 1, "gin" = 1) + result_amount = 2 - lemonade - name = "Lemonade" - id = "lemonade" - result = "lemonade" - required_reagents = list("lemonjuice" = 1, "sugar" = 1, "water" = 1) - result_amount = 3 +/datum/chemical_reaction/lemonade + name = "Lemonade" + id = "lemonade" + result = "lemonade" + required_reagents = list("lemonjuice" = 1, "sugar" = 1, "water" = 1) + result_amount = 3 - kiraspecial - name = "Kira Special" - id = "kiraspecial" - result = "kiraspecial" - required_reagents = list("orangejuice" = 1, "limejuice" = 1, "sodawater" = 1) - result_amount = 2 +/datum/chemical_reaction/kiraspecial + name = "Kira Special" + id = "kiraspecial" + result = "kiraspecial" + required_reagents = list("orangejuice" = 1, "limejuice" = 1, "sodawater" = 1) + result_amount = 2 - brownstar - name = "Brown Star" - id = "brownstar" - result = "brownstar" - required_reagents = list("orangejuice" = 2, "cola" = 1) - result_amount = 2 +/datum/chemical_reaction/brownstar + name = "Brown Star" + id = "brownstar" + result = "brownstar" + required_reagents = list("orangejuice" = 2, "cola" = 1) + result_amount = 2 - milkshake - name = "Milkshake" - id = "milkshake" - result = "milkshake" - required_reagents = list("cream" = 1, "ice" = 2, "milk" = 2) - result_amount = 5 +/datum/chemical_reaction/milkshake + name = "Milkshake" + id = "milkshake" + result = "milkshake" + required_reagents = list("cream" = 1, "ice" = 2, "milk" = 2) + result_amount = 5 - rewriter - name = "Rewriter" - id = "rewriter" - result = "rewriter" - required_reagents = list("spacemountainwind" = 1, "coffee" = 1) - result_amount = 2 \ No newline at end of file +/datum/chemical_reaction/rewriter + name = "Rewriter" + id = "rewriter" + result = "rewriter" + required_reagents = list("spacemountainwind" = 1, "coffee" = 1) + result_amount = 2 \ No newline at end of file diff --git a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_food.dm b/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_food.dm index 698f27350bb..65b19133fa3 100644 --- a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_food.dm +++ b/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_food.dm @@ -1,121 +1,125 @@ -/datum/chemical_reaction/ - tofu - name = "Tofu" - id = "tofu" - result = null - required_reagents = list("soymilk" = 10) - required_catalysts = list("enzyme" = 5) - result_amount = 1 - on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) - new /obj/item/weapon/reagent_containers/food/snacks/tofu(location) - return +/datum/chemical_reaction/tofu + name = "Tofu" + id = "tofu" + result = null + required_reagents = list("soymilk" = 10) + required_catalysts = list("enzyme" = 5) + result_amount = 1 - chocolate_bar - name = "Chocolate Bar" - id = "chocolate_bar" - result = null - required_reagents = list("soymilk" = 2, "coco" = 2, "sugar" = 2) - result_amount = 1 - on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) - new /obj/item/weapon/reagent_containers/food/snacks/chocolatebar(location) - return +/datum/chemical_reaction/tofu/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/weapon/reagent_containers/food/snacks/tofu(location) + return - chocolate_bar2 - name = "Chocolate Bar" - id = "chocolate_bar" - result = null - required_reagents = list("milk" = 2, "coco" = 2, "sugar" = 2) - result_amount = 1 - on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) - new /obj/item/weapon/reagent_containers/food/snacks/chocolatebar(location) - return +/datum/chemical_reaction/chocolate_bar + name = "Chocolate Bar" + id = "chocolate_bar" + result = null + required_reagents = list("soymilk" = 2, "cocoa" = 2, "sugar" = 2) + result_amount = 1 +/datum/chemical_reaction/chocolate_bar/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/weapon/reagent_containers/food/snacks/chocolatebar(location) + return - soysauce - name = "Soy Sauce" - id = "soysauce" - result = "soysauce" - required_reagents = list("soymilk" = 1,"sodiumchloride" = 1, "water" = 8) - result_amount = 10 +/datum/chemical_reaction/chocolate_bar2 + name = "Chocolate Bar" + id = "chocolate_bar" + result = null + required_reagents = list("milk" = 2, "cocoa" = 2, "sugar" = 2) + result_amount = 1 - cheesewheel - name = "Cheesewheel" - id = "cheesewheel" - result = null - required_reagents = list("milk" = 40) - required_catalysts = list("enzyme" = 5) - result_amount = 1 - on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - new /obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesewheel(location) - return +/datum/chemical_reaction/chocolate_bar2/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/weapon/reagent_containers/food/snacks/chocolatebar(location) + return - syntiflesh - name = "Syntiflesh" - id = "syntiflesh" - result = null - required_reagents = list("blood" = 5, "cryoxadone" = 1) - result_amount = 1 - on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - new /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh(location) - return +/datum/chemical_reaction/soysauce + name = "Soy Sauce" + id = "soysauce" + result = "soysauce" + required_reagents = list("soymilk" = 1,"sodiumchloride" = 1, "water" = 8) + result_amount = 10 - hot_ramen - name = "Hot Ramen" - id = "hot_ramen" - result = "hot_ramen" - required_reagents = list("water" = 1, "dry_ramen" = 3) - result_amount = 3 +/datum/chemical_reaction/cheesewheel + name = "Cheesewheel" + id = "cheesewheel" + result = null + required_reagents = list("milk" = 40) + required_catalysts = list("enzyme" = 5) + result_amount = 1 - hell_ramen - name = "Hell Ramen" - id = "hell_ramen" - result = "hell_ramen" - required_reagents = list("capsaicin" = 1, "hot_ramen" = 6) - result_amount = 6 +/datum/chemical_reaction/cheesewheel/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + new /obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesewheel(location) + return - doughball - name = "Ball of dough" - id = "dough_ball" - result = "dough_ball" - required_reagents = list("flour" = 15, "water" = 5) - required_catalysts = list("enzyme" = 5) +/datum/chemical_reaction/syntiflesh + name = "Syntiflesh" + id = "syntiflesh" + result = null + required_reagents = list("blood" = 5, "cryoxadone" = 1) + result_amount = 1 - sodiumchloride - name = "Sodium Chloride" - id = "sodiumchloride" - result = "sodiumchloride" - required_reagents = list("sodium" = 1, "chlorine" = 1, "water" = 1) - result_amount = 3 - mix_message = "The solution crystallizes with a brief flare of light." +/datum/chemical_reaction/syntiflesh/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + new /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh(location) + return - ice - name = "Ice" - id = "ice" - result = "ice" - required_reagents = list("water" = 1) - result_amount = 1 - max_temp = 273 - mix_message = "Ice forms as the water freezes." - mix_sound = null +/datum/chemical_reaction/hot_ramen + name = "Hot Ramen" + id = "hot_ramen" + result = "hot_ramen" + required_reagents = list("water" = 1, "dry_ramen" = 3) + result_amount = 3 - dough - name = "Dough" - id = "dough" - result = null - required_reagents = list("water" = 10, "flour" = 15) - result_amount = 1 - mix_message = "The ingredients form a dough." +/datum/chemical_reaction/hell_ramen + name = "Hell Ramen" + id = "hell_ramen" + result = "hell_ramen" + required_reagents = list("capsaicin" = 1, "hot_ramen" = 6) + result_amount = 6 - on_reaction(datum/reagents/holder, created_volume) - var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) - new /obj/item/weapon/reagent_containers/food/snacks/dough(location) \ No newline at end of file +/datum/chemical_reaction/doughball + name = "Ball of dough" + id = "dough_ball" + result = "dough_ball" + required_reagents = list("flour" = 15, "water" = 5) + required_catalysts = list("enzyme" = 5) + +/datum/chemical_reaction/sodiumchloride + name = "Sodium Chloride" + id = "sodiumchloride" + result = "sodiumchloride" + required_reagents = list("sodium" = 1, "chlorine" = 1, "water" = 1) + result_amount = 3 + mix_message = "The solution crystallizes with a brief flare of light." + +/datum/chemical_reaction/ice + name = "Ice" + id = "ice" + result = "ice" + required_reagents = list("water" = 1) + result_amount = 1 + max_temp = 273 + mix_message = "Ice forms as the water freezes." + mix_sound = null + +/datum/chemical_reaction/dough + name = "Dough" + id = "dough" + result = null + required_reagents = list("water" = 10, "flour" = 15) + result_amount = 1 + mix_message = "The ingredients form a dough." + +/datum/chemical_reaction/dough/on_reaction(datum/reagents/holder, created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/weapon/reagent_containers/food/snacks/dough(location) + return diff --git a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_slime.dm b/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_slime.dm index 8894c903a27..d6e1ed34ce4 100644 --- a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_slime.dm +++ b/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_slime.dm @@ -148,6 +148,7 @@ on_reaction(var/datum/reagents/holder) var/list/borks = subtypesof(/obj/item/weapon/reagent_containers/food/snacks) + borks = adminReagentCheck(borks) // BORK BORK BORK playsound(get_turf(holder.my_atom), 'sound/effects/phasein.ogg', 100, 1) @@ -175,6 +176,7 @@ on_reaction(var/datum/reagents/holder) var/list/borks = subtypesof(/obj/item/weapon/reagent_containers/food/drinks) + borks = adminReagentCheck(borks) // BORK BORK BORK playsound(get_turf(holder.my_atom), 'sound/effects/phasein.ogg', 100, 1) diff --git a/code/modules/reagents/oldchem/reagents/_reagent_base.dm b/code/modules/reagents/oldchem/reagents/_reagent_base.dm index c84b0f327e9..eab338f2882 100644 --- a/code/modules/reagents/oldchem/reagents/_reagent_base.dm +++ b/code/modules/reagents/oldchem/reagents/_reagent_base.dm @@ -16,7 +16,7 @@ //Processing flags, defines the type of mobs the reagent will affect //By default, all reagents will ONLY affect organics, not synthetics. Re-define in the reagent's definition if the reagent is meant to affect synths var/process_flags = ORGANIC - + var/admin_only = 0 /datum/reagent/proc/reaction_mob(var/mob/M, var/method=TOUCH, var/volume) //Some reagents transfer on touch, others don't; dependent on if they penetrate the skin or not. if(!istype(M, /mob/living)) return 0 diff --git a/code/modules/reagents/oldchem/reagents/drink/reagents_alcohol.dm b/code/modules/reagents/oldchem/reagents/drink/reagents_alcohol.dm index e2892ee3b89..6c9e58d483e 100644 --- a/code/modules/reagents/oldchem/reagents/drink/reagents_alcohol.dm +++ b/code/modules/reagents/oldchem/reagents/drink/reagents_alcohol.dm @@ -22,7 +22,7 @@ // Sobering multiplier. // Sober block makes it more difficult to get drunk var/sober_str=!(SOBER in M.mutations)?1:2 - M:nutrition += nutriment_factor + M.nutrition += nutriment_factor if(!src.data) data = 1 src.data++ @@ -36,14 +36,14 @@ if(ishuman(M)) var/mob/living/carbon/human/H = M - var/obj/item/organ/liver/L = H.internal_organs_by_name["liver"] + var/obj/item/organ/internal/liver/L = H.get_int_organ(/obj/item/organ/internal/liver) if(!L || (istype(L) && L.dna.species in list("Skrell", "Neara"))) d*=5 M.dizziness += dizzy_adj. if(d >= slur_start && d < pass_out) - if (!M:slurring) M:slurring = 1 - M:slurring += slurr_adj/sober_str + if (!M.slurring) M.slurring = 1 + M.slurring += slurr_adj/sober_str if(d >= brawl_start && ishuman(M)) var/mob/living/carbon/human/H = M F.teach(H,1) @@ -51,21 +51,21 @@ if(H.martial_art == F) F.remove(H) if(d >= confused_start && prob(33)) - if (!M:confused) M:confused = 1 - M.confused = max(M:confused+(confused_adj/sober_str),0) + if (!M.confused) M.confused = 1 + M.confused = max(M.confused+(confused_adj/sober_str),0) if(d >= blur_start) M.eye_blurry = max(M.eye_blurry, 10/sober_str) - M:drowsyness = max(M:drowsyness, 0) + M.drowsyness = max(M.drowsyness, 0) if(d >= vomit_start) if(prob(8)) M.fakevomit() if(d >= pass_out) - M:paralysis = max(M:paralysis, 20/sober_str) - M:drowsyness = max(M:drowsyness, 30/sober_str) + M.Paralyse(20 / sober_str) + M.drowsyness = max(M.drowsyness, 30/sober_str) if(ishuman(M)) var/mob/living/carbon/human/H = M - var/obj/item/organ/liver/L = H.internal_organs_by_name["liver"] - if (istype(L)) + if (H.get_int_organ(/obj/item/organ/internal/liver)) + var/obj/item/organ/internal/liver/L = /obj/item/organ/internal/liver L.take_damage(0.1, 1) H.adjustToxLoss(0.1) ..() @@ -639,7 +639,7 @@ /datum/reagent/ethanol/neurotoxin - name = "Neurotoxin" + name = "Neuro-toxin" id = "neurotoxin" description = "A strong neurotoxin that puts the subject into a death-like state." reagent_state = LIQUID diff --git a/code/modules/reagents/oldchem/reagents/reagents_admin.dm b/code/modules/reagents/oldchem/reagents/reagents_admin.dm index dd9e73a96b1..765bc480487 100644 --- a/code/modules/reagents/oldchem/reagents/reagents_admin.dm +++ b/code/modules/reagents/oldchem/reagents/reagents_admin.dm @@ -5,6 +5,7 @@ reagent_state = LIQUID color = "#C8A5DC" // rgb: 200, 165, 220 process_flags = ORGANIC | SYNTHETIC //Adminbuse knows no bounds! + admin_only=1 /datum/reagent/adminordrazine/on_mob_life(var/mob/living/carbon/M as mob) if(!M) M = holder.my_atom ///This can even heal dead people. @@ -24,7 +25,7 @@ M.eye_blind = 0 if(ishuman(M)) var/mob/living/carbon/human/H = M - var/obj/item/organ/eyes/E = H.internal_organs_by_name["eyes"] + var/obj/item/organ/internal/eyes/E = H.get_int_organ(/obj/item/organ/internal/eyes) if(istype(E)) E.damage = max(E.damage-5 , 0) M.SetWeakened(0) @@ -51,4 +52,27 @@ /datum/reagent/adminordrazine/nanites name = "Nanites" id = "nanites" - description = "Nanomachines that aid in rapid cellular regeneration." \ No newline at end of file + description = "Nanomachines that aid in rapid cellular regeneration." + + +// For random item spawning. Takes a list of paths, and returns the same list without anything that contains admin only reagents + +/proc/adminReagentCheck(var/list/incoming) + var/list/outgoing[0] + for(var/tocheck in incoming) + if(ispath(tocheck)) + var/check = new tocheck + if (istype(check, /atom)) + var/atom/reagentCheck = check + var/datum/reagents/reagents = reagentCheck.reagents + var/admin = 0 + for(var/reag in reagents.reagent_list) + var/datum/reagent/reagent = reag + if(reagent.admin_only) + admin = 1 + break + if(!(admin)) + outgoing += tocheck + else + outgoing += tocheck + return outgoing \ No newline at end of file diff --git a/code/modules/reagents/oldchem/reagents/reagents_food.dm b/code/modules/reagents/oldchem/reagents/reagents_food.dm index da3244cbda2..de7297a5f39 100644 --- a/code/modules/reagents/oldchem/reagents/reagents_food.dm +++ b/code/modules/reagents/oldchem/reagents/reagents_food.dm @@ -14,7 +14,7 @@ if(!(M.mind in ticker.mode.vampires)) if(ishuman(M)) var/mob/living/carbon/human/H = M - if(H.species && H.species.dietflags) //Make sure the species has it's dietflag set, otherwise it can't digest any nutrients + if(H.can_eat()) //Make sure the species has it's dietflag set, otherwise it can't digest any nutrients H.nutrition += nutriment_factor // For hunger and fatness if(prob(50)) M.heal_organ_damage(1,0) if(istype(M,/mob/living/simple_animal)) //Any nutrients can heal simple animals @@ -36,7 +36,7 @@ if(!(M.mind in ticker.mode.vampires)) if(ishuman(M)) var/mob/living/carbon/human/H = M - if(H.species && H.species.dietflags && !(H.species.dietflags & DIET_HERB)) //Make sure the species has it's dietflag set, and that it is not a herbivore + if(H.can_eat(DIET_CARN | DIET_OMNI)) //Make sure that it is not a herbivore H.nutrition += nutriment_factor // For hunger and fatness if(prob(50)) M.heal_organ_damage(1,0) if(istype(M,/mob/living/simple_animal)) //Any nutrients can heal simple animals @@ -58,7 +58,7 @@ if(!(M.mind in ticker.mode.vampires)) if(ishuman(M)) var/mob/living/carbon/human/H = M - if(H.species && H.species.dietflags && !(H.species.dietflags & DIET_CARN)) //Make sure the species has it's dietflag set, and that it is not a carnivore + if(H.can_eat(DIET_HERB | DIET_OMNI)) //Make sure that it is not a carnivore H.nutrition += nutriment_factor // For hunger and fatness if(prob(50)) M.heal_organ_damage(1,0) if(istype(M,/mob/living/simple_animal)) //Any nutrients can heal simple animals @@ -185,15 +185,15 @@ reagent_state = SOLID // no color (ie, black) -/datum/reagent/coco - name = "Coco Powder" - id = "coco" - description = "A fatty, bitter paste made from coco beans." +/datum/reagent/cocoa + name = "Cocoa Powder" + id = "cocoa" + description = "A fatty, bitter paste made from cocoa beans." reagent_state = SOLID nutriment_factor = 5 * REAGENTS_METABOLISM color = "#302000" // rgb: 48, 32, 0 -/datum/reagent/coco/on_mob_life(var/mob/living/M as mob) +/datum/reagent/cocoa/on_mob_life(var/mob/living/M as mob) M.nutrition += nutriment_factor ..() return @@ -201,7 +201,7 @@ /datum/reagent/hot_coco name = "Hot Chocolate" id = "hot_coco" - description = "Made with love! And coco beans." + description = "Made with love! And cocoa beans." reagent_state = LIQUID nutriment_factor = 2 * REAGENTS_METABOLISM color = "#403010" // rgb: 64, 48, 16 diff --git a/code/modules/reagents/oldchem/reagents/reagents_med.dm b/code/modules/reagents/oldchem/reagents/reagents_med.dm index 630f9c90c94..d0bb839a424 100644 --- a/code/modules/reagents/oldchem/reagents/reagents_med.dm +++ b/code/modules/reagents/oldchem/reagents/reagents_med.dm @@ -78,8 +78,8 @@ var/mob/living/carbon/human/H = M //Mitocholide is hard enough to get, it's probably fair to make this all internal organs - for(var/name in H.internal_organs_by_name) - var/obj/item/organ/I = H.internal_organs_by_name[name] + for(var/name in H.internal_organs) + var/obj/item/organ/internal/I = H.get_int_organ(name) if(I.damage > 0) I.damage = max(I.damage-0.4, 0) ..() diff --git a/code/modules/reagents/oldchem/reagents/reagents_water.dm b/code/modules/reagents/oldchem/reagents/reagents_water.dm index eea7dfad6c4..b7c296443b5 100644 --- a/code/modules/reagents/oldchem/reagents/reagents_water.dm +++ b/code/modules/reagents/oldchem/reagents/reagents_water.dm @@ -223,9 +223,18 @@ M.fakevomit(1) else M.fakevomit(0) - ..() + ..() return +/datum/reagent/fishwater/toiletwater + name = "Toilet Water" + id = "toiletwater" + description = "Filthy water scoured from a nasty toilet bowl. Absolutely disgusting." + reagent_state = LIQUID + color = "#757547" + +/datum/reagent/fishwater/toiletwater/reaction_mob(var/mob/M, var/method=TOUCH, var/volume) //For shennanigans + return /datum/reagent/holywater name = "Water" diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 7f9c3ee3c98..45df570eb07 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -12,9 +12,13 @@ set name = "Set transfer amount" set category = "Object" set src in range(0) + if(usr.stat || !usr.canmove || usr.restrained()) return - var/N = input("Amount per transfer from this:","[src]") as null|anything in possible_transfer_amounts + var/default = null + if(amount_per_transfer_from_this in possible_transfer_amounts) + default = amount_per_transfer_from_this + var/N = input("Amount per transfer from this:", "[src]", default) as null|anything in possible_transfer_amounts if (N) amount_per_transfer_from_this = N @@ -46,11 +50,6 @@ /obj/item/weapon/reagent_containers/attack_self(mob/user as mob) return -/obj/item/weapon/reagent_containers/attack(mob/M as mob, mob/user as mob, def_zone) - if (can_operate(M)) //Checks if mob is lying down on table for surgery - if (do_surgery(M,user,src)) - return - // this prevented pills, food, and other things from being picked up by bags. // possibly intentional, but removing it allows us to not duplicate functionality. // -Sayu (storage conslidation) @@ -67,4 +66,11 @@ for (var/datum/reagent/R in snack.reagents.reagent_list) //no reagents will be left behind data += "[R.id]([R.volume] units); " //Using IDs because SOME chemicals(I'm looking at you, chlorhydrate-beer) have the same names as other chemicals. return data - else return "No reagents" \ No newline at end of file + else return "No reagents" + +/obj/item/weapon/reagent_containers/wash(mob/user, atom/source) + if(is_open_container()) + reagents.add_reagent("water", min(volume - reagents.total_volume, amount_per_transfer_from_this)) + user << "You fill [src] from [source]." + return + ..() \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/food/cans.dm b/code/modules/reagents/reagent_containers/food/cans.dm index f22392fe2aa..4a4479c8b1e 100644 --- a/code/modules/reagents/reagent_containers/food/cans.dm +++ b/code/modules/reagents/reagent_containers/food/cans.dm @@ -223,4 +223,12 @@ icon_state = "sodawater" New() ..() - reagents.add_reagent("sodawater", 50) \ No newline at end of file + reagents.add_reagent("sodawater", 50) + +/obj/item/weapon/reagent_containers/food/drinks/cans/synthanol + name = "Beep's Classic Synthanol" + desc = "A can of IPC booze, however that works." + icon_state = "synthanolcan" + New() + ..() + reagents.add_reagent("synthanol", 50) diff --git a/code/modules/reagents/reagent_containers/food/drinks.dm b/code/modules/reagents/reagent_containers/food/drinks.dm index 663158d0757..589ae649256 100644 --- a/code/modules/reagents/reagent_containers/food/drinks.dm +++ b/code/modules/reagents/reagent_containers/food/drinks.dm @@ -23,7 +23,7 @@ var/fillevel = gulp_size if(!R.total_volume || !R) - user << "\red None of [src] left, oh no!" + user << " None of [src] left, oh no!" return 0 if(M == user) @@ -31,10 +31,13 @@ if(istype(M,/mob/living/carbon/human)) var/mob/living/carbon/human/H = M if(!H.check_has_mouth()) - user << "Where do you intend to put \the [src]? You don't have a mouth!" - return - - M << "\blue You swallow a gulp of [src]." + if(!H.get_species() == "Machine") + user << "Where do you intend to put \the [src]? You don't have a mouth!" + return + else + M << " You pour a bit of liquid from [src] into your connection port." + else + M << " You swallow a gulp of [src]." if(reagents.total_volume) reagents.reaction(M, INGEST) spawn(0) @@ -45,15 +48,15 @@ else if( istype(M, /mob/living/carbon/human) ) var/mob/living/carbon/human/H = M - if(!H.check_has_mouth()) + if(!H.check_has_mouth() && !H.get_species() == "Machine") user << "Where do you intend to put \the [src]? \The [H] doesn't have a mouth!" return for(var/mob/O in viewers(world.view, user)) - O.show_message("\red [user] attempts to feed [M] [src].", 1) + O.show_message(" [user] attempts to feed [M] [src].", 1) if(!do_mob(user, M)) return for(var/mob/O in viewers(world.view, user)) - O.show_message("\red [user] feeds [M] [src].", 1) + O.show_message(" [user] feeds [M] [src].", 1) M.attack_log += text("\[[time_stamp()]\] Has been fed [src.name] by [key_name(user)] Reagents: [reagentlist(src)]") user.attack_log += text("\[[time_stamp()]\] Fed [M.name] by [key_name(M)] Reagents: [reagentlist(src)]") @@ -95,23 +98,23 @@ if(istype(target, /obj/structure/reagent_dispensers)) //A dispenser. Transfer FROM it TO us. if(!target.reagents.total_volume) - user << "\red [target] is empty." + user << " [target] is empty." return if(reagents.total_volume >= reagents.maximum_volume) - user << "\red [src] is full." + user << " [src] is full." return var/trans = target.reagents.trans_to(src, target:amount_per_transfer_from_this) - user << "\blue You fill [src] with [trans] units of the contents of [target]." + user << " You fill [src] with [trans] units of the contents of [target]." else if(target.is_open_container()) //Something like a glass. Player probably wants to transfer TO it. if(!reagents.total_volume) - user << "\red [src] is empty." + user << " [src] is empty." return if(target.reagents.total_volume >= target.reagents.maximum_volume) - user << "\red [target] is full." + user << " [target] is full." return @@ -123,7 +126,7 @@ refillName = reagents.get_master_reagent_name() var/trans = src.reagents.trans_to(target, amount_per_transfer_from_this) - user << "\blue You transfer [trans] units of the solution to [target]." + user << " You transfer [trans] units of the solution to [target]." if(isrobot(user)) //Cyborg modules that include drinks automatically refill themselves, but drain the borg's cell if(refill in drinks) // Only synthesize drinks @@ -152,15 +155,15 @@ if(!..(user, 1)) return if(!reagents || reagents.total_volume==0) - user << "\blue \The [src] is empty!" + user << " \The [src] is empty!" else if (reagents.total_volume<=src.volume/4) - user << "\blue \The [src] is almost empty!" + user << " \The [src] is almost empty!" else if (reagents.total_volume<=src.volume*0.66) - user << "\blue \The [src] is half empty!" // Pessimism is the real order of the day. + user << " \The [src] is half full!" // We're all optimistic, right?! else if (reagents.total_volume<=src.volume*0.90) - user << "\blue \The [src] is almost full!" + user << " \The [src] is almost full!" else - user << "\blue \The [src] is full!" + user << " \The [src] is full!" //////////////////////////////////////////////////////////////////////////////// @@ -404,4 +407,4 @@ desc = "A flask with a Lithium Atom symbol on it." icon = 'icons/obj/custom_items.dmi' icon_state = "lithiumflask" - volume = 50 \ No newline at end of file + volume = 50 diff --git a/code/modules/reagents/reagent_containers/food/drinks/drinkingglass.dm b/code/modules/reagents/reagent_containers/food/drinks/drinkingglass.dm index caab1e519c1..1ce5be29367 100644 --- a/code/modules/reagents/reagent_containers/food/drinks/drinkingglass.dm +++ b/code/modules/reagents/reagent_containers/food/drinks/drinkingglass.dm @@ -564,6 +564,24 @@ icon_state = "patronglass" name = "Jack Rose" desc = "Drinking this makes you feel like you belong in a luxury hotel bar during the 1920s." + if("synthanol") + icon_state = "synthanolglass" + name = "Glass of Synthanol" + desc = "The equivalent of alcohol for synthetic crewmembers. They'd find it awful if they had tastebuds too." + if("robottears") + icon_state = "robottearsglass" + name = "Glass of Robot Tears" + desc = "No robots were hurt in the making of this drink." + if("trinary") + icon_state = "trinaryglass" + name = "Glass of Trinary" + desc = "Colorful drink made for synthetic crewmembers. It doesn't seem like it would taste well." + if("servo") + icon_state = "servoglass" + name = "Glass of Servo" + desc = "Chocolate - based drink made for IPCs. Not sure if anyone's actually tried out the recipe." + + else icon_state ="glass_brown" name = "Glass of ..what?" diff --git a/code/modules/reagents/reagent_containers/food/snacks.dm b/code/modules/reagents/reagent_containers/food/snacks.dm index f9d0f1136a8..89d4817328f 100644 --- a/code/modules/reagents/reagent_containers/food/snacks.dm +++ b/code/modules/reagents/reagent_containers/food/snacks.dm @@ -397,13 +397,12 @@ New() ..() reagents.add_reagent("nutriment", 2) - reagents.add_reagent("chocolate",2) - reagents.add_reagent("coco", 2) + reagents.add_reagent("chocolate",4) bitesize = 2 -/obj/item/weapon/reagent_containers/food/snacks/cocoa_pile //for reagent chocolate being spilled on turfs - name = "Pile of Cocoa Powder" - desc = "A pile of pure cocoa powder." +/obj/item/weapon/reagent_containers/food/snacks/choc_pile //for reagent chocolate being spilled on turfs + name = "Pile of Chocolate" + desc = "A pile of pure chocolate pieces." icon_state = "cocoa" filling_color = "#7D5F46" @@ -421,8 +420,7 @@ New() ..() reagents.add_reagent("nutriment", 3) - reagents.add_reagent("chocolate",2) - reagents.add_reagent("coco", 2) + reagents.add_reagent("chocolate",4) bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/donut @@ -477,7 +475,7 @@ if(5) reagents.add_reagent("plasma", 3) if(6) - reagents.add_reagent("coco", 3) + reagents.add_reagent("chocolate", 3) if(7) reagents.add_reagent("slimejelly", 3) if(8) @@ -834,7 +832,7 @@ reagents.add_reagent("synaptizine", 15) reagents.add_reagent("salglu_solution", 15) reagents.add_reagent("salbutamol", 15) - reagents.add_reagent("methamphetamine", 15) + reagents.add_reagent("methamphetamine2", 15) /obj/item/weapon/reagent_containers/food/snacks/brainburger name = "brainburger" @@ -1674,6 +1672,13 @@ if(volume >= 5) return Expand() +/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wash(mob/user, atom/source) + if(wrapped) + ..() + return + if(do_after(user, 40, target = source)) + return 1 + /obj/item/weapon/reagent_containers/food/snacks/monkeycube/proc/Expand() if(isnull(gcDestroyed)) visible_message("[src] expands!") @@ -1759,6 +1764,29 @@ reagents.add_reagent("capsaicin", 6) bitesize = 4 +/obj/item/weapon/reagent_containers/food/snacks/burrito + name = "Burrito" + desc = "Meat, beans, cheese, and rice wrapped up as an easy-to-hold meal." + icon_state = "burrito" + trash = /obj/item/trash/plate + filling_color = "#A36A1F" + +/obj/item/weapon/reagent_containers/food/snacks/burrito/New() + ..() + reagents.add_reagent("nutriment", 5) + +/obj/item/weapon/reagent_containers/food/snacks/chimichanga + name = "Chimichanga" + desc = "Time to eat a chimi-f***ing-changa." + icon_state = "chimichanga" + trash = /obj/item/trash/plate + filling_color = "#A36A1F" + +/obj/item/weapon/reagent_containers/food/snacks/chimichanga/New() + ..() + reagents.add_reagent("omnizine", 4) //Deadpool reference. Deal with it. + reagents.add_reagent("cheese", 2) + /obj/item/weapon/reagent_containers/food/snacks/monkeysdelight name = "monkey's Delight" desc = "Eeee Eee!" @@ -3322,15 +3350,6 @@ ..() reagents.add_reagent("nutriment", 3) -// potato + knife = raw sticks -/obj/item/weapon/reagent_containers/food/snacks/grown/potato/attackby(obj/item/weapon/W as obj, mob/user as mob, params) - if(istype(W,/obj/item/weapon/kitchen/knife)) - new /obj/item/weapon/reagent_containers/food/snacks/rawsticks(src) - user << "You cut the potato." - qdel(src) - else - ..() - /obj/item/weapon/reagent_containers/food/snacks/rawsticks name = "raw potato sticks" desc = "Raw fries, not very tasty." diff --git a/code/modules/reagents/reagent_containers/food/snacks/candy.dm b/code/modules/reagents/reagent_containers/food/snacks/candy.dm index 8e067cef75f..9ddd19c7e2c 100644 --- a/code/modules/reagents/reagent_containers/food/snacks/candy.dm +++ b/code/modules/reagents/reagent_containers/food/snacks/candy.dm @@ -7,12 +7,13 @@ //Candy / Candy Ingredients //Subclass so we can pass on values -/obj/item/weapon/reagent_containers/food/snacks/candy/ +/obj/item/weapon/reagent_containers/food/snacks/candy name = "generic candy" desc = "It's placeholder flavored. This shouldn't be seen." icon = 'icons/obj/food/candy.dmi' icon_state = "candy" - New() + +/obj/item/weapon/reagent_containers/food/snacks/candy/New() ..() // *********************************************************** @@ -25,12 +26,11 @@ icon_state = "chocolatebar" filling_color = "#7D5F46" - New() - ..() - reagents.add_reagent("nutriment", 2) - reagents.add_reagent("chocolate",2) - reagents.add_reagent("coco", 2) - bitesize = 2 +/obj/item/weapon/reagent_containers/food/snacks/chocolatebar/New() + ..() + reagents.add_reagent("nutriment", 2) + reagents.add_reagent("chocolate",4) + bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/candy/caramel name = "Caramel" @@ -38,11 +38,11 @@ icon_state = "caramel" filling_color = "#DB944D" - New() - ..() - reagents.add_reagent("cream", 2) - reagents.add_reagent("sugar", 2) - bitesize = 2 +/obj/item/weapon/reagent_containers/food/snacks/candy/caramel/New() + ..() + reagents.add_reagent("cream", 2) + reagents.add_reagent("sugar", 2) + bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/candy/toffee name = "Toffee" @@ -50,11 +50,11 @@ icon_state = "toffee" filling_color = "#7D5F46" - New() - ..() - reagents.add_reagent("nutriment", 3) - reagents.add_reagent("sugar", 3) - bitesize = 2 +/obj/item/weapon/reagent_containers/food/snacks/candy/toffee/New() + ..() + reagents.add_reagent("nutriment", 3) + reagents.add_reagent("sugar", 3) + bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/candy/nougat name = "Nougat" @@ -62,11 +62,11 @@ icon_state = "nougat" filling_color = "#7D5F46" - New() - ..() - reagents.add_reagent("nutriment", 3) - reagents.add_reagent("sugar", 3) - bitesize = 2 +/obj/item/weapon/reagent_containers/food/snacks/candy/nougat/New() + ..() + reagents.add_reagent("nutriment", 3) + reagents.add_reagent("sugar", 3) + bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/candy/taffy name = "Saltwater Taffy" @@ -74,12 +74,12 @@ icon_state = "candy1" filling_color = "#7D5F46" - New() - ..() - icon_state = pick("candy1", "candy2", "candy3", "candy4", "candy5") - reagents.add_reagent("nutriment", 3) - reagents.add_reagent("sugar", 3) - bitesize = 2 +/obj/item/weapon/reagent_containers/food/snacks/candy/taffy/New() + ..() + icon_state = pick("candy1", "candy2", "candy3", "candy4", "candy5") + reagents.add_reagent("nutriment", 3) + reagents.add_reagent("sugar", 3) + bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/candy/fudge name = "Fudge" @@ -87,12 +87,11 @@ icon_state = "fudge" filling_color = "#7D5F46" - New() - ..() - reagents.add_reagent("cream", 3) - reagents.add_reagent("chocolate",3) - reagents.add_reagent("coco", 3) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/fudge/New() + ..() + reagents.add_reagent("cream", 3) + reagents.add_reagent("chocolate",6) + bitesize = 3 // *********************************************************** // Candy Products (Pre-existing) @@ -102,11 +101,12 @@ name = "Donor Candy" desc = "A little treat for blood donors." trash = /obj/item/trash/candy - New() - ..() - reagents.add_reagent("nutriment", 10) - reagents.add_reagent("sugar", 3) - bitesize = 5 + +/obj/item/weapon/reagent_containers/food/snacks/candy/donor/New() + ..() + reagents.add_reagent("nutriment", 10) + reagents.add_reagent("sugar", 3) + bitesize = 5 /obj/item/weapon/reagent_containers/food/snacks/candy_corn name = "candy corn" @@ -114,11 +114,11 @@ icon_state = "candy_corn" filling_color = "#FFFCB0" - New() - ..() - reagents.add_reagent("nutriment", 4) - reagents.add_reagent("sugar", 2) - bitesize = 2 +/obj/item/weapon/reagent_containers/food/snacks/candy_corn/New() + ..() + reagents.add_reagent("nutriment", 4) + reagents.add_reagent("sugar", 2) + bitesize = 2 // *********************************************************** // Candy Products (plain / unflavored) @@ -131,10 +131,10 @@ trash = /obj/item/weapon/c_tube filling_color = "#FFFFFF" - New() - ..() - reagents.add_reagent("sugar", 15) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/cotton/New() + ..() + reagents.add_reagent("sugar", 15) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/candybar name = "candy" @@ -143,11 +143,11 @@ trash = /obj/item/trash/candy filling_color = "#7D5F46" - New() - ..() - reagents.add_reagent("nutriment", 2) - reagents.add_reagent("chocolate",5) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/candybar/New() + ..() + reagents.add_reagent("nutriment", 2) + reagents.add_reagent("chocolate",5) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/candycane name = "candy cane" @@ -155,11 +155,11 @@ icon_state = "candycane" filling_color = "#F2F2F2" - New() - ..() - reagents.add_reagent("minttoxin", 1) - reagents.add_reagent("sugar", 5) - bitesize = 2 +/obj/item/weapon/reagent_containers/food/snacks/candy/candycane/New() + ..() + reagents.add_reagent("minttoxin", 1) + reagents.add_reagent("sugar", 5) + bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/candy/gummybear name = "gummy bear" @@ -167,10 +167,10 @@ icon_state = "gbear" filling_color = "#FFFFFF" - New() - ..() - reagents.add_reagent("sugar", 10) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/gummybear/New() + ..() + reagents.add_reagent("sugar", 10) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/gummyworm name = "gummy worm" @@ -178,10 +178,10 @@ icon_state = "gworm" filling_color = "#FFFFFF" - New() - ..() - reagents.add_reagent("sugar", 10) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/gummyworm/New() + ..() + reagents.add_reagent("sugar", 10) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/jellybean name = "jelly bean" @@ -189,10 +189,10 @@ icon_state = "jbean" filling_color = "#FFFFFF" - New() - ..() - reagents.add_reagent("sugar", 10) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/New() + ..() + reagents.add_reagent("sugar", 10) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/jawbreaker name = "jawbreaker" @@ -200,10 +200,10 @@ icon_state = "jawbreaker" filling_color = "#ED0758" - New() - ..() - reagents.add_reagent("sugar", 10) - bitesize = 0.1 //this is gonna take a while, you'll be working at this all shift. +/obj/item/weapon/reagent_containers/food/snacks/candy/jawbreaker/New() + ..() + reagents.add_reagent("sugar", 10) + bitesize = 0.1 //this is gonna take a while, you'll be working at this all shift. /obj/item/weapon/reagent_containers/food/snacks/candy/cash name = "candy cash" @@ -211,12 +211,11 @@ icon_state = "candy_cash" filling_color = "#302000" - New() - ..() - reagents.add_reagent("nutriment", 2) - reagents.add_reagent("sugar", 2) - reagents.add_reagent("coco", 2) - bitesize = 2 +/obj/item/weapon/reagent_containers/food/snacks/candy/cash/New() + ..() + reagents.add_reagent("nutriment", 2) + reagents.add_reagent("chocolate", 4) + bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/candy/coin name = "chocolate coin" @@ -224,12 +223,11 @@ icon_state = "choc_coin" filling_color = "#302000" - New() - ..() - reagents.add_reagent("nutriment", 2) - reagents.add_reagent("chocolate",2) - reagents.add_reagent("coco", 2) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/coin/New() + ..() + reagents.add_reagent("nutriment", 2) + reagents.add_reagent("chocolate",4) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/gum name = "bubblegum" @@ -238,10 +236,10 @@ trash = /obj/item/trash/gum filling_color = "#FF7495" - New() - ..() - reagents.add_reagent("sugar", 5) - bitesize = 0.2 +/obj/item/weapon/reagent_containers/food/snacks/candy/gum/New() + ..() + reagents.add_reagent("sugar", 5) + bitesize = 0.2 /obj/item/weapon/reagent_containers/food/snacks/candy/sucker name = "sucker" @@ -249,10 +247,10 @@ icon_state = "sucker" filling_color = "#FFFFFF" - New() - ..() - reagents.add_reagent("sugar", 10) - bitesize = 1 +/obj/item/weapon/reagent_containers/food/snacks/candy/sucker/New() + ..() + reagents.add_reagent("sugar", 10) + bitesize = 1 // *********************************************************** // Gummy Bear Flavors @@ -264,10 +262,10 @@ icon_state = "gbear_red" filling_color = "#801E28" - New() - ..() - reagents.add_reagent("cherryjelly", 2) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/gummybear/red/New() + ..() + reagents.add_reagent("cherryjelly", 2) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/gummybear/blue name = "gummy bear" @@ -275,10 +273,10 @@ icon_state = "gbear_blue" filling_color = "#863333" - New() - ..() - reagents.add_reagent("berryjuice", 2) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/gummybear/blue/New() + ..() + reagents.add_reagent("berryjuice", 2) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/gummybear/poison name = "gummy bear" @@ -286,13 +284,12 @@ icon_state = "gbear_blue" filling_color = "#863353" - New() - ..() - reagents.add_reagent("poisonberryjuice", 12) - reagents.del_reagent("sugar") - reagents.update_total() - bitesize = 3 - +/obj/item/weapon/reagent_containers/food/snacks/candy/gummybear/poison/New() + ..() + reagents.add_reagent("poisonberryjuice", 12) + reagents.del_reagent("sugar") + reagents.update_total() + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/gummybear/green name = "gummy bear" @@ -300,10 +297,10 @@ icon_state = "gbear_green" filling_color = "#365E30" - New() - ..() - reagents.add_reagent("limejuice", 2) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/gummybear/green/New() + ..() + reagents.add_reagent("limejuice", 2) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/gummybear/yellow name = "gummy bear" @@ -311,10 +308,10 @@ icon_state = "gbear_yellow" filling_color = "#863333" - New() - ..() - reagents.add_reagent("lemonjuice", 2) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/gummybear/yellow/New() + ..() + reagents.add_reagent("lemonjuice", 2) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/gummybear/orange name = "gummy bear" @@ -322,10 +319,10 @@ icon_state = "gbear_orange" filling_color = "#E78108" - New() - ..() - reagents.add_reagent("orangejuice", 2) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/gummybear/orange/New() + ..() + reagents.add_reagent("orangejuice", 2) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/gummybear/purple name = "gummy bear" @@ -333,10 +330,10 @@ icon_state = "gbear_purple" filling_color = "#993399" - New() - ..() - reagents.add_reagent("grapejuice", 2) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/gummybear/purple/New() + ..() + reagents.add_reagent("grapejuice", 2) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/gummybear/wtf name = "gummy bear" @@ -344,11 +341,10 @@ icon_state = "gbear_wtf" filling_color = "#60A584" - New() - ..() - reagents.add_reagent("space_drugs", 2) - bitesize = 3 - +/obj/item/weapon/reagent_containers/food/snacks/candy/gummybear/wtf/New() + ..() + reagents.add_reagent("space_drugs", 2) + bitesize = 3 // *********************************************************** // Gummy Worm Flavors @@ -360,10 +356,10 @@ icon_state = "gworm_red" filling_color = "#801E28" - New() - ..() - reagents.add_reagent("cherryjelly", 2) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/gummyworm/red/New() + ..() + reagents.add_reagent("cherryjelly", 2) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/gummyworm/blue name = "gummy worm" @@ -371,10 +367,10 @@ icon_state = "gworm_blue" filling_color = "#863333" - New() - ..() - reagents.add_reagent("berryjuice", 2) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/gummyworm/blue/New() + ..() + reagents.add_reagent("berryjuice", 2) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/gummyworm/poison name = "gummy worm" @@ -382,12 +378,12 @@ icon_state = "gworm_blue" filling_color = "#863353" - New() - ..() - reagents.add_reagent("poisonberryjuice", 12) - reagents.del_reagent("sugar") - reagents.update_total() - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/gummyworm/poison/New() + ..() + reagents.add_reagent("poisonberryjuice", 12) + reagents.del_reagent("sugar") + reagents.update_total() + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/gummyworm/green name = "gummy worm" @@ -395,10 +391,10 @@ icon_state = "gworm_green" filling_color = "#365E30" - New() - ..() - reagents.add_reagent("limejuice", 10) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/gummyworm/green/New() + ..() + reagents.add_reagent("limejuice", 10) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/gummyworm/yellow name = "gummy worm" @@ -406,10 +402,10 @@ icon_state = "gworm_yellow" filling_color = "#863333" - New() - ..() - reagents.add_reagent("lemonjuice", 2) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/gummyworm/yellow/New() + ..() + reagents.add_reagent("lemonjuice", 2) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/gummyworm/orange name = "gummy worm" @@ -417,10 +413,10 @@ icon_state = "gworm_orange" filling_color = "#E78108" - New() - ..() - reagents.add_reagent("orangejuice", 2) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/gummyworm/orange/New() + ..() + reagents.add_reagent("orangejuice", 2) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/gummyworm/purple name = "gummy worm" @@ -428,10 +424,10 @@ icon_state = "gworm_purple" filling_color = "#993399" - New() - ..() - reagents.add_reagent("grapejuice", 2) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/gummyworm/purple/New() + ..() + reagents.add_reagent("grapejuice", 2) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/gummyworm/wtf name = "gummy worm" @@ -439,11 +435,10 @@ icon_state = "gworm_wtf" filling_color = "#60A584" - New() - ..() - reagents.add_reagent("space_drugs", 2) - bitesize = 3 - +/obj/item/weapon/reagent_containers/food/snacks/candy/gummyworm/wtf/New() + ..() + reagents.add_reagent("space_drugs", 2) + bitesize = 3 // *********************************************************** // Jelly Bean Flavors @@ -455,10 +450,10 @@ icon_state = "jbean_red" filling_color = "#801E28" - New() - ..() - reagents.add_reagent("cherryjelly", 2) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/red/New() + ..() + reagents.add_reagent("cherryjelly", 2) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/blue name = "jelly bean" @@ -466,10 +461,10 @@ icon_state = "jbean_blue" filling_color = "#863333" - New() - ..() - reagents.add_reagent("berryjuice", 2) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/blue/New() + ..() + reagents.add_reagent("berryjuice", 2) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/poison name = "jelly bean" @@ -477,12 +472,12 @@ icon_state = "jbean_blue" filling_color = "#863353" - New() - ..() - reagents.add_reagent("poisonberryjuice", 12) - reagents.del_reagent("sugar") - reagents.update_total() - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/poison/New() + ..() + reagents.add_reagent("poisonberryjuice", 12) + reagents.del_reagent("sugar") + reagents.update_total() + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/green name = "jelly bean" @@ -490,10 +485,10 @@ icon_state = "jbean_green" filling_color = "#365E30" - New() - ..() - reagents.add_reagent("limejuice", 2) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/green/New() + ..() + reagents.add_reagent("limejuice", 2) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/yellow name = "jelly bean" @@ -501,10 +496,10 @@ icon_state = "jbean_yellow" filling_color = "#863333" - New() - ..() - reagents.add_reagent("lemonjuice", 2) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/yellow/New() + ..() + reagents.add_reagent("lemonjuice", 2) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/orange name = "jelly bean" @@ -512,10 +507,10 @@ icon_state = "jbean_orange" filling_color = "#E78108" - New() - ..() - reagents.add_reagent("orangejuice", 2) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/orange/New() + ..() + reagents.add_reagent("orangejuice", 2) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/purple name = "jelly bean" @@ -523,10 +518,10 @@ icon_state = "jbean_purple" filling_color = "#993399" - New() - ..() - reagents.add_reagent("grapejuice", 2) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/purple/New() + ..() + reagents.add_reagent("grapejuice", 2) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/chocolate name = "jelly bean" @@ -534,10 +529,10 @@ icon_state = "jbean_choc" filling_color = "#302000" - New() - ..() - reagents.add_reagent("chocolate",2) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/chocolate/New() + ..() + reagents.add_reagent("chocolate",2) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/popcorn name = "jelly bean" @@ -545,10 +540,10 @@ icon_state = "jbean_popcorn" filling_color = "#664330" - New() - ..() - reagents.add_reagent("nutriment", 2) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/popcorn/New() + ..() + reagents.add_reagent("nutriment", 2) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/cola name = "jelly bean" @@ -556,10 +551,10 @@ icon_state = "jbean_cola" filling_color = "#102000" - New() - ..() - reagents.add_reagent("cola", 2) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/cola/New() + ..() + reagents.add_reagent("cola", 2) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/drgibb name = "jelly bean" @@ -567,10 +562,10 @@ icon_state = "jbean_cola" filling_color = "#102000" - New() - ..() - reagents.add_reagent("dr_gibb", 2) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/drgibb/New() + ..() + reagents.add_reagent("dr_gibb", 2) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/coffee name = "jelly bean" @@ -578,10 +573,10 @@ icon_state = "jbean_choc" filling_color = "#482000" - New() - ..() - reagents.add_reagent("coffee", 2) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/coffee/New() + ..() + reagents.add_reagent("coffee", 2) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/wtf name = "jelly bean" @@ -589,10 +584,10 @@ icon_state = "jbean_wtf" filling_color = "#60A584" - New() - ..() - reagents.add_reagent("space_drugs", 2) - bitesize = 3 +/obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/wtf/New() + ..() + reagents.add_reagent("space_drugs", 2) + bitesize = 3 // *********************************************************** // Cotton Candy Flavors @@ -605,10 +600,10 @@ trash = /obj/item/weapon/c_tube filling_color = "#801E28" - New() - ..() - reagents.add_reagent("cherryjelly", 5) - bitesize = 4 +/obj/item/weapon/reagent_containers/food/snacks/candy/cotton/red/New() + ..() + reagents.add_reagent("cherryjelly", 5) + bitesize = 4 /obj/item/weapon/reagent_containers/food/snacks/candy/cotton/blue name = "cotton candy" @@ -617,10 +612,10 @@ trash = /obj/item/weapon/c_tube filling_color = "#863333" - New() - ..() - reagents.add_reagent("berryjuice", 5) - bitesize = 4 +/obj/item/weapon/reagent_containers/food/snacks/candy/cotton/blue/New() + ..() + reagents.add_reagent("berryjuice", 5) + bitesize = 4 /obj/item/weapon/reagent_containers/food/snacks/candy/cotton/poison name = "cotton candy" @@ -629,12 +624,12 @@ trash = /obj/item/weapon/c_tube filling_color = "#863353" - New() - ..() - reagents.add_reagent("poisonberryjuice", 20) - reagents.del_reagent("sugar") - reagents.update_total() - bitesize = 4 +/obj/item/weapon/reagent_containers/food/snacks/candy/cotton/poison/New() + ..() + reagents.add_reagent("poisonberryjuice", 20) + reagents.del_reagent("sugar") + reagents.update_total() + bitesize = 4 /obj/item/weapon/reagent_containers/food/snacks/candy/cotton/green name = "cotton candy" @@ -643,10 +638,10 @@ trash = /obj/item/weapon/c_tube filling_color = "#365E30" - New() - ..() - reagents.add_reagent("limejuice", 5) - bitesize = 4 +/obj/item/weapon/reagent_containers/food/snacks/candy/cotton/green/New() + ..() + reagents.add_reagent("limejuice", 5) + bitesize = 4 /obj/item/weapon/reagent_containers/food/snacks/candy/cotton/yellow name = "cotton candy" @@ -655,10 +650,10 @@ trash = /obj/item/weapon/c_tube filling_color = "#863333" - New() - ..() - reagents.add_reagent("lemonjuice", 5) - bitesize = 4 +/obj/item/weapon/reagent_containers/food/snacks/candy/cotton/yellow/New() + ..() + reagents.add_reagent("lemonjuice", 5) + bitesize = 4 /obj/item/weapon/reagent_containers/food/snacks/candy/cotton/orange name = "cotton candy" @@ -667,10 +662,10 @@ trash = /obj/item/weapon/c_tube filling_color = "#E78108" - New() - ..() - reagents.add_reagent("orangejuice", 5) - bitesize = 4 +/obj/item/weapon/reagent_containers/food/snacks/candy/cotton/orange/New() + ..() + reagents.add_reagent("orangejuice", 5) + bitesize = 4 /obj/item/weapon/reagent_containers/food/snacks/candy/cotton/purple name = "cotton candy" @@ -679,10 +674,10 @@ trash = /obj/item/weapon/c_tube filling_color = "#993399" - New() - ..() - reagents.add_reagent("grapejuice", 5) - bitesize = 4 +/obj/item/weapon/reagent_containers/food/snacks/candy/cotton/purple/New() + ..() + reagents.add_reagent("grapejuice", 5) + bitesize = 4 /obj/item/weapon/reagent_containers/food/snacks/candy/cotton/pink name = "cotton candy" @@ -691,10 +686,10 @@ trash = /obj/item/weapon/c_tube filling_color = "#863333" - New() - ..() - reagents.add_reagent("watermelonjuice", 5) - bitesize = 4 +/obj/item/weapon/reagent_containers/food/snacks/candy/cotton/pink/New() + ..() + reagents.add_reagent("watermelonjuice", 5) + bitesize = 4 /obj/item/weapon/reagent_containers/food/snacks/candy/cotton/rainbow name = "cotton candy" @@ -703,12 +698,12 @@ trash = /obj/item/weapon/c_tube filling_color = "#C8A5DC" - New() - ..() - reagents.add_reagent("omnizine", 20) - reagents.del_reagent("sugar") - reagents.update_total() - bitesize = 4 +/obj/item/weapon/reagent_containers/food/snacks/candy/cotton/rainbow/New() + ..() + reagents.add_reagent("omnizine", 20) + reagents.del_reagent("sugar") + reagents.update_total() + bitesize = 4 /obj/item/weapon/reagent_containers/food/snacks/candy/cotton/bad_rainbow name = "cotton candy" @@ -717,12 +712,12 @@ trash = /obj/item/weapon/c_tube filling_color = "#32127A" - New() - ..() - reagents.add_reagent("sulfonal", 20) - reagents.del_reagent("sugar") - reagents.update_total() - bitesize = 4 +/obj/item/weapon/reagent_containers/food/snacks/candy/cotton/bad_rainbow/New() + ..() + reagents.add_reagent("sulfonal", 20) + reagents.del_reagent("sugar") + reagents.update_total() + bitesize = 4 // *********************************************************** // Candybar Flavors @@ -735,41 +730,26 @@ trash = /obj/item/trash/candy filling_color = "#7D5F46" - New() - ..() - /obj/item/weapon/reagent_containers/food/snacks/candy/candybar/toffee name = "Yum-baton Bar" desc = "Chocolate and toffee in the shape of a baton. Security sure knows how to pound these down!" icon_state = "yumbaton" filling_color = "#7D5F46" - New() - ..() - /obj/item/weapon/reagent_containers/food/snacks/candy/candybar/caramel name = "Malper Bar" desc = "A chocolate syringe filled with a caramel injection. Just what the doctor ordered!" icon_state = "malper" filling_color = "#7D5F46" - New() - ..() - /obj/item/weapon/reagent_containers/food/snacks/candy/candybar/caramel_nougat name = "Toxins Test Bar" desc = "An explosive combination of chocolate, caramel, and nougat. Research has never been so tasty!" icon_state = "toxinstest" filling_color = "#7D5F46" - New() - ..() - /obj/item/weapon/reagent_containers/food/snacks/candy/candybar/nougat name = "Tool-erone Bar" desc = "Chocolate-covered nougat, shaped like a wrench. Great for an engineer on the go!" icon_state = "toolerone" filling_color = "#7D5F46" - - New() - ..() \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/glass_containers.dm b/code/modules/reagents/reagent_containers/glass_containers.dm index a10e265fecf..b7c891370b0 100644 --- a/code/modules/reagents/reagent_containers/glass_containers.dm +++ b/code/modules/reagents/reagent_containers/glass_containers.dm @@ -23,6 +23,7 @@ /obj/structure/table, /obj/structure/closet, /obj/structure/sink, + /obj/structure/toilet, /obj/item/weapon/storage, /obj/machinery/atmospherics/unary/cryo_cell, /obj/machinery/dna_scannernew, @@ -336,7 +337,7 @@ materials = list(MAT_METAL=200) w_class = 3.0 amount_per_transfer_from_this = 20 - possible_transfer_amounts = list(5,10,15,25,30,50,80,100,120) + possible_transfer_amounts = list(5,10,15,20,25,30,50,80,100,120) volume = 120 flags = OPENCONTAINER diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index 802c2a5f25d..ed2809896c7 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -92,6 +92,7 @@ icon_state = "weldtank" amount_per_transfer_from_this = 10 var/obj/item/device/assembly_holder/rig = null + var/accepts_rig = 1 /obj/structure/reagent_dispensers/fueltank/New() ..() @@ -126,7 +127,7 @@ overlays = new/list() /obj/structure/reagent_dispensers/fueltank/attackby(obj/item/weapon/W as obj, mob/user as mob, params) - if (istype(W,/obj/item/device/assembly_holder)) + if (istype(W,/obj/item/device/assembly_holder) && accepts_rig) if (rig) user << "\red There is another device in the way." return ..() @@ -254,3 +255,9 @@ /obj/structure/reagent_dispensers/spacecleanertank/New() ..() reagents.add_reagent("cleaner",5000) + +/obj/structure/reagent_dispensers/fueltank/chem + icon_state = "weldingtank_chem" + anchored = 1 + density = 0 + accepts_rig = 0 \ No newline at end of file diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm index 6e5bcf0389b..68b0090e317 100644 --- a/code/modules/research/designs/autolathe_designs.dm +++ b/code/modules/research/designs/autolathe_designs.dm @@ -273,6 +273,14 @@ materials = list(MAT_METAL = 100) build_path = /obj/item/weapon/canvas/twentythreeXtwentythree category = list("initial", "Miscellaneous") + +/datum/design/glass_picture_frame + name = "Glass Picture Frame" + id = "glass_picture_frame" + build_type = AUTOLATHE + materials = list(MAT_METAL = 25, MAT_GLASS = 75) + build_path = /obj/item/weapon/picture_frame/glass + category = list("initial", "Miscellaneous") /datum/design/camera_assembly name = "Camera Assembly" diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index fb97c2b693c..25ec52af226 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -490,4 +490,14 @@ build_type = IMPRINTER materials = list(MAT_GLASS=1000, "sacid"=20) build_path = /obj/item/weapon/circuitboard/clawgame - category = list ("Misc. Machinery") \ No newline at end of file + category = list ("Misc. Machinery") + +/datum/design/prize_counter + name = "Machine Design (Prize Counter)" + desc = "The circuit board for an arcade Prize Counter." + id = "prize_counter" + req_tech = list("programming" = 2, "materials" = 2) + build_type = IMPRINTER + materials = list(MAT_GLASS=1000, "sacid"=20) + build_path = /obj/item/weapon/circuitboard/prize_counter + category = list("Misc. Machinery") \ No newline at end of file diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index c3d48fdb88e..227cd4618a4 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -984,7 +984,7 @@ name = "IPC Microbattery" id = "ipc_cell" build_type = MECHFAB - build_path = /obj/item/organ/cell + build_path = /obj/item/organ/internal/cell materials = list(MAT_METAL=2000, MAT_GLASS=750) construction_time = 200 category = list("Misc") @@ -993,7 +993,7 @@ name = "IPC Optical Sensor" id = "ipc_optics" build_type = MECHFAB - build_path = /obj/item/organ/optical_sensor + build_path = /obj/item/organ/internal/optical_sensor materials = list(MAT_METAL=1000, MAT_GLASS=2500) construction_time = 200 category = list("Misc") \ No newline at end of file diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index d0ed135176f..e5d0775457f 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -198,6 +198,111 @@ build_path = /obj/item/weapon/scalpel/manager category = list("Medical") + +///////////////////////////////////////// +//////////Cybernetic Implants//////////// +///////////////////////////////////////// + +/datum/design/cyberimp_welding + name = "Welding Shield implant" + desc = "These reactive micro-shields will protect you from welders and flashes without obscuring your vision." + id = "ci-welding" + req_tech = list("materials" = 4, "biotech" = 2) + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 200, MAT_GLASS = 400) + build_path = /obj/item/organ/internal/cyberimp/eyes/shield + category = list("Misc", "Medical Designs") + +/datum/design/cyberimp_medical_hud + name = "Medical HUD implant" + desc = "These cybernetic eyes will display a medical HUD over everything you see. Wiggle eyes to control." + id = "ci-medhud" + req_tech = list("materials" = 6, "programming" = 4, "biotech" = 4) + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_SILVER = 500, MAT_GOLD = 500) + build_path = /obj/item/organ/internal/cyberimp/eyes/hud/medical + category = list("Misc", "Medical Designs") + +/datum/design/cyberimp_security_hud + name = "Security HUD implant" + desc = "These cybernetic eyes will display a security HUD over everything you see. Wiggle eyes to control." + id = "ci-sechud" + req_tech = list("materials" = 6, "programming" = 5, "biotech" = 4, "combat" = 2) + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_SILVER = 750, MAT_GOLD = 750) + build_path = /obj/item/organ/internal/cyberimp/eyes/hud/security + category = list("Misc", "Medical Designs") + +/datum/design/cyberimp_xray + name = "X-Ray implant" + desc = "These cybernetic eyes will give you X-ray vision. Blinking is futile." + id = "ci-xray" + req_tech = list("materials" = 7, "programming" = 5, "biotech" = 6, "magnets" = 5) + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_SILVER = 600, MAT_GOLD = 600, MAT_PLASMA = 1000, MAT_URANIUM = 1000, MAT_DIAMOND = 2000) + build_path = /obj/item/organ/internal/cyberimp/eyes/xray + category = list("Misc", "Medical Designs") + +/datum/design/cyberimp_thermals + name = "Thermals implant" + desc = "These cybernetic eyes will give you Thermal vision. Vertical slit pupil included." + id = "ci-thermals" + req_tech = list("materials" = 7, "programming" = 5, "biotech" = 5, "magnets" = 5, "syndicate" = 5) + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_SILVER = 600, MAT_GOLD = 600, MAT_PLASMA = 1000, MAT_DIAMOND = 2000) + build_path = /obj/item/organ/internal/cyberimp/eyes/thermals + category = list("Misc", "Medical Designs") + +/datum/design/cyberimp_antidrop + name = "Anti-Drop implant" + desc = "This cybernetic brain implant will allow you to force your hand muscles to contract, preventing item dropping. Twitch ear to toggle." + id = "ci-antidrop" + req_tech = list("materials" = 7, "programming" = 5, "biotech" = 5) + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_SILVER = 400, MAT_GOLD = 400) + build_path = /obj/item/organ/internal/cyberimp/brain/anti_drop + category = list("Medical Designs") + +/datum/design/cyberimp_antistun + name = "CNS Rebooter implant" + desc = "This implant will automatically give you back control over your central nervous system, reducing downtime when stunned." + id = "ci-antistun" + req_tech = list("materials" = 7, "programming" = 5, "biotech" = 6) + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_SILVER = 500, MAT_GOLD = 1000) + build_path = /obj/item/organ/internal/cyberimp/brain/anti_stun + category = list("Medical Designs") + +/datum/design/cyberimp_nutriment + name = "Nutriment pump implant" + desc = "This implant with synthesize and pump into your bloodstream a small amount of nutriment when you are starving." + id = "ci-nutriment" + req_tech = list("materials" = 6, "programming" = 4, "biotech" = 5) + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_GOLD = 500, MAT_URANIUM = 500) + build_path = /obj/item/organ/internal/cyberimp/chest/nutriment + category = list("Medical Designs") + +/datum/design/cyberimp_nutriment_plus + name = "Nutriment pump implant PLUS" + desc = "This implant with synthesize and pump into your bloodstream a small amount of nutriment when you are hungry." + id = "ci-nutrimentplus" + req_tech = list("materials" = 6, "programming" = 4, "biotech" = 6) + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_GOLD = 500, MAT_URANIUM = 750) + build_path = /obj/item/organ/internal/cyberimp/chest/nutriment/plus + category = list("Medical Designs") + +/datum/design/cyberimp_reviver + name = "Reviver implant" + desc = "This implant will attempt to revive you if you lose consciousness. For the faint of heart!" + id = "ci-reviver" + req_tech = list("materials" = 6, "programming" = 4, "biotech" = 7, "syndicate" = 4) + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_GOLD = 500, MAT_URANIUM = 1000, MAT_DIAMOND = 2000) + build_path = /obj/item/organ/internal/cyberimp/chest/reviver + category = list("Misc", "Medical Designs") + ///////////////////////////////////////// ////////////Regular Implants///////////// ///////////////////////////////////////// diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm index 01917cb8ba0..4ce1f95e8d3 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -270,4 +270,15 @@ materials = list(MAT_GOLD = 5000,MAT_URANIUM = 10000, MAT_METAL = 4000) build_path = /obj/item/weapon/gun/energy/xray locked = 1 + category = list("Weapons") + +/datum/design/immolator + name = "Immolator Laser Gun" + desc = "Has fewer shots than a regular laser gun, but ignites the target on hit" + id = "immolator" + req_tech = list("combat" = 4, "materials" = 5, "powerstorage" = 5, "magnets" = 4) + build_type = PROTOLATHE + materials = list(MAT_METAL = 4000, MAT_GLASS = 1000, MAT_SILVER = 3000, MAT_PLASMA = 2000) + build_path = /obj/item/weapon/gun/energy/immolator + locked = 1 category = list("Weapons") \ No newline at end of file diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index d5f3d72e01e..62784d8c8ca 100644 --- a/code/modules/research/experimentor.dm +++ b/code/modules/research/experimentor.dm @@ -170,28 +170,25 @@ if(!linked_console) dat += "Scan for R&D Console
    " if(loaded_item) - if(recentlyExperimented) - dat += "The [src] is still resetting!" - else - dat += "Loaded Item: [loaded_item]
    " - dat += "Technology:
    " - var/list/D = ConvertReqString2List(loaded_item.origin_tech) - for(var/T in D) - dat += "[T]
    " - dat += "

    Available tests:" - dat += "
    Poke" - dat += "
    Irradiate" - dat += "
    Gas" - dat += "
    Burn" - dat += "
    Freeze" - dat += "
    Destroy
    " - if(istype(loaded_item,/obj/item/weapon/relic)) - dat += "
    Discover
    " - dat += "
    Eject" + dat += "Loaded Item: [loaded_item]
    " + dat += "Technology:
    " + var/list/D = ConvertReqString2List(loaded_item.origin_tech) + for(var/T in D) + dat += "[T]
    " + dat += "

    Available tests:" + dat += "
    Poke" + dat += "
    Irradiate" + dat += "
    Gas" + dat += "
    Burn" + dat += "
    Freeze" + dat += "
    Destroy
    " + if(istype(loaded_item,/obj/item/weapon/relic)) + dat += "
    Discover
    " + dat += "
    Eject" else dat += "Nothing loaded." dat += "
    Refresh
    " - dat += "
    Close
    " + dat += "
    Close
    " var/datum/browser/popup = new(user, "experimentor","Experimentor", 700, 400, src) popup.set_content(dat) popup.open() @@ -460,27 +457,23 @@ visible_message("[src]'s crusher goes way too many levels too high, crushing right through space-time!") playsound(src.loc, 'sound/effects/supermatter.ogg', 50, 1, -3) investigate_log("Experimentor has triggered the 'throw things' reaction.", "experimentor") - var/list/throwAt = list() - for(var/i in oview(7,src)) - if(istype(i,/obj/item) || istype(i,/mob/living)) - throwAt.Add(i) - var/counter - for(counter = 1, counter < throwAt.len, ++counter) - var/cast = throwAt[counter] - cast:throw_at(src,10,1) + for(var/atom/movable/AM in oview(7,src)) + if(!AM.anchored) + spawn(0) + AM.throw_at(src,10,1) + if(prob(EFFECT_PROB_LOW-badThingCoeff)) visible_message("[src]'s crusher goes one level too high, crushing right into space-time!") playsound(src.loc, 'sound/effects/supermatter.ogg', 50, 1, -3) investigate_log("Experimentor has triggered the 'minor throw things' reaction.", "experimentor") - var/list/oViewStuff = oview(7,src) var/list/throwAt = list() - for(var/i in oViewStuff) - if(istype(i,/obj/item) || istype(i,/mob/living)) - throwAt.Add(i) - var/counter - for(counter = 1, counter < throwAt.len, ++counter) - var/cast = throwAt[counter] - cast:throw_at(pick(throwAt),10,1) + for(var/atom/movable/AM in oview(7,src)) + if(!AM.anchored) + throwAt.Add(AM) + for(var/counter = 1, counter < throwAt.len, ++counter) + var/atom/movable/cast = throwAt[counter] + spawn(0) + cast.throw_at(pick(throwAt),10,1) ejectItem(TRUE) //////////////////////////////////////////////////////////////////////////////////////////////// if(exp == FAIL) @@ -553,8 +546,9 @@ var/scantype = href_list["function"] var/obj/item/process = locate(href_list["item"]) in src - if(scantype == "close") + if(href_list["close"]) usr << browse(null, "window=experimentor") + return else if(scantype == "search") var/obj/machinery/computer/rdconsole/D = locate(/obj/machinery/computer/rdconsole) in oview(3,src) if(D) @@ -567,6 +561,14 @@ if(recentlyExperimented) usr << "[src] has been used too recently!" return + else if(!loaded_item) + updateUsrDialog() //Set the interface to unloaded mode + usr << "[src] is not currently loaded!" + return + else if(!process || process != loaded_item) //Interface exploit protection (such as hrefs or swapping items with interface set to old item) + updateUsrDialog() //Refresh interface to update interface hrefs + usr << "Interface failure detected in [src]. Please try again." + return var/dotype if(text2num(scantype) == SCANTYPE_DISCOVER) dotype = SCANTYPE_DISCOVER @@ -579,9 +581,8 @@ var/list/temp_tech = ConvertReqString2List(process.origin_tech) for(var/T in temp_tech) linked_console.files.UpdateTech(T, temp_tech[T]) - linked_console.files.UpdateDesigns(process,process.type) - if(scantype != "close") - src.updateUsrDialog() + linked_console.files.UpdateDesigns(process,temp_tech) + src.updateUsrDialog() return //~~~~~~~~Admin logging proc, aka the Powergamer Alarm~~~~~~~~ diff --git a/code/modules/research/message_server.dm b/code/modules/research/message_server.dm index 7159f83ab0d..9d2c0dd1bb9 100644 --- a/code/modules/research/message_server.dm +++ b/code/modules/research/message_server.dm @@ -111,7 +111,7 @@ var/global/list/obj/machinery/message_server/message_servers = list() Console.set_light(2) /obj/machinery/message_server/attack_hand(user as mob) -// user << "\blue There seem to be some parts missing from this server. They should arrive on the station in a few days, give or take a few CentCom delays." +// user << "\blue There seem to be some parts missing from this server. They should arrive on the station in a few days, give or take a few CentComm delays." user << "You toggle PDA message passing from [active ? "On" : "Off"] to [active ? "Off" : "On"]" active = !active update_icon() diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index 6112d6f5a9b..017bf478bd4 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -177,6 +177,7 @@ proc/CallMaterialName(ID) /obj/machinery/computer/rdconsole/emag_act(user as mob) if(!emagged) playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) + req_access = list() emagged = 1 user << "You disable the security protocols" diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_hurt.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_hurt.dm index 17ed53282db..5a4f402269f 100644 --- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_hurt.dm +++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_hurt.dm @@ -17,7 +17,7 @@ C.apply_effect(25 * weakness,IRRADIATE,0) C.nutrition -= min(50 * weakness, C.nutrition) C.Dizzy(6 * weakness) - C.weakened += 6 * weakness + C.AdjustWeakened(6 * weakness) /datum/artifact_effect/hurt/DoEffectAura() if(holder) diff --git a/code/modules/research/xenoarchaeology/tools/suspension_generator.dm b/code/modules/research/xenoarchaeology/tools/suspension_generator.dm index e5a13d5fde2..f377d7322c8 100644 --- a/code/modules/research/xenoarchaeology/tools/suspension_generator.dm +++ b/code/modules/research/xenoarchaeology/tools/suspension_generator.dm @@ -28,14 +28,14 @@ var/turf/T = get_turf(suspension_field) if(field_type == "carbon") for(var/mob/living/carbon/M in T) - M.weakened = max(M.weakened, 3) + M.Weaken(3) cell.charge -= power_use if(prob(5)) M << "\blue [pick("You feel tingly.","You feel like floating.","It is hard to speak.","You can barely move.")]" if(field_type == "iron") for(var/mob/living/silicon/M in T) - M.weakened = max(M.weakened, 3) + M.Weaken(3) cell.charge -= power_use if(prob(5)) M << "\blue [pick("You feel tingly.","You feel like floating.","It is hard to speak.","You can barely move.")]" @@ -47,7 +47,7 @@ I.loc = suspension_field for(var/mob/living/simple_animal/M in T) - M.weakened = max(M.weakened, 3) + M.Weaken(3) cell.charge -= power_use if(prob(5)) M << "\blue [pick("You feel tingly.","You feel like floating.","It is hard to speak.","You can barely move.")]" @@ -247,7 +247,7 @@ if("carbon") success = 1 for(var/mob/living/carbon/C in T) - C.weakened += 5 + C.AdjustWeakened(5) C.visible_message("\blue \icon[C] [C] begins to float in the air!","You feel tingly and light, but it is difficult to move.") if("nitrogen") success = 1 @@ -270,7 +270,7 @@ if("iron") success = 1 for(var/mob/living/silicon/R in T) - R.weakened += 5 + R.AdjustWeakened(5) R.visible_message("\blue \icon[R] [R] begins to float in the air!","You feel tingly and light, but it is difficult to move.") // //in case we have a bad field type @@ -279,7 +279,7 @@ for(var/mob/living/simple_animal/C in T) C.visible_message("\blue \icon[C] [C] begins to float in the air!","You feel tingly and light, but it is difficult to move.") - C.weakened += 5 + C.AdjustWeakened(5) suspension_field = new(T) suspension_field.field_type = field_type @@ -306,7 +306,7 @@ for(var/mob/M in T) M << "You no longer feel like floating." - M.weakened = min(M.weakened, 3) + M.SetWeakened(min(M.weakened, 3)) src.visible_message("\blue \icon[src] [src] deactivates with a gentle shudder.") qdel(suspension_field) diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index 3fce14135e8..42d5ce1b93e 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -385,7 +385,8 @@ var/mob/living/M = A if(M in immune) continue - M.stunned = 10 + M.stunned += 10 + M.canmove = 0 M.anchored = 1 if(istype(M, /mob/living/simple_animal/hostile)) var/mob/living/simple_animal/hostile/H = M @@ -413,7 +414,7 @@ return /obj/effect/timestop/proc/unfreeze_mob(mob/living/M) - M.stunned = 0 + M.AdjustStunned(-10) M.anchored = 0 if(istype(M, /mob/living/simple_animal/hostile)) var/mob/living/simple_animal/hostile/H = M @@ -503,7 +504,7 @@ user << "The rune fizzles uselessly. There is no spirit nearby." return var/mob/living/carbon/human/golem/G = new /mob/living/carbon/human/golem - if(prob(50)) G.gender = "female" + G.change_gender(pick(MALE,FEMALE)) G.loc = src.loc G.key = ghost.key G << "You are an adamantine 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 [user], and assist them in completing their goals at any cost." diff --git a/code/modules/surgery/bones.dm b/code/modules/surgery/bones.dm index f75101b0298..998da2bf0ce 100644 --- a/code/modules/surgery/bones.dm +++ b/code/modules/surgery/bones.dm @@ -2,8 +2,36 @@ ////////////////////////////////////////////////////////////////// // BONE SURGERY // ////////////////////////////////////////////////////////////////// +///Surgery Datums +/datum/surgery/bone_repair + name = "bone repair" + steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/glue_bone, /datum/surgery_step/set_bone, /datum/surgery_step/finish_bone, /datum/surgery_step/generic/cauterize) + possible_locs = list("chest", "l_arm", "l_hand", "r_arm", "r_hand","r_leg", "r_foot", "l_leg", "l_foot", "groin") +/datum/surgery/bone_repair/skull + name = "bone repair" + steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/glue_bone, /datum/surgery_step/mend_skull, /datum/surgery_step/finish_bone, /datum/surgery_step/generic/cauterize) + possible_locs = list("head") + +/datum/surgery/bone_repair/can_start(mob/user, mob/living/carbon/target) + if(istype(target,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = target + var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) + if(affected && (affected.status & ORGAN_ROBOT)) + return 0 + if(affected && (affected.status & ORGAN_BROKEN)) + return 1 + if(target.get_species() == "Machine") + return 0 + if(target.get_species() == "Diona") + return 0 + return 1 + + +//surgery steps /datum/surgery_step/glue_bone + name = "mend bone" + allowed_tools = list( /obj/item/weapon/bonegel = 100, \ /obj/item/weapon/screwdriver = 75 @@ -11,102 +39,113 @@ can_infect = 1 blood_level = 1 - min_duration = 50 max_duration = 60 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/glue_bone/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) return affected && !(affected.status & ORGAN_ROBOT) && !(affected.cannot_break) && affected.open == 2 && affected.stage == 0 - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if (affected.stage == 0) - user.visible_message("[user] starts applying medication to the damaged bones in [target]'s [affected.name] with \the [tool]." , \ - "You start applying medication to the damaged bones in [target]'s [affected.name] with \the [tool].") - target.custom_pain("Something in your [affected.name] is causing you a lot of pain!",1) - ..() +/datum/surgery_step/glue_bone/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if (affected.stage == 0) + user.visible_message("[user] starts applying medication to the damaged bones in [target]'s [affected.name] with \the [tool]." , \ + "You start applying medication to the damaged bones in [target]'s [affected.name] with \the [tool].") + target.custom_pain("Something in your [affected.name] is causing you a lot of pain!",1) + ..() - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/glue_bone/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] applies some [tool] to [target]'s bone in [affected.name]", \ - "\blue You apply some [tool] to [target]'s bone in [affected.name] with \the [tool].") + user.visible_message(" [user] applies some [tool] to [target]'s bone in [affected.name]", \ + " You apply some [tool] to [target]'s bone in [affected.name] with \the [tool].") affected.stage = 1 - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + return 1 + +/datum/surgery_step/glue_bone/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, smearing [tool] in the incision in [target]'s [affected.name]!" , \ - "\red Your hand slips, smearing [tool] in the incision in [target]'s [affected.name]!") + user.visible_message(" [user]'s hand slips, smearing [tool] in the incision in [target]'s [affected.name]!" , \ + " Your hand slips, smearing [tool] in the incision in [target]'s [affected.name]!") + return 0 /datum/surgery_step/set_bone + name = "set bone" + allowed_tools = list( /obj/item/weapon/bonesetter = 100, \ /obj/item/weapon/wrench = 75 \ ) - min_duration = 60 max_duration = 70 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && !(affected.status & ORGAN_ROBOT) && affected.limb_name != "head" && affected.open == 2 && affected.stage == 1 +/datum/surgery_step/set_bone/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && !(affected.status & ORGAN_ROBOT) && affected.limb_name != "head" && affected.open == 2 && affected.stage == 1 - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] is beginning to set the bone in [target]'s [affected.name] in place with \the [tool]." , \ - "You are beginning to set the bone in [target]'s [affected.name] in place with \the [tool].") - target.custom_pain("The pain in your [affected.name] is going to make you pass out!",1) - ..() +/datum/surgery_step/set_bone/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] is beginning to set the bone in [target]'s [affected.name] in place with \the [tool]." , \ + "You are beginning to set the bone in [target]'s [affected.name] in place with \the [tool].") + target.custom_pain("The pain in your [affected.name] is going to make you pass out!",1) + ..() - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if (affected.status & ORGAN_BROKEN) - user.visible_message("\blue [user] sets the bone in [target]'s [affected.name] in place with \the [tool].", \ - "\blue You set the bone in [target]'s [affected.name] in place with \the [tool].") - affected.stage = 2 - else - user.visible_message("\blue [user] sets the bone in [target]'s [affected.name]\red in the WRONG place with \the [tool].", \ - "\blue You set the bone in [target]'s [affected.name]\red in the WRONG place with \the [tool].") - affected.fracture() +/datum/surgery_step/set_bone/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if (affected.status & ORGAN_BROKEN) + user.visible_message(" [user] sets the bone in [target]'s [affected.name] in place with \the [tool].", \ + " You set the bone in [target]'s [affected.name] in place with \the [tool].") + affected.stage = 2 + return 1 + else + user.visible_message(" [user] sets the bone in [target]'s [affected.name] in place with \the [tool].", \ + " You set the bone in [target]'s [affected.name] in place with \the [tool].") + return 1 - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, damaging the bone in [target]'s [affected.name] with \the [tool]!" , \ - "\red Your hand slips, damaging the bone in [target]'s [affected.name] with \the [tool]!") - affected.createwound(BRUISE, 5) +/datum/surgery_step/set_bone/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user]'s hand slips, damaging the bone in [target]'s [affected.name] with \the [tool]!" , \ + " Your hand slips, damaging the bone in [target]'s [affected.name] with \the [tool]!") + affected.createwound(BRUISE, 5) + return 0 /datum/surgery_step/mend_skull + name = "mend skull" + allowed_tools = list( /obj/item/weapon/bonesetter = 100, \ /obj/item/weapon/wrench = 75 \ ) - min_duration = 60 max_duration = 70 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && !(affected.status & ORGAN_ROBOT) && affected.limb_name == "head" && affected.open == 2 && affected.stage == 1 +/datum/surgery_step/mend_skull/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && !(affected.status & ORGAN_ROBOT) && affected.limb_name == "head" && affected.open == 2 && affected.stage == 1 - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] is beginning piece together [target]'s skull with \the [tool]." , \ - "You are beginning piece together [target]'s skull with \the [tool].") - ..() +/datum/surgery_step/mend_skull/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + user.visible_message("[user] is beginning piece together [target]'s skull with \the [tool]." , \ + "You are beginning piece together [target]'s skull with \the [tool].") + ..() - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] sets [target]'s skull with \the [tool]." , \ - "\blue You set [target]'s skull with \the [tool].") - affected.stage = 2 +/datum/surgery_step/mend_skull/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user] sets [target]'s skull with \the [tool]." , \ + " You set [target]'s skull with \the [tool].") + affected.stage = 2 - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, damaging [target]'s face with \the [tool]!" , \ - "\red Your hand slips, damaging [target]'s face with \the [tool]!") - var/obj/item/organ/external/head/h = affected - h.createwound(BRUISE, 10) - h.disfigured = 1 + return 1 + +/datum/surgery_step/mend_skull/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user]'s hand slips, damaging [target]'s face with \the [tool]!" , \ + " Your hand slips, damaging [target]'s face with \the [tool]!") + var/obj/item/organ/external/head/h = affected + h.createwound(BRUISE, 10) + h.disfigured = 1 + return 0 /datum/surgery_step/finish_bone + name = "medicate bones" + allowed_tools = list( /obj/item/weapon/bonegel = 100, \ /obj/item/weapon/screwdriver = 75 @@ -114,29 +153,31 @@ can_infect = 1 blood_level = 1 - min_duration = 50 max_duration = 60 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && !(affected.status & ORGAN_ROBOT) && affected.open == 2 && affected.stage == 2 +/datum/surgery_step/finish_bone/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && !(affected.status & ORGAN_ROBOT) && affected.open == 2 && affected.stage == 2 - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts to finish mending the damaged bones in [target]'s [affected.name] with \the [tool].", \ - "You start to finish mending the damaged bones in [target]'s [affected.name] with \the [tool].") - ..() +/datum/surgery_step/finish_bone/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts to finish mending the damaged bones in [target]'s [affected.name] with \the [tool].", \ + "You start to finish mending the damaged bones in [target]'s [affected.name] with \the [tool].") + ..() - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] has mended the damaged bones in [target]'s [affected.name] with \the [tool]." , \ - "\blue You have mended the damaged bones in [target]'s [affected.name] with \the [tool]." ) - affected.status &= ~ORGAN_BROKEN - affected.status &= ~ORGAN_SPLINTED - affected.stage = 0 - affected.perma_injury = 0 +/datum/surgery_step/finish_bone/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user] has mended the damaged bones in [target]'s [affected.name] with \the [tool]." , \ + " You have mended the damaged bones in [target]'s [affected.name] with \the [tool]." ) + affected.status &= ~ORGAN_BROKEN + affected.status &= ~ORGAN_SPLINTED + affected.stage = 0 + affected.perma_injury = 0 - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, smearing [tool] in the incision in [target]'s [affected.name]!" , \ - "\red Your hand slips, smearing [tool] in the incision in [target]'s [affected.name]!") \ No newline at end of file + return 1 + +/datum/surgery_step/finish_bone/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user]'s hand slips, smearing [tool] in the incision in [target]'s [affected.name]!" , \ + " Your hand slips, smearing [tool] in the incision in [target]'s [affected.name]!") + return 0 \ No newline at end of file diff --git a/code/modules/surgery/encased.dm b/code/modules/surgery/encased.dm index 1e59a3ea458..ebe1aa404ef 100644 --- a/code/modules/surgery/encased.dm +++ b/code/modules/surgery/encased.dm @@ -6,214 +6,226 @@ priority = 2 can_infect = 1 blood_level = 1 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (!hasorgans(target)) - return 0 +/datum/surgery_step/open_encased/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && !(affected.status & ORGAN_ROBOT) && affected.encased && affected.open >= 2 + if (!hasorgans(target)) + return 0 + + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && !(affected.status & ORGAN_ROBOT) && affected.encased && affected.open >= 2 /datum/surgery_step/open_encased/saw + name = "saw bone" allowed_tools = list( /obj/item/weapon/circular_saw = 100, \ /obj/item/weapon/melee/energy/sword/cyborg/saw = 100, \ /obj/item/weapon/hatchet = 75 ) - min_duration = 50 max_duration = 70 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (!hasorgans(target)) - return - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return ..() && affected && affected.open == 2 +/datum/surgery_step/open_encased/saw/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + if (!hasorgans(target)) + return + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return ..() && affected && affected.open == 2 - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/open_encased/saw/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - if (!hasorgans(target)) - return - var/obj/item/organ/external/affected = target.get_organ(target_zone) + if (!hasorgans(target)) + return + var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] begins to cut through [target]'s [affected.encased] with \the [tool].", \ - "You begin to cut through [target]'s [affected.encased] with \the [tool].") - target.custom_pain("Something hurts horribly in your [affected.name]!",1) - ..() + user.visible_message("[user] begins to cut through [target]'s [affected.encased] with \the [tool].", \ + "You begin to cut through [target]'s [affected.encased] with \the [tool].") + target.custom_pain("Something hurts horribly in your [affected.name]!",1) + ..() - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/open_encased/saw/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - if (!hasorgans(target)) - return - var/obj/item/organ/external/affected = target.get_organ(target_zone) + if (!hasorgans(target)) + return + var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] has cut [target]'s [affected.encased] open with \the [tool].", \ - "\blue You have cut [target]'s [affected.encased] open with \the [tool].") - affected.open = 2.5 + user.visible_message(" [user] has cut [target]'s [affected.encased] open with \the [tool].", \ + " You have cut [target]'s [affected.encased] open with \the [tool].") + affected.open = 2.5 + return 1 - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/open_encased/saw/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - if (!hasorgans(target)) - return - var/obj/item/organ/external/affected = target.get_organ(target_zone) + if (!hasorgans(target)) + return + var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, cracking [target]'s [affected.encased] with \the [tool]!" , \ - "\red Your hand slips, cracking [target]'s [affected.encased] with \the [tool]!" ) + user.visible_message(" [user]'s hand slips, cracking [target]'s [affected.encased] with \the [tool]!" , \ + " Your hand slips, cracking [target]'s [affected.encased] with \the [tool]!" ) - affected.createwound(CUT, 20) - affected.fracture() + affected.createwound(CUT, 20) + affected.fracture() + + return 0 /datum/surgery_step/open_encased/retract + name = "retract bone" allowed_tools = list( + /obj/item/weapon/scalpel/manager = 120, \ /obj/item/weapon/retractor = 100, \ /obj/item/weapon/crowbar = 75 ) - min_duration = 30 max_duration = 40 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (!hasorgans(target)) - return - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return ..() && affected && affected.open == 2.5 +/datum/surgery_step/open_encased/retract/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + if (!hasorgans(target)) + return + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return ..() && affected && affected.open == 2.5 - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/open_encased/retract/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - if (!hasorgans(target)) - return - var/obj/item/organ/external/affected = target.get_organ(target_zone) + if (!hasorgans(target)) + return + var/obj/item/organ/external/affected = target.get_organ(target_zone) - var/msg = "[user] starts to force open the [affected.encased] in [target]'s [affected.name] with \the [tool]." - var/self_msg = "You start to force open the [affected.encased] in [target]'s [affected.name] with \the [tool]." - user.visible_message(msg, self_msg) - target.custom_pain("Something hurts horribly in your [affected.name]!",1) - ..() + var/msg = "[user] starts to force open the [affected.encased] in [target]'s [affected.name] with \the [tool]." + var/self_msg = "You start to force open the [affected.encased] in [target]'s [affected.name] with \the [tool]." + user.visible_message(msg, self_msg) + target.custom_pain("Something hurts horribly in your [affected.name]!",1) + ..() - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/open_encased/retract/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - if (!hasorgans(target)) - return - var/obj/item/organ/external/affected = target.get_organ(target_zone) + if (!hasorgans(target)) + return + var/obj/item/organ/external/affected = target.get_organ(target_zone) - var/msg = "\blue [user] forces open [target]'s [affected.encased] with \the [tool]." - var/self_msg = "\blue You force open [target]'s [affected.encased] with \the [tool]." - user.visible_message(msg, self_msg) + var/msg = " [user] forces open [target]'s [affected.encased] with \the [tool]." + var/self_msg = " You force open [target]'s [affected.encased] with \the [tool]." + user.visible_message(msg, self_msg) - affected.open = 3 + affected.open = 3 - // Whoops! - if(prob(10)) - affected.fracture() + // Whoops! + if(prob(10) && !isrobot(user)) + affected.fracture()//WTF WHY?! - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + return 1 - if (!hasorgans(target)) - return - var/obj/item/organ/external/affected = target.get_organ(target_zone) +/datum/surgery_step/open_encased/retract/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - var/msg = "\red [user]'s hand slips, cracking [target]'s [affected.encased]!" - var/self_msg = "\red Your hand slips, cracking [target]'s [affected.encased]!" - user.visible_message(msg, self_msg) + if (!hasorgans(target)) + return + var/obj/item/organ/external/affected = target.get_organ(target_zone) - affected.createwound(BRUISE, 20) - affected.fracture() + var/msg = " [user]'s hand slips, cracking [target]'s [affected.encased]!" + var/self_msg = " Your hand slips, cracking [target]'s [affected.encased]!" + user.visible_message(msg, self_msg) + + affected.createwound(BRUISE, 20) + affected.fracture() + + return 0 /datum/surgery_step/open_encased/close + name = "unretract bone" //i suck at names okay? give me a new one allowed_tools = list( + /obj/item/weapon/scalpel/manager = 120, \ /obj/item/weapon/retractor = 100, \ /obj/item/weapon/crowbar = 75 ) - min_duration = 20 max_duration = 40 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/open_encased/close/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - if (!hasorgans(target)) - return - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return ..() && affected && affected.open == 3 + if (!hasorgans(target)) + return + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return ..() && affected && affected.open == 3 - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/open_encased/close/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - if (!hasorgans(target)) - return - var/obj/item/organ/external/affected = target.get_organ(target_zone) + if (!hasorgans(target)) + return + var/obj/item/organ/external/affected = target.get_organ(target_zone) - var/msg = "[user] starts bending [target]'s [affected.encased] back into place with \the [tool]." - var/self_msg = "You start bending [target]'s [affected.encased] back into place with \the [tool]." - user.visible_message(msg, self_msg) - target.custom_pain("Something hurts horribly in your [affected.name]!",1) - ..() + var/msg = "[user] starts bending [target]'s [affected.encased] back into place with \the [tool]." + var/self_msg = "You start bending [target]'s [affected.encased] back into place with \the [tool]." + user.visible_message(msg, self_msg) + target.custom_pain("Something hurts horribly in your [affected.name]!",1) + ..() - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/open_encased/close/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - if (!hasorgans(target)) - return - var/obj/item/organ/external/affected = target.get_organ(target_zone) + if (!hasorgans(target)) + return + var/obj/item/organ/external/affected = target.get_organ(target_zone) - var/msg = "\blue [user] bends [target]'s [affected.encased] back into place with \the [tool]." - var/self_msg = "\blue You bend [target]'s [affected.encased] back into place with \the [tool]." - user.visible_message(msg, self_msg) + var/msg = " [user] bends [target]'s [affected.encased] back into place with \the [tool]." + var/self_msg = " You bend [target]'s [affected.encased] back into place with \the [tool]." + user.visible_message(msg, self_msg) - affected.open = 2.5 + affected.open = 2.5 - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + return 1 - if (!hasorgans(target)) - return - var/obj/item/organ/external/affected = target.get_organ(target_zone) +/datum/surgery_step/open_encased/close/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - var/msg = "\red [user]'s hand slips, bending [target]'s [affected.encased] the wrong way!" - var/self_msg = "\red Your hand slips, bending [target]'s [affected.encased] the wrong way!" - user.visible_message(msg, self_msg) + if (!hasorgans(target)) + return + var/obj/item/organ/external/affected = target.get_organ(target_zone) - affected.createwound(BRUISE, 20) - affected.fracture() + var/msg = " [user]'s hand slips, bending [target]'s [affected.encased] the wrong way!" + var/self_msg = " Your hand slips, bending [target]'s [affected.encased] the wrong way!" + user.visible_message(msg, self_msg) - /*if (prob(40)) //TODO: ORGAN REMOVAL UPDATE. - user.visible_message("\red A rib pierces the lung!") - target.rupture_lung()*/ + affected.createwound(BRUISE, 20) + affected.fracture() + + return 0 /datum/surgery_step/open_encased/mend + name = "mend bone" allowed_tools = list( /obj/item/weapon/bonegel = 100, \ /obj/item/weapon/screwdriver = 75 ) - min_duration = 20 max_duration = 40 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/open_encased/mend/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - if (!hasorgans(target)) - return - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return ..() && affected && affected.open == 2.5 + if (!hasorgans(target)) + return + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return ..() && affected && affected.open == 2.5 - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/open_encased/mend/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - if (!hasorgans(target)) - return - var/obj/item/organ/external/affected = target.get_organ(target_zone) + if (!hasorgans(target)) + return + var/obj/item/organ/external/affected = target.get_organ(target_zone) - var/msg = "[user] starts applying \the [tool] to [target]'s [affected.encased]." - var/self_msg = "You start applying \the [tool] to [target]'s [affected.encased]." - user.visible_message(msg, self_msg) - target.custom_pain("Something hurts horribly in your [affected.name]!",1) - ..() + var/msg = "[user] starts applying \the [tool] to [target]'s [affected.encased]." + var/self_msg = "You start applying \the [tool] to [target]'s [affected.encased]." + user.visible_message(msg, self_msg) + target.custom_pain("Something hurts horribly in your [affected.name]!",1) + ..() - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/open_encased/mend/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - if (!hasorgans(target)) - return - var/obj/item/organ/external/affected = target.get_organ(target_zone) + if (!hasorgans(target)) + return + var/obj/item/organ/external/affected = target.get_organ(target_zone) - var/msg = "\blue [user] applied \the [tool] to [target]'s [affected.encased]." - var/self_msg = "\blue You applied \the [tool] to [target]'s [affected.encased]." - user.visible_message(msg, self_msg) + var/msg = " [user] applied \the [tool] to [target]'s [affected.encased]." + var/self_msg = " You applied \the [tool] to [target]'s [affected.encased]." + user.visible_message(msg, self_msg) - affected.open = 2 \ No newline at end of file + affected.open = 2 + + return 1 \ No newline at end of file diff --git a/code/modules/surgery/face.dm b/code/modules/surgery/face.dm index 5257c55287e..a1675ae91e6 100644 --- a/code/modules/surgery/face.dm +++ b/code/modules/surgery/face.dm @@ -2,138 +2,176 @@ ////////////////////////////////////////////////////////////////// // FACE SURGERY // ////////////////////////////////////////////////////////////////// +/datum/surgery/plastic_surgery + name = "face repair" + steps = list(/datum/surgery_step/generic/cut_face, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/face/mend_vocal, /datum/surgery_step/face/fix_face,/datum/surgery_step/face/cauterize) + possible_locs = list("head") + + + +/datum/surgery/plastic_surgery/can_start(mob/user, mob/living/carbon/target) + if(istype(target,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = target + var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) + if(affected && (affected.status & ORGAN_ROBOT)) + return 0 + if((target.get_species() == "Machine")) + return 0 + return 1 /datum/surgery_step/face priority = 2 can_infect = 0 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (!hasorgans(target)) - return 0 - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if (!affected || (affected.status & ORGAN_ROBOT)) - return 0 - return target_zone == "mouth" + +/datum/surgery_step/face/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + if (!hasorgans(target)) + return 0 + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if (!affected || (affected.status & ORGAN_ROBOT)) + return 0 + return target_zone == "mouth" /datum/surgery_step/generic/cut_face + name = "make incision" allowed_tools = list( + /obj/item/weapon/scalpel/laser3 = 115, \ + /obj/item/weapon/scalpel/laser2 = 110, \ + /obj/item/weapon/scalpel/laser1 = 105, \ + /obj/item/weapon/scalpel/manager = 120, \ /obj/item/weapon/scalpel = 100, \ /obj/item/weapon/kitchen/knife = 75, \ /obj/item/weapon/shard = 50, \ ) - min_duration = 90 max_duration = 110 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return ..() && target_zone == "mouth" && target.op_stage.face == 0 +/datum/surgery_step/generic/cut_face/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + return ..() && target_zone == "mouth" //&& target.op_stage.face == 0//I NEED TO REPLACE THE OPSTAGE SHIT! - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/generic/cut_face/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) user.visible_message("[user] starts to cut open [target]'s face and neck with \the [tool].", \ "You start to cut open [target]'s face and neck with \the [tool].") ..() - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\blue [user] has cut open [target]'s face and neck with \the [tool]." , \ - "\blue You have cut open [target]'s face and neck with \the [tool].",) - target.op_stage.face = 1 +/datum/surgery_step/generic/cut_face/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + user.visible_message(" [user] has cut open [target]'s face and neck with \the [tool]." , \ + " You have cut open [target]'s face and neck with \the [tool].",) + //target.op_stage.face = 1//DID I MENTION I NEED TO REPLACE THE OPSTAGE SHIT! - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + return 1 + +/datum/surgery_step/generic/cut_face/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, slicing [target]'s throat wth \the [tool]!" , \ - "\red Your hand slips, slicing [target]'s throat wth \the [tool]!" ) + user.visible_message(" [user]'s hand slips, slicing [target]'s throat wth \the [tool]!" , \ + " Your hand slips, slicing [target]'s throat wth \the [tool]!" ) affected.createwound(CUT, 60) target.losebreath += 4 + return 0 + /datum/surgery_step/face/mend_vocal + name = "mend vocal cords" allowed_tools = list( + /obj/item/weapon/scalpel/manager = 120, \ /obj/item/weapon/hemostat = 100, \ /obj/item/stack/cable_coil = 75, \ /obj/item/device/assembly/mousetrap = 10 //I don't know. Don't ask me. But I'm leaving it because hilarity. ) - min_duration = 70 max_duration = 90 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return ..() && target.op_stage.face == 1 +/datum/surgery_step/face/mend_vocal/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + return ..()// && target.op_stage.face == 1 //NO REALLY NED TO REPLACE, MAYBE WITH FUCKING istype(S.get_surgery_step(), /datum/surgery_step/cut_face)) OR SOMETHING - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/face/mend_vocal/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) user.visible_message("[user] starts mending [target]'s vocal cords with \the [tool].", \ "You start mending [target]'s vocal cords with \the [tool].") ..() - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\blue [user] mends [target]'s vocal cords with \the [tool].", \ - "\blue You mend [target]'s vocal cords with \the [tool].") - target.op_stage.face = 2 +/datum/surgery_step/face/mend_vocal/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + user.visible_message(" [user] mends [target]'s vocal cords with \the [tool].", \ + " You mend [target]'s vocal cords with \the [tool].") + //target.op_stage.face = 2//I NEED TO REPLACE THE OPSTAGE SHIT! + return 1 - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\red [user]'s hand slips, clamping [target]'s trachea shut for a moment with \the [tool]!", \ - "\red Your hand slips, clamping [user]'s trachea shut for a moment with \the [tool]!") +/datum/surgery_step/face/mend_vocal/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + user.visible_message(" [user]'s hand slips, clamping [target]'s trachea shut for a moment with \the [tool]!", \ + " Your hand slips, clamping [user]'s trachea shut for a moment with \the [tool]!") target.losebreath += 4 + return 0 /datum/surgery_step/face/fix_face + name = "reshape face" allowed_tools = list( + /obj/item/weapon/scalpel/manager = 120, \ /obj/item/weapon/retractor = 100, \ /obj/item/weapon/crowbar = 55, \ /obj/item/weapon/kitchen/utensil/fork = 75) - min_duration = 80 max_duration = 100 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return ..() && target.op_stage.face == 2 +/datum/surgery_step/face/fix_face/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + return ..() //&& target.op_stage.face == 2//I NEED TO REPLACE THE OPSTAGE SHIT! - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/face/fix_face/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) user.visible_message("[user] starts pulling skin on [target]'s face back in place with \the [tool].", \ "You start pulling skin on [target]'s face back in place with \the [tool].") ..() - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\blue [user] pulls skin on [target]'s face back in place with \the [tool].", \ - "\blue You pull skin on [target]'s face back in place with \the [tool].") - target.op_stage.face = 3 +/datum/surgery_step/face/fix_face/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + user.visible_message(" [user] pulls skin on [target]'s face back in place with \the [tool].", \ + " You pull skin on [target]'s face back in place with \the [tool].") + //target.op_stage.face = 3//I NEED TO REPLACE THE OPSTAGE SHIT! + return 1 - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/face/fix_face/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, tearing skin on [target]'s face with \the [tool]!", \ - "\red Your hand slips, tearing skin on [target]'s face with \the [tool]!") + user.visible_message(" [user]'s hand slips, tearing skin on [target]'s face with \the [tool]!", \ + " Your hand slips, tearing skin on [target]'s face with \the [tool]!") target.apply_damage(10, BRUTE, affected, sharp=1, sharp=1) + return 0 /datum/surgery_step/face/cauterize + name = "close incision" allowed_tools = list( + /obj/item/weapon/scalpel/laser3 = 115, \ + /obj/item/weapon/scalpel/laser2 = 110, \ + /obj/item/weapon/scalpel/laser1 = 105, \ /obj/item/weapon/cautery = 100, \ /obj/item/clothing/mask/cigarette = 75, \ /obj/item/weapon/lighter = 50, \ /obj/item/weapon/weldingtool = 25 ) - min_duration = 70 max_duration = 100 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return ..() && target.op_stage.face > 0 +/datum/surgery_step/face/cauterize/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + return ..()// && target.op_stage.face > 0//I NEED TO REPLACE THE OPSTAGE SHIT! - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/face/cauterize/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) user.visible_message("[user] is beginning to cauterize the incision on [target]'s face and neck with \the [tool]." , \ "You are beginning to cauterize the incision on [target]'s face and neck with \the [tool].") ..() - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/face/cauterize/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] cauterizes the incision on [target]'s face and neck with \the [tool].", \ - "\blue You cauterize the incision on [target]'s face and neck with \the [tool].") + user.visible_message(" [user] cauterizes the incision on [target]'s face and neck with \the [tool].", \ + " You cauterize the incision on [target]'s face and neck with \the [tool].") affected.open = 0 affected.status &= ~ORGAN_BLEEDING - if (target.op_stage.face == 3) - var/obj/item/organ/external/head/h = affected - h.disfigured = 0 - h.update_icon() - target.regenerate_icons() - target.op_stage.face = 0 + //if (target.op_stage.face == 3)//I NEED TO REPLACE THE OPSTAGE SHIT! + var/obj/item/organ/external/head/h = affected + h.disfigured = 0 + h.update_icon() + target.regenerate_icons() + //target.op_stage.face = 0//I NEED TO REPLACE THE OPSTAGE SHIT! - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + return 1 + +/datum/surgery_step/face/cauterize/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, leaving a small burn on [target]'s face with \the [tool]!", \ - "\red Your hand slips, leaving a small burn on [target]'s face with \the [tool]!") - target.apply_damage(4, BURN, affected) \ No newline at end of file + user.visible_message(" [user]'s hand slips, leaving a small burn on [target]'s face with \the [tool]!", \ + " Your hand slips, leaving a small burn on [target]'s face with \the [tool]!") + target.apply_damage(4, BURN, affected) + + return 0 \ No newline at end of file diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm index 63c007cadb9..95e81d48e65 100644 --- a/code/modules/surgery/generic.dm +++ b/code/modules/surgery/generic.dm @@ -5,269 +5,219 @@ /datum/surgery_step/generic/ can_infect = 1 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (target_zone == "eyes") //there are specific steps for eye surgery - return 0 - if (!hasorgans(target)) - return 0 - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if (affected == null) - return 0 - if (affected.status & ORGAN_DESTROYED) - return 0 - if (affected.status & ORGAN_ROBOT) - return 0 - return 1 -/datum/surgery_step/generic/cut_with_laser - allowed_tools = list( - /obj/item/weapon/scalpel/laser3 = 95, \ - /obj/item/weapon/scalpel/laser2 = 85, \ - /obj/item/weapon/scalpel/laser1 = 75, \ - /obj/item/weapon/melee/energy/sword/saber = 5 - ) +/datum/surgery_step/generic/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + if (target_zone == "eyes") //there are specific steps for eye surgery + return 0 + if (!hasorgans(target)) + return 0 + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if (affected == null) + return 0 + if (affected.status & ORGAN_DESTROYED) + return 0 + if (affected.status & ORGAN_ROBOT) + return 0 + return 1 - min_duration = 90 - max_duration = 110 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected.open == 0 && target_zone != "mouth" - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts the bloodless incision on [target]'s [affected.name] with \the [tool].", \ - "You start the bloodless incision on [target]'s [affected.name] with \the [tool].") - target.custom_pain("You feel a horrible, searing pain in your [affected.name]!",1) - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] has made a bloodless incision on [target]'s [affected.name] with \the [tool].", \ - "\blue You have made a bloodless incision on [target]'s [affected.name] with \the [tool].",) - //Could be cleaner ... - affected.open = 1 - - if(istype(target) && !(target.species.flags & NO_BLOOD)) - affected.status |= ORGAN_BLEEDING - - affected.createwound(CUT, 1) - affected.clamp() - spread_germs_to_organ(affected, user) - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips as the blade sputters, searing a long gash in [target]'s [affected.name] with \the [tool]!", \ - "\red Your hand slips as the blade sputters, searing a long gash in [target]'s [affected.name] with \the [tool]!") - affected.createwound(CUT, 7.5) - affected.createwound(BURN, 12.5) - -/datum/surgery_step/generic/incision_manager - allowed_tools = list( - /obj/item/weapon/scalpel/manager = 100 - ) - - min_duration = 80 - max_duration = 120 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected.open == 0 && target_zone != "mouth" - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts to construct a prepared incision on and within [target]'s [affected.name] with \the [tool].", \ - "You start to construct a prepared incision on and within [target]'s [affected.name] with \the [tool].") - target.custom_pain("You feel a horrible, searing pain in your [affected.name] as it is pushed apart!",1) - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] has constructed a prepared incision on and within [target]'s [affected.name] with \the [tool].", \ - "\blue You have constructed a prepared incision on and within [target]'s [affected.name] with \the [tool].",) - affected.open = 1 - - if(istype(target) && !(target.species.flags & NO_BLOOD)) - affected.status |= ORGAN_BLEEDING - - affected.createwound(CUT, 1) - affected.clamp() - affected.open = 2 - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand jolts as the system sparks, ripping a gruesome hole in [target]'s [affected.name] with \the [tool]!", \ - "\red Your hand jolts as the system sparks, ripping a gruesome hole in [target]'s [affected.name] with \the [tool]!") - affected.createwound(CUT, 20) - affected.createwound(BURN, 15) /datum/surgery_step/generic/cut_open + name = "make incision" + allowed_tools = list( + /obj/item/weapon/scalpel/laser3 = 115, \ + /obj/item/weapon/scalpel/laser2 = 110, \ + /obj/item/weapon/scalpel/laser1 = 105, \ + /obj/item/weapon/scalpel/manager = 120, \ /obj/item/weapon/scalpel = 100, \ /obj/item/weapon/kitchen/knife = 75, \ /obj/item/weapon/shard = 50, \ + /obj/item/weapon/scissors = 10, \ + /obj/item/weapon/twohanded/chainsaw = 1, \ + /obj/item/weapon/claymore = 5, \ + /obj/item/weapon/melee/energy/ = 5, \ + /obj/item/weapon/pen/edagger = 5, \ ) - min_duration = 90 - max_duration = 110 + max_duration = 60 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (!ishuman(target)) - return 0 - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return ..() && affected.open == 0 && target_zone != "mouth" +/datum/surgery_step/generic/cut_open/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return ..() && affected.open == 0 && target_zone != "mouth" - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/generic/cut_open/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("[user] starts the incision on [target]'s [affected.name] with \the [tool].", \ "You start the incision on [target]'s [affected.name] with \the [tool].") target.custom_pain("You feel a horrible pain as if from a sharp knife in your [affected.name]!",1) ..() - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] has made an incision on [target]'s [affected.name] with \the [tool].", \ - "\blue You have made an incision on [target]'s [affected.name] with \the [tool].",) - affected.open = 1 - affected.status |= ORGAN_BLEEDING - affected.createwound(CUT, 1) - if (target_zone == "head") - target.brain_op_stage = 1 +/datum/surgery_step/generic/cut_open/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user] has made an incision on [target]'s [affected.name] with \the [tool].", \ + " You have made an incision on [target]'s [affected.name] with \the [tool].",) + affected.open = 1 + affected.status |= ORGAN_BLEEDING + affected.createwound(CUT, 1) + //if (target_zone == "head") + // target.brain_op_stage = 1 + return 1 - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, slicing open [target]'s [affected.name] in a wrong spot with \the [tool]!", \ - "\red Your hand slips, slicing open [target]'s [affected.name] in a wrong spot with \the [tool]!") - affected.createwound(CUT, 10) +/datum/surgery_step/generic/cut_open/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user]'s hand slips, slicing open [target]'s [affected.name] in a wrong spot with \the [tool]!", \ + " Your hand slips, slicing open [target]'s [affected.name] in a wrong spot with \the [tool]!") + affected.createwound(CUT, 10) + return 0 /datum/surgery_step/generic/clamp_bleeders + name = "clamp bleeders" + allowed_tools = list( + /obj/item/weapon/scalpel/laser3 = 115, \ + /obj/item/weapon/scalpel/laser2 = 110, \ + /obj/item/weapon/scalpel/laser1 = 105, \ + /obj/item/weapon/scalpel/manager = 120, \ /obj/item/weapon/hemostat = 100, \ /obj/item/stack/cable_coil = 75, \ /obj/item/device/assembly/mousetrap = 20 ) - min_duration = 40 max_duration = 60 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + +/datum/surgery_step/generic/clamp_bleeders/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) var/obj/item/organ/external/affected = target.get_organ(target_zone) return ..() && affected.open && (affected.status & ORGAN_BLEEDING) - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + +/datum/surgery_step/generic/clamp_bleeders/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("[user] starts clamping bleeders in [target]'s [affected.name] with \the [tool].", \ "You start clamping bleeders in [target]'s [affected.name] with \the [tool].") target.custom_pain("The pain in your [affected.name] is maddening!",1) ..() - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] clamps bleeders in [target]'s [affected.name] with \the [tool].", \ - "\blue You clamp bleeders in [target]'s [affected.name] with \the [tool].") - affected.clamp() - spread_germs_to_organ(affected, user) +/datum/surgery_step/generic/clamp_bleeders/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user] clamps bleeders in [target]'s [affected.name] with \the [tool].", \ + " You clamp bleeders in [target]'s [affected.name] with \the [tool].") + affected.clamp() + spread_germs_to_organ(affected, user) + return 1 - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, tearing blood vessals and causing massive bleeding in [target]'s [affected.name] with \the [tool]!", \ - "\red Your hand slips, tearing blood vessels and causing massive bleeding in [target]'s [affected.name] with \the [tool]!",) - affected.createwound(CUT, 10) +/datum/surgery_step/generic/clamp_bleeders/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user]'s hand slips, tearing blood vessals and causing massive bleeding in [target]'s [affected.name] with \the [tool]!", \ + " Your hand slips, tearing blood vessels and causing massive bleeding in [target]'s [affected.name] with \the [tool]!",) + affected.createwound(CUT, 10) + return 0 /datum/surgery_step/generic/retract_skin + name = "retract skin" + allowed_tools = list( + /obj/item/weapon/scalpel/manager = 120, \ /obj/item/weapon/retractor = 100, \ /obj/item/weapon/crowbar = 75, \ /obj/item/weapon/kitchen/utensil/fork = 50 ) - min_duration = 30 max_duration = 40 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/generic/retract_skin/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) var/obj/item/organ/external/affected = target.get_organ(target_zone) return ..() && affected.open == 1 && !(affected.status & ORGAN_BLEEDING) - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - var/msg = "[user] starts to pry open the incision on [target]'s [affected.name] with \the [tool]." - var/self_msg = "You start to pry open the incision on [target]'s [affected.name] with \the [tool]." - if (target_zone == "chest") - msg = "[user] starts to separate the ribcage and rearrange the organs in [target]'s torso with \the [tool]." - self_msg = "You start to separate the ribcage and rearrange the organs in [target]'s torso with \the [tool]." - if (target_zone == "groin") - msg = "[user] starts to pry open the incision and rearrange the organs in [target]'s lower abdomen with \the [tool]." - self_msg = "You start to pry open the incision and rearrange the organs in [target]'s lower abdomen with \the [tool]." - user.visible_message(msg, self_msg) - target.custom_pain("It feels like the skin on your [affected.name] is on fire!",1) - ..() +/datum/surgery_step/generic/retract_skin/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + var/msg = "[user] starts to pry open the incision on [target]'s [affected.name] with \the [tool]." + var/self_msg = "You start to pry open the incision on [target]'s [affected.name] with \the [tool]." + if (target_zone == "chest") + msg = "[user] starts to separate the ribcage and rearrange the organs in [target]'s torso with \the [tool]." + self_msg = "You start to separate the ribcage and rearrange the organs in [target]'s torso with \the [tool]." + if (target_zone == "groin") + msg = "[user] starts to pry open the incision and rearrange the organs in [target]'s lower abdomen with \the [tool]." + self_msg = "You start to pry open the incision and rearrange the organs in [target]'s lower abdomen with \the [tool]." + user.visible_message(msg, self_msg) + target.custom_pain("It feels like the skin on your [affected.name] is on fire!",1) + ..() - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - var/msg = "\blue [user] keeps the incision open on [target]'s [affected.name] with \the [tool]." - var/self_msg = "\blue You keep the incision open on [target]'s [affected.name] with \the [tool]." - if (target_zone == "chest") - msg = "\blue [user] keeps the ribcage open on [target]'s torso with \the [tool]." - self_msg = "\blue You keep the ribcage open on [target]'s torso with \the [tool]." - if (target_zone == "groin") - msg = "\blue [user] keeps the incision open on [target]'s lower abdomen with \the [tool]." - self_msg = "\blue You keep the incision open on [target]'s lower abdomen with \the [tool]." - user.visible_message(msg, self_msg) - affected.open = 2 +/datum/surgery_step/generic/retract_skin/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + var/msg = " [user] keeps the incision open on [target]'s [affected.name] with \the [tool]." + var/self_msg = " You keep the incision open on [target]'s [affected.name] with \the [tool]." + if (target_zone == "chest") + msg = " [user] keeps the ribcage open on [target]'s torso with \the [tool]." + self_msg = " You keep the ribcage open on [target]'s torso with \the [tool]." + if (target_zone == "groin") + msg = " [user] keeps the incision open on [target]'s lower abdomen with \the [tool]." + self_msg = " You keep the incision open on [target]'s lower abdomen with \the [tool]." + user.visible_message(msg, self_msg) + affected.open = 2 + return 1 - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - var/msg = "\red [user]'s hand slips, tearing the edges of incision on [target]'s [affected.name] with \the [tool]!" - var/self_msg = "\red Your hand slips, tearing the edges of incision on [target]'s [affected.name] with \the [tool]!" - if (target_zone == "chest") - msg = "\red [user]'s hand slips, damaging several organs [target]'s torso with \the [tool]!" - self_msg = "\red Your hand slips, damaging several organs [target]'s torso with \the [tool]!" - if (target_zone == "groin") - msg = "\red [user]'s hand slips, damaging several organs [target]'s lower abdomen with \the [tool]" - self_msg = "\red Your hand slips, damaging several organs [target]'s lower abdomen with \the [tool]!" - user.visible_message(msg, self_msg) - target.apply_damage(12, BRUTE, affected, sharp=1) +/datum/surgery_step/generic/retract_skin/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + var/msg = " [user]'s hand slips, tearing the edges of incision on [target]'s [affected.name] with \the [tool]!" + var/self_msg = " Your hand slips, tearing the edges of incision on [target]'s [affected.name] with \the [tool]!" + if (target_zone == "chest") + msg = " [user]'s hand slips, damaging several organs [target]'s torso with \the [tool]!" + self_msg = " Your hand slips, damaging several organs [target]'s torso with \the [tool]!" + if (target_zone == "groin") + msg = " [user]'s hand slips, damaging several organs [target]'s lower abdomen with \the [tool]" + self_msg = " Your hand slips, damaging several organs [target]'s lower abdomen with \the [tool]!" + user.visible_message(msg, self_msg) + target.apply_damage(12, BRUTE, affected, sharp=1) + return 0 /datum/surgery_step/generic/cauterize + + name = "cauterize incision" + allowed_tools = list( + /obj/item/weapon/scalpel/laser3 = 115, \ + /obj/item/weapon/scalpel/laser2 = 110, \ + /obj/item/weapon/scalpel/laser1 = 105, \ /obj/item/weapon/cautery = 100, \ /obj/item/clothing/mask/cigarette = 75, \ /obj/item/weapon/lighter = 50, \ /obj/item/weapon/weldingtool = 25 ) - min_duration = 70 - max_duration = 100 + max_duration = 90 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return ..() && affected.open && target_zone != "mouth" +/datum/surgery_step/generic/cauterize/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return ..() && affected.open && target_zone != "mouth" - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] is beginning to cauterize the incision on [target]'s [affected.name] with \the [tool]." , \ - "You are beginning to cauterize the incision on [target]'s [affected.name] with \the [tool].") - target.custom_pain("Your [affected.name] is being burned!",1) - ..() +/datum/surgery_step/generic/cauterize/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] is beginning to cauterize the incision on [target]'s [affected.name] with \the [tool]." , \ + "You are beginning to cauterize the incision on [target]'s [affected.name] with \the [tool].") + target.custom_pain("Your [affected.name] is being burned!",1) + ..() - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] cauterizes the incision on [target]'s [affected.name] with \the [tool].", \ - "\blue You cauterize the incision on [target]'s [affected.name] with \the [tool].") - affected.open = 0 - affected.germ_level = 0 - affected.status &= ~ORGAN_BLEEDING +/datum/surgery_step/generic/cauterize/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user] cauterizes the incision on [target]'s [affected.name] with \the [tool].", \ + " You cauterize the incision on [target]'s [affected.name] with \the [tool].") + affected.open = 0 + affected.germ_level = 0 + affected.status &= ~ORGAN_BLEEDING + return 1 - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, leaving a small burn on [target]'s [affected.name] with \the [tool]!", \ - "\red Your hand slips, leaving a small burn on [target]'s [affected.name] with \the [tool]!") - target.apply_damage(3, BURN, affected) +/datum/surgery_step/generic/cauterize/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user]'s hand slips, leaving a small burn on [target]'s [affected.name] with \the [tool]!", \ + " Your hand slips, leaving a small burn on [target]'s [affected.name] with \the [tool]!") + target.apply_damage(3, BURN, affected) + return 0 /datum/surgery_step/generic/amputate + name = "amputate limb" + allowed_tools = list( /obj/item/weapon/circular_saw = 100, \ /obj/item/weapon/melee/energy/sword/cyborg/saw = 100, \ @@ -275,37 +225,41 @@ /obj/item/weapon/melee/arm_blade = 60 ) - min_duration = 110 - max_duration = 160 + max_duration = 110 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (target_zone == "eyes") //there are specific steps for eye surgery - return 0 - if (!hasorgans(target)) - return 0 - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if (affected == null) - return 0 - if (affected.status & ORGAN_DESTROYED) - return 0 - return !affected.cannot_amputate +/datum/surgery_step/generic/amputate/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + if (target_zone == "eyes") //there are specific steps for eye surgery + return 0 + if (!hasorgans(target)) + return 0 + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if (affected == null) + return 0 + if (affected.status & ORGAN_DESTROYED) + return 0 + return !affected.cannot_amputate - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] is beginning to amputate [target]'s [affected.name] with \the [tool]." , \ - "You are beginning to cut through [target]'s [affected.amputation_point] with \the [tool].") - target.custom_pain("Your [affected.amputation_point] is being ripped apart!",1) - ..() +/datum/surgery_step/generic/amputate/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] is beginning to amputate [target]'s [affected.name] with \the [tool]." , \ + "You are beginning to cut through [target]'s [affected.amputation_point] with \the [tool].") + target.custom_pain("Your [affected.amputation_point] is being ripped apart!",1) + ..() - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] amputates [target]'s [affected.name] at the [affected.amputation_point] with \the [tool].", \ - "\blue You amputate [target]'s [affected.name] with \the [tool].") - affected.droplimb(1,DROPLIMB_EDGE) +/datum/surgery_step/generic/amputate/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user] amputates [target]'s [affected.name] at the [affected.amputation_point] with \the [tool].", \ + " You amputate [target]'s [affected.name] with \the [tool].") - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, sawing through the bone in [target]'s [affected.name] with \the [tool]!", \ - "\red Your hand slips, sawwing through the bone in [target]'s [affected.name] with \the [tool]!") - affected.createwound(CUT, 30) - affected.fracture() \ No newline at end of file + add_logs(target,user ,"surgically removed [affected.name] from", addition="INTENT: [uppertext(user.a_intent)]")//log it + + affected.droplimb(1,DROPLIMB_EDGE) + return 1 + +/datum/surgery_step/generic/amputate/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user]'s hand slips, sawing through the bone in [target]'s [affected.name] with \the [tool]!", \ + " Your hand slips, sawwing through the bone in [target]'s [affected.name] with \the [tool]!") + affected.createwound(CUT, 30) + affected.fracture() + return 0 \ No newline at end of file diff --git a/code/modules/surgery/helpers.dm b/code/modules/surgery/helpers.dm new file mode 100644 index 00000000000..be1cb2264a9 --- /dev/null +++ b/code/modules/surgery/helpers.dm @@ -0,0 +1,89 @@ +/proc/attempt_initiate_surgery(obj/item/I, mob/living/M, mob/user, var/override ) + if(istype(M)) + var/mob/living/carbon/human/H + var/obj/item/organ/external/affecting + var/selected_zone = user.zone_sel.selecting + + if(istype(M, /mob/living/carbon/human)) + H = M + affecting = H.get_organ(check_zone(selected_zone)) + + if(can_operate(M) || isslime(M)) //if they're prone or a slime + var/datum/surgery/current_surgery + for(var/datum/surgery/S in M.surgeries) + if(S.location == selected_zone) + current_surgery = S + + if(!current_surgery) + var/list/all_surgeries = surgeries_list.Copy() + var/list/available_surgeries = list() + + for(var/datum/surgery/S in all_surgeries) + if(!S.possible_locs.Find(selected_zone)) + continue + if(affecting && S.requires_organic_bodypart && affecting.status == ORGAN_ROBOT) + continue + if(!S.can_start(user, M)) + continue + + for(var/path in S.allowed_mob) + if(istype(M, path)) + available_surgeries[S.name] = S + break + + if(override) + if(istype(I,/obj/item/robot_parts)) + var/datum/surgery/S = available_surgeries["robotic limb attachment"] + if(S) + var/datum/surgery/procedure = new S.type + if(procedure) + procedure.location = selected_zone + M.surgeries += procedure + procedure.organ_ref = affecting + procedure.next_step(user, M) + + else + var/P = input("Begin which procedure?", "Surgery", null, null) as null|anything in available_surgeries + if(P && user && user.Adjacent(M) && (I in user)) + var/datum/surgery/S = available_surgeries[P] + var/datum/surgery/procedure = new S.type + if(procedure) + procedure.location = selected_zone + M.surgeries += procedure + procedure.organ_ref = affecting + user.visible_message("[user] prepares to operate on [M]'s [parse_zone(selected_zone)].", \ + "You prepare to operate on [M]'s [parse_zone(selected_zone)].") + + else if(!current_surgery.step_in_progress) + if(current_surgery.status == 1 ) + M.surgeries -= current_surgery + user << "You stop the surgery." + qdel(current_surgery) + else if(istype(user.get_inactive_hand(), /obj/item/weapon/cautery) && current_surgery.can_cancel) + M.surgeries -= current_surgery + user.visible_message("[user] mends the incision on [M]'s [parse_zone(selected_zone)] with the [I] .", \ + "You mend the incision on [M]'s [parse_zone(selected_zone)].") + if(affecting) + affecting.open = 0 + affecting.germ_level = 0 + affecting.status &= ~ORGAN_BLEEDING + qdel(current_surgery) + else if(current_surgery.can_cancel) + user << "You need to hold a cautery in inactive hand to stop [M]'s surgery!" + + + return 1 + return 0 + + + +proc/get_location_modifier(mob/M) + var/turf/T = get_turf(M) + if(locate(/obj/machinery/optable, T)) + return 1 + else if(locate(/obj/structure/table, T)) + return 0.8 + else if(locate(/obj/structure/stool/bed, T)) + return 0.7 + else + return 0.5 \ No newline at end of file diff --git a/code/modules/surgery/implant.dm b/code/modules/surgery/implant.dm index 25ebaf28f6c..0ac003c18f1 100644 --- a/code/modules/surgery/implant.dm +++ b/code/modules/surgery/implant.dm @@ -1,228 +1,353 @@ //Procedures in this file: Putting items in body cavity. Implant removal. Items removal. + ////////////////////////////////////////////////////////////////// // ITEM PLACEMENT SURGERY // ////////////////////////////////////////////////////////////////// +/datum/surgery/cavity_implant + name = "cavity implant/removal" + steps = list(/datum/surgery_step/generic/cut_open,/datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/open_encased/saw, + /datum/surgery_step/open_encased/retract, /datum/surgery_step/cavity/make_space,/datum/surgery_step/cavity/place_item,/datum/surgery_step/cavity/close_space,/datum/surgery_step/open_encased/close,/datum/surgery_step/glue_bone, /datum/surgery_step/set_bone,/datum/surgery_step/finish_bone,/datum/surgery_step/generic/cauterize) + + possible_locs = list("chest","head") + + +/datum/surgery/cavity_implant/soft + name = "cavity implant/removal" + steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/generic/cut_open, /datum/surgery_step/cavity/make_space,/datum/surgery_step/cavity/place_item,/datum/surgery_step/cavity/close_space,/datum/surgery_step/generic/cauterize) + + possible_locs = list("groin") + +/datum/surgery/cavity_implant/synth + name = "robotic cavity implant" + steps = list(/datum/surgery_step/robotics/external/unscrew_hatch,/datum/surgery_step/robotics/external/open_hatch,/datum/surgery_step/cavity/place_item,/datum/surgery_step/robotics/external/close_hatch) + possible_locs = list("chest","head","groin") + allowed_mob = list(/mob/living/carbon/human/machine) + +/datum/surgery/cavity_implant/can_start(mob/user, mob/living/carbon/target) + if(target.get_species() == "Machine") + return 0 + return 1 + +/datum/surgery/cavity_implant/synth/can_start(mob/user, mob/living/carbon/target) + return target.get_species() == "Machine" + /datum/surgery_step/cavity priority = 1 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(!hasorgans(target)) - return 0 - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.open == (affected.encased ? 3 : 2) && !(affected.status & ORGAN_BLEEDING) - proc/get_max_wclass(obj/item/organ/external/affected) - switch (affected.limb_name) - if ("head") - return 1 - if ("chest") - return 3 - if ("groin") - return 2 +/datum/surgery_step/cavity/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + if(!hasorgans(target)) return 0 + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected && affected.open == (affected.encased ? 3 : 2) && !(affected.status & ORGAN_BLEEDING) - proc/get_cavity(obj/item/organ/external/affected) - switch (affected.limb_name) - if ("head") - return "cranial" - if ("chest") - return "thoracic" - if ("groin") - return "abdominal" - return "" +/datum/surgery_step/cavity/proc/get_max_wclass(obj/item/organ/external/affected) + switch (affected.limb_name) + if ("head") + return 1 + if ("chest") + return 3 + if ("groin") + return 2 + return 0 - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, scraping around inside [target]'s [affected.name] with \the [tool]!", \ - "\red Your hand slips, scraping around inside [target]'s [affected.name] with \the [tool]!") - affected.createwound(CUT, 20) +/datum/surgery_step/cavity/proc/get_cavity(obj/item/organ/external/affected) + switch (affected.limb_name) + if ("head") + return "cranial" + if ("chest") + return "thoracic" + if ("groin") + return "abdominal" + return "" + +/datum/surgery_step/cavity/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) + user.visible_message(" [user]'s hand slips, scraping around inside [target]'s [affected.name] with \the [tool]!", \ + " Your hand slips, scraping around inside [target]'s [affected.name] with \the [tool]!") + affected.createwound(CUT, 20) /datum/surgery_step/cavity/make_space + name = "make cavity space" allowed_tools = list( /obj/item/weapon/surgicaldrill = 100, \ /obj/item/weapon/pen = 75, \ /obj/item/stack/rods = 50 ) - min_duration = 60 max_duration = 80 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return ..() && !affected.cavity && !affected.hidden +/datum/surgery_step/cavity/make_space/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return ..() && !affected.cavity && !affected.hidden - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts making some space inside [target]'s [get_cavity(affected)] cavity with \the [tool].", \ - "You start making some space inside [target]'s [get_cavity(affected)] cavity with \the [tool]." ) - target.custom_pain("The pain in your chest is living hell!",1) - affected.cavity = 1 - ..() +/datum/surgery_step/cavity/make_space/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts making some space inside [target]'s [get_cavity(affected)] cavity with \the [tool].", \ + "You start making some space inside [target]'s [get_cavity(affected)] cavity with \the [tool]." ) + target.custom_pain("The pain in your chest is living hell!",1) + affected.cavity = 1 + ..() - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] makes some space inside [target]'s [get_cavity(affected)] cavity with \the [tool].", \ - "\blue You make some space inside [target]'s [get_cavity(affected)] cavity with \the [tool]." ) +/datum/surgery_step/cavity/make_space/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) + user.visible_message(" [user] makes some space inside [target]'s [get_cavity(affected)] cavity with \the [tool].", \ + " You make some space inside [target]'s [get_cavity(affected)] cavity with \the [tool]." ) + + return 1 /datum/surgery_step/cavity/close_space - priority = 2 + name = "close cavity space" allowed_tools = list( + /obj/item/weapon/scalpel/laser3 = 115, \ + /obj/item/weapon/scalpel/laser2 = 110, \ + /obj/item/weapon/scalpel/laser1 = 105, \ + /obj/item/weapon/scalpel/manager = 120, \ /obj/item/weapon/cautery = 100, \ /obj/item/clothing/mask/cigarette = 75, \ /obj/item/weapon/lighter = 50, \ /obj/item/weapon/weldingtool = 25 ) - min_duration = 60 max_duration = 80 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return ..() && affected.cavity +/datum/surgery_step/cavity/close_space/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return ..() && affected.cavity - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts mending [target]'s [get_cavity(affected)] cavity wall with \the [tool].", \ - "You start mending [target]'s [get_cavity(affected)] cavity wall with \the [tool]." ) - target.custom_pain("The pain in your chest is living hell!",1) - affected.cavity = 0 - ..() +/datum/surgery_step/cavity/close_space/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts mending [target]'s [get_cavity(affected)] cavity wall with \the [tool].", \ + "You start mending [target]'s [get_cavity(affected)] cavity wall with \the [tool]." ) + target.custom_pain("The pain in your chest is living hell!",1) + affected.cavity = 0 + ..() + +/datum/surgery_step/cavity/close_space/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) + user.visible_message(" [user] mends [target]'s [get_cavity(affected)] cavity walls with \the [tool].", \ + " You mend [target]'s [get_cavity(affected)] cavity walls with \the [tool]." ) + + return 1 - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] mends [target]'s [get_cavity(affected)] cavity walls with \the [tool].", \ - "\blue You mend [target]'s [get_cavity(affected)] cavity walls with \the [tool]." ) /datum/surgery_step/cavity/place_item - priority = 0 + name = "implant/extract object" + accept_hand = 1 + accept_any_item = 1 + var/obj/item/IC = null allowed_tools = list(/obj/item = 100) - min_duration = 80 max_duration = 100 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (!ishuman(target)) - return 0 - var/obj/item/organ/external/affected = target.get_organ(target_zone) - var/can_fit = affected && !affected.hidden && affected.cavity && tool.w_class <= get_max_wclass(affected) - return ..() && can_fit - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) +/datum/surgery_step/cavity/place_item/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + if (!ishuman(target)) + return 0 + var/obj/item/organ/external/affected = target.get_organ(target_zone) + var/can_fit = affected && !affected.hidden && affected.cavity && tool.w_class <= get_max_wclass(affected) + return ..() && can_fit + +/datum/surgery_step/cavity/place_item/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + for(var/obj/item/I in target.internal_organs) + if(!istype(I, /obj/item/organ)) + IC = I + break + if(tool) user.visible_message("[user] starts putting \the [tool] inside [target]'s [get_cavity(affected)] cavity.", \ "You start putting \the [tool] inside [target]'s [get_cavity(affected)] cavity." ) - target.custom_pain("The pain in your chest is living hell!",1) - ..() + else if(IC) + user.visible_message("[user] checks for items in [target]'s [target_zone].", "You check for items in [target]'s [target_zone]...") + else //no internal items..but we still need a message! + user.visible_message("[user] checks for items in [target]'s [target_zone].", "You check for items in [target]'s [target_zone]...") - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) + target.custom_pain("The pain in your [target_zone] is living hell!",1) + ..() - if(istype(tool, /obj/item/weapon/disk/nuclear)) - user << "Central command would kill you if you implanted the disk into someone." +/datum/surgery_step/cavity/place_item/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) + + if(istype(tool, /obj/item/weapon/disk/nuclear)) + user << "Central command would kill you if you implanted the disk into someone." + return 0//fail + + if(istype(tool,/obj/item/organ)) + user << "This isn't the type of surgery for that!" + return 0//fail + + if(tool) + if(IC) + user << "There seems to be something in there already!" + return 1 else - user.visible_message("\blue [user] puts \the [tool] inside [target]'s [get_cavity(affected)] cavity.", \ - "\blue You put \the [tool] inside [target]'s [get_cavity(affected)] cavity." ) - if (tool.w_class > get_max_wclass(affected)/2 && prob(50) && !(affected.status & ORGAN_ROBOT)) - user << "\red You tear some vessels trying to fit such big object in this cavity." + user.visible_message(" [user] puts \the [tool] inside [target]'s [get_cavity(affected)] cavity.", \ + " You put \the [tool] inside [target]'s [get_cavity(affected)] cavity." ) + if((tool.w_class > get_max_wclass(affected)/2 && prob(50) && !(affected.status & ORGAN_ROBOT))) + user << " You tear some vessels trying to fit the object in the cavity." var/datum/wound/internal_bleeding/I = new () affected.wounds += I affected.owner.custom_pain("You feel something rip in your [affected.name]!", 1) user.drop_item() - affected.hidden = tool + target.internal_organs += tool tool.loc = target affected.cavity = 0 + return 1 + else + if(IC) + user.visible_message("[user] pulls [IC] out of [target]'s [target_zone]!", "You pull [IC] out of [target]'s [target_zone].") + user.put_in_hands(IC) + target.internal_organs -= IC + return 1 + else + user << "You don't find anything in [target]'s [target_zone]." + return 0 + ////////////////////////////////////////////////////////////////// // IMPLANT/ITEM REMOVAL SURGERY // ////////////////////////////////////////////////////////////////// +/datum/surgery/cavity_implant_rem + name = "implant removal" + steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin,/datum/surgery_step/cavity/implant_removal,/datum/surgery_step/cavity/close_space,/datum/surgery_step/generic/cauterize/) + possible_locs = list("chest")//head is for borers..i can put it elsewhere + +/datum/surgery/cavity_implant_rem/synth + name = "implant removal" + steps = list(/datum/surgery_step/robotics/external/unscrew_hatch,/datum/surgery_step/robotics/external/open_hatch,/datum/surgery_step/cavity/implant_removal,/datum/surgery_step/robotics/external/close_hatch) + possible_locs = list("chest")//head is for borers..i can put it elsewhere + allowed_mob = list(/mob/living/carbon/human/machine) + +/datum/surgery/cavity_implant_rem/can_start(mob/user, mob/living/carbon/target) + if(target.get_species() == "Machine") + return 0 + return 1 + +/datum/surgery/cavity_implant_rem/synth/can_start(mob/user, mob/living/carbon/target) + return target.get_species() == "Machine" + /datum/surgery_step/cavity/implant_removal + name = "extract implant" allowed_tools = list( /obj/item/weapon/hemostat = 100, \ /obj/item/weapon/wirecutters = 75, \ /obj/item/weapon/kitchen/utensil/fork = 20 ) + var/obj/item/weapon/implant/I = null + max_duration = 70 - min_duration = 80 - max_duration = 100 +/datum/surgery_step/cavity/implant_removal/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + I = locate(/obj/item/weapon/implant) in target + user.visible_message("[user] starts poking around inside [target]'s [affected.name] with \the [tool].", \ + "You start poking around inside [target]'s [affected.name] with \the [tool]." ) + target.custom_pain("The pain in your [affected.name] is living hell!",1) + ..() - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts poking around inside [target]'s [affected.name] with \the [tool].", \ - "You start poking around inside [target]'s [affected.name] with \the [tool]." ) - target.custom_pain("The pain in your [affected.name] is living hell!",1) - ..() +/datum/surgery_step/cavity/implant_removal/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + I = locate(/obj/item/weapon/implant) in target + if(I && (target_zone == "chest")) //implant removal only works on the chest. + user.visible_message("[user] takes something out of [target]'s [affected.name] with \the [tool].", \ + "You take [I] out of [target]'s [affected.name]s with \the [tool]." ) - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - var/obj/item/weapon/implant/I = locate(/obj/item/weapon/implant) in target + I.removed(target) - if (affected.implants.len) + var/obj/item/weapon/implantcase/case - var/obj/item/obj = affected.implants[1] + if(istype(user.get_item_by_slot(slot_l_hand), /obj/item/weapon/implantcase)) + case = user.get_item_by_slot(slot_l_hand) + else if(istype(user.get_item_by_slot(slot_r_hand), /obj/item/weapon/implantcase)) + case = user.get_item_by_slot(slot_r_hand) + else + case = locate(/obj/item/weapon/implantcase) in get_turf(target) - user.visible_message("\blue [user] takes something out of [target]'s [affected.name] with \the [tool].", \ - "\blue You take [obj] out of [target]'s [affected.name]s with \the [tool]." ) - affected.implants -= obj + if(case && !case.imp) + case.imp = I + I.loc = case + case.update_icon() + user.visible_message("[user] places [I] into [case]!", "You place [I] into [case].") + else + qdel(I) + //target.sec_hud_set_implants() + return 1 + else + user.visible_message(" [user] could not find anything inside [target]'s [affected.name], and pulls \the [tool] out.", \ + "You could not find anything inside [target]'s [affected.name].") + return 1 - //Handle possessive brain borers. - if(istype(obj,/mob/living/simple_animal/borer)) - var/mob/living/simple_animal/borer/worm = obj +/datum/surgery_step/cavity/implant_removal/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + ..() + var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) + if (affected.implants.len) + var/fail_prob = 10 + fail_prob += 100 - tool_quality(tool) + if (prob(fail_prob)) + var/obj/item/weapon/implant/imp = affected.implants[1] + user.visible_message(" Something beeps inside [target]'s [affected.name]!") + playsound(imp.loc, 'sound/items/countdown.ogg', 75, 1, -3) + spawn(25) + imp.activate() + return 0 + + +////////////////////////////////////////////////////////////////// +// EMBEDDED ITEM REOMOVAL // +////////////////////////////////////////////////////////////////// + +/datum/surgery/embedded_removal + name = "removal of embedded objects" + steps = list(/datum/surgery_step/generic/cut_open,/datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin,/datum/surgery_step/remove_object) + possible_locs = list("r_arm","l_arm","r_leg","l_leg","r_hand","r_foot","l_hand","l_foot","groin","chest","head") + + +/datum/surgery/embedded_removal/can_start(mob/user, mob/living/carbon/target) + if(target.get_species() == "Machine") + return 0 + return 1 + +/datum/surgery_step/remove_object + name = "remove embedded objects" + max_duration = 32 + accept_hand = 1 + var/obj/item/organ/external/L = null + + +/datum/surgery_step/remove_object/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery) + L = target.get_organ(target_zone) + if(L) + user.visible_message("[user] looks for objects embedded in [target]'s [target_zone].", "You look for objects embedded in [target]'s [target_zone]...") + else + user.visible_message("[user] looks for [target]'s [target_zone].", "You look for [target]'s [target_zone]...") + + +/datum/surgery_step/remove_object/end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery) + if(L) + if(ishuman(target)) + var/mob/living/carbon/human/H = target + var/objects = 0 + for(var/obj/item/I in L.implants) + if(!istype(I,/obj/item/weapon/implant)) + objects++ + I.forceMove(get_turf(H)) + L.implants -= I + + //Handle possessive brain borers. + if(H.has_brain_worms() && target_zone == "head")//remove worms outside the loop + var/mob/living/simple_animal/borer/worm = H.has_brain_worms() if(worm.controlling) target.release_control() worm.detatch() worm.leave_host() + user.visible_message("a slug like creature wiggles out of [H]'s [target_zone]!") - obj.loc = get_turf(target) - - else if(I && target_zone == "chest") //implant removal only works on the chest. - user.visible_message("[user] takes something out of [target]'s [affected.name] with \the [tool].", \ - "You take [I] out of [target]'s [affected.name]s with \the [tool]." ) - - I.removed(target) - - var/obj/item/weapon/implantcase/case - - if(istype(user.get_item_by_slot(slot_l_hand), /obj/item/weapon/implantcase)) - case = user.get_item_by_slot(slot_l_hand) - else if(istype(user.get_item_by_slot(slot_r_hand), /obj/item/weapon/implantcase)) - case = user.get_item_by_slot(slot_r_hand) + if(objects > 0) + user.visible_message("[user] sucessfully removes [objects] objects from [H]'s [L.limb_name]!", "You sucessfully remove [objects] objects from [H]'s [L.limb_name].") else - case = locate(/obj/item/weapon/implantcase) in get_turf(target) - - if(case && !case.imp) - case.imp = I - I.loc = case - case.update_icon() - user.visible_message("[user] places [I] into [case]!", "You place [I] into [case].") - else - qdel(I) - - else if (affected.hidden) - user.visible_message("\blue [user] takes something out of incision on [target]'s [affected.name] with \the [tool].", \ - "\blue You take something out of incision on [target]'s [affected.name]s with \the [tool]." ) - affected.hidden.loc = get_turf(target) - if(!affected.hidden.blood_DNA) - affected.hidden.blood_DNA = list() - affected.hidden.blood_DNA[target.dna.unique_enzymes] = target.dna.b_type - affected.hidden.update_icon() - affected.hidden = null - - else - user.visible_message("\blue [user] could not find anything inside [target]'s [affected.name], and pulls \the [tool] out.", \ - "\blue You could not find anything inside [target]'s [affected.name]." ) - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - ..() - var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) - if (affected.implants.len) - var/fail_prob = 10 - fail_prob += 100 - tool_quality(tool) - if (prob(fail_prob)) - var/obj/item/weapon/implant/imp = affected.implants[1] - user.visible_message("\red Something beeps inside [target]'s [affected.name]!") - playsound(imp.loc, 'sound/items/countdown.ogg', 75, 1, -3) - spawn(25) - imp.activate() + user << "You find no objects embedded in [H]'s [L.limb_name]!" + else + user << "You can't find [target]'s [target_zone], let alone any objects embedded in it!" + return 1 \ No newline at end of file diff --git a/code/modules/surgery/limb_reattach.dm b/code/modules/surgery/limb_reattach.dm index e264753633f..cc30fd87cb1 100644 --- a/code/modules/surgery/limb_reattach.dm +++ b/code/modules/surgery/limb_reattach.dm @@ -3,8 +3,70 @@ // LIMB SURGERY // ////////////////////////////////////////////////////////////////// +/datum/surgery/amputation + name = "amputation" + steps = list(/datum/surgery_step/generic/amputate) + possible_locs = list("head","l_arm", "l_hand","r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","groin") + + +/datum/surgery/amputation/can_start(mob/user, mob/living/carbon/target) + if(ishuman(target)) + var/mob/living/carbon/human/H = target + var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) + if((target.get_species() == "Machine")) + return 0 + if(!affected) + return 0 + + return 1 + + +/datum/surgery/reattach + name = "limb attachment" + steps = list(/datum/surgery_step/limb/attach,/datum/surgery_step/limb/connect) + possible_locs = list("head","l_arm", "l_hand","r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","groin") + +/datum/surgery/reattach/can_start(mob/user, mob/living/carbon/target) + if(ishuman(target)) + var/mob/living/carbon/human/H = target + var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) + if(!affected) + return 1 + if((target.get_species() == "Machine")) + return 0 + return 0 + +/datum/surgery/reattach_synth + name = "limb attachment" + steps = list(/datum/surgery_step/limb/attach) + possible_locs = list("head","l_arm", "l_hand","r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","groin") + allowed_mob = list(/mob/living/carbon/human/machine) + +/datum/surgery/reattach_synth/can_start(mob/user, mob/living/carbon/target) + if(ishuman(target)) + var/mob/living/carbon/human/H = target + var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) + if(!affected && (target.get_species() == "Machine")) + return 1 + + return 0 + + +/datum/surgery/robo_attach + name = "robotic limb attachment" + steps = list(/datum/surgery_step/limb/mechanize) + possible_locs = list("head","l_arm", "l_hand","r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","groin") + +/datum/surgery/robo_attach/can_start(mob/user, mob/living/carbon/target) + if(ishuman(target)) + var/mob/living/carbon/human/H = target + var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) + if(!affected) + return 1 + + return 0 + /datum/surgery_step/limb/ - priority = 3 // Must be higher than /datum/surgery_step/internal can_infect = 0 can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if (!hasorgans(target)) @@ -16,34 +78,44 @@ return !isnull(organ_data) /datum/surgery_step/limb/attach + name = "attach limb" allowed_tools = list(/obj/item/organ/external = 100) - min_duration = 50 max_duration = 70 - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/E = tool - user.visible_message("[user] starts attaching [E.name] to [target]'s [E.amputation_point].", \ - "You start attaching [E.name] to [target]'s [E.amputation_point].") +/datum/surgery_step/limb/attach/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/E = tool + user.visible_message("[user] starts attaching [E.name] to [target]'s [E.amputation_point].", \ + "You start attaching [E.name] to [target]'s [E.amputation_point].") - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/E = tool - user.visible_message("[user] has attached [target]'s [E.name] to the [E.amputation_point].", \ - "You have attached [target]'s [E.name] to the [E.amputation_point].") - user.unEquip(E) - E.replaced(target) - E.forceMove(target) - target.update_body() - target.updatehealth() - target.UpdateDamageIcon() +/datum/surgery_step/limb/attach/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/E = tool + user.visible_message("[user] has attached [target]'s [E.name] to the [E.amputation_point].", \ + "You have attached [target]'s [E.name] to the [E.amputation_point].") + user.unEquip(E) + E.replaced(target) + E.forceMove(target) + if(target.get_species() == "Machine")//as this is the only step needed for ipc put togethers + if(target_zone == "head") + target.h_style = "" + E.status &= ~ORGAN_DESTROYED + if(E.children) + for(var/obj/item/organ/external/C in E.children) + C.status &= ~ORGAN_DESTROYED + target.update_body() + target.updatehealth() + target.UpdateDamageIcon() + return 1 - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/E = tool - user.visible_message("[user]'s hand slips, damaging [target]'s [E.amputation_point]!", \ - "Your hand slips, damaging [target]'s [E.amputation_point]!") - target.apply_damage(10, BRUTE, null, sharp=1) +/datum/surgery_step/limb/attach/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/E = tool + user.visible_message("[user]'s hand slips, damaging [target]'s [E.amputation_point]!", \ + "Your hand slips, damaging [target]'s [E.amputation_point]!") + target.apply_damage(10, BRUTE, null, sharp=1) + return 0 /datum/surgery_step/limb/connect + name = "connect limb" allowed_tools = list( /obj/item/weapon/hemostat = 100, \ /obj/item/stack/cable_coil = 75, \ @@ -51,79 +123,93 @@ ) can_infect = 1 - min_duration = 100 max_duration = 120 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/E = target.get_organ(target_zone) - return E && !E.is_stump() && (E.status & ORGAN_DESTROYED) +/datum/surgery_step/limb/connect/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/E = target.get_organ(target_zone) + return E && !E.is_stump() && (E.status & ORGAN_DESTROYED) - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/E = target.get_organ(target_zone) - user.visible_message("[user] starts connecting tendons and muscles in [target]'s [E.amputation_point] with [tool].", \ - "You start connecting tendons and muscle in [target]'s [E.amputation_point].") +/datum/surgery_step/limb/connect/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/E = target.get_organ(target_zone) + user.visible_message("[user] starts connecting tendons and muscles in [target]'s [E.amputation_point] with [tool].", \ + "You start connecting tendons and muscle in [target]'s [E.amputation_point].") - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/E = target.get_organ(target_zone) - user.visible_message("[user] has connected tendons and muscles in [target]'s [E.amputation_point] with [tool].", \ - "You have connected tendons and muscles in [target]'s [E.amputation_point] with [tool].") - E.status &= ~ORGAN_DESTROYED - if(E.children) - for(var/obj/item/organ/external/C in E.children) - C.status &= ~ORGAN_DESTROYED - target.update_body() - target.updatehealth() - target.UpdateDamageIcon() +/datum/surgery_step/limb/connect/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/E = target.get_organ(target_zone) + user.visible_message("[user] has connected tendons and muscles in [target]'s [E.amputation_point] with [tool].", \ + "You have connected tendons and muscles in [target]'s [E.amputation_point] with [tool].") + E.status &= ~ORGAN_DESTROYED + var/obj/item/organ/external/stump = target.organs_by_name["limb stump"] + if(stump) + stump.remove(target) + if(E.children) + for(var/obj/item/organ/external/C in E.children) + C.status &= ~ORGAN_DESTROYED + target.update_body() + target.updatehealth() + target.UpdateDamageIcon() + return 1 - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/E = tool - user.visible_message("[user]'s hand slips, damaging [target]'s [E.amputation_point]!", \ - "Your hand slips, damaging [target]'s [E.amputation_point]!") - target.apply_damage(10, BRUTE, null, sharp=1) +/datum/surgery_step/limb/connect/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/organ/external/E = tool + user.visible_message("[user]'s hand slips, damaging [target]'s [E.amputation_point]!", \ + "Your hand slips, damaging [target]'s [E.amputation_point]!") + target.apply_damage(10, BRUTE, null, sharp=1) + return 0 /datum/surgery_step/limb/mechanize + name = "attach robotic limb" allowed_tools = list(/obj/item/robot_parts = 100) - min_duration = 80 max_duration = 100 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/obj/item/robot_parts/p = tool - if (p.part) - if (!(target_zone in p.part)) - return 0 - return isnull(target.get_organ(target_zone)) +/datum/surgery_step/limb/mechanize/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + if(..()) + var/obj/item/robot_parts/p = tool + if (p.part) + if (!(target_zone in p.part)) + return 0 + return isnull(target.get_organ(target_zone)) - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/limb/mechanize/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) user.visible_message("[user] starts attaching \the [tool] to [target].", \ "You start attaching \the [tool] to [target].") - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/robot_parts/L = tool - user.visible_message("[user] has attached \the [tool] to [target].", \ - "You have attached \the [tool] to [target].") +/datum/surgery_step/limb/mechanize/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/obj/item/robot_parts/L = tool + user.visible_message("[user] has attached \the [tool] to [target].", \ + "You have attached \the [tool] to [target].") - if(L.part) - for(var/part_name in L.part) - if(!isnull(target.get_organ(part_name))) - continue - var/list/organ_data = target.species.has_limbs["[part_name]"] - if(!organ_data) - continue - var/new_limb_type = organ_data["path"] - var/obj/item/organ/external/new_limb = new new_limb_type(target) - new_limb.robotize(L.model_info) - if(L.sabotaged) - new_limb.sabotaged = 1 + if(L.part) + for(var/part_name in L.part) + if(!isnull(target.get_organ(part_name))) + continue + var/list/organ_data = target.species.has_limbs["[part_name]"] + if(!organ_data) + continue + var/obj/item/organ/external/stump = target.organs_by_name["limb stump"] + if(stump) + stump.remove(target) + var/new_limb_type = organ_data["path"] + var/obj/item/organ/external/new_limb = new new_limb_type(target) + new_limb.robotize(L.model_info) + new_limb.replaced(target) + new_limb.status &= ~ORGAN_DESTROYED + if(new_limb.children) + for(var/obj/item/organ/external/C in new_limb.children) + C.status &= ~ORGAN_DESTROYED + if(L.sabotaged) + new_limb.sabotaged = 1 + target.update_body() + target.updatehealth() + target.UpdateDamageIcon() - target.update_body() - target.updatehealth() - target.UpdateDamageIcon() + qdel(tool) - qdel(tool) + return 1 - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user]'s hand slips, damaging [target]'s flesh!", \ - "Your hand slips, damaging [target]'s flesh!") - target.apply_damage(10, BRUTE, null, sharp=1) +/datum/surgery_step/limb/mechanize/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + user.visible_message("[user]'s hand slips, damaging [target]'s flesh!", \ + "Your hand slips, damaging [target]'s flesh!") + target.apply_damage(10, BRUTE, null, sharp=1) + return 0 diff --git a/code/modules/surgery/organs/augments_eyes.dm b/code/modules/surgery/organs/augments_eyes.dm new file mode 100644 index 00000000000..6dcd76bedfa --- /dev/null +++ b/code/modules/surgery/organs/augments_eyes.dm @@ -0,0 +1,141 @@ +/obj/item/organ/internal/cyberimp/eyes + name = "cybernetic eyes" + desc = "artificial photoreceptors with specialized functionality" + icon_state = "eye_implant" + implant_overlay = "eye_implant_overlay" + slot = "eye_sight" + parent_organ = "eyes" + w_class = 1 + + var/vision_flags = 0 + var/list/eye_colour = list(0,0,0) + var/list/old_eye_colour = list(0,0,0) + var/flash_protect = 0 + var/aug_message = "Your vision is augmented!" + +/obj/item/organ/internal/cyberimp/eyes/proc/update_colour() + if(!owner) + return + eye_colour = list( + owner.r_eyes ? owner.r_eyes : 0, + owner.g_eyes ? owner.g_eyes : 0, + owner.b_eyes ? owner.b_eyes : 0 + ) + + +/obj/item/organ/internal/cyberimp/eyes/insert(var/mob/living/carbon/M, var/special = 0) + ..() + if(istype(owner, /mob/living/carbon/human) && eye_colour) + var/mob/living/carbon/human/HMN = owner + old_eye_colour[1] = HMN.r_eyes + old_eye_colour[2] = HMN.g_eyes + old_eye_colour[2] = HMN.b_eyes + + HMN.r_eyes = eye_colour[1] + HMN.g_eyes = eye_colour[2] + HMN.b_eyes = eye_colour[3] + HMN.update_eyes() + if(aug_message && !special) + owner << "[aug_message]" + M.sight |= vision_flags + +/obj/item/organ/internal/cyberimp/eyes/remove(var/mob/living/carbon/M, var/special = 0) + ..() + M.sight ^= vision_flags + if(istype(owner,/mob/living/carbon/human) && eye_colour) + var/mob/living/carbon/human/HMN = owner + HMN.r_eyes = old_eye_colour[1] + HMN.g_eyes = old_eye_colour[2] + HMN.b_eyes = old_eye_colour[3] + HMN.update_eyes() + +/obj/item/organ/internal/cyberimp/eyes/on_life() + ..() + owner.sight |= vision_flags + +/obj/item/organ/internal/cyberimp/eyes/emp_act(severity) + if(!owner) + return + if(severity > 1) + if(prob(10 * severity)) + return + var/save_sight = owner.sight + owner.sight &= 0 + owner.sdisabilities |= BLIND + owner << "Static obfuscates your vision!" + spawn(60 / severity) + if(owner) + owner.sight |= save_sight + owner.sdisabilities ^= BLIND + + + +/obj/item/organ/internal/cyberimp/eyes/xray + name = "X-ray implant" + desc = "These cybernetic eye implants will give you X-ray vision. Blinking is futile." + eye_colour = list(0, 0, 0) + implant_color = "#000000" + origin_tech = "materials=6;programming=4;biotech=6;magnets=5" + vision_flags = SEE_MOBS | SEE_OBJS | SEE_TURFS + +/obj/item/organ/internal/cyberimp/eyes/thermals + name = "Thermals implant" + desc = "These cybernetic eye implants will give you Thermal vision. Vertical slit pupil included." + eye_colour = list(255, 204, 0) + implant_color = "#FFCC00" + vision_flags = SEE_MOBS + flash_protect = -1 + origin_tech = "materials=6;programming=4;biotech=5;magnets=5;syndicate=4" + aug_message = "You see prey everywhere you look..." + +// HUD implants +/obj/item/organ/internal/cyberimp/eyes/hud + name = "HUD implant" + desc = "These cybernetic eyes will display a HUD over everything you see. Maybe." + slot = "eye_hud" + var/HUD_type = 0 + +/obj/item/organ/internal/cyberimp/eyes/hud/insert(var/mob/living/carbon/M, var/special = 0) + ..() + if(HUD_type) + var/datum/atom_hud/H = huds[HUD_type] + H.add_hud_to(M) + M.permanent_huds |= H + +/obj/item/organ/internal/cyberimp/eyes/hud/remove(var/mob/living/carbon/M, var/special = 0) + ..() + if(HUD_type) + var/datum/atom_hud/H = huds[HUD_type] + M.permanent_huds ^= H + H.remove_hud_from(M) + +/obj/item/organ/internal/cyberimp/eyes/hud/medical + name = "Medical HUD implant" + desc = "These cybernetic eye implants will display a medical HUD over everything you see." + eye_colour = list(0,0,208) + implant_color = "#00FFFF" + origin_tech = "materials=4;programming=3;biotech=4" + aug_message = "You suddenly see health bars floating above people's heads..." + HUD_type = DATA_HUD_MEDICAL_ADVANCED + +/obj/item/organ/internal/cyberimp/eyes/hud/security + name = "Security HUD implant" + desc = "These cybernetic eye implants will display a security HUD over everything you see." + eye_colour = list(208,0,0) + implant_color = "#CC0000" + origin_tech = "materials=4;programming=4;biotech=3;combat=1" + aug_message = "Job indicator icons pop up in your vision. That is not a certified surgeon..." + HUD_type = DATA_HUD_SECURITY_ADVANCED + +// Welding shield implant +/obj/item/organ/internal/cyberimp/eyes/shield + name = "welding shield implant" + desc = "These reactive micro-shields will protect you from welders and flashes without obscuring your vision." + slot = "eye_shield" + origin_tech = "materials=4;biotech=3" + implant_color = "#101010" + flash_protect = 2 + // Welding with thermals will still hurt your eyes a bit. + +/obj/item/organ/internal/cyberimp/eyes/shield/emp_act(severity) + return \ No newline at end of file diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm new file mode 100644 index 00000000000..7e7eaf75ff9 --- /dev/null +++ b/code/modules/surgery/organs/augments_internal.dm @@ -0,0 +1,345 @@ +#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" + status = ORGAN_ROBOT + var/implant_color = "#FFFFFF" + var/implant_overlay + tough = 1 //not easyly broken by combat damage + sterile = 1 //not very germy + +/obj/item/organ/internal/cyberimp/New(var/mob/M = null) + if(iscarbon(M)) + src.insert(M) + if(implant_overlay) + var/image/overlay = new /image(icon, implant_overlay) + overlay.color = implant_color + overlays |= overlay + return ..() + + + +//[[[[BRAIN]]]] + +/obj/item/organ/internal/cyberimp/brain + name = "cybernetic brain implant" + desc = "injectors of extra sub-routines for the brain" + icon_state = "brain_implant" + implant_overlay = "brain_implant_overlay" + parent_organ = "head" + +/obj/item/organ/internal/cyberimp/brain/emp_act(severity) + if(!owner) + return + var/stun_amount = 5 + (severity-1 ? 0 : 5) + owner.Stun(stun_amount) + owner << "Your body seizes up!" + return stun_amount + + +/obj/item/organ/internal/cyberimp/brain/anti_drop + name = "Anti-drop implant" + desc = "This cybernetic brain implant will allow you to force your hand muscles to contract, preventing item dropping. Twitch ear to toggle." + var/active = 0 + var/l_hand_ignore = 0 + var/r_hand_ignore = 0 + var/obj/item/l_hand_obj = null + var/obj/item/r_hand_obj = null + implant_color = "#DE7E00" + slot = "brain_antidrop" + origin_tech = "materials=5;programming=4;biotech=4" + organ_action_name = "Toggle Anti-Drop" + +/obj/item/organ/internal/cyberimp/brain/anti_drop/ui_action_click() + active = !active + if(active) + l_hand_obj = owner.l_hand + r_hand_obj = owner.r_hand + if(l_hand_obj) + if(owner.l_hand.flags & NODROP) + l_hand_ignore = 1 + else + owner.l_hand.flags |= NODROP + l_hand_ignore = 0 + + if(r_hand_obj) + if(owner.r_hand.flags & NODROP) + r_hand_ignore = 1 + else + owner.r_hand.flags |= NODROP + r_hand_ignore = 0 + + if(!l_hand_obj && !r_hand_obj) + owner << "You are not holding any items, your hands relax..." + active = 0 + else + var/msg = 0 + msg += !l_hand_ignore && l_hand_obj ? 1 : 0 + msg += !r_hand_ignore && r_hand_obj ? 2 : 0 + switch(msg) + if(1) + owner << "Your left hand's grip tightens." + if(2) + owner << "Your right hand's grip tightens." + if(3) + owner << "Both of your hand's grips tighten." + else + release_items() + owner << "Your hands relax..." + l_hand_obj = null + r_hand_obj = null + +/obj/item/organ/internal/cyberimp/brain/anti_drop/emp_act(severity) + if(!owner) + return + var/range = severity ? 10 : 5 + var/atom/A + var/obj/item/L_item = owner.l_hand + var/obj/item/R_item = owner.r_hand + + release_items() + ..() + if(L_item) + A = pick(oview(range)) + L_item.throw_at(A, range, 2) + owner << "Your left arm spasms and throws the [L_item.name]!" + if(R_item) + A = pick(oview(range)) + R_item.throw_at(A, range, 2) + owner << "Your right arm spasms and throws the [R_item.name]!" + +/obj/item/organ/internal/cyberimp/brain/anti_drop/proc/release_items() + if(!l_hand_ignore && l_hand_obj in owner.contents) + l_hand_obj.flags ^= NODROP + if(!r_hand_ignore && r_hand_obj in owner.contents) + r_hand_obj.flags ^= NODROP + +/obj/item/organ/internal/cyberimp/brain/anti_drop/remove(var/mob/living/carbon/M, special = 0) + ..() + if(active) + ui_action_click() + + +/obj/item/organ/internal/cyberimp/brain/anti_stun + name = "CNS Rebooter implant" + desc = "This implant will automatically give you back control over your central nervous system, reducing downtime when stunned." + implant_color = "#FFFF00" + slot = "brain_antistun" + origin_tech = "materials=6;programming=4;biotech=5" + +/obj/item/organ/internal/cyberimp/brain/anti_stun/on_life() + ..() + if(crit_fail) + return + if(owner.stunned > STUN_SET_AMOUNT) + owner.stunned = STUN_SET_AMOUNT + if(owner.weakened > STUN_SET_AMOUNT) + owner.weakened = STUN_SET_AMOUNT + +/obj/item/organ/internal/cyberimp/brain/anti_stun/emp_act(severity) + if(crit_fail) + return + crit_fail = 1 + spawn(90 / severity) + crit_fail = 0 + +//[[[[CHEST]]]] +/obj/item/organ/internal/cyberimp/chest + name = "cybernetic torso implant" + desc = "implants for the organs in your torso" + icon_state = "chest_implant" + implant_overlay = "chest_implant_overlay" + parent_organ = "chest" + +/obj/item/organ/internal/cyberimp/chest/nutriment + name = "Nutriment pump implant" + desc = "This implant with synthesize and pump into your bloodstream a small amount of nutriment when you are starving." + icon_state = "chest_implant" + implant_color = "#00AA00" + var/hunger_threshold = 150 + var/synthesizing = 0 + var/poison_amount = 5 + slot = "stomach" + origin_tech = "materials=5;programming=3;biotech=4" + +/obj/item/organ/internal/cyberimp/chest/nutriment/on_life() + if(!owner) + return + if(synthesizing) + return + if(owner.stat == DEAD) + return + if(owner.nutrition <= hunger_threshold) + synthesizing = 1 + owner << "You feel less hungry..." + owner.nutrition += 50 + spawn(50) + synthesizing = 0 + +/obj/item/organ/internal/cyberimp/chest/nutriment/emp_act(severity) + if(!owner) + return + owner.reagents.add_reagent("????",poison_amount / severity) //food poisoning + owner << "You feel like your insides are burning." + +/obj/item/organ/internal/cyberimp/chest/nutriment/plus + name = "Nutriment pump implant PLUS" + desc = "This implant will synthesize and pump into your bloodstream a small amount of nutriment when you are hungry." + icon_state = "chest_implant" + implant_color = "#006607" + hunger_threshold = 250 + poison_amount = 10 + origin_tech = "materials=5;programming=3;biotech=5" + +/obj/item/organ/internal/cyberimp/chest/reviver + name = "Reviver implant" + desc = "This implant will attempt to revive you if you lose consciousness. For the faint of heart!" + icon_state = "chest_implant" + implant_color = "#AD0000" + origin_tech = "materials=6;programming=3;biotech=6;syndicate=4" + slot = "heartdrive" + var/revive_cost = 0 + var/reviving = 0 + var/cooldown = 0 + +/obj/item/organ/internal/cyberimp/chest/reviver/on_life() + if(reviving) + if(owner.stat == UNCONSCIOUS) + spawn(30) + if(prob(90) && owner.getOxyLoss()) + owner.adjustOxyLoss(-3) + revive_cost += 5 + if(prob(75) && owner.getBruteLoss()) + owner.adjustBruteLoss(-1) + revive_cost += 20 + if(prob(75) && owner.getFireLoss()) + owner.adjustFireLoss(-1) + revive_cost += 20 + if(prob(40) && owner.getToxLoss()) + owner.adjustToxLoss(-1) + revive_cost += 50 + else + cooldown = revive_cost + world.time + reviving = 0 + return + if(cooldown > world.time) + return + if(owner.stat != UNCONSCIOUS) + return + if(owner.suiciding) + return + revive_cost = 0 + reviving = 1 + +/obj/item/organ/internal/cyberimp/chest/reviver/emp_act(severity) + if(!owner) + return + if(reviving) + revive_cost += 200 + else + cooldown += 200 + if(istype(owner, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = owner + if(H.stat != DEAD && prob(50 / severity)) + H.heart_attack = 1 + spawn(600 / severity) + H.heart_attack = 0 + if(H.stat == CONSCIOUS) + H << "You feel your heart beating again!" + +//ARM...THAT GO IN THE CHEST +/obj/item/organ/internal/cyberimp/chest/arm_mod//dummy parent item for making arm-mod implants. works best with nodrop items that are sent to nullspace upon being dropped. + name = "Arm-mounted item implant" + desc = "You shouldn't see this! Adminhelp and report this as an issue on github!" + icon_state = "chest_implant" + implant_color = "#007ACC" + slot = "shoulders" + origin_tech = "materials=5;biotech=4;powerstorage=4" + organ_action_name = "Toggle Arm Mod" + var/obj/holder//is defined as the retractable item itself. ensure this is defined somewhere! + var/out = 0//determines if the item is in the owner's hand or not + var/overloaded = 0//is set to 1 when owner gets EMPed. if set to 1, implant doesn't work. + var/lasthand = null + +/obj/item/organ/internal/cyberimp/chest/arm_mod/ui_action_click() + if(overloaded)//ensure the implant isn't broken + owner << "The implant doesn't respond. It seems to be broken..." + return + if(out)//check if the owner has the item out already + owner.unEquip(holder, 1)//if he does, take it away. then, + holder.loc = null//stash it in nullspace + out = 0//and set this to clarify the item isn't out. + owner.visible_message("[owner] retracts [holder].","You retract [holder].") + playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, 1) + else//if he doesn't have the item out + if(owner.put_in_hands(holder))//put it in his hands. + lasthand = owner.get_active_hand() + out = 1 + owner.visible_message("[owner] extends [holder]!","You extend [holder]!") + playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, 1) + else//if this fails to put the item in his hands, + holder.loc = null//keep it in nullspace + owner << "You can't extend [holder] if you can't use your hands!" + +/obj/item/organ/internal/cyberimp/chest/arm_mod/emp_act(severity)//if the implant gets EMPed... + if(!owner || overloaded)//ensure that it's in an owner and that it's not already EMPed, then... + return + if(out)//check if he has the item out... + owner.unEquip(holder, 1)//if he does, take it away. + holder.loc = null + out = 0 + owner.visible_message("[holder] forcibly retracts into [owner]'s arm.") + owner.visible_message("A loud bang comes from [owner]...") + playsound(get_turf(owner), 'sound/effects/bang.ogg', 100, 1) + owner << "You feel an explosion erupt inside you as your chest implant breaks. Is it hot in here?" + owner.adjust_fire_stacks(20) + owner.IgniteMob()//ignite the owner, as well as + owner.say("AUUUUUUUUUUUUUUUUUUGH!!") + if(prob(50)) + if(lasthand == "r_hand") + var/obj/item/organ/external/limb = owner.get_organ("r_arm") + limb.droplimb(0, DROPLIMB_EDGE) + else if(lasthand == "l_hand") + var/obj/item/organ/external/limb = owner.get_organ("l_arm") + limb.droplimb(0, DROPLIMB_EDGE) + owner.say("I HAVE BEEN DISARMED!!!") + owner.adjustFireLoss(25)//severely injure him! + overloaded = 1//then make sure this can't happen again by breaking the implant. + +/obj/item/organ/internal/cyberimp/chest/arm_mod/tase//mounted, self-charging taser! + name = "Arm-cannon taser implant" + desc = "A variant of the arm cannon implant that fires electrodes and disabler shots. The cannon emerges from the subject's arms and remains in the shoulders when not in use." + icon_state = "armcannon_tase_implant" + origin_tech = "materials=5;combat=5;biotech=4;powerstorage=4" + organ_action_name = "Toggle Arm Cannon Taser" + +/obj/item/organ/internal/cyberimp/chest/arm_mod/tase/New()//when the implant is created... + holder = new /obj/item/weapon/gun/energy/advtaser/mounted(src)//assign a brand new item to it. (in this case, a gun) + +/obj/item/organ/internal/cyberimp/chest/arm_mod/lase//mounted, self-charging laser! + name = "Arm-cannon laser implant" + desc = "A variant of the arm cannon implant that fires lethal laser beams. The cannon emerges from the subject's arms and remains in the shoulders when not in use." + icon_state = "armcannon_lase_implant" + origin_tech = "materials=5;combat=5;biotech=4;powerstorage=4;syndicate=5"//this is kinda nutty and i might lower it + organ_action_name = "Toggle Arm Cannon Laser" + +/obj/item/organ/internal/cyberimp/chest/arm_mod/lase/New() + holder = new /obj/item/weapon/gun/energy/laser/mounted(src) + +//BOX O' IMPLANTS +/obj/item/weapon/storage/box/cyber_implants + name = "boxed cybernetic implants" + desc = "A sleek, sturdy box." + icon_state = "cyber_implants" + var/list/boxed = list(/obj/item/organ/internal/cyberimp/eyes/xray,/obj/item/organ/internal/cyberimp/eyes/thermals, + /obj/item/organ/internal/cyberimp/brain/anti_stun, /obj/item/organ/internal/cyberimp/chest/reviver) + var/amount = 5 + +/obj/item/weapon/storage/box/cyber_implants/New() + ..() + var/i + var/implant + for(i = 0, i < amount, i++) + implant = pick(boxed) + new implant(src) \ No newline at end of file diff --git a/code/modules/organs/blood.dm b/code/modules/surgery/organs/blood.dm similarity index 99% rename from code/modules/organs/blood.dm rename to code/modules/surgery/organs/blood.dm index 93fc4de5cc2..60dd2f1f10c 100644 --- a/code/modules/organs/blood.dm +++ b/code/modules/surgery/organs/blood.dm @@ -87,7 +87,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 // Damaged heart virtually reduces the blood volume, as the blood isn't // being pumped properly anymore. - var/obj/item/organ/heart/heart = internal_organs_by_name["heart"] + var/obj/item/organ/internal/heart/heart = get_int_organ(/obj/item/organ/internal/heart) if(heart) if(heart.damage > 1 && heart.damage < heart.min_bruised_damage) diff --git a/code/modules/surgery/organs/body_egg.dm b/code/modules/surgery/organs/body_egg.dm new file mode 100644 index 00000000000..4e53f525c4f --- /dev/null +++ b/code/modules/surgery/organs/body_egg.dm @@ -0,0 +1,53 @@ +/obj/item/organ/internal/body_egg + name = "body egg" + desc = "All slimy and yuck." + icon_state = "innards" + origin_tech = "biotech=5" + parent_organ = "chest" + slot = "parasite_egg" + +/obj/item/organ/internal/body_egg/on_find(mob/living/finder) + ..() + finder << "You found an unknown alien organism in [owner]'s [parent_organ]!" + +/obj/item/organ/internal/body_egg/New(loc) + if(iscarbon(loc)) + insert(loc) + return ..() + +/obj/item/organ/internal/body_egg/insert(var/mob/living/carbon/M, special = 0) + ..() + owner.status_flags |= XENO_HOST + processing_objects.Add(src) + owner.med_hud_set_status() + spawn(0) + AddInfectionImages(owner) + +/obj/item/organ/internal/body_egg/remove(var/mob/living/carbon/M, special = 0) + processing_objects.Remove(src) + if(owner) + owner.status_flags &= ~(XENO_HOST) + owner.med_hud_set_status() + spawn(0) + RemoveInfectionImages(owner) + ..() + +/obj/item/organ/internal/body_egg/process() + if(!owner) return + if(!(src in owner.internal_organs)) + remove(owner) + return + egg_process() + +/obj/item/organ/internal/body_egg/proc/egg_process() + return + +/obj/item/organ/internal/body_egg/proc/RefreshInfectionImage() + RemoveInfectionImages() + AddInfectionImages() + +/obj/item/organ/internal/body_egg/proc/AddInfectionImages() + return + +/obj/item/organ/internal/body_egg/proc/RemoveInfectionImages() + return \ No newline at end of file diff --git a/code/modules/surgery/organs/helpers.dm b/code/modules/surgery/organs/helpers.dm new file mode 100644 index 00000000000..29bd9801b26 --- /dev/null +++ b/code/modules/surgery/organs/helpers.dm @@ -0,0 +1,43 @@ +/mob/proc/get_int_organ(typepath) //int stands for internal + return + +/mob/proc/get_organs_zone(zone) + return + +/mob/proc/get_organ_slot(slot) //is it a brain, is it a brain_tumor? + return + +/mob/proc/get_int_organ_tag(tag) //is it a brain, is it a brain_tumor? + return + +/mob/living/carbon/get_int_organ(typepath) + return (locate(typepath) in internal_organs) + + +/mob/living/carbon/get_organs_zone(zone, var/subzones = 0) + var/list/returnorg = list() + if(subzones) + // Include subzones - groin for chest, eyes and mouth for head + //Fethas note:We have check_zone, i may need to remove the below + if(zone == "head") + returnorg = get_organs_zone("eyes") + get_organs_zone("mouth") + if(zone == "chest") + returnorg = get_organs_zone("groin") + + for(var/obj/item/organ/internal/O in internal_organs) + if(zone == O.parent_organ) + returnorg += O + return returnorg + +/mob/living/carbon/get_organ_slot(slot) + for(var/obj/item/organ/internal/O in internal_organs) + if(slot == O.slot) + return O + +/mob/living/carbon/get_int_organ_tag(tag) + for(var/obj/item/organ/internal/O in internal_organs) + if(tag == O.organ_tag) + return O + +/proc/is_int_organ(atom/A) + return istype(A, /obj/item/organ/internal) \ No newline at end of file diff --git a/code/modules/organs/organ.dm b/code/modules/surgery/organs/organ.dm similarity index 79% rename from code/modules/organs/organ.dm rename to code/modules/surgery/organs/organ.dm index 82f35730bf8..fee4aaa1eb6 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/surgery/organs/organ.dm @@ -29,42 +29,18 @@ var/list/organ_cache = list() var/freezer_update_period = 100 var/is_in_freezer = 0 -/obj/item/organ/Destroy() - if(!owner) - return ..() - - if(istype(owner, /mob/living/carbon)) - if((owner.internal_organs) && (src in owner.internal_organs)) - owner.internal_organs -= src - if(istype(owner, /mob/living/carbon/human)) - if((owner.internal_organs_by_name) && (src in owner.internal_organs_by_name)) - owner.internal_organs_by_name -= src - if((owner.organs) && (src in owner.organs)) - owner.organs -= src - if((owner.organs_by_name) && (src in owner.organs_by_name)) - owner.organs_by_name -= src - if(src in owner.contents) - owner.contents -= src - - return ..() - -/obj/item/organ/attack_self(mob/user as mob) - - // Convert it to an edible form, yum yum. - if(!robotic && user.a_intent == I_HARM) - bitten(user) - return + var/sterile = 0 //can the organ be infected by germs? + var/tough = 0 //can organ be easily damaged? /obj/item/organ/proc/update_health() return -/obj/item/organ/New(var/mob/living/carbon/holder, var/internal) +/obj/item/organ/New(var/mob/living/carbon/holder) ..(holder) create_reagents(5) if(!max_damage) max_damage = min_broken_damage * 2 if(istype(holder)) - src.owner = holder species = all_species["Human"] if(holder.dna) dna = holder.dna.Clone() @@ -73,18 +49,10 @@ var/list/organ_cache = list() log_to_dd("[src] at [loc] spawned without a proper DNA.") var/mob/living/carbon/human/H = holder if(istype(H)) - if(internal) - var/obj/item/organ/external/E = H.organs_by_name[src.parent_organ] - if(E) - if(E.internal_organs == null) - E.internal_organs = list() - E.internal_organs |= src if(dna) if(!blood_DNA) blood_DNA = list() blood_DNA[dna.unique_enzymes] = dna.b_type - if(internal) - holder.internal_organs |= src /obj/item/organ/proc/set_dna(var/datum/dna/new_dna) if(new_dna) @@ -104,8 +72,6 @@ var/list/organ_cache = list() owner.death() /obj/item/organ/process() - if(loc != owner) - owner = null //dead already, no need for more processing if(status & ORGAN_DEAD) @@ -115,7 +81,7 @@ var/list/organ_cache = list() return //Process infections - if ((status & ORGAN_ROBOT) || (owner && owner.species && (owner.species.flags & IS_PLANT))) + if ((status & ORGAN_ROBOT) || (sterile) ||(owner && owner.species && (owner.species.flags & IS_PLANT))) germ_level = 0 return @@ -246,6 +212,8 @@ var/list/organ_cache = list() //Note: external organs have their own version of this proc /obj/item/organ/proc/take_damage(amount, var/silent=0) + if(tough) + return if(src.status & ORGAN_ROBOT) src.damage = between(0, src.damage + (amount * 0.8), max_damage) else @@ -288,15 +256,10 @@ var/list/organ_cache = list() if(3.0) take_damage(0,3) -/obj/item/organ/proc/removed(var/mob/living/user) +/obj/item/organ/proc/remove(var/mob/living/user,special = 0) if(!istype(owner)) return - if(is_primary_organ()) - owner.internal_organs_by_name[organ_tag] = null - owner.internal_organs_by_name -= organ_tag - owner.internal_organs_by_name -= null // uh what does this line even do this seems silly - owner.internal_organs -= src var/obj/item/organ/external/affected = owner.get_organ(parent_organ) @@ -323,42 +286,13 @@ var/list/organ_cache = list() owner = target processing_objects -= src - target.internal_organs |= src affected.internal_organs |= src - if (!(organ_tag in target.internal_organs_by_name)) - target.internal_organs_by_name[organ_tag] = src // In case multiple of the same type are inserted, only the first one is the primary organ + if (!target.get_int_organ(src)) + target.internal_organs += src src.loc = target if(robotic) status |= ORGAN_ROBOT -/obj/item/organ/eyes/replaced(var/mob/living/carbon/human/target) - - // Apply our eye colour to the target. - if(istype(target) && eye_colour) - target.r_eyes = eye_colour[1] - target.g_eyes = eye_colour[2] - target.b_eyes = eye_colour[3] - target.update_eyes() - ..() - -/obj/item/organ/proc/bitten(mob/user) - - if(robotic) - return - - user << "\blue You take a bite out of \the [src]." - - user.unEquip(src) - var/obj/item/weapon/reagent_containers/food/snacks/organ/O = new(get_turf(src)) - O.name = name - O.icon_state = dead_icon ? dead_icon : icon_state - - if(fingerprints) O.fingerprints = fingerprints.Copy() - if(fingerprintshidden) O.fingerprintshidden = fingerprintshidden.Copy() - if(fingerprintslast) O.fingerprintslast = fingerprintslast - - user.put_in_active_hand(O) - qdel(src) /obj/item/organ/proc/surgeryize() return @@ -373,4 +307,4 @@ I use this so that this can be made better once the organ overhaul rolls out -- O = owner if (!istype(owner)) // You're not the primary organ of ANYTHING, bucko return 0 - return src == O.internal_organs_by_name[organ_tag] + return src == O.get_int_organ(organ_tag) diff --git a/code/modules/organs/organ_external.dm b/code/modules/surgery/organs/organ_external.dm similarity index 95% rename from code/modules/organs/organ_external.dm rename to code/modules/surgery/organs/organ_external.dm index acfaa22fd9d..63a958fe065 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/surgery/organs/organ_external.dm @@ -69,14 +69,15 @@ if(parent && parent.children) parent.children -= src + if(internal_organs) + for(var/obj/item/organ/internal/O in internal_organs) + internal_organs -= O + O.remove(owner,special = 1) + if(children) for(var/obj/item/organ/external/C in children) qdel(C) - if(internal_organs) - for(var/obj/item/organ/O in internal_organs) - qdel(O) - return ..() /obj/item/organ/external/attackby(obj/item/weapon/W as obj, mob/user as mob) @@ -99,11 +100,12 @@ if(contents.len) var/obj/item/removing = pick(contents) removing.loc = get_turf(user.loc) - var/obj/item/organ/O = removing + var/obj/item/organ/internal/O = removing if(istype(O)) O.status |= ORGAN_CUT_AWAY - spread_germs_to_organ(O,user) // This wouldn't be any cleaner than the actual surgery - O.removed(user) + if(!O.sterile) + spread_germs_to_organ(O,user) // This wouldn't be any cleaner than the actual surgery + O.forceMove(src) if(!(user.l_hand && user.r_hand)) user.put_in_hands(removing) user.visible_message("[user] extracts [removing] from [src] with [W]!") @@ -112,27 +114,32 @@ return ..() + /obj/item/organ/external/update_health() damage = min(max_damage, (brute_dam + burn_dam)) return -/obj/item/organ/external/New(var/mob/living/carbon/holder, var/internal) +/obj/item/organ/external/New(var/mob/living/carbon/holder) ..() - if(owner) - replaced(owner) - sync_colour_to_human(owner) + if(istype(holder, /mob/living/carbon/human)) + replaced(holder) + sync_colour_to_human(holder) spawn(1) get_icon() /obj/item/organ/external/replaced(var/mob/living/carbon/human/target) owner = target status = status & ~ORGAN_DESTROYED + forceMove(owner) if(istype(owner)) owner.organs_by_name[limb_name] = src owner.organs |= src for(var/obj/item/organ/organ in src) - organ.loc = owner + if(istype(src, /obj/item/organ/internal)) + var/obj/item/organ/internal/I = organ + if(target.get_organ_slot(I.slot)) + continue // Just leave it inside its limb, so brains with brainmobs in them don't get voided. organ.replaced(owner,src) if(parent_organ) @@ -141,6 +148,12 @@ if(!parent.children) parent.children = list() parent.children.Add(src) + //Remove all stump wounds since limb is not missing anymore + for(var/datum/wound/lost_limb/W in parent.wounds) + parent.wounds -= W + qdel(W) + break + parent.update_damages() /**************************************************** DAMAGE PROCS @@ -168,8 +181,9 @@ if(internal_organs && (brute_dam >= max_damage || (((sharp && brute >= sharp_thresh_int_dmg) || brute >= thresh_int_dmg) && prob(dmg_prob)) || (!encased && prob(no_bone_dmg_prob)))) // Damage an internal organ if(internal_organs && internal_organs.len) - var/obj/item/organ/I = pick(internal_organs) - I.take_damage(brute / 2) + var/obj/item/organ/internal/I = pick(internal_organs) + if(!I.tough)//mostly for cybernetic organs + I.take_damage(brute / 2) brute -= brute / 2 if(status & ORGAN_BROKEN && prob(40) && brute) @@ -294,7 +308,7 @@ This function completely restores a damaged organ to perfect condition. burn_dam = 0 // handle internal organs - for(var/obj/item/organ/current_organ in internal_organs) + for(var/obj/item/organ/internal/current_organ in internal_organs) current_organ.rejuvenate() @@ -462,8 +476,8 @@ Note that amputating the affected organ does in fact remove the infection from t if(germ_level >= INFECTION_LEVEL_TWO) //spread the infection to internal organs - var/obj/item/organ/target_organ = null //make internal organs become infected one at a time instead of all at once - for (var/obj/item/organ/I in internal_organs) + var/obj/item/organ/internal/target_organ = null //make internal organs become infected one at a time instead of all at once + for (var/obj/item/organ/internal/I in internal_organs) if (I.germ_level > 0 && I.germ_level < min(germ_level, INFECTION_LEVEL_TWO)) //once the organ reaches whatever we can give it, or level two, switch to a different one if (!target_organ || I.germ_level > target_organ.germ_level) //choose the organ with the highest germ_level target_organ = I @@ -471,7 +485,7 @@ Note that amputating the affected organ does in fact remove the infection from t if (!target_organ) //figure out which organs we can spread germs to and pick one at random var/list/candidate_organs = list() - for (var/obj/item/organ/I in internal_organs) + for (var/obj/item/organ/internal/I in internal_organs) if (I.germ_level < germ_level) candidate_organs |= I if (candidate_organs.len) @@ -657,7 +671,7 @@ Note that amputating the affected organ does in fact remove the infection from t "You hear the [gore_sound].") var/mob/living/carbon/human/victim = owner //Keep a reference for post-removed(). - removed(null, ignore_children) + remove(null, ignore_children) victim.traumatic_shock += 30 wounds.Cut() @@ -682,7 +696,6 @@ Note that amputating the affected organ does in fact remove the infection from t victim.UpdateDamageIcon() victim.regenerate_icons() dir = 2 - switch(disintegrate) if(DROPLIMB_EDGE) compile_icon() @@ -858,7 +871,7 @@ Note that amputating the affected organ does in fact remove the infection from t /obj/item/organ/external/proc/open_enough_for_surgery() return (encased ? (open == 3) : (open == 2)) -/obj/item/organ/external/removed(var/mob/living/user, var/ignore_children) +/obj/item/organ/external/remove(var/mob/living/user, var/ignore_children) if(!owner) return @@ -876,13 +889,13 @@ Note that amputating the affected organ does in fact remove the infection from t // Attached organs also fly off. if(!ignore_children) for(var/obj/item/organ/external/O in children) - O.removed() + O.remove() if(O) O.forceMove(src) // Grab all the internal giblets too. for(var/obj/item/organ/organ in internal_organs) - organ.removed() + organ.remove() organ.forceMove(src) release_restraints(victim) diff --git a/code/modules/organs/organ_icon.dm b/code/modules/surgery/organs/organ_icon.dm similarity index 94% rename from code/modules/organs/organ_icon.dm rename to code/modules/surgery/organs/organ_icon.dm index fb7c2b33433..2b591e6a302 100644 --- a/code/modules/organs/organ_icon.dm +++ b/code/modules/surgery/organs/organ_icon.dm @@ -33,10 +33,10 @@ var/global/list/limb_icon_cache = list() /obj/item/organ/external/head/sync_colour_to_human(var/mob/living/carbon/human/human) ..() - var/obj/item/organ/eyes/eyes = owner.internal_organs_by_name["eyes"] + var/obj/item/organ/internal/eyes/eyes = owner.get_int_organ(/obj/item/organ/internal/eyes)//owner.internal_organs_by_name["eyes"] if(eyes) eyes.update_colour() -/obj/item/organ/external/head/removed() +/obj/item/organ/external/head/remove() get_icon() ..() @@ -48,7 +48,7 @@ var/global/list/limb_icon_cache = list() return if(species.has_organ["eyes"]) - var/obj/item/organ/eyes/eyes = owner.internal_organs_by_name["eyes"] + var/obj/item/organ/internal/eyes/eyes = owner.get_int_organ(/obj/item/organ/internal/eyes)//owner.internal_organs_by_name["eyes"] if(species.eyes) var/icon/eyes_icon = new/icon('icons/mob/human_face.dmi', species.eyes) if(eyes) diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm new file mode 100644 index 00000000000..0e35aef343d --- /dev/null +++ b/code/modules/surgery/organs/organ_internal.dm @@ -0,0 +1,473 @@ +#define PROCESS_ACCURACY 10 + +/obj/item/organ/internal + origin_tech = "biotech=2" + force = 1 + w_class = 2 + throwforce = 0 + var/zone = "chest" + var/slot + vital = 0 + var/organ_action_name = null + +/obj/item/organ/internal/New(var/mob/living/carbon/holder) + if(istype(holder)) + insert(holder) + ..() + +/obj/item/organ/internal/proc/insert(mob/living/carbon/M, special = 0) + if(!iscarbon(M) || owner == M) + return + + var/obj/item/organ/internal/replaced = M.get_organ_slot(slot) + if(replaced) + replaced.remove(M, special = 1) + + owner = M + + M.internal_organs |= src + var/obj/item/organ/external/parent + if(istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + parent = H.get_organ(check_zone(parent_organ)) + if(!istype(parent)) + log_to_dd("[src] attempted to insert into a [parent], but [parent] wasn't an organ! Area: [get_area(M)]") + else + parent.internal_organs |= src + //M.internal_organs_by_name[src] |= src(H,1) + loc = null + if(organ_action_name) + action_button_name = organ_action_name + + +/obj/item/organ/internal/remove(mob/living/carbon/M, special = 0) + owner = null + if(M) + M.internal_organs -= src + if(vital && !special) + if(M.stat != DEAD)//safety check! + M.death() + + if(istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + var/obj/item/organ/external/parent = H.get_organ(check_zone(parent_organ)) + if(!istype(parent)) + log_to_dd("[src] attempted to remove from a [parent], but [parent] didn't exist! Area: [get_area(M)], Mob: [M]") + else + parent.internal_organs -= src + + if(organ_action_name) + action_button_name = null + + +/obj/item/organ/internal/replaced(var/mob/living/carbon/human/target,var/obj/item/organ/external/affected) + insert(target) + ..() + +/obj/item/organ/internal/proc/on_find(mob/living/finder) + return + +/obj/item/organ/internal/proc/on_life() + return + +/obj/item/organ/internal/Destroy() + if(owner) + remove(owner, 1) + return ..() + +/obj/item/organ/internal/proc/prepare_eat() + var/obj/item/weapon/reagent_containers/food/snacks/organ/S = new + S.name = name + S.desc = desc + S.icon = icon + S.icon_state = icon_state + S.origin_tech = origin_tech + S.w_class = w_class + + return S + +/obj/item/weapon/reagent_containers/food/snacks/organ + name = "appendix" + icon_state = "appendix" + icon = 'icons/obj/surgery.dmi' + +/obj/item/weapon/reagent_containers/food/snacks/organ/New() + ..() + + reagents.add_reagent("nutriment", 5) + + +/obj/item/organ/internal/Destroy() + if(owner) + remove(owner, 1) + return ..() + +/obj/item/organ/internal/attack(mob/living/carbon/M, mob/user) + if(M == user && ishuman(user)) + var/mob/living/carbon/human/H = user + var/obj/item/weapon/reagent_containers/food/snacks/S = prepare_eat() + if(S) + H.drop_item() + H.put_in_active_hand(S) + S.attack(H, H) + qdel(src) + else + ..() + +/**************************************************** + INTERNAL ORGANS DEFINES +****************************************************/ + + +// Brain is defined in brain_item.dm. +/obj/item/organ/internal/heart + name = "heart" + icon_state = "heart-on" + organ_tag = "heart" + parent_organ = "chest" + dead_icon = "heart-off" + vital = 1 + var/beating = 0 + +/obj/item/organ/internal/heart/update_icon() + if(beating) + icon_state = "heart-on" + else + icon_state = "heart-off" + +/obj/item/organ/internal/heart/insert(mob/living/carbon/M, special = 0) + ..() + beating = 1 + update_icon() + +/obj/item/organ/internal/heart/remove(mob/living/carbon/M, special = 0) + ..() + spawn(120) + beating = 0 + update_icon() + +/obj/item/organ/internal/heart/prepare_eat() + var/obj/S = ..() + S.icon_state = "heart-off" + return S + +/obj/item/organ/internal/lungs + name = "lungs" + icon_state = "lungs" + gender = PLURAL + organ_tag = "lungs" + parent_organ = "chest" + slot = "lungs" + vital = 1 + +//Insert something neat here. +///obj/item/organ/internal/lungs/remove(mob/living/carbon/M, special = 0) +// owner.losebreath += 10 + //insert oxy damage extream here. +// ..() + + +/obj/item/organ/internal/lungs/process() + ..() + + if(!owner) + return + if (germ_level > INFECTION_LEVEL_ONE) + if(prob(5)) + owner.emote("cough") //respitory tract infection + + if(is_bruised()) + if(prob(2)) + spawn owner.custom_emote(1, "coughs up blood!") + owner.drip(10) + if(prob(4)) + spawn owner.custom_emote(1, "gasps for air!") + owner.losebreath += 5 + +/obj/item/organ/internal/kidneys + name = "kidneys" + icon_state = "kidneys" + gender = PLURAL + organ_tag = "kidneys" + parent_organ = "groin" + slot = "kidneys" + +/obj/item/organ/internal/kidneys/process() + + ..() + + if(!owner) + return + + // Coffee is really bad for you with busted kidneys. + // This should probably be expanded in some way, but fucked if I know + // what else kidneys can process in our reagent list. + var/datum/reagent/coffee = locate(/datum/reagent/drink/coffee) in owner.reagents.reagent_list + if(coffee) + if(is_bruised()) + owner.adjustToxLoss(0.1 * PROCESS_ACCURACY) + else if(is_broken()) + owner.adjustToxLoss(0.3 * PROCESS_ACCURACY) + + +/obj/item/organ/internal/eyes + name = "eyeballs" + icon_state = "eyes" + gender = PLURAL + organ_tag = "eyes" + parent_organ = "head" + slot = "eyes" + var/list/eye_colour = list(0,0,0) + +/obj/item/organ/internal/eyes/proc/update_colour() + if(!owner) + return + eye_colour = list( + owner.r_eyes ? owner.r_eyes : 0, + owner.g_eyes ? owner.g_eyes : 0, + owner.b_eyes ? owner.b_eyes : 0 + ) + +/obj/item/organ/internal/eyes/insert(mob/living/carbon/M, special = 0) +// Apply our eye colour to the target. + if(istype(M) && eye_colour) + var/mob/living/carbon/human/eyes = M + eyes.r_eyes = eye_colour[1] + eyes.g_eyes = eye_colour[2] + eyes.b_eyes = eye_colour[3] + eyes.update_eyes() + ..() + +/obj/item/organ/internal/eyes/surgeryize() + if(!owner) + return + owner.disabilities &= ~NEARSIGHTED + owner.sdisabilities &= ~BLIND + owner.eye_blurry = 0 + owner.eye_blind = 0 + + +/obj/item/organ/internal/liver + name = "liver" + icon_state = "liver" + organ_tag = "liver" + parent_organ = "groin" + slot = "liver" + +/obj/item/organ/internal/liver/process() + + ..() + + if(!owner) + return + + if (germ_level > INFECTION_LEVEL_ONE) + if(prob(1)) + owner << " Your skin itches." + if (germ_level > INFECTION_LEVEL_TWO) + if(prob(1)) + spawn owner.vomit() + + if(owner.life_tick % PROCESS_ACCURACY == 0) + + //High toxins levels are dangerous + if(owner.getToxLoss() >= 60 && !owner.reagents.has_reagent("charcoal")) + //Healthy liver suffers on its own + if (src.damage < min_broken_damage) + src.damage += 0.2 * PROCESS_ACCURACY + //Damaged one shares the fun + else + var/obj/item/organ/internal/O = pick(owner.internal_organs) + if(O) + O.damage += 0.2 * PROCESS_ACCURACY + + //Detox can heal small amounts of damage + if (src.damage && src.damage < src.min_bruised_damage && owner.reagents.has_reagent("charcoal")) + src.damage -= 0.2 * PROCESS_ACCURACY + + if(src.damage < 0) + src.damage = 0 + + // Get the effectiveness of the liver. + var/filter_effect = 3 + if(is_bruised()) + filter_effect -= 1 + if(is_broken()) + filter_effect -= 2 + + // Damaged liver means some chemicals are very dangerous + if(src.damage >= src.min_bruised_damage) + for(var/datum/reagent/R in owner.reagents.reagent_list) + // Ethanol and all drinks are bad + if(istype(R, /datum/reagent/ethanol)) + owner.adjustToxLoss(0.1 * PROCESS_ACCURACY) + + // Can't cope with toxins at all + for(var/toxin in list("toxin", "plasma", "sacid", "facid", "cyanide", "amanitin", "carpotoxin")) + if(owner.reagents.has_reagent(toxin)) + owner.adjustToxLoss(0.3 * PROCESS_ACCURACY) + +/obj/item/organ/internal/appendix + name = "appendix" + icon_state = "appendix" + organ_tag = "appendix" + parent_organ = "groin" + slot = "appendix" + + +/* +/obj/item/organ/internal/appendix/removed() + + if(owner) + var/inflamed = 0 + for(var/datum/disease/appendicitis/appendicitis in owner.viruses) + inflamed = 1 + appendicitis.cure() + owner.resistances += appendicitis + if(inflamed) + icon_state = "appendixinflamed" + name = "inflamed appendix" + ..() +*/ +//shadowling tumor +/obj/item/organ/internal/shadowtumor + name = "black tumor" + desc = "A tiny black mass with red tendrils trailing from it. It seems to shrivel in the light." + icon_state = "blacktumor" + origin_tech = "biotech=4" + w_class = 1 + parent_organ = "head" + slot = "brain_tumor" + health = 3 + +/obj/item/organ/internal/shadowtumor/New() + ..() + processing_objects.Add(src) + +/obj/item/organ/internal/shadowtumor/Destroy() + processing_objects.Remove(src) + return ..() + +/obj/item/organ/internal/shadowtumor/process() + if(isturf(loc)) + var/turf/T = loc + var/light_count = T.get_lumcount()*10 + if(light_count > 4 && health > 0) //Die in the light + health-- + else if(light_count < 2 && health < 3) //Heal in the dark + health++ + if(health <= 0) + visible_message("[src] collapses in on itself!") + qdel(src) + +//debug and adminbus.... + +/obj/item/organ/internal/honktumor + name = "banana tumor" + desc = "A tiny yellow mass shaped like..a banana?" + icon_state = "honktumor" + origin_tech = "biotech=1" + w_class = 1 + parent_organ = "head" + slot = "brain_tumor" + health = 3 + var/organhonked = 0 + +/obj/item/organ/internal/honktumor/New() + ..() + processing_objects.Add(src) + +/obj/item/organ/internal/honktumor/insert(mob/living/carbon/M, special = 0) + ..() + M.mutations.Add(CLUMSY) + M.mutations.Add(COMICBLOCK) + M.dna.SetSEState(CLUMSYBLOCK,1,1) + M.dna.SetSEState(COMICBLOCK,1,1) + genemutcheck(M,CLUMSYBLOCK,null,MUTCHK_FORCED) + genemutcheck(M,COMICBLOCK,null,MUTCHK_FORCED) + organhonked = world.time + +/obj/item/organ/internal/honktumor/remove(mob/living/carbon/M, special = 0) + ..() + + M.mutations.Remove(CLUMSY) + M.mutations.Remove(COMICBLOCK) + M.dna.SetSEState(CLUMSYBLOCK,0) + M.dna.SetSEState(COMICBLOCK,0) + genemutcheck(M,CLUMSYBLOCK,null,MUTCHK_FORCED) + genemutcheck(M,COMICBLOCK,null,MUTCHK_FORCED) + +/obj/item/organ/internal/honktumor/Destroy() + processing_objects.Remove(src) + return ..() + +/obj/item/organ/internal/honktumor/process() + if(isturf(loc)) + visible_message("[src] honks in on itself!") + new /obj/item/weapon/bananapeel(get_turf(loc)) + qdel(src) + + +/obj/item/organ/internal/honktumor/on_life() + + if(!owner) + return + + if(organhonked < world.time) + organhonked = world.time+900 + owner << "HONK" + owner.sleeping = 0 + owner.stuttering = 20 + owner.ear_deaf = 30 + owner.Weaken(3) + owner << 'sound/items/AirHorn.ogg' + if(prob(30)) + owner.Stun(10) + owner.Paralyse(4) + else + owner.Jitter(500) + + if(istype(owner, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = owner + if(isobj(H.shoes)) + var/thingy = H.shoes + H.unEquip(H.shoes) + walk_away(thingy,H,15,2) + spawn(20) + if(thingy) + walk(thingy,0) + ..() + + +/obj/item/organ/internal/beard + name = "beard organ" + desc = "Let they who is worthy wear the beard of Thorbjorndottir." + icon_state = "liver" + origin_tech = "biotech=1" + w_class = 1 + parent_organ = "head" + slot = "hair_organ" + + +/obj/item/organ/internal/beard/on_life() + + if(!owner) + return + + if(istype(owner, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = owner + if(!(H.h_style == "Very Long Hair" || H.h_style == "Mowhawk")) + if(prob(10)) + H.h_style = "Mohawk" + else + H.h_style = "Very Long Hair" + H.r_hair = 216 + H.g_hair = 192 + H.b_hair = 120 + H.update_hair() + if(!(H.f_style == "Very Long Beard")) + H.f_style = "Very Long Beard" + H.r_facial = 216 + H.g_facial = 192 + H.b_facial = 120 + H.update_fhair() \ No newline at end of file diff --git a/code/modules/organs/organ_stump.dm b/code/modules/surgery/organs/organ_stump.dm similarity index 94% rename from code/modules/organs/organ_stump.dm rename to code/modules/surgery/organs/organ_stump.dm index c850575efde..b310a5862fc 100644 --- a/code/modules/organs/organ_stump.dm +++ b/code/modules/surgery/organs/organ_stump.dm @@ -19,7 +19,7 @@ /obj/item/organ/external/stump/is_stump() return 1 -/obj/item/organ/external/stump/removed() +/obj/item/organ/external/stump/remove() ..() qdel(src) diff --git a/code/modules/organs/pain.dm b/code/modules/surgery/organs/pain.dm similarity index 92% rename from code/modules/organs/pain.dm rename to code/modules/surgery/organs/pain.dm index ebfc3442d54..d1aac66a71c 100644 --- a/code/modules/organs/pain.dm +++ b/code/modules/surgery/organs/pain.dm @@ -118,12 +118,12 @@ mob/living/carbon/human/proc/handle_pain() // Damage to internal organs hurts a lot. - for(var/obj/item/organ/I in internal_organs) - if(istype(I, /obj/item/organ/brain)) //the brain has no pain receptors, and brain damage is meant to be a stealthy damage type. + for(var/obj/item/organ/internal/I in internal_organs) + if(istype(I, /obj/item/organ/internal/brain)) //the brain has no pain receptors, and brain damage is meant to be a stealthy damage type. continue if(I.damage > 2) if(prob(2)) var/obj/item/organ/external/parent = get_organ(I.parent_organ) - src.custom_pain("You feel a sharp pain in your [parent.name]", 1) + src.custom_pain("You feel a sharp pain in your [parent.limb_name]", 1) var/toxDamageMessage = null var/toxMessageProb = 1 diff --git a/code/modules/organs/robolimbs.dm b/code/modules/surgery/organs/robolimbs.dm similarity index 100% rename from code/modules/organs/robolimbs.dm rename to code/modules/surgery/organs/robolimbs.dm diff --git a/code/modules/organs/skeleton.dm b/code/modules/surgery/organs/skeleton.dm similarity index 100% rename from code/modules/organs/skeleton.dm rename to code/modules/surgery/organs/skeleton.dm diff --git a/code/modules/organs/subtypes/diona.dm b/code/modules/surgery/organs/subtypes/diona.dm similarity index 78% rename from code/modules/organs/subtypes/diona.dm rename to code/modules/surgery/organs/subtypes/diona.dm index e41c8ce3c62..8b9b2447b33 100644 --- a/code/modules/organs/subtypes/diona.dm +++ b/code/modules/surgery/organs/subtypes/diona.dm @@ -131,7 +131,7 @@ parent_organ = "chest" var/can_intake_reagents = 1 -/obj/item/organ/external/diona/head/removed() +/obj/item/organ/external/diona/head/remove() if(owner) owner.unEquip(owner.head) owner.unEquip(owner.l_ear) @@ -149,35 +149,62 @@ /obj/item/organ/diona/process() return -/obj/item/organ/diona/strata +/obj/item/organ/internal/heart/diona name = "neural strata" - parent_organ = "chest" - -/obj/item/organ/diona/bladder - name = "gas bladder" - parent_organ = "head" - -/obj/item/organ/diona/polyp - name = "polyp segment" - parent_organ = "groin" - -/obj/item/organ/diona/ligament - name = "anchoring ligament" - parent_organ = "groin" - -/obj/item/organ/diona/node - name = "receptor node" - parent_organ = "head" - -/obj/item/organ/diona/nutrients - name = "nutrient vessel" - parent_organ = "chest" - -/obj/item/organ/diona - name = "diona nymph" icon = 'icons/obj/objects.dmi' icon_state = "nymph" - organ_tag = "special" // Turns into a nymph instantly, no transplanting possible. + organ_tag = "heart" // Turns into a nymph instantly, no transplanting possible. + origin_tech = "biotech=3" + parent_organ = "chest" + slot = "heart" + +/obj/item/organ/internal/brain/diona + name = "gas bladder" + parent_organ = "head" + icon = 'icons/obj/objects.dmi' + icon_state = "nymph" + organ_tag = "brain" // Turns into a nymph instantly, no transplanting possible. + origin_tech = "biotech=3" + slot = "brain" + +/obj/item/organ/internal/kidneys/diona + name = "polyp segment" + icon = 'icons/obj/objects.dmi' + icon_state = "nymph" + organ_tag = "kidneys" // Turns into a nymph instantly, no transplanting possible. + origin_tech = "biotech=3" + parent_organ = "groin" + slot = "kidneys" + +/obj/item/organ/internal/appendix/diona + name = "anchoring ligament" + icon = 'icons/obj/objects.dmi' + icon_state = "nymph" + organ_tag = "appendix" // Turns into a nymph instantly, no transplanting possible. + origin_tech = "biotech=3" + parent_organ = "groin" + slot = "appendix" + +/obj/item/organ/internal/eyes/diona + name = "receptor node" + organ_tag = "eyes" + icon = 'icons/mob/alien.dmi' + icon_state = "claw" + origin_tech = "biotech=3" + parent_organ = "head" + slot = "eyes" + +//TODO:Make absorb rads on insert + +/obj/item/organ/internal/liver/diona + name = "nutrient vessel" + parent_organ = "chest" + organ_tag = "liver" + icon = 'icons/mob/alien.dmi' + icon_state = "claw" + slot = "liver" + +//TODO:Make absorb light on insert. /*/obj/item/organ/diona/removed(var/mob/living/user) var/mob/living/carbon/human/H = owner @@ -186,23 +213,3 @@ H.death() if(prob(50) && spawn_diona_nymph_from_organ(src)) qdel(src) */ - -// These are different to the standard diona organs as they have a purpose in other -// species (absorbing radiation and light respectively) -/obj/item/organ/diona/nutrients - name = "nutrient vessel" - organ_tag = "nutrient vessel" - icon = 'icons/mob/alien.dmi' - icon_state = "claw" - -/obj/item/organ/diona/nutrients/removed() - return - -/obj/item/organ/diona/node - name = "receptor node" - organ_tag = "receptor node" - icon = 'icons/mob/alien.dmi' - icon_state = "claw" - -/obj/item/organ/diona/node/removed() - return diff --git a/code/modules/organs/subtypes/machine.dm b/code/modules/surgery/organs/subtypes/machine.dm similarity index 64% rename from code/modules/organs/subtypes/machine.dm rename to code/modules/surgery/organs/subtypes/machine.dm index 88f84b385b3..6ba6f5055db 100644 --- a/code/modules/organs/subtypes/machine.dm +++ b/code/modules/surgery/organs/subtypes/machine.dm @@ -5,6 +5,7 @@ max_damage = 50 //made same as arm, since it is not vital min_broken_damage = 30 encased = null + status = ORGAN_ROBOT /obj/item/organ/external/head/ipc/New() robotize("Morpheus Cyberkinetics") @@ -12,89 +13,134 @@ /obj/item/organ/external/chest/ipc encased = null + status = ORGAN_ROBOT /obj/item/organ/external/chest/ipc/New() robotize("Morpheus Cyberkinetics") ..() +/obj/item/organ/external/groin/ipc + encased = null + status = ORGAN_ROBOT + /obj/item/organ/external/groin/ipc/New() robotize("Morpheus Cyberkinetics") ..() +/obj/item/organ/external/arm/ipc + encased = null + status = ORGAN_ROBOT + /obj/item/organ/external/arm/ipc/New() robotize("Morpheus Cyberkinetics") ..() +/obj/item/organ/external/arm/right/ipc + encased = null + status = ORGAN_ROBOT + /obj/item/organ/external/arm/right/ipc/New() robotize("Morpheus Cyberkinetics") ..() +/obj/item/organ/external/leg/ipc + encased = null + status = ORGAN_ROBOT /obj/item/organ/external/leg/ipc/New() robotize("Morpheus Cyberkinetics") ..() +/obj/item/organ/external/leg/right/ipc + encased = null + status = ORGAN_ROBOT + + /obj/item/organ/external/leg/right/ipc/New() robotize("Morpheus Cyberkinetics") ..() +/obj/item/organ/external/foot/ipc + encased = null + status = ORGAN_ROBOT + + /obj/item/organ/external/foot/ipc/New() robotize("Morpheus Cyberkinetics") ..() +/obj/item/organ/external/foot/right/ipc + encased = null + status = ORGAN_ROBOT + + /obj/item/organ/external/foot/right/ipc/New() robotize("Morpheus Cyberkinetics") ..() +/obj/item/organ/external/hand/ipc + encased = null + status = ORGAN_ROBOT + /obj/item/organ/external/hand/ipc/New() robotize("Morpheus Cyberkinetics") ..() +/obj/item/organ/external/hand/right/ipc + encased = null + status = ORGAN_ROBOT + /obj/item/organ/external/hand/right/ipc/New() robotize("Morpheus Cyberkinetics") ..() -/obj/item/organ/cell +/obj/item/organ/internal/cell name = "microbattery" desc = "A small, powerful cell for use in fully prosthetic bodies." icon = 'icons/obj/power.dmi' icon_state = "scell" - organ_tag = "cell" + organ_tag = "heart" parent_organ = "chest" + slot = "heart" vital = 1 + status = ORGAN_ROBOT -/obj/item/organ/cell/New() +/obj/item/organ/internal/cell/New() robotize() ..() -/obj/item/organ/cell/replaced() +/obj/item/organ/internal/cell/insert() ..() // This is very ghetto way of rebooting an IPC. TODO better way. if(owner && owner.stat == DEAD) owner.stat = CONSCIOUS owner.visible_message("\The [owner] twitches visibly!") -/obj/item/organ/optical_sensor +/obj/item/organ/internal/optical_sensor name = "optical sensor" - organ_tag = "optics" + organ_tag = "eyes" parent_organ = "head" icon = 'icons/obj/robot_component.dmi' icon_state = "camera" - dead_icon = "camera_broken" + slot = "eyes" + status = ORGAN_ROBOT +// dead_icon = "camera_broken" -/obj/item/organ/optical_sensor/New() +/obj/item/organ/internal/optical_sensor/New() robotize() ..() // Used for an MMI or posibrain being installed into a human. -/obj/item/organ/mmi_holder +/obj/item/organ/internal/brain/mmi_holder name = "brain" organ_tag = "brain" parent_organ = "chest" vital = 1 max_damage = 200 + slot = "brain" + status = ORGAN_ROBOT var/obj/item/device/mmi/stored_mmi -/obj/item/organ/mmi_holder/proc/update_from_mmi() +/obj/item/organ/internal/brain/mmi_holder/proc/update_from_mmi() if(!stored_mmi) return name = stored_mmi.name @@ -102,11 +148,12 @@ icon = stored_mmi.icon icon_state = stored_mmi.icon_state -/obj/item/organ/mmi_holder/removed(var/mob/living/user) - if(stored_mmi) - stored_mmi.loc = get_turf(src) - if(owner.mind) - owner.mind.transfer_to(stored_mmi.brainmob) +/obj/item/organ/internal/brain/mmi_holder/remove(var/mob/living/user,special = 0) + if(!special) + if(stored_mmi) + stored_mmi.forceMove(get_turf(owner)) + if(owner.mind) + owner.mind.transfer_to(stored_mmi.brainmob) ..() var/mob/living/holder_mob = loc @@ -114,7 +161,7 @@ holder_mob.unEquip(src) qdel(src) -/obj/item/organ/mmi_holder/New() +/obj/item/organ/internal/brain/mmi_holder/New() ..() // This is very ghetto way of rebooting an IPC. TODO better way. spawn(1) @@ -122,7 +169,7 @@ owner.stat = CONSCIOUS owner.visible_message("\The [owner] twitches visibly!") -/obj/item/organ/mmi_holder/posibrain/New() +/obj/item/organ/internal/brain/mmi_holder/posibrain/New() robotize() stored_mmi = new /obj/item/device/mmi/posibrain/ipc(src) ..() diff --git a/code/modules/organs/subtypes/misc.dm b/code/modules/surgery/organs/subtypes/misc.dm similarity index 80% rename from code/modules/organs/subtypes/misc.dm rename to code/modules/surgery/organs/subtypes/misc.dm index a2febc6d1e4..240a36149f8 100644 --- a/code/modules/organs/subtypes/misc.dm +++ b/code/modules/surgery/organs/subtypes/misc.dm @@ -1,10 +1,14 @@ //CORTICAL BORER ORGANS. -/obj/item/organ/borer +/obj/item/organ/internal/borer name = "cortical borer" + icon = 'icons/obj/objects.dmi' + icon_state = "borer" parent_organ = "head" + organ_tag = "brain" + slot = "borer" vital = 1 -/obj/item/organ/borer/process() +/obj/item/organ/internal/borer/process() // Borer husks regenerate health, feel no pain, and are resistant to stuns and brainloss. for(var/chem in list("saline", "sailcylic", "meth", "mannitol")) @@ -26,14 +30,7 @@ goo.basecolor = "#412464" goo.update_icon() -/obj/item/organ/borer - name = "cortical borer" - icon = 'icons/obj/objects.dmi' - icon_state = "borer" - organ_tag = "brain" - desc = "A disgusting space slug." - -/obj/item/organ/borer/removed(var/mob/living/user) +/obj/item/organ/internal/borer/remove(var/mob/living/user) ..() @@ -46,22 +43,23 @@ qdel(src) //VOX ORGANS. -/obj/item/organ/stack +/obj/item/organ/internal/stack name = "cortical stack" icon_state = "brain-prosthetic" parent_organ = "head" organ_tag = "stack" + slot = "vox_stack" robotic = 2 vital = 1 var/backup_time = 0 var/datum/mind/backup -/obj/item/organ/stack/process() +/obj/item/organ/internal/stack/process() if(owner && owner.stat != 2 && !is_broken()) backup_time = world.time if(owner.mind) backup = owner.mind -/obj/item/organ/stack/vox +/obj/item/organ/internal/stack/vox name = "vox cortical stack" -/obj/item/organ/stack/vox/stack +/obj/item/organ/internal/stack/vox/stack diff --git a/code/modules/organs/subtypes/nucleation.dm b/code/modules/surgery/organs/subtypes/nucleation.dm similarity index 62% rename from code/modules/organs/subtypes/nucleation.dm rename to code/modules/surgery/organs/subtypes/nucleation.dm index 40d7745d86e..f174cf9d75d 100644 --- a/code/modules/organs/subtypes/nucleation.dm +++ b/code/modules/surgery/organs/subtypes/nucleation.dm @@ -1,33 +1,37 @@ //NUCLEATION ORGAN -/obj/item/organ/nucleation +/obj/item/organ/internal/nucleation name = "nucleation organ" icon = 'icons/obj/surgery.dmi' desc = "A crystalized human organ. /red It has a strangely iridescent glow." -/obj/item/organ/nucleation/resonant_crystal +/obj/item/organ/internal/nucleation/resonant_crystal name = "resonant crystal" icon_state = "resonant-crystal" organ_tag = "resonant crystal" parent_organ = "head" + slot = "res_crystal" -/obj/item/organ/nucleation/strange_crystal +/obj/item/organ/internal/nucleation/strange_crystal name = "strange crystal" icon_state = "strange-crystal" organ_tag = "strange crystal" parent_organ = "chest" + slot = "heart" -/obj/item/organ/eyes/luminescent_crystal + +/obj/item/organ/internal/eyes/luminescent_crystal name = "luminescent eyes" icon_state = "crystal-eyes" organ_tag = "luminescent eyes" light_color = "#1C1C00" parent_organ = "head" + slot = "eyes" - New() - set_light(2) +/obj/item/organ/internal/eyes/luminescent_crystal/New() + set_light(2) -/obj/item/organ/brain/crystal +/obj/item/organ/internal/brain/crystal name = "crystalized brain" icon_state = "crystal-brain" organ_tag = "crystalized brain" - \ No newline at end of file + slot = "brain" diff --git a/code/modules/organs/subtypes/standard.dm b/code/modules/surgery/organs/subtypes/standard.dm similarity index 83% rename from code/modules/organs/subtypes/standard.dm rename to code/modules/surgery/organs/subtypes/standard.dm index d464a9bdfdf..da8681e1b4e 100644 --- a/code/modules/organs/subtypes/standard.dm +++ b/code/modules/surgery/organs/subtypes/standard.dm @@ -83,8 +83,8 @@ amputation_point = "left ankle" can_stand = 1 -/obj/item/organ/external/foot/removed() - if(owner) owner.unEquip(owner.shoes) +/obj/item/organ/external/foot/remove() + if(owner.shoes) owner.unEquip(owner.shoes) ..() /obj/item/organ/external/foot/right @@ -108,8 +108,9 @@ amputation_point = "left wrist" can_grasp = 1 -/obj/item/organ/external/hand/removed() - owner.unEquip(owner.gloves) +/obj/item/organ/external/hand/remove() + if(owner.gloves) + owner.unEquip(owner.gloves) ..() /obj/item/organ/external/hand/right @@ -135,19 +136,30 @@ encased = "skull" var/can_intake_reagents = 1 -/obj/item/organ/external/head/removed() +/obj/item/organ/external/head/remove() if(owner) if(!istype(dna)) dna = owner.dna.Clone() name = "[dna.real_name]'s head" - owner.unEquip(owner.glasses) - owner.unEquip(owner.head) - owner.unEquip(owner.l_ear) - owner.unEquip(owner.r_ear) - owner.unEquip(owner.wear_mask) + if(owner.glasses) + owner.unEquip(owner.glasses) + if(owner.head) + owner.unEquip(owner.head) + if(owner.l_ear) + owner.unEquip(owner.l_ear) + if(owner.r_ear) + owner.unEquip(owner.r_ear) + if(owner.wear_mask) + owner.unEquip(owner.wear_mask) spawn(1) - owner.update_hair() - owner.update_fhair() + if(owner)//runtimer no runtiming + owner.update_hair() + owner.update_fhair() + ..() + +/obj/item/organ/external/head/replaced() + name = limb_name + ..() /obj/item/organ/external/head/take_damage(brute, burn, sharp, edge, used_weapon = null, list/forbidden_limbs = list()) diff --git a/code/modules/organs/subtypes/unbreakable.dm b/code/modules/surgery/organs/subtypes/unbreakable.dm similarity index 100% rename from code/modules/organs/subtypes/unbreakable.dm rename to code/modules/surgery/organs/subtypes/unbreakable.dm diff --git a/code/modules/organs/subtypes/wryn.dm b/code/modules/surgery/organs/subtypes/wryn.dm similarity index 64% rename from code/modules/organs/subtypes/wryn.dm rename to code/modules/surgery/organs/subtypes/wryn.dm index 5d0c687f9f2..14a5d46dd8f 100644 --- a/code/modules/organs/subtypes/wryn.dm +++ b/code/modules/surgery/organs/subtypes/wryn.dm @@ -1,11 +1,8 @@ //WRYN ORGAN -/obj/item/organ/wryn/hivenode - name = "antennae" - parent_organ = "head" - -/obj/item/organ/wryn/hivenode +/obj/item/organ/internal/wryn/hivenode name = "antennae" organ_tag = "antennae" icon = 'icons/mob/human_races/r_wryn.dmi' icon_state = "antennae" - \ No newline at end of file + parent_organ = "head" + slot = "hivenode" \ No newline at end of file diff --git a/code/modules/surgery/organs/subtypes/xenos.dm b/code/modules/surgery/organs/subtypes/xenos.dm new file mode 100644 index 00000000000..b94d58d91bf --- /dev/null +++ b/code/modules/surgery/organs/subtypes/xenos.dm @@ -0,0 +1,162 @@ +/obj/item/organ/internal/xenos + origin_tech = "biotech=5" + icon_state = "xgibmid2" + var/list/alien_powers = list() + tough = 1 + sterile = 1 + +///obj/item/organ/internal/xenos/New() +// for(var/A in alien_powers) +// if(ispath(A)) +// alien_powers -= A +// alien_powers += new A(src) +// ..() + +///can be changed if xenos get an update.. +/obj/item/organ/internal/xenos/insert(mob/living/carbon/M, special = 0) + ..() + for(var/P in alien_powers) + M.verbs |= P + //M.verbs |= alien_powers.Copy() + +/obj/item/organ/internal/xenos/remove(mob/living/carbon/M, special = 0) + for(var/P in alien_powers) + M.verbs -= P + //M.verbs -= alien_powers.Copy() + + ..() + +/obj/item/organ/internal/xenos/prepare_eat() + var/obj/S = ..() + S.reagents.add_reagent("sacid", 10) + return S + +//XENOMORPH ORGANS + +/obj/item/organ/internal/xenos/plasmavessel + name = "xeno plasma vessel" + icon_state = "plasma" + origin_tech = "biotech=5;plasmatech=2" + w_class = 3 + parent_organ = "chest" + slot = "plasmavessel" + alien_powers = list(/mob/living/carbon/alien/humanoid/verb/plant, /mob/living/carbon/alien/humanoid/verb/transfer_plasma) + + + var/stored_plasma = 0 + var/max_plasma = 500 + var/heal_rate = 5 + var/plasma_rate = 10 + +/obj/item/organ/internal/xenos/plasmavessel/prepare_eat() + var/obj/S = ..() + S.reagents.add_reagent("plasma", stored_plasma/10) + return S + +/obj/item/organ/internal/xenos/plasmavessel/queen + name = "bloated xeno plasma vessel" + icon_state = "plasma_large" + origin_tech = "biotech=6;plasma=3" + stored_plasma = 200 + max_plasma = 500 + plasma_rate = 25 + +/obj/item/organ/internal/xenos/plasmavessel/drone + name = "large xeno plasma vessel" + icon_state = "plasma_large" + stored_plasma = 200 + max_plasma = 500 + +/obj/item/organ/internal/xenos/plasmavessel/sentinel + stored_plasma = 100 + max_plasma = 250 + +/obj/item/organ/internal/xenos/plasmavessel/hunter + name = "small xeno plasma vessel" + icon_state = "plasma_tiny" + stored_plasma = 100 + max_plasma = 150 + alien_powers = list(/mob/living/carbon/alien/humanoid/verb/plant) + +/obj/item/organ/internal/xenos/plasmavessel/larva + name = "tiny xeno plasma vessel" + icon_state = "plasma_tiny" + max_plasma = 100 + + +/obj/item/organ/internal/xenos/plasmavessel/on_life() + //If there are alien weeds on the ground then heal if needed or give some plasma + if(locate(/obj/structure/alien/weeds) in owner.loc) + if(owner.health >= owner.maxHealth) + owner.adjustPlasma(plasma_rate) + else + var/heal_amt = heal_rate + if(!isalien(owner)) + heal_amt *= 0.2 + owner.adjustPlasma(plasma_rate*0.5) + owner.adjustBruteLoss(-heal_amt) + owner.adjustFireLoss(-heal_amt) + owner.adjustOxyLoss(-heal_amt) + owner.adjustCloneLoss(-heal_amt) + +/obj/item/organ/internal/xenos/plasmavessel/insert(mob/living/carbon/M, special = 0) + ..() + if(isalien(M)) + var/mob/living/carbon/alien/A = M + A.updatePlasmaDisplay() + +/obj/item/organ/internal/alien/plasmavessel/remove(mob/living/carbon/M, special = 0) + ..() + if(isalien(M)) + var/mob/living/carbon/alien/A = M + A.updatePlasmaDisplay() + + +/obj/item/organ/internal/xenos/acidgland + name = "xeno acid gland" + parent_organ = "head" + slot = "acid" + origin_tech = "biotech=5;materials=2;combat=2" + alien_powers = list(/mob/living/carbon/alien/humanoid/proc/corrosive_acid) + + +/obj/item/organ/internal/xenos/hivenode + name = "xeno hive node" + parent_organ = "head" + slot = "hivenode" + origin_tech = "biotech=5;magnets=4;bluespace=3" + w_class = 1 + alien_powers = list(/mob/living/carbon/alien/humanoid/verb/whisp) + +/obj/item/organ/internal/xenos/hivenode/insert(mob/living/carbon/M, special = 0) + ..() + M.faction |= "alien" + +/obj/item/organ/internal/xenos/hivenode/remove(mob/living/carbon/M, special = 0) + M.faction -= "alien" + ..() + +/obj/item/organ/internal/xenos/neurotoxin + name = "xeno neurotoxin gland" + icon_state = "neurotox" + parent_organ = "head" + slot = "neurotox" + origin_tech = "biotech=5;combat=5" + alien_powers = list(/mob/living/carbon/alien/humanoid/proc/neurotoxin) + +/obj/item/organ/internal/xenos/resinspinner + name = "xeno resin organ"//...there tiger.... + parent_organ = "mouth" + icon_state = "liver-x" + slot = "hivenode" + origin_tech = "biotech=5;materials=4" + alien_powers = list(/mob/living/carbon/alien/humanoid/proc/resin) + +/obj/item/organ/internal/xenos/eggsac + name = "xeno egg sac" + icon_state = "eggsac" + parent_organ = "groin" + slot = "eggsac" + w_class = 4 + origin_tech = "biotech=8" + alien_powers = list(/mob/living/carbon/alien/humanoid/queen/verb/lay_egg) \ No newline at end of file diff --git a/code/modules/organs/wound.dm b/code/modules/surgery/organs/wound.dm similarity index 100% rename from code/modules/organs/wound.dm rename to code/modules/surgery/organs/wound.dm diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm index ca8cf5eefe2..63f49b2834a 100644 --- a/code/modules/surgery/organs_internal.dm +++ b/code/modules/surgery/organs_internal.dm @@ -1,10 +1,53 @@ +/datum/surgery/organ_manipulation + name = "organ manipulation" + steps = list(/datum/surgery_step/generic/cut_open,/datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/open_encased/saw, + /datum/surgery_step/open_encased/retract, /datum/surgery_step/internal/manipulate_organs, /datum/surgery_step/glue_bone, /datum/surgery_step/set_bone,/datum/surgery_step/finish_bone,/datum/surgery_step/generic/cauterize) + possible_locs = list("chest","head") + requires_organic_bodypart = 1 + +/datum/surgery/organ_manipulation/soft + possible_locs = list("groin", "eyes", "mouth") + steps = list(/datum/surgery_step/generic/cut_open,/datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/internal/manipulate_organs,/datum/surgery_step/generic/cauterize) + requires_organic_bodypart = 1 + +/datum/surgery/organ_manipulation_boneless + name = "organ manipulation" + possible_locs = list("chest","head","groin", "eyes", "mouth") + steps = list(/datum/surgery_step/generic/cut_open,/datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/internal/manipulate_organs,/datum/surgery_step/generic/cauterize) + requires_organic_bodypart = 1 + allowed_mob = list(/mob/living/carbon/human/diona) + +/datum/surgery/organ_manipulation/alien + name = "alien organ manipulation" + possible_locs = list("chest", "head", "groin", "eyes", "mouth") + allowed_mob = list(/mob/living/carbon/alien/humanoid) + steps = list(/datum/surgery_step/saw_carapace,/datum/surgery_step/cut_carapace, /datum/surgery_step/retract_carapace,/datum/surgery_step/internal/manipulate_organs) + + +/datum/surgery/organ_manipulation/can_start(mob/user, mob/living/carbon/target) + if(istype(target,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = target + var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) + if(affected && (affected.status & ORGAN_ROBOT)) + return 0 + if((target.get_species() == "Machine")) + return 0 + if((target.get_species() == "Diona")) + return 0 + return 1 + +/datum/surgery/organ_manipulation/alien/can_start(mob/user, mob/living/carbon/target) + if(istype(target,/mob/living/carbon/alien/humanoid)) + return 1 + else return 0 + // Internal surgeries. /datum/surgery_step/internal priority = 2 can_infect = 1 blood_level = 1 -/datum/surgery_step/internal/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/internal/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) if (!hasorgans(target)) return 0 @@ -12,452 +55,366 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) return affected && affected.open_enough_for_surgery() -////////////////////////////////////////////////////////////////// -// Dethrall Shadowling // -////////////////////////////////////////////////////////////////// -/datum/surgery_step/internal/dethrall - allowed_tools = list( - /obj/item/weapon/hemostat = 100, \ - /obj/item/weapon/wirecutters = 75, \ - /obj/item/weapon/kitchen/utensil/fork = 20 - ) - - min_duration = 120 - max_duration = 120 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (!hasorgans(target)) - return - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return ..() && affected && is_thrall(target) && affected.open_enough_for_surgery() && target_zone == target.named_organ_parent("brain") - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/braincase = target.named_organ_parent("brain") - user.visible_message("[user] begins looking around in [target]'s [braincase].", "You begin looking for foreign influences on [target]'s brain...") - user << "You locate a small, pulsing black tumor on the side of [target]'s brain and begin to remove it." - target << "A small part of your [braincase] pulses with agony as the light impacts it." - user.visible_message("[user] begins removing something from [target]'s [braincase].", \ - "You begin carefully extracting the tumor...") - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/braincase = target.named_organ_parent("brain") - user.visible_message("[user] carefully extracts the tumor from [target]'s brain!", \ - "You extract the black tumor from [target]'s [braincase]. It quickly shrivels and burns away.") - ticker.mode.remove_thrall(target.mind,0) - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/braincase = target.named_organ_parent("brain") - if(prob(50)) - user.visible_message("[user] slips and rips the tumor out from [target]'s [braincase]!", \ - "You fumble and tear out [target]'s tumor!") - target.adjustBrainLoss(110) // This is so you can't just defib'n go - ticker.mode.remove_thrall(target.mind,1) - else - user.visible_message("[user]'s hand slips and fumbles! Luckily, they didn't damage anything!") - -////////////////////////////////////////////////////////////////// -// ALIEN EMBRYO SURGERY // -////////////////////////////////////////////////////////////////// -/datum/surgery_step/internal/remove_embryo - allowed_tools = list( - /obj/item/weapon/hemostat = 100, \ - /obj/item/weapon/wirecutters = 75, \ - /obj/item/weapon/kitchen/utensil/fork = 20 - ) - blood_level = 2 - - min_duration = 80 - max_duration = 100 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/embryo = 0 - for(var/obj/item/alien_embryo/A in target) - embryo = 1 - break - - if (!hasorgans(target)) - return - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return ..() && affected && embryo && affected.open_enough_for_surgery() && target_zone == "chest" - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/msg = "[user] starts to pull something out from [target]'s ribcage with \the [tool]." - var/self_msg = "You start to pull something out from [target]'s ribcage with \the [tool]." - user.visible_message(msg, self_msg) - target.custom_pain("Something hurts horribly in your chest!",1) - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\red [user] rips the larva out of [target]'s ribcage!", - "You rip the larva out of [target]'s ribcage!") - - for(var/obj/item/alien_embryo/A in target) - A.loc = A.loc.loc -////////////////////////////////////////////////////////////////// -// CHEST INTERNAL ORGAN SURGERY // -////////////////////////////////////////////////////////////////// -/datum/surgery_step/internal/fix_organ - allowed_tools = list( - /obj/item/stack/medical/advanced/bruise_pack= 100, \ - /obj/item/stack/medical/bruise_pack = 20 - ) - - min_duration = 70 +/datum/surgery_step/internal/manipulate_organs + name = "manipulate organs" + allowed_tools = list(/obj/item/organ/internal = 100, /obj/item/weapon/reagent_containers/food/snacks/organ = 0) + var/implements_extract = list(/obj/item/weapon/hemostat = 100, /obj/item/weapon/kitchen/utensil/fork = 55) + var/implements_mend = list(/obj/item/stack/medical/advanced/bruise_pack = 100,/obj/item/stack/nanopaste = 100,/obj/item/stack/medical/bruise_pack = 20) + //Finish is just so you can close up after you do other things. + var/implements_finsh = list(/obj/item/weapon/scalpel/manager = 120,/obj/item/weapon/retractor = 100 ,/obj/item/weapon/crowbar = 75) + var/current_type + var/obj/item/organ/internal/I = null + var/obj/item/organ/external/affected = null max_duration = 90 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/internal/manipulate_organs/New() + ..() + allowed_tools = allowed_tools + implements_extract + implements_mend + implements_finsh - if (!hasorgans(target)) - return - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!affected) - return - var/is_organ_damaged = 0 - for(var/obj/item/organ/I in affected.internal_organs) - if(I.damage > 0 && I.robotic < 2) - is_organ_damaged = 1 - break - return ..() && is_organ_damaged - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + +/datum/surgery_step/internal/manipulate_organs/begin_step(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool,datum/surgery/surgery) + + I = null + var/mob/living/carbon/human/H + if(istype(target,/mob/living/carbon/human)) + H = target + affected = H.get_organ(target_zone) + if(is_int_organ(tool)) + current_type = "insert" + I = tool + if(target_zone != I.parent_organ || target.get_organ_slot(I.slot)) + user << "There is no room for [I] in [target]'s [parse_zone(target_zone)]!" + return -1 + + if(I.damage > (I.max_damage * 0.75)) + user << " \The [I] is in no state to be transplanted." + return -1 + + if(target.get_int_organ(I)) + user << " \The [target] already has [I]." + return -1 + if(affected) + user.visible_message("[user] starts transplanting \the [tool] into [target]'s [affected.name].", \ + "You start transplanting \the [tool] into [target]'s [affected.name].") + H.custom_pain("Someone's rooting around in your [affected.name]!",1) + else + user.visible_message("[user] starts transplanting \the [tool] into [target]'s [parse_zone(target_zone)].", \ + "You start transplanting \the [tool] into [target]'s [parse_zone(target_zone)].") + + else if(implement_type in implements_finsh) + //same as surgery step /datum/surgery_step/open_encased/close/ + current_type = "finish" + + if(affected && affected.encased) + var/msg = "[user] starts bending [target]'s [affected.encased] back into place with \the [tool]." + var/self_msg = "You start bending [target]'s [affected.encased] back into place with \the [tool]." + user.visible_message(msg, self_msg) + else + var/msg = "[user] starts pulling [target]'s skin back into place with \the [tool]." + var/self_msg = "You start pulling [target]'s skin back into place with \the [tool]." + user.visible_message(msg, self_msg) + if(affected) + H.custom_pain("Something hurts horribly in your [affected.name]!",1) + else if(implement_type in implements_extract) + current_type = "extract" + var/list/organs = target.get_organs_zone(target_zone) + if(!organs.len) + user << "There are no removeable organs in [target]'s [parse_zone(target_zone)]!" + return -1 + else + for(var/obj/item/organ/internal/O in organs) + O.on_find(user) + organs -= O + organs[O.name] = O + + I = input("Remove which organ?", "Surgery", null, null) as null|anything in organs + if(I && user && target && user.Adjacent(target) && user.get_active_hand() == tool) + I = organs[I] + if(!I) return -1 + user.visible_message("[user] starts to separate [target]'s [I] with \the [tool].", \ + "You start to separate [target]'s [I] with \the [tool] for removal." ) + if(affected) + H.custom_pain("The pain in your [affected.name] is living hell!",1) + else + return -1 + + else if(implement_type in implements_mend) + //todo Change message, make it heal the organs... + current_type = "mend" var/tool_name = "\the [tool]" if (istype(tool, /obj/item/stack/medical/advanced/bruise_pack)) tool_name = "regenerative membrane" else if (istype(tool, /obj/item/stack/medical/bruise_pack)) tool_name = "the bandaid" + else if (istype(tool, /obj/item/stack/nanopaste)) + tool_name = "\the [tool]" //what else do you call nanopaste medically? - if (!hasorgans(target)) + if(!hasorgans(target)) + user << "They do not have organs to mend!" return - var/obj/item/organ/external/affected = target.get_organ(target_zone) - - for(var/obj/item/organ/I in affected.internal_organs) + for(var/obj/item/organ/internal/I in affected.internal_organs) if(I && I.damage > 0) - if(I.robotic < 2) - spread_germs_to_organ(I, user) + if(I.robotic < 2 && !istype (tool, /obj/item/stack/nanopaste)) + if(!(I.sterile)) + spread_germs_to_organ(I, user) + user.visible_message("[user] starts treating damage to [target]'s [I.name] with [tool_name].", \ + "You start treating damage to [target]'s [I.name] with [tool_name]." ) + else if(I.robotic > 2 && istype(tool, /obj/item/stack/nanopaste)) user.visible_message("[user] starts treating damage to [target]'s [I.name] with [tool_name].", \ "You start treating damage to [target]'s [I.name] with [tool_name]." ) - target.custom_pain("The pain in your [affected.name] is living hell!",1) - ..() + user << "No organs appear to be damaged." + H.custom_pain("The pain in your [affected.name] is living hell!",1) - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + else if(istype(tool, /obj/item/weapon/reagent_containers/food/snacks/organ)) + user << "[tool] was biten by someone! It's too damaged to use!" + return -1 + ..() + +/datum/surgery_step/internal/manipulate_organs/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + if(current_type == "mend") var/tool_name = "\the [tool]" if (istype(tool, /obj/item/stack/medical/advanced/bruise_pack)) tool_name = "regenerative membrane" if (istype(tool, /obj/item/stack/medical/bruise_pack)) tool_name = "the bandaid" + if (istype(tool, /obj/item/stack/nanopaste)) + tool_name = "\the [tool]" //what else do you call nanopaste medically? if (!hasorgans(target)) return - var/obj/item/organ/external/affected = target.get_organ(target_zone) - - for(var/obj/item/organ/I in affected.internal_organs) + for(var/obj/item/organ/internal/I in affected.internal_organs) if(I) I.surgeryize() if(I && I.damage > 0) - if(I.robotic < 2) - user.visible_message("\blue [user] treats damage to [target]'s [I.name] with [tool_name].", \ - "\blue You treat damage to [target]'s [I.name] with [tool_name]." ) + if(I.robotic < 2 && !istype (tool, /obj/item/stack/nanopaste)) + user.visible_message(" [user] treats damage to [target]'s [I.name] with [tool_name].", \ + " You treat damage to [target]'s [I.name] with [tool_name]." ) I.damage = 0 + else if(I.robotic > 2 && istype (tool, /obj/item/stack/nanopaste)) + user.visible_message(" [user] treats damage to [target]'s [I.name] with [tool_name].", \ + " You treat damage to [target]'s [I.name] with [tool_name]." ) + I.damage = 0 + //return 1 + else if(current_type == "insert") + I = tool + user.drop_item() + I.insert(target) + spread_germs_to_organ(I, user) + if(affected) + user.visible_message(" [user] has transplanted \the [tool] into [target]'s [affected.name].", \ + " You have transplanted \the [tool] into [target]'s [affected.name].") + else + user.visible_message(" [user] has transplanted \the [tool] into [target]'s [affected.name].", \ + " You have transplanted \the [tool] into [target]'s [parse_zone(target_zone)].") + I.status &= ~ORGAN_CUT_AWAY - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + else if(current_type == "extract") + if(I && I.owner == target) + user.visible_message(" [user] has separated and extracts [target]'s [I] with \the [tool]." , \ + " You have separated and extracted [target]'s [I] with \the [tool].") + add_logs(target,user, "surgically removed [I.name] from", addition="INTENT: [uppertext(user.a_intent)]") + spread_germs_to_organ(I, user) + I.status |= ORGAN_CUT_AWAY + I.remove(target) + I.loc = get_turf(target) + else + user.visible_message("[user] can't seem to extract anything from [target]'s [parse_zone(target_zone)]!", + "You can't extract anything from [target]'s [parse_zone(target_zone)]!") + else if(current_type == "finish") + + if(affected.encased) + var/msg = " [user] bends [target]'s [affected.encased] back into place with \the [tool]." + var/self_msg = " You bend [target]'s [affected.encased] back into place with \the [tool]." + user.visible_message(msg, self_msg) + affected.open = 2.5 + else + var/msg = "[user] pulls [target]'s flesh back into place with \the [tool]." + var/self_msg = "You pull [target]'s flesh back into place with \the [tool]." + user.visible_message(msg, self_msg) + + return 1 + + + return 0 + +/datum/surgery_step/internal/manipulate_organs/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + if(current_type == "mend") if (!hasorgans(target)) return - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, getting mess and tearing the inside of [target]'s [affected.name] with \the [tool]!", \ - "\red Your hand slips, getting mess and tearing the inside of [target]'s [affected.name] with \the [tool]!") + user.visible_message(" [user]'s hand slips, getting mess and tearing the inside of [target]'s [affected.name] with \the [tool]!", \ + " Your hand slips, getting mess and tearing the inside of [target]'s [affected.name] with \the [tool]!") var/dam_amt = 2 if (istype(tool, /obj/item/stack/medical/advanced/bruise_pack)) target.adjustToxLoss(5) - else if (istype(tool, /obj/item/stack/medical/bruise_pack)) + else if (istype(tool, /obj/item/stack/medical/bruise_pack) || istype(tool, /obj/item/stack/nanopaste)) dam_amt = 5 target.adjustToxLoss(10) affected.createwound(CUT, 5) - for(var/obj/item/organ/I in affected.internal_organs) - if(I && I.damage > 0) + for(var/obj/item/organ/internal/I in affected.internal_organs) + if(I && I.damage > 0 && !(I.tough)) I.take_damage(dam_amt,0) -/datum/surgery_step/internal/detatch_organ + return 0 + else if(current_type == "insert") + user.visible_message(" [user]'s hand slips, damaging \the [tool]!", \ + " Your hand slips, damaging \the [tool]!") + var/obj/item/organ/internal/I = tool + if(istype(I) &&!(I.tough)) + I.take_damage(rand(3,5),0) + return 0 + + + else if(current_type == "extract") + if(I && I.owner == target) + user.visible_message(" [user]'s hand slips, damaging [target]'s [affected.name] with \the [tool]!", \ + " Your hand slips, damaging [target]'s [affected.name] with \the [tool]!") + affected.createwound(BRUISE, 20) + else + user.visible_message("[user] can't seem to extract anything from [target]'s [parse_zone(target_zone)]!", + "You can't extract anything from [target]'s [parse_zone(target_zone)]!") + return 0 + else if(current_type == "finish") + if(affected.encased) + var/msg = " [user]'s hand slips, bending [target]'s [affected.encased] the wrong way!" + var/self_msg = " Your hand slips, bending [target]'s [affected.encased] the wrong way!" + user.visible_message(msg, self_msg) + affected.fracture() + else + var/msg = " [user]'s hand slips, tearing the skin!" + var/self_msg = " Your hand slips, tearing skin!" + user.visible_message(msg, self_msg) + affected.createwound(BRUISE, 20) + return 0 + + + return 0 + + +////////////////////////////////////////////////////////////////// +// SPESHUL AYLIUM STUPS // +////////////////////////////////////////////////////////////////// + +/datum/surgery_step/saw_carapace + name = "saw carapace" allowed_tools = list( + /obj/item/weapon/circular_saw = 100, \ + /obj/item/weapon/melee/energy/sword/cyborg/saw = 100, \ + /obj/item/weapon/hatchet = 75 + ) + + max_duration = 70 + + +/datum/surgery_step/saw_carapace/begin_step(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool,datum/surgery/surgery) + + user.visible_message("[user] begins to cut through [target]'s [target_zone] with \the [tool].", \ + "You begin to cut through [target]'s [target_zone] with \the [tool].") + ..() + +/datum/surgery_step/saw_carapace/end_step(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool,datum/surgery/surgery) + + user.visible_message(" [user] has cut [target]'s [target_zone] open with \the [tool].", \ + " You have cut [target]'s [target_zone] open with \the [tool].") + return 1 + +/datum/surgery_step/saw_carapace/fail_step(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool,datum/surgery/surgery) + + user.visible_message(" [user]'s hand slips, cracking [target]'s [target_zone] with \the [tool]!" , \ + " Your hand slips, cracking [target]'s [target_zone] with \the [tool]!" ) + return 0 + +/datum/surgery_step/cut_carapace + name = "cut carapace" + allowed_tools = list( + /obj/item/weapon/scalpel/laser3 = 115, \ + /obj/item/weapon/scalpel/laser2 = 110, \ + /obj/item/weapon/scalpel/laser1 = 105, \ + /obj/item/weapon/scalpel/manager = 120, \ /obj/item/weapon/scalpel = 100, \ /obj/item/weapon/kitchen/knife = 75, \ /obj/item/weapon/shard = 50, \ + /obj/item/weapon/scissors = 10, \ + /obj/item/weapon/twohanded/chainsaw = 1, \ + /obj/item/weapon/claymore = 5, \ + /obj/item/weapon/melee/energy/ = 5, \ + /obj/item/weapon/pen/edagger = 5, \ ) - min_duration = 90 - max_duration = 110 + max_duration = 60 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/cut_carapace/begin_step(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool,datum/surgery/surgery) - if (!..()) - return 0 + user.visible_message("[user] starts the incision on [target]'s [target_zone] with \the [tool].", \ + "You start the incision on [target]'s [target_zone] with \the [tool].") + ..() - var/obj/item/organ/external/affected = target.get_organ(target_zone) +/datum/surgery_step/cut_carapace/end_step(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool,datum/surgery/surgery) - if(!(affected && !(affected.status & ORGAN_ROBOT))) - return 0 + user.visible_message(" [user] has made an incision on [target]'s [target_zone] with \the [tool].", \ + " You have made an incision on [target]'s [target_zone] with \the [tool].",) + return 1 - target.op_stage.current_organ = null - target.op_stage.organ_ref = null +/datum/surgery_step/cut_carapace/fail_step(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool,datum/surgery/surgery) - var/list/attached_organs = list() - for(var/organ in affected.internal_organs) - var/obj/item/organ/I = organ - if(I && !(I.status & ORGAN_CUT_AWAY) && I.parent_organ == target_zone) - attached_organs[I.organ_tag] = I + user.visible_message(" [user]'s hand slips, slicing open [target]'s [target_zone] in a wrong spot with \the [tool]!", \ + " Your hand slips, slicing open [target]'s [target_zone] in a wrong spot with \the [tool]!") + return 0 - var/organ_to_remove = input(user, "Which organ do you want to prepare for removal?") as null|anything in attached_organs - if(!organ_to_remove) - return 0 - - target.op_stage.current_organ = organ_to_remove - target.op_stage.organ_ref = attached_organs[organ_to_remove] - - return ..() && organ_to_remove - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - - var/obj/item/organ/external/affected = target.get_organ(target_zone) - - user.visible_message("[user] starts to separate [target]'s [target.op_stage.current_organ] with \the [tool].", \ - "You start to separate [target]'s [target.op_stage.current_organ] with \the [tool]." ) - target.custom_pain("The pain in your [affected.name] is living hell!",1) - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\blue [user] has separated [target]'s [target.op_stage.current_organ] with \the [tool]." , \ - "\blue You have separated [target]'s [target.op_stage.current_organ] with \the [tool].") - - var/obj/item/organ/I = target.op_stage.organ_ref - if(I && istype(I)) - spread_germs_to_organ(I, user) - I.status |= ORGAN_CUT_AWAY - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, slicing an artery inside [target]'s [affected.name] with \the [tool]!", \ - "\red Your hand slips, slicing an artery inside [target]'s [affected.name] with \the [tool]!") - affected.createwound(CUT, rand(30,50), 1) - -/datum/surgery_step/internal/remove_organ +/datum/surgery_step/retract_carapace + name = "retract carapace" allowed_tools = list( - /obj/item/weapon/hemostat = 100, \ - /obj/item/weapon/wirecutters = 75, \ - /obj/item/weapon/kitchen/utensil/fork = 20 + /obj/item/weapon/scalpel/manager = 120, \ + /obj/item/weapon/retractor = 100, \ + /obj/item/weapon/crowbar = 75, \ + /obj/item/weapon/kitchen/utensil/fork = 50 ) - min_duration = 60 - max_duration = 80 + max_duration = 40 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/retract_carapace/begin_step(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/msg = "[user] starts to pry open the incision on [target]'s [target_zone] with \the [tool]." + var/self_msg = "You start to pry open the incision on [target]'s [target_zone] with \the [tool]." + if (target_zone == "chest") + msg = "[user] starts to separate the ribcage and rearrange the organs in [target]'s torso with \the [tool]." + self_msg = "You start to separate the ribcage and rearrange the organs in [target]'s torso with \the [tool]." + if (target_zone == "groin") + msg = "[user] starts to pry open the incision and rearrange the organs in [target]'s lower abdomen with \the [tool]." + self_msg = "You start to pry open the incision and rearrange the organs in [target]'s lower abdomen with \the [tool]." + user.visible_message(msg, self_msg) + ..() - if (!..()) - return 0 - var/obj/item/organ/external/affected = target.get_organ(target_zone) +/datum/surgery_step/retract_carapace/end_step(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/msg = " [user] keeps the incision open on [target]'s [target_zone] with \the [tool]." + var/self_msg = " You keep the incision open on [target]'s [target_zone] with \the [tool]." + if (target_zone == "chest") + msg = " [user] keeps the ribcage open on [target]'s torso with \the [tool]." + self_msg = " You keep the ribcage open on [target]'s torso with \the [tool]." + if (target_zone == "groin") + msg = " [user] keeps the incision open on [target]'s lower abdomen with \the [tool]." + self_msg = " You keep the incision open on [target]'s lower abdomen with \the [tool]." + user.visible_message(msg, self_msg) + return 1 - if(!istype(affected)) - return 0 - - target.op_stage.current_organ = null - target.op_stage.organ_ref = null - - var/list/removable_organs = list() - for(var/organ in affected.internal_organs) - var/obj/item/organ/I = organ - if(istype(I) && (I.status & ORGAN_CUT_AWAY) && I.parent_organ == target_zone) - removable_organs[I.organ_tag] = I - - var/organ_to_remove = input(user, "Which organ do you want to remove?") as null|anything in removable_organs - if(!organ_to_remove) - return 0 - - target.op_stage.current_organ = organ_to_remove - target.op_stage.organ_ref = removable_organs[organ_to_remove] - return ..() - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] starts removing [target]'s [target.op_stage.current_organ] with \the [tool].", \ - "You start removing [target]'s [target.op_stage.current_organ] with \the [tool].") - target.custom_pain("Someone's ripping out your [target.op_stage.current_organ]!",1) - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\blue [user] has removed [target]'s [target.op_stage.current_organ] with \the [tool].", \ - "\blue You have removed [target]'s [target.op_stage.current_organ] with \the [tool].") - - // Extract the organ! - if(target.op_stage.current_organ) - var/obj/item/organ/O = target.op_stage.organ_ref - if(O && istype(O)) - spread_germs_to_organ(O, user) - O.removed(user) - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, damaging [target]'s [affected.name] with \the [tool]!", \ - "\red Your hand slips, damaging [target]'s [affected.name] with \the [tool]!") - affected.createwound(BRUISE, 20) - -/datum/surgery_step/internal/replace_organ - allowed_tools = list( - /obj/item/organ = 100 - ) - - min_duration = 60 - max_duration = 80 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - - var/obj/item/organ/O = tool - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!affected) return - var/organ_compatible - var/organ_missing - - if(!istype(O)) - return 0 - - if((affected.status & ORGAN_ROBOT) && !(O.status & ORGAN_ROBOT)) - user << "You cannot install a naked organ into a robotic body." - return 2 - - if(!target.species) - user << "\red You have no idea what species this person is. Report this on the bug tracker." - return 2 - - var/o_is = (O.gender == PLURAL) ? "are" : "is" - var/o_a = (O.gender == PLURAL) ? "" : "a " - var/o_do = (O.gender == PLURAL) ? "don't" : "doesn't" - - if(O.organ_tag == "limb") - return 0 - else if(target.species.has_organ[O.organ_tag]) - - if(O.damage > (O.max_damage * 0.75)) - user << "\red \The [O.organ_tag] [o_is] in no state to be transplanted." - return 2 - - if(!target.internal_organs_by_name[O.organ_tag]) - organ_missing = 1 - else - user << "\red \The [target] already has [o_a][O.organ_tag]." - return 2 - - if(O && affected.limb_name == O.parent_organ) - organ_compatible = 1 - else - user << "\red \The [O.organ_tag] [o_do] normally go in \the [affected.name]." - return 2 - else - user << "\red You're pretty sure [target.species.name] don't normally have [o_a][O.organ_tag]." - return 2 - - return ..() && organ_missing && organ_compatible - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts transplanting \the [tool] into [target]'s [affected.name].", \ - "You start transplanting \the [tool] into [target]'s [affected.name].") - target.custom_pain("Someone's rooting around in your [affected.name]!",1) - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] has transplanted \the [tool] into [target]'s [affected.name].", \ - "\blue You have transplanted \the [tool] into [target]'s [affected.name].") - user.drop_item(tool) - var/obj/item/organ/O = tool - if(istype(O)) - O.replaced(target,affected) - spread_germs_to_organ(O, user) - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\red [user]'s hand slips, damaging \the [tool]!", \ - "\red Your hand slips, damaging \the [tool]!") - var/obj/item/organ/I = tool - if(istype(I)) - I.take_damage(rand(3,5),0) - -/datum/surgery_step/internal/attach_organ - allowed_tools = list( - /obj/item/weapon/FixOVein = 100, \ - /obj/item/stack/cable_coil = 75 - ) - - min_duration = 100 - max_duration = 120 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - - if (!..()) - return 0 - - var/obj/item/organ/external/affected = target.get_organ(target_zone) - - if(!istype(affected)) - return 0 - - target.op_stage.current_organ = null - target.op_stage.organ_ref = null - - var/list/removable_organs = list() - for(var/organ in affected.internal_organs) - var/obj/item/organ/I = organ - if(I && istype(I) && (I.status & ORGAN_CUT_AWAY) && !(I.status & ORGAN_ROBOT) && I.parent_organ == target_zone) - removable_organs[I.organ_tag] = I - - var/organ_to_replace = input(user, "Which organ do you want to reattach?") as null|anything in removable_organs - if(!organ_to_replace) - return 0 - - target.op_stage.current_organ = organ_to_replace - target.op_stage.organ_ref = removable_organs[organ_to_replace] - return ..() - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] begins reattaching [target]'s [target.op_stage.current_organ] with \the [tool].", \ - "You start reattaching [target]'s [target.op_stage.current_organ] with \the [tool].") - target.custom_pain("Someone's digging needles into your [target.op_stage.current_organ]!",1) - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\blue [user] has reattached [target]'s [target.op_stage.current_organ] with \the [tool]." , \ - "\blue You have reattached [target]'s [target.op_stage.current_organ] with \the [tool].") - - var/obj/item/organ/I = target.op_stage.organ_ref - if(I && istype(I)) - I.status &= ~ORGAN_CUT_AWAY - spread_germs_to_organ(I, user) - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, damaging the flesh in [target]'s [affected.name] with \the [tool]!", \ - "\red Your hand slips, damaging the flesh in [target]'s [affected.name] with \the [tool]!") - affected.createwound(BRUISE, 20) - -////////////////////////////////////////////////////////////////// -// HEART SURGERY // -////////////////////////////////////////////////////////////////// -// To be finished after some tests. -// /datum/surgery_step/ribcage/heart/cut -// allowed_tools = list( -// /obj/item/weapon/scalpel = 100, \ -// /obj/item/weapon/kitchen/knife = 75, \ -// /obj/item/weapon/shard = 50, \ -// ) - -// min_duration = 30 -// max_duration = 40 - -// can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) -// return ..() && target.op_stage.ribcage == 2 \ No newline at end of file +/datum/surgery_step/generic/retract_carapace/fail_step(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/msg = " [user]'s hand slips, tearing the edges of incision on [target]'s [target_zone] with \the [tool]!" + var/self_msg = " Your hand slips, tearing the edges of incision on [target]'s [target_zone] with \the [tool]!" + if (target_zone == "chest") + msg = " [user]'s hand slips, damaging several organs [target]'s torso with \the [tool]!" + self_msg = " Your hand slips, damaging several organs [target]'s torso with \the [tool]!" + if (target_zone == "groin") + msg = " [user]'s hand slips, damaging several organs [target]'s lower abdomen with \the [tool]" + self_msg = " Your hand slips, damaging several organs [target]'s lower abdomen with \the [tool]!" + user.visible_message(msg, self_msg) + return 0 diff --git a/code/modules/surgery/other.dm b/code/modules/surgery/other.dm index 6e4c9f04571..c79eb220c38 100644 --- a/code/modules/surgery/other.dm +++ b/code/modules/surgery/other.dm @@ -2,10 +2,27 @@ ////////////////////////////////////////////////////////////////// // INTERNAL WOUND PATCHING // ////////////////////////////////////////////////////////////////// +/datum/surgery/bleeding + name = "internal bleeding" + steps = list(/datum/surgery_step/generic/cut_open,/datum/surgery_step/generic/clamp_bleeders,/datum/surgery_step/generic/retract_skin,/datum/surgery_step/fix_vein,/datum/surgery_step/generic/cauterize) + possible_locs = list("chest","head","groin") +/datum/surgery/bleeding/can_start(mob/user, mob/living/carbon/target) + if(ishuman(target)) + var/mob/living/carbon/human/H = target + var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) + if(!affected) return 0 + + var/internal_bleeding = 0 + for(var/datum/wound/W in affected.wounds) if(W.internal) + internal_bleeding = 1 + break + if(internal_bleeding) + return 1 + return 0 /datum/surgery_step/fix_vein - priority = 2 + name = "mend internal bleeding" allowed_tools = list( /obj/item/weapon/FixOVein = 100, \ /obj/item/stack/cable_coil = 75 @@ -13,45 +30,50 @@ can_infect = 1 blood_level = 1 - min_duration = 70 max_duration = 90 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!affected) return 0 +/datum/surgery_step/fix_vein/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if(!affected) return 0 - var/internal_bleeding = 0 - for(var/datum/wound/W in affected.wounds) if(W.internal) - internal_bleeding = 1 - break + var/internal_bleeding = 0 + for(var/datum/wound/W in affected.wounds) if(W.internal) + internal_bleeding = 1 + break - return affected.open == 2 && internal_bleeding + return affected.open == 2 && internal_bleeding - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts patching the damaged vein in [target]'s [affected.name] with \the [tool]." , \ - "You start patching the damaged vein in [target]'s [affected.name] with \the [tool].") - target.custom_pain("The pain in [affected.name] is unbearable!",1) - ..() +/datum/surgery_step/fix_vein/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts patching the damaged vein in [target]'s [affected.name] with \the [tool]." , \ + "You start patching the damaged vein in [target]'s [affected.name] with \the [tool].") + target.custom_pain("The pain in [affected.name] is unbearable!",1) + ..() - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] has patched the damaged vein in [target]'s [affected.name] with \the [tool].", \ - "\blue You have patched the damaged vein in [target]'s [affected.name] with \the [tool].") +/datum/surgery_step/fix_vein/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user] has patched the damaged vein in [target]'s [affected.name] with \the [tool].", \ + " You have patched the damaged vein in [target]'s [affected.name] with \the [tool].") - for(var/datum/wound/W in affected.wounds) if(W.internal) - affected.wounds -= W - affected.update_damages() - if (ishuman(user) && prob(40)) user:bloody_hands(target, 0) + for(var/datum/wound/W in affected.wounds) if(W.internal) + affected.wounds -= W + affected.update_damages() + if (ishuman(user) && prob(40)) + var/mob/living/carbon/human/U = user + U.bloody_hands(target, 0) - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, smearing [tool] in the incision in [target]'s [affected.name]!" , \ - "\red Your hand slips, smearing [tool] in the incision in [target]'s [affected.name]!") - affected.take_damage(5, 0) + return 1 + +/datum/surgery_step/fix_vein/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user]'s hand slips, smearing [tool] in the incision in [target]'s [affected.name]!" , \ + " Your hand slips, smearing [tool] in the incision in [target]'s [affected.name]!") + affected.take_damage(5, 0) + + return 0 /datum/surgery_step/fix_dead_tissue //Debridement - priority = 2 + name = "remove dead tissue" allowed_tools = list( /obj/item/weapon/scalpel = 100, \ /obj/item/weapon/kitchen/knife = 75, \ @@ -61,41 +83,44 @@ can_infect = 1 blood_level = 1 - min_duration = 110 max_duration = 160 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(!hasorgans(target)) - return 0 +/datum/surgery_step/fix_dead_tissue/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + if(!hasorgans(target)) + return 0 - if (target_zone == "mouth" || target_zone == "eyes") - return 0 + if (target_zone == "mouth" || target_zone == "eyes") + return 0 - var/obj/item/organ/external/affected = target.get_organ(target_zone) + var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.open == 2 && (affected.status & ORGAN_DEAD) + return affected && affected.open == 2 && (affected.status & ORGAN_DEAD) - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts cutting away necrotic tissue in [target]'s [affected.name] with \the [tool]." , \ - "You start cutting away necrotic tissue in [target]'s [affected.name] with \the [tool].") - target.custom_pain("The pain in [affected.name] is unbearable!",1) - ..() +/datum/surgery_step/fix_dead_tissue/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts cutting away necrotic tissue in [target]'s [affected.name] with \the [tool]." , \ + "You start cutting away necrotic tissue in [target]'s [affected.name] with \the [tool].") + target.custom_pain("The pain in [affected.name] is unbearable!",1) + ..() - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] has cut away necrotic tissue in [target]'s [affected.name] with \the [tool].", \ - "\blue You have cut away necrotic tissue in [target]'s [affected.name] with \the [tool].") - affected.open = 3 +/datum/surgery_step/fix_dead_tissue/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user] has cut away necrotic tissue in [target]'s [affected.name] with \the [tool].", \ + " You have cut away necrotic tissue in [target]'s [affected.name] with \the [tool].") + affected.open = 3 - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, slicing an artery inside [target]'s [affected.name] with \the [tool]!", \ - "\red Your hand slips, slicing an artery inside [target]'s [affected.name] with \the [tool]!") - affected.createwound(CUT, 20, 1) + return 1 + +/datum/surgery_step/fix_dead_tissue/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user]'s hand slips, slicing an artery inside [target]'s [affected.name] with \the [tool]!", \ + " Your hand slips, slicing an artery inside [target]'s [affected.name] with \the [tool]!") + affected.createwound(CUT, 20, 1) + + return 0 /datum/surgery_step/treat_necrosis - priority = 2 + name = "treat necrosis" allowed_tools = list( /obj/item/weapon/reagent_containers/dropper = 100, /obj/item/weapon/reagent_containers/glass/bottle = 75, @@ -107,63 +132,126 @@ can_infect = 0 blood_level = 0 - min_duration = 50 max_duration = 60 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (!istype(tool, /obj/item/weapon/reagent_containers)) - return 0 +/datum/surgery_step/fix_dead_tissue/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + if (!istype(tool, /obj/item/weapon/reagent_containers)) + return 0 - var/obj/item/weapon/reagent_containers/container = tool - if(!container.reagents.has_reagent("mitocholide")) - return 0 + var/obj/item/weapon/reagent_containers/container = tool + if(!container.reagents.has_reagent("mitocholide")) + return 0 - if(!hasorgans(target)) - return 0 + if(!hasorgans(target)) + return 0 - if (target_zone == "mouth" || target_zone == "eyes") - return 0 + if (target_zone == "mouth" || target_zone == "eyes") + return 0 - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected.open == 3 && (affected.status & ORGAN_DEAD) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return affected.open == 3 && (affected.status & ORGAN_DEAD) - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts applying medication to the affected tissue in [target]'s [affected.name] with \the [tool]." , \ - "You start applying medication to the affected tissue in [target]'s [affected.name] with \the [tool].") - target.custom_pain("Something in your [affected.name] is causing you a lot of pain!",1) - ..() +/datum/surgery_step/fix_dead_tissue/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts applying medication to the affected tissue in [target]'s [affected.name] with \the [tool]." , \ + "You start applying medication to the affected tissue in [target]'s [affected.name] with \the [tool].") + target.custom_pain("Something in your [affected.name] is causing you a lot of pain!",1) + ..() - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) +/datum/surgery_step/fix_dead_tissue/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) - if (!istype(tool, /obj/item/weapon/reagent_containers)) - return + if (!istype(tool, /obj/item/weapon/reagent_containers)) + return - var/obj/item/weapon/reagent_containers/container = tool + var/obj/item/weapon/reagent_containers/container = tool - var/trans = container.reagents.trans_to(target, container.amount_per_transfer_from_this) - if (trans > 0) - container.reagents.reaction(target, INGEST) //technically it's contact, but the reagents are being applied to internal tissue - - if(container.reagents.has_reagent("mitocholide")) - affected.status &= ~ORGAN_DEAD - - user.visible_message("\blue [user] applies [trans] units of the solution to affected tissue in [target]'s [affected.name]", \ - "\blue You apply [trans] units of the solution to affected tissue in [target]'s [affected.name] with \the [tool].") - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - - if (!istype(tool, /obj/item/weapon/reagent_containers)) - return - - var/obj/item/weapon/reagent_containers/container = tool - - var/trans = container.reagents.trans_to(target, container.amount_per_transfer_from_this) + var/trans = container.reagents.trans_to(target, container.amount_per_transfer_from_this) + if (trans > 0) container.reagents.reaction(target, INGEST) //technically it's contact, but the reagents are being applied to internal tissue - user.visible_message("\red [user]'s hand slips, applying [trans] units of the solution to the wrong place in [target]'s [affected.name] with the [tool]!" , \ - "\red Your hand slips, applying [trans] units of the solution to the wrong place in [target]'s [affected.name] with the [tool]!") + if(container.reagents.has_reagent("mitocholide")) + affected.status &= ~ORGAN_DEAD - //no damage or anything, just wastes medicine + user.visible_message(" [user] applies [trans] units of the solution to affected tissue in [target]'s [affected.name]", \ + " You apply [trans] units of the solution to affected tissue in [target]'s [affected.name] with \the [tool].") + + return 1 + +/datum/surgery_step/fix_dead_tissue/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + + if (!istype(tool, /obj/item/weapon/reagent_containers)) + return + + var/obj/item/weapon/reagent_containers/container = tool + + var/trans = container.reagents.trans_to(target, container.amount_per_transfer_from_this) + container.reagents.reaction(target, INGEST) //technically it's contact, but the reagents are being applied to internal tissue + + user.visible_message(" [user]'s hand slips, applying [trans] units of the solution to the wrong place in [target]'s [affected.name] with the [tool]!" , \ + " Your hand slips, applying [trans] units of the solution to the wrong place in [target]'s [affected.name] with the [tool]!") + + //no damage or anything, just wastes medicine + + +////////////////////////////////////////////////////////////////// +// Dethrall Shadowling // +////////////////////////////////////////////////////////////////// +/datum/surgery/remove_thrall + name = "clense contaminations"//RENAME MEH + steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/open_encased/saw,/datum/surgery_step/open_encased/retract, /datum/surgery_step/internal/dethrall,/datum/surgery_step/glue_bone, /datum/surgery_step/set_bone,/datum/surgery_step/finish_bone,/datum/surgery_step/generic/cauterize) + possible_locs = list("head") + +/datum/surgery/remove_thrall/synth + name = "clense contaminations"//RENAME MEH + steps = list(/datum/surgery_step/robotics/external/unscrew_hatch,/datum/surgery_step/robotics/external/open_hatch,/datum/surgery_step/internal/dethrall,/datum/surgery_step/robotics/external/close_hatch) + possible_locs = list("chest") + + + +/datum/surgery/remove_thrall/can_start(mob/user, mob/living/carbon/target) + return is_thrall(target)//would this be too meta? + +/datum/surgery/remove_thrall/synth/can_start(mob/user, mob/living/carbon/target) + return is_thrall(target) && target.get_species() == "Machine" + + +/datum/surgery_step/dethrall + name = "cleanse contamination" + allowed_tools = list(/obj/item/device/flash = 100, /obj/item/device/flashlight/pen = 80, /obj/item/device/flashlight = 40) + + max_duration = 120 + +/datum/surgery_step/internal/dethrall/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + if (!hasorgans(target)) + return + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return ..() && affected && is_thrall(target) && affected.open_enough_for_surgery() && target_zone == target.named_organ_parent("brain") + +/datum/surgery_step/internal/dethrall/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/braincase = target.named_organ_parent("brain") + user.visible_message("[user] reaches into [target]'s head with [tool].", "You begin aligning [tool]'s light to the tumor on [target]'s brain...") + target << "A small part of your [braincase] pulses with agony as the light impacts it." + ..() + +/datum/surgery_step/internal/dethrall/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + user.visible_message("[user] shines light onto the tumor in [target]'s head!", "You cleanse the contamination from [target]'s brain!") + ticker.mode.remove_thrall(target.mind,0) + target.visible_message("A strange black mass falls from [target]'s head!") + new /obj/item/organ/internal/shadowtumor(get_turf(target)) + + return 1 + +/datum/surgery_step/internal/dethrall/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/braincase = target.named_organ_parent("brain") + if(prob(50)) + user.visible_message("[user] slips and rips the tumor out from [target]'s [braincase]!", \ + "You fumble and tear out [target]'s tumor!") + target.adjustBrainLoss(110) // This is so you can't just defib'n go + ticker.mode.remove_thrall(target.mind,1) + + return 0 + else + user.visible_message("[user]'s hand slips and fumbles! Luckily, they didn't damage anything!") + return 0 diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm index 8d906366dcc..9ab6d952bf9 100644 --- a/code/modules/surgery/robotics.dm +++ b/code/modules/surgery/robotics.dm @@ -3,10 +3,51 @@ // COMMON STEPS // ////////////////////////////////////////////////////////////////// +/datum/surgery/cybernetic_repair + name = "Cybernetic Repair" + steps = list(/datum/surgery_step/robotics/external/unscrew_hatch,/datum/surgery_step/robotics/external/open_hatch,/datum/surgery_step/robotics/external/repair_brute,/datum/surgery_step/robotics/external/repair_burn,/datum/surgery_step/robotics/external/close_hatch) + possible_locs = list("chest","head","l_arm", "l_hand","r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","groin") + requires_organic_bodypart = 0 + +/datum/surgery/cybernetic_repair/internal + name = "Internal Cybernetic Mainpulation" + steps = list(/datum/surgery_step/robotics/external/unscrew_hatch,/datum/surgery_step/robotics/external/open_hatch,/datum/surgery_step/robotics/manipulate_robotic_organs) + possible_locs = list("chest","head","groin") + requires_organic_bodypart = 0 + +/datum/surgery/cybernetic_amputation + name = "robotic limb amputation" + steps = list(/datum/surgery_step/robotics/external/amputate) + possible_locs = list("chest","head","l_arm", "l_hand","r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","groin") + requires_organic_bodypart = 0 + +/datum/surgery/cybernetic_repair/can_start(mob/user, mob/living/carbon/target) + + if(istype(target,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = target + var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) + if(!affected) + return 0 + if(!(affected.status & ORGAN_ROBOT)) + return 0 + return 1 + +/datum/surgery/cybernetic_amputation/can_start(mob/user, mob/living/carbon/target) + + if(istype(target,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = target + var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) + if(!affected) + return 0 + if(!(affected.status & ORGAN_ROBOT)) + return 0 + return 1 + +//to do, moar surgerys or condense down ala mainpulate organs. /datum/surgery_step/robotics can_infect = 0 -/datum/surgery_step/robotics/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/robotics/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) if (isslime(target)) return 0 if (target_zone == "eyes") //there are specific steps for eye surgery @@ -22,7 +63,7 @@ /datum/surgery_step/robotics/external -/datum/surgery_step/robotics/external/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/robotics/external/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) if (!..()) return 0 var/obj/item/organ/external/affected = target.get_organ(target_zone) @@ -31,361 +72,437 @@ return 1 /datum/surgery_step/robotics/external/unscrew_hatch + name = "unscrew hatch" allowed_tools = list( /obj/item/weapon/screwdriver = 100, /obj/item/weapon/coin = 50, /obj/item/weapon/kitchen/knife = 50 ) - min_duration = 90 max_duration = 110 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.open == 0 && target_zone != "mouth" - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/robotics/external/unscrew_hatch/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + if(..()) var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts to unscrew the maintenance hatch on [target]'s [affected.name] with \the [tool].", \ - "You start to unscrew the maintenance hatch on [target]'s [affected.name] with \the [tool].") - ..() + return affected && affected.open == 0 && target_zone != "mouth" - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] has opened the maintenance hatch on [target]'s [affected.name] with \the [tool].", \ - "\blue You have opened the maintenance hatch on [target]'s [affected.name] with \the [tool].",) - affected.open = 1 +/datum/surgery_step/robotics/external/unscrew_hatch/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts to unscrew the maintenance hatch on [target]'s [affected.name] with \the [tool].", \ + "You start to unscrew the maintenance hatch on [target]'s [affected.name] with \the [tool].") + ..() - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s [tool.name] slips, failing to unscrew [target]'s [affected.name].", \ - "\red Your [tool] slips, failing to unscrew [target]'s [affected.name].") +/datum/surgery_step/robotics/external/unscrew_hatch/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user] has opened the maintenance hatch on [target]'s [affected.name] with \the [tool].", \ + " You have opened the maintenance hatch on [target]'s [affected.name] with \the [tool].",) + affected.open = 1 + return 1 + +/datum/surgery_step/robotics/external/unscrew_hatch/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user]'s [tool.name] slips, failing to unscrew [target]'s [affected.name].", \ + " Your [tool] slips, failing to unscrew [target]'s [affected.name].") + return 0 /datum/surgery_step/robotics/external/open_hatch + name = "open hatch" allowed_tools = list( /obj/item/weapon/retractor = 100, /obj/item/weapon/crowbar = 100, /obj/item/weapon/kitchen/utensil/ = 50 ) - min_duration = 30 max_duration = 40 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.open == 1 - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/robotics/external/open_hatch/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + if(..()) var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts to pry open the maintenance hatch on [target]'s [affected.name] with \the [tool].", - "You start to pry open the maintenance hatch on [target]'s [affected.name] with \the [tool].") - ..() + return affected && affected.open == 1 - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] opens the maintenance hatch on [target]'s [affected.name] with \the [tool].", \ - "\blue You open the maintenance hatch on [target]'s [affected.name] with \the [tool]." ) - affected.open = 2 +/datum/surgery_step/robotics/external/open_hatch/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts to pry open the maintenance hatch on [target]'s [affected.name] with \the [tool].", + "You start to pry open the maintenance hatch on [target]'s [affected.name] with \the [tool].") + ..() - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s [tool.name] slips, failing to open the hatch on [target]'s [affected.name].", - "\red Your [tool] slips, failing to open the hatch on [target]'s [affected.name].") +/datum/surgery_step/robotics/external/open_hatch/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user] opens the maintenance hatch on [target]'s [affected.name] with \the [tool].", \ + " You open the maintenance hatch on [target]'s [affected.name] with \the [tool]." ) + affected.open = 2 + return 1 + +/datum/surgery_step/robotics/external/open_hatch/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user]'s [tool.name] slips, failing to open the hatch on [target]'s [affected.name].", + " Your [tool] slips, failing to open the hatch on [target]'s [affected.name].") + return 0 /datum/surgery_step/robotics/external/close_hatch + name = "close hatch" allowed_tools = list( /obj/item/weapon/retractor = 100, /obj/item/weapon/crowbar = 100, /obj/item/weapon/kitchen/utensil = 50 ) - min_duration = 70 max_duration = 100 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.open && target_zone != "mouth" - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/robotics/external/close_hatch/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + if(..()) var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] begins to close and secure the hatch on [target]'s [affected.name] with \the [tool]." , \ - "You begin to close and secure the hatch on [target]'s [affected.name] with \the [tool].") - ..() + return affected && affected.open && target_zone != "mouth" - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] closes and secures the hatch on [target]'s [affected.name] with \the [tool].", \ - "\blue You close and secure the hatch on [target]'s [affected.name] with \the [tool].") - affected.open = 0 - affected.germ_level = 0 +/datum/surgery_step/robotics/external/close_hatch/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] begins to close and secure the hatch on [target]'s [affected.name] with \the [tool]." , \ + "You begin to close and secure the hatch on [target]'s [affected.name] with \the [tool].") + ..() - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s [tool.name] slips, failing to close the hatch on [target]'s [affected.name].", - "\red Your [tool.name] slips, failing to close the hatch on [target]'s [affected.name].") +/datum/surgery_step/robotics/external/close_hatch/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user] closes and secures the hatch on [target]'s [affected.name] with \the [tool].", \ + " You close and secure the hatch on [target]'s [affected.name] with \the [tool].") + affected.open = 0 + affected.germ_level = 0 + return 1 + +/datum/surgery_step/robotics/external/close_hatch/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user]'s [tool.name] slips, failing to close the hatch on [target]'s [affected.name].", + " Your [tool.name] slips, failing to close the hatch on [target]'s [affected.name].") + return 0 /datum/surgery_step/robotics/external/repair_brute + name = "Repair brute damage" allowed_tools = list( /obj/item/weapon/weldingtool = 100, /obj/item/weapon/gun/energy/plasmacutter = 50 ) - min_duration = 50 max_duration = 60 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(istype(tool,/obj/item/weapon/weldingtool)) - var/obj/item/weapon/weldingtool/welder = tool - if(!welder.isOn() || !welder.remove_fuel(1,user)) - return 0 - return affected && affected.open == 2 && (affected.brute_dam > 0 || affected.disfigured)&& target_zone != "mouth" - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/robotics/external/repair_brute/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + if(..()) var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] begins to patch damage to [target]'s [affected.name]'s support structure with \the [tool]." , \ - "You begin to patch damage to [target]'s [affected.name]'s support structure with \the [tool].") - ..() + if(istype(tool,/obj/item/weapon/weldingtool)) + var/obj/item/weapon/weldingtool/welder = tool + if(!welder.isOn() || !welder.remove_fuel(1,user)) + return 0 + return affected && affected.open == 2 && (affected.brute_dam > 0 || affected.disfigured)&& target_zone != "mouth" - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] finishes patching damage to [target]'s [affected.name] with \the [tool].", \ - "\blue You finish patching damage to [target]'s [affected.name] with \the [tool].") - affected.heal_damage(rand(30,50),0,1,1) - if(affected.disfigured) - affected.disfigured = 0 - affected.update_icon() - target.regenerate_icons() +/datum/surgery_step/robotics/external/repair_brute/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] begins to patch damage to [target]'s [affected.name]'s support structure with \the [tool]." , \ + "You begin to patch damage to [target]'s [affected.name]'s support structure with \the [tool].") + ..() - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s [tool.name] slips, damaging the internal structure of [target]'s [affected.name].", - "\red Your [tool.name] slips, damaging the internal structure of [target]'s [affected.name].") - target.apply_damage(rand(5,10), BURN, affected) +/datum/surgery_step/robotics/external/repair_brute/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user] finishes patching damage to [target]'s [affected.name] with \the [tool].", \ + " You finish patching damage to [target]'s [affected.name] with \the [tool].") + affected.heal_damage(rand(30,50),0,1,1) + if(affected.disfigured) + affected.disfigured = 0 + affected.update_icon() + target.regenerate_icons() + return 1 + +/datum/surgery_step/robotics/external/repair_brute/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user]'s [tool.name] slips, damaging the internal structure of [target]'s [affected.name].", + " Your [tool.name] slips, damaging the internal structure of [target]'s [affected.name].") + target.apply_damage(rand(5,10), BURN, affected) + return 0 /datum/surgery_step/robotics/external/repair_burn + name = "repair heat damage" allowed_tools = list( /obj/item/stack/cable_coil = 100 ) - min_duration = 50 max_duration = 60 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/obj/item/stack/cable_coil/C = tool - var/obj/item/organ/external/affected = target.get_organ(target_zone) - var/limb_can_operate = (affected && affected.open == 2 && affected.burn_dam > 0 && target_zone != "mouth") - if(limb_can_operate) - if(istype(C)) - if(!C.get_amount() >= 3) - user << "You need three or more cable pieces to repair this damage." - return 2 - C.use(3) - return 1 - return 0 - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/robotics/external/repair_burn/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + if(..()) + var/obj/item/stack/cable_coil/C = tool var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] begins to splice new cabling into [target]'s [affected.name]." , \ - "You begin to splice new cabling into [target]'s [affected.name].") - ..() + var/limb_can_operate = (affected && affected.open == 2 && affected.burn_dam > 0 && target_zone != "mouth") + if(limb_can_operate) + if(istype(C)) + if(!C.get_amount() >= 3) + user << "You need three or more cable pieces to repair this damage." + return 2 + C.use(3) + return 1 + return 0 - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] finishes splicing cable into [target]'s [affected.name].", \ - "\blue You finishes splicing new cable into [target]'s [affected.name].") - affected.heal_damage(0,rand(30,50),1,1) +/datum/surgery_step/robotics/external/repair_burn/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] begins to splice new cabling into [target]'s [affected.name]." , \ + "You begin to splice new cabling into [target]'s [affected.name].") + ..() - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user] causes a short circuit in [target]'s [affected.name]!", - "\red You cause a short circuit in [target]'s [affected.name]!") - target.apply_damage(rand(5,10), BURN, affected) +/datum/surgery_step/robotics/external/repair_burn/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user] finishes splicing cable into [target]'s [affected.name].", \ + " You finishes splicing new cable into [target]'s [affected.name].") + affected.heal_damage(0,rand(30,50),1,1) + return 1 -/datum/surgery_step/robotics/fix_organ_robotic //For artificial organs - allowed_tools = list( - /obj/item/stack/nanopaste = 100, \ - /obj/item/weapon/bonegel = 30, \ - /obj/item/weapon/screwdriver = 70, \ - ) +/datum/surgery_step/robotics/external/repair_burn/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user] causes a short circuit in [target]'s [affected.name]!", + " You cause a short circuit in [target]'s [affected.name]!") + target.apply_damage(rand(5,10), BURN, affected) + return 0 - min_duration = 70 +///////condenseing remove/extract/repair here. ///////////// +/datum/surgery_step/robotics/manipulate_robotic_organs + + name = "internal part mainpulation" + allowed_tools = list(/obj/item/device/mmi = 100) + var/implements_extract = list(/obj/item/device/multitool = 100) + var/implements_mend = list( /obj/item/stack/nanopaste = 100,/obj/item/weapon/bonegel = 30, /obj/item/weapon/screwdriver = 70) + var/implements_insert = list(/obj/item/weapon/screwdriver = 100) + var/implements_finish =list(/obj/item/weapon/retractor = 100,/obj/item/weapon/crowbar = 100,/obj/item/weapon/kitchen/utensil = 50) + var/current_type + var/obj/item/organ/internal/I = null + var/obj/item/organ/external/affected = null max_duration = 90 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/robotics/manipulate_robotic_organs/New() + ..() + allowed_tools = allowed_tools + implements_extract + implements_mend + implements_insert + implements_finish - if (!hasorgans(target)) - return - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!affected) return - var/is_organ_damaged = 0 - for(var/obj/item/organ/I in affected.internal_organs) - if(I.damage > 0 && I.robotic >= 2) - is_organ_damaged = 1 - break - return affected.open_enough_for_surgery() && is_organ_damaged - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + +/datum/surgery_step/robotics/manipulate_robotic_organs/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + + I = null + affected = target.get_organ(target_zone) + if(implement_type in implements_insert) + current_type = "insert" + //I = tool + var/off_tool = user.get_inactive_hand() + + if(!off_tool || !istype(off_tool,/obj/item/organ/internal)) + user << "You need a replacement internal part in your off hand." + return -1 + I = off_tool //and please god let it be an organ... + if(target_zone != I.parent_organ || target.get_organ_slot(I.slot)) + user << "There is no room for [I] in [target]'s [parse_zone(target_zone)]!" + return -1 + + if(I.damage > (I.max_damage * 0.75)) + user << " \The [I] is in no state to be transplanted." + return -1 + + if(target.get_int_organ(I)) + user << " \The [target] already has [I]." + return -1 + + user.visible_message("[user] begins reattaching [target]'s [off_tool] with \the [tool].", \ + "You start reattaching [target]'s [off_tool] with \the [tool].") + target.custom_pain("Someone's rooting around in your [affected.name]!",1) + else if(istype(tool,/obj/item/device/mmi)) + current_type = "install" + + if(target_zone != "chest") + user << " You must target the chest cavity." + + return -1 + var/obj/item/device/mmi/M = tool + + + if(!(affected && affected.open_enough_for_surgery())) + return -1 + + if(!istype(M)) + return -1 + + if(!M.brainmob || !M.brainmob.client || !M.brainmob.ckey || M.brainmob.stat >= DEAD) + user << "That brain is not usable." + return -1 + + if(!(affected.status & ORGAN_ROBOT)) + user << "You cannot install a computer brain into a meat enclosure." + return -1 + + if(!target.species) + user << "You have no idea what species this person is. Report this on the bug tracker." + return -1 + + if(!target.species.has_organ["brain"]) + user << "You're pretty sure [target.species.name_plural] don't normally have a brain." + return -1 + + if(target.get_int_organ(/obj/item/organ/internal/brain/)) + user << "Your subject already has a brain." + return -1 + + user.visible_message("[user] starts installing \the [tool] into [target]'s [affected.name].", \ + "You start installing \the [tool] into [target]'s [affected.name].") + + else if(implement_type in implements_extract) + current_type = "extract" + var/list/organs = target.get_organs_zone(target_zone) + if(!(affected && (affected.status & ORGAN_ROBOT))) + return -1 + if(!affected.open_enough_for_surgery()) + return -1 + if(!organs.len) + user << "There is no removeable organs in [target]'s [parse_zone(target_zone)]!" + return -1 + else + for(var/obj/item/organ/internal/O in organs) + O.on_find(user) + organs -= O + organs[O.name] = O + + I = input("Remove which organ?", "Surgery", null, null) as null|anything in organs + if(I && user && target && user.Adjacent(target) && user.get_active_hand() == tool) + I = organs[I] + if(!I) return -1 + user.visible_message("[user] starts to decouple [target]'s [I] with \the [tool].", \ + "You start to decouple [target]'s [I] with \the [tool]." ) + + target.custom_pain("The pain in your [affected.name] is living hell!",1) + else + return -1 + + else if(implement_type in implements_mend) + current_type = "mend" if (!hasorgans(target)) return var/obj/item/organ/external/affected = target.get_organ(target_zone) - for(var/obj/item/organ/I in affected.internal_organs) + for(var/obj/item/organ/internal/I in affected.internal_organs) if(I && I.damage > 0) if(I.robotic >= 2) user.visible_message("[user] starts mending the damage to [target]'s [I.name]'s mechanisms.", \ "You start mending the damage to [target]'s [I.name]'s mechanisms." ) target.custom_pain("The pain in your [affected.name] is living hell!",1) - ..() - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + else if(implement_type in implements_finish) + current_type = "finish" + user.visible_message("[user] begins to close and secure the hatch on [target]'s [affected.name] with \the [tool]." , \ + "You begin to close and secure the hatch on [target]'s [affected.name] with \the [tool].") + + + ..() + +/datum/surgery_step/robotics/manipulate_robotic_organs/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + if(current_type == "mend") if (!hasorgans(target)) return - var/obj/item/organ/external/affected = target.get_organ(target_zone) - - for(var/obj/item/organ/I in affected.internal_organs) - + for(var/obj/item/organ/internal/I in affected.internal_organs) if(I && I.damage > 0) if(I.robotic >= 2) - user.visible_message("\blue [user] repairs [target]'s [I.name] with [tool].", \ - "\blue You repair [target]'s [I.name] with [tool]." ) + user.visible_message(" [user] repairs [target]'s [I.name] with [tool].", \ + " You repair [target]'s [I.name] with [tool]." ) I.damage = 0 + else if(current_type == "insert") + var/obj/item/organ/internal/I = target.get_int_organ(surgery.current_organ) - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/off_tool = user.get_inactive_hand() + I = off_tool + //user.drop_item() + I.insert(target) + user.visible_message(" [user] has reattached [target]'s [I] with \the [tool]." , \ + " You have reattached [target]'s [I] with \the [tool].") + if(I && istype(I)) + I.status &= ~ORGAN_CUT_AWAY + qdel(off_tool) + else if (current_type == "install") + user.visible_message(" [user] has installed \the [tool] into [target]'s [affected.name].", \ + " You have installed \the [tool] into [target]'s [affected.name].") + + var/obj/item/device/mmi/M = tool + var/obj/item/organ/internal/brain/mmi_holder/holder = new() + if (istype(M, /obj/item/device/mmi/posibrain)) + holder.robotize() + + holder.insert(target) + user.unEquip(tool) + tool.forceMove(holder) + holder.stored_mmi = tool + holder.update_from_mmi() + + if(M.brainmob && M.brainmob.mind) + M.brainmob.mind.transfer_to(target) + + else if(current_type == "extract") + if(I && I.owner == target) + user.visible_message(" [user] has decoupled [target]'s [surgery.current_organ] with \the [tool]." , \ + " You have decoupled [target]'s [surgery.current_organ] with \the [tool].") + + add_logs(target,user, "surgically removed [I.name] from", addition="INTENT: [uppertext(user.a_intent)]") + spread_germs_to_organ(I, user) + I.status |= ORGAN_CUT_AWAY + I.remove(target) + I.loc = get_turf(target) + else + user.visible_message("[user] can't seem to extract anything from [target]'s [parse_zone(target_zone)]!", + "You can't extract anything from [target]'s [parse_zone(target_zone)]!") + else if(current_type == "finish") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user] closes and secures the hatch on [target]'s [affected.name] with \the [tool].", \ + " You close and secure the hatch on [target]'s [affected.name] with \the [tool].") + affected.open = 0 + affected.germ_level = 0 + return 1 + return 0 + +/datum/surgery_step/robotics/manipulate_robotic_organs/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + + if(current_type == "mend") if (!hasorgans(target)) return var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\red [user]'s hand slips, gumming up the mechanisms inside of [target]'s [affected.name] with \the [tool]!", \ - "\red Your hand slips, gumming up the mechanisms inside of [target]'s [affected.name] with \the [tool]!") + user.visible_message(" [user]'s hand slips, gumming up the mechanisms inside of [target]'s [affected.name] with \the [tool]!", \ + " Your hand slips, gumming up the mechanisms inside of [target]'s [affected.name] with \the [tool]!") target.adjustToxLoss(5) affected.createwound(CUT, 5) - for(var/obj/item/organ/I in affected.internal_organs) + for(var/obj/item/organ/internal/I in affected.internal_organs) if(I) I.take_damage(rand(3,5),0) -/datum/surgery_step/robotics/detatch_organ_robotic + else if(current_type == "insert") + user.visible_message(" [user]'s hand slips, disconnecting \the [tool].", \ + " Your hand slips, disconnecting \the [tool].") - allowed_tools = list( - /obj/item/device/multitool = 100 - ) - - min_duration = 90 - max_duration = 110 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + else if(current_type == "extract") + user.visible_message(" [user]'s hand slips, disconnecting \the [tool].", \ + " Your hand slips, disconnecting \the [tool].") + else if (current_type == "install") + user.visible_message(" [user]'s hand slips!.", \ + " Your hand slips!") + else if(current_type == "finish") var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!(affected && (affected.status & ORGAN_ROBOT))) - return 0 - if(!affected.open_enough_for_surgery()) - return 0 + user.visible_message(" [user]'s [tool.name] slips, failing to close the hatch on [target]'s [affected.name].", + " Your [tool.name] slips, failing to close the hatch on [target]'s [affected.name].") + return -1 - target.op_stage.current_organ = null - target.op_stage.organ_ref = null - var/list/attached_organs = list() - for(var/organ in affected.internal_organs) - var/obj/item/organ/I = organ - if(I && istype(I) && !(I.status & ORGAN_CUT_AWAY) && I.parent_organ == target_zone) - attached_organs[I.organ_tag] = I - - var/organ_to_remove = input(user, "Which organ do you want to prepare for removal?") as null|anything in attached_organs - if(!organ_to_remove) - return 0 - - target.op_stage.current_organ = organ_to_remove - target.op_stage.organ_ref = attached_organs[organ_to_remove] - - return ..() && organ_to_remove - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] starts to decouple [target]'s [target.op_stage.current_organ] with \the [tool].", \ - "You start to decouple [target]'s [target.op_stage.current_organ] with \the [tool]." ) - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\blue [user] has decoupled [target]'s [target.op_stage.current_organ] with \the [tool]." , \ - "\blue You have decoupled [target]'s [target.op_stage.current_organ] with \the [tool].") - - var/obj/item/organ/I = target.internal_organs_by_name[target.op_stage.current_organ] - if(I && istype(I)) - I.status |= ORGAN_CUT_AWAY - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\red [user]'s hand slips, disconnecting \the [tool].", \ - "\red Your hand slips, disconnecting \the [tool].") - -/datum/surgery_step/robotics/attach_organ_robotic - allowed_tools = list( - /obj/item/weapon/screwdriver = 100, - ) - - min_duration = 100 - max_duration = 120 - - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!(affected && (affected.status & ORGAN_ROBOT))) - return 0 - if(!affected.open_enough_for_surgery()) - return 0 - - target.op_stage.current_organ = null - target.op_stage.organ_ref = null - - var/list/removable_organs = list() - for(var/organ in affected.internal_organs) - var/obj/item/organ/I = organ - if(I && istype(I) && (I.status & ORGAN_CUT_AWAY) && (I.status & ORGAN_ROBOT) && I.parent_organ == target_zone) - removable_organs[I.organ_tag] = I - - var/organ_to_replace = input(user, "Which organ do you want to reattach?") as null|anything in removable_organs - if(!organ_to_replace) - return 0 - - target.op_stage.current_organ = organ_to_replace - target.op_stage.organ_ref = removable_organs[organ_to_replace] - return ..() - - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] begins reattaching [target]'s [target.op_stage.current_organ] with \the [tool].", \ - "You start reattaching [target]'s [target.op_stage.current_organ] with \the [tool].") - ..() - - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\blue [user] has reattached [target]'s [target.op_stage.current_organ] with \the [tool]." , \ - "\blue You have reattached [target]'s [target.op_stage.current_organ] with \the [tool].") - - var/obj/item/organ/I = target.internal_organs_by_name[target.op_stage.current_organ] - if(I && istype(I)) - I.status &= ~ORGAN_CUT_AWAY - - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\red [user]'s hand slips, disconnecting \the [tool].", \ - "\red Your hand slips, disconnecting \the [tool].") /datum/surgery_step/robotics/install_mmi allowed_tools = list( /obj/item/device/mmi = 100 ) - min_duration = 60 max_duration = 80 - can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) if(target_zone != "chest") return 0 @@ -414,29 +531,29 @@ user << "You're pretty sure [target.species.name_plural] don't normally have a brain." return 2 - if(!isnull(target.internal_organs["brain"])) + if(target.get_int_organ(/obj/item/organ/internal/brain/)) user << "Your subject already has a brain." return 2 return 1 - begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("[user] starts installing \the [tool] into [target]'s [affected.name].", \ "You start installing \the [tool] into [target]'s [affected.name].") ..() - end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("\blue [user] has installed \the [tool] into [target]'s [affected.name].", \ - "\blue You have installed \the [tool] into [target]'s [affected.name].") + user.visible_message(" [user] has installed \the [tool] into [target]'s [affected.name].", \ + " You have installed \the [tool] into [target]'s [affected.name].") var/obj/item/device/mmi/M = tool - var/obj/item/organ/mmi_holder/holder = new(target, 1) + var/obj/item/organ/internal/brain/mmi_holder/holder = new() if (istype(M, /obj/item/device/mmi/posibrain)) holder.robotize() - target.internal_organs_by_name["brain"] = holder + holder.insert(target) user.unEquip(tool) tool.forceMove(holder) holder.stored_mmi = tool @@ -445,6 +562,39 @@ if(M.brainmob && M.brainmob.mind) M.brainmob.mind.transfer_to(target) - fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("\red [user]'s hand slips.", \ - "\red Your hand slips.") \ No newline at end of file + fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + user.visible_message(" [user]'s hand slips.", \ + " Your hand slips.") + +/datum/surgery_step/robotics/external/amputate + name = "remove robotic limb" + + allowed_tools = list( + /obj/item/device/multitool = 100) + + max_duration = 110 + +/datum/surgery_step/robotics/external/amputate/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts to decouple [target]'s [affected.name] with \the [tool].", \ + "You start to decouple [target]'s [affected.name] with \the [tool]." ) + + target.custom_pain("Your [affected.amputation_point] is being ripped apart!",1) + ..() + +/datum/surgery_step/robotics/external/amputate/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user] has decoupled [target]'s [affected.name] with \the [tool]." , \ + " You have decoupled [target]'s [affected.name] with \the [tool].") + + + add_logs(target,user ,"surgically removed [affected.name] from", addition="INTENT: [uppertext(user.a_intent)]")//log it + + affected.droplimb(1,DROPLIMB_EDGE) + return 1 + +/datum/surgery_step/robotics/external/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + + user.visible_message(" [user]'s hand slips!", \ + " Your hand slips!") + return 0 \ No newline at end of file diff --git a/code/modules/surgery/slime.dm b/code/modules/surgery/slime.dm index fe4da556a49..62a7d890701 100644 --- a/code/modules/surgery/slime.dm +++ b/code/modules/surgery/slime.dm @@ -1,13 +1,19 @@ ////////////////////////////////////////////////////////////////// // SLIME CORE EXTRACTION // ////////////////////////////////////////////////////////////////// +/datum/surgery/core_removal + name = "core removal" + steps = list(/datum/surgery_step/slime/cut_flesh, /datum/surgery_step/slime/cut_innards, /datum/surgery_step/slime/saw_core) + allowed_mob = list(/mob/living/carbon/slime) + possible_locs = list("chest")//urgghhhhhhhhhhhh + /datum/surgery_step/slime is_valid_target(mob/living/carbon/slime/target) return istype(target, /mob/living/carbon/slime/) can_use(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) - return target.stat == 2 + return target.stat == DEAD /datum/surgery_step/slime/cut_flesh allowed_tools = list( @@ -16,24 +22,26 @@ /obj/item/weapon/shard = 50, \ ) - min_duration = 30 max_duration = 50 - can_use(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) +/datum/surgery_step/slime/cut_flesh/can_use(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) return ..() && istype(target) && target.core_removal_stage == 0 - begin_step(mob/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) +/datum/surgery_step/slime/cut_flesh/begin_step(mob/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) user.visible_message("[user] starts cutting through [target]'s flesh with \the [tool].", \ "You start cutting through [target]'s flesh with \the [tool].") - end_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) - user.visible_message("\blue [user] cuts through [target]'s flesh with \the [tool].", \ - "\blue You cut through [target]'s flesh with \the [tool], revealing its silky innards.") +/datum/surgery_step/slime/cut_flesh/end_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) + user.visible_message(" [user] cuts through [target]'s flesh with \the [tool].", \ + " You cut through [target]'s flesh with \the [tool], revealing its silky innards.") target.core_removal_stage = 1 - fail_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) - user.visible_message("\red [user]'s hand slips, tearing [target]'s flesh with \the [tool]!", \ - "\red Your hand slips, tearing [target]'s flesh with \the [tool]!") + return 1 + +/datum/surgery_step/slime/cut_flesh/fail_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) + user.visible_message(" [user]'s hand slips, tearing [target]'s flesh with \the [tool]!", \ + " Your hand slips, tearing [target]'s flesh with \the [tool]!") + return 0 /datum/surgery_step/slime/cut_innards allowed_tools = list( @@ -42,24 +50,25 @@ /obj/item/weapon/shard = 50, \ ) - min_duration = 30 max_duration = 50 - can_use(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) +/datum/surgery_step/slime/cut_innards/can_use(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) return ..() && istype(target) && target.core_removal_stage == 1 - begin_step(mob/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) +/datum/surgery_step/slime/cut_innards/begin_step(mob/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) user.visible_message("[user] starts cutting [target]'s silky innards apart with \the [tool].", \ "You start cutting [target]'s silky innards apart with \the [tool].") - end_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) - user.visible_message("\blue [user] cuts [target]'s innards apart with \the [tool], exposing the cores.", \ - "\blue You cut [target]'s innards apart with \the [tool], exposing the cores.") +/datum/surgery_step/slime/cut_innards/end_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) + user.visible_message(" [user] cuts [target]'s innards apart with \the [tool], exposing the cores.", \ + " You cut [target]'s innards apart with \the [tool], exposing the cores.") target.core_removal_stage = 2 + return 1 - fail_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) - user.visible_message("\red [user]'s hand slips, tearing [target]'s innards with \the [tool]!", \ - "\red Your hand slips, tearing [target]'s innards with \the [tool]!") +/datum/surgery_step/slime/cut_innards/fail_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) + user.visible_message(" [user]'s hand slips, tearing [target]'s innards with \the [tool]!", \ + " Your hand slips, tearing [target]'s innards with \the [tool]!") + return 0 /datum/surgery_step/slime/saw_core allowed_tools = list( @@ -67,26 +76,28 @@ /obj/item/weapon/hatchet = 75 ) - min_duration = 50 max_duration = 70 - can_use(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) +/datum/surgery_step/slime/saw_core/can_use(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) return ..() && (istype(target) && target.core_removal_stage == 2 && target.cores > 0) //This is being passed a human as target, unsure why. - begin_step(mob/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) +/datum/surgery_step/slime/saw_core/begin_step(mob/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) user.visible_message("[user] starts cutting out one of [target]'s cores with \the [tool].", \ "You start cutting out one of [target]'s cores with \the [tool].") - end_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) - target.cores-- - user.visible_message("\blue [user] cuts out one of [target]'s cores with \the [tool].",, \ - "\blue You cut out one of [target]'s cores with \the [tool]. [target.cores] cores left.") +/datum/surgery_step/slime/saw_core/end_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) + target.cores-- + user.visible_message(" [user] cuts out one of [target]'s cores with \the [tool].", \ + " You cut out one of [target]'s cores with \the [tool]. [target.cores] cores left.") - if(target.cores >= 0) - new target.coretype(target.loc) - if(target.cores <= 0) - target.icon_state = "[target.colour] baby slime dead-nocore" + if(target.cores >= 0) + new target.coretype(target.loc) + if(target.cores <= 0) + target.icon_state = "[target.colour] baby slime dead-nocore" - fail_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) - user.visible_message("\red [user]'s hand slips, causing \him to miss the core!", \ - "\red Your hand slips, causing you to miss the core!") \ No newline at end of file + return 1 + +/datum/surgery_step/slime/saw_core/fail_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool) + user.visible_message(" [user]'s hand slips, causing \him to miss the core!", \ + " Your hand slips, causing you to miss the core!") + return 0 \ No newline at end of file diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index e71df599342..99dfc5a4856 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -1,22 +1,133 @@ +///Datum Surgery Helpers// +/datum/surgery + var/name + var/status = 1 + var/list/steps = list() + /* + var/eyes = 0 + var/face = 0 + var/appendix = 0 + var/ribcage = 0 + var/head_reattach = 0 //Steps in a surgery + */ + + var/can_cancel = 1 + var/step_in_progress = 0 + var/list/in_progress = list() //Actively performing a Surgery + var/location = "chest" //Surgery location + var/requires_organic_bodypart = 1 //Prevents you from performing an operation on robotic limbs + var/list/possible_locs = list() //Multiple locations -- c0 + var/obj/item/organ/organ_ref //Operable body part + var/current_organ = "organ" + var/list/allowed_mob = list(/mob/living/carbon/human) + +/datum/surgery/proc/can_start(mob/user, mob/living/carbon/target) + // if 0 surgery wont show up in list + // put special restrictions here + return 1 + + +/datum/surgery/proc/next_step(mob/user, mob/living/carbon/target) + if(step_in_progress) return + + var/datum/surgery_step/S = get_surgery_step() + if(S) + if(S.try_op(user, target, user.zone_sel.selecting, user.get_active_hand(), src)) + return 1 + return 0 + +/datum/surgery/proc/get_surgery_step() + var/step_type = steps[status] + return new step_type + + +/datum/surgery/proc/complete(mob/living/carbon/human/target) + target.surgeries -= src + src = null + + + /* SURGERY STEPS */ /datum/surgery_step var/priority = 0 //steps with higher priority would be attempted first // type path referencing tools that can be used for this step, and how well are they suited for it var/list/allowed_tools = null - // type paths referencing mutantraces that this step applies to. - var/list/allowed_species = null - var/list/disallowed_species = null + var/implement_type = null // duration of the step - var/min_duration = 0 var/max_duration = 0 + var/name + var/accept_hand = 0 //does the surgery step require an open hand? If true, ignores implements. Compatible with accept_any_item. + var/accept_any_item = 0 + // evil infection stuff that will make everyone hate me var/can_infect = 0 //How much blood this step can get on surgeon. 1 - hands, 2 - full body. var/blood_level = 0 + var/list/allowed_mob = list() + var/list/disallowed_mob = list() + + +/datum/surgery_step/proc/try_op(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + var/success = 0 + if(accept_hand) + if(!tool) + success = 1 + if(accept_any_item) + if(tool && tool_quality(tool)) + success = 1 + else + for(var/path in allowed_tools) + if(istype(tool, path)) + implement_type = path + if(tool_quality(tool)) + success = 1 + + if(success) + if(target_zone == surgery.location) + initiate(user, target, target_zone, tool, surgery) + return 1//returns 1 so we don't stab the guy in the dick or wherever. + if(isrobot(user) && user.a_intent != I_HARM) //to save asimov borgs a LOT of heartache + return 1 + return 0 + +/datum/surgery_step/proc/initiate(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + surgery.step_in_progress = 1 + + if(begin_step(user, target, target_zone, tool, surgery) == -1) + surgery.step_in_progress = 0 + return + + var/advance = 0 + var/prob_chance = 100 + + if(implement_type) //this means it isn't a require nd or any item step. + prob_chance = min(allowed_tools[implement_type], 100) + prob_chance *= get_location_modifier(target) + + if(prob_chance > 100)//if we are using a super tool + max_duration = max_duration/prob_chance //PLACEHOLDER VALUES + + if(do_after(user, max_duration, target = target)) + + + if(prob(prob_chance) || isrobot(user)) + if(end_step(user, target, target_zone, tool, surgery)) + advance = 1 + else + if(fail_step(user, target, target_zone, tool, surgery)) + advance = 1 + + if(advance) + surgery.status++ + if(surgery.status > surgery.steps.len) + surgery.complete(target) + + surgery.step_in_progress = 0 + //returns how well tool is suited for this step /datum/surgery_step/proc/tool_quality(obj/item/tool) for (var/T in allowed_tools) @@ -29,28 +140,29 @@ if(!hasorgans(target)) return 0 - if(allowed_species) - for(var/species in allowed_species) - if(target.species.name == species) + if(allowed_mob)//can i just remove this and/or change it? + for(var/species in allowed_mob) + if(target.get_species() == species) return 1 - if(disallowed_species) - for(var/species in disallowed_species) - if(target.species.name == species) + if(disallowed_mob) + for(var/species in disallowed_mob) + if(target.get_species() == species) return 0 return 1 // checks whether this step can be applied with the given user and target -/datum/surgery_step/proc/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/proc/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) return 0 // does stuff to begin the step, usually just printing messages. Moved germs transfering and bloodying here too -/datum/surgery_step/proc/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if (can_infect && affected) - spread_germs_to_organ(affected, user) - if (ishuman(user) && prob(60)) +/datum/surgery_step/proc/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + if(ishuman(target)) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if (can_infect && affected) + spread_germs_to_organ(affected, user) + if (ishuman(user) && !(istype(target,/mob/living/carbon/alien)) && prob(60)) var/mob/living/carbon/human/H = user if (blood_level) H.bloody_hands(target,0) @@ -59,54 +171,23 @@ return // does stuff to end the step, which is normally print a message + do whatever this step changes -/datum/surgery_step/proc/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/proc/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) return // stuff that happens when the step fails -/datum/surgery_step/proc/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) +/datum/surgery_step/proc/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) return null + /proc/spread_germs_to_organ(obj/item/organ/E, mob/living/carbon/human/user) if(!istype(user) || !istype(E)) return - + //world << "Germ spread: [E] : [E.owner]" var/germ_level = user.germ_level if(user.gloves) germ_level = user.gloves.germ_level if(!(E.status & ORGAN_ROBOT)) //Germs on robotic limbs bad E.germ_level = max(germ_level,E.germ_level) //as funny as scrubbing microbes out with clean gloves is - no. -/proc/do_surgery(mob/living/carbon/M, mob/living/user, obj/item/tool) - if(!istype(M)) - return 0 - if (user.a_intent == I_HARM) //check for Hippocratic Oath - return 0 - var/zone = user.zone_sel.selecting - if(zone in M.op_stage.in_progress) //Can't operate on someone repeatedly. - user << "\red You can't operate on this area while surgery is already in progress." - return 1 - for(var/datum/surgery_step/S in surgery_steps) - //check if tool is right or close enough and if this step is possible - if(S.tool_quality(tool)) - var/step_is_valid = S.can_use(user, M, zone, tool) - if(step_is_valid && S.is_valid_target(M)) - if(step_is_valid == 2) // This is a failure that already has a message for failing. - return 1 - M.op_stage.in_progress += zone - S.begin_step(user, M, zone, tool) //start on it - //We had proper tools! (or RNG smiled.) and user did not move or change hands. - if(prob(S.tool_quality(tool)) && do_mob(user, M, rand(S.min_duration, S.max_duration))) - S.end_step(user, M, zone, tool) //finish successfully - else if ((tool in user.contents) && user.Adjacent(M)) //or - S.fail_step(user, M, zone, tool) //malpractice~ - else // This failing silently was a pain. - user << "You must remain close to your patient to conduct surgery." - M.op_stage.in_progress -= zone // Clear the in-progress flag. - return 1 //don't want to do weapony things after surgery - - if (user.a_intent == I_HELP) - user << "You can't see any useful way to use [tool] on [M]." - return 1 - return 0 /proc/sort_surgeries() var/gap = surgery_steps.len @@ -123,13 +204,3 @@ if(l.priority < r.priority) surgery_steps.Swap(i, gap + i) swapped = 1 - -/datum/surgery_status/ - var/eyes = 0 - var/face = 0 - var/appendix = 0 - var/ribcage = 0 - var/head_reattach = 0 - var/current_organ = "organ" - var/obj/item/organ/organ_ref = null - var/list/in_progress = list() \ No newline at end of file diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index edc8f6accb4..3c588c2f11b 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -82,9 +82,9 @@ /* * Researchable Scalpels */ -/obj/item/weapon/scalpel/laser1 +/obj/item/weapon/scalpel/laser1 //lasers also count as catuarys name = "laser scalpel" - desc = "A scalpel augmented with a directed laser, for more precise cutting without blood entering the field. This one looks basic and could be improved." + desc = "A scalpel augmented with a directed laser. This one looks basic and could be improved." icon_state = "scalpel_laser1_on" item_state = "scalpel" damtype = "fire" @@ -92,7 +92,7 @@ /obj/item/weapon/scalpel/laser2 name = "laser scalpel" - desc = "A scalpel augmented with a directed laser, for more precise cutting without blood entering the field. This one looks somewhat advanced." + desc = "A scalpel augmented with a directed laser. This one looks somewhat advanced." icon_state = "scalpel_laser2_on" item_state = "scalpel" damtype = "fire" @@ -100,13 +100,13 @@ /obj/item/weapon/scalpel/laser3 name = "laser scalpel" - desc = "A scalpel augmented with a directed laser, for more precise cutting without blood entering the field. This one looks to be the pinnacle of precision energy cutlery!" + desc = "A scalpel augmented with a directed laser. This one looks to be the pinnacle of precision energy cutlery!" icon_state = "scalpel_laser3_on" item_state = "scalpel" damtype = "fire" hitsound = 'sound/weapons/sear.ogg' -/obj/item/weapon/scalpel/manager +/obj/item/weapon/scalpel/manager //super tool! Retractor/hemostat name = "incision management system" desc = "A true extension of the surgeon's body, this marvel instantly and completely prepares an incision allowing for the immediate commencement of therapeutic steps." icon_state = "scalpel_manager_on" @@ -132,7 +132,6 @@ origin_tech = "materials=1;biotech=1" attack_verb = list("attacked", "slashed", "sawed", "cut") - //misc, formerly from code/defines/weapons.dm /obj/item/weapon/bonegel name = "bone gel" @@ -171,9 +170,3 @@ w_class = 1.0 origin_tech = "biotech=1" attack_verb = list("slapped") - -/* -/obj/item/weapon/surgical_drapes/attack(mob/living/M, mob/user) - if(!attempt_initiate_surgery(src, M, user)) - ..() -*/ \ No newline at end of file diff --git a/code/modules/vehicle/train/train.dm b/code/modules/vehicle/train/train.dm index 33021d80e06..72b5b2a7ed1 100644 --- a/code/modules/vehicle/train/train.dm +++ b/code/modules/vehicle/train/train.dm @@ -54,6 +54,9 @@ var/turf/T = get_step(A, dir) if(isturf(T)) A.Move(T) //bump things away when hit + + if(ismob(load) && istype(Obstacle, /obj/machinery/door)) + Obstacle.Bumped(load) if(emagged) if(istype(A, /mob/living)) diff --git a/code/modules/virus2/effect.dm b/code/modules/virus2/effect.dm index d54115adcfe..0ce20640940 100644 --- a/code/modules/virus2/effect.dm +++ b/code/modules/virus2/effect.dm @@ -221,7 +221,7 @@ activate(var/mob/living/carbon/mob,var/multiplier) if(istype(mob, /mob/living/carbon/human)) var/mob/living/carbon/human/H = mob - var/obj/item/organ/brain/B = H.internal_organs_by_name["brain"] + var/obj/item/organ/internal/brain/B = H.get_int_organ(/obj/item/organ/internal/brain) if (B.damage < B.min_broken_damage) B.take_damage(5, 1) else @@ -442,7 +442,7 @@ activate(var/mob/living/carbon/mob,var/multiplier) if(istype(mob, /mob/living/carbon/human)) var/mob/living/carbon/human/H = mob - var/obj/item/organ/brain/B = H.internal_organs_by_name["brain"] + var/obj/item/organ/internal/brain/B = H.get_int_organ(/obj/item/organ/internal/brain) if (B.damage < B.min_broken_damage) B.take_damage(1, 1) else @@ -693,7 +693,7 @@ var/list/compatible_mobs = list(/mob/living/carbon/human) activate(var/mob/living/carbon/mob,var/multiplier) if(istype(mob, /mob/living/carbon/human)) var/mob/living/carbon/human/H = mob - var/obj/item/organ/brain/B = H.internal_organs_by_name["brain"] + var/obj/item/organ/internal/brain/B = H.get_int_organ(/obj/item/organ/internal/brain) if (B.damage < B.min_broken_damage) B.take_damage(0.5, 1) else @@ -925,7 +925,7 @@ var/list/compatible_mobs = list(/mob/living/carbon/human) name = "Watery Eyes" stage = 1 activate(var/mob/living/carbon/human/mob,var/multiplier) - var/obj/item/organ/eyes/E = mob.internal_organs_by_name["eyes"] + var/obj/item/organ/internal/eyes/E = mob.get_int_organ(/obj/item/organ/internal/eyes) if(!istype(E) || (E.status & ORGAN_ROBOT)) // No eyes or robotic eyes? No problem! return mob << "Your eyes sting and water!" diff --git a/config/example/config.txt b/config/example/config.txt index c21bbcec76e..e7eaed2443a 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -245,8 +245,8 @@ GHOST_INTERACTION ## Uncomment to enable sending data to the IRC bot. #USE_IRC_BOT -## Host where the IRC bot is hosted. Port 45678 needs to be open. -#IRC_BOT_HOST localhost +## Host(s) where the IRC bot is hosted. Seperate IP's by ;. Port 45678 needs to be open. +#IRC_BOT_HOST 127.0.0.1;localhost ## IRC channel to send information to. Leave blank to disable. #MAIN_IRC #main diff --git a/html/changelog.html b/html/changelog.html index 56172c88974..610b6ceb5b6 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -55,6 +55,265 @@ -->
    +

    26 February 2016

    +

    FalseIncarnate updated:

    +
      +
    • Chocolate can now make you fat, as expected.
    • +
    +

    Fox McCloud updated:

    +
      +
    • stamina damage now regenerates slightly faster
    • +
    • Adds in whetstones for sharpening objects
    • +
    • Kitchen vendor starts off with 5 salt+pepper shakers
    • +
    • Can now point while lying or buckled
    • +
    • Fixes Capulettium Plus not silencing
    • +
    • Fixes slurring, stuttering, drugginess, and silences last half of what they should
    • +
    +

    KasparoVy updated:

    +
      +
    • Jackets that start open are recognized as actually being open already now. This fixes a bug with certain items that don't have an open state, or cases where it ended up giving an item the wrong icon (one that didn't exist)
    • +
    +

    Spacemanspark updated:

    +
      +
    • Fixes synthetics from giving off the proper message in the chat box when using the *yes and *no emotes.
    • +
    +

    Tastyfish updated:

    +
      +
    • Wheelchairs, janicarts, and ambulances can now go through doors according to the user's driver's access.
    • +
    + +

    24 February 2016

    +

    Crazylemon64 updated:

    +
      +
    • The defib should be more reliable on people who have ghosted
    • +
    • The defib will now give a message if the ghost is still haunting about
    • +
    • Attacking someone with an accessory will now let you put things on them without having to strip them.
    • +
    • Borers will now properly detach upon death of a mob they are controlling
    • +
    • Borers can now see their chemical count while in control of a mob
    • +
    • Borers can now silently communicate with their host - this is not available to the host until the borer has either begun to communicate, or has taken control at least once - this is to avoid spoiling that the borer exists
    • +
    • Borers won't be able to talk out loud inside of a host, by default - they can remove this safeguard with a verb under their borer tab. Borer hivespeak is unaffected.
    • +
    • Borers infesting and hiding are now silent.
    • +
    • Made borer's chem lists more nicely formatted
    • +
    • No more superspeed attacking simplemobs
    • +
    • New players now show up properly under the "who" verb when used as an admin
    • +
    • Mining drones will now automatically collect sand lying around
    • +
    • RIPLEYs can now drill asteroid turfs for sand
    • +
    • You can now load exosuit fuel generators with items containing their material - this means you can fuel yourself off of ores, but this will be highly inefficient and cost you mining points later on, as you can't take fuel back out.
    • +
    • You can now load the fuel generators from an ore box.
    • +
    • The plasma generator now produces 3x as much power from the same amount of fuel - this lets it even remotely compete with the uranium generator.
    • +
    • You can now light cigarettes off of burning mobs.
    • +
    • Exosuit tracking beacons now fit in boxes - prior, they were far too large for even a backpack, as they shared the same size as all other mecha equipment
    • +
    • Miners can now collect ore by walking over it with an ore satchel on.
    • +
    +

    FalseIncarnate updated:

    +
      +
    • Adds prize tickets as a replacement for physical arcade prizes.
    • +
    • Adds a buildable prize counter to exchange tickets for prizes.
    • +
    • Adds a bike. Despite what Prof. Oak might claim, you can ride it indoors.
    • +
    • Adds colorful wallets, for that old school arcade pride.
    • +
    • Fixes accidental removal of plump helmet biscuit recipe.
    • +
    • Temporarily adds a prize counter to the bar (Cyberiad) or dorms (MetaStation), and adds a max upgrade one to the Ninja Holding Area (Cyberiad z2)
    • +
    • Fixes Metastation. Seriously fixed a lot, just read the PR description for the full list.
    • +
    +

    FlattestGuitar updated:

    +
      +
    • Adds IPC alcohol and a few derivative drinks
    • +
    • IPCs can now drink and be fed from glasses
    • +
    +

    Fox McCloud updated:

    +
      +
    • Laser eyes mutation no longer drains nutrition
    • +
    • splits the EMP kit into two things: the standard EMP kit (2 grenades and an implant), and the EMP flashlight by itself
    • +
    • nerfs heart attacks so they do less damage
    • +
    • Pickpocket gloves now put the item you strip into your hands as opposed to the floor
    • +
    • Picketpocket gloves can now silently strip accessories
    • +
    • Pickpocket gloves will no longer give a message for messing up a pickpocket
    • +
    +

    KasparoVy updated:

    +
      +
    • Adjusting masks while they are not on the face will no longer turn off internals.
    • +
    • Adjusting masks while they are not on the face will now cause the mask to hide/reveal the wearer's identity the next time it's worn as intended.
    • +
    • Adds the ability to open/close bomber jackets.
    • +
    • Adds a security bomber jacket. This jacket inherits the protection and storage capabilities as a standard Security vest with additional bomber jacket benefits.
    • +
    • Adds UI button in top left of screen for jacket adjustment.
    • +
    • Replaces the standard bomber jacket in the Pod Pilot bay with the Security version.
    • +
    • Centralizes jacket/coat adjustment handling.
    • +
    • All jackets start closed by default.
    • +
    • Geneticist duffelbag on-mob sprite (for all species).
    • +
    • Vox-fitted backpacks, satchels, ERT backpacks, duffelbags and defib unit.
    • +
    • Refactors back-item icon generation.
    • +
    • Typo in the description of Santa's sack.
    • +
    • Missing punctuation and gender macros in the description of the bag of holding.
    • +
    • The tweak to back-icon generation fixes a bug where the wrong sprite name was being used to generate back-item icons.
    • +
    +

    PPI updated:

    +
      +
    • Adds the ability to hide papers in vents. You can now leave a romantic love letter, exchange information in secret, or hide papers infused with the power of nar'sie from sight.
    • +
    +

    Regen1 updated:

    +
      +
    • Adds the Immolator laser gun, a modified laser gun with 8 shots that will ignite mobs, can be made in R&D
    • +
    +

    Spacemanspark updated:

    +
      +
    • Adds *yes and *no emotes to Synthetics. Glory to Synthetica.
    • +
    +

    Tastyfish updated:

    +
      +
    • The PDA system has been completely redone behind the scenes! It should be functionally similar, although there is now a Home and Back button at the bottom as appropriate.
    • +
    • All of the heads now have multicolored pens.
    • +
    • EngiVend now has 10 camera assemblies.
    • +
    • Borgs can now use vending machines.
    • +
    • There are now picture frames that can be made from the autolathe or wood planks for papers, photos, posters, and canvases!
    • +
    +

    pinatacolada updated:

    +
      +
    • Makes the Protect Station AI law board no longer consider people that damage the station crew, instead of human
    • +
    +

    ppi updated:

    +
      +
    • When revealed Revenants will not be able to move at the maximum move speed, nor be able to pass through any solid object, like walls, windows, grills, computers and mechs.
    • +
    + +

    13 February 2016

    +

    Crazylemon64 updated:

    +
      +
    • Relaxes the check on what atoms you can follow to any movable atom
    • +
    • Mages are now more ragin
    • +
    • Admins can now adjust the total number of wizards at runtime by tweaking either max_mages, or players_per mage
    • +
    +

    DaveTheHeadcrab updated:

    +
      +
    • Adds new worn icons for duffelbags to better reflect their size, compliments of WJohn at /tg/
    • +
    +

    FalseIncarnate updated:

    +
      +
    • Adds burritos, made from cutlets, beans, rice, capsacin oil (hotsauce), cheese, and flat dough (because we lack proper tortillas) in the microwave.
    • +
    • Adds chimichangas. You know you want a deep-fried burrito.
    • +
    +

    Fox McCloud updated:

    +
      +
    • Updates some spell icons with better/higher quality icons
    • +
    • Updates unarmed attacks to allow for more customization
    • +
    • Updates martial arts so they factor in specie's attack messages and sounds
    • +
    • Re-balances Sleeping Carp fighting style
    • +
    • Re-balances Bo Staff
    • +
    • Rebalances Golem: they should now be spaceproof, fire+cold proof, rad proof, virus immune, clonable, parapen+syringe gun immune, deal increased melee damage. Their armor has been reduced to 55 melee across the board, their slip immunity removed, pain immunity removed, and they're slightly slower
    • +
    • Fixes Ei Nath generating two brains
    • +
    • Ensures the Necromatic Stone generates actual skeletons
    • +
    • Can now strip PDA/IDs from Golems
    • +
    • Fixes sleeping carp grab not being an instant aggressive grab
    • +
    • Fixes an exploit with declaring war on the station
    • +
    +

    KasparoVy updated:

    +
      +
    • Orange and purple bandanas for all station species.
    • +
    • The ability to colour bandanas with a crayon in a washing machine.
    • +
    • Refactors the bandana adjustment system.
    • +
    • Minor adjustments to Tajaran and Unathi bandana east/west sprites.
    • +
    • Adjusting a bandana will now take if off of your head/face and put it in an available hand. If both hands are available, it goes in the selected hand.
    • +
    • Adjusting a coloured bandana will no longer revert it to the original coloured icons anymore.
    • +
    • Adjusting a bandana from mask-style to hat-style means the bandana won't obscure your identity anymore.
    • +
    • Greys now use re-positioned smokeables. They no longer smoke out the eyes.
    • +
    +

    TheDZD updated:

    +
      +
    • Fixes spacepods being able to shoot through walls.
    • +
    • Lowers spacepod weapons fire delay.
    • +
    • Increases spacepod weapons energy costs.
    • +
    • Makes spacepods move at speeds not rivaling those of photon beams. They are now a hair bit faster than a person with a jetpack.
    • +
    • Reduces battery costs for spacepod movement.
    • +
    + +

    10 February 2016

    +

    Crazylemon64 updated:

    +
      +
    • The cloner now checks for NO_SCAN on the brain when scanning - unclonable species are now truly unclonable. You are still able to revive them with a brain transplant and a defib, however.
    • +
    • A tier-4 DNA scanner linked to a cloning system will now be able to reproduce a body from a brain's DNA, in event of the original corpse being gibbed or similar.
    • +
    • Species with organic limbs and NO_BLOOD will no longer bleed (though still on hit - write that off as "bone powder")
    • +
    • Skeletons now lack internal organs, except for the runic mind which exists in their head - an analogue for the brain
    • +
    • Skeletons that drink milk will be regenerated at a moderate pace, have a small chance of mending bones, and will praise the great name of mr skeltal
    • +
    • Adds a reagent system for species reacting to specific reagents
    • +
    • Slime People can now select from all human hairstyles, and their "hair" will be tinted a shade of their body.
    • +
    • Increases the frequency of the cortical borer event.
    • +
    • People with borers cannot commit suicide - this applies to a controlling borer, too.
    • +
    • Borers can no longer overdose their hosts.
    • +
    • Borers can now inject Saline-Glucose, Spaceacillin, Hydrocodone, Mitocholide, Salbutamol, Capulettium+, and Charcoal. Styptic was removed, as it's pathetic at healing when directly injected. Salicyclic acid was removed too, as its functionality is duplicated by both hydrocodone and saline-glucose.
    • +
    • A mind trapped by a cortical borer can now understand things it could understand when normally in its body.
    • +
    • Changes chemistry's welding tank to a wall-mounted version, to increase the room available.
    • +
    • You can now gib butterflies and lizards with a knife
    • +
    • Ghosts can now follow mecha
    • +
    • You can now access an R&D console by emagging it - it did nothing before.
    • +
    • Walls will now properly smooth and show damage.
    • +
    • Fixes the dialog that occurs when the AI shuts off to actually do what it says it does
    • +
    +

    Fox McCloud updated:

    +
      +
    • Fixes not being able to attach IEDs to beartraps
    • +
    • Can no longer spamclick someone to death using headslamming on a toilet/urimal
    • +
    • Toilet/urinal headslamming now plays a sound
    • +
    • Toilet headslamming damage reduced slightly
    • +
    • Can now fill open reagent containers in a toilet to receive "toilet water".
    • +
    • No more message spam when someone fills a container using a sink
    • +
    • Can now wash your face using a sink, which washes away lipstick and wakes you up slightly
    • +
    • Washing things will now use progress bars
    • +
    • Ensures consuming a single syndicate donk pocket won't get you addicted to meth
    • +
    • Kinetic Accelerators and E-bows automatically reload
    • +
    +

    Glorken updated:

    +
      +
    • Added a Knight Arena for Holodeck.
    • +
    • Added red and blue claymore sprites.
    • +
    • Changed overrided to overrode when emagging Holodeck computer.
    • +
    +

    KasparoVy updated:

    +
      +
    • Vox versions of the Officer SWAT sechailer + HOS SWAT sechailer + Warden SWAT sechailer.
    • +
    • Resprited versions of most Human masks to fit Unathi, Tajara and Vulpkanin.
    • +
    • Warden now gets their own version of the SWAT sechailer in their locker.
    • +
    • HOS now gets the appropriate version of the SWAT sechailer in their locker.
    • +
    • Repositioned smokeables now available for Vox, Unathi, Tajara and Vulpkanin.
    • +
    • Properly shades Vox bandana down-state sprites.
    • +
    • Readds Tajaran bald hairstyle.
    • +
    • Alternate style of non-Human breath mask (incl. surgical/sterile mask) down-state positioning.
    • +
    • Corrects all non-Human species' breath mask (incl. surgical/sterile mask) down-state icons to use the right position style.
    • +
    • Minor adjustments to Tajaran breath mask up-state sprites.
    • +
    +

    PPI updated:

    +
      +
    • Adds a reconnect button to the File menu in the client.
    • +
    • Adds head patting
    • +
    +

    Regen updated:

    +
      +
    • Powersink can now drain a lot more power before going boom
    • +
    • Buffed the powersinks drain rate
    • +
    • Buffed explosion from an overloaded powersink, try to find it instead of overloading the grid.
    • +
    • Admin log warning before the powersink explodes
    • +
    +

    Spacemanspark updated:

    +
      +
    • Miners can now utilize the power of mob capsules to take along their lazarus injected mining creatures!
    • +
    • Store your Pokemo- er, sorry, I mean mining mobs that you've captured in the lazarus capsule belt.
    • +
    +

    Tastyfish updated:

    +
      +
    • Species that don't breathe can kill themselves now!
    • +
    • Suicide messages are now catered to your species.
    • +
    • Shortened the default pill & patch name when using the ChemMaster.
    • +
    • The chaplain now has a service radio headset, as Space Jesus intended.
    • +
    +

    TheDZD updated:

    +
      +
    • When Ahelping, "Question" is now "Mentorhelp" and "Player Complaint" is now "Adminhelp."
    • +
    • Mentorhelps and PM replies from mentors appear in a bold aqua blue color.
    • +
    • Adminhelps and PM replies from admins appear in a bold bright red color.
    • +
    • PM replies from players appear in a dull/dark purple color.
    • +
    • Adds admin attack log to players being converted to cult.
    • +
    • Adds shadowling thrall jobbans.
    • +
    • Jobbanned players who are converted to shadowling thrall, revolutionary, or cultist will have the control of their body offered up to eligible ghosts.
    • +
    +

    31 January 2016

    Crazylemon64 updated:

      diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 70cedd14768..5578c36630e 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -379,3 +379,264 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - rscadd: Adds NanoUI to the operating computer - rscadd: Adds health announcing, critical and oxygen damage aural alerts to the computer, with a menu to selectively turn them on and off +2016-02-10: + Crazylemon64: + - tweak: The cloner now checks for NO_SCAN on the brain when scanning - unclonable + species are now truly unclonable. You are still able to revive them with a brain + transplant and a defib, however. + - rscadd: A tier-4 DNA scanner linked to a cloning system will now be able to reproduce + a body from a brain's DNA, in event of the original corpse being gibbed or similar. + - bugfix: Species with organic limbs and NO_BLOOD will no longer bleed (though still + on hit - write that off as "bone powder") + - tweak: Skeletons now lack internal organs, except for the runic mind which exists + in their head - an analogue for the brain + - rscadd: Skeletons that drink milk will be regenerated at a moderate pace, have + a small chance of mending bones, and will praise the great name of mr skeltal + - tweak: Adds a reagent system for species reacting to specific reagents + - rscadd: Slime People can now select from all human hairstyles, and their "hair" + will be tinted a shade of their body. + - tweak: Increases the frequency of the cortical borer event. + - tweak: People with borers cannot commit suicide - this applies to a controlling + borer, too. + - tweak: Borers can no longer overdose their hosts. + - tweak: Borers can now inject Saline-Glucose, Spaceacillin, Hydrocodone, Mitocholide, + Salbutamol, Capulettium+, and Charcoal. Styptic was removed, as it's pathetic + at healing when directly injected. Salicyclic acid was removed too, as its functionality + is duplicated by both hydrocodone and saline-glucose. + - bugfix: A mind trapped by a cortical borer can now understand things it could + understand when normally in its body. + - rscadd: Changes chemistry's welding tank to a wall-mounted version, to increase + the room available. + - rscadd: You can now gib butterflies and lizards with a knife + - rscadd: Ghosts can now follow mecha + - bugfix: You can now access an R&D console by emagging it - it did nothing before. + - bugfix: Walls will now properly smooth and show damage. + - bugfix: Fixes the dialog that occurs when the AI shuts off to actually do what + it says it does + Fox McCloud: + - bugfix: Fixes not being able to attach IEDs to beartraps + - bugfix: Can no longer spamclick someone to death using headslamming on a toilet/urimal + - tweak: Toilet/urinal headslamming now plays a sound + - tweak: Toilet headslamming damage reduced slightly + - rscadd: Can now fill open reagent containers in a toilet to receive "toilet water". + - tweak: No more message spam when someone fills a container using a sink + - rscadd: Can now wash your face using a sink, which washes away lipstick and wakes + you up slightly + - tweak: Washing things will now use progress bars + - tweak: Ensures consuming a single syndicate donk pocket won't get you addicted + to meth + - tweak: Kinetic Accelerators and E-bows automatically reload + Glorken: + - rscadd: Added a Knight Arena for Holodeck. + - imageadd: Added red and blue claymore sprites. + - spellcheck: Changed overrided to overrode when emagging Holodeck computer. + KasparoVy: + - rscadd: Vox versions of the Officer SWAT sechailer + HOS SWAT sechailer + Warden + SWAT sechailer. + - rscadd: Resprited versions of most Human masks to fit Unathi, Tajara and Vulpkanin. + - rscadd: Warden now gets their own version of the SWAT sechailer in their locker. + - tweak: HOS now gets the appropriate version of the SWAT sechailer in their locker. + - tweak: Repositioned smokeables now available for Vox, Unathi, Tajara and Vulpkanin. + - tweak: Properly shades Vox bandana down-state sprites. + - rscadd: Readds Tajaran bald hairstyle. + - rscadd: Alternate style of non-Human breath mask (incl. surgical/sterile mask) + down-state positioning. + - tweak: Corrects all non-Human species' breath mask (incl. surgical/sterile mask) + down-state icons to use the right position style. + - tweak: Minor adjustments to Tajaran breath mask up-state sprites. + PPI: + - rscadd: Adds a reconnect button to the File menu in the client. + - rscadd: Adds head patting + Regen: + - tweak: Powersink can now drain a lot more power before going boom + - tweak: Buffed the powersinks drain rate + - tweak: Buffed explosion from an overloaded powersink, try to find it instead of + overloading the grid. + - rscadd: Admin log warning before the powersink explodes + Spacemanspark: + - rscadd: Miners can now utilize the power of mob capsules to take along their lazarus + injected mining creatures! + - rscadd: Store your Pokemo- er, sorry, I mean mining mobs that you've captured + in the lazarus capsule belt. + Tastyfish: + - bugfix: Species that don't breathe can kill themselves now! + - rscadd: Suicide messages are now catered to your species. + - tweak: Shortened the default pill & patch name when using the ChemMaster. + - rscadd: The chaplain now has a service radio headset, as Space Jesus intended. + TheDZD: + - tweak: When Ahelping, "Question" is now "Mentorhelp" and "Player Complaint" is + now "Adminhelp." + - tweak: Mentorhelps and PM replies from mentors appear in a bold aqua blue color. + - tweak: Adminhelps and PM replies from admins appear in a bold bright red color. + - tweak: PM replies from players appear in a dull/dark purple color. + - rscadd: Adds admin attack log to players being converted to cult. + - rscadd: Adds shadowling thrall jobbans. + - rscadd: Jobbanned players who are converted to shadowling thrall, revolutionary, + or cultist will have the control of their body offered up to eligible ghosts. +2016-02-13: + Crazylemon64: + - tweak: Relaxes the check on what atoms you can follow to any movable atom + - tweak: Mages are now more ragin + - tweak: Admins can now adjust the total number of wizards at runtime by tweaking + either max_mages, or players_per mage + DaveTheHeadcrab: + - rscadd: Adds new worn icons for duffelbags to better reflect their size, compliments + of WJohn at /tg/ + FalseIncarnate: + - rscadd: Adds burritos, made from cutlets, beans, rice, capsacin oil (hotsauce), + cheese, and flat dough (because we lack proper tortillas) in the microwave. + - rscadd: Adds chimichangas. You know you want a deep-fried burrito. + Fox McCloud: + - tweak: Updates some spell icons with better/higher quality icons + - tweak: Updates unarmed attacks to allow for more customization + - tweak: Updates martial arts so they factor in specie's attack messages and sounds + - tweak: Re-balances Sleeping Carp fighting style + - tweak: Re-balances Bo Staff + - tweak: 'Rebalances Golem: they should now be spaceproof, fire+cold proof, rad + proof, virus immune, clonable, parapen+syringe gun immune, deal increased melee + damage. Their armor has been reduced to 55 melee across the board, their slip + immunity removed, pain immunity removed, and they''re slightly slower' + - bugfix: Fixes Ei Nath generating two brains + - bugfix: Ensures the Necromatic Stone generates actual skeletons + - bugfix: Can now strip PDA/IDs from Golems + - bugfix: Fixes sleeping carp grab not being an instant aggressive grab + - bugfix: Fixes an exploit with declaring war on the station + KasparoVy: + - rscadd: Orange and purple bandanas for all station species. + - rscadd: The ability to colour bandanas with a crayon in a washing machine. + - tweak: Refactors the bandana adjustment system. + - tweak: Minor adjustments to Tajaran and Unathi bandana east/west sprites. + - tweak: Adjusting a bandana will now take if off of your head/face and put it in + an available hand. If both hands are available, it goes in the selected hand. + - bugfix: Adjusting a coloured bandana will no longer revert it to the original + coloured icons anymore. + - bugfix: Adjusting a bandana from mask-style to hat-style means the bandana won't + obscure your identity anymore. + - rscadd: Greys now use re-positioned smokeables. They no longer smoke out the eyes. + TheDZD: + - bugfix: Fixes spacepods being able to shoot through walls. + - tweak: Lowers spacepod weapons fire delay. + - tweak: Increases spacepod weapons energy costs. + - tweak: Makes spacepods move at speeds not rivaling those of photon beams. They + are now a hair bit faster than a person with a jetpack. + - tweak: Reduces battery costs for spacepod movement. +2016-02-24: + Crazylemon64: + - tweak: The defib should be more reliable on people who have ghosted + - tweak: The defib will now give a message if the ghost is still haunting about + - rscadd: Attacking someone with an accessory will now let you put things on them + without having to strip them. + - bugfix: Borers will now properly detach upon death of a mob they are controlling + - tweak: Borers can now see their chemical count while in control of a mob + - rscadd: Borers can now silently communicate with their host - this is not available + to the host until the borer has either begun to communicate, or has taken control + at least once - this is to avoid spoiling that the borer exists + - tweak: Borers won't be able to talk out loud inside of a host, by default - they + can remove this safeguard with a verb under their borer tab. Borer hivespeak + is unaffected. + - tweak: Borers infesting and hiding are now silent. + - tweak: Made borer's chem lists more nicely formatted + - bugfix: No more superspeed attacking simplemobs + - tweak: New players now show up properly under the "who" verb when used as an admin + - rscadd: Mining drones will now automatically collect sand lying around + - bugfix: RIPLEYs can now drill asteroid turfs for sand + - rscadd: You can now load exosuit fuel generators with items containing their material + - this means you can fuel yourself off of ores, but this will be highly inefficient + and cost you mining points later on, as you can't take fuel back out. + - rscadd: You can now load the fuel generators from an ore box. + - tweak: The plasma generator now produces 3x as much power from the same amount + of fuel - this lets it even remotely compete with the uranium generator. + - tweak: You can now light cigarettes off of burning mobs. + - tweak: Exosuit tracking beacons now fit in boxes - prior, they were far too large + for even a backpack, as they shared the same size as all other mecha equipment + - tweak: Miners can now collect ore by walking over it with an ore satchel on. + FalseIncarnate: + - rscadd: Adds prize tickets as a replacement for physical arcade prizes. + - rscadd: Adds a buildable prize counter to exchange tickets for prizes. + - rscadd: Adds a bike. Despite what Prof. Oak might claim, you can ride it indoors. + - rscadd: Adds colorful wallets, for that old school arcade pride. + - bugfix: Fixes accidental removal of plump helmet biscuit recipe. + - rscadd: Temporarily adds a prize counter to the bar (Cyberiad) or dorms (MetaStation), + and adds a max upgrade one to the Ninja Holding Area (Cyberiad z2) + - bugfix: Fixes Metastation. Seriously fixed a lot, just read the PR description + for the full list. + FlattestGuitar: + - rscadd: Adds IPC alcohol and a few derivative drinks + - tweak: IPCs can now drink and be fed from glasses + Fox McCloud: + - tweak: Laser eyes mutation no longer drains nutrition + - tweak: 'splits the EMP kit into two things: the standard EMP kit (2 grenades and + an implant), and the EMP flashlight by itself' + - tweak: nerfs heart attacks so they do less damage + - tweak: Pickpocket gloves now put the item you strip into your hands as opposed + to the floor + - tweak: Picketpocket gloves can now silently strip accessories + - tweak: Pickpocket gloves will no longer give a message for messing up a pickpocket + KasparoVy: + - bugfix: Adjusting masks while they are not on the face will no longer turn off + internals. + - bugfix: Adjusting masks while they are not on the face will now cause the mask + to hide/reveal the wearer's identity the next time it's worn as intended. + - rscadd: Adds the ability to open/close bomber jackets. + - rscadd: Adds a security bomber jacket. This jacket inherits the protection and + storage capabilities as a standard Security vest with additional bomber jacket + benefits. + - rscadd: Adds UI button in top left of screen for jacket adjustment. + - tweak: Replaces the standard bomber jacket in the Pod Pilot bay with the Security + version. + - tweak: Centralizes jacket/coat adjustment handling. + - tweak: All jackets start closed by default. + - rscadd: Geneticist duffelbag on-mob sprite (for all species). + - rscadd: Vox-fitted backpacks, satchels, ERT backpacks, duffelbags and defib unit. + - tweak: Refactors back-item icon generation. + - bugfix: Typo in the description of Santa's sack. + - bugfix: Missing punctuation and gender macros in the description of the bag of + holding. + - bugfix: The tweak to back-icon generation fixes a bug where the wrong sprite name + was being used to generate back-item icons. + PPI: + - rscadd: Adds the ability to hide papers in vents. You can now leave a romantic + love letter, exchange information in secret, or hide papers infused with the + power of nar'sie from sight. + Regen1: + - rscadd: Adds the Immolator laser gun, a modified laser gun with 8 shots that will + ignite mobs, can be made in R&D + Spacemanspark: + - rscadd: Adds *yes and *no emotes to Synthetics. Glory to Synthetica. + Tastyfish: + - tweak: The PDA system has been completely redone behind the scenes! It should + be functionally similar, although there is now a Home and Back button at the + bottom as appropriate. + - rscadd: All of the heads now have multicolored pens. + - rscadd: EngiVend now has 10 camera assemblies. + - tweak: Borgs can now use vending machines. + - rscadd: There are now picture frames that can be made from the autolathe or wood + planks for papers, photos, posters, and canvases! + pinatacolada: + - tweak: Makes the Protect Station AI law board no longer consider people that damage + the station crew, instead of human + ppi: + - tweak: When revealed Revenants will not be able to move at the maximum move speed, + nor be able to pass through any solid object, like walls, windows, grills, computers + and mechs. +2016-02-26: + FalseIncarnate: + - tweak: Chocolate can now make you fat, as expected. + Fox McCloud: + - tweak: stamina damage now regenerates slightly faster + - rscadd: Adds in whetstones for sharpening objects + - tweak: Kitchen vendor starts off with 5 salt+pepper shakers + - tweak: Can now point while lying or buckled + - bugfix: Fixes Capulettium Plus not silencing + - bugfix: Fixes slurring, stuttering, drugginess, and silences last half of what + they should + KasparoVy: + - bugfix: Jackets that start open are recognized as actually being open already + now. This fixes a bug with certain items that don't have an open state, or cases + where it ended up giving an item the wrong icon (one that didn't exist) + Spacemanspark: + - bugfix: Fixes synthetics from giving off the proper message in the chat box when + using the *yes and *no emotes. + Tastyfish: + - rscadd: Wheelchairs, janicarts, and ambulances can now go through doors according + to the user's driver's access. diff --git a/html/changelogs/AutoChangeLog-pr-3438.yml b/html/changelogs/AutoChangeLog-pr-3438.yml deleted file mode 100644 index 1bf5db185b8..00000000000 --- a/html/changelogs/AutoChangeLog-pr-3438.yml +++ /dev/null @@ -1,7 +0,0 @@ -author: Crazylemon64 -delete-after: True -changes: - - bugfix: "Species with organic limbs and NO_BLOOD will no longer bleed (though still on hit - write that off as \"bone powder\")" - - tweak: "Skeletons now lack internal organs, except for the runic mind which exists in their head - an analogue for the brain" - - rscadd: "Skeletons that drink milk will be regenerated at a moderate pace, have a small chance of mending bones, and will praise the great name of mr skeltal" - - tweak: "Adds a reagent system for species reacting to specific reagents" diff --git a/html/changelogs/AutoChangeLog-pr-3441.yml b/html/changelogs/AutoChangeLog-pr-3441.yml deleted file mode 100644 index 98352b61717..00000000000 --- a/html/changelogs/AutoChangeLog-pr-3441.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: Crazylemon64 -delete-after: True -changes: - - rscadd: "Slime People can now select from all human hairstyles, and their \"hair\" will be tinted a shade of their body." diff --git a/html/changelogs/AutoChangeLog-pr-3455.yml b/html/changelogs/AutoChangeLog-pr-3455.yml deleted file mode 100644 index 404b0cc887f..00000000000 --- a/html/changelogs/AutoChangeLog-pr-3455.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: Glorken -delete-after: True -changes: - - rscadd: "Added a Knight Arena for Holodeck." - - imageadd: "Added red and blue claymore sprites." - - spellcheck: "Changed overrided to overrode when emagging Holodeck computer." diff --git a/html/changelogs/AutoChangeLog-pr-3461.yml b/html/changelogs/AutoChangeLog-pr-3461.yml deleted file mode 100644 index ca27ae1f755..00000000000 --- a/html/changelogs/AutoChangeLog-pr-3461.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: Tastyfish -delete-after: True -changes: - - bugfix: "Species that don't breathe can kill themselves now!" - - rscadd: "Suicide messages are now catered to your species." diff --git a/html/changelogs/AutoChangeLog-pr-3462.yml b/html/changelogs/AutoChangeLog-pr-3462.yml deleted file mode 100644 index be27197c72a..00000000000 --- a/html/changelogs/AutoChangeLog-pr-3462.yml +++ /dev/null @@ -1,9 +0,0 @@ -author: KasparoVy -delete-after: True -changes: - - rscadd: "Vox versions of the Officer SWAT sechailer + HOS SWAT sechailer + Warden SWAT sechailer." - - rscadd: "Resprited versions of most Human masks to fit Unathi, Tajara and Vulpkanin." - - rscadd: "Warden now gets their own version of the SWAT sechailer in their locker." - - tweak: "HOS now gets the appropriate version of the SWAT sechailer in their locker." - - tweak: "Repositioned smokeables now available for Vox, Unathi, Tajara and Vulpkanin." - - tweak: "Properly shades Vox bandana down-state sprites." diff --git a/html/changelogs/AutoChangeLog-pr-3480.yml b/html/changelogs/AutoChangeLog-pr-3480.yml deleted file mode 100644 index 353d01afd32..00000000000 --- a/html/changelogs/AutoChangeLog-pr-3480.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: Crazylemon64 -delete-after: True -changes: - - tweak: "Increases the frequency of the cortical borer event." diff --git a/html/changelogs/AutoChangeLog-pr-3485.yml b/html/changelogs/AutoChangeLog-pr-3485.yml deleted file mode 100644 index 208bf40efeb..00000000000 --- a/html/changelogs/AutoChangeLog-pr-3485.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: Crazylemon64 -delete-after: True -changes: - - tweak: "People with borers cannot commit suicide - this applies to a controlling borer, too." - - tweak: "Borers can no longer overdose their hosts." - - tweak: "Borers can now inject Saline-Glucose, Spaceacillin, Hydrocodone, Mitocholide, Salbutamol, Capulettium+, and Charcoal. Styptic was removed, as it's pathetic at healing when directly injected. Salicyclic acid was removed too, as its functionality is duplicated by both hydrocodone and saline-glucose." diff --git a/html/changelogs/AutoChangeLog-pr-3639.yml b/html/changelogs/AutoChangeLog-pr-3639.yml new file mode 100644 index 00000000000..26ff551f761 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3639.yml @@ -0,0 +1,6 @@ +author: Crazylemon64 +delete-after: True +changes: + - rscadd: "People with VAREDIT can now write matrix variables" + - rscadd: "People with VAREDIT can now modify path variables" + - tweak: "Refactors the variable editor code somewhat." diff --git a/html/changelogs/AutoChangeLog-pr-3721.yml b/html/changelogs/AutoChangeLog-pr-3721.yml new file mode 100644 index 00000000000..bf75540c480 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3721.yml @@ -0,0 +1,6 @@ +author: Fox McCloud +delete-after: True +changes: + - bugfix: "Fixes the \"yeah\" glasses so the sound doesn't vary and a message is displayed, on use" + - bugfix: "Noir mode only activates when the glasses are equipped to your actual eyes" + - rscadd: "Noir Glasses mode can be toggled on or off (defaults to off)" diff --git a/html/changelogs/AutoChangeLog-pr-3722.yml b/html/changelogs/AutoChangeLog-pr-3722.yml new file mode 100644 index 00000000000..aa88b58c820 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3722.yml @@ -0,0 +1,5 @@ +author: Tastyfish +delete-after: True +changes: + - tweak: "Infrared emitters can now be rotated while already in an assembly via the UI popup." + - tweak: "The infrared emitter can no longer be hidden inside of boxes and still work." diff --git a/html/changelogs/AutoChangeLog-pr-3724.yml b/html/changelogs/AutoChangeLog-pr-3724.yml new file mode 100644 index 00000000000..57bd1d0ade5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3724.yml @@ -0,0 +1,8 @@ +author: KasparoVy +delete-after: True +changes: + - tweak: "Jackets who have the verb available but are not intended to be adjusted will not have the action button available." + - bugfix: "You can now adjust breath masks while buckled into beds and chairs." + - bugfix: "Known issues with adjusted jackets using the wrong sprites." + - rscadd: "Blueshield coat in hand and item icons." + - rscadd: "Hulks now rip apart adjustable and droppable jackets. The items stored in the jackets get dropped on the ground." diff --git a/html/changelogs/AutoChangeLog-pr-3725.yml b/html/changelogs/AutoChangeLog-pr-3725.yml new file mode 100644 index 00000000000..2213cdb85d9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3725.yml @@ -0,0 +1,4 @@ +author: Tastyfish +delete-after: True +changes: + - rscadd: "The beach now has a border and is splashier." diff --git a/html/changelogs/AutoChangeLog-pr-3728.yml b/html/changelogs/AutoChangeLog-pr-3728.yml new file mode 100644 index 00000000000..a84a87eefa4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3728.yml @@ -0,0 +1,4 @@ +author: FalseIncarnate +delete-after: True +changes: + - tweak: "Water Balloons can be filled from more sources than just beakers and watertanks." diff --git a/html/changelogs/AutoChangeLog-pr-3736.yml b/html/changelogs/AutoChangeLog-pr-3736.yml new file mode 100644 index 00000000000..64d251036fe --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3736.yml @@ -0,0 +1,10 @@ +author: Fox McCloud +delete-after: True +changes: + - bugfix: "Mimes can no longer use spells and continue speaking" + - tweak: "Mime abilities are now spells with proper icons" + - tweak: "Mime wall now last 30 seconds, up from 5" + - tweak: "forecfields/invisible walls now block air currents" + - rscadd: "Adds the Sleeping Carp scroll to the uplink for 17 TC" + - bugfix: "Fixes Shadowlings being able to use guns" + - bugfix: "Fixes sleeping carp scroll users being able to use guns" diff --git a/html/changelogs/AutoChangeLog-pr-3740.yml b/html/changelogs/AutoChangeLog-pr-3740.yml new file mode 100644 index 00000000000..e2126e6d2dc --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3740.yml @@ -0,0 +1,8 @@ +author: Crazylemon64 +delete-after: True +changes: + - rscadd: "The buildmode area tool now shows reticules of what you've selected." + - bugfix: "Switching mobs while using the buildmode tool no longer screws up your UI." + - tweak: "Refactors buildmode so it's no longer a special-case system." + - rscadd: "Adds a copy mode to build mode, which lets you duplicate objects." + - tweak: "Any mob in buildmode can work at the fastest possible rate." diff --git a/html/changelogs/AutoChangeLog-pr-3744.yml b/html/changelogs/AutoChangeLog-pr-3744.yml new file mode 100644 index 00000000000..b4ae4e5af9d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3744.yml @@ -0,0 +1,9 @@ +author: Crazylemon64 +delete-after: True +changes: + - bugfix: "Fixed a problem where the icons of a person would not correctly update when changing gender." + - tweak: "One's hairstyle only adjusts on gender change if it's incompatible with your new gender." + - bugfix: "Fixed a bug where a person's icon would only be updated if their sprite had a new layer added or removed." + - bugfix: "You no longer lose your name when monkeyized and reverted - you'll still look like a monkey while you're a monkey, though." + - bugfix: "Your organs will now match your gender when you are cloned." + - bugfix: "Skeletons (when a body rots) no longer retain a fleshy torso." diff --git a/html/changelogs/AutoChangeLog-pr-3751.yml b/html/changelogs/AutoChangeLog-pr-3751.yml new file mode 100644 index 00000000000..04a8fd75198 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3751.yml @@ -0,0 +1,5 @@ +author: Crazylemon64 +delete-after: True +changes: + - bugfix: "Putting people in an active cryotube now produces the message on insertion, rather than release." + - bugfix: "An EMP'd cloning pod will now display its sprites correctly." diff --git a/html/changelogs/AutoChangeLog-pr-3757.yml b/html/changelogs/AutoChangeLog-pr-3757.yml new file mode 100644 index 00000000000..4837e456b8a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3757.yml @@ -0,0 +1,4 @@ +author: Tastyfish +delete-after: True +changes: + - tweak: "The ethanol-based neurotoxin drink is now called Neuro-toxin to avoid being confused with the deadly toxin." diff --git a/html/changelogs/AutoChangeLog-pr-3760.yml b/html/changelogs/AutoChangeLog-pr-3760.yml new file mode 100644 index 00000000000..87b7f1c7a79 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3760.yml @@ -0,0 +1,5 @@ +author: Fox McCloud +delete-after: True +changes: + - bugfix: "Fixes the Experimentor throwing one item at a time" + - tweak: "Experimentor menu now automatically refreshes after use" diff --git a/html/changelogs/VampyrBytes-pr-3748.yml b/html/changelogs/VampyrBytes-pr-3748.yml new file mode 100644 index 00000000000..a60fdda062d --- /dev/null +++ b/html/changelogs/VampyrBytes-pr-3748.yml @@ -0,0 +1,36 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. Remove the quotation mark and put in your name when copy+pasting the example changelog. +author: VampyrBytes + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit. +# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog. +changes: + - bugfix: "Fixes emotes ending with s needing 2. Emotes now work with grammatical options eg ping or pings, squish or squishes" + - tweak: "Updated emote help with missing emotes. Help will also show any species specific emotes for your current species" diff --git a/icons/misc/beach.dmi b/icons/misc/beach.dmi index bb6b942e0dd..2b3e9760af4 100644 Binary files a/icons/misc/beach.dmi and b/icons/misc/beach.dmi differ diff --git a/icons/misc/buildmode.dmi b/icons/misc/buildmode.dmi index beed381e391..ca9d1fd05cc 100644 Binary files a/icons/misc/buildmode.dmi and b/icons/misc/buildmode.dmi differ diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi index 57d17caaa46..814d9bf3153 100644 Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi index 6f24676144a..988ebe78eea 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 38b7f17c679..70aa813cbb8 100644 Binary files a/icons/mob/belt.dmi and b/icons/mob/belt.dmi differ diff --git a/icons/mob/feet.dmi b/icons/mob/feet.dmi index e13cab2b876..c493ef8c94b 100644 Binary files a/icons/mob/feet.dmi and b/icons/mob/feet.dmi differ diff --git a/icons/mob/human_face.dmi b/icons/mob/human_face.dmi index 7eec478d96b..83dfb8e81e6 100644 Binary files a/icons/mob/human_face.dmi and b/icons/mob/human_face.dmi differ diff --git a/icons/mob/inhands/clothing_lefthand.dmi b/icons/mob/inhands/clothing_lefthand.dmi index 0231c8122d9..035a015dd1c 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 97d0e9c0d5a..e0a47cf1b9a 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/guns_lefthand.dmi b/icons/mob/inhands/guns_lefthand.dmi index 1d0f86b5842..e7571df2d11 100644 Binary files a/icons/mob/inhands/guns_lefthand.dmi and b/icons/mob/inhands/guns_lefthand.dmi differ diff --git a/icons/mob/inhands/guns_righthand.dmi b/icons/mob/inhands/guns_righthand.dmi index f5d84cb5f0e..cdd8499b590 100644 Binary files a/icons/mob/inhands/guns_righthand.dmi and b/icons/mob/inhands/guns_righthand.dmi differ diff --git a/icons/mob/mask.dmi b/icons/mob/mask.dmi index d839e71c4d7..d6dacdce500 100644 Binary files a/icons/mob/mask.dmi and b/icons/mob/mask.dmi differ diff --git a/icons/mob/screen_gen.dmi b/icons/mob/screen_gen.dmi index 7d1cd453ed5..431f1df9ddb 100644 Binary files a/icons/mob/screen_gen.dmi and b/icons/mob/screen_gen.dmi differ diff --git a/icons/mob/species/grey/mask.dmi b/icons/mob/species/grey/mask.dmi new file mode 100644 index 00000000000..27785b33141 Binary files /dev/null and b/icons/mob/species/grey/mask.dmi differ diff --git a/icons/mob/species/tajaran/mask.dmi b/icons/mob/species/tajaran/mask.dmi index 0b046910f48..9c3339e29e0 100644 Binary files a/icons/mob/species/tajaran/mask.dmi and b/icons/mob/species/tajaran/mask.dmi differ diff --git a/icons/mob/species/unathi/mask.dmi b/icons/mob/species/unathi/mask.dmi index 80b212e9008..a37b45b4e96 100644 Binary files a/icons/mob/species/unathi/mask.dmi and b/icons/mob/species/unathi/mask.dmi differ diff --git a/icons/mob/species/vox/back.dmi b/icons/mob/species/vox/back.dmi new file mode 100644 index 00000000000..6ab32288475 Binary files /dev/null and b/icons/mob/species/vox/back.dmi differ diff --git a/icons/mob/species/vox/mask.dmi b/icons/mob/species/vox/mask.dmi index 632ffe24c6f..df31a6851ae 100644 Binary files a/icons/mob/species/vox/mask.dmi and b/icons/mob/species/vox/mask.dmi differ diff --git a/icons/mob/species/vox/shoes.dmi b/icons/mob/species/vox/shoes.dmi index c56d9f1124f..2e6b182ceb2 100644 Binary files a/icons/mob/species/vox/shoes.dmi and b/icons/mob/species/vox/shoes.dmi differ diff --git a/icons/mob/species/vulpkanin/mask.dmi b/icons/mob/species/vulpkanin/mask.dmi index 86c84471a08..37aedd13592 100644 Binary files a/icons/mob/species/vulpkanin/mask.dmi and b/icons/mob/species/vulpkanin/mask.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index 0ac8cffa837..31efd6b1d8b 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/obj/arcade.dmi b/icons/obj/arcade.dmi index 50f8e800273..9861aea35c9 100644 Binary files a/icons/obj/arcade.dmi and b/icons/obj/arcade.dmi differ diff --git a/icons/obj/bureaucracy.dmi b/icons/obj/bureaucracy.dmi index 159d2f572f2..1bd8373670c 100644 Binary files a/icons/obj/bureaucracy.dmi and b/icons/obj/bureaucracy.dmi differ diff --git a/icons/obj/clothing/belts.dmi b/icons/obj/clothing/belts.dmi index 85d9cffdbfc..7427f32fd3e 100644 Binary files a/icons/obj/clothing/belts.dmi and b/icons/obj/clothing/belts.dmi differ diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi index 9bd0199de51..1e033f6746d 100644 Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ diff --git a/icons/obj/clothing/shoes.dmi b/icons/obj/clothing/shoes.dmi index 56a2195ad69..148bf8b21a1 100644 Binary files a/icons/obj/clothing/shoes.dmi and b/icons/obj/clothing/shoes.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index 988f0153964..1f0ca57476f 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/contraband.dmi b/icons/obj/contraband.dmi index 4a187225cd3..91432c14d1a 100644 Binary files a/icons/obj/contraband.dmi and b/icons/obj/contraband.dmi differ diff --git a/icons/obj/decals.dmi b/icons/obj/decals.dmi index f69d1560cb7..13913aae9bd 100644 Binary files a/icons/obj/decals.dmi and b/icons/obj/decals.dmi differ diff --git a/icons/obj/drinks.dmi b/icons/obj/drinks.dmi index 5bb37da57df..4ec1ce7cc3b 100644 Binary files a/icons/obj/drinks.dmi and b/icons/obj/drinks.dmi differ diff --git a/icons/obj/food/food.dmi b/icons/obj/food/food.dmi index f8728eb6ab3..b2ff355592b 100644 Binary files a/icons/obj/food/food.dmi and b/icons/obj/food/food.dmi differ diff --git a/icons/obj/gun.dmi b/icons/obj/gun.dmi index d2eca5637a7..00bd10b184a 100644 Binary files a/icons/obj/gun.dmi and b/icons/obj/gun.dmi differ diff --git a/icons/obj/kitchen.dmi b/icons/obj/kitchen.dmi index 68ccb9f003e..328cc04d001 100644 Binary files a/icons/obj/kitchen.dmi and b/icons/obj/kitchen.dmi differ diff --git a/icons/obj/mobcap.dmi b/icons/obj/mobcap.dmi new file mode 100644 index 00000000000..829593a2849 Binary files /dev/null and b/icons/obj/mobcap.dmi differ diff --git a/icons/obj/objects.dmi b/icons/obj/objects.dmi index af2b1274097..3ec5db973f5 100644 Binary files a/icons/obj/objects.dmi and b/icons/obj/objects.dmi differ diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi index 111bc8d2061..34c75f5ac8b 100644 Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi index dfef3e3dcbd..42379ff68b6 100644 Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ diff --git a/icons/obj/wallets.dmi b/icons/obj/wallets.dmi new file mode 100644 index 00000000000..0a96bc16f5c Binary files /dev/null and b/icons/obj/wallets.dmi differ diff --git a/icons/turf/areas.dmi b/icons/turf/areas.dmi index 292e13cb2ec..cb1c5e0ded3 100755 Binary files a/icons/turf/areas.dmi and b/icons/turf/areas.dmi differ diff --git a/icons/turf/floors.dmi b/icons/turf/floors.dmi index 18dd60eb768..8e7e4d25454 100644 Binary files a/icons/turf/floors.dmi and b/icons/turf/floors.dmi differ diff --git a/icons/vehicles/motorcycle.dmi b/icons/vehicles/motorcycle.dmi index 8b5a004fa5d..2f3c2d5517f 100644 Binary files a/icons/vehicles/motorcycle.dmi and b/icons/vehicles/motorcycle.dmi differ diff --git a/interface/skin.dmf b/interface/skin.dmf index b227491cf6a..c3d9f693726 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -1374,6 +1374,15 @@ menu "menu" group = "" is-disabled = false saved-params = "is-checked" + elem + name = "&Reconnect" + command = ".reconnect" + category = "&File" + is-checked = false + can-check = false + group = "" + is-disabled = false + saved-params = "is-checked" elem name = "" command = "" diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm index caa1f6950af..b045e1adbdc 100644 --- a/interface/stylesheet.dm +++ b/interface/stylesheet.dm @@ -19,10 +19,14 @@ em {font-style: normal; font-weight: bold;} .looc {color: #6699CC;} .adminobserverooc {color: #0099cc; font-weight: bold;} .adminooc {color: #b82e00; font-weight: bold;} +.mentorhelp {color: #0077bb; font-weight: bold;} +.adminhelp {color: #aa0000; font-weight: bold;} .adminobserver {color: #996600; font-weight: bold;} .admin {color: #386aff; font-weight: bold;} +.playerreply {color: #8800bb; font-weight: bold;} + .name { font-weight: bold;} .say {} @@ -54,6 +58,7 @@ h1.alert, h2.alert {color: #000000;} .disarm {color: #990000;} .passive {color: #660000;} +.biggerdanger {color: #ff0000; font-weight: bold; font-size: 5;} .userdanger {color: #ff0000; font-weight: bold; font-size: 3;} .danger {color: #ff0000; font-weight: bold;} .warning {color: #ff0000; font-style: italic;} diff --git a/nano/assets/nano.js b/nano/assets/nano.js index 9ae1ecc460a..030468c4940 100644 --- a/nano/assets/nano.js +++ b/nano/assets/nano.js @@ -1 +1 @@ -function NanoStateDefaultClass(){this.key="default",this.key=this.key.toLowerCase(),NanoStateManager.addState(this)}function NanoStateClass(){}var NanoUtility=function(){var e={};return{init:function(){var t=$("body");e=t.data("urlParameters")},generateHref:function(t){var n="?";for(var a in e)e.hasOwnProperty(a)&&("?"!==n&&(n+=";"),n+=a+"="+e[a]);for(var a in t)t.hasOwnProperty(a)&&("?"!==n&&(n+=";"),n+=a+"="+t[a]);return n},winset:function(e,t,n){var a,r;return null==n&&(n=NanoStateManager.getData().config.window.ref),a={},a[n+"."+e]=t,r=a,location.href=NanoUtility.href("winset",r)},extend:function(e,t){return Object.keys(t).forEach(function(n){var a;return a=t[n],a&&"[object Object]"===Object.prototype.toString.call(a)?(e[n]=e[n]||{},NanoUtility.extend(e[n],a)):e[n]=a}),e},href:function(e,t){return null==e&&(e=""),null==t&&(t={}),e=new Url("byond://"+e),NanoUtility.extend(e.query,t),e},close:function(){var t;return t={command:"nanoclose "+e.src},this.winset("is-visible","false"),location.href=NanoUtility.href("winset",t)}}}();"undefined"==typeof jQuery&&reportError("ERROR: Javascript library failed to load!"),"undefined"==typeof doT&&reportError("ERROR: Template engine failed to load!");var reportError=function(e){window.location="byond://?nano_err="+encodeURIComponent(e),alert(e)};$(document).ready(function(){NanoUtility.init(),NanoStateManager.init(),NanoTemplate.init(),NanoWindow.init()}),Array.prototype.indexOf||(Array.prototype.indexOf=function(e){var t=this.length,n=Number(arguments[1])||0;for(n=0>n?Math.ceil(n):Math.floor(n),0>n&&(n+=t);t>n;n++)if(n in this&&this[n]===e)return n;return-1}),String.prototype.format||(String.prototype.format=function(e){var t=this;return t.replace(String.prototype.format.regex,function(t){var n,a=parseInt(t.substring(1,t.length-1));return n=a>=0?e[a]:-1===a?"{":-2===a?"}":""})},String.prototype.format.regex=new RegExp("{-?[0-9]+}","g")),Object.size=function(e){var t,n=0;for(var t in e)e.hasOwnProperty(t)&&n++;return n},window.console||(window.console={log:function(e){return!1}}),String.prototype.toTitleCase=function(){var e=/^(a|an|and|as|at|but|by|en|for|if|in|of|on|or|the|to|vs?\.?|via)$/i;return this.replace(/([^\W_]+[^\s-]*) */g,function(t,n,a,r){return a>0&&a+n.length!==r.length&&n.search(e)>-1&&":"!==r.charAt(a-2)&&r.charAt(a-1).search(/[^\s-]/)<0?t.toLowerCase():n.substr(1).search(/[A-Z]|\../)>-1?t:t.charAt(0).toUpperCase()+t.substr(1)})},$.ajaxSetup({cache:!1}),Function.prototype.inheritsFrom=function(e){return this.prototype=new e,this.prototype.constructor=this,this.prototype.parent=e.prototype,this},String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),String.prototype.ckey||(String.prototype.ckey=function(){return this.replace(/\W/g,"").toLowerCase()}),NanoStateManager=function(){var e=!1,t=null,n={},a={},r={},o=null,i=function(){t=$("body").data("initialData"),null!=t&&t.hasOwnProperty("config")&&t.hasOwnProperty("data")||reportError("Error: Initial data did not load correctly.");var n="default";t.config.hasOwnProperty("stateKey")&&t.config.stateKey&&(n=t.config.stateKey.toLowerCase()),NanoStateManager.setCurrentState(n),$(document).on("templatesLoaded",function(){l(t),e=!0})},s=function(n){var a;try{a=jQuery.parseJSON(n)}catch(r){return void reportError("recieveUpdateData failed.
      Error name: "+r.name+"
      Error Message: "+r.message)}a.hasOwnProperty("data")||(t&&t.hasOwnProperty("data")?a.data=t.data:a.data={}),e?l(a):t=a},l=function(e){if(null!=o){if(e=o.onBeforeUpdate(e),e===!1)return void reportError("data is false, return");t=e,o.onUpdate(t),o.onAfterUpdate(t)}},c=function(e,t){for(var n in e)e.hasOwnProperty(n)&&jQuery.isFunction(e[n])&&(t=e[n].call(this,t));return t};return{init:function(){i()},receiveUpdateData:function(e){s(e)},addBeforeUpdateCallback:function(e,t){n[e]=t},addBeforeUpdateCallbacks:function(e){for(var t in e)e.hasOwnProperty(t)&&NanoStateManager.addBeforeUpdateCallback(t,e[t])},removeBeforeUpdateCallback:function(e){n.hasOwnProperty(e)&&delete n[e]},executeBeforeUpdateCallbacks:function(e){return c(n,e)},addAfterUpdateCallback:function(e,t){a[e]=t},addAfterUpdateCallbacks:function(e){for(var t in e)e.hasOwnProperty(t)&&NanoStateManager.addAfterUpdateCallback(t,e[t])},removeAfterUpdateCallback:function(e){a.hasOwnProperty(e)&&delete a[e]},executeAfterUpdateCallbacks:function(e){return c(a,e)},addState:function(e){return e instanceof NanoStateClass?e.key?void(r[e.key]=e):void reportError("ERROR: Attempted to add a state with an invalid stateKey"):void reportError("ERROR: Attempted to add a state which is not instanceof NanoStateClass")},setCurrentState:function(e){if("undefined"==typeof e||!e)return reportError("ERROR: No state key was passed!"),!1;if(!r.hasOwnProperty(e))return reportError("ERROR: Attempted to set a current state which does not exist: "+e),!1;var t=o;return o=r[e],null!=t&&t.onRemove(o),o.onAdd(t),!0},getCurrentState:function(){return o},getData:function(){return t}}}(),NanoBaseCallbacks=function(){var e=!0,t={},n={status:function(t){var n;return 2==t.config.status?(n="good",$(".linkActive").removeClass("inactive")):1==t.config.status?(n="average",$(".linkActive").addClass("inactive")):(n="bad",$(".linkActive").addClass("inactive")),$(".statusicon").removeClass("good bad average").addClass(n),$(".linkActive").stopTime("linkPending"),$(".linkActive").removeClass("linkPending"),$(".linkActive").off("click").on("click",function(n){n.preventDefault();var a=$(this).data("href");null!=a&&e&&(e=!1,$("body").oneTime(300,"enableClick",function(){e=!0}),2==t.config.status&&$(this).oneTime(300,"linkPending",function(){$(this).addClass("linkPending")}),window.location.href=a)}),t},nanomap:function(e){return $(".mapIcon").off("mouseenter mouseleave").on("mouseenter",function(e){$("#uiMapTooltip").html($(this).children(".tooltip").html()).show().stopTime().oneTime(5e3,"hideTooltip",function(){$(this).fadeOut(500)})}),$(".zoomLink").off("click").on("click",function(e){e.preventDefault();var t=$(this).data("zoomLevel"),n=$("#uiMap"),a=n.width()*t,r=n.height()*t;n.css({zoom:t,left:"50%",top:"50%",marginLeft:"-"+Math.floor(a/2)+"px",marginTop:"-"+Math.floor(r/2)+"px"})}),$("#uiMapImage").attr("src","nanomap_z"+e.config.mapZLevel+".png"),e}};return{addCallbacks:function(){NanoStateManager.addBeforeUpdateCallbacks(t),NanoStateManager.addAfterUpdateCallbacks(n)},removeCallbacks:function(){for(var e in t)t.hasOwnProperty(e)&&NanoStateManager.removeBeforeUpdateCallback(e);for(var e in n)n.hasOwnProperty(e)&&NanoStateManager.removeAfterUpdateCallback(e)}}}(),NanoBaseHelpers=function(){var e={syndicateMode:function(){return $("body").css("background-color","#8f1414"),$("body").css("background-image","url('uiBackground-Syndicate.png')"),$("body").css("background-position","50% 0"),$("body").css("background-repeat","repeat-x"),$("#uiTitleFluff").css("background-image","url('uiTitleFluff-Syndicate.png')"),$("#uiTitleFluff").css("background-position","50% 50%"),$("#uiTitleFluff").css("background-repeat","no-repeat"),""},combine:function(e,t){return e&&t?e.concat(t):e||t},dump:function(e){return JSON.stringify(e)},link:function(e,t,n,a,r,o){var i="",s="noIcon";"undefined"!=typeof t&&t&&(i='
      ',s="hasIcon"),"undefined"!=typeof r&&r||(r="link");var l="";return"undefined"!=typeof o&&o&&(l='id="'+o+'"'),"undefined"!=typeof a&&a?'":'
      "+i+e+"
      "},xor:function(e,t){return e^t},precisionRound:function(e,t){if(0==t)return Math.round(number);var n=Math.pow(10,t);return Math.round(e*n)/n},round:function(e){return Math.round(e)},fixed:function(e){return Math.round(10*e)/10},floor:function(e){return Math.floor(e)},ceil:function(e){return Math.ceil(e)},string:function(){if(0==arguments.length)return"";if(1==arguments.length)return arguments[0];if(arguments.length>1){stringArgs=[];for(var e=1;et?t>e?e=t:e>n&&(e=n):e>t?e=t:n>e&&(e=n),"undefined"!=typeof a&&a||(a=""),"undefined"!=typeof r&&r||(r="");var o=Math.round((e-t)/(n-t)*100);return'
      '+r+"
      "},dangerToClass:function(e){return 0==e?"good":1==e?"average":"bad"},dangerToSpan:function(e){return 0==e?'"Good"':1==e?'"Minor Alert"':'"Major Alert"'},generateHref:function(e){var t=$("body");_urlParameters=t.data("urlParameters");var n="?";for(var a in _urlParameters)_urlParameters.hasOwnProperty(a)&&("?"!==n&&(n+=";"),n+=a+"="+_urlParameters[a]);for(var a in e)e.hasOwnProperty(a)&&("?"!==n&&(n+=";"),n+=a+"="+e[a]);return n},displayDNABlocks:function(e,t,n,a,r){if(!e)return'
      Please place a valid subject into the DNA modifier.
      ';var o=e.split(""),i='
      ',s=1,l=1;for(var c in o)if(o.hasOwnProperty(c)&&"object"!=typeof o[c]){var u;u="UI"==r.toUpperCase()?{selectUIBlock:s,selectUISubblock:l}:{selectSEBlock:s,selectSESubblock:l};var d="linkActive";s==t&&l==n&&(d="selected"),i+='",c++,c%a==0&&c
      "):l++}return i+="
      "},cMirror:function(e){CodeMirror.fromTextArea(document.getElementById(e),{lineNumbers:!0,indentUnit:4,indentWithTabs:!0,theme:"lesser-dark"})}};return{addHelpers:function(){NanoTemplate.addHelpers(e)},removeHelpers:function(){for(var t in e)e.hasOwnProperty(t)&&NanoTemplate.removeHelper(t)}}}(),NanoStateDefaultClass.inheritsFrom(NanoStateClass);var NanoStateDefault=new NanoStateDefaultClass;NanoStateClass.prototype.key=null,NanoStateClass.prototype.layoutRendered=!1,NanoStateClass.prototype.contentRendered=!1,NanoStateClass.prototype.mapInitialised=!1,NanoStateClass.prototype.isCurrent=function(){return NanoStateManager.getCurrentState()==this},NanoStateClass.prototype.onAdd=function(e){NanoBaseCallbacks.addCallbacks(),NanoBaseHelpers.addHelpers()},NanoStateClass.prototype.onRemove=function(e){NanoBaseCallbacks.removeCallbacks(),NanoBaseHelpers.removeHelpers()},NanoStateClass.prototype.onBeforeUpdate=function(e){return e=NanoStateManager.executeBeforeUpdateCallbacks(e)},NanoStateClass.prototype.onUpdate=function(e){try{(!this.layoutRendered||e.config.hasOwnProperty("autoUpdateLayout")&&e.config.autoUpdateLayout)&&($("#uiLayout").html(NanoTemplate.parse("layout",e)),this.layoutRendered=!0),(!this.contentRendered||e.config.hasOwnProperty("autoUpdateContent")&&e.config.autoUpdateContent)&&($("#uiContent").html(NanoTemplate.parse("main",e)),this.contentRendered=!0),NanoTemplate.templateExists("mapContent")&&(this.mapInitialised||($("#uiMap").draggable(),$("#uiMapTooltip").off("click").on("click",function(e){e.preventDefault(),$(this).fadeOut(400)}),this.mapInitialised=!0),$("#uiMapContent").html(NanoTemplate.parse("mapContent",e)),e.config.hasOwnProperty("showMap")&&e.config.showMap?($("#uiContent").addClass("hidden"),$("#uiMapWrapper").removeClass("hidden")):($("#uiMapWrapper").addClass("hidden"),$("#uiContent").removeClass("hidden"))),NanoTemplate.templateExists("mapHeader")&&$("#uiMapHeader").html(NanoTemplate.parse("mapHeader",e)),NanoTemplate.templateExists("mapFooter")&&$("#uiMapFooter").html(NanoTemplate.parse("mapFooter",e))}catch(t){return void reportError("ERROR: An error occurred while rendering the UI: "+t.message)}},NanoStateClass.prototype.onAfterUpdate=function(e){NanoStateManager.executeAfterUpdateCallbacks(e)},NanoStateClass.prototype.alertText=function(e){alert(e)};var NanoTemplate=function(){var e={},t={},n={},a={},r=function(){e=$("body").data("templateData"),null==e&&reportError("Error: Template data did not load correctly."),o()},o=function(){var t=Object.size(e);if(!t)return void $(document).trigger("templatesLoaded");for(var n in e)if(e.hasOwnProperty(n))return void $.when($.ajax({url:e[n],cache:!1,dataType:"text"})).done(function(t){t+='
      ';try{NanoTemplate.addTemplate(n,t)}catch(a){return void reportError("ERROR: An error occurred while loading the UI: "+a.message)}delete e[n],o()}).fail(function(){reportError("ERROR: Loading template "+n+"("+e[n]+") failed!")})},i=function(){for(var e in t)try{n[e]=doT.template(t[e],null,t)}catch(a){reportError(a.message)}};return{init:function(){r()},addTemplate:function(e,n){t[e]=n},templateExists:function(e){return t.hasOwnProperty(e)},parse:function(e,r){if(!n.hasOwnProperty(e)||!n[e]){if(!t.hasOwnProperty(e))return reportError('ERROR: Template "'+e+'" does not exist in _compiledTemplates!'),"

      Template error (does not exist)

      ";i()}return"function"!=typeof n[e]?(reportError(n[e]),reportError('ERROR: Template "'+e+'" failed to compile!'),"

      Template error (failed to compile)

      "):n[e].call(this,r.data,r.config,a)},addHelper:function(e,t){return jQuery.isFunction(t)?void(a[e]=t):void reportError("NanoTemplate.addHelper failed to add "+e+" as it is not a function.")},addHelpers:function(e){for(var t in e)e.hasOwnProperty(t)&&NanoTemplate.addHelper(t,e[t])},removeHelper:function(e){helpers.hasOwnProperty(e)&&delete a[e]}}}(),NanoWindow=function(){var e,t,n,a,r,o,i=function(e,t){NanoUtility.winset("pos",e+","+t)},s=function(e,t){NanoUtility.winset("size",e+","+t)},l=function(){NanoStateManager.getData().config.user.fancy&&(c(),u(),d(),f())},c=function(){NanoUtility.winset("titlebar",0),NanoUtility.winset("can-resize",0),$(".fancy").show(),$("#uiTitleFluff").css("right","65px")},u=function(){var e=function(){return NanoUtility.close()},t=function(){return NanoUtility.winset("is-minimized","true")};$(".close").on("click",function(t){e()}),$(".minimize").on("click",function(e){t()})},d=function(){$("#uiTitleWrapper").on("mousemove",function(e){p()}),$("#uiTitleWrapper").on("mousedown",function(t){e=!0}),$("#uiTitleWrapper").on("mouseup",function(a){e=!1,t=null,n=null})},p=function(a){var r,o;null==a&&(a=window.event),e&&(null==t&&(t=a.screenX),null==n&&(n=a.screenY),r=a.screenX-t+window.screenLeft,o=a.screenY-n+window.screenTop,i(r,o),t=a.screenX,n=a.screenY)},f=function(){$("#resize").on("mousemove",function(e){m()}),$("#resize").on("mousedown",function(e){a=!0}),$("#resize").on("mouseup",function(e){a=!1})},m=function(){var e,t;null==event&&(event=window.event),a&&(null==r&&(r=event.screenX),null==o&&(o=event.screenY),e=Math.max(150,event.screenX-r+window.innerWidth),t=Math.max(150,event.screenY-o+window.innerHeight),s(e,t),r=event.screenX,o=event.screenY)};return{init:function(){$(document).on("templatesLoaded",function(){l()})}}}(); \ No newline at end of file +function NanoStateDefaultClass(){this.key="default",this.key=this.key.toLowerCase(),NanoStateManager.addState(this)}function NanoStatePDAClass(){this.key="pda",this.key=this.key.toLowerCase(),this.current_template="",NanoStateManager.addState(this)}function NanoStateClass(){}var NanoUtility=function(){var e={};return{init:function(){var t=$("body");e=t.data("urlParameters")},generateHref:function(t){var n="?";for(var a in e)e.hasOwnProperty(a)&&("?"!==n&&(n+=";"),n+=a+"="+e[a]);for(var a in t)t.hasOwnProperty(a)&&("?"!==n&&(n+=";"),n+=a+"="+t[a]);return n},winset:function(e,t,n){var a,r;return null==n&&(n=NanoStateManager.getData().config.window.ref),a={},a[n+"."+e]=t,r=a,location.href=NanoUtility.href("winset",r)},extend:function(e,t){return Object.keys(t).forEach(function(n){var a;return a=t[n],a&&"[object Object]"===Object.prototype.toString.call(a)?(e[n]=e[n]||{},NanoUtility.extend(e[n],a)):e[n]=a}),e},href:function(e,t){return null==e&&(e=""),null==t&&(t={}),e=new Url("byond://"+e),NanoUtility.extend(e.query,t),e},close:function(){var t;return t={command:"nanoclose "+e.src},this.winset("is-visible","false"),location.href=NanoUtility.href("winset",t)}}}();"undefined"==typeof jQuery&&reportError("ERROR: Javascript library failed to load!"),"undefined"==typeof doT&&reportError("ERROR: Template engine failed to load!");var reportError=function(e){window.location="byond://?nano_err="+encodeURIComponent(e),alert(e)};$(document).ready(function(){NanoUtility.init(),NanoStateManager.init(),NanoTemplate.init(),NanoWindow.init()}),Array.prototype.indexOf||(Array.prototype.indexOf=function(e){var t=this.length,n=Number(arguments[1])||0;for(n=0>n?Math.ceil(n):Math.floor(n),0>n&&(n+=t);t>n;n++)if(n in this&&this[n]===e)return n;return-1}),String.prototype.format||(String.prototype.format=function(e){var t=this;return t.replace(String.prototype.format.regex,function(t){var n,a=parseInt(t.substring(1,t.length-1));return n=a>=0?e[a]:-1===a?"{":-2===a?"}":""})},String.prototype.format.regex=new RegExp("{-?[0-9]+}","g")),Object.size=function(e){var t,n=0;for(var t in e)e.hasOwnProperty(t)&&n++;return n},window.console||(window.console={log:function(e){return!1}}),String.prototype.toTitleCase=function(){var e=/^(a|an|and|as|at|but|by|en|for|if|in|of|on|or|the|to|vs?\.?|via)$/i;return this.replace(/([^\W_]+[^\s-]*) */g,function(t,n,a,r){return a>0&&a+n.length!==r.length&&n.search(e)>-1&&":"!==r.charAt(a-2)&&r.charAt(a-1).search(/[^\s-]/)<0?t.toLowerCase():n.substr(1).search(/[A-Z]|\../)>-1?t:t.charAt(0).toUpperCase()+t.substr(1)})},$.ajaxSetup({cache:!1}),Function.prototype.inheritsFrom=function(e){return this.prototype=new e,this.prototype.constructor=this,this.prototype.parent=e.prototype,this},String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),String.prototype.ckey||(String.prototype.ckey=function(){return this.replace(/\W/g,"").toLowerCase()}),NanoStateManager=function(){var e=!1,t=null,n={},a={},r={},o=null,i=function(){t=$("body").data("initialData"),null!=t&&t.hasOwnProperty("config")&&t.hasOwnProperty("data")||reportError("Error: Initial data did not load correctly.");var n="default";t.config.hasOwnProperty("stateKey")&&t.config.stateKey&&(n=t.config.stateKey.toLowerCase()),NanoStateManager.setCurrentState(n),$(document).on("templatesLoaded",function(){l(t),e=!0})},s=function(n){var a;try{a=jQuery.parseJSON(n)}catch(r){return void reportError("recieveUpdateData failed.
      Error name: "+r.name+"
      Error Message: "+r.message)}a.hasOwnProperty("data")||(t&&t.hasOwnProperty("data")?a.data=t.data:a.data={}),e?l(a):t=a},l=function(e){if(null!=o){if(e=o.onBeforeUpdate(e),e===!1)return void reportError("data is false, return");t=e,o.onUpdate(t),o.onAfterUpdate(t)}},c=function(e,t){for(var n in e)e.hasOwnProperty(n)&&jQuery.isFunction(e[n])&&(t=e[n].call(this,t));return t};return{init:function(){i()},receiveUpdateData:function(e){s(e)},addBeforeUpdateCallback:function(e,t){n[e]=t},addBeforeUpdateCallbacks:function(e){for(var t in e)e.hasOwnProperty(t)&&NanoStateManager.addBeforeUpdateCallback(t,e[t])},removeBeforeUpdateCallback:function(e){n.hasOwnProperty(e)&&delete n[e]},executeBeforeUpdateCallbacks:function(e){return c(n,e)},addAfterUpdateCallback:function(e,t){a[e]=t},addAfterUpdateCallbacks:function(e){for(var t in e)e.hasOwnProperty(t)&&NanoStateManager.addAfterUpdateCallback(t,e[t])},removeAfterUpdateCallback:function(e){a.hasOwnProperty(e)&&delete a[e]},executeAfterUpdateCallbacks:function(e){return c(a,e)},addState:function(e){return e instanceof NanoStateClass?e.key?void(r[e.key]=e):void reportError("ERROR: Attempted to add a state with an invalid stateKey"):void reportError("ERROR: Attempted to add a state which is not instanceof NanoStateClass")},setCurrentState:function(e){if("undefined"==typeof e||!e)return reportError("ERROR: No state key was passed!"),!1;if(!r.hasOwnProperty(e))return reportError("ERROR: Attempted to set a current state which does not exist: "+e),!1;var t=o;return o=r[e],null!=t&&t.onRemove(o),o.onAdd(t),!0},getCurrentState:function(){return o},getData:function(){return t}}}(),NanoBaseCallbacks=function(){var e=!0,t={},n={status:function(t){var n;return 2==t.config.status?(n="good",$(".linkActive").removeClass("inactive")):1==t.config.status?(n="average",$(".linkActive").addClass("inactive")):(n="bad",$(".linkActive").addClass("inactive")),$(".statusicon").removeClass("good bad average").addClass(n),$(".linkActive").stopTime("linkPending"),$(".linkActive").removeClass("linkPending"),$(".linkActive").off("click").on("click",function(n){n.preventDefault();var a=$(this).data("href");null!=a&&e&&(e=!1,$("body").oneTime(300,"enableClick",function(){e=!0}),2==t.config.status&&$(this).oneTime(300,"linkPending",function(){$(this).addClass("linkPending")}),window.location.href=a)}),t},nanomap:function(e){return $(".mapIcon").off("mouseenter mouseleave").on("mouseenter",function(e){$("#uiMapTooltip").html($(this).children(".tooltip").html()).show().stopTime().oneTime(5e3,"hideTooltip",function(){$(this).fadeOut(500)})}),$(".zoomLink").off("click").on("click",function(e){e.preventDefault();var t=$(this).data("zoomLevel"),n=$("#uiMap"),a=n.width()*t,r=n.height()*t;n.css({zoom:t,left:"50%",top:"50%",marginLeft:"-"+Math.floor(a/2)+"px",marginTop:"-"+Math.floor(r/2)+"px"})}),$("#uiMapImage").attr("src","nanomap_z"+e.config.mapZLevel+".png"),e}};return{addCallbacks:function(){NanoStateManager.addBeforeUpdateCallbacks(t),NanoStateManager.addAfterUpdateCallbacks(n)},removeCallbacks:function(){for(var e in t)t.hasOwnProperty(e)&&NanoStateManager.removeBeforeUpdateCallback(e);for(var e in n)n.hasOwnProperty(e)&&NanoStateManager.removeAfterUpdateCallback(e)}}}(),NanoBaseHelpers=function(){var e={syndicateMode:function(){return $("body").css("background-color","#8f1414"),$("body").css("background-image","url('uiBackground-Syndicate.png')"),$("body").css("background-position","50% 0"),$("body").css("background-repeat","repeat-x"),$("#uiTitleFluff").css("background-image","url('uiTitleFluff-Syndicate.png')"),$("#uiTitleFluff").css("background-position","50% 50%"),$("#uiTitleFluff").css("background-repeat","no-repeat"),""},combine:function(e,t){return e&&t?e.concat(t):e||t},dump:function(e){return JSON.stringify(e)},link:function(e,t,n,a,r,o){var i="",s="noIcon";"undefined"!=typeof t&&t&&(i='
      ',s="hasIcon"),"undefined"!=typeof r&&r||(r="link");var l="";return"undefined"!=typeof o&&o&&(l='id="'+o+'"'),"undefined"!=typeof a&&a?'":'
      "+i+e+"
      "},xor:function(e,t){return e^t},precisionRound:function(e,t){if(0==t)return Math.round(number);var n=Math.pow(10,t);return Math.round(e*n)/n},round:function(e){return Math.round(e)},fixed:function(e){return Math.round(10*e)/10},floor:function(e){return Math.floor(e)},ceil:function(e){return Math.ceil(e)},string:function(){if(0==arguments.length)return"";if(1==arguments.length)return arguments[0];if(arguments.length>1){stringArgs=[];for(var e=1;et?t>e?e=t:e>n&&(e=n):e>t?e=t:n>e&&(e=n),"undefined"!=typeof a&&a||(a=""),"undefined"!=typeof r&&r||(r="");var o=Math.round((e-t)/(n-t)*100);return'
      '+r+"
      "},dangerToClass:function(e){return 0==e?"good":1==e?"average":"bad"},dangerToSpan:function(e){return 0==e?'"Good"':1==e?'"Minor Alert"':'"Major Alert"'},generateHref:function(e){var t=$("body");_urlParameters=t.data("urlParameters");var n="?";for(var a in _urlParameters)_urlParameters.hasOwnProperty(a)&&("?"!==n&&(n+=";"),n+=a+"="+_urlParameters[a]);for(var a in e)e.hasOwnProperty(a)&&("?"!==n&&(n+=";"),n+=a+"="+e[a]);return n},displayDNABlocks:function(e,t,n,a,r){if(!e)return'
      Please place a valid subject into the DNA modifier.
      ';var o=e.split(""),i='
      ',s=1,l=1;for(var c in o)if(o.hasOwnProperty(c)&&"object"!=typeof o[c]){var u;u="UI"==r.toUpperCase()?{selectUIBlock:s,selectUISubblock:l}:{selectSEBlock:s,selectSESubblock:l};var d="linkActive";s==t&&l==n&&(d="selected"),i+='",c++,c%a==0&&c
      "):l++}return i+="
      "},cMirror:function(e){CodeMirror.fromTextArea(document.getElementById(e),{lineNumbers:!0,indentUnit:4,indentWithTabs:!0,theme:"lesser-dark"})}};return{addHelpers:function(){NanoTemplate.addHelpers(e)},removeHelpers:function(){for(var t in e)e.hasOwnProperty(t)&&NanoTemplate.removeHelper(t)}}}(),NanoStateDefaultClass.inheritsFrom(NanoStateClass);var NanoStateDefault=new NanoStateDefaultClass;NanoStatePDAClass.inheritsFrom(NanoStateClass);var NanoStatePDA=new NanoStatePDAClass;NanoStatePDAClass.prototype.onUpdate=function(e){NanoStateClass.prototype.onUpdate.call(this,e);var t=this;try{if(null!=e.data.app){var n=e.data.app.template;null!=n&&n!=t.current_template?$.when($.ajax({url:n+".tmpl",cache:!1,dataType:"text"})).done(function(a){a+='
      ';try{NanoTemplate.addTemplate("app",a),NanoTemplate.resetTemplate("app"),$("#uiApp").html(NanoTemplate.parse("app",e)),t.current_template=n,t.onAfterUpdate(e)}catch(r){return void reportError("ERROR: An error occurred while loading the PDA App UI: "+r.message)}}).fail(function(){reportError("ERROR: Loading template app("+n+") failed!")}):NanoTemplate.templateExists("app")&&$("#uiApp").html(NanoTemplate.parse("app",e))}}catch(a){return void reportError("ERROR: An error occurred while rendering the PDA App UI: "+a.message)}},NanoStateClass.prototype.key=null,NanoStateClass.prototype.layoutRendered=!1,NanoStateClass.prototype.contentRendered=!1,NanoStateClass.prototype.mapInitialised=!1,NanoStateClass.prototype.isCurrent=function(){return NanoStateManager.getCurrentState()==this},NanoStateClass.prototype.onAdd=function(e){NanoBaseCallbacks.addCallbacks(),NanoBaseHelpers.addHelpers()},NanoStateClass.prototype.onRemove=function(e){NanoBaseCallbacks.removeCallbacks(),NanoBaseHelpers.removeHelpers()},NanoStateClass.prototype.onBeforeUpdate=function(e){return e=NanoStateManager.executeBeforeUpdateCallbacks(e)},NanoStateClass.prototype.onUpdate=function(e){try{(!this.layoutRendered||e.config.hasOwnProperty("autoUpdateLayout")&&e.config.autoUpdateLayout)&&($("#uiLayout").html(NanoTemplate.parse("layout",e)),this.layoutRendered=!0),(!this.contentRendered||e.config.hasOwnProperty("autoUpdateContent")&&e.config.autoUpdateContent)&&($("#uiContent").html(NanoTemplate.parse("main",e)),this.contentRendered=!0),NanoTemplate.templateExists("mapContent")&&(this.mapInitialised||($("#uiMap").draggable(),$("#uiMapTooltip").off("click").on("click",function(e){e.preventDefault(),$(this).fadeOut(400)}),this.mapInitialised=!0),$("#uiMapContent").html(NanoTemplate.parse("mapContent",e)),e.config.hasOwnProperty("showMap")&&e.config.showMap?($("#uiContent").addClass("hidden"),$("#uiMapWrapper").removeClass("hidden")):($("#uiMapWrapper").addClass("hidden"),$("#uiContent").removeClass("hidden"))),NanoTemplate.templateExists("mapHeader")&&$("#uiMapHeader").html(NanoTemplate.parse("mapHeader",e)),NanoTemplate.templateExists("mapFooter")&&$("#uiMapFooter").html(NanoTemplate.parse("mapFooter",e))}catch(t){return void reportError("ERROR: An error occurred while rendering the UI: "+t.message)}},NanoStateClass.prototype.onAfterUpdate=function(e){NanoStateManager.executeAfterUpdateCallbacks(e)},NanoStateClass.prototype.alertText=function(e){alert(e)};var NanoTemplate=function(){var e={},t={},n={},a={},r=function(){e=$("body").data("templateData"),null==e&&reportError("Error: Template data did not load correctly."),o()},o=function(){var t=Object.size(e);if(!t)return void $(document).trigger("templatesLoaded");for(var n in e)if(e.hasOwnProperty(n))return void $.when($.ajax({url:e[n],cache:!1,dataType:"text"})).done(function(t){t+='
      ';try{NanoTemplate.addTemplate(n,t)}catch(a){return void reportError("ERROR: An error occurred while loading the UI: "+a.message)}delete e[n],o()}).fail(function(){reportError("ERROR: Loading template "+n+"("+e[n]+") failed!")})},i=function(){for(var e in t)try{n[e]=doT.template(t[e],null,t)}catch(a){reportError(a.message)}};return{init:function(){r()},addTemplate:function(e,n){t[e]=n},templateExists:function(e){return t.hasOwnProperty(e)},resetTemplate:function(e){n[e]=null},parse:function(e,r){if(!n.hasOwnProperty(e)||!n[e]){if(!t.hasOwnProperty(e))return reportError('ERROR: Template "'+e+'" does not exist in _compiledTemplates!'),"

      Template error (does not exist)

      ";i()}return"function"!=typeof n[e]?(reportError(n[e]),reportError('ERROR: Template "'+e+'" failed to compile!'),"

      Template error (failed to compile)

      "):n[e].call(this,r.data,r.config,a)},addHelper:function(e,t){return jQuery.isFunction(t)?void(a[e]=t):void reportError("NanoTemplate.addHelper failed to add "+e+" as it is not a function.")},addHelpers:function(e){for(var t in e)e.hasOwnProperty(t)&&NanoTemplate.addHelper(t,e[t])},removeHelper:function(e){helpers.hasOwnProperty(e)&&delete a[e]}}}(),NanoWindow=function(){var e,t,n,a,r,o,i=function(e,t){NanoUtility.winset("pos",e+","+t)},s=function(e,t){NanoUtility.winset("size",e+","+t)},l=function(){NanoStateManager.getData().config.user.fancy&&(c(),u(),d(),f())},c=function(){NanoUtility.winset("titlebar",0),NanoUtility.winset("can-resize",0),$(".fancy").show(),$("#uiTitleFluff").css("right","65px")},u=function(){var e=function(){return NanoUtility.close()},t=function(){return NanoUtility.winset("is-minimized","true")};$(".close").on("click",function(t){e()}),$(".minimize").on("click",function(e){t()})},d=function(){$("#uiTitleWrapper").on("mousemove",function(e){p()}),$("#uiTitleWrapper").on("mousedown",function(t){e=!0}),$("#uiTitleWrapper").on("mouseup",function(a){e=!1,t=null,n=null})},p=function(a){var r,o;null==a&&(a=window.event),e&&(null==t&&(t=a.screenX),null==n&&(n=a.screenY),r=a.screenX-t+window.screenLeft,o=a.screenY-n+window.screenTop,i(r,o),t=a.screenX,n=a.screenY)},f=function(){$("#resize").on("mousemove",function(e){m()}),$("#resize").on("mousedown",function(e){a=!0}),$("#resize").on("mouseup",function(e){a=!1})},m=function(){var e,t;null==event&&(event=window.event),a&&(null==r&&(r=event.screenX),null==o&&(o=event.screenY),e=Math.max(150,event.screenX-r+window.innerWidth),t=Math.max(150,event.screenY-o+window.innerHeight),s(e,t),r=event.screenX,o=event.screenY)};return{init:function(){$(document).on("templatesLoaded",function(){l()})}}}(); \ No newline at end of file diff --git a/nano/assets/nanoui.css b/nano/assets/nanoui.css index e99b2f94fd5..b4006f704b1 100644 --- a/nano/assets/nanoui.css +++ b/nano/assets/nanoui.css @@ -1,2 +1,2 @@ @font-face{font-family:FontAwesome;src:url(fontawesome-webfont.eot?v=4.5.0);src:url(fontawesome-webfont.eot?#iefix&v=4.5.0) format('embedded-opentype'),url(fontawesome-webfont.woff2?v=4.5.0) format('woff2'),url(fontawesome-webfont.woff?v=4.5.0) format('woff'),url(fontawesome-webfont.ttf?v=4.5.0) format('truetype'),url(fontawesome-webfont.svg?v=4.5.0#fontawesomeregular) format('svg');font-weight:400;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:a 2s infinite linear;animation:a 2s infinite linear}.fa-pulse{-webkit-animation:a 1s infinite steps(8);animation:a 1s infinite steps(8)}@-webkit-keyframes a{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes a{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0,mirror=1);-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2,mirror=1);-webkit-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-close:before,.fa-remove:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-cog:before,.fa-gear:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-repeat:before,.fa-rotate-right:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-exclamation-triangle:before,.fa-warning:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-cogs:before,.fa-gears:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-floppy-o:before,.fa-save:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-sort:before,.fa-unsorted:before{content:"\f0dc"}.fa-sort-desc:before,.fa-sort-down:before{content:"\f0dd"}.fa-sort-asc:before,.fa-sort-up:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-gavel:before,.fa-legal:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-bolt:before,.fa-flash:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-clipboard:before,.fa-paste:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-chain-broken:before,.fa-unlink:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:"\f150"}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:"\f151"}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:"\f152"}.fa-eur:before,.fa-euro:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-inr:before,.fa-rupee:before{content:"\f156"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:"\f157"}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:"\f158"}.fa-krw:before,.fa-won:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-try:before,.fa-turkish-lira:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-bank:before,.fa-institution:before,.fa-university:before{content:"\f19c"}.fa-graduation-cap:before,.fa-mortar-board:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:"\f1c5"}.fa-file-archive-o:before,.fa-file-zip-o:before{content:"\f1c6"}.fa-file-audio-o:before,.fa-file-sound-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-empire:before,.fa-ge:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-paper-plane:before,.fa-send:before{content:"\f1d8"}.fa-paper-plane-o:before,.fa-send-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-bed:before,.fa-hotel:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-y-combinator:before,.fa-yc:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-television:before,.fa-tv:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"} -.displayBar{position:relative;width:236px;height:16px;border:1px solid #666;float:left;margin:0 5px 0 0;overflow:hidden;background:#000}.displayBarText{position:absolute;top:-2px;left:5px;width:100%;height:100%;color:#fff;font-weight:400}.displayBarFill{width:0;height:100%;background:#40628a;overflow:hidden;float:left}.displayBarFill.alignRight{float:right}.displayBarFill.good{color:#fff;background:#4f7529}.displayBarFill.notgood{color:#fff;background:#ffb400}.displayBarFill.average{color:#fff;background:#cd6500}.displayBarFill.bad{color:#fff;background:#e00}.displayBarFill.highlight{color:#fff;background:#8ba5c4}.disabled,.link,.linkOff,.linkOn,.redButton,.selected,.yellowButton{float:left;min-width:15px;height:16px;text-align:center;color:#fff;text-decoration:none;background:#40628a;border:1px solid #161616;padding:0 4px 4px;margin:0 2px 2px 0;cursor:default;white-space:nowrap}.hasIcon{padding:0 4px 4px 0}.linkActive:hover,.zoomLink:hover,a:hover{background:#507aac}.linkPending,.linkPending:hover{color:#fff;background:#507aac}a.white,a.white:active,a.white:link,a.white:visited{color:#40628a;text-decoration:none;background:#fff;border:1px solid #161616;padding:1px 4px;margin:0 2px 0 0;cursor:default}a.white:hover{color:#fff;background:#40628a}.linkOn,.selected,a.linkOn:active,a.linkOn:hover,a.linkOn:link,a.linkOn:visited,a.selected:active,a.selected:hover,a.selected:link,a.selected:visited{color:#fff;background:#2f943c}.disabled,.linkOff,a.disabled:active,a.disabled:hover,a.disabled:link,a.disabled:visited,a.linkOff:active,a.linkOff:hover,a.linkOff:link,a.linkOff:visited{color:#fff;background:#999;border-color:#666}.disabled.icon,.linkOff.icon,.linkOn.icon,.selected.icon,a.icon{position:relative;padding:1px 4px 2px 20px}.disabled.icon img,.linkOff.icon img,.linkOn.icon img,.selected.icon img,a.icon img{position:absolute;top:0;left:0;width:18px;height:18px}.linkDanger,a.linkDanger:active,a.linkDanger:link,a.linkDanger:visited{color:#fff;background-color:red;border-color:#a00}.linkDanger:hover{background-color:#f66}.inactive,a.inactive:active,a.inactive:hover,a.inactive:link,a.inactive:visited{color:#fff;background:#999;border-color:#666}.white{color:#fff}.good,.white{font-weight:700}.good{color:#4f7529}.average{color:#cd6500}.average,.bad{font-weight:700}.bad{color:#e00}.idle{color:#272727;font-weight:700}.redButton{background:#ea0000}.yellowButton{background:#cacc00}.highlight{color:#8ba5c4}.dark{color:#272727}.burn{color:orange}.brute{color:red}.toxin{color:green}.toxin_light{color:#3adf00}.oxyloss{color:blue}.oxyloss_light{color:#6698ff}.Red{color:red}.Blue{color:#00f}.Green{color:#0f0}.Marigold{color:#fda505}.Fuschia{color:#ff0080}.Black{color:#000}.Pearl{color:#c6cacb}.cold1{color:#94b8ff}.cold2{color:#69f}.cold3{color:#293d66}.hot1{color:#f96}.hot2{color:#993d00}.hot3{color:#f60}.itemGroup{border:1px solid #e9c183;background:#2c2c2c;padding:4px;clear:both}.item{width:100%;margin:4px 0 0;clear:both;overflow:auto}.itemContent,.itemContentNarrow{float:left}.itemContentNarrow{width:30%}.itemContent{width:69%}.itemLabel,.itemLabelNarrow,.itemLabelWide,.itemLabelWider,.itemLabelWidest{float:left;color:#e9c183}.itemLabelNarrow{width:20%}.itemLabel{width:30%}.itemLabelWide{width:45%}.itemLabelWider{width:69%}.itemLabelWidest{width:100%}.itemContentWide{float:left;width:79%}.itemContentSmall{float:left;width:33%}.itemContentMedium{float:left;width:55%}.block{padding:8px;margin:10px 4px 4px;border:1px solid #40628a;background-color:#202020}.block h3{padding:0}.clearBoth{clear:both}.clearLeft{clear:left}.clearRight{clear:right}.line{width:100%;clear:both}.fixedLeft{width:110px;float:left}.fixedLeftWide{width:165px;float:left}.fixedLeftWider{width:220px;float:left}.fixedLeftWidest{width:250px;float:left}.floatRight{float:right}.floatLeft{float:left}.hidden{display:none}.statusDisplay{overflow:hidden}.statusDisplay,.statusDisplayRecords{background:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000);background:rgba(0,0,0,.5);color:#fff;border:1px solid #40628a;padding:4px;margin:3px 0}.statusDisplayRecords{overflow-x:hidden;overflow-y:auto}.statusLabel{width:138px;float:left;overflow:hidden;color:#98b0c3}.statusValue{float:left}.fancy{display:none}.minimize{color:#e9c183;position:absolute;top:6px;right:46px}.minimize:hover{color:#b8c9d6}.close{color:#e9c183;position:absolute;top:4px;right:12px}.close:hover{color:#b8c9d6}div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 30px 30px;border-color:transparent transparent #363636;-webkit-transform:rotate(1turn);transform:rotate(1turn)}.uiLinkPendingIcon{display:none;float:left;width:16px;height:16px;margin:2px 2px 0;background-image:url(uiLinkPendingIcon.gif)}.linkPending .fa{display:none}.linkPending .uiLinkPendingIcon{display:block}.mapIcon16{position:absolute;width:16px;height:16px;background-image:url(uiIcons16Green.png);background-position:-144px -96px;background-repeat:no-repeat;zoom:.125;margin-left:-1px}.mapIcon16.bad,.mapIcon16.dead{background-image:url(uiIcons16Red.png)}.mapIcon16.average{background-image:url(uiIcons16Orange.png)}.mapIcon16.good{background-image:url(uiIcons16Green.png)}.mapIcon16.icon-airalarm{background-position:0 -144px}.mapIcon16.rank-captain{background-position:-224px -112px}.mapIcon16.rank-headofpersonnel{background-position:-112px -96px}.mapIcon16.rank-headofsecurity{background-position:-112px -128px}.mapIcon16.rank-chiefengineer{background-position:-176px -112px}.mapIcon16.rank-researchdirector{background-position:-128px -128px}.mapIcon16.rank-chiefmedicalofficer{background-position:-32px -128px}.mapIcon16.rank-atmospherictechnician,.mapIcon16.rank-stationengineer{background-position:-176px -112px}.mapIcon16.rank-chemist,.mapIcon16.rank-geneticist,.mapIcon16.rank-medicaldoctor,.mapIcon16.rank-psychiatrist{background-position:-32px -128px}.mapIcon16.rank-geneticist,.mapIcon16.rank-roboticist,.mapIcon16.rank-scientist,.mapIcon16.rank-xenobiologist{background-position:-128px -128px}.mapIcon16.rank-detective,.mapIcon16.rank-securityofficer,.mapIcon16.rank-warden{background-position:-112px -128px}ul{padding:4px 0 0 10px;margin:0;list-style-type:none}li{padding:0 0 2px}table.fixed{table-layout:fixed}table.fixed td{overflow:hidden}table.pmon{border:2px solid #4169e1}table.pmon td,table.pmon th{border-bottom:1px dotted #000;padding:0 5px}th.command{background:#33f}th.command,th.sec{font-weight:700;color:#fff}th.sec{background:#8e0000}th.med{background:#060}th.eng,th.med{font-weight:700;color:#fff}th.eng{background:#b27300}th.sci{background:#a65ba6}th.sci,th.ser{font-weight:700;color:#fff}th.ser{background:#7100aa}th.sup{background:#666621}th.civ,th.sup{font-weight:700;color:#fff}th.civ{background:#a32800}th.misc{background:#666;font-weight:700;color:#fff}span.qm-job{color:#b77a41;font-weight:700}.striped:not(table)>:nth-child(even),.striped tr:nth-child(even){background-color:#404040}#uiNoScript{position:fixed;top:50%;left:50%;margin:-60px 0 0 -150px;width:280px;height:120px;background:#fff;border:2px solid red;color:#000;font-size:10px;font-weight:700;z-index:1;padding:0 10px;text-align:center}.notice{background:url(uiNoticeBackground.jpg) 50% 50%;color:#000}.notice,.noticePlaceholder{position:relative;font-size:12px;font-style:italic;font-weight:700;padding:3px 4px;margin:4px 0}.notice.icon{padding:2px 4px 0 20px}.notice img{position:absolute;top:0;left:0;width:16px;height:16px}div.notice{clear:both}.wholeScreen{position:absolute;color:#517087;font-size:16px;font-weight:700;text-align:center}.pdalink{float:left;white-space:nowrap}.pdanote{color:#cd6500;font-weight:700}.dnaBlock{float:left;width:90px;padding:0 0 5px}.dnaBlockNumber{color:#fff;background:#363636;min-width:20px}.dnaBlockNumber,.dnaSubBlock{font-family:Fixed,monospace;float:left;height:20px;padding:0;text-align:center}.dnaSubBlock{min-width:16px}.mask{position:fixed;left:0;top:0;width:100%;height:100%;background:url(uiMaskBackground.png)}.maskContent{width:100%;height:200px;margin:200px 0;text-align:center}body{background:#272727;color:#fff;font-family:Verdana,Geneva,sans-serif;font-size:12px;line-height:170%;margin:0;padding:0}hr{background-color:#40628a;height:1px;border:none}a img,img{border-style:none}h1,h2,h3,h4,h5,h6{margin:0;padding:12px 0 6px;color:#fff;clear:both}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4{font-size:12px}body{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1' viewBox='0 0 425 200' opacity='.25'%3E%3Cpath d='M178.004.04H106.8a6.76 6.026 0 0 0-6.76 6.024v187.872a6.76 6.026 0 0 0 6.76 6.025h53.107a6.76 6.026 0 0 0 6.762-6.024V92.392l72.215 104.7a6.76 6.026 0 0 0 5.76 2.87H318.2a6.76 6.026 0 0 0 6.76-6.026V6.064A6.76 6.026 0 0 0 318.2.04h-54.717a6.76 6.026 0 0 0-6.76 6.024v102.62L183.762 2.91a6.76 6.026 0 0 0-5.76-2.87zM4.845 22.11A13.412 12.502 0 0 1 13.478.04h66.118a5.365 5 0 0 1 5.365 5v79.88zM420.155 177.89a13.412 12.502 0 0 1-8.633 22.07h-66.118a5.365 5 0 0 1-5.365-5v-79.88z'/%3E%3C/svg%3E") no-repeat fixed center/70% 70%,linear-gradient(180deg,#2a2a2a 0,#202020) no-repeat fixed center/100% 100%;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff2a2a2a',endColorstr='#ff000000',GradientType=0)}#uiWrapper{width:100%;height:100%;-ms-user-select:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}#uiTitleWrapper{position:relative;height:30px}#uiTitleText{position:absolute;top:6px;left:44px;width:66%;overflow:hidden;color:#e9c183;font-size:16px}#uiTitle.icon{padding:6px 8px 6px 42px;background-position:2px 50%;background-repeat:no-repeat}#uiTitleFluff{position:absolute;top:4px;right:12px;width:42px;height:24px;background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1' viewBox='0 0 425 200' opacity='.25'%3E%3Cpath d='M178.004.04H106.8a6.76 6.026 0 0 0-6.76 6.024v187.872a6.76 6.026 0 0 0 6.76 6.025h53.107a6.76 6.026 0 0 0 6.762-6.024V92.392l72.215 104.7a6.76 6.026 0 0 0 5.76 2.87H318.2a6.76 6.026 0 0 0 6.76-6.026V6.064A6.76 6.026 0 0 0 318.2.04h-54.717a6.76 6.026 0 0 0-6.76 6.024v102.62L183.762 2.91a6.76 6.026 0 0 0-5.76-2.87zM4.845 22.11A13.412 12.502 0 0 1 13.478.04h66.118a5.365 5 0 0 1 5.365 5v79.88zM420.155 177.89a13.412 12.502 0 0 1-8.633 22.07h-66.118a5.365 5 0 0 1-5.365-5v-79.88z'/%3E%3C/svg%3E") 50% 50% no-repeat}.statusicon{position:absolute;top:4px;left:12px}#uiMapWrapper{clear:both;padding:8px}#uiMapHeader{position:relative;clear:both}#uiMapContainer{position:relative;width:100%;height:600px;overflow:hidden;border:1px solid #40628a;background:url(nanomapBackground.png)}#uiMap{top:50%;left:50%;margin:-512px 0 0 -512px;overflow:hidden;zoom:4}#uiMap,#uiMapImage{position:absolute;width:256px;height:256px}#uiMapImage{bottom:1px;left:1px}#uiMapContent{position:absolute;bottom:-13.5px;left:0;width:256px;height:256px}#uiMapFooter{position:relative;clear:both}#uiContent{clear:both;padding:8px}#uiMapTooltip{position:absolute;right:10px;top:10px;border:1px solid #40628a;background-color:#272727;padding:8px;display:none;z-index:1}#uiLoadingNotice{position:relative;background:url(uiNoticeBackground.jpg) 50% 50%;color:#000;font-size:14px;font-style:italic;font-weight:700;padding:3px 4px;margin:4px 0} \ No newline at end of file +.displayBar{position:relative;width:236px;height:16px;border:1px solid #666;float:left;margin:0 5px 0 0;overflow:hidden;background:#000}.displayBarText{position:absolute;top:-2px;left:5px;width:100%;height:100%;color:#fff;font-weight:400}.displayBarFill{width:0;height:100%;background:#40628a;overflow:hidden;float:left}.displayBarFill.alignRight{float:right}.displayBarFill.good{color:#fff;background:#4f7529}.displayBarFill.notgood{color:#fff;background:#ffb400}.displayBarFill.average{color:#fff;background:#cd6500}.displayBarFill.bad{color:#fff;background:#e00}.displayBarFill.highlight{color:#fff;background:#8ba5c4}.disabled,.link,.linkOff,.linkOn,.redButton,.selected,.yellowButton{float:left;min-width:15px;height:16px;text-align:center;color:#fff;text-decoration:none;background:#40628a;border:1px solid #161616;padding:0 4px 4px;margin:0 2px 2px 0;cursor:default;white-space:nowrap}.hasIcon{padding:0 4px 4px 0}.linkActive:hover,.zoomLink:hover,a:hover{background:#507aac}.linkPending,.linkPending:hover{color:#fff;background:#507aac}a.white,a.white:active,a.white:link,a.white:visited{color:#40628a;text-decoration:none;background:#fff;border:1px solid #161616;padding:1px 4px;margin:0 2px 0 0;cursor:default}a.white:hover{color:#fff;background:#40628a}.linkOn,.selected,a.linkOn:active,a.linkOn:hover,a.linkOn:link,a.linkOn:visited,a.selected:active,a.selected:hover,a.selected:link,a.selected:visited{color:#fff;background:#2f943c}.disabled,.linkOff,a.disabled:active,a.disabled:hover,a.disabled:link,a.disabled:visited,a.linkOff:active,a.linkOff:hover,a.linkOff:link,a.linkOff:visited{color:#fff;background:#999;border-color:#666}.disabled.icon,.linkOff.icon,.linkOn.icon,.selected.icon,a.icon{position:relative;padding:1px 4px 2px 20px}.disabled.icon img,.linkOff.icon img,.linkOn.icon img,.selected.icon img,a.icon img{position:absolute;top:0;left:0;width:18px;height:18px}.linkDanger,a.linkDanger:active,a.linkDanger:link,a.linkDanger:visited{color:#fff;background-color:red;border-color:#a00}.linkDanger:hover{background-color:#f66}.inactive,a.inactive:active,a.inactive:hover,a.inactive:link,a.inactive:visited{color:#fff;background:#999;border-color:#666}.white{color:#fff}.good,.white{font-weight:700}.good{color:#4f7529}.average{color:#cd6500}.average,.bad{font-weight:700}.bad{color:#e00}.idle{color:#272727;font-weight:700}.redButton{background:#ea0000}.yellowButton{background:#cacc00}.highlight{color:#8ba5c4}.dark{color:#272727}.burn{color:orange}.brute{color:red}.toxin{color:green}.toxin_light{color:#3adf00}.oxyloss{color:blue}.oxyloss_light{color:#6698ff}.Red{color:red}.Blue{color:#00f}.Green{color:#0f0}.Marigold{color:#fda505}.Fuschia{color:#ff0080}.Black{color:#000}.Pearl{color:#c6cacb}.cold1{color:#94b8ff}.cold2{color:#69f}.cold3{color:#293d66}.hot1{color:#f96}.hot2{color:#993d00}.hot3{color:#f60}.itemGroup{border:1px solid #e9c183;background:#2c2c2c;padding:4px;clear:both}.item{width:100%;margin:4px 0 0;clear:both;overflow:auto}.itemContent,.itemContentNarrow{float:left}.itemContentNarrow{width:30%}.itemContent{width:69%}.itemLabel,.itemLabelNarrow,.itemLabelWide,.itemLabelWider,.itemLabelWidest{float:left;color:#e9c183}.itemLabelNarrow{width:20%}.itemLabel{width:30%}.itemLabelWide{width:45%}.itemLabelWider{width:69%}.itemLabelWidest{width:100%}.itemContentWide{float:left;width:79%}.itemContentSmall{float:left;width:33%}.itemContentMedium{float:left;width:55%}.block{padding:8px;margin:10px 4px 4px;border:1px solid #40628a;background-color:#202020}.block h3{padding:0}.clearBoth{clear:both}.clearLeft{clear:left}.clearRight{clear:right}.line{width:100%;clear:both}.fixedLeft{width:110px;float:left}.fixedLeftWide{width:165px;float:left}.fixedLeftWider{width:220px;float:left}.fixedLeftWidest{width:250px;float:left}.floatRight{float:right}.floatLeft{float:left}.hidden{display:none}.statusDisplay{overflow:hidden}.statusDisplay,.statusDisplayRecords{background:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000);background:rgba(0,0,0,.5);color:#fff;border:1px solid #40628a;padding:4px;margin:3px 0}.statusDisplayRecords{overflow-x:hidden;overflow-y:auto}.statusLabel{width:138px;float:left;overflow:hidden;color:#98b0c3}.statusValue{float:left}.fancy{display:none}.minimize{color:#e9c183;position:absolute;top:6px;right:46px}.minimize:hover{color:#b8c9d6}.close{color:#e9c183;position:absolute;top:4px;right:12px}.close:hover{color:#b8c9d6}div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 30px 30px;border-color:transparent transparent #363636;-webkit-transform:rotate(1turn);transform:rotate(1turn)}.uiLinkPendingIcon{display:none;float:left;width:16px;height:16px;margin:2px 2px 0;background-image:url(uiLinkPendingIcon.gif)}.linkPending .fa{display:none}.linkPending .uiLinkPendingIcon{display:block}.mapIcon16{position:absolute;width:16px;height:16px;background-image:url(uiIcons16Green.png);background-position:-144px -96px;background-repeat:no-repeat;zoom:.125;margin-left:-1px}.mapIcon16.bad,.mapIcon16.dead{background-image:url(uiIcons16Red.png)}.mapIcon16.average{background-image:url(uiIcons16Orange.png)}.mapIcon16.good{background-image:url(uiIcons16Green.png)}.mapIcon16.icon-airalarm{background-position:0 -144px}.mapIcon16.rank-captain{background-position:-224px -112px}.mapIcon16.rank-headofpersonnel{background-position:-112px -96px}.mapIcon16.rank-headofsecurity{background-position:-112px -128px}.mapIcon16.rank-chiefengineer{background-position:-176px -112px}.mapIcon16.rank-researchdirector{background-position:-128px -128px}.mapIcon16.rank-chiefmedicalofficer{background-position:-32px -128px}.mapIcon16.rank-atmospherictechnician,.mapIcon16.rank-stationengineer{background-position:-176px -112px}.mapIcon16.rank-chemist,.mapIcon16.rank-geneticist,.mapIcon16.rank-medicaldoctor,.mapIcon16.rank-psychiatrist{background-position:-32px -128px}.mapIcon16.rank-geneticist,.mapIcon16.rank-roboticist,.mapIcon16.rank-scientist,.mapIcon16.rank-xenobiologist{background-position:-128px -128px}.mapIcon16.rank-detective,.mapIcon16.rank-securityofficer,.mapIcon16.rank-warden{background-position:-112px -128px}ul{padding:4px 0 0 10px;margin:0;list-style-type:none}li{padding:0 0 2px}table.fixed{table-layout:fixed}table.fixed td{overflow:hidden}table.pmon{border:2px solid #4169e1}table.pmon td,table.pmon th{border-bottom:1px dotted #000;padding:0 5px}th.command{background:#33f}th.command,th.sec{font-weight:700;color:#fff}th.sec{background:#8e0000}th.med{background:#060}th.eng,th.med{font-weight:700;color:#fff}th.eng{background:#b27300}th.sci{background:#a65ba6}th.sci,th.ser{font-weight:700;color:#fff}th.ser{background:#7100aa}th.sup{background:#666621}th.civ,th.sup{font-weight:700;color:#fff}th.civ{background:#a32800}th.misc{background:#666;font-weight:700;color:#fff}span.qm-job{color:#b77a41;font-weight:700}.striped:not(table)>:nth-child(even),.striped tr:nth-child(even){background-color:#404040}#uiNoScript{position:fixed;top:50%;left:50%;margin:-60px 0 0 -150px;width:280px;height:120px;background:#fff;border:2px solid red;color:#000;font-size:10px;font-weight:700;z-index:1;padding:0 10px;text-align:center}.notice{background:url(uiNoticeBackground.jpg) 50% 50%;color:#000}.notice,.noticePlaceholder{position:relative;font-size:12px;font-style:italic;font-weight:700;padding:3px 4px;margin:4px 0}.notice.icon{padding:2px 4px 0 20px}.notice img{position:absolute;top:0;left:0;width:16px;height:16px}div.notice{clear:both}.wholeScreen{position:absolute;color:#517087;font-size:16px;font-weight:700;text-align:center}.pdalink{float:left;white-space:nowrap;cursor:default!important}.pdalink.disabled{background:none;border:none;color:#999;text-align:left}.pdanote{color:#cd6500;font-weight:700}.item.mainmenu{padding-bottom:.5em}div.clock{color:#fff;font-weight:700;float:right;padding-right:2em}#pdaFooter{position:fixed;left:0;bottom:0;width:100%;background:#272727}.pdaFooterButton{width:33%;padding:.5em 0;font-size:200%;border:none;background:none;color:#fff}.pdaFooterButton:hover{background:#507aac}.pdaFooterButton.disabled{background:none!important;color:#555!important}.pdaFooterButton .uiLinkPendingIcon{position:absolute;width:33%;background-repeat:no-repeat;background-position:center}.dnaBlock{float:left;width:90px;padding:0 0 5px}.dnaBlockNumber{color:#fff;background:#363636;min-width:20px}.dnaBlockNumber,.dnaSubBlock{font-family:Fixed,monospace;float:left;height:20px;padding:0;text-align:center}.dnaSubBlock{min-width:16px}.mask{position:fixed;left:0;top:0;width:100%;height:100%;background:url(uiMaskBackground.png)}.maskContent{width:100%;height:200px;margin:200px 0;text-align:center}body{background:#272727;color:#fff;font-family:Verdana,Geneva,sans-serif;font-size:12px;line-height:170%;margin:0;padding:0}hr{background-color:#40628a;height:1px;border:none}a img,img{border-style:none}h1,h2,h3,h4,h5,h6{margin:0;padding:12px 0 6px;color:#fff;clear:both}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4{font-size:12px}body{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1' viewBox='0 0 425 200' opacity='.25'%3E%3Cpath d='M178.004.04H106.8a6.76 6.026 0 0 0-6.76 6.024v187.872a6.76 6.026 0 0 0 6.76 6.025h53.107a6.76 6.026 0 0 0 6.762-6.024V92.392l72.215 104.7a6.76 6.026 0 0 0 5.76 2.87H318.2a6.76 6.026 0 0 0 6.76-6.026V6.064A6.76 6.026 0 0 0 318.2.04h-54.717a6.76 6.026 0 0 0-6.76 6.024v102.62L183.762 2.91a6.76 6.026 0 0 0-5.76-2.87zM4.845 22.11A13.412 12.502 0 0 1 13.478.04h66.118a5.365 5 0 0 1 5.365 5v79.88zM420.155 177.89a13.412 12.502 0 0 1-8.633 22.07h-66.118a5.365 5 0 0 1-5.365-5v-79.88z'/%3E%3C/svg%3E") no-repeat fixed center/70% 70%,linear-gradient(180deg,#2a2a2a 0,#202020) no-repeat fixed center/100% 100%;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff2a2a2a',endColorstr='#ff000000',GradientType=0)}#uiWrapper{width:100%;height:100%;-ms-user-select:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}#uiTitleWrapper{position:relative;height:30px}#uiTitleText{position:absolute;top:6px;left:44px;width:66%;overflow:hidden;color:#e9c183;font-size:16px}#uiTitle.icon{padding:6px 8px 6px 42px;background-position:2px 50%;background-repeat:no-repeat}#uiTitleFluff{position:absolute;top:4px;right:12px;width:42px;height:24px;background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1' viewBox='0 0 425 200' opacity='.25'%3E%3Cpath d='M178.004.04H106.8a6.76 6.026 0 0 0-6.76 6.024v187.872a6.76 6.026 0 0 0 6.76 6.025h53.107a6.76 6.026 0 0 0 6.762-6.024V92.392l72.215 104.7a6.76 6.026 0 0 0 5.76 2.87H318.2a6.76 6.026 0 0 0 6.76-6.026V6.064A6.76 6.026 0 0 0 318.2.04h-54.717a6.76 6.026 0 0 0-6.76 6.024v102.62L183.762 2.91a6.76 6.026 0 0 0-5.76-2.87zM4.845 22.11A13.412 12.502 0 0 1 13.478.04h66.118a5.365 5 0 0 1 5.365 5v79.88zM420.155 177.89a13.412 12.502 0 0 1-8.633 22.07h-66.118a5.365 5 0 0 1-5.365-5v-79.88z'/%3E%3C/svg%3E") 50% 50% no-repeat}.statusicon{position:absolute;top:4px;left:12px}#uiMapWrapper{clear:both;padding:8px}#uiMapHeader{position:relative;clear:both}#uiMapContainer{position:relative;width:100%;height:600px;overflow:hidden;border:1px solid #40628a;background:url(nanomapBackground.png)}#uiMap{top:50%;left:50%;margin:-512px 0 0 -512px;overflow:hidden;zoom:4}#uiMap,#uiMapImage{position:absolute;width:256px;height:256px}#uiMapImage{bottom:1px;left:1px}#uiMapContent{position:absolute;bottom:-13.5px;left:0;width:256px;height:256px}#uiMapFooter{position:relative;clear:both}#uiContent{clear:both;padding:8px}#uiMapTooltip{position:absolute;right:10px;top:10px;border:1px solid #40628a;background-color:#272727;padding:8px;display:none;z-index:1}#uiLoadingNotice{position:relative;background:url(uiNoticeBackground.jpg) 50% 50%;color:#000;font-size:14px;font-style:italic;font-weight:700;padding:3px 4px;margin:4px 0} \ No newline at end of file diff --git a/nano/scripts/nano/nano_state_pda.js b/nano/scripts/nano/nano_state_pda.js new file mode 100644 index 00000000000..d46419bfeaf --- /dev/null +++ b/nano/scripts/nano/nano_state_pda.js @@ -0,0 +1,53 @@ +NanoStatePDAClass.inheritsFrom(NanoStateClass); +var NanoStatePDA = new NanoStatePDAClass(); + +function NanoStatePDAClass() { + this.key = 'pda'; + this.key = this.key.toLowerCase(); + this.current_template = ""; + + NanoStateManager.addState(this); +} + +NanoStatePDAClass.prototype.onUpdate = function(data) { + NanoStateClass.prototype.onUpdate.call(this, data); + var state = this; + + try { + if(data['data']['app'] != null) { + var template = data['data']['app']['template']; + if(template != null && template != state.current_template) { + $.when($.ajax({ + url: template + '.tmpl', + cache: false, + dataType: 'text' + })) + .done(function(templateMarkup) { + templateMarkup += '
      '; + + try { + NanoTemplate.addTemplate('app', templateMarkup); + NanoTemplate.resetTemplate('app'); + $("#uiApp").html(NanoTemplate.parse('app', data)); + state.current_template = template; + + state.onAfterUpdate(data); + } catch(error) { + reportError('ERROR: An error occurred while loading the PDA App UI: ' + error.message); + return; + } + }) + .fail( function () { + reportError('ERROR: Loading template app(' + template + ') failed!'); + }); + } else { + if (NanoTemplate.templateExists('app')) { + $("#uiApp").html(NanoTemplate.parse('app', data)); + } + } + } + } catch(error) { + reportError('ERROR: An error occurred while rendering the PDA App UI: ' + error.message); + return; + } +} \ No newline at end of file diff --git a/nano/scripts/nano/nano_template.js b/nano/scripts/nano/nano_template.js index 7350e62d48d..e37724f1bb4 100644 --- a/nano/scripts/nano/nano_template.js +++ b/nano/scripts/nano/nano_template.js @@ -87,6 +87,9 @@ var NanoTemplate = function () { templateExists: function (key) { return _templates.hasOwnProperty(key); }, + resetTemplate: function (key) { + _compiledTemplates[key] = null; + }, parse: function (templateKey, data) { if (!_compiledTemplates.hasOwnProperty(templateKey) || !_compiledTemplates[templateKey]) { if (!_templates.hasOwnProperty(templateKey)) { diff --git a/nano/styles/_color.less b/nano/styles/_color.less index 6194a96ac2b..68fc1d89c5b 100644 --- a/nano/styles/_color.less +++ b/nano/styles/_color.less @@ -1,9 +1,4 @@ -@good-color: #4f7529; -@average-color: #cd6500; -@bad-color: #ee0000; - -@highlight-color: #8BA5C4; -@dark-color: #272727; +@import "_config"; .white { color: white; diff --git a/nano/styles/_config.less b/nano/styles/_config.less index a44ef50fd54..dffcc37331c 100644 --- a/nano/styles/_config.less +++ b/nano/styles/_config.less @@ -4,4 +4,12 @@ // Body Colors @background-start: #2a2a2a; -@background-end: #202020; \ No newline at end of file +@background-end: #202020; + +// Element Colors +@good-color: #4f7529; +@average-color: #cd6500; +@bad-color: #ee0000; + +@highlight-color: #8BA5C4; +@dark-color: #272727; \ No newline at end of file diff --git a/nano/styles/_misc.less b/nano/styles/_misc.less index 55f8216b3b6..fe7646062b2 100644 --- a/nano/styles/_misc.less +++ b/nano/styles/_misc.less @@ -74,6 +74,14 @@ div.notice { .pdalink { float: left; white-space: nowrap; + cursor: default !important; + + &.disabled { + background: none; + border: none; + color: #999; + text-align: left; + } } .pdanote { @@ -81,6 +89,50 @@ div.notice { font-weight: bold; } +.item.mainmenu { + padding-bottom: 0.5em; +} + +div.clock { + color: white; + font-weight: bold; + float: right; + padding-right: 2em; +} + +#pdaFooter { + position: fixed; + left: 0; + bottom: 0; + width: 100%; + background: @dark-color; +} + +.pdaFooterButton { + width: 33%; + padding: 0.5em 0; + font-size: 200%; + border: none; + background: none; + color: #fff; + + &:hover { + background: #507aac; + } + + &.disabled { + background: none !important; + color: #555 !important; + } + + .uiLinkPendingIcon { + position: absolute; + width: 33%; + background-repeat: no-repeat; + background-position: center; + } +} + /* DNA Modifier styling */ .dnaBlock { float: left; diff --git a/nano/styles/_native.less b/nano/styles/_native.less index 8114d75133c..3061b54c72c 100644 --- a/nano/styles/_native.less +++ b/nano/styles/_native.less @@ -1,7 +1,7 @@ @import "_config"; body { - background: #272727; + background: @dark-color; color: #ffffff; font-family: @font; font-size: @fontsize; diff --git a/nano/templates/cloning_console.tmpl b/nano/templates/cloning_console.tmpl index ffb9502d181..c541ca6d6b4 100644 --- a/nano/templates/cloning_console.tmpl +++ b/nano/templates/cloning_console.tmpl @@ -56,11 +56,19 @@ Used In File(s): \code\game\machinery\computer\cloning.dm
      Scan Occupant
      {{:helper.link('Scan', 'search', {'scan' : 1}, !data.occupant ? 'disabled' : '')}}
      -
      +
      Scanner Lock
      {{if data.occupant}}{{:helper.link('Engaged', 'lock', {'lock' : 1}, data.locked ? 'selected' : '')}}{{else}} {{:helper.link('Engaged', 'lock', null, 'disabled')}}{{/if}}{{:helper.link('Disengaged', 'unlock', {'lock' : 1}, !data.locked ? 'selected' : '')}}
      -
      +
      + {{if data.can_brainscan}} +
      +
      Scan Mode
      +
      + {{:helper.link('Brain', null, {'toggle_mode' : 1}, !data.scan_mode ? '' : 'selected')}}{{:helper.link('Body', null, {'toggle_mode' : 1}, data.scan_mode ? '' : 'selected')}} +
      +
      + {{/if}} {{/if}} {{if data.numberofpods}}

      Pods

      diff --git a/nano/templates/identification_computer.tmpl b/nano/templates/identification_computer.tmpl index 7170d8a1a69..c10ea44ff86 100644 --- a/nano/templates/identification_computer.tmpl +++ b/nano/templates/identification_computer.tmpl @@ -221,7 +221,7 @@ {{if data.centcom_access}} - CentCom + CentComm {{for data.centcom_jobs}} {{:helper.link(value.display_name, '', {'choice' : 'assign', 'assign_target' : value.job}, data.target_rank == value.job ? 'disabled' : null)}} diff --git a/nano/templates/op_computer.tmpl b/nano/templates/op_computer.tmpl index 027fdf3443b..16fce184a83 100644 --- a/nano/templates/op_computer.tmpl +++ b/nano/templates/op_computer.tmpl @@ -111,7 +111,14 @@ Used In File(s): \code\game\machinery\computer\Operating.dm
      Pulse:
      {{:data.occupant.pulse}} bpm
    {{/if}} - + {{if data.occupant.inSurgery}} +
    +
    Initiated Surgery Procedure:
    {{:data.occupant.surgeryName}}
    +
    +
    Next Step:
    {{:data.occupant.stepName}}
    + +
    + {{/if}}

    {{/if}} diff --git a/nano/templates/pda.tmpl b/nano/templates/pda.tmpl index 54ab77a9be6..3d11ee0a6f8 100644 --- a/nano/templates/pda.tmpl +++ b/nano/templates/pda.tmpl @@ -1,4 +1,3 @@ - - {{:helper.link('Close', 'gear', {'choice' : "Close"}, null, 'pdalink fixedLeft')}} - {{if data.idInserted}} {{:helper.link('Update PDA Info', 'eject', {'choice' : "UpdateInfo"}, null, 'pdalink fixedLeftWide')}} {{/if}} - {{if data.mode != 0}} {{:helper.link('Return', 'arrow-left', {'choice' : "Return"}, null, 'pdalink fixedLeft')}} {{/if}} - {{:helper.link('Toggle R.E.T.R.O. mode', 'gear', {'choice': "Retro"}, null, 'floatRight')}} +
    + {{if data.idInserted}} + {{:helper.link(data.idLink, 'eject', {'choice' : "Authenticate"}, null, 'pdalink fixedLeftWide')}} + {{/if}} + {{if data.cartridge_name}} + {{:helper.link(data.cartridge_name, 'eject', {'choice' : "Eject"}, null, 'pdalink fixedLeftWidest')}} + {{/if}} + {{:helper.link('Toggle R.E.T.R.O. mode', 'gear', {'choice': "Retro"}, null, 'pdalink fixedLeftWide')}} +
    +
    + {{:data.stationTime}}
    -
    -
    -
    - Station Time: -
    -
    - {{:data.stationTime}} -
    + + {{if data.app}} +

     {{:data.app.name}}

    +
    +
     
    + {{/if}} + +
    + {{:helper.link("", 'undo', {'choice' : "Back"}, data.app.has_back ? null : 'disabled', 'link pdaFooterButton')}} + {{:helper.link("", 'home', {'choice' : "Home"}, data.app.is_home ? 'disabled' : null, 'link pdaFooterButton')}}
    -
    - - - {{if data.mode == 0}} -
    -
    - Owner: -
    -
    - {{:data.owner}}, {{:data.ownjob}} -
    -
    -
    -
    -
    - ID: -
    -
    - {{:helper.link(data.idLink, 'eject', {'choice' : "Authenticate"}, data.idInserted ? null : 'disabled', data.idInserted ? 'link fixedLeftWidest' : 'link fixedLeft')}} -
    -
    -
    -
    -
    - Cartridge: -
    -
    - {{if data.cart_loaded==1}} - {{:helper.link(data.cartridge.name, 'eject', {'choice' : "Eject"},null,null)}} - {{else}} - {{:helper.link('None', 'eject', {'choice' : "Eject"},'disabled',null)}} - {{/if}} -
    -
    -
    -

    Functions

    -
    -
    -
    - General: -
    -
    - {{:helper.link('Notekeeper', 'sticky-note', {'choice' : "1"}, null, 'pdalink fixedLeftWide')}} - {{:helper.link('Messenger', data.newMessage ? 'envelope' : 'envelope-o', {'choice' : "2"}, null, 'pdalink fixedLeftWide')}} - {{:helper.link('Crew Manifest', 'user', {'choice' : "41"}, null, 'pdalink fixedLeftWide')}} -
    -
    -
    - {{if data.cartridge}} - {{if data.cartridge.access.access_clown == 1}} -
    -
    - Clown: -
    -
    - {{:helper.link('Honk Synthesizer', 'gear', {'choice' : "Honk"}, null, 'pdalink fixedLeftWide')}} -
    -
    -
    - {{/if}} - {{if data.cartridge.access.access_engine == 1}} -
    -
    - Engineering: -
    -
    - {{:helper.link('Power Monitor', 'exclamation-triangle', {'choice' : "43"}, null, 'pdalink fixedLeftWide')}} -
    -
    -
    - {{/if}} - {{if data.cartridge.access.access_medical == 1}} -
    -
    - Medical: -
    -
    - {{:helper.link('Medical Records', 'gear', {'choice' : "44"}, null, 'pdalink fixedLeftWide')}} - {{:helper.link(data.scanmode == 1 ? 'Disable Med Scanner' : 'Enable Med Scanner', 'gear', {'choice' : "Medical Scan"}, null , 'pdalink fixedLeftWide')}} -
    -
    -
    - {{/if}} - {{if data.cartridge.access.access_security == 1}} -
    -
    - Security: -
    -
    - {{:helper.link('Security Records', 'gear', {'choice' : "45"}, null, 'pdalink fixedLeftWide')}} - {{if data.cartridge.radio ==1}} {{:helper.link('Security Bot Access', 'gear', {'choice' : "46"}, null, 'pdalink fixedLeftWide')}} {{/if}} -
    -
    -
    -
    - {{/if}} - {{if data.cartridge.access.access_quartermaster == 1}} -
    -
    - Quartermaster: -
    -
    - {{:helper.link('Supply Records', 'gear', {'choice' : "47"}, null, 'pdalink fixedLeftWide')}} - {{if data.cartridge.radio == 3}} {{:helper.link('Delivery Bot Control', 'gear', {'choice' : "48"}, null, 'pdalink fixedLeftWide')}} {{/if}} -
    -
    -
    -
    - {{/if}} - {{/if}} -
    -
    -
    - Utilities: -
    -
    - {{if data.cartridge}} - {{if data.cartridge.access.access_status_display == 1}} - {{:helper.link('Status Display', 'gear', {'choice' : "42"}, null, 'pdalink fixedLeftWide')}} - {{/if}} - {{if data.cartridge.access.access_janitor==1}} - {{:helper.link('Custodial Locator', 'gear', {'choice' : "49"}, null, 'pdalink fixedLeftWide')}} - {{/if}} - {{if data.cartridge.radio == 2}} - {{:helper.link('Signaler System', 'gear', {'choice' : "40"}, null, 'pdalink fixedLeftWide')}} - {{/if}} - {{if data.cartridge.access.access_reagent_scanner==1}} - {{:helper.link(data.scanmode == 3 ? 'Disable Reagent Scanner' : 'Enable Reagent Scanner', 'gear', {'choice' : "Reagent Scan"}, null, 'pdalink fixedLeftWider')}} - {{/if}} - {{if data.cartridge.access.access_engine==1}} - {{:helper.link(data.scanmode == 4 ? 'Disable Halogen Counter' : 'Enable Halogen Counter', 'gear', {'choice' : "Halogen Counter"}, null, 'pdalink fixedLeftWider')}} - {{/if}} - {{if data.cartridge.access.access_atmos==1}} - {{:helper.link(data.scanmode == 5 ? 'Disable Gas Scanner' : 'Enable Gas Scanner', 'gear', {'choice' : "Gas Scan"}, null, 'pdalink fixedLeftWide')}} - {{/if}} - {{if data.cartridge.access.access_remote_door==1}} - {{:helper.link('Toggle Door', 'gear', {'choice' : "Toggle Door"}, null, 'pdalink fixedLeftWide')}} - {{/if}} - {{/if}} - {{:helper.link('Atmospheric Scan', 'gear', {'choice' : "3"}, null, 'pdalink fixedLeftWide')}} - {{:helper.link(data.fon==1 ? 'Disable Flashlight' : 'Enable Flashlight', 'lightbulb-o', {'choice' : "Light"}, null,'pdalink fixedLeftWide')}} -
    -
    - {{if data.pai}} -
    -
    - PAI Utilities: -
    -
    - {{:helper.link('Configuration', 'gear', {'choice' : "pai", 'option' : "1"}, null, 'pdalink fixedLeft')}} - {{:helper.link('Eject pAI', 'eject', {'choice' : "pai", 'option' : "2"}, null, 'pdalink fixedLeft')}} -
    -
    - {{/if}} - - - {{else data.mode == 1}} -
    -
    - Notes: -
    -
    -
    -
    -
    - {{:data.note}} -
    -
    -
    -
    -
    - {{:helper.link('Edit Notes', 'gear', {'choice' : "Edit"}, null, 'pdalink fixedLeft')}} -
    -
    - - - {{else data.mode == 2}} -

    SpaceMessenger V4.0.1

    -
    -
    - Messenger Functions: -
    -
    - {{:helper.link(data.silent==1 ? 'Ringer: Off' : 'Ringer: On', data.silent==1 ? 'volume-off' : 'volume-up', {'choice' : "Toggle Ringer"}, null, 'pdalink fixedLeftWide')}} - {{:helper.link(data.toff==1 ? 'Messenger: Off' : 'Messenger: On',data.toff==1 ? 'close':'check', {'choice' : "Toggle Messenger"}, null, 'pdalink fixedLeftWide')}} - {{:helper.link('Set Ringtone', 'comment', {'choice' : "Ringtone"}, null, 'pdalink fixedLeftWide')}} - {{:helper.link('Delete all Conversations', 'trash', {'choice' : "Clear", 'option' : "All"}, null, 'pdalink fixedLeftWider')}} -
    -
    - {{if data.toff == 0}} -

    - {{if data.cartridge}} - {{if data.cartridge.charges}} -
    - {{:data.cartridge.charges}} - {{if data.cartridge.access.access_detonate_pda}} detonation charges left. {{/if}} - {{if data.cartridge.access.access_clown || data.cartridge.access.access_mime}} viral files left. {{/if}} - -

    -
    - {{/if}} - {{/if}} - - {{if data.pda_count == 0}} - No other PDAS located - {{else}} -

    Current Conversations

    - {{for data.convopdas}} -
    - {{:helper.link(value.Name, 'arrow-circle-down', {'choice' : "Select Conversation", 'convo' : value.Reference } , null, 'pdalink')}} - {{if data.cartridge}} - {{if data.cartridge.access.access_detonate_pda && value.Detonate}} - {{:helper.link('*Detonate*', 'exclamation-circle', {'choice' : "Detonate", 'target' : value.Reference}, null, 'pdalink fixedLeft')}} - {{/if}} - {{if data.cartridge.access.access_clown}} - {{:helper.link('*Send Virus*', 'star', {'choice' : "Send Honk", 'target' : value.Reference}, null, 'pdalink fixedLeft')}} - {{/if}} - {{if data.cartridge.access.access_mime}} - {{:helper.link('*Send Virus*', 'arrow-circle-down', {'choice' : "Send Silence", 'target' : value.Reference}, null, 'pdalink fixedLeft')}} - {{/if}} - {{/if}} -
    - {{/for}} -

    Other PDAs

    - {{for data.pdas}} -
    - {{:helper.link(value.Name, 'arrow-circle-down', {'choice' : "Message", 'target' : value.Reference}, null, 'pdalink')}} - {{if data.cartridge}} - {{if data.cartridge.access.access_detonate_pda && value.Detonate}} {{:helper.link('*Detonate*', 'exclamation-circle', {'choice' : "Detonate", 'target' : value.Reference}, null, 'pdalink fixedLeft')}} {{/if}} - {{if data.cartridge.access.access_clown}} {{:helper.link('*Send Virus*', 'star', {'choice' : "Send Honk", 'target' : value.Reference}, null, 'pdalink fixedLeft')}} {{/if}} - {{if data.cartridge.access.access_mime}} {{:helper.link('*Send Virus*', 'arrow-circle-down', {'choice' : "Send Silence", 'target' : value.Reference}, null, 'pdalink fixedLeft')}} {{/if}} - {{/if}} -
    - {{/for}} - {{/if}} - {{/if}} - - - {{else data.mode == 21}} -

    SpaceMessenger V4.0.1

    -
    -
    - Messenger Functions: -
    -
    - {{:helper.link('Delete Conversation', 'trash', {'choice' : "Clear", 'option' : "Convo"}, null, 'pdalink fixedLeftWide')}} -
    -
    -
    -
    -

    Conversation with: {{:data.convo_name}} ({{:data.convo_job}})

    -
    -
    -
    - {{for data.messages}} - {{if data.active_conversation == value.target}} - {{if value.sent==0}} - Them: {{:value.message}}
    - {{else}} - You: {{:value.message}}
    - {{/if}} - {{/if}} - {{/for}} -
    -
    -
    - {{:helper.link('Reply', 'comment', {'choice' : "Message", 'target': data.active_conversation}, null, 'pdalink fixedLeft')}} - - - {{else data.mode== 41}} -
    -
    - {{if data.manifest.heads}} - - {{for data.manifest["heads"]}} - {{if value.rank == "Captain"}} - - {{else}} - - {{/if}} - {{/for}} - {{/if}} - {{if data.manifest.sec}} - - {{for data.manifest["sec"]}} - {{if value.rank == "Head of Security"}} - - {{else}} - - {{/if}} - {{/for}} - {{/if}} - {{if data.manifest.eng}} - - {{for data.manifest["eng"]}} - {{if value.rank == "Chief Engineer"}} - - {{else}} - - {{/if}} - {{/for}} - {{/if}} - {{if data.manifest.med}} - - {{for data.manifest["med"]}} - {{if value.rank == "Chief Medical Officer"}} - - {{else}} - - {{/if}} - {{/for}} - {{/if}} - {{if data.manifest.sci}} - - {{for data.manifest["sci"]}} - {{if value.rank == "Research Director"}} - - {{else}} - - {{/if}} - {{/for}} - {{/if}} - {{if data.manifest.ser}} - - {{for data.manifest["ser"]}} - {{if value.rank == "Head of Personnel"}} - - {{else}} - - {{/if}} - {{/for}} - {{/if}} - {{if data.manifest.sup}} - - {{for data.manifest["sup"]}} - {{if value.rank == "Head of Personnel"}} - - {{else value.rank == "Quartermaster"}} - - {{else}} - - {{/if}} - {{/for}} - {{/if}} - {{if data.manifest.civ}} - - {{for data.manifest["civ"]}} - {{if value.rank == "Head of Personnel"}} - - {{else}} - - {{/if}} - {{/for}} - {{/if}} - {{if data.manifest.misc}} - - {{for data.manifest["misc"]}} - - {{/for}} - {{/if}} -
    Command
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Security
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Engineering
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Medical
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Science
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Service
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Supply
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Civilian
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Misc
    {{:value.name}}{{:value.rank}}{{:value.active}}
    -
    - - - {{else data.mode == 3}} -

    Atmospheric Scan

    -
    -
    - {{if data.aircontents.reading == 1}} -
    - Pressure: -
    -
    - {{:helper.string('{1} kPa', data.aircontents.pressure < 80 || data.aircontents.pressure > 120 ? 'bad' : data.aircontents.pressure < 95 || data.aircontents.pressure > 110 ? 'average' : 'good' , data.aircontents.pressure)}} -
    -
    - Temperature: -
    -
    - {{:helper.string('{1} °C', data.aircontents.temp < 5 || data.aircontents.temp > 35 ? 'bad' : data.aircontents.temp < 15 || data.aircontents.temp > 25 ? 'average' : 'good' , data.aircontents.temp)}} -
    -
    -
    - Oxygen: -
    -
    - {{:helper.string('{1}%', data.aircontents.oxygen < 17 ? 'bad' : data.aircontents.oxygen < 19 ? 'average' : 'good' , data.aircontents.oxygen)}} -
    -
    - Nitrogen: -
    -
    - {{:helper.string('{1}%', data.aircontents.nitrogen > 82 ? 'bad' : data.aircontents.nitrogen > 80 ? 'average' : 'good' , data.aircontents.nitrogen)}} -
    -
    - Carbon Dioxide: -
    -
    - {{:helper.string('{1}%', data.aircontents.carbon_dioxide > 5 ? 'bad' : 'good' , data.aircontents.carbon_dioxide)}} -
    -
    - Plasma: -
    -
    - {{:helper.string('{1}%', data.aircontents.plasma > 0 ? 'bad' : 'good' , data.aircontents.plasma)}} - -
    - {{if data.aircontents.other > 0}} -
    - Unknown: -
    -
    - {{:data.aircontents.other}}% -
    - {{/if}} - {{else}} -
    - Unable to get air reading -
    - {{/if}} -
    -
    - - - {{else data.mode == 40}} -

    Remote Signaling System

    -
    -
    - Frequency: -
    -
    - {{:data.records.signal_freq}} -
    -   - {{:helper.link('-1', null, {'cartmenu' : "1", 'choice' : "Signal Frequency", 'sfreq' : "-10"}, null, null)}}  - {{:helper.link('-.2', null, {'cartmenu' : "1", 'choice' : "Signal Frequency", 'sfreq' : "-2"}, null, null)}}  - - {{:helper.link('+.2', null, {'cartmenu' : "1", 'choice' : "Signal Frequency", 'sfreq' : "2"}, null, null)}}  - {{:helper.link('+1', null, {'cartmenu' : "1", 'choice' : "Signal Frequency", 'sfreq' : "10"}, null, null)}} -
    -
    -
    -
    -
    -
    - Code: -
    -
    - - {{:data.records.signal_code}}
    -
    - {{:helper.link('-5', null, {'cartmenu' : "1", 'choice' : "Signal Code", 'scode' : "-5"}, null, null)}} - {{:helper.link('-1', null, {'cartmenu' : "1", 'choice' : "Signal Code", 'scode' : "-1"}, null, null)}} - {{:helper.link('+1', null, {'cartmenu' : "1", 'choice' : "Signal Code", 'scode' : "1"}, null, null)}} - {{:helper.link('+5', null, {'cartmenu' : "1", 'choice' : "Signal Code", 'scode' : "5"}, null, null)}} -
    -
    -
    - {{:helper.link('Send Signal', 'exclamation-circle', {'cartmenu' : "1", 'choice' : "Send Signal"}, null, null)}} -
    - - - {{else data.mode == 42}} -

    Station Status Displays Interlink

    -
    -
    - Code: -
    -
    - {{:helper.link('Clear', 'trash', {'cartmenu' : "1", 'choice' : "Status", 'statdisp' : "blank"}, null, null)}} - {{:helper.link('Shuttle ETA', 'gear', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "shuttle"}, null, null)}} - {{:helper.link('Message', 'gear', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "message"}, null, null)}} -
    -
    -
    -
    -
    - Message line 1 -
    -
    - {{:helper.link(data.records.message1 + ' (set)', 'pencil', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "setmsg1"}, null, null)}} -
    -
    -
    -
    - Message line 2 -
    -
    - {{:helper.link(data.records.message2 + ' (set)', 'pencil', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "setmsg2"}, null, null)}} -
    -
    - -
    -
    -
    - ALERT!: -
    -
    - {{:helper.link('None', 'bell', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "alert", 'exclamation-triangle' : "default"}, null, null)}} - {{:helper.link('Red Alert', 'bell', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "alert", 'exclamation-triangle' : "redalert"}, null, null)}} - {{:helper.link('Lockdown', 'exclamation-circle', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "alert", 'exclamation-triangle' : "lockdown"}, null, null)}} - {{:helper.link('Biohazard', 'exclamation-circle', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "alert", 'exclamation-triangle' : "biohazard"}, null, null)}} -
    -
    - - - {{else data.mode == 43}} -

    Station Power Monitors

    -
    - Select a power monitor: -
    - {{for data.records.powermonitors}} -
    - {{:helper.link(value.Name, 'exclamation-circle', {'cartmenu' : "1", 'choice' : "Power Select",'target' : value.ref}, null, null)}} -
    - {{/for}} - - - {{else data.mode == 433}} -

    Powernet Status

    - {{if data.records.powerconnected == 1}} -
    -
    - Total Power: -
    -
    - {{:data.records.poweravail}} W -
    -
    -
    -
    - Total Load: -
    -
    - {{:data.records.powerload}} W -
    -
    -
    -
    - Total Demand: -
    -
    - {{:data.records.powerdemand}} W -
    -
    -
    - - - {{for data.records.apcs}} - - {{:helper.string('', value.Equipment == "On" || value.Equipment == "AOn" ? '#4f7529' : '#8f1414', value.Equipment)}} - {{:helper.string('', value.Lights == "On" || value.Lights == "AOn" ? '#4f7529' : '#8f1414', value.Lights)}} - {{:helper.string('', value.Environment == "On" || value.Environment == "AOn" ? '#4f7529' : '#8f1414', value.Environment)}} - {{:helper.string('', value.CellStatus == "F" ? '#4f7529' : value.CellStatus == "C" ? '#cd6500' : '#8f1414', value.CellStatus == "M" ? 'No Cell' : value.CellPct + '%', value.CellStatus == "M" ? '' : ' (' + value.CellStatus + ')')}} - - - {{/for}} -
    AreaEquip.LightingEnviron.CellLoad
    {{:value.Name}}{1}{1}{1}{1}{2}{{:value.Load}}W
    -
    - {{else}} - Power monitor not connected to net. - {{/if}} - - - - {{else data.mode == 44}} -

    Medical Record List

    -
    - Select A record -
    -
    - {{for data.records.medical_records}} -
    - {{:helper.link(value.Name, 'gear', {'cartmenu' : "1", 'choice' : "Medical Records",'target' : value.ref}, null, null)}} -
    - {{/for}} - - - {{else data.mode == 441}} -

    Medical Record

    -
    -
    -
    - {{if data.records.general_exists == 1}} - Name: {{:data.records.general.name}}
    - Sex: {{:data.records.general.sex}}
    - Species: {{:data.records.general.species}}
    - Age: {{:data.records.general.age}}
    - Rank: {{:data.records.general.rank}}
    - Fingerprint: {{:data.records.general.fingerprint}}
    - Physical Status: {{:data.records.general.p_stat}}
    - Mental Status: {{:data.records.general.m_stat}}

    - {{else}} - - General Record Lost!

    -
    - {{/if}} - {{if data.records.medical_exists == 1}} - Medical Data:
    - Blood Type: {{:data.records.medical.b_type}}

    - Minor Disabilities: {{:data.records.medical.mi_dis}}
    - Details: {{:data.records.medical.mi_dis_d}}

    - Major Disabilities: {{:data.records.medical.ma_dis}}
    - Details: {{:data.records.medical.ma_dis_d}}

    - Allergies: {{:data.records.medical.alg}}
    - Details: {{:data.records.medical.alg_d}}

    - Current Disease: {{:data.records.medical.cdi}}
    - Details: {{:data.records.medical.alg_d}}

    - Important Notes: {{:data.records.medical.notes}} - {{else}} - - Medical Record Lost! -
    -
    -
    - {{/if}} -
    -
    -
    - - - {{else data.mode == 45}} -

    Security Record List

    -
    - Select A record -
    -
    - {{for data.records.security_records}} -
    - {{:helper.link(value.Name, 'gear', {'cartmenu' : "1", 'choice' : "Security Records",'target' : value.ref}, null, null)}} -
    - {{/for}} - - - {{else data.mode == 451}} -

    Security Record

    -
    -
    -
    - {{if data.records.general_exists == 1}} - Name: {{:data.records.general.name}}
    - Sex: {{:data.records.general.sex}}
    - Species: {{:data.records.general.species}}
    - Age: {{:data.records.general.age}}
    - Rank: {{:data.records.general.rank}}
    - Fingerprint: {{:data.records.general.fingerprint}}
    - Physical Status: {{:data.records.general.p_stat}}
    - Mental Status: {{:data.records.general.m_stat}}

    - {{else}} - - General Record Lost!

    -
    - {{/if}} - {{if data.records.security_exists == 1}} - Security Data:
    - Criminal Status: {{:data.records.security.criminal}}

    - Minor Crimes: {{:data.records.security.mi_crim}}
    - Details: {{:data.records.security.mi_crim_d}}

    - Major Crimes: {{:data.records.security.ma_crim}}
    - Details: {{:data.records.security.ma_crim_d}}

    - Important Notes: {{:data.records.security.notes}} - {{else}} - - Security Record Lost!

    -
    - {{/if}} -
    -
    -
    - - - {{else data.mode == 46}} -

    Security Bot Control

    - {{if data.records.beepsky.active == null || data.records.beepsky.active == 0}} - {{if data.records.beepsky.count == 0}} -

    No bots found.

    - {{else}} -
    - Select A Bot. -
    -
    - {{for data.records.beepsky.bots}} -
    - {{:helper.link(value.Name, 'gear', {'radiomenu' : "1", 'op' : "control",'bot' : value.ref}, null, null)}} (Location: {{:value.Location}}) -
    - {{/for}} - {{/if}} -
    - {{:helper.link('Scan for Bots','gear', {'radiomenu' : "1", 'op' : "scanbots"}, null, null)}} - {{else}} -

    {{:data.records.beepsky.active}}

    -

    - {{if data.records.beepsky.botstatus.mode == -1}} -

    Waiting for response...

    - {{else}} -

    Status:

    -
    -
    -
    - Location: -
    -
    - {{:data.records.beepsky.botstatus.loca}} -
    -
    -
    -
    - Mode: -
    -
    - - {{if data.records.beepsky.botstatus.mode ==0}} - Ready - {{else data.records.beepsky.botstatus.mode == 1}} - Apprehending target - {{else data.records.beepsky.botstatus.mode ==2 || data.records.beepsky.botstatus.mode == 3}} - Arresting target - {{else data.records.beepsky.botstatus.mode ==4}} - Starting patrol - {{else data.records.beepsky.botstatus.mode ==5}} - On Patrol - {{else data.records.beepsky.botstatus.mode ==6}} - Responding to summons - {{/if}} - -
    -
    -
    - {{:helper.link('Stop Patrol', 'gear', {'radiomenu' : "1", 'op' : "stop"}, null, null)}} - {{:helper.link('Start Patrol', 'gear', {'radiomenu' : "1", 'op' : "go"}, null, null)}} - {{:helper.link('Summon Bot', 'gear', {'radiomenu' : "1", 'op' : "summon"}, null, null)}} -
    - {{/if}} - {{:helper.link('Return to Bot list', 'gear', {'radiomenu' : "1", 'op' : "botlist"}, null, null)}} - {{/if}} - - - {{else data.mode == 47}} -

    Supply Record Interlink

    -
    -
    - Location: -
    -
    - - {{if data.records.supply.shuttle_moving}} - Moving to {{:data.records.supply.shuttle_loc}} - {{else}} - Shuttle at {{:data.records.supply.shuttle_loc}} - {{/if}} -
    - {{:data.records.supply.shuttle_time}} -
    -
    -
    -
    -
    -
    - Current Approved Orders
    - {{if data.records.supply.approved_count == 0}} - No current approved orders

    - {{else}} - {{for data.records.supply.approved}} - #{{:value.Number}} - {{:value.Name}} approved by {{:value.OrderedBy}}
    {{if value.Comment != ""}} {{:value.Comment}}
    {{/if}}
    - {{/for}} - {{/if}} -

    - Current Requested Orders
    - {{if data.records.supply.requests_count == 0}} - No current requested orders

    - {{else}} - {{for data.records.supply.requests}} - #{{:value.Number}} - {{:value.Name}} requested by {{:value.OrderedBy}}
    {{if value.Comment != ""}} {{:value.Comment}}
    {{/if}}
    - {{/for}} - {{/if}} -
    -
    -
    - - - {{else data.mode == 48}} -

    Mule Control

    - {{if data.records.mulebot.active == null || data.records.mulebot.active == 0}} - {{if data.records.mulebot.count == 0}} -

    No bots found.

    - {{else}} -

    Mule List

    -
    - Select A Mulebot -
    -
    - {{for data.records.mulebot.bots}} -
    - {{:helper.link(value.Name, 'gear', {'radiomenu' : "1", 'op' : "control",'bot' : value.ref}, null, null)}} (Location: {{:value.Location}}) -
    - {{/for}} - {{/if}} -
    - {{:helper.link('Scan for Bots','gear', {'radiomenu' : "1", 'op' : "scanbots"}, null, null)}} - {{else}} - {{if data.records.mulebot.botstatus.mode == -1}} -

    Waiting for response...

    - {{else}} -

    Status:

    -
    -
    -
    - Location: -
    -
    - {{:data.records.mulebot.botstatus.loca}} -
    -
    -
    -
    - Mode: -
    -
    - - {{if data.records.mulebot.botstatus.mode ==0}} - Ready - {{else data.records.mulebot.botstatus.mode == 1}} - Loading/Unloading - {{else data.records.mulebot.botstatus.mode ==2}} - Navigating to Delivery Location - {{else data.records.mulebot.botstatus.mode == 3}} - Navigating to Home - {{else data.records.mulebot.botstatus.mode ==4}} - Waiting for Clear Path - {{else data.records.mulebot.botstatus.mode ==5 || data.records.mulebot.botstatus.mode == 6}} - Calculating navigation Path - {{else data.records.mulebot.botstatus.mode ==7}} - Unable to locate destination - {{/if}} - -
    -
    -
    -
    - Current Load: -
    -
    - - {{:helper.link(data.records.mulebot.botstatus.load == null ? 'None (Unload)' : data.records.mulebot.botstatus.load + ' (Unload)', 'gear', {'radiomenu' : "1", 'op' : "unload"},data.records.mulebot.botstatus.load == null ? 'disabled' : null, null)}} - -
    -
    -
    -
    - Power: -
    -
    - - {{:data.records.mulebot.botstatus.powr}}% - -
    -
    -
    -
    - Destination: -
    -
    - {{:helper.link(data.records.mulebot.botstatus.dest == null || data.records.mulebot.botstatus.dest == "" ? 'None (Set)': data.records.mulebot.botstatus.dest+ ' (Set)', 'gear', {'radiomenu' : "1", 'op' : "setdest"}, null, null)}} -
    -
    -
    -
    - Home: -
    -
    - {{if data.records.mulebot.botstatus.home == null}} None {{else}} {{:data.records.mulebot.botstatus.home}} {{/if}} -
    -
    -
    -
    - Auto Return: -
    -
    - {{:helper.link(data.records.mulebot.botstatus.retn == 1 ? 'ON' : 'OFF', 'gear', {'radiomenu' : "1", 'op' : data.records.mulebot.botstatus.retn==1 ? "retoff" : "reton"}, null, null)}} -
    -
    -
    -
    - Auto Pickup: -
    -
    - {{:helper.link(data.records.mulebot.botstatus.pick==1? 'ON' : 'OFF', 'gear', {'radiomenu' : "1", 'op' : data.records.mulebot.botstatus.pick==1 ? "pickoff" : "pickon"}, null, null)}} -
    -
    -
    -
    - Functions: -
    -
    - {{:helper.link('Stop', 'gear', {'radiomenu' : "1", 'op' : "stop"}, null, null)}} - {{:helper.link('Proceed', 'gear', {'radiomenu' : "1", 'op' : "go"}, null, null)}} - {{:helper.link('Return Home', 'gear', {'radiomenu' : "1", 'op' : "home"}, null, null)}} -
    -
    -

    - {{:helper.link('Return to Bot list', 'gear', {'radiomenu' : "1", 'op' : "botlist"}, null, null)}} - {{/if}} - {{/if}} - - - {{else data.mode == 49}} -

    Janatorial Supplies Locator

    -
    - Current Location: - {{if data.records.janitor.user_loc.x == 0}} - Unknown - {{else}} - {{:data.records.janitor.user_loc.x}} / {{:data.records.janitor.user_loc.y}} - {{/if}} -
    -
    - {{for data.records.janitor.mops}} - {{if value.x==0}} - Unable to locate Mop - {{else}} - Mop Location: - ({{:value.x}} / {{:value.y}}) - {{:value.dir}} - Status: {{:value.status}}
    - {{/if}} - {{/for}} -
    -
    - {{for data.records.janitor.buckets}} - {{if value.x==0}} - Unable to locate Water Buckets - {{else}} - Water Buckets Location: - ({{:value.x}} / {{:value.y}}) - {{:value.dir}} - Water Level: {{:value.status}}
    - {{/if}} - {{/for}} -
    -
    - {{for data.records.janitor.cleanbots}} - {{if value.x==0}} - Unable to locate Clean Bots - {{else}} - Clean Bots Location: - ({{:value.x}} / {{:value.y}}) - {{:value.dir}} - Status: {{:value.status}}
    - {{/if}} - {{/for}} -
    -
    - {{for data.records.janitor.carts}} - {{if value.x==0}} - Unable to locate Janitorial Cart - {{else}} - Janitorial cart Location: - ({{:value.x}} / {{:value.y}}) - {{:value.dir}} - Status: {{:value.status}}
    - {{/if}} - {{/for}} -
    - {{/if}} {{else}}







    No Owner information found, please swipe ID
    -{{/if}} - +{{/if}} \ No newline at end of file diff --git a/nano/templates/pda_atmos_scan.tmpl b/nano/templates/pda_atmos_scan.tmpl new file mode 100644 index 00000000000..80fa3838995 --- /dev/null +++ b/nano/templates/pda_atmos_scan.tmpl @@ -0,0 +1,60 @@ + +
    +
    + {{if data.aircontents.reading == 1}} +
    + Pressure: +
    +
    + {{:helper.string('{1} kPa', data.aircontents.pressure < 80 || data.aircontents.pressure > 120 ? 'bad' : data.aircontents.pressure < 95 || data.aircontents.pressure > 110 ? 'average' : 'good' , data.aircontents.pressure)}} +
    +
    + Temperature: +
    +
    + {{:helper.string('{1} °C', data.aircontents.temp < 5 || data.aircontents.temp > 35 ? 'bad' : data.aircontents.temp < 15 || data.aircontents.temp > 25 ? 'average' : 'good' , data.aircontents.temp)}} +
    +
    +
    + Oxygen: +
    +
    + {{:helper.string('{1}%', data.aircontents.oxygen < 17 ? 'bad' : data.aircontents.oxygen < 19 ? 'average' : 'good' , data.aircontents.oxygen)}} +
    +
    + Nitrogen: +
    +
    + {{:helper.string('{1}%', data.aircontents.nitrogen > 82 ? 'bad' : data.aircontents.nitrogen > 80 ? 'average' : 'good' , data.aircontents.nitrogen)}} +
    +
    + Carbon Dioxide: +
    +
    + {{:helper.string('{1}%', data.aircontents.carbon_dioxide > 5 ? 'bad' : 'good' , data.aircontents.carbon_dioxide)}} +
    +
    + Plasma: +
    +
    + {{:helper.string('{1}%', data.aircontents.plasma > 0 ? 'bad' : 'good' , data.aircontents.plasma)}} + +
    + {{if data.aircontents.other > 0}} +
    + Unknown: +
    +
    + {{:data.aircontents.other}}% +
    + {{/if}} + {{else}} +
    + Unable to get air reading +
    + {{/if}} +
    +
    \ No newline at end of file diff --git a/nano/templates/pda_janitor.tmpl b/nano/templates/pda_janitor.tmpl new file mode 100644 index 00000000000..a2fd282ad3f --- /dev/null +++ b/nano/templates/pda_janitor.tmpl @@ -0,0 +1,50 @@ +
    +
    + Current Location: + {{if data.janitor.user_loc.x == 0}} + Unknown + {{else}} + {{:data.janitor.user_loc.x}} / {{:data.janitor.user_loc.y}} + {{/if}} +
    +
    + {{for data.janitor.mops}} + {{if value.x==0}} + Unable to locate Mop + {{else}} + Mop Location: + ({{:value.x}} / {{:value.y}}) - {{:value.dir}} - Status: {{:value.status}}
    + {{/if}} + {{/for}} +
    +
    + {{for data.janitor.buckets}} + {{if value.x==0}} + Unable to locate Water Buckets + {{else}} + Water Buckets Location: + ({{:value.x}} / {{:value.y}}) - {{:value.dir}} - Water Level: {{:value.status}}
    + {{/if}} + {{/for}} +
    +
    + {{for data.janitor.cleanbots}} + {{if value.x==0}} + Unable to locate Clean Bots + {{else}} + Clean Bots Location: + ({{:value.x}} / {{:value.y}}) - {{:value.dir}} - Status: {{:value.status}}
    + {{/if}} + {{/for}} +
    +
    + {{for data.janitor.carts}} + {{if value.x==0}} + Unable to locate Janitorial Cart + {{else}} + Janitorial cart Location: + ({{:value.x}} / {{:value.y}}) - {{:value.dir}} - Status: {{:value.status}}
    + {{/if}} + {{/for}} +
    +
    \ No newline at end of file diff --git a/nano/templates/pda_main_menu.tmpl b/nano/templates/pda_main_menu.tmpl new file mode 100644 index 00000000000..680e4a8fa75 --- /dev/null +++ b/nano/templates/pda_main_menu.tmpl @@ -0,0 +1,48 @@ + +
    +
    + Owner: +
    +
    + {{:data.owner}}, {{:data.ownjob}} +
    +
    +
    +
    + ID: +
    +
    + {{:helper.link('Update PDA Info', 'refresh', {'choice' : "UpdateInfo"}, data.idInserted ? null : 'disabled', 'pdalink fixedLeftWide')}} +
    +
    + +
    +

    Functions

    +
    +{{for data.categories : cat : i}} + +{{/for}} + +{{if data.pai}} +
    +
    + PAI Utilities: +
    +
    + {{:helper.link('Configuration', 'gear', {'choice' : "pai", 'option' : "1"}, null, 'pdalink fixedLeft')}} + {{:helper.link('Eject pAI', 'eject', {'choice' : "pai", 'option' : "2"}, null, 'pdalink fixedLeft')}} +
    +
    +{{/if}} \ No newline at end of file diff --git a/nano/templates/pda_manifest.tmpl b/nano/templates/pda_manifest.tmpl new file mode 100644 index 00000000000..ef9e91a088f --- /dev/null +++ b/nano/templates/pda_manifest.tmpl @@ -0,0 +1,96 @@ + +
    +
    + {{if data.manifest.heads}} + + {{for data.manifest["heads"]}} + {{if value.rank == "Captain"}} + + {{else}} + + {{/if}} + {{/for}} + {{/if}} + {{if data.manifest.sec}} + + {{for data.manifest["sec"]}} + {{if value.rank == "Head of Security"}} + + {{else}} + + {{/if}} + {{/for}} + {{/if}} + {{if data.manifest.eng}} + + {{for data.manifest["eng"]}} + {{if value.rank == "Chief Engineer"}} + + {{else}} + + {{/if}} + {{/for}} + {{/if}} + {{if data.manifest.med}} + + {{for data.manifest["med"]}} + {{if value.rank == "Chief Medical Officer"}} + + {{else}} + + {{/if}} + {{/for}} + {{/if}} + {{if data.manifest.sci}} + + {{for data.manifest["sci"]}} + {{if value.rank == "Research Director"}} + + {{else}} + + {{/if}} + {{/for}} + {{/if}} + {{if data.manifest.ser}} + + {{for data.manifest["ser"]}} + {{if value.rank == "Head of Personnel"}} + + {{else}} + + {{/if}} + {{/for}} + {{/if}} + {{if data.manifest.sup}} + + {{for data.manifest["sup"]}} + {{if value.rank == "Head of Personnel"}} + + {{else value.rank == "Quartermaster"}} + + {{else}} + + {{/if}} + {{/for}} + {{/if}} + {{if data.manifest.civ}} + + {{for data.manifest["civ"]}} + {{if value.rank == "Head of Personnel"}} + + {{else}} + + {{/if}} + {{/for}} + {{/if}} + {{if data.manifest.misc}} + + {{for data.manifest["misc"]}} + + {{/for}} + {{/if}} +
    Command
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Security
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Engineering
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Medical
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Science
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Service
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Supply
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Civilian
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Misc
    {{:value.name}}{{:value.rank}}{{:value.active}}
    +
    \ No newline at end of file diff --git a/nano/templates/pda_medical.tmpl b/nano/templates/pda_medical.tmpl new file mode 100644 index 00000000000..777fb91f4b8 --- /dev/null +++ b/nano/templates/pda_medical.tmpl @@ -0,0 +1,54 @@ +{{if !data.records}} +
    +
    Select a record:
    +
    + {{for data.recordsList}} +
    + {{:helper.link(value.Name, 'user', {'choice' : "Records", 'target' : value.ref}, null, 'pdalink fixedLeftWidest')}} +
    + {{empty}} +
    + No records found. +
    + {{/for}} +{{else}} +
    +
    +
    + {{if data.records.general}} + Name: {{:data.records.general.name}}
    + Sex: {{:data.records.general.sex}}
    + Species: {{:data.records.general.species}}
    + Age: {{:data.records.general.age}}
    + Rank: {{:data.records.general.rank}}
    + Fingerprint: {{:data.records.general.fingerprint}}
    + Physical Status: {{:data.records.general.p_stat}}
    + Mental Status: {{:data.records.general.m_stat}}

    + {{else}} + + General Record Lost!

    +
    + {{/if}} + {{if data.records.medical}} +
    +
    Medical Data:
    +
    + Blood Type: {{:data.records.medical.b_type}}

    + Minor Disabilities: {{:data.records.medical.mi_dis}}
    + Details: {{:data.records.medical.mi_dis_d}}

    + Major Disabilities: {{:data.records.medical.ma_dis}}
    + Details: {{:data.records.medical.ma_dis_d}}

    + Allergies: {{:data.records.medical.alg}}
    + Details: {{:data.records.medical.alg_d}}

    + Current Disease: {{:data.records.medical.cdi}}
    + Details: {{:data.records.medical.alg_d}}

    + Important Notes: {{:data.records.medical.notes}} + {{else}} + + Medical Record Lost! + + {{/if}} +
    +
    +
    +{{/if}} \ No newline at end of file diff --git a/nano/templates/pda_messenger.tmpl b/nano/templates/pda_messenger.tmpl new file mode 100644 index 00000000000..633ae7d4691 --- /dev/null +++ b/nano/templates/pda_messenger.tmpl @@ -0,0 +1,81 @@ + +{{if data.active_conversation}} +
    +
    + Messenger Functions: +
    +
    + {{:helper.link('Delete Conversation', 'trash', {'choice' : "Clear", 'option' : "Convo"}, null, 'pdalink fixedLeftWide')}} +
    +
    +
    +
    +

    Conversation with: {{:data.convo_name}} ({{:data.convo_job}})

    +
    +
    +
    + {{for data.messages}} + {{if data.active_conversation == value.target}} + {{if value.sent==0}} + Them: {{:value.message}}
    + {{else}} + You: {{:value.message}}
    + {{/if}} + {{/if}} + {{/for}} +
    +
    +
    + {{:helper.link('Reply', 'comment', {'choice' : "Message", 'target': data.active_conversation}, null, 'pdalink fixedLeft')}} +{{else}} +
    +
    + Messenger Functions: +
    +
    + {{:helper.link(data.silent==1 ? 'Ringer: Off' : 'Ringer: On', data.silent==1 ? 'volume-off' : 'volume-up', {'choice' : "Toggle Ringer"}, null, 'pdalink fixedLeftWide')}} + {{:helper.link(data.toff==1 ? 'Messenger: Off' : 'Messenger: On',data.toff==1 ? 'close':'check', {'choice' : "Toggle Messenger"}, null, 'pdalink fixedLeftWide')}} + {{:helper.link('Set Ringtone', 'comment', {'choice' : "Ringtone"}, null, 'pdalink fixedLeftWide')}} + {{:helper.link('Delete all Conversations', 'trash', {'choice' : "Clear", 'option' : "All"}, null, 'pdalink fixedLeftWider')}} +
    +
    + {{if data.toff == 0}} +
    + {{if data.charges}} +
    + {{:data.charges}} charges left. +

    +
    + {{/if}} + + {{if data.pda_count == 0}} + No other PDAS located + {{else}} +

    Current Conversations

    + {{for data.convopdas}} +
    + {{:helper.link(value.Name, 'arrow-circle-down', {'choice' : "Select Conversation", 'convo' : value.Reference } , null, 'pdalink')}} + {{if data.charges}} + {{for data.plugins : plugin : i}} + {{:helper.link(plugin.name, plugin.icon, {'choice' : "Messenger Plugin", 'plugin' : plugin.ref, 'target' : value.Reference}, null, 'pdalink fixedLeft')}} + {{/for}} + {{/if}} +
    + {{/for}} +

    Other PDAs

    + {{for data.pdas}} +
    + {{:helper.link(value.Name, 'arrow-circle-down', {'choice' : "Message", 'target' : value.Reference}, null, 'pdalink')}} + {{if data.charges}} + {{for data.plugins : plugin : i}} + {{:helper.link(plugin.name, plugin.icon, {'choice' : "Messenger Plugin", 'plugin' : plugin.ref, 'target' : value.Reference}, null, 'pdalink fixedLeft')}} + {{/for}} + {{/if}} +
    + {{/for}} + {{/if}} + {{/if}} +{{/if}} \ No newline at end of file diff --git a/nano/templates/pda_mule.tmpl b/nano/templates/pda_mule.tmpl new file mode 100644 index 00000000000..cf3c5eff6f6 --- /dev/null +++ b/nano/templates/pda_mule.tmpl @@ -0,0 +1,118 @@ +{{if !data.mulebot.active}} + {{if data.mulebot.count == 0}} +

    No bots found.

    + {{else}} +
    + Select a MULE: +
    +
    + {{for data.mulebot.bots}} +
    + {{:helper.link(value.Name, 'gear', {'radiomenu' : "1", 'op' : "control",'bot' : value.ref}, null, 'pdalink fixedLeftWidest')}} (Location: {{:value.Location}}) +
    + {{/for}} + {{/if}} +
    + {{:helper.link('Scan for Bots','rss', {'radiomenu' : "1", 'op' : "scanbots"}, null, 'pdalink fixedLeftWidest')}} +{{else}} +

    {{:data.mulebot.active}}

    + {{if data.mulebot.botstatus.mode == -1}} +

    Waiting for response...

    + {{else}} +

    Status:

    +
    +
    + Location: +
    +
    + {{:data.mulebot.botstatus.loca}} +
    +
    +
    +
    + Mode: +
    +
    + + {{if data.mulebot.botstatus.mode == 0}} + Ready + {{else data.mulebot.botstatus.mode == 1}} + Loading/Unloading + {{else data.mulebot.botstatus.mode == 2}} + Navigating to Delivery Location + {{else data.mulebot.botstatus.mode == 3}} + Navigating to Home + {{else data.mulebot.botstatus.mode == 4}} + Waiting for Clear Path + {{else data.mulebot.botstatus.mode == 5 || data.mulebot.botstatus.mode == 6}} + Calculating navigation Path + {{else data.mulebot.botstatus.mode == 7}} + Unable to locate destination + {{/if}} + +
    +
    +
    +
    + Current Load: +
    +
    + + {{:helper.link(data.mulebot.botstatus.load == null ? 'None (Unload)' : data.mulebot.botstatus.load + ' (Unload)', 'archive', {'radiomenu' : "1", 'op' : "unload"},data.mulebot.botstatus.load == null ? 'disabled' : null, 'pdalink fixedLeftWidest')}} + +
    +
    +
    +
    + Power: +
    +
    + + {{:data.mulebot.botstatus.powr}}% + +
    +
    +
    +
    + Destination: +
    +
    + {{:helper.link(data.mulebot.botstatus.dest == null || data.mulebot.botstatus.dest == "" ? 'None (Set)' : data.mulebot.botstatus.dest + ' (Set)', 'gear', {'radiomenu' : "1", 'op' : "setdest"}, null, 'pdalink fixedLeftWidest')}} +
    +
    +
    +
    + Home: +
    +
    + {{if data.mulebot.botstatus.home == null}} None {{else}} {{:data.mulebot.botstatus.home}} {{/if}} +
    +
    +
    +
    + Auto Return: +
    +
    + {{:helper.link(data.mulebot.botstatus.retn == 1 ? 'ON' : 'OFF', 'gear', {'radiomenu' : "1", 'op' : (data.mulebot.botstatus.retn==1 ? "retoff" : "reton")}, null, 'pdalink fixedLeftWidest')}} +
    +
    +
    +
    + Auto Pickup: +
    +
    + {{:helper.link(data.mulebot.botstatus.pick==1? 'ON' : 'OFF', 'gear', {'radiomenu' : "1", 'op' : (data.mulebot.botstatus.pick==1 ? "pickoff" : "pickon")}, null, 'pdalink fixedLeftWidest')}} +
    +
    +
    +
    + Functions: +
    +
    + {{:helper.link('Stop', 'gear', {'radiomenu' : "1", 'op' : "stop"}, null, 'pdalink fixedLeft')}} + {{:helper.link('Proceed', 'gear', {'radiomenu' : "1", 'op' : "go"}, null, 'pdalink fixedLeft')}} + {{:helper.link('Return Home', 'gear', {'radiomenu' : "1", 'op' : "home"}, null, 'pdalink fixedLeft')}} +
    +
    + {{/if}} +{{/if}} \ No newline at end of file diff --git a/nano/templates/pda_notekeeper.tmpl b/nano/templates/pda_notekeeper.tmpl new file mode 100644 index 00000000000..53db3be6438 --- /dev/null +++ b/nano/templates/pda_notekeeper.tmpl @@ -0,0 +1,21 @@ + +
    +
    + Notes: +
    +
    +
    +
    +
    + {{:data.note}} +
    +
    +
    +
    +
    + {{:helper.link('Edit Notes', 'pencil-square-o', {'choice': "Edit"}, null, 'pdalink')}} +
    +
    \ No newline at end of file diff --git a/nano/templates/pda_power.tmpl b/nano/templates/pda_power.tmpl new file mode 100644 index 00000000000..7ba04188b71 --- /dev/null +++ b/nano/templates/pda_power.tmpl @@ -0,0 +1,49 @@ +{{if !data.records.powerconnected}} +
    +
    Select a power monitor:
    +
    + {{for data.records.powermonitors}} +
    + {{:helper.link(value.Name, 'exclamation-circle', {'choice' : "Power Select", 'target' : value.ref}, null, 'pdalink fixedLeftWidest')}} +
    + {{/for}} +{{else}} +
    +
    + Total Power: +
    +
    + {{:data.records.poweravail}} W +
    +
    +
    +
    + Total Load: +
    +
    + {{:data.records.powerload}} W +
    +
    +
    +
    + Total Demand: +
    +
    + {{:data.records.powerdemand}} W +
    +
    +
    + + + {{for data.records.apcs}} + + {{:helper.string('', value.Equipment == "On" || value.Equipment == "AOn" ? '#4f7529' : '#8f1414', value.Equipment)}} + {{:helper.string('', value.Lights == "On" || value.Lights == "AOn" ? '#4f7529' : '#8f1414', value.Lights)}} + {{:helper.string('', value.Environment == "On" || value.Environment == "AOn" ? '#4f7529' : '#8f1414', value.Environment)}} + {{:helper.string('', value.CellStatus == "F" ? '#4f7529' : value.CellStatus == "C" ? '#cd6500' : '#8f1414', value.CellStatus == "M" ? 'No Cell' : value.CellPct + '%', value.CellStatus == "M" ? '' : ' (' + value.CellStatus + ')')}} + + + {{/for}} +
    AreaEquip.LightingEnviron.CellLoad
    {{:value.Name}}{1}{1}{1}{1}{2}{{:value.Load}}W
    +
    +{{/if}} \ No newline at end of file diff --git a/nano/templates/pda_secbot.tmpl b/nano/templates/pda_secbot.tmpl new file mode 100644 index 00000000000..6ff8c98e147 --- /dev/null +++ b/nano/templates/pda_secbot.tmpl @@ -0,0 +1,59 @@ +{{if !data.beepsky.active}} + {{if data.beepsky.count == 0}} +

    No bots found.

    + {{else}} +
    + Select a bot: +
    +
    + {{for data.beepsky.bots}} +
    + {{:helper.link(value.Name, 'gear', {'radiomenu' : "1", 'op' : "control",'bot' : value.ref}, null, 'pdalink fixedLeftWidest')}} (Location: {{:value.Location}}) +
    + {{/for}} + {{/if}} +
    + {{:helper.link('Scan for Bots','rss', {'radiomenu' : "1", 'op' : "scanbots"}, null, 'pdalink fixedLeftWidest')}} +{{else}} +

    {{:data.beepsky.active}}

    + {{if data.beepsky.botstatus.mode == -1}} +

    Waiting for response...

    + {{else}} +

    Status:

    +
    +
    + Location: +
    +
    + {{:data.beepsky.botstatus.loca}} +
    +
    +
    +
    + Mode: +
    +
    + + {{if data.beepsky.botstatus.mode ==0}} + Ready + {{else data.beepsky.botstatus.mode == 1}} + Apprehending target + {{else data.beepsky.botstatus.mode ==2 || data.beepsky.botstatus.mode == 3}} + Arresting target + {{else data.beepsky.botstatus.mode ==4}} + Starting patrol + {{else data.beepsky.botstatus.mode ==5}} + On Patrol + {{else data.beepsky.botstatus.mode ==6}} + Responding to summons + {{/if}} + +
    +
    +
    + {{:helper.link('Stop Patrol', 'gear', {'radiomenu' : "1", 'op' : "stop"}, null, 'pdalink fixedLeftWide')}} + {{:helper.link('Start Patrol', 'gear', {'radiomenu' : "1", 'op' : "go"}, null, 'pdalink fixedLeftWide')}} + {{:helper.link('Summon Bot', 'gear', {'radiomenu' : "1", 'op' : "summon"}, null, 'pdalink fixedLeftWide')}} +
    + {{/if}} +{{/if}} \ No newline at end of file diff --git a/nano/templates/pda_security.tmpl b/nano/templates/pda_security.tmpl new file mode 100644 index 00000000000..53d40185e05 --- /dev/null +++ b/nano/templates/pda_security.tmpl @@ -0,0 +1,50 @@ +{{if !data.records}} +
    +
    Select a record:
    +
    + {{for data.recordsList}} +
    + {{:helper.link(value.Name, 'user', {'choice' : "Records", 'target' : value.ref}, null, 'pdalink fixedLeftWidest')}} +
    + {{empty}} +
    + No records found. +
    + {{/for}} +{{else}} +
    +
    +
    + {{if data.records.general}} + Name: {{:data.records.general.name}}
    + Sex: {{:data.records.general.sex}}
    + Species: {{:data.records.general.species}}
    + Age: {{:data.records.general.age}}
    + Rank: {{:data.records.general.rank}}
    + Fingerprint: {{:data.records.general.fingerprint}}
    + Physical Status: {{:data.records.general.p_stat}}
    + Mental Status: {{:data.records.general.m_stat}}

    + {{else}} + + General Record Lost!

    +
    + {{/if}} + {{if data.records.security}} +
    +
    Security Data:
    +
    + Criminal Status: {{:data.records.security.criminal}}

    + Minor Crimes: {{:data.records.security.mi_crim}}
    + Details: {{:data.records.security.mi_crim_d}}

    + Major Crimes: {{:data.records.security.ma_crim}}
    + Details: {{:data.records.security.ma_crim_d}}

    + Important Notes: {{:data.records.security.notes}} + {{else}} + + Security Record Lost!

    +
    + {{/if}} +
    +
    +
    +{{/if}} \ No newline at end of file diff --git a/nano/templates/pda_signaller.tmpl b/nano/templates/pda_signaller.tmpl new file mode 100644 index 00000000000..2b5f148b025 --- /dev/null +++ b/nano/templates/pda_signaller.tmpl @@ -0,0 +1,38 @@ + +
    +
    + Frequency: +
    +
    + {{:data.signal_freq}} +
    +   + {{:helper.link('-1', null, {'choice' : "Signal Frequency", 'sfreq' : "-10"}, null, null)}}  + {{:helper.link('-.2', null, {'choice' : "Signal Frequency", 'sfreq' : "-2"}, null, null)}}  + + {{:helper.link('+.2', null, {'choice' : "Signal Frequency", 'sfreq' : "2"}, null, null)}}  + {{:helper.link('+1', null, {'choice' : "Signal Frequency", 'sfreq' : "10"}, null, null)}} +
    +
    +
    +
    +
    +
    + Code: +
    +
    + + {{:data.signal_code}}
    +
    + {{:helper.link('-5', null, {'choice' : "Signal Code", 'scode' : "-5"}, null, null)}} + {{:helper.link('-1', null, {'choice' : "Signal Code", 'scode' : "-1"}, null, null)}} + {{:helper.link('+1', null, {'choice' : "Signal Code", 'scode' : "1"}, null, null)}} + {{:helper.link('+5', null, {'choice' : "Signal Code", 'scode' : "5"}, null, null)}} +
    +
    +
    + {{:helper.link('Send Signal', 'exclamation-circle', {'choice' : "Send Signal"}, null, null)}} +
    \ No newline at end of file diff --git a/nano/templates/pda_status_display.tmpl b/nano/templates/pda_status_display.tmpl new file mode 100644 index 00000000000..8b153ad0ffd --- /dev/null +++ b/nano/templates/pda_status_display.tmpl @@ -0,0 +1,44 @@ + +
    +
    + Code: +
    +
    + {{:helper.link('Clear', 'trash', {'choice' : "Status", 'statdisp' : "blank"}, null, 'pdalink fixedLeftWide')}} + {{:helper.link('Shuttle ETA', 'gear', {'cartmenu' : "1", 'choice' : "Status", 'statdisp' : "shuttle"}, null, 'pdalink fixedLeftWide')}} + {{:helper.link('Message', 'gear', {'choice' : "Status", 'statdisp' : "message"}, null, 'pdalink fixedLeftWide')}} +
    +
    +
    +
    +
    + Message line 1 +
    +
    + {{:helper.link(data.records.message1 + ' (set)', 'pencil', {'choice' : "Status", 'statdisp' : "setmsg1"}, null, 'pdalink fixedLeftWide')}} +
    +
    +
    +
    + Message line 2 +
    +
    + {{:helper.link(data.records.message2 + ' (set)', 'pencil', {'choice' : "Status", 'statdisp' : "setmsg2"}, null, 'pdalink fixedLeftWide')}} +
    +
    + +
    +
    +
    + ALERT!: +
    +
    + {{:helper.link('None', 'bell', {'choice' : "Status", 'statdisp' : "alert", 'alert' : "default"}, null, 'pdalink fixedLeftWide')}} + {{:helper.link('Red Alert', 'bell', {'choice' : "Status", 'statdisp' : "alert", 'alert' : "redalert"}, null, 'pdalink fixedLeftWide')}} + {{:helper.link('Lockdown', 'exclamation-circle', {'choice' : "Status", 'statdisp' : "alert", 'alert' : "lockdown"}, null, 'pdalink fixedLeftWide')}} + {{:helper.link('Biohazard', 'exclamation-circle', {'choice' : "Status", 'statdisp' : "alert", 'alert' : "biohazard"}, null, 'pdalink fixedLeftWide')}} +
    +
    \ No newline at end of file diff --git a/nano/templates/pda_supply.tmpl b/nano/templates/pda_supply.tmpl new file mode 100644 index 00000000000..810fc193769 --- /dev/null +++ b/nano/templates/pda_supply.tmpl @@ -0,0 +1,39 @@ +
    +
    + Location: +
    +
    + + {{if data.supply.shuttle_moving}} + Moving to {{:data.supply.shuttle_loc}} + {{else}} + Shuttle at {{:data.supply.shuttle_loc}} + {{/if}} +
    + {{:data.supply.shuttle_time}} +
    +
    +
    +
    +
    +
    + Current Approved Orders
    + {{if data.supply.approved_count == 0}} + No current approved orders

    + {{else}} + {{for data.supply.approved}} + #{{:value.Number}} - {{:value.Name}} approved by {{:value.OrderedBy}}
    {{if value.Comment != ""}} {{:value.Comment}}
    {{/if}}
    + {{/for}} + {{/if}} +

    + Current Requested Orders
    + {{if data.supply.requests_count == 0}} + No current requested orders

    + {{else}} + {{for data.supply.requests}} + #{{:value.Number}} - {{:value.Name}} requested by {{:value.OrderedBy}}
    {{if value.Comment != ""}} {{:value.Comment}}
    {{/if}}
    + {{/for}} + {{/if}} +
    +
    +
    \ No newline at end of file diff --git a/paradise.dme b/paradise.dme index e31271b9e11..111dc8d88eb 100644 --- a/paradise.dme +++ b/paradise.dme @@ -25,12 +25,14 @@ #include "code\__DEFINES\genetics.dm" #include "code\__DEFINES\hud.dm" #include "code\__DEFINES\hydroponics.dm" +#include "code\__DEFINES\is_helpers.dm" #include "code\__DEFINES\language.dm" #include "code\__DEFINES\lighting.dm" #include "code\__DEFINES\machines.dm" #include "code\__DEFINES\math.dm" #include "code\__DEFINES\misc.dm" #include "code\__DEFINES\mob.dm" +#include "code\__DEFINES\pda.dm" #include "code\__DEFINES\preferences.dm" #include "code\__DEFINES\process_scheduler.dm" #include "code\__DEFINES\qdel.dm" @@ -167,6 +169,7 @@ #include "code\controllers\Processes\shuttles.dm" #include "code\controllers\Processes\sun.dm" #include "code\controllers\Processes\ticker.dm" +#include "code\controllers\Processes\timer.dm" #include "code\controllers\Processes\vote.dm" #include "code\controllers\Processes\shuttles\emergency.dm" #include "code\controllers\Processes\shuttles\supply.dm" @@ -221,6 +224,7 @@ #include "code\datums\spells\lichdom.dm" #include "code\datums\spells\lightning.dm" #include "code\datums\spells\magnet.dm" +#include "code\datums\spells\mime.dm" #include "code\datums\spells\mind_transfer.dm" #include "code\datums\spells\projectile.dm" #include "code\datums\spells\summonitem.dm" @@ -394,7 +398,6 @@ #include "code\game\jobs\access.dm" #include "code\game\jobs\job_controller.dm" #include "code\game\jobs\job_objective.dm" -#include "code\game\jobs\jobprocs.dm" #include "code\game\jobs\jobs.dm" #include "code\game\jobs\whitelist.dm" #include "code\game\jobs\job\civilian.dm" @@ -671,10 +674,6 @@ #include "code\game\objects\items\devices\uplinks.dm" #include "code\game\objects\items\devices\violin.dm" #include "code\game\objects\items\devices\whistle.dm" -#include "code\game\objects\items\devices\PDA\cart.dm" -#include "code\game\objects\items\devices\PDA\chatroom.dm" -#include "code\game\objects\items\devices\PDA\PDA.dm" -#include "code\game\objects\items\devices\PDA\radio.dm" #include "code\game\objects\items\devices\radio\beacon.dm" #include "code\game\objects\items\devices\radio\electropack.dm" #include "code\game\objects\items\devices\radio\encryptionkey.dm" @@ -757,6 +756,7 @@ #include "code\game\objects\items\weapons\twohanded.dm" #include "code\game\objects\items\weapons\vending_items.dm" #include "code\game\objects\items\weapons\weaponry.dm" +#include "code\game\objects\items\weapons\whetstone.dm" #include "code\game\objects\items\weapons\wires.dm" #include "code\game\objects\items\weapons\grenades\bananade.dm" #include "code\game\objects\items\weapons\grenades\chem_grenade.dm" @@ -840,6 +840,7 @@ #include "code\game\objects\structures\safe.dm" #include "code\game\objects\structures\signs.dm" #include "code\game\objects\structures\spirit_board.dm" +#include "code\game\objects\structures\statue.dm" #include "code\game\objects\structures\tables_racks.dm" #include "code\game\objects\structures\tank_dispenser.dm" #include "code\game\objects\structures\target_stake.dm" @@ -884,7 +885,6 @@ #include "code\game\objects\structures\transit_tubes\station.dm" #include "code\game\objects\structures\transit_tubes\transit_tube.dm" #include "code\game\objects\structures\transit_tubes\transit_tube_pod.dm" -#include "code\game\structure\structure.dm" #include "code\game\turfs\simulated.dm" #include "code\game\turfs\turf.dm" #include "code\game\turfs\unsimulated.dm" @@ -988,6 +988,8 @@ #include "code\modules\arcade\arcade_base.dm" #include "code\modules\arcade\arcade_prize.dm" #include "code\modules\arcade\claw_game.dm" +#include "code\modules\arcade\prize_counter.dm" +#include "code\modules\arcade\prize_datums.dm" #include "code\modules\assembly\assembly.dm" #include "code\modules\assembly\bomb.dm" #include "code\modules\assembly\health.dm" @@ -1022,6 +1024,7 @@ #include "code\modules\awaymissions\maploader\swapmaps.dm" #include "code\modules\awaymissions\maploader\writer.dm" #include "code\modules\awaymissions\mission_code\academy.dm" +#include "code\modules\awaymissions\mission_code\beach.dm" #include "code\modules\awaymissions\mission_code\blackmarketpackers.dm" #include "code\modules\awaymissions\mission_code\centcomAway.dm" #include "code\modules\awaymissions\mission_code\challenge.dm" @@ -1514,6 +1517,7 @@ #include "code\modules\mob\living\simple_animal\hostile\winter_mobs.dm" #include "code\modules\mob\living\simple_animal\hostile\retaliate\clown.dm" #include "code\modules\mob\living\simple_animal\hostile\retaliate\drone.dm" +#include "code\modules\mob\living\simple_animal\hostile\retaliate\fish.dm" #include "code\modules\mob\living\simple_animal\hostile\retaliate\pet.dm" #include "code\modules\mob\living\simple_animal\hostile\retaliate\retaliate.dm" #include "code\modules\mob\living\simple_animal\hostile\retaliate\undead.dm" @@ -1561,30 +1565,13 @@ #include "code\modules\ninja\suit\shoes.dm" #include "code\modules\ninja\suit\suit.dm" #include "code\modules\ninja\suit\suit_initialisation.dm" -#include "code\modules\organs\blood.dm" -#include "code\modules\organs\organ.dm" -#include "code\modules\organs\organ_external.dm" -#include "code\modules\organs\organ_icon.dm" -#include "code\modules\organs\organ_internal.dm" -#include "code\modules\organs\organ_stump.dm" -#include "code\modules\organs\pain.dm" -#include "code\modules\organs\robolimbs.dm" -#include "code\modules\organs\skeleton.dm" -#include "code\modules\organs\wound.dm" -#include "code\modules\organs\subtypes\diona.dm" -#include "code\modules\organs\subtypes\machine.dm" -#include "code\modules\organs\subtypes\misc.dm" -#include "code\modules\organs\subtypes\nucleation.dm" -#include "code\modules\organs\subtypes\standard.dm" -#include "code\modules\organs\subtypes\unbreakable.dm" -#include "code\modules\organs\subtypes\wryn.dm" -#include "code\modules\organs\subtypes\xenos.dm" #include "code\modules\paperwork\carbonpaper.dm" #include "code\modules\paperwork\clipboard.dm" #include "code\modules\paperwork\fax.dm" #include "code\modules\paperwork\faxmachine.dm" #include "code\modules\paperwork\filingcabinet.dm" #include "code\modules\paperwork\folders.dm" +#include "code\modules\paperwork\frames.dm" #include "code\modules\paperwork\handlabeler.dm" #include "code\modules\paperwork\paper.dm" #include "code\modules\paperwork\paper_bundle.dm" @@ -1594,6 +1581,18 @@ #include "code\modules\paperwork\photography.dm" #include "code\modules\paperwork\silicon_photography.dm" #include "code\modules\paperwork\stamps.dm" +#include "code\modules\pda\ai.dm" +#include "code\modules\pda\app.dm" +#include "code\modules\pda\cart.dm" +#include "code\modules\pda\cart_apps.dm" +#include "code\modules\pda\chatroom.dm" +#include "code\modules\pda\core_apps.dm" +#include "code\modules\pda\messenger.dm" +#include "code\modules\pda\messenger_plugins.dm" +#include "code\modules\pda\PDA.dm" +#include "code\modules\pda\pdas.dm" +#include "code\modules\pda\radio.dm" +#include "code\modules\pda\utilities.dm" #include "code\modules\pooling\pool.dm" #include "code\modules\power\apc.dm" #include "code\modules\power\cable.dm" @@ -1651,6 +1650,7 @@ #include "code\modules\projectiles\guns\alien.dm" #include "code\modules\projectiles\guns\energy.dm" #include "code\modules\projectiles\guns\magic.dm" +#include "code\modules\projectiles\guns\mounted.dm" #include "code\modules\projectiles\guns\projectile.dm" #include "code\modules\projectiles\guns\syringe_gun.dm" #include "code\modules\projectiles\guns\energy\advtaser.dm" @@ -1860,6 +1860,7 @@ #include "code\modules\surgery\encased.dm" #include "code\modules\surgery\face.dm" #include "code\modules\surgery\generic.dm" +#include "code\modules\surgery\helpers.dm" #include "code\modules\surgery\implant.dm" #include "code\modules\surgery\limb_reattach.dm" #include "code\modules\surgery\organs_internal.dm" @@ -1868,6 +1869,28 @@ #include "code\modules\surgery\slime.dm" #include "code\modules\surgery\surgery.dm" #include "code\modules\surgery\tools.dm" +#include "code\modules\surgery\organs\augments_eyes.dm" +#include "code\modules\surgery\organs\augments_internal.dm" +#include "code\modules\surgery\organs\blood.dm" +#include "code\modules\surgery\organs\body_egg.dm" +#include "code\modules\surgery\organs\helpers.dm" +#include "code\modules\surgery\organs\organ.dm" +#include "code\modules\surgery\organs\organ_external.dm" +#include "code\modules\surgery\organs\organ_icon.dm" +#include "code\modules\surgery\organs\organ_internal.dm" +#include "code\modules\surgery\organs\organ_stump.dm" +#include "code\modules\surgery\organs\pain.dm" +#include "code\modules\surgery\organs\robolimbs.dm" +#include "code\modules\surgery\organs\skeleton.dm" +#include "code\modules\surgery\organs\wound.dm" +#include "code\modules\surgery\organs\subtypes\diona.dm" +#include "code\modules\surgery\organs\subtypes\machine.dm" +#include "code\modules\surgery\organs\subtypes\misc.dm" +#include "code\modules\surgery\organs\subtypes\nucleation.dm" +#include "code\modules\surgery\organs\subtypes\standard.dm" +#include "code\modules\surgery\organs\subtypes\unbreakable.dm" +#include "code\modules\surgery\organs\subtypes\wryn.dm" +#include "code\modules\surgery\organs\subtypes\xenos.dm" #include "code\modules\telesci\bscrystal.dm" #include "code\modules\telesci\gps.dm" #include "code\modules\telesci\telepad.dm" diff --git a/sound/machines/synth_no.ogg b/sound/machines/synth_no.ogg new file mode 100644 index 00000000000..f0d2c3bfb0c Binary files /dev/null and b/sound/machines/synth_no.ogg differ diff --git a/sound/machines/synth_yes.ogg b/sound/machines/synth_yes.ogg new file mode 100644 index 00000000000..300cad132ed Binary files /dev/null and b/sound/machines/synth_yes.ogg differ diff --git a/sound/misc/yeah.ogg b/sound/misc/yeah.ogg new file mode 100644 index 00000000000..355d46019e1 Binary files /dev/null and b/sound/misc/yeah.ogg differ