diff --git a/README.md b/README.md
index d33438f606..0ce4d8a094 100644
--- a/README.md
+++ b/README.md
@@ -1,147 +1,154 @@
-
-##Citadel Station 13
-Based and maintained from /tg/station.
-
-[](https://travis-ci.org/Citadel-Station-13/Citadel-Station-13) [](http://www.krihelinator.xyz)
-
-[](http://isitmaintained.com/project/Citadel-Station-13/Citadel-Station-13 "Percentage of issues still open") [](http://isitmaintained.com/project/Citadel-Station-13/Citadel-Station-13 "Average time to resolve an issue")
-
-**Upstream Information**
-**Website:** http://www.tgstation13.org
-**Code:** https://github.com/tgstation/tgstation
-**Wiki** http://tgstation13.org/wiki/Main_Page
-**IRC:** irc://irc.rizon.net/coderbus or if you dont have an IRC client, you can click [here](https://kiwiirc.com/client/irc.rizon.net:6667/?&theme=cli#coderbus).
-
-**Citadel Station Information**
-**Forums:** http://citadel-station.net/forum/
-**Ban Appeals:** http://citadel-station.net/forum/forumdisplay.php?fid=8
-**Code:** https://github.com/Citadel-Station-13/Citadel-Station-13
-**Discord:** [Here](https://discord.gg/3gJ9pnM).
-
-## DOWNLOADING
-
-There are a number of ways to download the source code. Some are described here, an alternative all-inclusive guide is also located at http://www.tgstation13.org/wiki/Downloading_the_source_code
-
-Option 1:
-Follow this: http://www.tgstation13.org/wiki/Setting_up_git
-
+
+##Citadel Station 13
+Based and maintained from /tg/station.
+
+[](https://travis-ci.org/Citadel-Station-13/Citadel-Station-13) [](http://www.krihelinator.xyz)
+
+[](http://isitmaintained.com/project/Citadel-Station-13/Citadel-Station-13 "Percentage of issues still open") [](http://isitmaintained.com/project/Citadel-Station-13/Citadel-Station-13 "Average time to resolve an issue")
+
+**Upstream Information**
+**Website:** http://www.tgstation13.org
+**Code:** https://github.com/tgstation/tgstation
+**Wiki** http://tgstation13.org/wiki/Main_Page
+**IRC:** irc://irc.rizon.net/coderbus or if you dont have an IRC client, you can click [here](https://kiwiirc.com/client/irc.rizon.net:6667/?&theme=cli#coderbus).
+
+**Citadel Station Information**
+**Forums:** http://citadel-station.net/forum/
+**Ban Appeals:** http://citadel-station.net/forum/forumdisplay.php?fid=8
+**Code:** https://github.com/Citadel-Station-13/Citadel-Station-13
+**Discord:** [Here](https://discord.gg/3gJ9pnM).
+
+## DOWNLOADING
+
+There are a number of ways to download the source code. Some are described here, an alternative all-inclusive guide is also located at http://www.tgstation13.org/wiki/Downloading_the_source_code
+
+Option 1:
+Follow this: http://www.tgstation13.org/wiki/Setting_up_git
+
Option 2: Download the source code as a zip by clicking the ZIP button in the
-code tab of https://github.com/tgstation/tgstation
-(note: this will use a lot of bandwidth if you wish to update and is a lot of
-hassle if you want to make any changes at all, so it's not recommended.)
-
-## INSTALLATION
-
-First-time installation should be fairly straightforward. First, you'll need
-BYOND installed. You can get it from http://www.byond.com/. Once you've done
-that, extract the game files to wherever you want to keep them. This is a
-sourcecode-only release, so the next step is to compile the server files.
-Open tgstation.dme by double-clicking it, open the Build menu, and click
-compile. This'll take a little while, and if everything's done right you'll get
-a message like this:
-
-```
-saving tgstation.dmb (DEBUG mode)
-tgstation.dmb - 0 errors, 0 warnings
-```
-
-If you see any errors or warnings, something has gone wrong - possibly a corrupt
-download or the files extracted wrong. If problems persist, ask for assistance
-in irc://irc.rizon.net/coderbus
-
-Once that's done, open up the config folder. You'll want to edit config.txt to
-set the probabilities for different gamemodes in Secret and to set your server
-location so that all your players don't get disconnected at the end of each
-round. It's recommended you don't turn on the gamemodes with probability 0,
-except Extended, as they have various issues and aren't currently being tested,
-so they may have unknown and bizarre bugs. Extended is essentially no mode, and
-isn't in the Secret rotation by default as it's just not very fun.
-
-You'll also want to edit config/admins.txt to remove the default admins and add
-your own. "Game Master" is the highest level of access, and probably the one
-you'll want to use for now. You can set up your own ranks and find out more in
-config/admin_ranks.txt
-
-The format is
-
-```
-byondkey = Rank
-((i.e. spessmans = Host ))
-```
-
-where the admin rank must be properly capitalised.
-
-Finally, to start the server, run Dream Daemon and enter the path to your
-compiled tgstation.dmb file. Make sure to set the port to the one you
-specified in the config.txt, and set the Security box to 'Safe'. Then press GO
-and the server should start up and be ready to join. It is also recommended that
-you set up the SQL backend (see below).
-
-## UPDATING
-
-To update an existing installation, first back up your /config and /data folders
-as these store your server configuration, player preferences and banlist.
-
-Then, extract the new files (preferably into a clean directory, but updating in
-place should work fine), copy your /config and /data folders back into the new
-install, overwriting when prompted except if we've specified otherwise, and
-recompile the game. Once you start the server up again, you should be running
-the new version.
-
-## MAPS
-
-Citadel Station maintains their own map, but frequently uses /tg/station's currently maintained maps as well.
-
-* [tgstation2 (default)](http://tgstation13.org/wiki/Boxstation)
-* [MetaStation](https://tgstation13.org/wiki/MetaStation)
-* [DeltaStation](https://tgstation13.org/wiki/DeltaStation)
-* [OmegaStation](https://tgstation13.org/wiki/OmegaStation)
-* [PubbyStation](https://tgstation13.org/wiki/PubbyStation)
-
-
-All maps have their own code file that is in the base of the _maps directory. Maps are loaded dynamically when the game starts. Follow this guideline when adding your own map, to your fork, for easy compatibility.
-
-The map that will be loaded for the upcoming round is determined by reading data/next_map.json, which is a copy of the json files found in the _maps tree. If this file does not exist, the default map from config/maps.txt will be loaded. Failing that, tgstation2 will be loaded. If you want to set a specific map to load next round you can use the Change Map verb in game before restarting the server or copy a json from _maps to data/next_map.json before starting the server. Also, for debugging purposes, ticking a corresponding map's code file in Dream Maker will force that map to load every round.
-
-If you are hosting a server, and want randomly picked maps to be played each round, you can enable map rotation in [config.txt](config/config.txt) and then set the maps to be picked in the [maps.txt](config/maps.txt) file.
-
-Anytime you want to make changes to a map it's imperative you use the [Map Merging tools](http://tgstation13.org/wiki/Map_Merger)
-
-## AWAY MISSIONS
-
-/tg/station supports loading away missions however they are disabled by default.
-
-Map files for away missions are located in the _maps/RandomZLevels directory. Each away mission includes it's own code definitions located in /code/modules/awaymissions/mission_code. These files must be included and compiled with the server beforehand otherwise the server will crash upon trying to load away missions that lack their code.
-
-To enable an away mission open `config/awaymissionconfig.txt` and uncomment one of the .dmm lines by removing the #. If more than one away mission is uncommented then the away mission loader will randomly select one the enabled ones to load.
-
-## SQL SETUP
-
-The SQL backend requires a MySQL server. SQL is required for the library, stats tracking, admin notes, and job-only bans, among other features, mostly related to server administration. Your server details go in /config/dbconfig.txt, and the SQL schema is in /SQL/tgstation_schema.sql and /SQL/tgstation_schema_prefix.sql depending on if you want table prefixes. More detailed setup instructions are located here: http://www.tgstation13.org/wiki/Downloading_the_source_code#Setting_up_the_database
-
-## IRC BOT SETUP
-
-Included in the repository is a python3 compatible IRC bot capable of relaying adminhelps to a specified
-IRC channel/server, see the /bot folder for more
-
-## CONTRIBUTING
-
-Please see [CONTRIBUTING.md](.github/CONTRIBUTING.md)
-
-## LICENSE
-
-All code after [commit 333c566b88108de218d882840e61928a9b759d8f on 2014/31/12 at 4:38 PM PST](https://github.com/tgstation/tgstation/commit/333c566b88108de218d882840e61928a9b759d8f) is licensed under [GNU AGPL v3](http://www.gnu.org/licenses/agpl-3.0.html).
-
-All code before [commit 333c566b88108de218d882840e61928a9b759d8f on 2014/31/12 at 4:38 PM PST](https://github.com/tgstation/tgstation/commit/333c566b88108de218d882840e61928a9b759d8f) is licensed under [GNU GPL v3](https://www.gnu.org/licenses/gpl-3.0.html).
-(Including tools unless their readme specifies otherwise.)
-
-See LICENSE-AGPLv3.txt and LICENSE-GPLv3.txt for more details.
-
-tgui clientside is licensed as a subproject under the MIT license.
-Font Awesome font files, used by tgui, are licensed under the SIL Open Font License v1.1
-tgui assets are licensed under a [Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/).
-
-See tgui/LICENSE.md for the MIT license.
-See tgui/assets/fonts/SIL-OFL-1.1-LICENSE.md for the SIL Open Font License.
-
-All assets including icons and sound are under a [Creative Commons 3.0 BY-SA license](http://creativecommons.org/licenses/by-sa/3.0/) unless otherwise indicated.
+code tab of https://github.com/tgstation/tgstation
+(note: this will use a lot of bandwidth if you wish to update and is a lot of
+hassle if you want to make any changes at all, so it's not recommended.)
+
+## INSTALLATION
+
+First-time installation should be fairly straightforward. First, you'll need
+BYOND installed. You can get it from http://www.byond.com/. Once you've done
+that, extract the game files to wherever you want to keep them. This is a
+sourcecode-only release, so the next step is to compile the server files.
+Open tgstation.dme by double-clicking it, open the Build menu, and click
+compile. This'll take a little while, and if everything's done right you'll get
+a message like this:
+
+```
+saving tgstation.dmb (DEBUG mode)
+tgstation.dmb - 0 errors, 0 warnings
+```
+
+If you see any errors or warnings, something has gone wrong - possibly a corrupt
+download or the files extracted wrong. If problems persist, ask for assistance
+in irc://irc.rizon.net/coderbus
+
+Once that's done, open up the config folder. You'll want to edit config.txt to
+set the probabilities for different gamemodes in Secret and to set your server
+location so that all your players don't get disconnected at the end of each
+round. It's recommended you don't turn on the gamemodes with probability 0,
+except Extended, as they have various issues and aren't currently being tested,
+so they may have unknown and bizarre bugs. Extended is essentially no mode, and
+isn't in the Secret rotation by default as it's just not very fun.
+
+You'll also want to edit config/admins.txt to remove the default admins and add
+your own. "Game Master" is the highest level of access, and probably the one
+you'll want to use for now. You can set up your own ranks and find out more in
+config/admin_ranks.txt
+
+The format is
+
+```
+byondkey = Rank
+```
+
+where the admin rank must be properly capitalised.
+
+Finally, to start the server, run Dream Daemon and enter the path to your
+compiled tgstation.dmb file. Make sure to set the port to the one you
+specified in the config.txt, and set the Security box to 'Safe'. Then press GO
+and the server should start up and be ready to join. It is also recommended that
+you set up the SQL backend (see below).
+
+## UPDATING
+
+To update an existing installation, first back up your /config and /data folders
+as these store your server configuration, player preferences and banlist.
+
+Then, extract the new files (preferably into a clean directory, but updating in
+place should work fine), copy your /config and /data folders back into the new
+install, overwriting when prompted except if we've specified otherwise, and
+recompile the game. Once you start the server up again, you should be running
+the new version.
+
+## HOSTING
+
+If you'd like a more robust server hosting option for tgstation and its
+derivatives. Check out our server tools suite at
+https://github.com/tgstation/tgstation-server
+
+## MAPS
+
+/tg/station currently comes equipped with five maps.
+
+* [BoxStation (default)](http://tgstation13.org/wiki/Boxstation)
+* [MetaStation](https://tgstation13.org/wiki/MetaStation)
+* [DeltaStation](https://tgstation13.org/wiki/DeltaStation)
+* [OmegaStation](https://tgstation13.org/wiki/OmegaStation)
+* [PubbyStation](https://tgstation13.org/wiki/PubbyStation)
+
+
+All maps have their own code file that is in the base of the _maps directory. Maps are loaded dynamically when the game starts. Follow this guideline when adding your own map, to your fork, for easy compatibility.
+
+The map that will be loaded for the upcoming round is determined by reading data/next_map.json, which is a copy of the json files found in the _maps tree. If this file does not exist, the default map from config/maps.txt will be loaded. Failing that, tgstation2 will be loaded. If you want to set a specific map to load next round you can use the Change Map verb in game before restarting the server or copy a json from _maps to data/next_map.json before starting the server. Also, for debugging purposes, ticking a corresponding map's code file in Dream Maker will force that map to load every round.
+
+If you are hosting a server, and want randomly picked maps to be played each round, you can enable map rotation in [config.txt](config/config.txt) and then set the maps to be picked in the [maps.txt](config/maps.txt) file.
+
+Anytime you want to make changes to a map it's imperative you use the [Map Merging tools](http://tgstation13.org/wiki/Map_Merger)
+
+## AWAY MISSIONS
+
+/tg/station supports loading away missions however they are disabled by default.
+
+Map files for away missions are located in the _maps/RandomZLevels directory. Each away mission includes it's own code definitions located in /code/modules/awaymissions/mission_code. These files must be included and compiled with the server beforehand otherwise the server will crash upon trying to load away missions that lack their code.
+
+To enable an away mission open `config/awaymissionconfig.txt` and uncomment one of the .dmm lines by removing the #. If more than one away mission is uncommented then the away mission loader will randomly select one the enabled ones to load.
+
+## SQL SETUP
+
+The SQL backend requires a MySQL server. SQL is required for the library, stats tracking, admin notes, and job-only bans, among other features, mostly related to server administration. Your server details go in /config/dbconfig.txt, and the SQL schema is in /SQL/tgstation_schema.sql and /SQL/tgstation_schema_prefix.sql depending on if you want table prefixes. More detailed setup instructions are located here: http://www.tgstation13.org/wiki/Downloading_the_source_code#Setting_up_the_database
+
+## IRC BOT SETUP
+
+Included in the repository is a python3 compatible IRC bot capable of relaying adminhelps to a specified
+IRC channel/server, see the /tools/minibot folder for more
+
+## CONTRIBUTING
+
+Please see [CONTRIBUTING.md](.github/CONTRIBUTING.md)
+
+## LICENSE
+
+All code after [commit 333c566b88108de218d882840e61928a9b759d8f on 2014/31/12 at 4:38 PM PST](https://github.com/tgstation/tgstation/commit/333c566b88108de218d882840e61928a9b759d8f) is licensed under [GNU AGPL v3](http://www.gnu.org/licenses/agpl-3.0.html).
+
+All code before [commit 333c566b88108de218d882840e61928a9b759d8f on 2014/31/12 at 4:38 PM PST](https://github.com/tgstation/tgstation/commit/333c566b88108de218d882840e61928a9b759d8f) is licensed under [GNU GPL v3](https://www.gnu.org/licenses/gpl-3.0.html).
+(Including tools unless their readme specifies otherwise.)
+
+See LICENSE-AGPLv3.txt and LICENSE-GPLv3.txt for more details.
+
+tgui clientside is licensed as a subproject under the MIT license.
+Font Awesome font files, used by tgui, are licensed under the SIL Open Font License v1.1
+tgui assets are licensed under a [Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/).
+The TGS3 API is licensed as a subproject under the MIT license.
+
+See tgui/LICENSE.md for the MIT license.
+See tgui/assets/fonts/SIL-OFL-1.1-LICENSE.md for the SIL Open Font License.
+See the footers of code/\_\_DEFINES/server\_tools.dm, code/modules/server\_tools/st\_commands.dm, and code/modules/server\_tools/st\_inteface.dm for the MIT license.
+
+All assets including icons and sound are under a [Creative Commons 3.0 BY-SA license](http://creativecommons.org/licenses/by-sa/3.0/) unless otherwise indicated.
diff --git a/TGS3.json b/TGS3.json
new file mode 100644
index 0000000000..4fd41ab9f1
--- /dev/null
+++ b/TGS3.json
@@ -0,0 +1,22 @@
+{
+ "documentation": "/tg/station server 3 configuration file",
+ "changelog": {
+ "script": "tools/ss13_genchangelog.py",
+ "arguments": "html/changelog.html html/changelogs",
+ "pip_dependancies": [
+ "PyYaml",
+ "beautifulsoup4"
+ ]
+ },
+ "synchronize_paths": [
+ "html/changelog.html",
+ "html/changelogs/*"
+ ],
+ "static_directories": [
+ "config",
+ "data"
+ ],
+ "dlls": [
+ "libmysql.dll"
+ ]
+ }
\ No newline at end of file
diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm
index 6712e631a7..27c4f5074b 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm
@@ -198,6 +198,7 @@
/obj/structure/stone_tile{
dir = 4
},
+/obj/item/dildo/custom,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/ruin/unpowered/ash_walkers)
"aC" = (
@@ -287,6 +288,7 @@
/obj/structure/stone_tile/cracked{
dir = 4
},
+/obj/item/dildo/custom,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/ruin/unpowered/ash_walkers)
"aN" = (
@@ -305,6 +307,7 @@
/area/ruin/unpowered/ash_walkers)
"aP" = (
/obj/structure/stone_tile,
+/obj/item/dildo/custom,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/ruin/unpowered/ash_walkers)
"aQ" = (
@@ -379,6 +382,7 @@
/obj/structure/stone_tile/cracked{
dir = 1
},
+/obj/item/dildo/custom,
/turf/open/indestructible/boss,
/area/ruin/unpowered/ash_walkers)
"aZ" = (
@@ -401,6 +405,7 @@
/obj/structure/stone_tile{
dir = 4
},
+/obj/item/dildo/custom,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/ruin/unpowered/ash_walkers)
"bb" = (
@@ -489,6 +494,7 @@
dir = 4
},
/obj/item/storage/bag/plants/portaseeder,
+/obj/item/dildo/custom,
/turf/open/indestructible/boss,
/area/ruin/unpowered/ash_walkers)
"bk" = (
@@ -509,6 +515,7 @@
/obj/structure/stone_tile/cracked{
dir = 1
},
+/obj/item/dildo/custom,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/ruin/unpowered/ash_walkers)
"bm" = (
@@ -568,6 +575,7 @@
/obj/structure/stone_tile{
dir = 8
},
+/obj/item/dildo/custom,
/turf/open/indestructible/boss/air,
/area/ruin/unpowered/ash_walkers)
"br" = (
@@ -897,6 +905,7 @@
/obj/structure/stone_tile/surrounding_tile/cracked{
dir = 8
},
+/obj/item/dildo/custom,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
"ci" = (
@@ -1042,6 +1051,7 @@
icon_state = "cracked_slab1";
dir = 4
},
+/obj/item/dildo/custom,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/ruin/unpowered/ash_walkers)
"cB" = (
@@ -1475,6 +1485,26 @@
/obj/structure/stone_tile,
/turf/closed/mineral/volcanic,
/area/lavaland/surface/outdoors)
+"dG" = (
+/obj/structure/stone_tile/slab,
+/obj/item/dildo/custom,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"dH" = (
+/obj/structure/stone_tile/block/cracked,
+/obj/structure/stone_tile/block{
+ dir = 1
+ },
+/obj/item/dildo/custom,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
+"dI" = (
+/obj/structure/stone_tile{
+ dir = 4
+ },
+/obj/item/dildo/custom,
+/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
(1,1,1) = {"
aa
@@ -1597,7 +1627,7 @@ aO
bl
bx
bD
-bS
+dG
de
bV
dg
@@ -1625,7 +1655,7 @@ ci
bA
ct
bN
-bL
+dI
cI
ah
ah
@@ -1732,7 +1762,7 @@ ak
bP
bL
bX
-dh
+dH
do
du
dz
diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm
index 8ca77f7dd2..49e1dd8484 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm
@@ -24,15 +24,6 @@
/area/ruin/unpowered)
"g" = (
/obj/effect/decal/cleanable/blood/old,
-/obj/effect/step_trigger/thrower{
- name = "south";
- tiles = 5
- },
-/obj/effect/step_trigger/sound_effect{
- name = "turn around";
- sound = 'sound/hallucinations/turn_around1.ogg';
- triggerer_only = 1
- },
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=14;n2=23;TEMP=300"
},
@@ -79,16 +70,6 @@
/area/ruin/unpowered)
"n" = (
/obj/effect/decal/cleanable/blood/old,
-/obj/effect/step_trigger/thrower{
- direction = 4;
- name = "east";
- tiles = 5
- },
-/obj/effect/step_trigger/sound_effect{
- name = "turn around";
- sound = 'sound/hallucinations/turn_around1.ogg';
- triggerer_only = 1
- },
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=14;n2=23;TEMP=300"
},
@@ -117,16 +98,6 @@
/area/ruin/unpowered)
"p" = (
/obj/effect/decal/cleanable/blood/old,
-/obj/effect/step_trigger/thrower{
- direction = 8;
- name = "west";
- tiles = 5
- },
-/obj/effect/step_trigger/sound_effect{
- name = "turn around";
- sound = 'sound/hallucinations/turn_around1.ogg';
- triggerer_only = 1
- },
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=14;n2=23;TEMP=300"
},
@@ -142,16 +113,6 @@
/area/ruin/unpowered)
"r" = (
/obj/effect/decal/cleanable/blood/old,
-/obj/effect/step_trigger/thrower{
- direction = 1;
- name = "north";
- tiles = 5
- },
-/obj/effect/step_trigger/sound_effect{
- name = "turn around";
- sound = 'sound/hallucinations/turn_around1.ogg';
- triggerer_only = 1
- },
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=14;n2=23;TEMP=300"
},
diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm
index 07642f1d08..1ef76788eb 100644
--- a/_maps/map_files/BoxStation/BoxStation.dmm
+++ b/_maps/map_files/BoxStation/BoxStation.dmm
@@ -24665,7 +24665,7 @@
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/open/floor/plating,
-/area/maintenance/aft)
+/area/maintenance/department/medical/morgue)
"bgp" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on,
/turf/open/floor/plasteel/white,
@@ -26862,7 +26862,7 @@
dir = 4
},
/turf/open/floor/plating,
-/area/maintenance/aft)
+/area/maintenance/department/medical/morgue)
"blh" = (
/obj/structure/table/reinforced,
/obj/machinery/door/window/eastright{
@@ -26940,7 +26940,7 @@
dir = 4
},
/turf/open/floor/plating,
-/area/maintenance/aft)
+/area/maintenance/department/medical/morgue)
"blp" = (
/obj/machinery/power/apc{
dir = 8;
@@ -26974,7 +26974,7 @@
dir = 4
},
/turf/open/floor/plating,
-/area/maintenance/aft)
+/area/maintenance/department/medical/morgue)
"blr" = (
/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
dir = 4
@@ -29030,7 +29030,7 @@
},
/obj/structure/disposalpipe/segment,
/turf/open/floor/plating,
-/area/maintenance/aft)
+/area/maintenance/department/medical/morgue)
"bpR" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/structure/disposalpipe/segment{
@@ -60163,7 +60163,7 @@
icon_state = "2-4"
},
/turf/open/floor/plating,
-/area/maintenance/aft)
+/area/maintenance/department/medical/morgue)
"cHE" = (
/obj/machinery/door/airlock/maintenance{
name = "Mech Bay Maintenance";
@@ -63862,6 +63862,167 @@
},
/turf/open/floor/plating,
/area/maintenance/starboard/aft)
+"cTJ" = (
+/obj/machinery/door/airlock/maintenance{
+ req_access_txt = "12"
+ },
+/obj/structure/disposalpipe/segment,
+/obj/structure/cable{
+ d1 = 1;
+ d2 = 2;
+ icon_state = "1-2"
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/turf/open/floor/plating,
+/area/maintenance/department/medical/morgue)
+"cTK" = (
+/obj/structure/disposalpipe/segment,
+/obj/structure/cable{
+ d1 = 1;
+ d2 = 2;
+ icon_state = "1-2"
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/turf/open/floor/plating,
+/area/maintenance/department/medical/morgue)
+"cTL" = (
+/obj/structure/cable{
+ d1 = 1;
+ d2 = 2;
+ icon_state = "1-2"
+ },
+/obj/structure/cable{
+ d1 = 2;
+ d2 = 4;
+ icon_state = "2-4"
+ },
+/turf/open/floor/plasteel/black,
+/area/medical/morgue)
+"cTM" = (
+/obj/machinery/power/apc{
+ dir = 4;
+ name = "Morgue Maintenance APC";
+ areastring = "/area/maintenance/department/medical/morgue";
+ pixel_x = 26
+ },
+/obj/structure/cable{
+ d2 = 8;
+ icon_state = "0-8"
+ },
+/turf/open/floor/plasteel/black,
+/area/medical/morgue)
+"cTN" = (
+/obj/structure/disposalpipe/segment,
+/obj/structure/cable{
+ d1 = 1;
+ d2 = 2;
+ icon_state = "1-2"
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/turf/open/floor/plating,
+/area/maintenance/department/medical/morgue)
+"cTO" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/structure/cable{
+ d1 = 4;
+ d2 = 8;
+ icon_state = "4-8"
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/maintenance/department/medical/morgue)
+"cTP" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/structure/cable{
+ d1 = 4;
+ d2 = 8;
+ icon_state = "4-8"
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/maintenance/department/medical/morgue)
+"cTQ" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/structure/cable{
+ d1 = 4;
+ d2 = 8;
+ icon_state = "4-8"
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/maintenance/department/medical/morgue)
+"cTR" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/structure/cable{
+ d1 = 4;
+ d2 = 8;
+ icon_state = "4-8"
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/maintenance/department/medical/morgue)
+"cTS" = (
+/obj/structure/disposalpipe/segment,
+/obj/structure/cable{
+ d1 = 1;
+ d2 = 2;
+ icon_state = "1-2"
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/maintenance/department/medical/morgue)
+"cTT" = (
+/obj/structure/disposalpipe/segment,
+/obj/structure/cable{
+ d1 = 1;
+ d2 = 2;
+ icon_state = "1-2"
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/turf/open/floor/plating,
+/area/maintenance/department/medical/morgue)
+"cTU" = (
+/obj/structure/disposalpipe/segment,
+/obj/structure/cable{
+ d1 = 1;
+ d2 = 2;
+ icon_state = "1-2"
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/turf/open/floor/plating,
+/area/maintenance/department/medical/morgue)
+"cTV" = (
+/obj/machinery/door/airlock/maintenance{
+ req_access_txt = "12"
+ },
+/obj/structure/disposalpipe/segment,
+/obj/structure/cable{
+ d1 = 1;
+ d2 = 2;
+ icon_state = "1-2"
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/turf/open/floor/plating,
+/area/maintenance/department/medical/morgue)
(1,1,1) = {"
aaa
@@ -103574,7 +103735,7 @@ bfL
bhp
biB
biB
-biB
+cTL
bkU
bmX
bpE
@@ -103831,7 +103992,7 @@ bfL
bhq
bhm
bkb
-bhm
+cTM
bla
bmZ
bpH
@@ -104346,7 +104507,7 @@ bfS
biC
bkd
bfS
-bKH
+cTO
bmZ
bpJ
brc
@@ -104860,7 +105021,7 @@ bfS
biE
bkf
bfS
-bKH
+cTP
bmZ
bpL
bre
@@ -105117,7 +105278,7 @@ bfS
biD
bke
bfS
-bKH
+cTQ
bmZ
bpK
brd
@@ -105374,7 +105535,7 @@ bfS
bfS
bfS
bfS
-bKH
+cTR
bmZ
bon
bon
@@ -105626,17 +105787,17 @@ aYV
baR
bcb
bdl
-bdO
+cTJ
cHD
bgo
-bPv
-bPv
+cTK
+cTN
blq
-bna
-bPv
+cTS
+cTT
bpQ
-bPv
-bdO
+cTU
+cTV
btm
buy
bvz
@@ -115146,7 +115307,7 @@ aaa
aaa
aaa
bky
-btq
+btp
brH
bvQ
bxt
@@ -115660,7 +115821,7 @@ aaa
aaa
aaa
bZi
-btp
+btq
brI
bvR
cNS
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm
index 5809176275..efae305c74 100644
--- a/_maps/map_files/Deltastation/DeltaStation2.dmm
+++ b/_maps/map_files/Deltastation/DeltaStation2.dmm
@@ -91795,7 +91795,7 @@
"dwO" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/closed/wall,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dwP" = (
/obj/machinery/door/firedoor,
/obj/structure/cable/white{
@@ -91815,7 +91815,7 @@
dir = 1
},
/turf/open/floor/plasteel,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dwQ" = (
/obj/structure/table/glass,
/obj/item/clipboard,
@@ -92448,7 +92448,7 @@
/turf/open/floor/plasteel/vault{
dir = 5
},
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dyb" = (
/obj/structure/bed/roller,
/obj/machinery/iv_drip,
@@ -92456,12 +92456,12 @@
/turf/open/floor/plasteel/vault{
dir = 5
},
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dyc" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plating,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dyd" = (
/obj/structure/cable/white{
d1 = 1;
@@ -92470,7 +92470,7 @@
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/open/floor/plating,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dye" = (
/obj/structure/table/glass,
/obj/item/folder/white,
@@ -92923,12 +92923,12 @@
"dzf" = (
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plasteel/neutral,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dzg" = (
/obj/effect/decal/cleanable/blood/old,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plating,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dzh" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/cable/white{
@@ -92938,14 +92938,14 @@
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/open/floor/plating,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dzi" = (
/obj/structure/table,
/obj/effect/decal/cleanable/dirt,
/obj/item/storage/backpack/duffelbag/med,
/obj/item/device/flashlight/pen,
/turf/open/floor/plating,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dzj" = (
/turf/closed/wall,
/area/crew_quarters/heads/cmo)
@@ -93674,7 +93674,7 @@
dir = 4
},
/turf/open/floor/plasteel,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dAw" = (
/obj/structure/cable/white{
d1 = 4;
@@ -93687,7 +93687,7 @@
/turf/open/floor/plasteel/vault{
dir = 5
},
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dAx" = (
/obj/structure/cable/white{
d1 = 4;
@@ -93699,7 +93699,7 @@
dir = 1
},
/turf/open/floor/plating,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dAy" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/cable/white{
@@ -93712,7 +93712,7 @@
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plating,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dAz" = (
/obj/structure/cable/white{
d1 = 1;
@@ -93733,14 +93733,14 @@
dir = 4
},
/turf/open/floor/plasteel/neutral,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dAA" = (
/obj/structure/table,
/obj/item/clothing/gloves/color/latex/nitrile,
/obj/item/clothing/suit/apron/surgical,
/obj/item/clothing/mask/breath/medical,
/turf/open/floor/plating,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dAB" = (
/obj/structure/closet/secure_closet/CMO,
/obj/item/clothing/under/rank/nursesuit,
@@ -94324,7 +94324,7 @@
/turf/open/floor/plasteel/vault{
dir = 5
},
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dBP" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/components/unary/vent_pump/on{
@@ -94334,13 +94334,13 @@
dir = 4
},
/turf/open/floor/plasteel/neutral,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dBQ" = (
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
dir = 4
},
/turf/open/floor/plating,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dBR" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/cable/white{
@@ -94350,7 +94350,7 @@
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/open/floor/plasteel/neutral,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dBS" = (
/obj/structure/rack,
/obj/effect/decal/cleanable/dirt,
@@ -94359,7 +94359,7 @@
/turf/open/floor/plasteel/vault{
dir = 5
},
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dBT" = (
/obj/machinery/light{
dir = 8
@@ -95032,15 +95032,15 @@
/obj/structure/closet/secure_closet/medical3,
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dDe" = (
/obj/structure/closet/wardrobe/white/medical,
/turf/open/floor/plating,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dDf" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plating,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dDg" = (
/obj/structure/cable/white{
d1 = 1;
@@ -95048,10 +95048,15 @@
icon_state = "1-2"
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/obj/structure/cable/white{
+ d1 = 2;
+ d2 = 4;
+ icon_state = "2-4"
+ },
/turf/open/floor/plasteel/vault{
dir = 5
},
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dDh" = (
/obj/machinery/suit_storage_unit/cmo,
/obj/effect/turf_decal/stripes/line{
@@ -95603,7 +95608,7 @@
dir = 1
},
/turf/open/floor/plasteel,
-/area/medical/morgue)
+/area/maintenance/department/medical/morgue)
"dEn" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/closed/wall,
@@ -113090,6 +113095,50 @@
/obj/structure/ore_box,
/turf/open/floor/plating,
/area/shuttle/auxillary_base)
+"esz" = (
+/turf/closed/wall/r_wall,
+/area/maintenance/department/medical/morgue)
+"esA" = (
+/turf/closed/wall/r_wall,
+/area/maintenance/department/medical/morgue)
+"esB" = (
+/turf/closed/wall,
+/area/maintenance/department/medical/morgue)
+"esC" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plasteel/vault{
+ dir = 5
+ },
+/area/maintenance/department/medical/morgue)
+"esD" = (
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/maintenance/department/medical/morgue)
+"esE" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/power/apc{
+ dir = 2;
+ name = "Morgue Maintenance APC";
+ areastring = "/area/maintenance/department/medical/morgue";
+ pixel_y = -26
+ },
+/obj/structure/cable/white{
+ d2 = 8;
+ icon_state = "0-8"
+ },
+/turf/open/floor/plasteel/vault{
+ dir = 5
+ },
+/area/maintenance/department/medical/morgue)
+"esF" = (
+/turf/closed/wall,
+/area/maintenance/department/medical/morgue)
+"esG" = (
+/turf/closed/wall,
+/area/maintenance/department/medical/morgue)
+"esH" = (
+/turf/closed/wall,
+/area/maintenance/department/medical/morgue)
(1,1,1) = {"
aaa
@@ -155932,13 +155981,13 @@ drr
dsR
dur
dvw
-dwN
+esz
dya
-dyY
+esD
dAw
dBO
dDd
-dwK
+esF
dFd
dGE
dHP
@@ -156189,13 +156238,13 @@ drs
dsS
drs
dvx
-dwN
+esA
dyb
dzf
dAx
dBP
dDe
-dwK
+esG
dFe
dGF
dHP
@@ -156960,13 +157009,13 @@ drv
dlO
dus
dvA
-dwK
-dxS
+esB
+esC
dzi
dAA
dBS
-dxS
-dwK
+esE
+esH
dEY
dGA
dHP
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index 21180a53bd..5a1762e989 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -4354,13 +4354,6 @@
/obj/structure/closet{
name = "Evidence Closet 1"
},
-/obj/item/storage/backpack{
- name = "Evidence Bag 1"
- },
-/obj/effect/spawner/lootdrop/maintenance{
- lootcount = 2;
- name = "2maintenance loot spawner"
- },
/turf/open/floor/plasteel/vault{
dir = 1
},
@@ -4387,11 +4380,6 @@
/area/security/warden)
"aiz" = (
/obj/structure/closet/secure_closet/evidence,
-/obj/item/storage/secure/briefcase{
- name = "Secure Evidence Briefcase";
- pixel_x = 3;
- pixel_y = -3
- },
/turf/open/floor/plasteel/vault{
dir = 4
},
@@ -4758,17 +4746,10 @@
/obj/structure/closet{
name = "Evidence Closet 2"
},
-/obj/item/storage/backpack{
- name = "Evidence Bag 2"
- },
/obj/machinery/airalarm{
dir = 4;
pixel_x = -23
},
-/obj/effect/spawner/lootdrop/maintenance{
- lootcount = 2;
- name = "2maintenance loot spawner"
- },
/turf/open/floor/plasteel/vault{
dir = 1
},
@@ -4792,13 +4773,6 @@
/obj/structure/closet{
name = "Evidence Closet 5"
},
-/obj/item/storage/backpack{
- name = "Evidence Bag 5"
- },
-/obj/effect/spawner/lootdrop/maintenance{
- lootcount = 2;
- name = "2maintenance loot spawner"
- },
/obj/machinery/firealarm{
dir = 4;
pixel_x = 28
@@ -5363,13 +5337,6 @@
/obj/structure/closet{
name = "Evidence Closet 4"
},
-/obj/item/storage/backpack{
- name = "Evidence Bag 4"
- },
-/obj/effect/spawner/lootdrop/maintenance{
- lootcount = 2;
- name = "2maintenance loot spawner"
- },
/turf/open/floor/plasteel/vault{
dir = 4
},
@@ -20485,13 +20452,6 @@
/obj/structure/closet{
name = "Evidence Closet 3"
},
-/obj/item/storage/backpack{
- name = "Evidence Bag 3"
- },
-/obj/effect/spawner/lootdrop/maintenance{
- lootcount = 2;
- name = "2maintenance loot spawner"
- },
/turf/open/floor/plasteel/vault{
dir = 4
},
diff --git a/_maps/map_files/generic/City_of_Cogs.dmm b/_maps/map_files/generic/City_of_Cogs.dmm
index 1b6943675f..68f45f5472 100644
--- a/_maps/map_files/generic/City_of_Cogs.dmm
+++ b/_maps/map_files/generic/City_of_Cogs.dmm
@@ -1,345 +1,65838 @@
-"aa" = (/turf/closed/indestructible/reebe,/area/reebe)
-"ab" = (/obj/structure/lattice/clockwork,/turf/closed/indestructible/reebe,/area/reebe)
-"ac" = (/obj/structure/destructible/clockwork/wall_gear,/turf/closed/indestructible/reebe,/area/reebe)
-"ad" = (/turf/closed/wall/clockwork,/area/reebe/city_of_cogs)
-"ae" = (/obj/structure/window/reinforced/clockwork/fulltile,/obj/structure/grille/ratvar,/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"af" = (/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"ag" = (/obj/item/clockwork/alloy_shards/pinion_lock,/turf/closed/indestructible/reebe,/area/reebe)
-"ah" = (/obj/structure/lattice/clockwork,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/large,/obj/item/clockwork/alloy_shards/large,/turf/closed/indestructible/reebe,/area/reebe)
-"ai" = (/obj/structure/destructible/clockwork/massive/celestial_gateway,/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"aj" = (/obj/structure/lattice/clockwork,/obj/structure/destructible/clockwork/wall_gear,/turf/closed/indestructible/reebe,/area/reebe)
-"ak" = (/obj/item/clockwork/alloy_shards/small,/turf/closed/indestructible/reebe,/area/reebe)
-"al" = (/obj/structure/lattice/clockwork,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/large,/turf/closed/indestructible/reebe,/area/reebe)
-"am" = (/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/small,/turf/closed/indestructible/reebe,/area/reebe)
-"an" = (/obj/structure/lattice/clockwork,/obj/item/clockwork/alloy_shards/medium,/turf/closed/indestructible/reebe,/area/reebe)
-"ao" = (/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/medium,/turf/closed/indestructible/reebe,/area/reebe)
-"ap" = (/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/medium,/obj/item/clockwork/alloy_shards/large,/turf/closed/indestructible/reebe,/area/reebe)
-"aq" = (/obj/structure/lattice/clockwork,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/medium,/turf/closed/indestructible/reebe,/area/reebe)
-"ar" = (/obj/structure/lattice/clockwork,/obj/structure/destructible/clockwork/wall_gear,/obj/item/clockwork/alloy_shards/small,/turf/closed/indestructible/reebe,/area/reebe)
-"as" = (/obj/structure/lattice/clockwork,/obj/item/clockwork/alloy_shards/medium,/obj/item/clockwork/alloy_shards/large,/turf/closed/indestructible/reebe,/area/reebe)
-"at" = (/obj/machinery/sleeper/clockwork,/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"au" = (/obj/structure/table/reinforced/brass,/obj/item/storage/firstaid,/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"av" = (/obj/structure/noticeboard,/obj/item/paper/fluff/ruins/djstation{name = "paper - 'Station Radio Frequencies'"},/turf/closed/wall/clockwork,/area/reebe/city_of_cogs)
-"aw" = (/obj/machinery/telecomms/relay/preset/reebe,/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"ax" = (/obj/machinery/door/airlock/clockwork/brass{name = "Ark Chamber"},/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"ay" = (/obj/machinery/computer/camera_advanced/ratvar,/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"az" = (/obj/structure/closet/wardrobe/mixed,/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"aA" = (/obj/structure/dresser,/obj/structure/mirror{pixel_y = 26},/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"aB" = (/obj/structure/table/reinforced/brass,/obj/item/clockwork/slab,/obj/item/clockwork/slab,/obj/item/clockwork/slab,/obj/item/clockwork/slab,/obj/item/clockwork/slab,/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"aC" = (/obj/structure/table/reinforced/brass,/obj/item/device/radio/intercom/ratvar,/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"aD" = (/obj/structure/chair/brass{dir = 8},/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"aE" = (/obj/structure/chair/brass{dir = 4},/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"aF" = (/obj/structure/chair/brass{dir = 1},/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"aG" = (/obj/item/clockwork/alloy_shards/medium,/turf/closed/indestructible/reebe,/area/reebe)
-"aH" = (/obj/machinery/door/airlock/clockwork/brass{name = "Dressing Room"},/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"aI" = (/obj/structure/destructible/clockwork/heralds_beacon,/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"aJ" = (/obj/machinery/door/airlock/clockwork/brass{name = "Infirmary"},/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"aK" = (/obj/structure/lattice/clockwork,/obj/item/clockwork/alloy_shards/medium,/obj/item/clockwork/alloy_shards/medium,/obj/item/clockwork/alloy_shards/medium,/turf/closed/indestructible/reebe,/area/reebe)
-"aL" = (/obj/item/clockwork/alloy_shards/medium,/obj/item/clockwork/alloy_shards/medium,/turf/closed/indestructible/reebe,/area/reebe)
-"aM" = (/obj/structure/table/reinforced/brass,/obj/item/clockwork/construct_chassis/cogscarab,/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"aN" = (/obj/machinery/sleeper/clockwork{dir = 1},/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"aO" = (/obj/machinery/door/airlock/clockwork/brass{name = "Listening Station"},/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"aP" = (/obj/machinery/door/airlock/clockwork/brass{name = "Observation Room"},/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"aQ" = (/turf/closed/wall/clockwork{opacity = 0},/area/reebe/city_of_cogs)
-"aR" = (/obj/effect/landmark/servant_of_ratvar,/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"aS" = (/obj/structure/table/reinforced/brass,/obj/item/clockwork/slab,/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"aT" = (/obj/structure/table/reinforced/brass,/obj/item/screwdriver/brass,/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"aU" = (/obj/structure/table/reinforced/brass,/obj/item/crowbar/brass,/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"aV" = (/obj/structure/table/reinforced/brass,/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"aW" = (/obj/structure/table/reinforced/brass,/obj/item/clockwork/component/replicant_alloy,/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"aX" = (/obj/structure/lattice/clockwork,/obj/structure/destructible/clockwork/wall_gear,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/small,/turf/closed/indestructible/reebe,/area/reebe)
-"aY" = (/obj/structure/table/reinforced/brass,/obj/item/weldingtool/experimental/brass,/turf/open/floor/clockwork/reebe,/area/reebe/city_of_cogs)
-"aZ" = (/obj/structure/lattice/clockwork,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/small,/turf/closed/indestructible/reebe,/area/reebe)
-"ba" = (/obj/item/clockwork/alloy_shards/large,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/small,/turf/closed/indestructible/reebe,/area/reebe)
-"bb" = (/obj/item/clockwork/component/replicant_alloy/smashed_anima_fragment,/turf/closed/indestructible/reebe,/area/reebe)
-"bc" = (/obj/item/clockwork/component/belligerent_eye/blind_eye,/obj/item/clockwork/alloy_shards/large,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/small,/turf/closed/indestructible/reebe,/area/reebe)
-"bd" = (/obj/structure/lattice/clockwork,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/small,/turf/closed/indestructible/reebe,/area/reebe)
-"be" = (/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/large,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/small,/turf/closed/indestructible/reebe,/area/reebe)
-"bf" = (/obj/structure/lattice/clockwork,/obj/item/clockwork/alloy_shards/medium,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/large,/obj/item/clockwork/component/replicant_alloy,/turf/closed/indestructible/reebe,/area/reebe)
-"bg" = (/obj/structure/lattice/clockwork,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/small,/turf/closed/indestructible/reebe,/area/reebe)
-"bh" = (/obj/item/clockwork/alloy_shards/medium,/obj/item/clockwork/alloy_shards/medium,/obj/item/clockwork/alloy_shards/small,/turf/closed/indestructible/reebe,/area/reebe)
-"bi" = (/obj/structure/lattice/clockwork,/obj/structure/lattice/clockwork,/turf/closed/indestructible/reebe,/area/reebe)
-"bj" = (/obj/structure/lattice/clockwork,/obj/item/clockwork/alloy_shards/small,/turf/closed/indestructible/reebe,/area/reebe)
-"bk" = (/obj/structure/lattice/clockwork,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/medium,/turf/closed/indestructible/reebe,/area/reebe)
-"bl" = (/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/small,/turf/closed/indestructible/reebe,/area/reebe)
-"bm" = (/obj/structure/lattice/clockwork,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/medium,/obj/item/clockwork/alloy_shards/large,/turf/closed/indestructible/reebe,/area/reebe)
-"bn" = (/obj/effect/clockwork/servant_blocker{dir = 1},/turf/open/indestructible/clock_spawn_room,/area/reebe/city_of_cogs)
-"bo" = (/turf/open/indestructible/clock_spawn_room,/area/reebe/city_of_cogs)
-"bp" = (/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/large,/turf/closed/indestructible/reebe,/area/reebe)
-"bq" = (/obj/structure/grille/ratvar,/obj/structure/window/reinforced/clockwork/fulltile,/turf/open/indestructible/clock_spawn_room,/area/reebe/city_of_cogs)
-"br" = (/obj/machinery/door/airlock/clockwork/brass,/turf/open/indestructible/clock_spawn_room,/area/reebe/city_of_cogs)
-"bs" = (/obj/effect/landmark/city_of_cogs,/turf/open/indestructible/clock_spawn_room,/area/reebe/city_of_cogs)
-"bt" = (/obj/structure/lattice/clockwork,/obj/item/clockwork/alloy_shards/medium,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/small,/turf/closed/indestructible/reebe,/area/reebe)
-"bu" = (/obj/structure/lattice/clockwork,/obj/item/clockwork/alloy_shards/medium,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/small,/turf/closed/indestructible/reebe,/area/reebe)
-"bv" = (/obj/structure/lattice/clockwork,/obj/structure/destructible/clockwork/wall_gear,/obj/item/clockwork/alloy_shards/medium,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/small,/obj/item/clockwork/alloy_shards/small,/turf/closed/indestructible/reebe,/area/reebe)
-"bw" = (/obj/structure/table/reinforced/brass,/obj/item/clockwork/component/belligerent_eye/blind_eye,/turf/open/indestructible/clock_spawn_room,/area/reebe/city_of_cogs)
-"bx" = (/obj/structure/table/reinforced/brass,/obj/item/clockwork/component/belligerent_eye,/turf/open/indestructible/clock_spawn_room,/area/reebe/city_of_cogs)
-"by" = (/obj/structure/table/reinforced/brass,/obj/item/clockwork/component/belligerent_eye/lens_gem,/turf/open/indestructible/clock_spawn_room,/area/reebe/city_of_cogs)
-"bz" = (/obj/structure/destructible/clockwork/wall_gear,/obj/item/clockwork/alloy_shards/small,/turf/closed/indestructible/reebe,/area/reebe)
-"bA" = (/obj/structure/table/reinforced/brass,/obj/item/clockwork/component/replicant_alloy,/turf/open/indestructible/clock_spawn_room,/area/reebe/city_of_cogs)
-"bB" = (/obj/structure/table/reinforced/brass,/obj/item/clockwork/component/replicant_alloy/smashed_anima_fragment,/turf/open/indestructible/clock_spawn_room,/area/reebe/city_of_cogs)
-"bC" = (/obj/structure/table/reinforced/brass,/obj/item/clockwork/component/replicant_alloy/replication_plate,/turf/open/indestructible/clock_spawn_room,/area/reebe/city_of_cogs)
-"bD" = (/obj/structure/table/reinforced/brass,/obj/item/clockwork/component/geis_capacitor/antennae,/turf/open/indestructible/clock_spawn_room,/area/reebe/city_of_cogs)
-"bE" = (/obj/structure/table/reinforced/brass,/obj/item/clockwork/component/geis_capacitor/fallen_armor,/turf/open/indestructible/clock_spawn_room,/area/reebe/city_of_cogs)
-"bF" = (/obj/structure/table/reinforced/brass,/obj/item/clockwork/component/geis_capacitor,/turf/open/indestructible/clock_spawn_room,/area/reebe/city_of_cogs)
-"bG" = (/obj/structure/lattice/clockwork,/obj/item/clockwork/alloy_shards/large,/obj/item/clockwork/alloy_shards/large,/obj/item/clockwork/alloy_shards/large,/turf/closed/indestructible/reebe,/area/reebe)
-"bH" = (/obj/structure/lattice/clockwork,/obj/item/clockwork/alloy_shards/large,/turf/closed/indestructible/reebe,/area/reebe)
-"bI" = (/obj/structure/lattice/clockwork,/obj/item/clockwork/alloy_shards/large,/obj/item/clockwork/alloy_shards/large,/turf/closed/indestructible/reebe,/area/reebe)
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"aa" = (
+/turf/open/indestructible/reebe_void,
+/area/reebe)
+"ab" = (
+/turf/open/indestructible/reebe_void/spawning/lattices,
+/area/reebe)
+"ac" = (
+/obj/structure/lattice/clockwork,
+/obj/structure/grille/ratvar,
+/turf/open/indestructible/reebe_void,
+/area/reebe)
+"ad" = (
+/obj/structure/lattice/clockwork,
+/obj/item/clockwork/component/belligerent_eye/blind_eye,
+/turf/open/indestructible/reebe_void,
+/area/reebe)
+"ae" = (
+/obj/structure/lattice/clockwork,
+/turf/open/indestructible/reebe_void,
+/area/reebe)
+"af" = (
+/obj/structure/lattice/clockwork,
+/obj/item/clockwork/component/geis_capacitor/antennae,
+/turf/open/indestructible/reebe_void,
+/area/reebe)
+"ag" = (
+/obj/structure/lattice/catwalk/clockwork,
+/turf/open/indestructible/reebe_void,
+/area/reebe)
+"ah" = (
+/turf/closed/wall/clockwork,
+/area/reebe/city_of_cogs)
+"ai" = (
+/obj/structure/window/reinforced/clockwork/fulltile,
+/obj/structure/grille/ratvar,
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"aj" = (
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"ak" = (
+/obj/structure/destructible/clockwork/massive/celestial_gateway,
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"al" = (
+/obj/machinery/sleeper/clockwork,
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"am" = (
+/obj/structure/table/reinforced/brass,
+/obj/item/storage/firstaid,
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"an" = (
+/obj/structure/noticeboard,
+/obj/item/paper/fluff/ruins/djstation{
+ name = "paper - 'Station Radio Frequencies'"
+ },
+/turf/closed/wall/clockwork,
+/area/reebe/city_of_cogs)
+"ao" = (
+/obj/machinery/telecomms/relay/preset/reebe,
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"ap" = (
+/obj/machinery/door/airlock/clockwork/brass{
+ name = "Ark Chamber"
+ },
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"aq" = (
+/obj/machinery/computer/camera_advanced/ratvar,
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"ar" = (
+/obj/structure/closet/wardrobe/mixed,
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"as" = (
+/obj/structure/dresser,
+/obj/structure/mirror{
+ pixel_y = 26
+ },
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"at" = (
+/obj/structure/table/reinforced/brass,
+/obj/item/clockwork/slab,
+/obj/item/clockwork/slab,
+/obj/item/clockwork/slab,
+/obj/item/clockwork/slab,
+/obj/item/clockwork/slab,
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"au" = (
+/obj/structure/table/reinforced/brass,
+/obj/item/device/radio/intercom/ratvar,
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"av" = (
+/obj/structure/chair/brass{
+ dir = 8
+ },
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"aw" = (
+/obj/structure/chair/brass{
+ dir = 4
+ },
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"ax" = (
+/obj/structure/chair/brass{
+ dir = 1
+ },
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"ay" = (
+/obj/machinery/door/airlock/clockwork/brass{
+ name = "Dressing Room"
+ },
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"az" = (
+/obj/structure/destructible/clockwork/heralds_beacon,
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"aA" = (
+/obj/machinery/door/airlock/clockwork/brass{
+ name = "Infirmary"
+ },
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"aB" = (
+/obj/structure/table/reinforced/brass,
+/obj/item/clockwork/construct_chassis/cogscarab,
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"aC" = (
+/obj/machinery/sleeper/clockwork{
+ dir = 1
+ },
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"aD" = (
+/obj/machinery/door/airlock/clockwork/brass{
+ name = "Listening Station"
+ },
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"aE" = (
+/obj/machinery/door/airlock/clockwork/brass{
+ name = "Observation Room"
+ },
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"aF" = (
+/turf/open/indestructible/reebe_void/spawning,
+/area/reebe)
+"aG" = (
+/turf/closed/wall/clockwork{
+ opacity = 0
+ },
+/area/reebe/city_of_cogs)
+"aH" = (
+/obj/effect/landmark/servant_of_ratvar,
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"aI" = (
+/obj/structure/table/reinforced/brass,
+/obj/item/clockwork/slab,
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"aJ" = (
+/obj/structure/table/reinforced/brass,
+/obj/item/screwdriver/brass,
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"aK" = (
+/obj/structure/table/reinforced/brass,
+/obj/item/crowbar/brass,
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"aL" = (
+/obj/structure/table/reinforced/brass,
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"aM" = (
+/obj/structure/table/reinforced/brass,
+/obj/item/clockwork/component/replicant_alloy,
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"aN" = (
+/obj/structure/table/reinforced/brass,
+/obj/item/weldingtool/experimental/brass,
+/turf/open/floor/clockwork/reebe,
+/area/reebe/city_of_cogs)
+"aO" = (
+/obj/structure/lattice/catwalk/clockwork,
+/obj/item/clockwork/component/belligerent_eye/lens_gem,
+/turf/open/indestructible/reebe_void,
+/area/reebe)
+"aP" = (
+/obj/structure/lattice/catwalk/clockwork,
+/obj/item/clockwork/component/hierophant_ansible/obelisk,
+/turf/open/indestructible/reebe_void,
+/area/reebe)
+"aQ" = (
+/obj/structure/lattice/clockwork,
+/obj/item/clockwork/alloy_shards/clockgolem_remains,
+/turf/open/indestructible/reebe_void,
+/area/reebe)
+"aR" = (
+/obj/effect/clockwork/servant_blocker{
+ dir = 1
+ },
+/obj/structure/lattice/clockwork,
+/turf/open/indestructible/reebe_void,
+/area/reebe/city_of_cogs)
+"aS" = (
+/obj/effect/clockwork/servant_blocker{
+ dir = 1
+ },
+/obj/structure/lattice/catwalk/clockwork,
+/turf/open/indestructible/reebe_void,
+/area/reebe/city_of_cogs)
+"aT" = (
+/turf/open/indestructible/clock_spawn_room,
+/area/reebe/city_of_cogs)
+"aU" = (
+/obj/structure/grille/ratvar,
+/obj/structure/window/reinforced/clockwork/fulltile,
+/turf/open/indestructible/clock_spawn_room,
+/area/reebe/city_of_cogs)
+"aV" = (
+/obj/machinery/door/airlock/clockwork/brass,
+/turf/open/indestructible/clock_spawn_room,
+/area/reebe/city_of_cogs)
+"aW" = (
+/obj/item/clockwork/component/replicant_alloy/replication_plate,
+/turf/open/indestructible/reebe_void/spawning/lattices,
+/area/reebe)
+"aX" = (
+/obj/effect/landmark/city_of_cogs,
+/turf/open/indestructible/clock_spawn_room,
+/area/reebe/city_of_cogs)
+"aY" = (
+/obj/structure/table/reinforced/brass,
+/obj/item/clockwork/component/belligerent_eye/blind_eye,
+/turf/open/indestructible/clock_spawn_room,
+/area/reebe/city_of_cogs)
+"aZ" = (
+/obj/structure/table/reinforced/brass,
+/obj/item/clockwork/component/belligerent_eye,
+/turf/open/indestructible/clock_spawn_room,
+/area/reebe/city_of_cogs)
+"ba" = (
+/obj/structure/table/reinforced/brass,
+/obj/item/clockwork/component/belligerent_eye/lens_gem,
+/turf/open/indestructible/clock_spawn_room,
+/area/reebe/city_of_cogs)
+"bb" = (
+/obj/structure/table/reinforced/brass,
+/obj/item/clockwork/component/replicant_alloy,
+/turf/open/indestructible/clock_spawn_room,
+/area/reebe/city_of_cogs)
+"bc" = (
+/obj/structure/table/reinforced/brass,
+/obj/item/clockwork/component/replicant_alloy/smashed_anima_fragment,
+/turf/open/indestructible/clock_spawn_room,
+/area/reebe/city_of_cogs)
+"bd" = (
+/obj/structure/table/reinforced/brass,
+/obj/item/clockwork/component/replicant_alloy/replication_plate,
+/turf/open/indestructible/clock_spawn_room,
+/area/reebe/city_of_cogs)
+"be" = (
+/obj/structure/table/reinforced/brass,
+/obj/item/clockwork/component/geis_capacitor/antennae,
+/turf/open/indestructible/clock_spawn_room,
+/area/reebe/city_of_cogs)
+"bf" = (
+/obj/structure/table/reinforced/brass,
+/obj/item/clockwork/component/geis_capacitor/fallen_armor,
+/turf/open/indestructible/clock_spawn_room,
+/area/reebe/city_of_cogs)
+"bg" = (
+/obj/structure/table/reinforced/brass,
+/obj/item/clockwork/component/geis_capacitor,
+/turf/open/indestructible/clock_spawn_room,
+/area/reebe/city_of_cogs)
+"bh" = (
+/obj/structure/lattice/catwalk/clockwork,
+/obj/item/clockwork/integration_cog,
+/turf/open/indestructible/reebe_void,
+/area/reebe)
+"bi" = (
+/obj/structure/lattice/catwalk/clockwork,
+/obj/item/clockwork/component/vanguard_cogwheel/onyx_prism,
+/turf/open/indestructible/reebe_void,
+/area/reebe)
(1,1,1) = {"
-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
-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
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababacababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabadadadaeadadadabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacadafafafafafadabagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabadafafafafafadahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaeafafaiafafaeajakakalamaaacaaaaanaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacabadafafafafafadahaoapaqaradadaeadadasaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajabaaaaadaeadabadafafafafafadadaeaeaeadadatauatadajanaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadadadadadavadawadavadaeaeaxaeaeadayayayayayadafafafadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadazaAaBadaCaDafaEaCaeafafafafafaeaFaFaFaFaFadafafafaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaeafafafaHafafafafafaxafafaIafafaxafafafafafaJafafafadaKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaLadafafafadaCaDafaEaCaeafafafafafaeafafafaMaMadaNafaNadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaLadadaHadadadadaOaeaeadaeaeaxaeaeadaeaeaPadadadadaJadadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQafafafafafafafaRaSaTafafafafafafafafafafafafafafafaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabajaQafafafafafafafafaUaRafafafafafaRaRafafafafafafafafaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaQafafafafafafafafaRafafafafafaRaVaWaRafafafafafafafaQaraXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaLaQafafafafafafafafafafafafafafaRaYaVaRafafafafafafafaQaZakaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaQafafafafafafafafafafafafafafafaRaRafafafafafafafafaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaQafafafafafafafafafafafafafafafafafafafafafafafafafaQaaaaaaakakbaakaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbaaaGaQafafafafafafafafafafafafafafafafafafafafafafafafafaQaraaakbcbabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaQafafafafafafafafafafafafafafafafafafafafafafafafafaQaXbdbebaakaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasbfaQafafafafafafafafafafafafafafafafafafafafafafafafafaQbgakaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabhalaQafafafafafafafafafafafafafafafafafafafafafafafafafaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaQafafafafafafafafafafafafafafafafafafafafafafafafafaQacaaaaababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaQafafafafafafafafafafafafafafafafafafafafafafafafafaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabiaQafafafafafafafafafafafafafafafafafafafafafafafafafaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaQafafafafafafafafafafafafafafafafafafafafafafafafafaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQafafafafafafafafafafafafafafafafafafafafafafafafafaQabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQafafafafafafafafafafafafafafafafafafafafafafafafafaQabakamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakbjbkaQafafafafafafafafafafafafafafafafafafafafafafafafafaQbjamblakaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakakbjbmbkaQafafafafafafafafafafafafafafafafafafafafafafafafafaQabakakaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakakakakakakbjaQafafafafafafafafafafafafafafafafafafafafafafafafafaQabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakakakakaaaaaQafafafafafafafafafafafafafafafafafafafafafafafafafaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakaaaaaabnbnbnbnbnbnbnbnbnbnbnbnbnbnbnbnbnbnbnbnbnbnbnbnbnbnbnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjajadboboboboboboboboboboboboboboboboboboboboboboboboboadabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajakadboboboboboboboboboboboboboboboboboboboboboboboboboadaZbjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakakadboboboboboboboboboboboboboboboboboboboboboboboboboadbjajaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakbjadboboboboboboboboboboboboboboboboboboboboboboboboboadbjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpbjadadadbqbqbrbqbqadadadbqbqbrbqbqadadadbqbqbrbqbqadadadabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakbjadboboboboboboboadboboboboboboboadboboboboboboboadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaaaaaaaaaaaaaaaabjadbobobobobobobobqbobobobobobobobqboboboboboboboadabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakbladbobobsbsbsbobobqbobobsbsbsbobobqbobobsbsbsboboadbtamakakaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaadbobobsbsbsbobobrbobobsbsbsbobobrbobobsbsbsboboadbublakakaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadbobobsbsbsbobobqbobobsbsbsbobobqbobobsbsbsboboadbvamakakakaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadbobobobobobobobqbobobobobobobobqboboboboboboboadbuamakaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaradboboboboboboboadboboboboboboboadboboboboboboboadabaaakaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjadadadaeaeaeadadadadadaeaeaeadadadadadaeaeaeadadadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabjbjadbwbxbyadaZbzaZadbAbBbCadaaaaaaadbDbEbFadbGbHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakaaadadadadadakaaaaadadadadadbHaaaaadadadadadbHaGaaaaaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakaaaaaaaaabbjaaaaaGaaaaaaaabHbIbIaaaaaaaaajabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakaaaaaaaaaaaaaaaaaaaaaaaaaaaGaaaaaaaaaaaaaaaaaaaaaaaaaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-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
-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
-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
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(2,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(3,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(4,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(5,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(6,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(7,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(8,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(9,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(10,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(11,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(12,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(13,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(14,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(15,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(16,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(17,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(18,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(19,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(20,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(21,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(22,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(23,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(24,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(25,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(26,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(27,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(28,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(29,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(30,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(31,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(32,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(33,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(34,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(35,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(36,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(37,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(38,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(39,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(40,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(41,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(42,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(43,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(44,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(45,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(46,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(47,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(48,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(49,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(50,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(51,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(52,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(53,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(54,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(55,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(56,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(57,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(58,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(59,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(60,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(61,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(62,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(63,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(64,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(65,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(66,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(67,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(68,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(69,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(70,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(71,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(72,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(73,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(74,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(75,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(76,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(77,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(78,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(79,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(80,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(81,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(82,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(83,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(84,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(85,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(86,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(87,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(88,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(89,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(90,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(91,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(92,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(93,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(94,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(95,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(96,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(97,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(98,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(99,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(100,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aF
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(101,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aF
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(102,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aF
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(103,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ae
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aF
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(104,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ac
+ae
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aF
+ab
+ab
+ab
+ab
+ab
+ab
+aW
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(105,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ae
+af
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ae
+ab
+aP
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aF
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(106,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aF
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(107,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aF
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(108,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aF
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(109,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aF
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(110,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+ae
+ae
+ae
+ae
+ae
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(111,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ae
+ae
+ah
+ah
+ai
+ah
+ah
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aR
+ah
+ah
+ah
+ah
+ah
+ae
+ae
+ae
+ae
+ae
+ae
+ae
+ae
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(112,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ae
+ag
+ag
+ah
+ar
+aj
+aj
+ah
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aS
+aT
+aT
+aT
+aT
+ah
+ah
+ai
+ai
+ai
+ai
+ai
+ah
+ah
+ae
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(113,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ae
+ag
+ag
+ah
+as
+aj
+aj
+ay
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aS
+aT
+aT
+aT
+aT
+ah
+aT
+aT
+aT
+aT
+aT
+aT
+aT
+ah
+ag
+ae
+ab
+ab
+ab
+ab
+ab
+ae
+bi
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(114,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ae
+ag
+ag
+ah
+at
+aj
+aj
+ah
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aS
+aT
+aT
+aT
+aT
+aU
+aT
+aT
+aT
+aT
+aT
+aT
+aT
+ah
+ah
+ah
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ae
+ac
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(115,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ae
+ae
+ah
+ah
+ay
+ah
+ah
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aS
+aT
+aT
+aT
+aT
+aU
+aT
+aT
+aX
+aX
+aX
+aT
+aT
+ai
+aY
+ai
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(116,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ae
+an
+au
+aj
+au
+ah
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aS
+aT
+aT
+aT
+aT
+aV
+aT
+aT
+aX
+aX
+aX
+aT
+aT
+ai
+aZ
+ai
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(117,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ah
+ah
+av
+aj
+av
+ah
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aS
+aT
+aT
+aT
+aT
+aU
+aT
+aT
+aX
+aX
+aX
+aT
+aT
+ai
+ba
+ai
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(118,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ae
+ai
+ao
+aj
+aj
+aj
+aD
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aS
+aT
+aT
+aT
+aT
+aU
+aT
+aT
+aT
+aT
+aT
+aT
+aT
+ah
+ah
+ah
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(119,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ae
+ah
+ah
+aw
+aj
+aw
+ai
+aH
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aS
+aT
+aT
+aT
+aT
+ah
+aT
+aT
+aT
+aT
+aT
+aT
+aT
+ah
+ag
+ae
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(120,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ae
+ae
+ag
+ag
+an
+au
+aj
+au
+ai
+aI
+aK
+aH
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aS
+aT
+aT
+aT
+aT
+ah
+ah
+aU
+aU
+aV
+aU
+aU
+ah
+ah
+ag
+ae
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(121,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ah
+ah
+ah
+ai
+ah
+ah
+ah
+ai
+ap
+ai
+ah
+aJ
+aH
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aS
+aT
+aT
+aT
+aT
+ah
+aT
+aT
+aT
+aT
+aT
+aT
+aT
+ah
+ag
+ae
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(122,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ac
+ah
+aj
+aj
+aj
+aj
+aj
+ai
+aj
+aj
+aj
+ai
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aS
+aT
+aT
+aT
+aT
+aU
+aT
+aT
+aT
+aT
+aT
+aT
+aT
+ah
+ah
+ah
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(123,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ae
+ah
+aj
+aj
+aj
+aj
+aj
+ai
+aj
+aj
+aj
+ai
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aS
+aT
+aT
+aT
+aT
+aU
+aT
+aT
+aX
+aX
+aX
+aT
+aT
+ai
+bb
+ai
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(124,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ae
+ag
+ai
+aj
+aj
+ak
+aj
+aj
+ap
+aj
+az
+aj
+ap
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aS
+aT
+aT
+aT
+aT
+aV
+aT
+aT
+aX
+aX
+aX
+aT
+aT
+ai
+bc
+ai
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(125,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ae
+ah
+aj
+aj
+aj
+aj
+aj
+ai
+aj
+aj
+aj
+ai
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aS
+aT
+aT
+aT
+aT
+aU
+aT
+aT
+aX
+aX
+aX
+aT
+aT
+ai
+bd
+ai
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(126,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ae
+ah
+aj
+aj
+aj
+aj
+aj
+ai
+aj
+aj
+aj
+ai
+aj
+aj
+aH
+aH
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aS
+aT
+aT
+aT
+aT
+aU
+aT
+aT
+aT
+aT
+aT
+aT
+aT
+ah
+ah
+ah
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(127,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ah
+ah
+ah
+ai
+ah
+ah
+ah
+ai
+ap
+ai
+ah
+aj
+aH
+aL
+aN
+aH
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aS
+aT
+aT
+aT
+aT
+ah
+aT
+aT
+aT
+aT
+aT
+aT
+aT
+ah
+ag
+ae
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(128,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ae
+ae
+ag
+ah
+aq
+ax
+aj
+aj
+ai
+aj
+aH
+aM
+aL
+aH
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aS
+aT
+aT
+aT
+aT
+ah
+ah
+aU
+aU
+aV
+aU
+aU
+ah
+ah
+ag
+ae
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(129,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ae
+ai
+aq
+ax
+aj
+aj
+ai
+aj
+aj
+aH
+aH
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aS
+aT
+aT
+aT
+aT
+ah
+aT
+aT
+aT
+aT
+aT
+aT
+aT
+ah
+ag
+ae
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(130,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ae
+ai
+aq
+ax
+aj
+aj
+aE
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aS
+aT
+aT
+aT
+aT
+aU
+aT
+aT
+aT
+aT
+aT
+aT
+aT
+ah
+ah
+ah
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(131,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ac
+ad
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ai
+aq
+ax
+aj
+aB
+ah
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aS
+aT
+aT
+aT
+aT
+aU
+aT
+aT
+aX
+aX
+aX
+aT
+aT
+ai
+be
+ai
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(132,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ah
+aq
+ax
+aj
+aB
+ah
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aS
+aT
+aT
+aT
+aT
+aV
+aT
+aT
+aX
+aX
+aX
+aT
+aT
+ai
+bf
+ai
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(133,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ah
+ah
+ah
+ah
+aA
+ah
+ah
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aS
+aT
+aT
+aT
+aT
+aU
+aT
+aT
+aX
+aX
+aX
+aT
+aT
+ai
+bg
+ai
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(134,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ae
+ah
+al
+aj
+aj
+aj
+aC
+ah
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aS
+aT
+aT
+aT
+aT
+aU
+aT
+aT
+aT
+aT
+aT
+aT
+aT
+ah
+ah
+ah
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(135,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ae
+ai
+am
+aj
+aj
+aj
+aj
+aA
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aS
+aT
+aT
+aT
+aT
+ah
+aT
+aT
+aT
+aT
+aT
+aT
+aT
+ah
+ag
+ae
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(136,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ae
+ah
+al
+aj
+aj
+aj
+aC
+ah
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aj
+aS
+aT
+aT
+aT
+aT
+ah
+ah
+ai
+ai
+ai
+ai
+ai
+ah
+ah
+ae
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(137,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ah
+ah
+ah
+ai
+ah
+ah
+ah
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aG
+aR
+ah
+ah
+ah
+ah
+ah
+ae
+ae
+ae
+ae
+ae
+ae
+ae
+ae
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(138,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+aF
+ae
+ae
+ae
+ae
+ae
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(139,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aF
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(140,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aF
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ae
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(141,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aF
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ac
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(142,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aF
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ac
+bh
+ae
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(143,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aO
+ac
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aQ
+ab
+ab
+ab
+ab
+ab
+ab
+aF
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(144,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aF
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(145,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aF
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(146,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aF
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(147,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aF
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(148,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aF
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+ab
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(149,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(150,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(151,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(152,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(153,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(154,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(155,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(156,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(157,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(158,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(159,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(160,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(161,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(162,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(163,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(164,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(165,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(166,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(167,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(168,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(169,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(170,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(171,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(172,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(173,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(174,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(175,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(176,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(177,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(178,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(179,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(180,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(181,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(182,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(183,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(184,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(185,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(186,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(187,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(188,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(189,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(190,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(191,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(192,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(193,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(194,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(195,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(196,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(197,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(198,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(199,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(200,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(201,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(202,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(203,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(204,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(205,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(206,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(207,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(208,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(209,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(210,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(211,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(212,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(213,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(214,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(215,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(216,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(217,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(218,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(219,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(220,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(221,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(222,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(223,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(224,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(225,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(226,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(227,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(228,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(229,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(230,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(231,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(232,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(233,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(234,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(235,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(236,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(237,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(238,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(239,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(240,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(241,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(242,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(243,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(244,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(245,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(246,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(247,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(248,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(249,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(250,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(251,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(252,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(253,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(254,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+"}
+(255,1,1) = {"
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
+aa
"}
diff --git a/code/__DEFINES/configuration.dm b/code/__DEFINES/configuration.dm
new file mode 100644
index 0000000000..c78dfb28ab
--- /dev/null
+++ b/code/__DEFINES/configuration.dm
@@ -0,0 +1,10 @@
+//config files
+#define CONFIG_DEF(X) /datum/config_entry/##X { resident_file = CURRENT_RESIDENT_FILE }; /datum/config_entry/##X
+#define CONFIG_GET(X) global.config.Get(/datum/config_entry/##X)
+#define CONFIG_SET(X, Y) global.config.Set(/datum/config_entry/##X, ##Y)
+
+#define CONFIG_MAPS_FILE "maps.txt"
+
+//flags
+#define CONFIG_ENTRY_LOCKED 1 //can't edit
+#define CONFIG_ENTRY_HIDDEN 2 //can't see value
diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm
index c55b8216a3..4376ba9c03 100644
--- a/code/__DEFINES/is_helpers.dm
+++ b/code/__DEFINES/is_helpers.dm
@@ -9,6 +9,8 @@
#define ismovableatom(A) (istype(A, /atom/movable))
//Turfs
+//#define isturf(A) (istype(A, /turf)) This is actually a byond built-in. Added here for completeness sake.
+
#define isopenturf(A) (istype(A, /turf/open))
#define isindestructiblefloor(A) (istype(A, /turf/open/indestructible))
@@ -136,6 +138,10 @@
#define isitem(A) (istype(A, /obj/item))
+#define isstructure(A) (istype(A, /obj/structure))
+
+#define ismecha(A) (istype(A, /obj/mecha))
+
#define is_cleanable(A) (istype(A, /obj/effect/decal/cleanable) || istype(A, /obj/effect/rune)) //if something is cleanable
#define isorgan(A) (istype(A, /obj/item/organ))
@@ -164,9 +170,9 @@ GLOBAL_LIST_INIT(pointed_types, typecacheof(list(
#define istimer(O) (istype(O, /obj/item/device/assembly/timer))
GLOBAL_LIST_INIT(glass_sheet_types, typecacheof(list(
- /obj/item/stack/sheet/glass,
- /obj/item/stack/sheet/rglass,
- /obj/item/stack/sheet/plasmaglass,
+ /obj/item/stack/sheet/glass,
+ /obj/item/stack/sheet/rglass,
+ /obj/item/stack/sheet/plasmaglass,
/obj/item/stack/sheet/plasmarglass)))
#define is_glass_sheet(O) (is_type_in_typecache(O, GLOB.glass_sheet_types))
diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm
index 2e0b359fac..d33eaa35da 100644
--- a/code/__DEFINES/layers.dm
+++ b/code/__DEFINES/layers.dm
@@ -6,7 +6,10 @@
#define PLANE_SPACE -95
#define PLANE_SPACE_PARALLAX -90
-#define GAME_PLANE 0
+#define GAME_PLANE -1
+#define BLACKNESS_PLANE 0 //To keep from conflicts with SEE_BLACKNESS internals
+#define SPACE_LAYER 1.8
+#define ABOVE_SPACE_LAYER 1.9
//#define TURF_LAYER 2 //For easy recordkeeping; this is a byond define
#define MID_TURF_LAYER 2.02
#define HIGH_TURF_LAYER 2.03
diff --git a/code/__DEFINES/lighting.dm b/code/__DEFINES/lighting.dm
index 6d7c9568a9..819abd032f 100644
--- a/code/__DEFINES/lighting.dm
+++ b/code/__DEFINES/lighting.dm
@@ -70,6 +70,8 @@
#define LIGHT_COLOR_TUNGSTEN "#FAE1AF" //Extremely diluted yellow, close to skin color (for some reason). rgb(250, 225, 175)
#define LIGHT_COLOR_HALOGEN "#F0FAFA" //Barely visible cyan-ish hue, as the doctor prescribed. rgb(240, 250, 250)
+#define LIGHT_RANGE_FIRE 3 //How many tiles standard fires glow.
+
#define LIGHTING_PLANE_ALPHA_VISIBLE 255
#define LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE 192
#define LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE 128 //For lighting alpha, small amounts lead to big changes. even at 128 its hard to figure out what is dark and what is light, at 64 you almost can't even tell.
diff --git a/code/__DEFINES/server_tools.dm b/code/__DEFINES/server_tools.dm
index d2be3e578e..2773965d9c 100644
--- a/code/__DEFINES/server_tools.dm
+++ b/code/__DEFINES/server_tools.dm
@@ -1,34 +1,126 @@
+// /tg/station 13 server tools API v3.1.0.1
+
+//CONFIGURATION
+//use this define if you want to do configuration outside of this file
+#ifndef SERVER_TOOLS_EXTERNAL_CONFIGURATION
+//Comment this out once you've filled in the below
+//#error /tg/station server tools interface unconfigured
+
+//Required interfaces (fill in with your codebase equivalent):
+
+//create a global variable named `Name` and set it to `Value`
+//These globals must not be modifiable from anywhere outside of the server tools
+#define SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(Name, Value) GLOBAL_VAR_INIT(##Name, ##Value); GLOBAL_PROTECT(##Name)
+//Read the value in the global variable `Name`
+#define SERVER_TOOLS_READ_GLOBAL(Name) GLOB.##Name
+//Set the value in the global variable `Name` to `Value`
+#define SERVER_TOOLS_WRITE_GLOBAL(Name, Value) GLOB.##Name = ##Value
+//display an announcement `message` from the server to all players
+#define SERVER_TOOLS_WORLD_ANNOUNCE(message) to_chat(world, "[html_encode(##message)] ")
+//Write a string `message` to a server log
+#define SERVER_TOOLS_LOG(message) log_world("SERVICE: [##message]")
+//Notify current in-game administrators of a string `event`
+#define SERVER_TOOLS_NOTIFY_ADMINS(event) message_admins(##event)
+//The current amount of connected clients
+#define SERVER_TOOLS_CLIENT_COUNT GLOB.clients.len
+#endif
+
+//Required hooks:
+
+//Put this somewhere in /world/New() that is always run
+#define SERVER_TOOLS_ON_NEW ServiceInit()
+//Put this somewhere in /world/Topic(T, Addr, Master, Keys) that is always run before T is modified
+#define SERVER_TOOLS_ON_TOPIC var/service_topic_return = ServiceCommand(params2list(T)); if(service_topic_return) return service_topic_return
+//Put at the beginning of world/Reboot(reason)
+#define SERVER_TOOLS_ON_REBOOT ServiceReboot()
+
+//Optional callable functions:
+
+//Returns the string version of the API
+#define SERVER_TOOLS_API_VERSION ServiceAPIVersion()
+//Returns TRUE if the world was launched under the server tools and the API matches, FALSE otherwise
+//No function below this succeed if this is FALSE
+#define SERVER_TOOLS_PRESENT RunningService()
+//Gets the current version of the service running the server
+#define SERVER_TOOLS_VERSION ServiceVersion()
+//Forces a hard reboot of BYOND by ending the process
+//unlike del(world) clients will try to reconnect
+//If the service has not requested a shutdown, the world will reboot shortly after
+#define SERVER_TOOLS_REBOOT_BYOND world.ServiceEndProcess()
+/*
+ Gets the list of any testmerged github pull requests
+
+ "[PR Number]" => list(
+ "title" -> PR title
+ "commit" -> Full hash of commit merged
+ "author" -> Github username of the author of the PR
+ )
+*/
+#define SERVER_TOOLS_PR_LIST GetTestMerges()
+//Sends a message to connected game chats
+#define SERVER_TOOLS_CHAT_BROADCAST(message) world.ChatBroadcast(message)
+//Sends a message to connected admin chats
+#define SERVER_TOOLS_RELAY_BROADCAST(message) world.AdminBroadcast(message)
+
+//IMPLEMENTATION
+
+#define SERVICE_API_VERSION_STRING "3.1.0.1"
+
#define REBOOT_MODE_NORMAL 0
#define REBOOT_MODE_HARD 1
#define REBOOT_MODE_SHUTDOWN 2
-#define IRC_STATUS_THROTTLE 5
-
-#define PR_ANNOUNCEMENTS_PER_ROUND 5 //The number of unique PR announcements allowed per round
- //This makes sure that a single person can only spam 3 reopens and 3 closes before being ignored
-
-//keep these in sync with TGS3
#define SERVICE_WORLD_PARAM "server_service"
#define SERVICE_VERSION_PARAM "server_service_version"
#define SERVICE_PR_TEST_JSON "prtestjob.json"
-#define SERVICE_PR_TEST_JSON_OLD "..\\..\\[SERVICE_PR_TEST_JSON]"
+#define SERVICE_INTERFACE_DLL "TGServiceInterface.dll"
+#define SERVICE_INTERFACE_FUNCTION "DDEntryPoint"
#define SERVICE_CMD_HARD_REBOOT "hard_reboot"
#define SERVICE_CMD_GRACEFUL_SHUTDOWN "graceful_shutdown"
#define SERVICE_CMD_WORLD_ANNOUNCE "world_announce"
-#define SERVICE_CMD_IRC_CHECK "irc_check"
-#define SERVICE_CMD_IRC_STATUS "irc_status"
-#define SERVICE_CMD_ADMIN_MSG "adminmsg"
-#define SERVICE_CMD_NAME_CHECK "namecheck"
-#define SERVICE_CMD_ADMIN_WHO "adminwho"
+#define SERVICE_CMD_LIST_CUSTOM "list_custom_commands"
+#define SERVICE_CMD_API_COMPATIBLE "api_compat"
+#define SERVICE_CMD_PLAYER_COUNT "client_count"
#define SERVICE_CMD_PARAM_KEY "serviceCommsKey"
#define SERVICE_CMD_PARAM_COMMAND "command"
-#define SERVICE_CMD_PARAM_MESSAGE "message"
-#define SERVICE_CMD_PARAM_TARGET "target"
#define SERVICE_CMD_PARAM_SENDER "sender"
+#define SERVICE_CMD_PARAM_CUSTOM "custom"
+
+#define SERVICE_JSON_PARAM_HELPTEXT "help_text"
+#define SERVICE_JSON_PARAM_ADMINONLY "admin_only"
+#define SERVICE_JSON_PARAM_REQUIREDPARAMETERS "required_parameters"
#define SERVICE_REQUEST_KILL_PROCESS "killme"
#define SERVICE_REQUEST_IRC_BROADCAST "irc"
#define SERVICE_REQUEST_IRC_ADMIN_CHANNEL_MESSAGE "send2irc"
#define SERVICE_REQUEST_WORLD_REBOOT "worldreboot"
+#define SERVICE_REQUEST_API_VERSION "api_ver"
+
+/*
+The MIT License
+
+Copyright (c) 2011 Dominic Tarr
+
+Permission is hereby granted, free of charge,
+to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to
+deal in the Software without restriction, including
+without limitation the rights to use, copy, modify,
+merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom
+the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm
index 8f3a0163b9..91508ded32 100644
--- a/code/__HELPERS/_logging.dm
+++ b/code/__HELPERS/_logging.dm
@@ -26,74 +26,74 @@
/proc/log_admin(text)
GLOB.admin_log.Add(text)
- if (config.log_admin)
+ if (CONFIG_GET(flag/log_admin))
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]ADMIN: [text]")
//Items using this proc are stripped from public logs - use with caution
/proc/log_admin_private(text)
GLOB.admin_log.Add(text)
- if (config.log_admin)
+ if (CONFIG_GET(flag/log_admin))
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]ADMINPRIVATE: [text]")
/proc/log_adminsay(text)
- if (config.log_adminchat)
+ if (CONFIG_GET(flag/log_adminchat))
log_admin_private("ASAY: [text]")
/proc/log_dsay(text)
- if (config.log_adminchat)
+ if (CONFIG_GET(flag/log_adminchat))
log_admin("DSAY: [text]")
/proc/log_game(text)
- if (config.log_game)
+ if (CONFIG_GET(flag/log_game))
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]GAME: [text]")
/proc/log_vote(text)
- if (config.log_vote)
+ if (CONFIG_GET(flag/log_vote))
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]VOTE: [text]")
/proc/log_access(text)
- if (config.log_access)
+ if (CONFIG_GET(flag/log_access))
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]ACCESS: [text]")
/proc/log_say(text)
- if (config.log_say)
+ if (CONFIG_GET(flag/log_say))
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]SAY: [text]")
/proc/log_prayer(text)
- if (config.log_prayer)
+ if (CONFIG_GET(flag/log_prayer))
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]PRAY: [text]")
/proc/log_law(text)
- if (config.log_law)
+ if (CONFIG_GET(flag/log_law))
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]LAW: [text]")
/proc/log_ooc(text)
- if (config.log_ooc)
+ if (CONFIG_GET(flag/log_ooc))
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]OOC: [text]")
/proc/log_whisper(text)
- if (config.log_whisper)
+ if (CONFIG_GET(flag/log_whisper))
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]WHISPER: [text]")
/proc/log_emote(text)
- if (config.log_emote)
+ if (CONFIG_GET(flag/log_emote))
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]EMOTE: [text]")
/proc/log_attack(text)
- if (config.log_attack)
+ if (CONFIG_GET(flag/log_attack))
WRITE_FILE(GLOB.world_attack_log, "\[[time_stamp()]]ATTACK: [text]")
/proc/log_pda(text)
- if (config.log_pda)
+ if (CONFIG_GET(flag/log_pda))
WRITE_FILE(GLOB.world_pda_log, "\[[time_stamp()]]PDA: [text]")
/proc/log_comment(text)
- if (config.log_pda)
+ if (CONFIG_GET(flag/log_pda))
//reusing the PDA option because I really don't think news comments are worth a config option
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]COMMENT: [text]")
/proc/log_chat(text)
- if (config.log_pda)
+ if (CONFIG_GET(flag/log_pda))
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]CHAT: [text]")
/proc/log_qdel(text)
@@ -102,6 +102,10 @@
/proc/log_sql(text)
WRITE_FILE(GLOB.sql_error_log, "\[[time_stamp()]]SQL: [text]")
+/proc/log_config(text)
+ WRITE_FILE(GLOB.config_error_log, text)
+ SEND_TEXT(world.log, text)
+
//This replaces world.log so it displays both in DD and the file
/proc/log_world(text)
WRITE_FILE(GLOB.world_runtime_log, text)
diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index c040e264e6..a16f91b317 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -314,10 +314,11 @@
// Will return a list of active candidates. It increases the buffer 5 times until it finds a candidate which is active within the buffer.
-/proc/get_candidates(be_special_type, afk_bracket = config.inactivity_period, jobbanType)
+/proc/get_candidates(be_special_type, afk_bracket = CONFIG_GET(number/inactivity_period), jobbanType)
var/list/candidates = list()
// Keep looping until we find a non-afk candidate within the time bracket (we limit the bracket to 10 minutes (6000))
- while(!candidates.len && afk_bracket < config.afk_period)
+ var/afk_period = CONFIG_GET(number/afk_period)
+ while(!candidates.len && afk_bracket < afk_period)
for(var/mob/dead/observer/G in GLOB.player_list)
if(G.client != null)
if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
@@ -330,6 +331,20 @@
afk_bracket += 600 // Add a minute to the bracket, for every attempt
return candidates
+/proc/considered_alive(datum/mind/M, enforce_human = TRUE)
+ if(M && M.current)
+ if(enforce_human)
+ var/mob/living/carbon/human/H
+ if(ishuman(M.current))
+ H = M.current
+ return M.current.stat != DEAD && !issilicon(M.current) && !isbrain(M.current) && (!H || H.dna.species.id != "memezombies")
+ else if(isliving(M.current))
+ return M.current.stat != DEAD
+ return FALSE
+
+/proc/considered_afk(datum/mind/M)
+ return !M || !M.current || !M.current.client || M.current.client.is_afk()
+
/proc/ScreenText(obj/O, maptext="", screen_loc="CENTER-7,CENTER-7", maptext_height=480, maptext_width=480)
if(!isobj(O))
O = new /obj/screen/text()
diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm
index 1af231f893..0b79afb941 100644
--- a/code/__HELPERS/global_lists.dm
+++ b/code/__HELPERS/global_lists.dm
@@ -1,116 +1,115 @@
-//////////////////////////
-/////Initial Building/////
-//////////////////////////
-
-/proc/make_datum_references_lists()
- //hair
- init_sprite_accessory_subtypes(/datum/sprite_accessory/hair, GLOB.hair_styles_list, GLOB.hair_styles_male_list, GLOB.hair_styles_female_list)
- //facial hair
- init_sprite_accessory_subtypes(/datum/sprite_accessory/facial_hair, GLOB.facial_hair_styles_list, GLOB.facial_hair_styles_male_list, GLOB.facial_hair_styles_female_list)
- //underwear
- init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear, GLOB.underwear_list, GLOB.underwear_m, GLOB.underwear_f)
- //undershirt
- init_sprite_accessory_subtypes(/datum/sprite_accessory/undershirt, GLOB.undershirt_list, GLOB.undershirt_m, GLOB.undershirt_f)
- //socks
- init_sprite_accessory_subtypes(/datum/sprite_accessory/socks, GLOB.socks_list)
- //lizard bodyparts (blizzard intensifies)
- init_sprite_accessory_subtypes(/datum/sprite_accessory/body_markings, GLOB.body_markings_list)
- init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/lizard, GLOB.tails_list_lizard)
- init_sprite_accessory_subtypes(/datum/sprite_accessory/tails_animated/lizard, GLOB.animated_tails_list_lizard)
- init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/human, GLOB.tails_list_human)
- init_sprite_accessory_subtypes(/datum/sprite_accessory/tails_animated/human, GLOB.animated_tails_list_human)
- init_sprite_accessory_subtypes(/datum/sprite_accessory/snouts, GLOB.snouts_list)
- init_sprite_accessory_subtypes(/datum/sprite_accessory/horns,GLOB.horns_list)
- init_sprite_accessory_subtypes(/datum/sprite_accessory/ears, GLOB.ears_list)
- init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, GLOB.wings_list)
- init_sprite_accessory_subtypes(/datum/sprite_accessory/wings_open, GLOB.wings_open_list)
- init_sprite_accessory_subtypes(/datum/sprite_accessory/frills, GLOB.frills_list)
- init_sprite_accessory_subtypes(/datum/sprite_accessory/spines, GLOB.spines_list)
- init_sprite_accessory_subtypes(/datum/sprite_accessory/spines_animated, GLOB.animated_spines_list)
- init_sprite_accessory_subtypes(/datum/sprite_accessory/legs, GLOB.legs_list)
- init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, GLOB.r_wings_list,roundstart = TRUE)
-
- //citadel code
- //mammal bodyparts (fucking furries)
- init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_body_markings, GLOB.mam_body_markings_list)
- init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_tails, GLOB.mam_tails_list)
- init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_ears, GLOB.mam_ears_list)
- init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_tails_animated, GLOB.mam_tails_animated_list)
- init_sprite_accessory_subtypes(/datum/sprite_accessory/taur, GLOB.taur_list)
- //avian bodyparts (i swear this isn't starbound)
-// init_sprite_accessory_subtypes(/datum/sprite_accessory/beaks/avian, GLOB.avian_beaks_list)
-// init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/avian, GLOB.avian_tails_list)
-// init_sprite_accessory_subtypes(/datum/sprite_accessory/avian_wings, GLOB.avian_wings_list)
-// init_sprite_accessory_subtypes(/datum/sprite_accessory/avian_open_wings, GLOB.avian_open_wings_list)
- //xeno parts (hiss?)
- init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_head, GLOB.xeno_head_list)
- init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_tail, GLOB.xeno_tail_list)
- init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_dorsal, GLOB.xeno_dorsal_list)
- //genitals
- init_sprite_accessory_subtypes(/datum/sprite_accessory/penis, GLOB.cock_shapes_list)
-
- for(var/K in GLOB.cock_shapes_list)
- var/datum/sprite_accessory/penis/value = GLOB.cock_shapes_list[K]
- GLOB.cock_shapes_icons[K] = value.icon_state
-
- init_sprite_accessory_subtypes(/datum/sprite_accessory/vagina, GLOB.vagina_shapes_list)
- init_sprite_accessory_subtypes(/datum/sprite_accessory/breasts, GLOB.breasts_shapes_list)
- GLOB.breasts_size_list = list("a","b","c","d","e") //We need the list to choose from initialized, but it's no longer a sprite_accessory thing.
-
- //Species
- for(var/spath in subtypesof(/datum/species))
- var/datum/species/S = new spath()
- if(S.roundstart)
- GLOB.roundstart_species[S.id] = S.type
- GLOB.species_list[S.id] = S.type
-
- //Surgeries
- for(var/path in subtypesof(/datum/surgery))
- GLOB.surgeries_list += new path()
-
- //Materials
- for(var/path in subtypesof(/datum/material))
- var/datum/material/D = new path()
- GLOB.materials_list[D.id] = D
-
- //Techs
- for(var/path in subtypesof(/datum/tech))
- var/datum/tech/D = new path()
- GLOB.tech_list[D.id] = D
-
- //Emotes
- for(var/path in subtypesof(/datum/emote))
- var/datum/emote/E = new path()
- E.emote_list[E.key] = E
-
- init_subtypes(/datum/crafting_recipe, GLOB.crafting_recipes)
-
-/* // Uncomment to debug chemical reaction list.
-/client/verb/debug_chemical_list()
-
- for (var/reaction in chemical_reactions_list)
- . += "chemical_reactions_list\[\"[reaction]\"\] = \"[chemical_reactions_list[reaction]]\"\n"
- if(islist(chemical_reactions_list[reaction]))
- var/list/L = chemical_reactions_list[reaction]
- for(var/t in L)
- . += " has: [t]\n"
- to_chat(world, .)
-*/
-
-//creates every subtype of prototype (excluding prototype) and adds it to list L.
-//if no list/L is provided, one is created.
-/proc/init_subtypes(prototype, list/L)
- if(!istype(L))
- L = list()
- for(var/path in subtypesof(prototype))
- L += new path()
- return L
-
-//returns a list of paths to every subtype of prototype (excluding prototype)
-//if no list/L is provided, one is created.
-/proc/init_paths(prototype, list/L)
- if(!istype(L))
- L = list()
- for(var/path in subtypesof(prototype))
- L+= path
- return L
+//////////////////////////
+/////Initial Building/////
+//////////////////////////
+
+/proc/make_datum_references_lists()
+ //hair
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/hair, GLOB.hair_styles_list, GLOB.hair_styles_male_list, GLOB.hair_styles_female_list)
+ //facial hair
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/facial_hair, GLOB.facial_hair_styles_list, GLOB.facial_hair_styles_male_list, GLOB.facial_hair_styles_female_list)
+ //underwear
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear, GLOB.underwear_list, GLOB.underwear_m, GLOB.underwear_f)
+ //undershirt
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/undershirt, GLOB.undershirt_list, GLOB.undershirt_m, GLOB.undershirt_f)
+ //socks
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/socks, GLOB.socks_list)
+ //lizard bodyparts (blizzard intensifies)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/body_markings, GLOB.body_markings_list)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/lizard, GLOB.tails_list_lizard)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/tails_animated/lizard, GLOB.animated_tails_list_lizard)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/human, GLOB.tails_list_human)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/tails_animated/human, GLOB.animated_tails_list_human)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/snouts, GLOB.snouts_list)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/horns,GLOB.horns_list)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/ears, GLOB.ears_list)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, GLOB.wings_list)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/wings_open, GLOB.wings_open_list)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/frills, GLOB.frills_list)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/spines, GLOB.spines_list)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/spines_animated, GLOB.animated_spines_list)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/legs, GLOB.legs_list)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, GLOB.r_wings_list,roundstart = TRUE)
+
+ //citadel code
+ //mammal bodyparts (fucking furries)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_body_markings, GLOB.mam_body_markings_list)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_tails, GLOB.mam_tails_list)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_ears, GLOB.mam_ears_list)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_tails_animated, GLOB.mam_tails_animated_list)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/taur, GLOB.taur_list)
+ //avian bodyparts (i swear this isn't starbound)
+// init_sprite_accessory_subtypes(/datum/sprite_accessory/beaks/avian, GLOB.avian_beaks_list)
+// init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/avian, GLOB.avian_tails_list)
+// init_sprite_accessory_subtypes(/datum/sprite_accessory/avian_wings, GLOB.avian_wings_list)
+// init_sprite_accessory_subtypes(/datum/sprite_accessory/avian_open_wings, GLOB.avian_open_wings_list)
+ //xeno parts (hiss?)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_head, GLOB.xeno_head_list)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_tail, GLOB.xeno_tail_list)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_dorsal, GLOB.xeno_dorsal_list)
+ //genitals
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/penis, GLOB.cock_shapes_list)
+
+ for(var/K in GLOB.cock_shapes_list)
+ var/datum/sprite_accessory/penis/value = GLOB.cock_shapes_list[K]
+ GLOB.cock_shapes_icons[K] = value.icon_state
+
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/vagina, GLOB.vagina_shapes_list)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/breasts, GLOB.breasts_shapes_list)
+ GLOB.breasts_size_list = list("a","b","c","d","e") //We need the list to choose from initialized, but it's no longer a sprite_accessory thing.
+
+
+ //Species
+ for(var/spath in subtypesof(/datum/species))
+ var/datum/species/S = new spath()
+ GLOB.species_list[S.id] = spath
+
+ //Surgeries
+ for(var/path in subtypesof(/datum/surgery))
+ GLOB.surgeries_list += new path()
+
+ //Materials
+ for(var/path in subtypesof(/datum/material))
+ var/datum/material/D = new path()
+ GLOB.materials_list[D.id] = D
+
+ //Techs
+ for(var/path in subtypesof(/datum/tech))
+ var/datum/tech/D = new path()
+ GLOB.tech_list[D.id] = D
+
+ //Emotes
+ for(var/path in subtypesof(/datum/emote))
+ var/datum/emote/E = new path()
+ E.emote_list[E.key] = E
+
+ init_subtypes(/datum/crafting_recipe, GLOB.crafting_recipes)
+
+/* // Uncomment to debug chemical reaction list.
+/client/verb/debug_chemical_list()
+
+ for (var/reaction in chemical_reactions_list)
+ . += "chemical_reactions_list\[\"[reaction]\"\] = \"[chemical_reactions_list[reaction]]\"\n"
+ if(islist(chemical_reactions_list[reaction]))
+ var/list/L = chemical_reactions_list[reaction]
+ for(var/t in L)
+ . += " has: [t]\n"
+ to_chat(world, .)
+*/
+
+//creates every subtype of prototype (excluding prototype) and adds it to list L.
+//if no list/L is provided, one is created.
+/proc/init_subtypes(prototype, list/L)
+ if(!istype(L))
+ L = list()
+ for(var/path in subtypesof(prototype))
+ L += new path()
+ return L
+
+//returns a list of paths to every subtype of prototype (excluding prototype)
+//if no list/L is provided, one is created.
+/proc/init_paths(prototype, list/L)
+ if(!istype(L))
+ L = list()
+ for(var/path in subtypesof(prototype))
+ L+= path
+ return L
diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index ed855c33b9..de606b137e 100644
--- a/code/__HELPERS/mobs.dm
+++ b/code/__HELPERS/mobs.dm
@@ -220,7 +220,6 @@ GLOBAL_LIST_INIT(skin_tones, list(
))
GLOBAL_LIST_EMPTY(species_list)
-GLOBAL_LIST_EMPTY(roundstart_species)
/proc/age2agedescription(age)
switch(age)
diff --git a/code/__HELPERS/names.dm b/code/__HELPERS/names.dm
index 67179e8c8f..bfcfd23f50 100644
--- a/code/__HELPERS/names.dm
+++ b/code/__HELPERS/names.dm
@@ -1,246 +1,248 @@
-#define ION_FILE "ion_laws.json"
-
-/proc/lizard_name(gender)
- if(gender == MALE)
- return "[pick(GLOB.lizard_names_male)]-[pick(GLOB.lizard_names_male)]"
- else
- return "[pick(GLOB.lizard_names_female)]-[pick(GLOB.lizard_names_female)]"
-
-/proc/plasmaman_name()
- return "[pick(GLOB.plasmaman_names)] \Roman[rand(1,99)]"
-
-/proc/church_name()
- var/static/church_name
- if (church_name)
- return church_name
-
- var/name = ""
-
- name += pick("Holy", "United", "First", "Second", "Last")
-
- if (prob(20))
- name += " Space"
-
- name += " " + pick("Church", "Cathedral", "Body", "Worshippers", "Movement", "Witnesses")
- name += " of [religion_name()]"
-
- return name
-
-GLOBAL_VAR(command_name)
-/proc/command_name()
- if (GLOB.command_name)
- return GLOB.command_name
-
- var/name = "Central Command"
-
- GLOB.command_name = name
- return name
-
-/proc/change_command_name(name)
-
- GLOB.command_name = name
-
- return name
-
-/proc/religion_name()
- var/static/religion_name
- if (religion_name)
- return religion_name
-
- var/name = ""
-
- name += pick("bee", "science", "edu", "captain", "assistant", "monkey", "alien", "space", "unit", "sprocket", "gadget", "bomb", "revolution", "beyond", "station", "goon", "robot", "ivor", "hobnob")
- name += pick("ism", "ia", "ology", "istism", "ites", "ick", "ian", "ity")
-
- return capitalize(name)
-
-/proc/station_name()
- if(!GLOB.station_name)
- var/newname
- if(config && config.station_name)
- newname = config.station_name
- else
- newname = new_station_name()
-
- set_station_name(newname)
-
- return GLOB.station_name
-
-/proc/set_station_name(newname)
- GLOB.station_name = newname
-
- if(config && config.server_name)
- world.name = "[config.server_name][config.server_name==GLOB.station_name ? "" : ": [GLOB.station_name]"]"
- else
- world.name = GLOB.station_name
-
-
-/proc/new_station_name()
- var/random = rand(1,5)
- var/name = ""
- var/new_station_name = ""
-
- //Rare: Pre-Prefix
- if (prob(10))
- name = pick(GLOB.station_prefixes)
- new_station_name = name + " "
- name = ""
-
- // Prefix
- for(var/holiday_name in SSevents.holidays)
- if(holiday_name == "Friday the 13th")
- random = 13
- var/datum/holiday/holiday = SSevents.holidays[holiday_name]
- name = holiday.getStationPrefix()
- //get normal name
- if(!name)
- name = pick(GLOB.station_names)
- if(name)
- new_station_name += name + " "
-
- // Suffix
- name = pick(GLOB.station_suffixes)
- new_station_name += name + " "
-
- // ID Number
- switch(random)
- if(1)
- new_station_name += "[rand(1, 99)]"
- if(2)
- new_station_name += pick(GLOB.greek_letters)
- if(3)
- new_station_name += "\Roman[rand(1,99)]"
- if(4)
- new_station_name += pick(GLOB.phonetic_alphabet)
- if(5)
- new_station_name += pick(GLOB.numbers_as_words)
- if(13)
- new_station_name += pick("13","XIII","Thirteen")
- return new_station_name
-
-/proc/syndicate_name()
- var/static/syndicate_name
- if (syndicate_name)
- return syndicate_name
-
- var/name = ""
-
- // Prefix
- name += pick("Clandestine", "Prima", "Blue", "Zero-G", "Max", "Blasto", "Waffle", "North", "Omni", "Newton", "Cyber", "Bonk", "Gene", "Gib")
-
- // Suffix
- if (prob(80))
- name += " "
-
- // Full
- if (prob(60))
- name += pick("Syndicate", "Consortium", "Collective", "Corporation", "Group", "Holdings", "Biotech", "Industries", "Systems", "Products", "Chemicals", "Enterprises", "Family", "Creations", "International", "Intergalactic", "Interplanetary", "Foundation", "Positronics", "Hive")
- // Broken
- else
- name += pick("Syndi", "Corp", "Bio", "System", "Prod", "Chem", "Inter", "Hive")
- name += pick("", "-")
- name += pick("Tech", "Sun", "Co", "Tek", "X", "Inc", "Code")
- // Small
- else
- name += pick("-", "*", "")
- name += pick("Tech", "Sun", "Co", "Tek", "X", "Inc", "Gen", "Star", "Dyne", "Code", "Hive")
-
- syndicate_name = name
- return name
-
-
-//Traitors and traitor silicons will get these. Revs will not.
-GLOBAL_VAR(syndicate_code_phrase) //Code phrase for traitors.
-GLOBAL_VAR(syndicate_code_response) //Code response for traitors.
-
- /*
- Should be expanded.
- How this works:
- Instead of "I'm looking for James Smith," the traitor would say "James Smith" as part of a conversation.
- Another traitor may then respond with: "They enjoy running through the void-filled vacuum of the derelict."
- The phrase should then have the words: James Smith.
- The response should then have the words: run, void, and derelict.
- This way assures that the code is suited to the conversation and is unpredicatable.
- Obviously, some people will be better at this than others but in theory, everyone should be able to do it and it only enhances roleplay.
- Can probably be done through "{ }" but I don't really see the practical benefit.
- One example of an earlier system is commented below.
- /N
- */
-
-/proc/generate_code_phrase(return_list=FALSE)//Proc is used for phrase and response in master_controller.dm
-
- if(!return_list)
- . = ""
- else
- . = list()
-
- var/words = pick(//How many words there will be. Minimum of two. 2, 4 and 5 have a lesser chance of being selected. 3 is the most likely.
- 50; 2,
- 200; 3,
- 50; 4,
- 25; 5
- )
-
- var/list/safety = list(1,2,3)//Tells the proc which options to remove later on.
- var/nouns = strings(ION_FILE, "ionabstract")
- var/objects = strings(ION_FILE, "ionobjects")
- var/adjectives = strings(ION_FILE, "ionadjectives")
- var/threats = strings(ION_FILE, "ionthreats")
- var/foods = strings(ION_FILE, "ionfood")
- var/drinks = strings(ION_FILE, "iondrinks")
- var/list/locations = GLOB.teleportlocs.len ? GLOB.teleportlocs : drinks //if null, defaults to drinks instead.
-
- var/list/names = list()
- for(var/datum/data/record/t in GLOB.data_core.general)//Picks from crew manifest.
- names += t.fields["name"]
-
- var/maxwords = words//Extra var to check for duplicates.
-
- for(words,words>0,words--)//Randomly picks from one of the choices below.
-
- if(words==1&&(1 in safety)&&(2 in safety))//If there is only one word remaining and choice 1 or 2 have not been selected.
- safety = list(pick(1,2))//Select choice 1 or 2.
- else if(words==1&&maxwords==2)//Else if there is only one word remaining (and there were two originally), and 1 or 2 were chosen,
- safety = list(3)//Default to list 3
-
- switch(pick(safety))//Chance based on the safety list.
- if(1)//1 and 2 can only be selected once each to prevent more than two specific names/places/etc.
- switch(rand(1,2))//Mainly to add more options later.
- if(1)
- if(names.len&&prob(70))
- . += pick(names)
- else
- if(prob(10))
- . += pick(lizard_name(MALE),lizard_name(FEMALE))
- else
- var/new_name = pick(pick(GLOB.first_names_male,GLOB.first_names_female))
- new_name += " "
- new_name += pick(GLOB.last_names)
- . += new_name
- if(2)
- . += pick(get_all_jobs())//Returns a job.
- safety -= 1
- if(2)
- switch(rand(1,3))//Food, drinks, or things. Only selectable once.
- if(1)
- . += lowertext(pick(drinks))
- if(2)
- . += lowertext(pick(foods))
- if(3)
- . += lowertext(pick(locations))
- safety -= 2
- if(3)
- switch(rand(1,4))//Abstract nouns, objects, adjectives, threats. Can be selected more than once.
- if(1)
- . += lowertext(pick(nouns))
- if(2)
- . += lowertext(pick(objects))
- if(3)
- . += lowertext(pick(adjectives))
- if(4)
- . += lowertext(pick(threats))
- if(!return_list)
- if(words==1)
- . += "."
- else
- . += ", "
+#define ION_FILE "ion_laws.json"
+
+/proc/lizard_name(gender)
+ if(gender == MALE)
+ return "[pick(GLOB.lizard_names_male)]-[pick(GLOB.lizard_names_male)]"
+ else
+ return "[pick(GLOB.lizard_names_female)]-[pick(GLOB.lizard_names_female)]"
+
+/proc/plasmaman_name()
+ return "[pick(GLOB.plasmaman_names)] \Roman[rand(1,99)]"
+
+/proc/church_name()
+ var/static/church_name
+ if (church_name)
+ return church_name
+
+ var/name = ""
+
+ name += pick("Holy", "United", "First", "Second", "Last")
+
+ if (prob(20))
+ name += " Space"
+
+ name += " " + pick("Church", "Cathedral", "Body", "Worshippers", "Movement", "Witnesses")
+ name += " of [religion_name()]"
+
+ return name
+
+GLOBAL_VAR(command_name)
+/proc/command_name()
+ if (GLOB.command_name)
+ return GLOB.command_name
+
+ var/name = "Central Command"
+
+ GLOB.command_name = name
+ return name
+
+/proc/change_command_name(name)
+
+ GLOB.command_name = name
+
+ return name
+
+/proc/religion_name()
+ var/static/religion_name
+ if (religion_name)
+ return religion_name
+
+ var/name = ""
+
+ name += pick("bee", "science", "edu", "captain", "assistant", "monkey", "alien", "space", "unit", "sprocket", "gadget", "bomb", "revolution", "beyond", "station", "goon", "robot", "ivor", "hobnob")
+ name += pick("ism", "ia", "ology", "istism", "ites", "ick", "ian", "ity")
+
+ return capitalize(name)
+
+/proc/station_name()
+ if(!GLOB.station_name)
+ var/newname
+ var/config_station_name = CONFIG_GET(string/stationname)
+ if(config_station_name)
+ newname = config_station_name
+ else
+ newname = new_station_name()
+
+ set_station_name(newname)
+
+ return GLOB.station_name
+
+/proc/set_station_name(newname)
+ GLOB.station_name = newname
+
+ var/config_server_name = CONFIG_GET(string/servername)
+ if(config_server_name)
+ world.name = "[config_server_name][config_server_name == GLOB.station_name ? "" : ": [GLOB.station_name]"]"
+ else
+ world.name = GLOB.station_name
+
+
+/proc/new_station_name()
+ var/random = rand(1,5)
+ var/name = ""
+ var/new_station_name = ""
+
+ //Rare: Pre-Prefix
+ if (prob(10))
+ name = pick(GLOB.station_prefixes)
+ new_station_name = name + " "
+ name = ""
+
+ // Prefix
+ for(var/holiday_name in SSevents.holidays)
+ if(holiday_name == "Friday the 13th")
+ random = 13
+ var/datum/holiday/holiday = SSevents.holidays[holiday_name]
+ name = holiday.getStationPrefix()
+ //get normal name
+ if(!name)
+ name = pick(GLOB.station_names)
+ if(name)
+ new_station_name += name + " "
+
+ // Suffix
+ name = pick(GLOB.station_suffixes)
+ new_station_name += name + " "
+
+ // ID Number
+ switch(random)
+ if(1)
+ new_station_name += "[rand(1, 99)]"
+ if(2)
+ new_station_name += pick(GLOB.greek_letters)
+ if(3)
+ new_station_name += "\Roman[rand(1,99)]"
+ if(4)
+ new_station_name += pick(GLOB.phonetic_alphabet)
+ if(5)
+ new_station_name += pick(GLOB.numbers_as_words)
+ if(13)
+ new_station_name += pick("13","XIII","Thirteen")
+ return new_station_name
+
+/proc/syndicate_name()
+ var/static/syndicate_name
+ if (syndicate_name)
+ return syndicate_name
+
+ var/name = ""
+
+ // Prefix
+ name += pick("Clandestine", "Prima", "Blue", "Zero-G", "Max", "Blasto", "Waffle", "North", "Omni", "Newton", "Cyber", "Bonk", "Gene", "Gib")
+
+ // Suffix
+ if (prob(80))
+ name += " "
+
+ // Full
+ if (prob(60))
+ name += pick("Syndicate", "Consortium", "Collective", "Corporation", "Group", "Holdings", "Biotech", "Industries", "Systems", "Products", "Chemicals", "Enterprises", "Family", "Creations", "International", "Intergalactic", "Interplanetary", "Foundation", "Positronics", "Hive")
+ // Broken
+ else
+ name += pick("Syndi", "Corp", "Bio", "System", "Prod", "Chem", "Inter", "Hive")
+ name += pick("", "-")
+ name += pick("Tech", "Sun", "Co", "Tek", "X", "Inc", "Code")
+ // Small
+ else
+ name += pick("-", "*", "")
+ name += pick("Tech", "Sun", "Co", "Tek", "X", "Inc", "Gen", "Star", "Dyne", "Code", "Hive")
+
+ syndicate_name = name
+ return name
+
+
+//Traitors and traitor silicons will get these. Revs will not.
+GLOBAL_VAR(syndicate_code_phrase) //Code phrase for traitors.
+GLOBAL_VAR(syndicate_code_response) //Code response for traitors.
+
+ /*
+ Should be expanded.
+ How this works:
+ Instead of "I'm looking for James Smith," the traitor would say "James Smith" as part of a conversation.
+ Another traitor may then respond with: "They enjoy running through the void-filled vacuum of the derelict."
+ The phrase should then have the words: James Smith.
+ The response should then have the words: run, void, and derelict.
+ This way assures that the code is suited to the conversation and is unpredicatable.
+ Obviously, some people will be better at this than others but in theory, everyone should be able to do it and it only enhances roleplay.
+ Can probably be done through "{ }" but I don't really see the practical benefit.
+ One example of an earlier system is commented below.
+ /N
+ */
+
+/proc/generate_code_phrase(return_list=FALSE)//Proc is used for phrase and response in master_controller.dm
+
+ if(!return_list)
+ . = ""
+ else
+ . = list()
+
+ var/words = pick(//How many words there will be. Minimum of two. 2, 4 and 5 have a lesser chance of being selected. 3 is the most likely.
+ 50; 2,
+ 200; 3,
+ 50; 4,
+ 25; 5
+ )
+
+ var/list/safety = list(1,2,3)//Tells the proc which options to remove later on.
+ var/nouns = strings(ION_FILE, "ionabstract")
+ var/objects = strings(ION_FILE, "ionobjects")
+ var/adjectives = strings(ION_FILE, "ionadjectives")
+ var/threats = strings(ION_FILE, "ionthreats")
+ var/foods = strings(ION_FILE, "ionfood")
+ var/drinks = strings(ION_FILE, "iondrinks")
+ var/list/locations = GLOB.teleportlocs.len ? GLOB.teleportlocs : drinks //if null, defaults to drinks instead.
+
+ var/list/names = list()
+ for(var/datum/data/record/t in GLOB.data_core.general)//Picks from crew manifest.
+ names += t.fields["name"]
+
+ var/maxwords = words//Extra var to check for duplicates.
+
+ for(words,words>0,words--)//Randomly picks from one of the choices below.
+
+ if(words==1&&(1 in safety)&&(2 in safety))//If there is only one word remaining and choice 1 or 2 have not been selected.
+ safety = list(pick(1,2))//Select choice 1 or 2.
+ else if(words==1&&maxwords==2)//Else if there is only one word remaining (and there were two originally), and 1 or 2 were chosen,
+ safety = list(3)//Default to list 3
+
+ switch(pick(safety))//Chance based on the safety list.
+ if(1)//1 and 2 can only be selected once each to prevent more than two specific names/places/etc.
+ switch(rand(1,2))//Mainly to add more options later.
+ if(1)
+ if(names.len&&prob(70))
+ . += pick(names)
+ else
+ if(prob(10))
+ . += pick(lizard_name(MALE),lizard_name(FEMALE))
+ else
+ var/new_name = pick(pick(GLOB.first_names_male,GLOB.first_names_female))
+ new_name += " "
+ new_name += pick(GLOB.last_names)
+ . += new_name
+ if(2)
+ . += pick(get_all_jobs())//Returns a job.
+ safety -= 1
+ if(2)
+ switch(rand(1,3))//Food, drinks, or things. Only selectable once.
+ if(1)
+ . += lowertext(pick(drinks))
+ if(2)
+ . += lowertext(pick(foods))
+ if(3)
+ . += lowertext(pick(locations))
+ safety -= 2
+ if(3)
+ switch(rand(1,4))//Abstract nouns, objects, adjectives, threats. Can be selected more than once.
+ if(1)
+ . += lowertext(pick(nouns))
+ if(2)
+ . += lowertext(pick(objects))
+ if(3)
+ . += lowertext(pick(adjectives))
+ if(4)
+ . += lowertext(pick(threats))
+ if(!return_list)
+ if(words==1)
+ . += "."
+ else
+ . += ", "
diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm
index ce8f9f9bd2..3491e831e6 100644
--- a/code/__HELPERS/text.dm
+++ b/code/__HELPERS/text.dm
@@ -19,7 +19,7 @@
return copytext(sqltext, 2, lentext(sqltext));//Quote() adds quotes around input, we already do that
/proc/format_table_name(table as text)
- return global.sqlfdbktableprefix + table
+ return CONFIG_GET(string/feedback_tableprefix) + table
/*
* Text sanitization
@@ -443,8 +443,8 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
if(!limited)
t = replacetext(t, "((", "")
t = replacetext(t, "))", " ")
- t = replacetext(t, regex("^-{3,}$", "gm"), "
")
- t = replacetext(t, regex("^\\(-{3,})$", "gm"), "$1")
+ t = replacetext(t, regex("(-){3,}", "gm"), " ")
+ t = replacetext(t, regex("^\\((-){3,}\\)$", "gm"), "$1")
// Parse lists
@@ -594,7 +594,7 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
//in the json file and have it be reflected in the in game item/mob it came from.
//(That's what things like savefiles are for) Note that this list is not shuffled.
/proc/twitterize(list/proposed, filename, cullshort = 1, storemax = 1000)
- if(!islist(proposed) || !filename || !config.log_twitter)
+ if(!islist(proposed) || !filename || !CONFIG_GET(flag/log_twitter))
return
//Regular expressions are, as usual, absolute magic
diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm
index 60b5d82940..46d6c2ce5c 100644
--- a/code/__HELPERS/type2type.dm
+++ b/code/__HELPERS/type2type.dm
@@ -554,3 +554,24 @@
else
return /datum
return text2path(copytext(string_type, 1, last_slash))
+
+//returns a string the last bit of a type, without the preceeding '/'
+/proc/type2top(the_type)
+ //handle the builtins manually
+ if(!ispath(the_type))
+ return
+ switch(the_type)
+ if(/datum)
+ return "datum"
+ if(/atom)
+ return "atom"
+ if(/obj)
+ return "obj"
+ if(/mob)
+ return "mob"
+ if(/area)
+ return "area"
+ if(/turf)
+ return "turf"
+ else //regex everything else (works for /proc too)
+ return lowertext(replacetext("[the_type]", "[type2parent(the_type)]/", ""))
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index c2398982c2..5e190ab709 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -1266,7 +1266,7 @@ proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types())
#define QDEL_LIST(L) if(L) { for(var/I in L) qdel(I); L.Cut(); }
#define QDEL_LIST_IN(L, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/______qdel_list_wrapper, L), time, TIMER_STOPPABLE)
#define QDEL_LIST_ASSOC(L) if(L) { for(var/I in L) { qdel(L[I]); qdel(I); } L.Cut(); }
-#define QDEL_LIST_ASSOC_VAL(L) if(L) { for(var/I in L) qel(L[I]); L.Cut(); }
+#define QDEL_LIST_ASSOC_VAL(L) if(L) { for(var/I in L) qdel(L[I]); L.Cut(); }
/proc/______qdel_list_wrapper(list/L) //the underscores are to encourage people not to use this directly.
QDEL_LIST(L)
@@ -1364,63 +1364,6 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
return FALSE
return TRUE
-//WHATEVER YOU USE THIS FOR MUST BE SANITIZED TO SHIT, IT USES SHELL
-//It also sleeps
-
-//Set this to TRUE before calling
-//This prevents RCEs from badmins
-//kevinz000 if you touch this I will hunt you down
-GLOBAL_VAR_INIT(valid_HTTPSGet, FALSE)
-GLOBAL_PROTECT(valid_HTTPSGet)
-/proc/HTTPSGet(url) //tgs2 support
- if(findtext(url, "\""))
- GLOB.valid_HTTPSGet = FALSE
-
- if(!GLOB.valid_HTTPSGet)
- if(usr)
- CRASH("[usr.ckey]([usr]) just attempted an invalid HTTPSGet on: [url]!")
- else
- CRASH("Invalid HTTPSGet call on: [url]")
- GLOB.valid_HTTPSGet = FALSE
-
- //"This has got to be the ugliest hack I have ever done"
- //warning, here be dragons
- /*
- | @___oo
- /\ /\ / (__,,,,|
- ) /^\) ^\/ _)
- ) /^\/ _)
- ) _ / / _)
- /\ )/\/ || | )_)
- < > |(,,) )__)
- || / \)___)\
- | \____( )___) )___
- \______(_______;;; __;;;
- */
- var/temp_file = "data/HTTPSGetOutput.txt"
- var/command
- if(world.system_type == MS_WINDOWS)
- command = "powershell -Command \"wget [url] -OutFile [temp_file]\""
- else if(world.system_type == UNIX)
- command = "wget -O [temp_file] [url]"
- else
- CRASH("Invalid world.system_type ([world.system_type])? Yell at Lummox.")
-
- log_world("HTTPSGet: [url]")
- var/result = shell(command)
- if(result != 0)
- log_world("Download failed: shell exited with code: [result]")
- return
-
- var/f = file(temp_file)
- if(!f)
- log_world("Download failed: Temp file not found")
- return
-
- . = file2text(f)
- f = null
- fdel(temp_file)
-
#define UNTIL(X) while(!(X)) stoplag()
/proc/pass()
diff --git a/code/_globalvars/configuration.dm b/code/_globalvars/configuration.dm
index 83bf3cfb5a..391744e34c 100644
--- a/code/_globalvars/configuration.dm
+++ b/code/_globalvars/configuration.dm
@@ -1,4 +1,4 @@
-GLOBAL_REAL(config, /datum/configuration)
+GLOBAL_REAL(config, /datum/controller/configuration)
GLOBAL_DATUM_INIT(revdata, /datum/getrev, new)
@@ -11,9 +11,7 @@ GLOBAL_VAR_INIT(hub_visibility, FALSE)
GLOBAL_VAR_INIT(ooc_allowed, TRUE) // used with admin verbs to disable ooc - not a config option apparently
GLOBAL_VAR_INIT(dooc_allowed, TRUE)
-GLOBAL_VAR_INIT(abandon_allowed, TRUE)
GLOBAL_VAR_INIT(enter_allowed, TRUE)
-GLOBAL_VAR_INIT(guests_allowed, TRUE)
GLOBAL_VAR_INIT(shuttle_frozen, FALSE)
GLOBAL_VAR_INIT(shuttle_left, FALSE)
GLOBAL_VAR_INIT(tinted_weldhelh, TRUE)
@@ -25,10 +23,16 @@ GLOBAL_VAR_INIT(Debug, FALSE) // global debug switch
GLOBAL_VAR_INIT(Debug2, FALSE)
//This was a define, but I changed it to a variable so it can be changed in-game.(kept the all-caps definition because... code...) -Errorage
+//Protecting these because the proper way to edit them is with the config/secrets
GLOBAL_VAR_INIT(MAX_EX_DEVESTATION_RANGE, 3)
+GLOBAL_PROTECT(MAX_EX_DEVESTATION_RANGE)
GLOBAL_VAR_INIT(MAX_EX_HEAVY_RANGE, 7)
+GLOBAL_PROTECT(MAX_EX_HEAVY_RANGE)
GLOBAL_VAR_INIT(MAX_EX_LIGHT_RANGE, 14)
+GLOBAL_PROTECT(MAX_EX_LIGHT_RANGE)
GLOBAL_VAR_INIT(MAX_EX_FLASH_RANGE, 14)
+GLOBAL_PROTECT(MAX_EX_FLASH_RANGE)
GLOBAL_VAR_INIT(MAX_EX_FLAME_RANGE, 14)
+GLOBAL_PROTECT(MAX_EX_FLAME_RANGE)
GLOBAL_VAR_INIT(DYN_EX_SCALE, 0.5)
diff --git a/code/_globalvars/lists/names.dm b/code/_globalvars/lists/names.dm
index 522ff84ff0..d855c7f141 100644
--- a/code/_globalvars/lists/names.dm
+++ b/code/_globalvars/lists/names.dm
@@ -15,6 +15,7 @@ GLOBAL_LIST_INIT(carp_names, world.file2list("strings/names/carp.txt"))
GLOBAL_LIST_INIT(golem_names, world.file2list("strings/names/golem.txt"))
GLOBAL_LIST_INIT(plasmaman_names, world.file2list("strings/names/plasmaman.txt"))
GLOBAL_LIST_INIT(posibrain_names, world.file2list("strings/names/posibrain.txt"))
+GLOBAL_LIST_INIT(nightmare_names, world.file2list("strings/names/nightmare.txt"))
GLOBAL_LIST_INIT(verbs, world.file2list("strings/names/verbs.txt"))
diff --git a/code/_globalvars/sensitive.dm b/code/_globalvars/sensitive.dm
deleted file mode 100644
index e1a02621ac..0000000000
--- a/code/_globalvars/sensitive.dm
+++ /dev/null
@@ -1,16 +0,0 @@
-//Server API key
-GLOBAL_REAL_VAR(comms_key) = "default_pwd"
-GLOBAL_REAL_VAR(comms_allowed) = FALSE //By default, the server does not allow messages to be sent to it, unless the key is strong enough (this is to prevent misconfigured servers from becoming vulnerable)
-
-GLOBAL_REAL_VAR(medal_hub)
-GLOBAL_REAL_VAR(medal_pass) = " "
-GLOBAL_REAL_VAR(medals_enabled) = TRUE //will be auto set to false if the game fails contacting the medal hub to prevent unneeded calls.
-
-// MySQL configuration
-
-GLOBAL_REAL_VAR(sqladdress) = "localhost"
-GLOBAL_REAL_VAR(sqlport) = "3306"
-GLOBAL_REAL_VAR(sqlfdbkdb) = "test"
-GLOBAL_REAL_VAR(sqlfdbklogin) = "root"
-GLOBAL_REAL_VAR(sqlfdbkpass) = ""
-GLOBAL_REAL_VAR(sqlfdbktableprefix) = ""
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index 2bc6e144dd..99d12568bc 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -96,7 +96,7 @@
if(!modifiers["catcher"] && A.IsObscured())
return
- if(istype(loc, /obj/mecha))
+ if(ismecha(loc))
var/obj/mecha/M = loc
return M.click_action(A,src,params)
@@ -327,7 +327,7 @@
ML.pulled(src)
/mob/living/carbon/human/CtrlClick(mob/user)
- if(ishuman(user) && Adjacent(user))
+ if(ishuman(user) && Adjacent(user) && !user.incapacitated())
if(world.time < user.next_move)
return FALSE
var/mob/living/carbon/human/H = user
@@ -359,7 +359,6 @@
else
user.listed_turf = T
user.client.statpanel = T.name
- user.Stat() //responsive ui pls
/mob/proc/TurfAdjacent(turf/T)
return T.Adjacent(src)
diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm
index 1e3c10d57c..3cc6734482 100644
--- a/code/_onclick/hud/alert.dm
+++ b/code/_onclick/hud/alert.dm
@@ -538,7 +538,7 @@ so as to remain in compliance with the most up-to-date laws."
if(NOTIFY_JUMP)
var/turf/T = get_turf(target)
if(T && isturf(T))
- G.loc = T
+ G.forceMove(T)
if(NOTIFY_ORBIT)
G.ManualFollow(target)
diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm
index 07c17b891f..4d1ca2c778 100644
--- a/code/_onclick/hud/human.dm
+++ b/code/_onclick/hud/human.dm
@@ -28,7 +28,7 @@
icon_state = "act_equip"
/obj/screen/human/equip/Click()
- if(istype(usr.loc, /obj/mecha)) // stops inventory actions in a mech
+ if(ismecha(usr.loc)) // stops inventory actions in a mech
return 1
var/mob/living/carbon/human/H = usr
H.quick_equip()
@@ -313,11 +313,15 @@
inv.hud = src
inv_slots[inv.slot_id] = inv
inv.update_icon()
+
+ update_locked_slots()
/datum/hud/human/update_locked_slots()
if(!mymob)
return
var/mob/living/carbon/human/H = mymob
+ if(!istype(H) || !H.dna.species)
+ return
var/datum/species/S = H.dna.species
for(var/obj/screen/inventory/inv in (static_inventory + toggleable_inventory))
if(inv.slot_id)
diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm
index 2d94f41ba9..0906a099a0 100644
--- a/code/_onclick/hud/screen_objects.dm
+++ b/code/_onclick/hud/screen_objects.dm
@@ -1,586 +1,586 @@
-/*
- Screen objects
- Todo: improve/re-implement
-
- Screen objects are only used for the hud and should not appear anywhere "in-game".
- They are used with the client/screen list and the screen_loc var.
- For more information, see the byond documentation on the screen_loc and screen vars.
-*/
-/obj/screen
- name = ""
- icon = 'icons/mob/screen_gen.dmi'
- layer = ABOVE_HUD_LAYER
- plane = ABOVE_HUD_PLANE
- resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
- appearance_flags = APPEARANCE_UI
- var/obj/master = null //A reference to the object in the slot. Grabs or items, generally.
- var/datum/hud/hud = null // A reference to the owner HUD, if any.
-
-/obj/screen/take_damage()
- return
-
-/obj/screen/Destroy()
- master = null
- hud = null
- return ..()
-
-/obj/screen/examine(mob/user)
- return
-
-/obj/screen/orbit()
- return
-
-/obj/screen/text
- icon = null
- icon_state = null
+/*
+ Screen objects
+ Todo: improve/re-implement
+
+ Screen objects are only used for the hud and should not appear anywhere "in-game".
+ They are used with the client/screen list and the screen_loc var.
+ For more information, see the byond documentation on the screen_loc and screen vars.
+*/
+/obj/screen
+ name = ""
+ icon = 'icons/mob/screen_gen.dmi'
+ layer = ABOVE_HUD_LAYER
+ plane = ABOVE_HUD_PLANE
+ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
+ appearance_flags = APPEARANCE_UI
+ var/obj/master = null //A reference to the object in the slot. Grabs or items, generally.
+ var/datum/hud/hud = null // A reference to the owner HUD, if any.
+
+/obj/screen/take_damage()
+ return
+
+/obj/screen/Destroy()
+ master = null
+ hud = null
+ return ..()
+
+/obj/screen/examine(mob/user)
+ return
+
+/obj/screen/orbit()
+ return
+
+/obj/screen/text
+ icon = null
+ icon_state = null
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
- screen_loc = "CENTER-7,CENTER-7"
- maptext_height = 480
- maptext_width = 480
-
-/obj/screen/swap_hand
- layer = HUD_LAYER
- plane = HUD_PLANE
- name = "swap hand"
-
-/obj/screen/swap_hand/Click()
- // At this point in client Click() code we have passed the 1/10 sec check and little else
- // We don't even know if it's a middle click
- if(world.time <= usr.next_move)
- return 1
-
- if(usr.incapacitated())
- return 1
-
- if(ismob(usr))
- var/mob/M = usr
- M.swap_hand()
- return 1
-
-/obj/screen/craft
- name = "crafting menu"
- icon = 'icons/mob/screen_midnight.dmi'
- icon_state = "craft"
- screen_loc = ui_crafting
-
-/obj/screen/craft/Click()
- var/mob/living/M = usr
- if(isobserver(usr))
- return
- M.OpenCraftingMenu()
-
-/obj/screen/area_creator
- name = "create new area"
- icon = 'icons/mob/screen_midnight.dmi'
- icon_state = "area_edit"
- screen_loc = ui_building
-
-/obj/screen/area_creator/Click()
- if(usr.incapacitated())
- return 1
- var/area/A = get_area(usr)
- if(!A.outdoors)
- to_chat(usr, "There is already a defined structure here. ")
- return 1
- create_area(usr)
-
-/obj/screen/language_menu
- name = "language menu"
- icon = 'icons/mob/screen_midnight.dmi'
- icon_state = "talk_wheel"
- screen_loc = ui_language_menu
-
-/obj/screen/language_menu/Click()
- var/mob/M = usr
- var/datum/language_holder/H = M.get_language_holder()
- H.open_language_menu(usr)
-
-/obj/screen/inventory
- var/slot_id // The indentifier for the slot. It has nothing to do with ID cards.
- var/icon_empty // Icon when empty. For now used only by humans.
- var/icon_full // Icon when contains an item. For now used only by humans.
- layer = HUD_LAYER
- plane = HUD_PLANE
-
-/obj/screen/inventory/Click(location, control, params)
- // At this point in client Click() code we have passed the 1/10 sec check and little else
- // We don't even know if it's a middle click
- if(world.time <= usr.next_move)
- return 1
-
- if(usr.incapacitated())
- return 1
- if(istype(usr.loc, /obj/mecha)) // stops inventory actions in a mech
- return 1
-
- if(hud && hud.mymob && slot_id)
- var/obj/item/inv_item = hud.mymob.get_item_by_slot(slot_id)
- if(inv_item)
- return inv_item.Click(location, control, params)
-
- if(usr.attack_ui(slot_id))
- usr.update_inv_hands()
- return 1
-
-/obj/screen/inventory/update_icon()
- if(!icon_empty)
- icon_empty = icon_state
-
- if(hud && hud.mymob && slot_id && icon_full)
- if(hud.mymob.get_item_by_slot(slot_id))
- icon_state = icon_full
- else
- icon_state = icon_empty
-
-/obj/screen/inventory/hand
- var/mutable_appearance/handcuff_overlay
- var/static/mutable_appearance/blocked_overlay = mutable_appearance('icons/mob/screen_gen.dmi', "blocked")
- var/held_index = 0
-
-/obj/screen/inventory/hand/update_icon()
- ..()
-
- if(!handcuff_overlay)
- var/state = (!(held_index % 2)) ? "markus" : "gabrielle"
- handcuff_overlay = mutable_appearance('icons/mob/screen_gen.dmi', state)
-
- cut_overlays()
-
- if(hud && hud.mymob)
- if(iscarbon(hud.mymob))
- var/mob/living/carbon/C = hud.mymob
- if(C.handcuffed)
- add_overlay(handcuff_overlay)
-
- if(held_index)
- if(!C.has_hand_for_held_index(held_index))
- add_overlay(blocked_overlay)
-
- if(held_index == hud.mymob.active_hand_index)
- add_overlay("hand_active")
-
-
-/obj/screen/inventory/hand/Click(location, control, params)
- // At this point in client Click() code we have passed the 1/10 sec check and little else
- // We don't even know if it's a middle click
- if(world.time <= usr.next_move)
- return 1
- if(usr.incapacitated() || isobserver(usr))
- return 1
- if (istype(usr.loc, /obj/mecha)) // stops inventory actions in a mech
- return 1
-
- if(hud.mymob.active_hand_index == held_index)
- var/obj/item/I = hud.mymob.get_active_held_item()
- if(I)
- I.Click(location, control, params)
- else
- hud.mymob.swap_hand(held_index)
- return 1
-
-/obj/screen/close
- name = "close"
-
-/obj/screen/close/Click()
- if(istype(master, /obj/item/storage))
- var/obj/item/storage/S = master
- S.close(usr)
- return 1
-
-
-/obj/screen/drop
- name = "drop"
- icon = 'icons/mob/screen_midnight.dmi'
- icon_state = "act_drop"
- layer = HUD_LAYER
- plane = HUD_PLANE
-
-/obj/screen/drop/Click()
- usr.drop_item_v()
-
-/obj/screen/act_intent
- name = "intent"
- icon_state = "help"
- screen_loc = ui_acti
-
-/obj/screen/act_intent/Click(location, control, params)
- usr.a_intent_change(INTENT_HOTKEY_RIGHT)
-
-/obj/screen/act_intent/segmented/Click(location, control, params)
- if(usr.client.prefs.toggles & INTENT_STYLE)
- var/_x = text2num(params2list(params)["icon-x"])
- var/_y = text2num(params2list(params)["icon-y"])
-
- if(_x<=16 && _y<=16)
- usr.a_intent_change(INTENT_HARM)
-
- else if(_x<=16 && _y>=17)
- usr.a_intent_change(INTENT_HELP)
-
- else if(_x>=17 && _y<=16)
- usr.a_intent_change(INTENT_GRAB)
-
- else if(_x>=17 && _y>=17)
- usr.a_intent_change(INTENT_DISARM)
- else
- return ..()
-
-/obj/screen/act_intent/alien
- icon = 'icons/mob/screen_alien.dmi'
- screen_loc = ui_movi
-
-/obj/screen/act_intent/robot
- icon = 'icons/mob/screen_cyborg.dmi'
- screen_loc = ui_borg_intents
-
-/obj/screen/internals
- name = "toggle internals"
- icon_state = "internal0"
- screen_loc = ui_internal
-
-/obj/screen/internals/Click()
- if(!iscarbon(usr))
- return
- var/mob/living/carbon/C = usr
- if(C.incapacitated())
- return
-
- if(C.internal)
- C.internal = null
- to_chat(C, "You are no longer running on internals. ")
- icon_state = "internal0"
- else
- if(!C.getorganslot("breathing_tube"))
- if(!istype(C.wear_mask, /obj/item/clothing/mask))
- to_chat(C, "You are not wearing an internals mask! ")
- return 1
- else
- var/obj/item/clothing/mask/M = C.wear_mask
- if(M.mask_adjusted) // if mask on face but pushed down
- M.adjustmask(C) // adjust it back
+ screen_loc = "CENTER-7,CENTER-7"
+ maptext_height = 480
+ maptext_width = 480
+
+/obj/screen/swap_hand
+ layer = HUD_LAYER
+ plane = HUD_PLANE
+ name = "swap hand"
+
+/obj/screen/swap_hand/Click()
+ // At this point in client Click() code we have passed the 1/10 sec check and little else
+ // We don't even know if it's a middle click
+ if(world.time <= usr.next_move)
+ return 1
+
+ if(usr.incapacitated())
+ return 1
+
+ if(ismob(usr))
+ var/mob/M = usr
+ M.swap_hand()
+ return 1
+
+/obj/screen/craft
+ name = "crafting menu"
+ icon = 'icons/mob/screen_midnight.dmi'
+ icon_state = "craft"
+ screen_loc = ui_crafting
+
+/obj/screen/craft/Click()
+ var/mob/living/M = usr
+ if(isobserver(usr))
+ return
+ M.OpenCraftingMenu()
+
+/obj/screen/area_creator
+ name = "create new area"
+ icon = 'icons/mob/screen_midnight.dmi'
+ icon_state = "area_edit"
+ screen_loc = ui_building
+
+/obj/screen/area_creator/Click()
+ if(usr.incapacitated())
+ return 1
+ var/area/A = get_area(usr)
+ if(!A.outdoors)
+ to_chat(usr, "There is already a defined structure here. ")
+ return 1
+ create_area(usr)
+
+/obj/screen/language_menu
+ name = "language menu"
+ icon = 'icons/mob/screen_midnight.dmi'
+ icon_state = "talk_wheel"
+ screen_loc = ui_language_menu
+
+/obj/screen/language_menu/Click()
+ var/mob/M = usr
+ var/datum/language_holder/H = M.get_language_holder()
+ H.open_language_menu(usr)
+
+/obj/screen/inventory
+ var/slot_id // The indentifier for the slot. It has nothing to do with ID cards.
+ var/icon_empty // Icon when empty. For now used only by humans.
+ var/icon_full // Icon when contains an item. For now used only by humans.
+ layer = HUD_LAYER
+ plane = HUD_PLANE
+
+/obj/screen/inventory/Click(location, control, params)
+ // At this point in client Click() code we have passed the 1/10 sec check and little else
+ // We don't even know if it's a middle click
+ if(world.time <= usr.next_move)
+ return 1
+
+ if(usr.incapacitated())
+ return 1
+ if(ismecha(usr.loc)) // stops inventory actions in a mech
+ return 1
+
+ if(hud && hud.mymob && slot_id)
+ var/obj/item/inv_item = hud.mymob.get_item_by_slot(slot_id)
+ if(inv_item)
+ return inv_item.Click(location, control, params)
+
+ if(usr.attack_ui(slot_id))
+ usr.update_inv_hands()
+ return 1
+
+/obj/screen/inventory/update_icon()
+ if(!icon_empty)
+ icon_empty = icon_state
+
+ if(hud && hud.mymob && slot_id && icon_full)
+ if(hud.mymob.get_item_by_slot(slot_id))
+ icon_state = icon_full
+ else
+ icon_state = icon_empty
+
+/obj/screen/inventory/hand
+ var/mutable_appearance/handcuff_overlay
+ var/static/mutable_appearance/blocked_overlay = mutable_appearance('icons/mob/screen_gen.dmi', "blocked")
+ var/held_index = 0
+
+/obj/screen/inventory/hand/update_icon()
+ ..()
+
+ if(!handcuff_overlay)
+ var/state = (!(held_index % 2)) ? "markus" : "gabrielle"
+ handcuff_overlay = mutable_appearance('icons/mob/screen_gen.dmi', state)
+
+ cut_overlays()
+
+ if(hud && hud.mymob)
+ if(iscarbon(hud.mymob))
+ var/mob/living/carbon/C = hud.mymob
+ if(C.handcuffed)
+ add_overlay(handcuff_overlay)
+
+ if(held_index)
+ if(!C.has_hand_for_held_index(held_index))
+ add_overlay(blocked_overlay)
+
+ if(held_index == hud.mymob.active_hand_index)
+ add_overlay("hand_active")
+
+
+/obj/screen/inventory/hand/Click(location, control, params)
+ // At this point in client Click() code we have passed the 1/10 sec check and little else
+ // We don't even know if it's a middle click
+ if(world.time <= usr.next_move)
+ return 1
+ if(usr.incapacitated() || isobserver(usr))
+ return 1
+ if (ismecha(usr.loc)) // stops inventory actions in a mech
+ return 1
+
+ if(hud.mymob.active_hand_index == held_index)
+ var/obj/item/I = hud.mymob.get_active_held_item()
+ if(I)
+ I.Click(location, control, params)
+ else
+ hud.mymob.swap_hand(held_index)
+ return 1
+
+/obj/screen/close
+ name = "close"
+
+/obj/screen/close/Click()
+ if(istype(master, /obj/item/storage))
+ var/obj/item/storage/S = master
+ S.close(usr)
+ return 1
+
+
+/obj/screen/drop
+ name = "drop"
+ icon = 'icons/mob/screen_midnight.dmi'
+ icon_state = "act_drop"
+ layer = HUD_LAYER
+ plane = HUD_PLANE
+
+/obj/screen/drop/Click()
+ usr.drop_item_v()
+
+/obj/screen/act_intent
+ name = "intent"
+ icon_state = "help"
+ screen_loc = ui_acti
+
+/obj/screen/act_intent/Click(location, control, params)
+ usr.a_intent_change(INTENT_HOTKEY_RIGHT)
+
+/obj/screen/act_intent/segmented/Click(location, control, params)
+ if(usr.client.prefs.toggles & INTENT_STYLE)
+ var/_x = text2num(params2list(params)["icon-x"])
+ var/_y = text2num(params2list(params)["icon-y"])
+
+ if(_x<=16 && _y<=16)
+ usr.a_intent_change(INTENT_HARM)
+
+ else if(_x<=16 && _y>=17)
+ usr.a_intent_change(INTENT_HELP)
+
+ else if(_x>=17 && _y<=16)
+ usr.a_intent_change(INTENT_GRAB)
+
+ else if(_x>=17 && _y>=17)
+ usr.a_intent_change(INTENT_DISARM)
+ else
+ return ..()
+
+/obj/screen/act_intent/alien
+ icon = 'icons/mob/screen_alien.dmi'
+ screen_loc = ui_movi
+
+/obj/screen/act_intent/robot
+ icon = 'icons/mob/screen_cyborg.dmi'
+ screen_loc = ui_borg_intents
+
+/obj/screen/internals
+ name = "toggle internals"
+ icon_state = "internal0"
+ screen_loc = ui_internal
+
+/obj/screen/internals/Click()
+ if(!iscarbon(usr))
+ return
+ var/mob/living/carbon/C = usr
+ if(C.incapacitated())
+ return
+
+ if(C.internal)
+ C.internal = null
+ to_chat(C, "You are no longer running on internals. ")
+ icon_state = "internal0"
+ else
+ if(!C.getorganslot("breathing_tube"))
+ if(!istype(C.wear_mask, /obj/item/clothing/mask))
+ to_chat(C, "You are not wearing an internals mask! ")
+ return 1
+ else
+ var/obj/item/clothing/mask/M = C.wear_mask
+ if(M.mask_adjusted) // if mask on face but pushed down
+ M.adjustmask(C) // adjust it back
if( !(M.flags_1 & MASKINTERNALS_1) )
- to_chat(C, "You are not wearing an internals mask! ")
- return
-
- var/obj/item/I = C.is_holding_item_of_type(/obj/item/tank)
- if(I)
- to_chat(C, "You are now running on internals from the [I] on your [C.get_held_index_name(C.get_held_index_of_item(I))]. ")
- C.internal = I
- else if(ishuman(C))
- var/mob/living/carbon/human/H = C
- if(istype(H.s_store, /obj/item/tank))
- to_chat(H, "You are now running on internals from the [H.s_store] on your [H.wear_suit]. ")
- H.internal = H.s_store
- else if(istype(H.belt, /obj/item/tank))
- to_chat(H, "You are now running on internals from the [H.belt] on your belt. ")
- H.internal = H.belt
- else if(istype(H.l_store, /obj/item/tank))
- to_chat(H, "You are now running on internals from the [H.l_store] in your left pocket. ")
- H.internal = H.l_store
- else if(istype(H.r_store, /obj/item/tank))
- to_chat(H, "You are now running on internals from the [H.r_store] in your right pocket. ")
- H.internal = H.r_store
-
+ to_chat(C, "You are not wearing an internals mask! ")
+ return
+
+ var/obj/item/I = C.is_holding_item_of_type(/obj/item/tank)
+ if(I)
+ to_chat(C, "You are now running on internals from the [I] on your [C.get_held_index_name(C.get_held_index_of_item(I))]. ")
+ C.internal = I
+ else if(ishuman(C))
+ var/mob/living/carbon/human/H = C
+ if(istype(H.s_store, /obj/item/tank))
+ to_chat(H, "You are now running on internals from the [H.s_store] on your [H.wear_suit]. ")
+ H.internal = H.s_store
+ else if(istype(H.belt, /obj/item/tank))
+ to_chat(H, "You are now running on internals from the [H.belt] on your belt. ")
+ H.internal = H.belt
+ else if(istype(H.l_store, /obj/item/tank))
+ to_chat(H, "You are now running on internals from the [H.l_store] in your left pocket. ")
+ H.internal = H.l_store
+ else if(istype(H.r_store, /obj/item/tank))
+ to_chat(H, "You are now running on internals from the [H.r_store] in your right pocket. ")
+ H.internal = H.r_store
+
//Separate so CO2 jetpacks are a little less cumbersome.
- if(!C.internal && istype(C.back, /obj/item/tank))
- to_chat(C, "You are now running on internals from the [C.back] on your back. ")
- C.internal = C.back
-
- if(C.internal)
- icon_state = "internal1"
- else
- to_chat(C, "You don't have an oxygen tank! ")
- return
- C.update_action_buttons_icon()
-
-/obj/screen/mov_intent
- name = "run/walk toggle"
- icon = 'icons/mob/screen_midnight.dmi'
- icon_state = "running"
-
-/obj/screen/mov_intent/Click()
- toggle(usr)
-
-/obj/screen/mov_intent/proc/toggle(mob/user)
- if(isobserver(user))
- return
- switch(user.m_intent)
- if("run")
- user.m_intent = MOVE_INTENT_WALK
- icon_state = "walking"
- if("walk")
- user.m_intent = MOVE_INTENT_RUN
- icon_state = "running"
- user.update_icons()
-
-/obj/screen/pull
- name = "stop pulling"
- icon = 'icons/mob/screen_midnight.dmi'
- icon_state = "pull"
-
-/obj/screen/pull/Click()
- if(isobserver(usr))
- return
- usr.stop_pulling()
-
-/obj/screen/pull/update_icon(mob/mymob)
- if(!mymob) return
- if(mymob.pulling)
- icon_state = "pull"
- else
- icon_state = "pull0"
-
-/obj/screen/resist
- name = "resist"
- icon = 'icons/mob/screen_midnight.dmi'
- icon_state = "act_resist"
- layer = HUD_LAYER
- plane = HUD_PLANE
-
-/obj/screen/resist/Click()
- if(isliving(usr))
- var/mob/living/L = usr
- L.resist()
-
-/obj/screen/storage
- name = "storage"
-
-/obj/screen/storage/Click(location, control, params)
- if(world.time <= usr.next_move)
- return 1
- if(usr.stat || usr.IsUnconscious() || usr.IsKnockdown() || usr.IsStun())
- return 1
- if (istype(usr.loc, /obj/mecha)) // stops inventory actions in a mech
- return 1
- if(master)
- var/obj/item/I = usr.get_active_held_item()
- if(I)
- master.attackby(I, usr, params)
- return 1
-
-/obj/screen/throw_catch
- name = "throw/catch"
- icon = 'icons/mob/screen_midnight.dmi'
- icon_state = "act_throw_off"
-
-/obj/screen/throw_catch/Click()
- if(iscarbon(usr))
- var/mob/living/carbon/C = usr
- C.toggle_throw_mode()
-
-/obj/screen/zone_sel
- name = "damage zone"
- icon_state = "zone_sel"
- screen_loc = ui_zonesel
- var/selecting = "chest"
-
-/obj/screen/zone_sel/Click(location, control,params)
- if(isobserver(usr))
- return
-
- var/list/PL = params2list(params)
- var/icon_x = text2num(PL["icon-x"])
- var/icon_y = text2num(PL["icon-y"])
- var/choice
-
- switch(icon_y)
- if(1 to 9) //Legs
- switch(icon_x)
- if(10 to 15)
- choice = "r_leg"
- if(17 to 22)
- choice = "l_leg"
- else
- return 1
- if(10 to 13) //Hands and groin
- switch(icon_x)
- if(8 to 11)
- choice = "r_arm"
- if(12 to 20)
- choice = "groin"
- if(21 to 24)
- choice = "l_arm"
- else
- return 1
- if(14 to 22) //Chest and arms to shoulders
- switch(icon_x)
- if(8 to 11)
- choice = "r_arm"
- if(12 to 20)
- choice = "chest"
- if(21 to 24)
- choice = "l_arm"
- else
- return 1
- if(23 to 30) //Head, but we need to check for eye or mouth
- if(icon_x in 12 to 20)
- choice = "head"
- switch(icon_y)
- if(23 to 24)
- if(icon_x in 15 to 17)
- choice = "mouth"
- if(26) //Eyeline, eyes are on 15 and 17
- if(icon_x in 14 to 18)
- choice = "eyes"
- if(25 to 27)
- if(icon_x in 15 to 17)
- choice = "eyes"
-
- return set_selected_zone(choice, usr)
-
-/obj/screen/zone_sel/proc/set_selected_zone(choice, mob/user)
- if(isobserver(user))
- return
-
- if(choice != selecting)
- selecting = choice
- update_icon(usr)
- return 1
-
-/obj/screen/zone_sel/update_icon(mob/user)
- cut_overlays()
- add_overlay(mutable_appearance('icons/mob/screen_gen.dmi', "[selecting]"))
- user.zone_selected = selecting
-
-/obj/screen/zone_sel/alien
- icon = 'icons/mob/screen_alien.dmi'
-
-/obj/screen/zone_sel/alien/update_icon(mob/user)
- cut_overlays()
- add_overlay(mutable_appearance('icons/mob/screen_alien.dmi', "[selecting]"))
- user.zone_selected = selecting
-
-/obj/screen/zone_sel/robot
- icon = 'icons/mob/screen_cyborg.dmi'
-
-
-/obj/screen/flash
- name = "flash"
- icon_state = "blank"
- blend_mode = BLEND_ADD
- screen_loc = "WEST,SOUTH to EAST,NORTH"
- layer = FLASH_LAYER
- plane = FULLSCREEN_PLANE
-
-/obj/screen/damageoverlay
- icon = 'icons/mob/screen_full.dmi'
- icon_state = "oxydamageoverlay0"
- name = "dmg"
- blend_mode = BLEND_MULTIPLY
- screen_loc = "CENTER-7,CENTER-7"
+ if(!C.internal && istype(C.back, /obj/item/tank))
+ to_chat(C, "You are now running on internals from the [C.back] on your back. ")
+ C.internal = C.back
+
+ if(C.internal)
+ icon_state = "internal1"
+ else
+ to_chat(C, "You don't have an oxygen tank! ")
+ return
+ C.update_action_buttons_icon()
+
+/obj/screen/mov_intent
+ name = "run/walk toggle"
+ icon = 'icons/mob/screen_midnight.dmi'
+ icon_state = "running"
+
+/obj/screen/mov_intent/Click()
+ toggle(usr)
+
+/obj/screen/mov_intent/proc/toggle(mob/user)
+ if(isobserver(user))
+ return
+ switch(user.m_intent)
+ if("run")
+ user.m_intent = MOVE_INTENT_WALK
+ icon_state = "walking"
+ if("walk")
+ user.m_intent = MOVE_INTENT_RUN
+ icon_state = "running"
+ user.update_icons()
+
+/obj/screen/pull
+ name = "stop pulling"
+ icon = 'icons/mob/screen_midnight.dmi'
+ icon_state = "pull"
+
+/obj/screen/pull/Click()
+ if(isobserver(usr))
+ return
+ usr.stop_pulling()
+
+/obj/screen/pull/update_icon(mob/mymob)
+ if(!mymob) return
+ if(mymob.pulling)
+ icon_state = "pull"
+ else
+ icon_state = "pull0"
+
+/obj/screen/resist
+ name = "resist"
+ icon = 'icons/mob/screen_midnight.dmi'
+ icon_state = "act_resist"
+ layer = HUD_LAYER
+ plane = HUD_PLANE
+
+/obj/screen/resist/Click()
+ if(isliving(usr))
+ var/mob/living/L = usr
+ L.resist()
+
+/obj/screen/storage
+ name = "storage"
+
+/obj/screen/storage/Click(location, control, params)
+ if(world.time <= usr.next_move)
+ return 1
+ if(usr.stat || usr.IsUnconscious() || usr.IsKnockdown() || usr.IsStun())
+ return 1
+ if (ismecha(usr.loc)) // stops inventory actions in a mech
+ return 1
+ if(master)
+ var/obj/item/I = usr.get_active_held_item()
+ if(I)
+ master.attackby(I, usr, params)
+ return 1
+
+/obj/screen/throw_catch
+ name = "throw/catch"
+ icon = 'icons/mob/screen_midnight.dmi'
+ icon_state = "act_throw_off"
+
+/obj/screen/throw_catch/Click()
+ if(iscarbon(usr))
+ var/mob/living/carbon/C = usr
+ C.toggle_throw_mode()
+
+/obj/screen/zone_sel
+ name = "damage zone"
+ icon_state = "zone_sel"
+ screen_loc = ui_zonesel
+ var/selecting = "chest"
+
+/obj/screen/zone_sel/Click(location, control,params)
+ if(isobserver(usr))
+ return
+
+ var/list/PL = params2list(params)
+ var/icon_x = text2num(PL["icon-x"])
+ var/icon_y = text2num(PL["icon-y"])
+ var/choice
+
+ switch(icon_y)
+ if(1 to 9) //Legs
+ switch(icon_x)
+ if(10 to 15)
+ choice = "r_leg"
+ if(17 to 22)
+ choice = "l_leg"
+ else
+ return 1
+ if(10 to 13) //Hands and groin
+ switch(icon_x)
+ if(8 to 11)
+ choice = "r_arm"
+ if(12 to 20)
+ choice = "groin"
+ if(21 to 24)
+ choice = "l_arm"
+ else
+ return 1
+ if(14 to 22) //Chest and arms to shoulders
+ switch(icon_x)
+ if(8 to 11)
+ choice = "r_arm"
+ if(12 to 20)
+ choice = "chest"
+ if(21 to 24)
+ choice = "l_arm"
+ else
+ return 1
+ if(23 to 30) //Head, but we need to check for eye or mouth
+ if(icon_x in 12 to 20)
+ choice = "head"
+ switch(icon_y)
+ if(23 to 24)
+ if(icon_x in 15 to 17)
+ choice = "mouth"
+ if(26) //Eyeline, eyes are on 15 and 17
+ if(icon_x in 14 to 18)
+ choice = "eyes"
+ if(25 to 27)
+ if(icon_x in 15 to 17)
+ choice = "eyes"
+
+ return set_selected_zone(choice, usr)
+
+/obj/screen/zone_sel/proc/set_selected_zone(choice, mob/user)
+ if(isobserver(user))
+ return
+
+ if(choice != selecting)
+ selecting = choice
+ update_icon(usr)
+ return 1
+
+/obj/screen/zone_sel/update_icon(mob/user)
+ cut_overlays()
+ add_overlay(mutable_appearance('icons/mob/screen_gen.dmi', "[selecting]"))
+ user.zone_selected = selecting
+
+/obj/screen/zone_sel/alien
+ icon = 'icons/mob/screen_alien.dmi'
+
+/obj/screen/zone_sel/alien/update_icon(mob/user)
+ cut_overlays()
+ add_overlay(mutable_appearance('icons/mob/screen_alien.dmi', "[selecting]"))
+ user.zone_selected = selecting
+
+/obj/screen/zone_sel/robot
+ icon = 'icons/mob/screen_cyborg.dmi'
+
+
+/obj/screen/flash
+ name = "flash"
+ icon_state = "blank"
+ blend_mode = BLEND_ADD
+ screen_loc = "WEST,SOUTH to EAST,NORTH"
+ layer = FLASH_LAYER
+ plane = FULLSCREEN_PLANE
+
+/obj/screen/damageoverlay
+ icon = 'icons/mob/screen_full.dmi'
+ icon_state = "oxydamageoverlay0"
+ name = "dmg"
+ blend_mode = BLEND_MULTIPLY
+ screen_loc = "CENTER-7,CENTER-7"
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
- layer = UI_DAMAGE_LAYER
- plane = FULLSCREEN_PLANE
-
-/obj/screen/healths
- name = "health"
- icon_state = "health0"
- screen_loc = ui_health
-
-/obj/screen/healths/alien
- icon = 'icons/mob/screen_alien.dmi'
- screen_loc = ui_alien_health
-
-/obj/screen/healths/robot
- icon = 'icons/mob/screen_cyborg.dmi'
- screen_loc = ui_borg_health
-
-/obj/screen/healths/deity
- name = "Nexus Health"
- icon_state = "deity_nexus"
- screen_loc = ui_deityhealth
-
-/obj/screen/healths/blob
- name = "blob health"
- icon_state = "block"
- screen_loc = ui_internal
+ layer = UI_DAMAGE_LAYER
+ plane = FULLSCREEN_PLANE
+
+/obj/screen/healths
+ name = "health"
+ icon_state = "health0"
+ screen_loc = ui_health
+
+/obj/screen/healths/alien
+ icon = 'icons/mob/screen_alien.dmi'
+ screen_loc = ui_alien_health
+
+/obj/screen/healths/robot
+ icon = 'icons/mob/screen_cyborg.dmi'
+ screen_loc = ui_borg_health
+
+/obj/screen/healths/deity
+ name = "Nexus Health"
+ icon_state = "deity_nexus"
+ screen_loc = ui_deityhealth
+
+/obj/screen/healths/blob
+ name = "blob health"
+ icon_state = "block"
+ screen_loc = ui_internal
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
-
-/obj/screen/healths/blob/naut
- name = "health"
- icon = 'icons/mob/blob.dmi'
- icon_state = "nauthealth"
-
-/obj/screen/healths/blob/naut/core
- name = "overmind health"
- screen_loc = ui_health
- icon_state = "corehealth"
-
-/obj/screen/healths/guardian
- name = "summoner health"
- icon = 'icons/mob/guardian.dmi'
- icon_state = "base"
- screen_loc = ui_health
+
+/obj/screen/healths/blob/naut
+ name = "health"
+ icon = 'icons/mob/blob.dmi'
+ icon_state = "nauthealth"
+
+/obj/screen/healths/blob/naut/core
+ name = "overmind health"
+ screen_loc = ui_health
+ icon_state = "corehealth"
+
+/obj/screen/healths/guardian
+ name = "summoner health"
+ icon = 'icons/mob/guardian.dmi'
+ icon_state = "base"
+ screen_loc = ui_health
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
-
-/obj/screen/healths/clock
- icon = 'icons/mob/actions.dmi'
- icon_state = "bg_clock"
- screen_loc = ui_health
+
+/obj/screen/healths/clock
+ icon = 'icons/mob/actions.dmi'
+ icon_state = "bg_clock"
+ screen_loc = ui_health
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
-
-/obj/screen/healths/clock/gear
- icon = 'icons/mob/clockwork_mobs.dmi'
- icon_state = "bg_gear"
- screen_loc = ui_internal
-
-/obj/screen/healths/revenant
- name = "essence"
- icon = 'icons/mob/actions.dmi'
- icon_state = "bg_revenant"
- screen_loc = ui_health
+
+/obj/screen/healths/clock/gear
+ icon = 'icons/mob/clockwork_mobs.dmi'
+ icon_state = "bg_gear"
+ screen_loc = ui_internal
+
+/obj/screen/healths/revenant
+ name = "essence"
+ icon = 'icons/mob/actions.dmi'
+ icon_state = "bg_revenant"
+ screen_loc = ui_health
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
-
-/obj/screen/healths/construct
- icon = 'icons/mob/screen_construct.dmi'
- icon_state = "artificer_health0"
- screen_loc = ui_construct_health
+
+/obj/screen/healths/construct
+ icon = 'icons/mob/screen_construct.dmi'
+ icon_state = "artificer_health0"
+ screen_loc = ui_construct_health
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
-
-/obj/screen/healthdoll
- name = "health doll"
- screen_loc = ui_healthdoll
-
-/obj/screen/splash
- icon = 'config/title_screens/images/title1.dmi'
- icon_state = ""
- screen_loc = "1,1"
- layer = SPLASHSCREEN_LAYER
- plane = SPLASHSCREEN_PLANE
- var/client/holder
-
-/obj/screen/splash/New(client/C, visible, use_previous_title) //TODO: Make this use INITIALIZE_IMMEDIATE
- holder = C
-
- if(!visible)
- alpha = 0
-
- if(!use_previous_title)
- if(SStitle.icon)
- icon = SStitle.icon
- else
- if(!SStitle.previous_icon)
- qdel(src)
- return
- icon = SStitle.previous_icon
-
- holder.screen += src
-
- ..()
-
-/obj/screen/splash/proc/Fade(out, qdel_after = TRUE)
- if(QDELETED(src))
- return
- if(out)
- animate(src, alpha = 0, time = 30)
- else
- alpha = 0
- animate(src, alpha = 255, time = 30)
- if(qdel_after)
- QDEL_IN(src, 30)
-
-/obj/screen/splash/Destroy()
- if(holder)
- holder.screen -= src
- holder = null
- return ..()
+
+/obj/screen/healthdoll
+ name = "health doll"
+ screen_loc = ui_healthdoll
+
+/obj/screen/splash
+ icon = 'config/title_screens/images/title1.dmi'
+ icon_state = ""
+ screen_loc = "1,1"
+ layer = SPLASHSCREEN_LAYER
+ plane = SPLASHSCREEN_PLANE
+ var/client/holder
+
+/obj/screen/splash/New(client/C, visible, use_previous_title) //TODO: Make this use INITIALIZE_IMMEDIATE
+ holder = C
+
+ if(!visible)
+ alpha = 0
+
+ if(!use_previous_title)
+ if(SStitle.icon)
+ icon = SStitle.icon
+ else
+ if(!SStitle.previous_icon)
+ qdel(src)
+ return
+ icon = SStitle.previous_icon
+
+ holder.screen += src
+
+ ..()
+
+/obj/screen/splash/proc/Fade(out, qdel_after = TRUE)
+ if(QDELETED(src))
+ return
+ if(out)
+ animate(src, alpha = 0, time = 30)
+ else
+ alpha = 0
+ animate(src, alpha = 255, time = 30)
+ if(qdel_after)
+ QDEL_IN(src, 30)
+
+/obj/screen/splash/Destroy()
+ if(holder)
+ holder.screen -= src
+ holder = null
+ return ..()
diff --git a/code/_onclick/telekinesis.dm b/code/_onclick/telekinesis.dm
index b0ab260d63..903f3c0790 100644
--- a/code/_onclick/telekinesis.dm
+++ b/code/_onclick/telekinesis.dm
@@ -92,7 +92,7 @@
/obj/item/tk_grab/dropped(mob/user)
if(focus && user && loc != user && loc != user.loc) // drop_item() gets called when you tk-attack a table/closet with an item
if(focus.Adjacent(loc))
- focus.loc = loc
+ focus.forceMove(loc)
. = ..()
//stops TK grabs being equipped anywhere but into hands
diff --git a/code/citadel/cit_guns.dm b/code/citadel/cit_guns.dm
index e62884ecbc..73a98db4e3 100644
--- a/code/citadel/cit_guns.dm
+++ b/code/citadel/cit_guns.dm
@@ -596,10 +596,10 @@ obj/item/projectile/bullet/c10mm/soporific
if((blocked != 100) && isliving(target))
var/mob/living/L = target
L.blur_eyes(6)
- if(L.staminaloss >= 40)
+ if(L.staminaloss >= 60)
L.Sleeping(250)
else
- L.adjustStaminaLoss(58)
+ L.adjustStaminaLoss(25)
return 1
/obj/item/ammo_casing/c10mm/soporific
diff --git a/code/citadel/custom_loadout/custom_items.dm b/code/citadel/custom_loadout/custom_items.dm
index c100f0013c..397f4c6576 100644
--- a/code/citadel/custom_loadout/custom_items.dm
+++ b/code/citadel/custom_loadout/custom_items.dm
@@ -30,6 +30,14 @@
item_color = null
tagname = null
+/obj/item/clothing/accessory/medal/steele
+ name = "Insignia Of Steele"
+ desc = "An intricate pendant given to those who help a key member of the Steele Corporation."
+ icon = 'icons/obj/custom.dmi'
+ icon_state = "steele"
+ item_color = "steele"
+ medaltype = "medal-silver"
+
/*DirtyOldHarry*/
/obj/item/lighter/gold
@@ -55,6 +63,12 @@
item_color = "zombscarf"
dog_fashion = /datum/dog_fashion/head
+/obj/item/clothing/suit/toggle/labcoat/mad/red
+ name = "\improper The Mad's labcoat"
+ desc = "An oddly special looking coat."
+ icon_state = "labred"
+ item_state = "labred"
+
/*PLACEHOLDER*/
@@ -117,4 +131,14 @@
desc = "You would swear this was in your nightmares after eating too many veggies."
icon_state = "hos-g"
item_state = "hos-g"
- body_parts_covered = CHEST|GROIN|ARMS|LEGS
\ No newline at end of file
+ body_parts_covered = CHEST|GROIN|ARMS|LEGS
+
+
+/*Slomek*/
+/obj/item/reagent_containers/food/drinks/flask/russian
+ name = "russian flask"
+ desc = "Every good russian spaceman knows it's a good idea to bring along a couple of pints of whiskey wherever they go."
+ icon = 'icons/obj/custom.dmi'
+ icon_state = "russianflask"
+ item_state = "russianflask"
+ volume = 60
diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index 0c0baccc56..1e4a574e13 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -1,296 +1,156 @@
-//Configuraton defines //TODO: Move all yes/no switches into bitflags
-
-//Used by jobs_have_maint_access
-#define ASSISTANTS_HAVE_MAINT_ACCESS 1
-#define SECURITY_HAS_MAINT_ACCESS 2
-#define EVERYONE_HAS_MAINT_ACCESS 4
-
GLOBAL_VAR_INIT(config_dir, "config/")
GLOBAL_PROTECT(config_dir)
+/datum/controller/configuration
+ name = "Configuration"
+
+ var/hiding_entries_by_type = TRUE //Set for readability, admins can set this to FALSE if they want to debug it
+ var/list/entries
+ var/list/entries_by_type
+
+ var/list/maplist
+ var/datum/map_config/defaultmap
+
+ var/list/modes // allowed modes
+ var/list/gamemode_cache
+ var/list/votable_modes // votable modes
+ var/list/mode_names
+ var/list/mode_reports
+ var/list/mode_false_report_weight
+
+/datum/controller/configuration/New()
+ config = src
+ var/list/config_files = InitEntries()
+ LoadModes()
+ for(var/I in config_files)
+ LoadEntries(I)
+ if(Get(/datum/config_entry/flag/maprotation))
+ loadmaplist(CONFIG_MAPS_FILE)
+
+/datum/controller/configuration/Destroy()
+ entries_by_type.Cut()
+ QDEL_LIST_ASSOC_VAL(entries)
+ QDEL_LIST_ASSOC_VAL(maplist)
+ QDEL_NULL(defaultmap)
+
+ config = null
-/datum/configuration/can_vv_get(var_name)
- var/static/list/banned_gets = list("autoadmin", "autoadmin_rank")
- if (var_name in banned_gets)
- return FALSE
return ..()
-/datum/configuration/vv_edit_var(var_name, var_value)
- var/static/list/banned_edits = list("cross_address", "cross_allowed", "autoadmin", "autoadmin_rank", "invoke_youtubedl")
- if(var_name in banned_edits)
- return FALSE
- return ..()
+/datum/controller/configuration/proc/InitEntries()
+ var/list/_entries = list()
+ entries = _entries
+ var/list/_entries_by_type = list()
+ entries_by_type = _entries_by_type
-/datum/configuration
- var/name = "Configuration" // datum name
+ . = list()
- var/autoadmin = 0
- var/autoadmin_rank = "Game Admin"
+ for(var/I in typesof(/datum/config_entry)) //typesof is faster in this case
+ var/datum/config_entry/E = I
+ if(initial(E.abstract_type) == I)
+ continue
+ E = new I
+ _entries_by_type[I] = E
+ var/esname = E.name
+ var/datum/config_entry/test = _entries[esname]
+ if(test)
+ log_config("Error: [test.type] has the same name as [E.type]: [esname]! Not initializing [E.type]!")
+ qdel(E)
+ continue
+ _entries[esname] = E
+ .[E.resident_file] = TRUE
- var/server_name = null // server name (the name of the game window)
- var/server_sql_name = null // short form server name used for the DB
- var/station_name = null // station name (the name of the station in-game)
- var/lobby_countdown = 120 // In between round countdown.
- var/round_end_countdown = 25 // Post round murder death kill countdown
- var/hub = 0
+/datum/controller/configuration/proc/RemoveEntry(datum/config_entry/CE)
+ entries -= CE.name
+ entries_by_type -= CE.type
- var/log_ooc = 0 // log OOC channel
- var/log_access = 0 // log login/logout
- var/log_say = 0 // log client say
- var/log_admin = 0 // log admin actions
- var/log_game = 0 // log game events
- var/log_vote = 0 // log voting
- var/log_whisper = 0 // log client whisper
- var/log_prayer = 0 // log prayers
- var/log_law = 0 // log lawchanges
- var/log_emote = 0 // log emotes
- var/log_attack = 0 // log attack messages
- var/log_adminchat = 0 // log admin chat messages
- var/log_pda = 0 // log pda messages
- var/log_twitter = 0 // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases.
- var/log_world_topic = 0 // log all world.Topic() calls
- var/sql_enabled = 0 // for sql switching
- var/allow_admin_ooccolor = 0 // Allows admins with relevant permissions to have their own ooc colour
- var/allow_vote_restart = 0 // allow votes to restart
- var/allow_vote_mode = 0 // allow votes to change mode
- var/vote_delay = 6000 // minimum time between voting sessions (deciseconds, 10 minute default)
- var/vote_period = 600 // length of voting period (deciseconds, default 1 minute)
- var/vote_no_default = 0 // vote does not default to nochange/norestart (tbi)
- var/vote_no_dead = 0 // dead people can't vote (tbi)
- var/del_new_on_log = 1 // del's new players if they log before they spawn in
- var/allow_Metadata = 0 // Metadata is supported.
- var/popup_admin_pm = 0 //adminPMs to non-admins show in a pop-up 'reply' window when set to 1.
- var/fps = 20
- var/allow_holidays = 0 //toggles whether holiday-specific content should be used
- var/tick_limit_mc_init = TICK_LIMIT_MC_INIT_DEFAULT //SSinitialization throttling
+/datum/controller/configuration/proc/LoadEntries(filename)
+ log_config("Loading config file [filename]...")
+ var/list/lines = world.file2list("[GLOB.config_dir][filename]")
+ var/list/_entries = entries
+ for(var/L in lines)
+ if(!L)
+ continue
- var/hostedby = null
- var/respawn = 1
- var/guest_jobban = 1
- var/usewhitelist = 0
- var/inactivity_period = 3000 //time in ds until a player is considered inactive
- var/afk_period = 6000 //time in ds until a player is considered afk and kickable
- var/kick_inactive = FALSE //force disconnect for inactive players
- var/load_jobs_from_txt = 0
- var/automute_on = 0 //enables automuting/spam prevention
- var/minimal_access_threshold = 0 //If the number of players is larger than this threshold, minimal access will be turned on.
- var/jobs_have_minimal_access = 0 //determines whether jobs use minimal access or expanded access.
- var/jobs_have_maint_access = 0 //Who gets maint access? See defines above.
- var/sec_start_brig = 0 //makes sec start in brig or dept sec posts
+ if(copytext(L, 1, 2) == "#")
+ continue
- var/server
- var/banappeals
- var/wikiurl = "http://www.tgstation13.org/wiki" // Default wiki link.
- var/forumurl = "http://tgstation13.org/phpBB/index.php" //default forums
- var/rulesurl = "http://www.tgstation13.org/wiki/Rules" // default rules
- var/githuburl = "https://www.github.com/tgstation/-tg-station" //default github
- var/githubrepoid
+ var/pos = findtext(L, " ")
+ var/entry = null
+ var/value = null
- var/forbid_singulo_possession = 0
- var/useircbot = 0
+ if(pos)
+ entry = lowertext(copytext(L, 1, pos))
+ value = copytext(L, pos + 1)
+ else
+ entry = lowertext(L)
- var/check_randomizer = 0
+ if(!entry)
+ continue
- var/panic_server_name
- var/panic_address //Reconnect a player this linked server if this server isn't accepting new players
+ var/datum/config_entry/E = _entries[entry]
+ if(!E)
+ log_config("Unknown setting in configuration: '[entry]'")
+ continue
- var/invoke_youtubedl
+ if(filename != E.resident_file)
+ log_config("Found [entry] in [filename] when it should have been in [E.resident_file]! Ignoring.")
+ continue
- //IP Intel vars
- var/ipintel_email
- var/ipintel_rating_bad = 1
- var/ipintel_save_good = 12
- var/ipintel_save_bad = 1
- var/ipintel_domain = "check.getipintel.net"
+ var/validated = E.ValidateAndSet(value)
+ if(!validated)
+ log_config("Failed to validate setting \"[value]\" for [entry]")
+ else if(E.modified && !E.dupes_allowed)
+ log_config("Duplicate setting for [entry] ([value]) detected! Using latest.")
- var/admin_legacy_system = 0 //Defines whether the server uses the legacy admin system with admins.txt or the SQL system. Config option in config.txt
- var/ban_legacy_system = 0 //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. Config option in config.txt
- var/use_age_restriction_for_jobs = 0 //Do jobs use account age restrictions? --requires database
- var/use_account_age_for_jobs = 0 //Uses the time they made the account for the job restriction stuff. New player joining alerts should be unaffected.
- var/see_own_notes = 0 //Can players see their own admin notes (read-only)? Config option in config.txt
- var/note_fresh_days
- var/note_stale_days
+ if(validated)
+ E.modified = TRUE
- var/use_exp_tracking = FALSE
- var/use_exp_restrictions_heads = FALSE
- var/use_exp_restrictions_heads_hours = 0
- var/use_exp_restrictions_heads_department = FALSE
- var/use_exp_restrictions_other = FALSE
- var/use_exp_restrictions_admin_bypass = FALSE
+/datum/controller/configuration/can_vv_get(var_name)
+ return (var_name != "entries_by_type" || !hiding_entries_by_type) && ..()
- //Population cap vars
- var/soft_popcap = 0
- var/hard_popcap = 0
- var/extreme_popcap = 0
- var/soft_popcap_message = "Be warned that the server is currently serving a high number of users, consider using alternative game servers."
- var/hard_popcap_message = "The server is currently serving a high number of users, You cannot currently join. You may wait for the number of living crew to decline, observe, or find alternative servers."
- var/extreme_popcap_message = "The server is currently serving a high number of users, find alternative servers."
+/datum/controller/configuration/vv_edit_var(var_name, var_value)
+ return !(var_name in list("entries_by_type", "entries")) && ..()
- //game_options.txt configs
- var/force_random_names = 0
- var/list/mode_names = list()
- var/list/mode_reports = list()
- var/list/mode_false_report_weight = list()
- var/list/modes = list() // allowed modes
- var/list/votable_modes = list() // votable modes
- var/list/probabilities = list() // relative probability of each mode
- var/list/min_pop = list() // overrides for acceptible player counts in a mode
- var/list/max_pop = list()
- var/list/repeated_mode_adjust = list() // weight adjustments for recent modes
- var/humans_need_surnames = 0
- var/allow_ai = 0 // allow ai job
- var/forbid_secborg = 0 // disallow secborg module to be chosen.
- var/forbid_peaceborg = 0
- var/panic_bunker = 0 // prevents new people it hasn't seen before from connecting
- var/notify_new_player_age = 0 // how long do we notify admins of a new player
- var/notify_new_player_account_age = 0 // how long do we notify admins of a new byond account
- var/irc_first_connection_alert = 0 // do we notify the irc channel when somebody is connecting for the first time?
+/datum/controller/configuration/stat_entry()
+ if(!statclick)
+ statclick = new/obj/effect/statclick/debug(null, "Edit", src)
+ stat("[name]:", statclick)
- var/traitor_scaling_coeff = 6 //how much does the amount of players get divided by to determine traitors
- var/brother_scaling_coeff = 25 //how many players per brother team
- var/changeling_scaling_coeff = 6 //how much does the amount of players get divided by to determine changelings
- var/security_scaling_coeff = 8 //how much does the amount of players get divided by to determine open security officer positions
- var/abductor_scaling_coeff = 15 //how many players per abductor team
+/datum/controller/configuration/proc/Get(entry_type)
+ if(IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Get" && GLOB.LastAdminCalledTargetRef == "\ref[src]")
+ log_admin_private("Config access of [entry_type] attempted by [key_name(usr)]")
+ return
+ var/datum/config_entry/E = entry_type
+ var/entry_is_abstract = initial(E.abstract_type) == entry_type
+ if(entry_is_abstract)
+ CRASH("Tried to retrieve an abstract config_entry: [entry_type]")
+ E = entries_by_type[entry_type]
+ if(!E)
+ CRASH("Missing config entry for [entry_type]!")
+ return E.value
- var/traitor_objectives_amount = 2
- var/brother_objectives_amount = 2
- var/protect_roles_from_antagonist = 0 //If security and such can be traitor/cult/other
- var/protect_assistant_from_antagonist = 0 //If assistants can be traitor/cult/other
- var/enforce_human_authority = 0 //If non-human species are barred from joining as a head of staff
- var/allow_latejoin_antagonists = 0 // If late-joining players can be traitor/changeling
- var/list/continuous = list() // which roundtypes continue if all antagonists die
- var/list/midround_antag = list() // which roundtypes use the midround antagonist system
- var/midround_antag_time_check = 60 // How late (in minutes) you want the midround antag system to stay on, setting this to 0 will disable the system
- var/midround_antag_life_check = 0.7 // A ratio of how many people need to be alive in order for the round not to immediately end in midround antagonist
- var/shuttle_refuel_delay = 12000
- var/show_game_type_odds = 0 //if set this allows players to see the odds of each roundtype on the get revision screen
- var/mutant_races = 0 //players can choose their mutant race before joining the game
- var/list/roundstart_races = list() //races you can play as from the get go. If left undefined the game's roundstart var for species is used
- var/mutant_humans = 0 //players can pick mutant bodyparts for humans before joining the game
+/datum/controller/configuration/proc/Set(entry_type, new_val)
+ if(IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Set" && GLOB.LastAdminCalledTargetRef == "\ref[src]")
+ log_admin_private("Config rewrite of [entry_type] to [new_val] attempted by [key_name(usr)]")
+ return
+ var/datum/config_entry/E = entry_type
+ var/entry_is_abstract = initial(E.abstract_type) == entry_type
+ if(entry_is_abstract)
+ CRASH("Tried to retrieve an abstract config_entry: [entry_type]")
+ E = entries_by_type[entry_type]
+ if(!E)
+ CRASH("Missing config entry for [entry_type]!")
+ return E.ValidateAndSet(new_val)
- var/no_summon_guns //No
- var/no_summon_magic //Fun
- var/no_summon_events //Allowed
-
- var/intercept = 1 //Whether or not to send a communications intercept report roundstart. This may be overriden by gamemodes.
- var/alert_desc_green = "All threats to the station have passed. Security may not have weapons visible, privacy laws are once again fully enforced."
- var/alert_desc_blue_upto = "The station has received reliable information about possible hostile activity on the station. Security staff may have weapons visible, random searches are permitted."
- var/alert_desc_blue_downto = "The immediate threat has passed. Security may no longer have weapons drawn at all times, but may continue to have them visible. Random searches are still allowed."
- var/alert_desc_red_upto = "There is an immediate serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised."
- var/alert_desc_red_downto = "The station's destruction has been averted. There is still however an immediate serious threat to the station. Security may have weapons unholstered at all times, random searches are allowed and advised."
- var/alert_desc_delta = "Destruction of the station is imminent. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill."
-
- var/revival_pod_plants = FALSE
- var/revival_cloning = FALSE
- var/revival_brain_life = -1
-
- var/rename_cyborg = 0
- var/ooc_during_round = 0
- var/emojis = 0
- var/no_credits_round_end = FALSE
-
- //Used for modifying movement speed for mobs.
- //Unversal modifiers
- var/run_speed = 0
- var/walk_speed = 0
-
- //Mob specific modifiers. NOTE: These will affect different mob types in different ways
- var/human_delay = 0
- var/robot_delay = 0
- var/monkey_delay = 0
- var/alien_delay = 0
- var/slime_delay = 0
- var/animal_delay = 0
-
- var/gateway_delay = 18000 //How long the gateway takes before it activates. Default is half an hour.
- var/ghost_interaction = 0
-
- var/silent_ai = 0
- var/silent_borg = 0
-
- var/damage_multiplier = 1 //Modifier for damage to all mobs. Impacts healing as well.
-
- var/allowwebclient = 0
- var/webclientmembersonly = 0
-
- var/sandbox_autoclose = FALSE // close the sandbox panel after spawning an item, potentially reducing griff
-
- var/default_laws = 0 //Controls what laws the AI spawns with.
- var/silicon_max_law_amount = 12
- var/list/lawids = list()
-
- var/list/law_weights = list()
-
- var/assistant_cap = -1
-
- var/starlight = 0
- var/generate_minimaps = 0
- var/grey_assistants = 0
-
- var/id_console_jobslot_delay = 30
-
- var/lavaland_budget = 60
- var/space_budget = 16
-
- var/aggressive_changelog = 0
-
- var/reactionary_explosions = 0 //If we use reactionary explosions, explosions that react to walls and doors
-
- var/autoconvert_notes = 0 //if all connecting player's notes should attempt to be converted to the database
-
- var/announce_admin_logout = 0
- var/announce_admin_login = 0
-
- var/list/datum/map_config/maplist = list()
- var/datum/map_config/defaultmap = null
- var/maprotation = 1
- var/maprotatechancedelta = 0.75
- var/allow_map_voting = TRUE
-
- // Enables random events mid-round when set to 1
- var/allow_random_events = 0
-
- // Multipliers for random events minimal starting time and minimal players amounts
- var/events_min_time_mul = 1
- var/events_min_players_mul = 1
-
- // The object used for the clickable stat() button.
- var/obj/effect/statclick/statclick
-
- var/client_warn_version = 0
- var/client_warn_message = "Your version of byond may have issues or be blocked from accessing this server in the future."
- var/client_error_version = 0
- var/client_error_message = "Your version of byond is too old, may have issues, and is blocked from accessing this server."
-
- var/cross_name = "Other server"
- var/cross_address = "byond://"
- var/cross_allowed = FALSE
- var/showircname = 0
-
- var/list/gamemode_cache = null
-
- var/minutetopiclimit
- var/secondtopiclimit
-
- var/error_cooldown = 600 // The "cooldown" time for each occurrence of a unique error
- var/error_limit = 50 // How many occurrences before the next will silence them
- var/error_silence_time = 6000 // How long a unique error will be silenced for
- var/error_msg_delay = 50 // How long to wait between messaging admins about occurrences of a unique error
-
- var/arrivals_shuttle_dock_window = 55 //Time from when a player late joins on the arrivals shuttle to when the shuttle docks on the station
- var/arrivals_shuttle_require_undocked = FALSE //Require the arrivals shuttle to be undocked before latejoiners can join
- var/arrivals_shuttle_require_safe_latejoin = FALSE //Require the arrivals shuttle to be operational in order for latejoiners to join
-
- var/mice_roundstart = 10 // how many wire chewing rodents spawn at roundstart.
-
- var/irc_announce_new_game = FALSE
-
- var/list/policies = list()
-
- var/debug_admin_hrefs = FALSE //turns off admin href token protection for debugging purposes
-
-/datum/configuration/New()
- gamemode_cache = typecacheof(/datum/game_mode,TRUE)
+/datum/controller/configuration/proc/LoadModes()
+ gamemode_cache = typecacheof(/datum/game_mode, TRUE)
+ modes = list()
+ mode_names = list()
+ mode_reports = list()
+ mode_false_report_weight = list()
+ votable_modes = list()
+ var/list/probabilities = Get(/datum/config_entry/keyed_number_list/probability)
for(var/T in gamemode_cache)
// I wish I didn't have to instance the game modes in order to look up
// their information, but it is the only way (at least that I know of).
@@ -298,7 +158,6 @@ GLOBAL_PROTECT(config_dir)
if(M.config_tag)
if(!(M.config_tag in modes)) // ensure each mode is added only once
- WRITE_FILE(GLOB.config_error_log, "Adding game mode [M.name] ([M.config_tag]) to configuration.")
modes += M.config_tag
mode_names[M.config_tag] = M.name
probabilities[M.config_tag] = M.probability
@@ -309,558 +168,7 @@ GLOBAL_PROTECT(config_dir)
qdel(M)
votable_modes += "secret"
- Reload()
-
-/datum/configuration/proc/Reload()
- load("config.txt")
- load("comms.txt", "comms")
- load("game_options.txt","game_options")
- load("policies.txt", "policies")
- loadsql("dbconfig.txt")
- reload_custom_roundstart_items_list()
- if (maprotation)
- loadmaplist("maps.txt")
-
- // apply some settings from config..
- GLOB.abandon_allowed = respawn
-
-/datum/configuration/proc/load(filename, type = "config") //the type can also be game_options, in which case it uses a different switch. not making it separate to not copypaste code - Urist
- filename = "[GLOB.config_dir][filename]"
- var/list/Lines = world.file2list(filename)
-
- for(var/t in Lines)
- if(!t)
- continue
-
- t = trim(t)
- if(length(t) == 0)
- continue
- else if(copytext(t, 1, 2) == "#")
- continue
-
- var/pos = findtext(t, " ")
- var/name = null
- var/value = null
-
- if(pos)
- name = lowertext(copytext(t, 1, pos))
- value = copytext(t, pos + 1)
- else
- name = lowertext(t)
-
- if(!name)
- continue
-
- if(type == "config")
- switch(name)
- if("hub")
- hub = 1
- if("admin_legacy_system")
- admin_legacy_system = 1
- if("ban_legacy_system")
- ban_legacy_system = 1
- if("use_age_restriction_for_jobs")
- use_age_restriction_for_jobs = 1
- if("use_account_age_for_jobs")
- use_account_age_for_jobs = 1
- if("use_exp_tracking")
- use_exp_tracking = TRUE
- if("use_exp_restrictions_heads")
- use_exp_restrictions_heads = TRUE
- if("use_exp_restrictions_heads_hours")
- use_exp_restrictions_heads_hours = text2num(value)
- if("use_exp_restrictions_heads_department")
- use_exp_restrictions_heads_department = TRUE
- if("use_exp_restrictions_other")
- use_exp_restrictions_other = TRUE
- if("use_exp_restrictions_admin_bypass")
- use_exp_restrictions_admin_bypass = TRUE
- if("lobby_countdown")
- lobby_countdown = text2num(value)
- if("round_end_countdown")
- round_end_countdown = text2num(value)
- if("log_ooc")
- log_ooc = 1
- if("log_access")
- log_access = 1
- if("log_say")
- log_say = 1
- if("log_admin")
- log_admin = 1
- if("log_prayer")
- log_prayer = 1
- if("log_law")
- log_law = 1
- if("log_game")
- log_game = 1
- if("log_vote")
- log_vote = 1
- if("log_whisper")
- log_whisper = 1
- if("log_attack")
- log_attack = 1
- if("log_emote")
- log_emote = 1
- if("log_adminchat")
- log_adminchat = 1
- if("log_pda")
- log_pda = 1
- if("log_twitter")
- log_twitter = 1
- if("log_world_topic")
- log_world_topic = 1
- if("allow_admin_ooccolor")
- allow_admin_ooccolor = 1
- if("allow_vote_restart")
- allow_vote_restart = 1
- if("allow_vote_mode")
- allow_vote_mode = 1
- if("no_dead_vote")
- vote_no_dead = 1
- if("default_no_vote")
- vote_no_default = 1
- if("vote_delay")
- vote_delay = text2num(value)
- if("vote_period")
- vote_period = text2num(value)
- if("norespawn")
- respawn = 0
- if("servername")
- server_name = value
- if("serversqlname")
- server_sql_name = value
- if("stationname")
- station_name = value
- if("hostedby")
- hostedby = value
- if("server")
- server = value
- if("banappeals")
- banappeals = value
- if("wikiurl")
- wikiurl = value
- if("forumurl")
- forumurl = value
- if("rulesurl")
- rulesurl = value
- if("githuburl")
- githuburl = value
- if("githubrepoid")
- githubrepoid = value
- if("guest_jobban")
- guest_jobban = 1
- if("guest_ban")
- GLOB.guests_allowed = 0
- if("usewhitelist")
- usewhitelist = TRUE
- if("allow_metadata")
- allow_Metadata = 1
- if("id_console_jobslot_delay")
- id_console_jobslot_delay = text2num(value)
- if("inactivity_period")
- inactivity_period = text2num(value) * 10 //documented as seconds in config.txt
- if("afk_period")
- afk_period = text2num(value) * 10 // ^^^
- if("kick_inactive")
- kick_inactive = TRUE
- if("load_jobs_from_txt")
- load_jobs_from_txt = 1
- if("forbid_singulo_possession")
- forbid_singulo_possession = 1
- if("popup_admin_pm")
- popup_admin_pm = 1
- if("allow_holidays")
- allow_holidays = 1
- if("useircbot") //tgs2 support
- useircbot = 1
- if("ticklag")
- var/ticklag = text2num(value)
- if(ticklag > 0)
- fps = 10 / ticklag
- if("tick_limit_mc_init")
- tick_limit_mc_init = text2num(value)
- if("fps")
- fps = text2num(value)
- if("automute_on")
- automute_on = 1
- if("panic_server_name")
- if (value != "\[Put the name here\]")
- panic_server_name = value
- if("panic_server_address")
- if(value != "byond://address:port")
- panic_address = value
- if("invoke_youtubedl")
- invoke_youtubedl = value
- if("show_irc_name")
- showircname = 1
- if("see_own_notes")
- see_own_notes = 1
- if("note_fresh_days")
- note_fresh_days = text2num(value)
- if("note_stale_days")
- note_stale_days = text2num(value)
- if("soft_popcap")
- soft_popcap = text2num(value)
- if("hard_popcap")
- hard_popcap = text2num(value)
- if("extreme_popcap")
- extreme_popcap = text2num(value)
- if("soft_popcap_message")
- soft_popcap_message = value
- if("hard_popcap_message")
- hard_popcap_message = value
- if("extreme_popcap_message")
- extreme_popcap_message = value
- if("panic_bunker")
- panic_bunker = 1
- if("notify_new_player_age")
- notify_new_player_age = text2num(value)
- if("notify_new_player_account_age")
- notify_new_player_account_age = text2num(value)
- if("irc_first_connection_alert")
- irc_first_connection_alert = 1
- if("check_randomizer")
- check_randomizer = 1
- if("ipintel_email")
- if (value != "ch@nge.me")
- ipintel_email = value
- if("ipintel_rating_bad")
- ipintel_rating_bad = text2num(value)
- if("ipintel_domain")
- ipintel_domain = value
- if("ipintel_save_good")
- ipintel_save_good = text2num(value)
- if("ipintel_save_bad")
- ipintel_save_bad = text2num(value)
- if("aggressive_changelog")
- aggressive_changelog = 1
- if("autoconvert_notes")
- autoconvert_notes = 1
- if("allow_webclient")
- allowwebclient = 1
- if("webclient_only_byond_members")
- webclientmembersonly = 1
- if("announce_admin_logout")
- announce_admin_logout = 1
- if("announce_admin_login")
- announce_admin_login = 1
- if("maprotation")
- maprotation = 1
- if("allow_map_voting")
- allow_map_voting = text2num(value)
- if("maprotationchancedelta")
- maprotatechancedelta = text2num(value)
- if("autoadmin")
- autoadmin = 1
- if(value)
- autoadmin_rank = ckeyEx(value)
- if("generate_minimaps")
- generate_minimaps = 1
- if("client_warn_version")
- client_warn_version = text2num(value)
- if("client_warn_message")
- client_warn_message = value
- if("client_error_version")
- client_error_version = text2num(value)
- if("client_error_message")
- client_error_message = value
- if("minute_topic_limit")
- minutetopiclimit = text2num(value)
- if("second_topic_limit")
- secondtopiclimit = text2num(value)
- if("error_cooldown")
- error_cooldown = text2num(value)
- if("error_limit")
- error_limit = text2num(value)
- if("error_silence_time")
- error_silence_time = text2num(value)
- if("error_msg_delay")
- error_msg_delay = text2num(value)
- if("irc_announce_new_game")
- irc_announce_new_game = TRUE
- if("debug_admin_hrefs")
- debug_admin_hrefs = TRUE
- else
-#if DM_VERSION > 511
-#error Replace the line below with WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'")
-#endif
- HandleCommsConfig(name, value) //TODO: Deprecate this eventually
- else if(type == "comms")
- HandleCommsConfig(name, value)
- else if(type == "game_options")
- switch(name)
- if("damage_multiplier")
- damage_multiplier = text2num(value)
- if("revival_pod_plants")
- revival_pod_plants = TRUE
- if("revival_cloning")
- revival_cloning = TRUE
- if("revival_brain_life")
- revival_brain_life = text2num(value)
- if("rename_cyborg")
- rename_cyborg = 1
- if("ooc_during_round")
- ooc_during_round = 1
- if("emojis")
- emojis = 1
- if("no_credits_round_end")
- no_credits_round_end = TRUE
- if("run_delay")
- run_speed = text2num(value)
- if("walk_delay")
- walk_speed = text2num(value)
- if("human_delay")
- human_delay = text2num(value)
- if("robot_delay")
- robot_delay = text2num(value)
- if("monkey_delay")
- monkey_delay = text2num(value)
- if("alien_delay")
- alien_delay = text2num(value)
- if("slime_delay")
- slime_delay = text2num(value)
- if("animal_delay")
- animal_delay = text2num(value)
- if("alert_red_upto")
- alert_desc_red_upto = value
- if("alert_red_downto")
- alert_desc_red_downto = value
- if("alert_blue_downto")
- alert_desc_blue_downto = value
- if("alert_blue_upto")
- alert_desc_blue_upto = value
- if("alert_green")
- alert_desc_green = value
- if("alert_delta")
- alert_desc_delta = value
- if("no_intercept_report")
- intercept = 0
- if("assistants_have_maint_access")
- jobs_have_maint_access |= ASSISTANTS_HAVE_MAINT_ACCESS
- if("security_has_maint_access")
- jobs_have_maint_access |= SECURITY_HAS_MAINT_ACCESS
- if("everyone_has_maint_access")
- jobs_have_maint_access |= EVERYONE_HAS_MAINT_ACCESS
- if("sec_start_brig")
- sec_start_brig = 1
- if("gateway_delay")
- gateway_delay = text2num(value)
- if("continuous")
- var/mode_name = lowertext(value)
- if(mode_name in modes)
- continuous[mode_name] = 1
- else
- WRITE_FILE(GLOB.config_error_log, "Unknown continuous configuration definition: [mode_name].")
- if("midround_antag")
- var/mode_name = lowertext(value)
- if(mode_name in modes)
- midround_antag[mode_name] = 1
- else
- WRITE_FILE(GLOB.config_error_log, "Unknown midround antagonist configuration definition: [mode_name].")
- if("midround_antag_time_check")
- midround_antag_time_check = text2num(value)
- if("midround_antag_life_check")
- midround_antag_life_check = text2num(value)
- if("min_pop")
- var/pop_pos = findtext(value, " ")
- var/mode_name = null
- var/mode_value = null
-
- if(pop_pos)
- mode_name = lowertext(copytext(value, 1, pop_pos))
- mode_value = copytext(value, pop_pos + 1)
- if(mode_name in modes)
- min_pop[mode_name] = text2num(mode_value)
- else
- WRITE_FILE(GLOB.config_error_log, "Unknown minimum population configuration definition: [mode_name].")
- else
- WRITE_FILE(GLOB.config_error_log, "Incorrect minimum population configuration definition: [mode_name] [mode_value].")
- if("max_pop")
- var/pop_pos = findtext(value, " ")
- var/mode_name = null
- var/mode_value = null
-
- if(pop_pos)
- mode_name = lowertext(copytext(value, 1, pop_pos))
- mode_value = copytext(value, pop_pos + 1)
- if(mode_name in modes)
- max_pop[mode_name] = text2num(mode_value)
- else
- WRITE_FILE(GLOB.config_error_log, "Unknown maximum population configuration definition: [mode_name].")
- else
- WRITE_FILE(GLOB.config_error_log, "Incorrect maximum population configuration definition: [mode_name] [mode_value].")
- if("shuttle_refuel_delay")
- shuttle_refuel_delay = text2num(value)
- if("show_game_type_odds")
- show_game_type_odds = 1
- if("ghost_interaction")
- ghost_interaction = 1
- if("traitor_scaling_coeff")
- traitor_scaling_coeff = text2num(value)
- if("brother_scaling_coeff")
- brother_scaling_coeff = text2num(value)
- if("changeling_scaling_coeff")
- changeling_scaling_coeff = text2num(value)
- if("security_scaling_coeff")
- security_scaling_coeff = text2num(value)
- if("abductor_scaling_coeff")
- abductor_scaling_coeff = text2num(value)
- if("traitor_objectives_amount")
- traitor_objectives_amount = text2num(value)
- if("brother_objectives_amount")
- brother_objectives_amount = text2num(value)
- if("probability")
- var/prob_pos = findtext(value, " ")
- var/prob_name = null
- var/prob_value = null
-
- if(prob_pos)
- prob_name = lowertext(copytext(value, 1, prob_pos))
- prob_value = copytext(value, prob_pos + 1)
- if(prob_name in modes)
- probabilities[prob_name] = text2num(prob_value)
- else
- WRITE_FILE(GLOB.config_error_log, "Unknown game mode probability configuration definition: [prob_name].")
- else
- WRITE_FILE(GLOB.config_error_log, "Incorrect probability configuration definition: [prob_name] [prob_value].")
- if("repeated_mode_adjust")
- if(value)
- repeated_mode_adjust.Cut()
- var/values = splittext(value," ")
- for(var/v in values)
- repeated_mode_adjust += text2num(v)
- else
- WRITE_FILE(GLOB.config_error_log, "Incorrect round weight adjustment configuration definition for [value].")
- if("protect_roles_from_antagonist")
- protect_roles_from_antagonist = 1
- if("protect_assistant_from_antagonist")
- protect_assistant_from_antagonist = 1
- if("enforce_human_authority")
- enforce_human_authority = 1
- if("allow_latejoin_antagonists")
- allow_latejoin_antagonists = 1
- if("allow_random_events")
- allow_random_events = 1
-
- if("events_min_time_mul")
- events_min_time_mul = text2num(value)
- if("events_min_players_mul")
- events_min_players_mul = text2num(value)
-
- if("minimal_access_threshold")
- minimal_access_threshold = text2num(value)
- if("jobs_have_minimal_access")
- jobs_have_minimal_access = 1
- if("humans_need_surnames")
- humans_need_surnames = 1
- if("force_random_names")
- force_random_names = 1
- if("allow_ai")
- allow_ai = 1
- if("disable_secborg")
- forbid_secborg = 1
- if("disable_peaceborg")
- forbid_peaceborg = 1
- if("silent_ai")
- silent_ai = 1
- if("silent_borg")
- silent_borg = 1
- if("sandbox_autoclose")
- sandbox_autoclose = 1
- if("default_laws")
- default_laws = text2num(value)
- if("random_laws")
- var/law_id = lowertext(value)
- lawids += law_id
- if("law_weight")
- // Value is in the form "LAWID,NUMBER"
- var/list/L = splittext(value, ",")
- if(L.len != 2)
- WRITE_FILE(GLOB.config_error_log, "Invalid LAW_WEIGHT: " + t)
- continue
- var/lawid = L[1]
- var/weight = text2num(L[2])
- law_weights[lawid] = weight
-
- if("silicon_max_law_amount")
- silicon_max_law_amount = text2num(value)
- if("join_with_mutant_race")
- mutant_races = 1
- if("roundstart_races")
- var/race_id = lowertext(value)
- for(var/species_id in GLOB.species_list)
- if(species_id == race_id)
- roundstart_races += GLOB.species_list[species_id]
- GLOB.roundstart_species[species_id] = GLOB.species_list[species_id]
- if("join_with_mutant_humans")
- mutant_humans = 1
- if("assistant_cap")
- assistant_cap = text2num(value)
- if("starlight")
- starlight = 1
- if("grey_assistants")
- grey_assistants = 1
- if("lavaland_budget")
- lavaland_budget = text2num(value)
- if("space_budget")
- space_budget = text2num(value)
- if("no_summon_guns")
- no_summon_guns = 1
- if("no_summon_magic")
- no_summon_magic = 1
- if("no_summon_events")
- no_summon_events = 1
- if("reactionary_explosions")
- reactionary_explosions = 1
- if("bombcap")
- var/BombCap = text2num(value)
- if (!BombCap)
- continue
- if (BombCap < 4)
- BombCap = 4
-
- GLOB.MAX_EX_DEVESTATION_RANGE = round(BombCap/4)
- GLOB.MAX_EX_HEAVY_RANGE = round(BombCap/2)
- GLOB.MAX_EX_LIGHT_RANGE = BombCap
- GLOB.MAX_EX_FLASH_RANGE = BombCap
- GLOB.MAX_EX_FLAME_RANGE = BombCap
- if("arrivals_shuttle_dock_window")
- arrivals_shuttle_dock_window = max(PARALLAX_LOOP_TIME, text2num(value))
- if("arrivals_shuttle_require_undocked")
- arrivals_shuttle_require_undocked = TRUE
- if("arrivals_shuttle_require_safe_latejoin")
- arrivals_shuttle_require_safe_latejoin = TRUE
- if("mice_roundstart")
- mice_roundstart = text2num(value)
- else
- WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'")
- else if(type == "policies")
- policies[name] = value
-
- fps = round(fps)
- if(fps <= 0)
- fps = initial(fps)
-
-/datum/configuration/proc/HandleCommsConfig(name, value)
- switch(name)
- if("comms_key")
- global.comms_key = value
- if(value != "default_pwd" && length(value) > 6) //It's the default value or less than 6 characters long, warn badmins
- global.comms_allowed = TRUE
- if("cross_server_address")
- cross_address = value
- if(value != "byond:\\address:port")
- cross_allowed = TRUE
- if("cross_comms_name")
- cross_name = value
- if("medal_hub_address")
- global.medal_hub = value
- if("medal_hub_password")
- global.medal_pass = value
- else
- WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'")
-
-/datum/configuration/proc/loadmaplist(filename)
+/datum/controller/configuration/proc/loadmaplist(filename)
filename = "[GLOB.config_dir][filename]"
var/list/Lines = world.file2list(filename)
@@ -895,7 +203,7 @@ GLOBAL_PROTECT(config_dir)
if ("map")
currentmap = new ("_maps/[data].json")
if(currentmap.defaulted)
- log_world("Failed to load map config for [data]!")
+ log_config("Failed to load map config for [data]!")
if ("minplayers","minplayer")
currentmap.config_min_users = text2num(data)
if ("maxplayers","maxplayer")
@@ -905,6 +213,7 @@ GLOBAL_PROTECT(config_dir)
if ("default","defaultmap")
defaultmap = currentmap
if ("endmap")
+ LAZYINITLIST(maplist)
maplist[currentmap.map_name] = currentmap
currentmap = null
if ("disabled")
@@ -913,51 +222,7 @@ GLOBAL_PROTECT(config_dir)
WRITE_FILE(GLOB.config_error_log, "Unknown command in map vote config: '[command]'")
-/datum/configuration/proc/loadsql(filename)
- filename = "[GLOB.config_dir][filename]"
- var/list/Lines = world.file2list(filename)
- for(var/t in Lines)
- if(!t)
- continue
-
- t = trim(t)
- if(length(t) == 0)
- continue
- else if(copytext(t, 1, 2) == "#")
- continue
-
- var/pos = findtext(t, " ")
- var/name = null
- var/value = null
-
- if(pos)
- name = lowertext(copytext(t, 1, pos))
- value = copytext(t, pos + 1)
- else
- name = lowertext(t)
-
- if(!name)
- continue
-
- switch(name)
- if("sql_enabled")
- sql_enabled = 1
- if("address")
- global.sqladdress = value
- if("port")
- global.sqlport = value
- if("feedback_database")
- global.sqlfdbkdb = value
- if("feedback_login")
- global.sqlfdbklogin = value
- if("feedback_password")
- global.sqlfdbkpass = value
- if("feedback_tableprefix")
- global.sqlfdbktableprefix = value
- else
- WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'")
-
-/datum/configuration/proc/pick_mode(mode_name)
+/datum/controller/configuration/proc/pick_mode(mode_name)
// I wish I didn't have to instance the game modes in order to look up
// their information, but it is the only way (at least that I know of).
// ^ This guy didn't try hard enough
@@ -968,8 +233,12 @@ GLOBAL_PROTECT(config_dir)
return new T
return new /datum/game_mode/extended()
-/datum/configuration/proc/get_runnable_modes()
+/datum/controller/configuration/proc/get_runnable_modes()
var/list/datum/game_mode/runnable_modes = new
+ var/list/probabilities = Get(/datum/config_entry/keyed_number_list/probability)
+ var/list/min_pop = Get(/datum/config_entry/keyed_number_list/min_pop)
+ var/list/max_pop = Get(/datum/config_entry/keyed_number_list/max_pop)
+ var/list/repeated_mode_adjust = Get(/datum/config_entry/number_list/repeated_mode_adjust)
for(var/T in gamemode_cache)
var/datum/game_mode/M = new T()
if(!(M.config_tag in modes))
@@ -994,8 +263,11 @@ GLOBAL_PROTECT(config_dir)
runnable_modes[M] = final_weight
return runnable_modes
-/datum/configuration/proc/get_runnable_midround_modes(crew)
+/datum/controller/configuration/proc/get_runnable_midround_modes(crew)
var/list/datum/game_mode/runnable_modes = new
+ var/list/probabilities = Get(/datum/config_entry/keyed_number_list/probability)
+ var/list/min_pop = Get(/datum/config_entry/keyed_number_list/min_pop)
+ var/list/max_pop = Get(/datum/config_entry/keyed_number_list/max_pop)
for(var/T in (gamemode_cache - SSticker.mode.type))
var/datum/game_mode/M = new T()
if(!(M.config_tag in modes))
@@ -1013,9 +285,3 @@ GLOBAL_PROTECT(config_dir)
continue
runnable_modes[M] = probabilities[M.config_tag]
return runnable_modes
-
-/datum/configuration/proc/stat_entry()
- if(!statclick)
- statclick = new/obj/effect/statclick/debug(null, "Edit", src)
-
- stat("[name]:", statclick)
diff --git a/code/controllers/configuration/config_entry.dm b/code/controllers/configuration/config_entry.dm
index b439743a79..5358073dbe 100644
--- a/code/controllers/configuration/config_entry.dm
+++ b/code/controllers/configuration/config_entry.dm
@@ -51,13 +51,7 @@
return FALSE
return ..()
-/datum/config_entry/proc/VASProcCallGuard(str_val)
- . = !(IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "ValidateAndSet" && GLOB.LastAdminCalledTargetRef == "\ref[src]")
- if(!.)
- log_admin_private("Config set of [type] to [str_val] attempted by [key_name(usr)]")
-
/datum/config_entry/proc/ValidateAndSet(str_val)
- VASProcCallGuard(str_val)
CRASH("Invalid config entry type!")
/datum/config_entry/proc/ValidateKeyedList(str_val, list_mode, splitter)
@@ -98,8 +92,6 @@
return var_name != "auto_trim" && ..()
/datum/config_entry/string/ValidateAndSet(str_val)
- if(!VASProcCallGuard(str_val))
- return FALSE
value = auto_trim ? trim(str_val) : str_val
return TRUE
@@ -111,8 +103,6 @@
var/min_val = -INFINITY
/datum/config_entry/number/ValidateAndSet(str_val)
- if(!VASProcCallGuard(str_val))
- return FALSE
var/temp = text2num(trim(str_val))
if(!isnull(temp))
value = Clamp(integer ? round(temp) : temp, min_val, max_val)
@@ -130,8 +120,6 @@
abstract_type = /datum/config_entry/flag
/datum/config_entry/flag/ValidateAndSet(str_val)
- if(!VASProcCallGuard(str_val))
- return FALSE
value = text2num(trim(str_val)) != 0
return TRUE
@@ -140,8 +128,6 @@
value = list()
/datum/config_entry/number_list/ValidateAndSet(str_val)
- if(!VASProcCallGuard(str_val))
- return FALSE
str_val = trim(str_val)
var/list/new_list = list()
var/list/values = splittext(str_val," ")
@@ -161,8 +147,6 @@
dupes_allowed = TRUE
/datum/config_entry/keyed_flag_list/ValidateAndSet(str_val)
- if(!VASProcCallGuard(str_val))
- return FALSE
return ValidateKeyedList(str_val, LIST_MODE_FLAG, " ")
/datum/config_entry/keyed_number_list
@@ -175,8 +159,6 @@
return var_name != "splitter" && ..()
/datum/config_entry/keyed_number_list/ValidateAndSet(str_val)
- if(!VASProcCallGuard(str_val))
- return FALSE
return ValidateKeyedList(str_val, LIST_MODE_NUM, splitter)
/datum/config_entry/keyed_string_list
@@ -189,8 +171,6 @@
return var_name != "splitter" && ..()
/datum/config_entry/keyed_string_list/ValidateAndSet(str_val)
- if(!VASProcCallGuard(str_val))
- return FALSE
return ValidateKeyedList(str_val, LIST_MODE_TEXT, splitter)
#undef LIST_MODE_NUM
diff --git a/code/controllers/configuration/configuration.dm b/code/controllers/configuration/configuration.dm
index 8df012e5de..a9807a599c 100644
--- a/code/controllers/configuration/configuration.dm
+++ b/code/controllers/configuration/configuration.dm
@@ -24,8 +24,7 @@ GLOBAL_PROTECT(config_dir)
LoadModes()
for(var/I in config_files)
LoadEntries(I)
- if(Get(/datum/config_entry/flag/maprotation))
- loadmaplist(CONFIG_MAPS_FILE)
+ loadmaplist(CONFIG_MAPS_FILE)
/datum/controller/configuration/Destroy()
entries_by_type.Cut()
@@ -75,6 +74,10 @@ GLOBAL_PROTECT(config_dir)
if(copytext(L, 1, 2) == "#")
continue
+ var/lockthis = copytext(L, 1, 2) == "@"
+ if(lockthis)
+ L = copytext(L, 2)
+
var/pos = findtext(L, " ")
var/entry = null
var/value = null
@@ -97,6 +100,9 @@ GLOBAL_PROTECT(config_dir)
log_config("Found [entry] in [filename] when it should have been in [E.resident_file]! Ignoring.")
continue
+ if(lockthis)
+ E.protection |= CONFIG_ENTRY_LOCKED
+
var/validated = E.ValidateAndSet(value)
if(!validated)
log_config("Failed to validate setting \"[value]\" for [entry]")
@@ -170,6 +176,7 @@ GLOBAL_PROTECT(config_dir)
/datum/controller/configuration/proc/loadmaplist(filename)
filename = "[GLOB.config_dir][filename]"
+ log_config("Loading config file [filename]...")
var/list/Lines = world.file2list(filename)
var/datum/map_config/currentmap = null
diff --git a/code/controllers/configuration/entries/comms.dm b/code/controllers/configuration/entries/comms.dm
new file mode 100644
index 0000000000..bf099f6cb6
--- /dev/null
+++ b/code/controllers/configuration/entries/comms.dm
@@ -0,0 +1,22 @@
+#define CURRENT_RESIDENT_FILE "comms.txt"
+
+CONFIG_DEF(string/comms_key)
+ protection = CONFIG_ENTRY_HIDDEN
+
+/datum/config_entry/string/comms_key/ValidateAndSet(str_val)
+ return str_val != "default_pwd" && length(str_val) > 6 && ..()
+
+CONFIG_DEF(string/cross_server_address)
+ protection = CONFIG_ENTRY_LOCKED
+
+/datum/config_entry/string/cross_server_address/ValidateAndSet(str_val)
+ return str_val != "byond:\\address:port" && ..()
+
+CONFIG_DEF(string/cross_comms_name)
+
+GLOBAL_VAR_INIT(medals_enabled, TRUE) //will be auto set to false if the game fails contacting the medal hub to prevent unneeded calls.
+
+CONFIG_DEF(string/medal_hub_address)
+
+CONFIG_DEF(string/medal_hub_password)
+ protection = CONFIG_ENTRY_HIDDEN
\ No newline at end of file
diff --git a/code/controllers/configuration/entries/config.dm b/code/controllers/configuration/entries/config.dm
new file mode 100644
index 0000000000..ec96e88553
--- /dev/null
+++ b/code/controllers/configuration/entries/config.dm
@@ -0,0 +1,354 @@
+#define CURRENT_RESIDENT_FILE "config.txt"
+
+CONFIG_DEF(flag/autoadmin) // if autoadmin is enabled
+ protection = CONFIG_ENTRY_LOCKED
+
+CONFIG_DEF(string/autoadmin_rank) // the rank for autoadmins
+ value = "Game Master"
+ protection = CONFIG_ENTRY_LOCKED
+
+CONFIG_DEF(string/servername) // server name (the name of the game window)
+
+CONFIG_DEF(string/serversqlname) // short form server name used for the DB
+
+CONFIG_DEF(string/stationname) // station name (the name of the station in-game)
+
+CONFIG_DEF(number/lobby_countdown) // In between round countdown.
+ value = 120
+ min_val = 0
+
+CONFIG_DEF(number/round_end_countdown) // Post round murder death kill countdown
+ value = 25
+ min_val = 0
+
+CONFIG_DEF(flag/hub) // if the game appears on the hub or not
+
+CONFIG_DEF(flag/log_ooc) // log OOC channel
+
+CONFIG_DEF(flag/log_access) // log login/logout
+
+CONFIG_DEF(flag/log_say) // log client say
+
+CONFIG_DEF(flag/log_admin) // log admin actions
+ protection = CONFIG_ENTRY_LOCKED
+
+CONFIG_DEF(flag/log_prayer) // log prayers
+
+CONFIG_DEF(flag/log_law) // log lawchanges
+
+CONFIG_DEF(flag/log_game) // log game events
+
+CONFIG_DEF(flag/log_vote) // log voting
+
+CONFIG_DEF(flag/log_whisper) // log client whisper
+
+CONFIG_DEF(flag/log_attack) // log attack messages
+
+CONFIG_DEF(flag/log_emote) // log emotes
+
+CONFIG_DEF(flag/log_adminchat) // log admin chat messages
+ protection = CONFIG_ENTRY_LOCKED
+
+CONFIG_DEF(flag/log_pda) // log pda messages
+
+CONFIG_DEF(flag/log_twitter) // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases.
+
+CONFIG_DEF(flag/log_world_topic) // log all world.Topic() calls
+
+CONFIG_DEF(flag/allow_admin_ooccolor) // Allows admins with relevant permissions to have their own ooc colour
+ protection = CONFIG_ENTRY_LOCKED
+
+CONFIG_DEF(flag/allow_vote_restart) // allow votes to restart
+
+CONFIG_DEF(flag/allow_vote_mode) // allow votes to change mode
+
+CONFIG_DEF(number/vote_delay) // minimum time between voting sessions (deciseconds, 10 minute default)
+ value = 6000
+ min_val = 0
+
+CONFIG_DEF(number/vote_period) // length of voting period (deciseconds, default 1 minute)
+ value = 600
+ min_val = 0
+
+CONFIG_DEF(flag/default_no_vote) // vote does not default to nochange/norestart
+
+CONFIG_DEF(flag/no_dead_vote) // dead people can't vote
+
+CONFIG_DEF(flag/allow_metadata) // Metadata is supported.
+
+CONFIG_DEF(flag/popup_admin_pm) // adminPMs to non-admins show in a pop-up 'reply' window when set
+
+CONFIG_DEF(number/fps)
+ value = 20
+ min_val = 1
+ max_val = 100 //byond will start crapping out at 50, so this is just ridic
+ var/sync_validate = FALSE
+
+/datum/config_entry/number/fps/ValidateAndSet(str_val)
+ . = ..()
+ if(.)
+ sync_validate = TRUE
+ var/datum/config_entry/number/ticklag/TL = config.entries_by_type[/datum/config_entry/number/ticklag]
+ if(!TL.sync_validate)
+ TL.ValidateAndSet(10 / value)
+ sync_validate = FALSE
+
+CONFIG_DEF(number/ticklag)
+ integer = FALSE
+ var/sync_validate = FALSE
+
+/datum/config_entry/number/ticklag/New() //ticklag weirdly just mirrors fps
+ var/datum/config_entry/CE = /datum/config_entry/number/fps
+ value = 10 / initial(CE.value)
+ ..()
+
+/datum/config_entry/number/ticklag/ValidateAndSet(str_val)
+ . = text2num(str_val) > 0 && ..()
+ if(.)
+ sync_validate = TRUE
+ var/datum/config_entry/number/fps/FPS = config.entries_by_type[/datum/config_entry/number/fps]
+ if(!FPS.sync_validate)
+ FPS.ValidateAndSet(10 / value)
+ sync_validate = FALSE
+
+CONFIG_DEF(flag/allow_holidays)
+
+CONFIG_DEF(number/tick_limit_mc_init) //SSinitialization throttling
+ value = TICK_LIMIT_MC_INIT_DEFAULT
+ min_val = 0 //oranges warned us
+ integer = FALSE
+
+CONFIG_DEF(flag/admin_legacy_system) //Defines whether the server uses the legacy admin system with admins.txt or the SQL system
+ protection = CONFIG_ENTRY_LOCKED
+
+CONFIG_DEF(string/hostedby)
+
+CONFIG_DEF(flag/norespawn)
+
+CONFIG_DEF(flag/guest_jobban)
+
+CONFIG_DEF(flag/usewhitelist)
+
+CONFIG_DEF(flag/ban_legacy_system) //Defines whether the server uses the legacy banning system with the files in /data or the SQL system.
+ protection = CONFIG_ENTRY_LOCKED
+
+CONFIG_DEF(flag/use_age_restriction_for_jobs) //Do jobs use account age restrictions? --requires database
+
+CONFIG_DEF(flag/use_account_age_for_jobs) //Uses the time they made the account for the job restriction stuff. New player joining alerts should be unaffected.
+
+CONFIG_DEF(flag/use_exp_tracking)
+
+CONFIG_DEF(flag/use_exp_restrictions_heads)
+
+CONFIG_DEF(number/use_exp_restrictions_heads_hours)
+ value = 0
+ min_val = 0
+
+CONFIG_DEF(flag/use_exp_restrictions_heads_department)
+
+CONFIG_DEF(flag/use_exp_restrictions_other)
+
+CONFIG_DEF(flag/use_exp_restrictions_admin_bypass)
+
+CONFIG_DEF(string/server)
+
+CONFIG_DEF(string/banappeals)
+
+CONFIG_DEF(string/wikiurl)
+ value = "http://www.tgstation13.org/wiki"
+
+CONFIG_DEF(string/forumurl)
+ value = "http://tgstation13.org/phpBB/index.php"
+
+CONFIG_DEF(string/rulesurl)
+ value = "http://www.tgstation13.org/wiki/Rules"
+
+CONFIG_DEF(string/githuburl)
+ value = "https://www.github.com/tgstation/-tg-station"
+
+CONFIG_DEF(number/githubrepoid)
+ value = null
+ min_val = 0
+
+CONFIG_DEF(flag/guest_ban)
+
+CONFIG_DEF(number/id_console_jobslot_delay)
+ value = 30
+ min_val = 0
+
+CONFIG_DEF(number/inactivity_period) //time in ds until a player is considered inactive)
+ value = 3000
+ min_val = 0
+
+/datum/config_entry/number/inactivity_period/ValidateAndSet(str_val)
+ . = ..()
+ if(.)
+ value *= 10 //documented as seconds in config.txt
+
+CONFIG_DEF(number/afk_period) //time in ds until a player is considered inactive)
+ value = 3000
+ min_val = 0
+
+/datum/config_entry/number/afk_period/ValidateAndSet(str_val)
+ . = ..()
+ if(.)
+ value *= 10 //documented as seconds in config.txt
+
+CONFIG_DEF(flag/kick_inactive) //force disconnect for inactive players
+
+CONFIG_DEF(flag/load_jobs_from_txt)
+
+CONFIG_DEF(flag/forbid_singulo_possession)
+
+CONFIG_DEF(flag/useircbot) //tgs2 support
+ protection = CONFIG_ENTRY_LOCKED
+
+CONFIG_DEF(flag/automute_on) //enables automuting/spam prevention
+
+CONFIG_DEF(string/panic_server_name)
+
+/datum/config_entry/string/panic_server_name/ValidateAndSet(str_val)
+ return str_val != "\[Put the name here\]" && ..()
+
+CONFIG_DEF(string/panic_address) //Reconnect a player this linked server if this server isn't accepting new players
+
+/datum/config_entry/string/panic_address/ValidateAndSet(str_val)
+ return str_val != "byond://address:port" && ..()
+
+CONFIG_DEF(string/invoke_youtubedl)
+ protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN
+
+CONFIG_DEF(flag/show_irc_name)
+
+CONFIG_DEF(flag/see_own_notes) //Can players see their own admin notes (read-only)?
+
+CONFIG_DEF(number/note_fresh_days)
+ value = null
+ min_val = 0
+ integer = FALSE
+
+CONFIG_DEF(number/note_stale_days)
+ value = null
+ min_val = 0
+ integer = FALSE
+
+CONFIG_DEF(flag/maprotation)
+
+CONFIG_DEF(number/maprotatechancedelta)
+ value = 0.75
+ min_val = 0
+ max_val = 1
+ integer = FALSE
+
+CONFIG_DEF(number/soft_popcap)
+ value = null
+ min_val = 0
+
+CONFIG_DEF(number/hard_popcap)
+ value = null
+ min_val = 0
+
+CONFIG_DEF(number/extreme_popcap)
+ value = null
+ min_val = 0
+
+CONFIG_DEF(string/soft_popcap_message)
+ value = "Be warned that the server is currently serving a high number of users, consider using alternative game servers."
+
+CONFIG_DEF(string/hard_popcap_message)
+ value = "The server is currently serving a high number of users, You cannot currently join. You may wait for the number of living crew to decline, observe, or find alternative servers."
+
+CONFIG_DEF(string/extreme_popcap_message)
+ value = "The server is currently serving a high number of users, find alternative servers."
+
+CONFIG_DEF(flag/panic_bunker) // prevents people the server hasn't seen before from connecting
+
+CONFIG_DEF(number/notify_new_player_age) // how long do we notify admins of a new player
+ min_val = -1
+
+CONFIG_DEF(number/notify_new_player_account_age) // how long do we notify admins of a new byond account
+ min_val = 0
+
+CONFIG_DEF(flag/irc_first_connection_alert) // do we notify the irc channel when somebody is connecting for the first time?
+
+CONFIG_DEF(flag/check_randomizer)
+
+CONFIG_DEF(string/ipintel_email)
+
+/datum/config_entry/string/ipintel_email/ValidateAndSet(str_val)
+ return str_val != "ch@nge.me" && ..()
+
+CONFIG_DEF(number/ipintel_rating_bad)
+ value = 1
+ integer = FALSE
+ min_val = 0
+ max_val = 1
+
+CONFIG_DEF(number/ipintel_save_good)
+ value = 12
+ min_val = 0
+
+CONFIG_DEF(number/ipintel_save_bad)
+ value = 1
+ min_val = 0
+
+CONFIG_DEF(string/ipintel_domain)
+ value = "check.getipintel.net"
+
+CONFIG_DEF(flag/aggressive_changelog)
+
+CONFIG_DEF(flag/autoconvert_notes) //if all connecting player's notes should attempt to be converted to the database
+ protection = CONFIG_ENTRY_LOCKED
+
+CONFIG_DEF(flag/allow_webclient)
+
+CONFIG_DEF(flag/webclient_only_byond_members)
+
+CONFIG_DEF(flag/announce_admin_logout)
+
+CONFIG_DEF(flag/announce_admin_login)
+
+CONFIG_DEF(flag/allow_map_voting)
+
+CONFIG_DEF(flag/generate_minimaps)
+
+CONFIG_DEF(number/client_warn_version)
+ value = null
+ min_val = 500
+ max_val = DM_VERSION - 1
+
+CONFIG_DEF(string/client_warn_message)
+ value = "Your version of byond may have issues or be blocked from accessing this server in the future."
+
+CONFIG_DEF(number/client_error_version)
+ value = null
+ min_val = 500
+ max_val = DM_VERSION - 1
+
+CONFIG_DEF(string/client_error_message)
+ value = "Your version of byond is too old, may have issues, and is blocked from accessing this server."
+
+CONFIG_DEF(number/minute_topic_limit)
+ value = null
+ min_val = 0
+
+CONFIG_DEF(number/second_topic_limit)
+ value = null
+ min_val = 0
+
+CONFIG_DEF(number/error_cooldown) // The "cooldown" time for each occurrence of a unique error)
+ value = 600
+ min_val = 0
+
+CONFIG_DEF(number/error_limit) // How many occurrences before the next will silence them
+ value = 50
+
+CONFIG_DEF(number/error_silence_time) // How long a unique error will be silenced for
+ value = 6000
+
+CONFIG_DEF(number/error_msg_delay) // How long to wait between messaging admins about occurrences of a unique error
+ value = 50
+
+CONFIG_DEF(flag/irc_announce_new_game)
+
+CONFIG_DEF(flag/debug_admin_hrefs)
\ No newline at end of file
diff --git a/code/controllers/configuration/entries/dbconfig.dm b/code/controllers/configuration/entries/dbconfig.dm
new file mode 100644
index 0000000000..c46880686a
--- /dev/null
+++ b/code/controllers/configuration/entries/dbconfig.dm
@@ -0,0 +1,28 @@
+#define CURRENT_RESIDENT_FILE "dbconfig.txt"
+
+CONFIG_DEF(flag/sql_enabled) // for sql switching
+ protection = CONFIG_ENTRY_LOCKED
+
+CONFIG_DEF(string/address)
+ value = "localhost"
+ protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN
+
+CONFIG_DEF(number/port)
+ value = 3306
+ min_val = 0
+ max_val = 65535
+ protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN
+
+CONFIG_DEF(string/feedback_database)
+ value = "test"
+ protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN
+
+CONFIG_DEF(string/feedback_login)
+ value = "root"
+ protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN
+
+CONFIG_DEF(string/feedback_password)
+ protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN
+
+CONFIG_DEF(string/feedback_tableprefix)
+ protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN
diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm
new file mode 100644
index 0000000000..106804a576
--- /dev/null
+++ b/code/controllers/configuration/entries/game_options.dm
@@ -0,0 +1,266 @@
+#define CURRENT_RESIDENT_FILE "game_options.txt"
+
+CONFIG_DEF(number_list/repeated_mode_adjust)
+
+CONFIG_DEF(keyed_number_list/probability)
+
+/datum/config_entry/keyed_number_list/probability/ValidateKeyName(key_name)
+ return key_name in config.modes
+
+CONFIG_DEF(keyed_number_list/max_pop)
+
+/datum/config_entry/keyed_number_list/max_pop/ValidateKeyName(key_name)
+ return key_name in config.modes
+
+CONFIG_DEF(keyed_number_list/min_pop)
+
+/datum/config_entry/keyed_number_list/min_pop/ValidateKeyName(key_name)
+ return key_name in config.modes
+
+CONFIG_DEF(keyed_flag_list/continuous) // which roundtypes continue if all antagonists die
+
+/datum/config_entry/keyed_flag_list/continuous/ValidateKeyName(key_name)
+ return key_name in config.modes
+
+CONFIG_DEF(keyed_flag_list/midround_antag) // which roundtypes use the midround antagonist system
+
+/datum/config_entry/keyed_flag_list/midround_antag/ValidateKeyName(key_name)
+ return key_name in config.modes
+
+CONFIG_DEF(keyed_string_list/policy)
+
+CONFIG_DEF(number/damage_multiplier)
+ value = 1
+ integer = FALSE
+
+CONFIG_DEF(number/minimal_access_threshold) //If the number of players is larger than this threshold, minimal access will be turned on.
+ min_val = 0
+
+CONFIG_DEF(flag/jobs_have_minimal_access) //determines whether jobs use minimal access or expanded access.
+
+CONFIG_DEF(flag/assistants_have_maint_access)
+
+CONFIG_DEF(flag/security_has_maint_access)
+
+CONFIG_DEF(flag/everyone_has_maint_access)
+
+CONFIG_DEF(flag/sec_start_brig) //makes sec start in brig instead of dept sec posts
+
+CONFIG_DEF(flag/force_random_names)
+
+CONFIG_DEF(flag/humans_need_surnames)
+
+CONFIG_DEF(flag/allow_ai) // allow ai job
+
+CONFIG_DEF(flag/disable_secborg) // disallow secborg module to be chosen.
+
+CONFIG_DEF(flag/disable_peaceborg)
+
+CONFIG_DEF(number/traitor_scaling_coeff) //how much does the amount of players get divided by to determine traitors
+ value = 6
+ min_val = 1
+
+CONFIG_DEF(number/brother_scaling_coeff) //how many players per brother team
+ value = 25
+ min_val = 1
+
+CONFIG_DEF(number/changeling_scaling_coeff) //how much does the amount of players get divided by to determine changelings
+ value = 6
+ min_val = 1
+
+CONFIG_DEF(number/security_scaling_coeff) //how much does the amount of players get divided by to determine open security officer positions
+ value = 8
+ min_val = 1
+
+CONFIG_DEF(number/abductor_scaling_coeff) //how many players per abductor team
+ value = 15
+ min_val = 1
+
+CONFIG_DEF(number/traitor_objectives_amount)
+ value = 2
+ min_val = 0
+
+CONFIG_DEF(number/brother_objectives_amount)
+ value = 2
+ min_val = 0
+
+CONFIG_DEF(flag/reactionary_explosions) //If we use reactionary explosions, explosions that react to walls and doors
+
+CONFIG_DEF(flag/protect_roles_from_antagonist) //If security and such can be traitor/cult/other
+
+CONFIG_DEF(flag/protect_assistant_from_antagonist) //If assistants can be traitor/cult/other
+
+CONFIG_DEF(flag/enforce_human_authority) //If non-human species are barred from joining as a head of staff
+
+CONFIG_DEF(flag/allow_latejoin_antagonists) // If late-joining players can be traitor/changeling
+
+CONFIG_DEF(number/midround_antag_time_check) // How late (in minutes) you want the midround antag system to stay on, setting this to 0 will disable the system
+ value = 60
+ min_val = 0
+
+CONFIG_DEF(number/midround_antag_life_check) // A ratio of how many people need to be alive in order for the round not to immediately end in midround antagonist
+ value = 0.7
+ integer = FALSE
+ min_val = 0
+ max_val = 1
+
+CONFIG_DEF(number/shuttle_refuel_delay)
+ value = 12000
+ min_val = 0
+
+CONFIG_DEF(flag/show_game_type_odds) //if set this allows players to see the odds of each roundtype on the get revision screen
+
+CONFIG_DEF(flag/join_with_mutant_race) //players can choose their mutant race before joining the game
+
+CONFIG_DEF(keyed_flag_list/roundstart_races) //races you can play as from the get go. If left undefined the game's roundstart var for species is used
+ var/first_edit = TRUE
+
+/datum/config_entry/keyed_flag_list/roundstart_races/New()
+ for(var/I in subtypesof(/datum/species))
+ var/datum/species/S = I
+ if(initial(S.roundstart))
+ value[initial(S.id)] = TRUE
+ ..()
+
+/datum/config_entry/keyed_flag_list/roundstart_races/ValidateAndSet(str_val)
+ var/list/old_val
+ if(first_edit)
+ old_val = value
+ old_val = old_val.Copy()
+ . = ..()
+ if(first_edit)
+ if(!.)
+ value = old_val
+ else
+ first_edit = FALSE
+
+CONFIG_DEF(flag/join_with_mutant_humans) //players can pick mutant bodyparts for humans before joining the game
+
+CONFIG_DEF(flag/no_summon_guns) //No
+
+CONFIG_DEF(flag/no_summon_magic) //Fun
+
+CONFIG_DEF(flag/no_summon_events) //Allowed
+
+CONFIG_DEF(flag/no_intercept_report) //Whether or not to send a communications intercept report roundstart. This may be overriden by gamemodes.
+
+CONFIG_DEF(number/arrivals_shuttle_dock_window) //Time from when a player late joins on the arrivals shuttle to when the shuttle docks on the station
+ value = 55
+ min_val = 30
+
+CONFIG_DEF(flag/arrivals_shuttle_require_undocked) //Require the arrivals shuttle to be undocked before latejoiners can join
+
+CONFIG_DEF(flag/arrivals_shuttle_require_safe_latejoin) //Require the arrivals shuttle to be operational in order for latejoiners to join
+
+CONFIG_DEF(string/alert_green)
+ value = "All threats to the station have passed. Security may not have weapons visible, privacy laws are once again fully enforced."
+
+CONFIG_DEF(string/alert_blue_upto)
+ value = "The station has received reliable information about possible hostile activity on the station. Security staff may have weapons visible, random searches are permitted."
+
+CONFIG_DEF(string/alert_blue_downto)
+ value = "The immediate threat has passed. Security may no longer have weapons drawn at all times, but may continue to have them visible. Random searches are still allowed."
+
+CONFIG_DEF(string/alert_red_upto)
+ value = "There is an immediate serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised."
+
+CONFIG_DEF(string/alert_red_downto)
+ value = "The station's destruction has been averted. There is still however an immediate serious threat to the station. Security may have weapons unholstered at all times, random searches are allowed and advised."
+
+CONFIG_DEF(string/alert_delta)
+ value = "Destruction of the station is imminent. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill."
+
+CONFIG_DEF(flag/revival_pod_plants)
+
+CONFIG_DEF(flag/revival_cloning)
+
+CONFIG_DEF(number/revival_brain_life)
+ value = -1
+ min_val = -1
+
+CONFIG_DEF(flag/rename_cyborg)
+
+CONFIG_DEF(flag/ooc_during_round)
+
+CONFIG_DEF(flag/emojis)
+
+CONFIG_DEF(number/run_delay) //Used for modifying movement speed for mobs.
+
+CONFIG_DEF(number/walk_delay)
+
+
+CONFIG_DEF(number/human_delay) //Mob specific modifiers. NOTE: These will affect different mob types in different ways
+CONFIG_DEF(number/robot_delay)
+CONFIG_DEF(number/monkey_delay)
+CONFIG_DEF(number/alien_delay)
+CONFIG_DEF(number/slime_delay)
+CONFIG_DEF(number/animal_delay)
+
+CONFIG_DEF(number/gateway_delay) //How long the gateway takes before it activates. Default is half an hour.
+ value = 18000
+ min_val = 0
+
+CONFIG_DEF(flag/ghost_interaction)
+
+CONFIG_DEF(flag/silent_ai)
+CONFIG_DEF(flag/silent_borg)
+
+CONFIG_DEF(flag/sandbox_autoclose) // close the sandbox panel after spawning an item, potentially reducing griff
+
+CONFIG_DEF(number/default_laws) //Controls what laws the AI spawns with.
+ value = 0
+ min_val = 0
+ max_val = 3
+
+CONFIG_DEF(number/silicon_max_law_amount)
+ value = 12
+ min_val = 0
+
+CONFIG_DEF(keyed_flag_list/random_laws)
+
+CONFIG_DEF(keyed_number_list/law_weight)
+ splitter = ","
+
+CONFIG_DEF(number/assistant_cap)
+ value = -1
+ min_val = -1
+
+CONFIG_DEF(flag/starlight)
+CONFIG_DEF(flag/grey_assistants)
+
+CONFIG_DEF(number/lavaland_budget)
+ value = 60
+ min_val = 0
+
+CONFIG_DEF(number/space_budget)
+ value = 16
+ min_val = 0
+
+CONFIG_DEF(flag/allow_random_events) // Enables random events mid-round when set
+
+CONFIG_DEF(number/events_min_time_mul) // Multipliers for random events minimal starting time and minimal players amounts
+ value = 1
+ min_val = 0
+ integer = FALSE
+
+CONFIG_DEF(number/events_min_players_mul)
+ value = 1
+ min_val = 0
+ integer = FALSE
+
+CONFIG_DEF(number/mice_roundstart)
+ value = 10
+ min_val = 0
+
+CONFIG_DEF(number/bombcap)
+ value = 14
+ min_val = 4
+
+/datum/config_entry/number/bombcap/ValidateAndSet(str_val)
+ . = ..()
+ if(.)
+ GLOB.MAX_EX_DEVESTATION_RANGE = round(value / 4)
+ GLOB.MAX_EX_HEAVY_RANGE = round(value / 2)
+ GLOB.MAX_EX_LIGHT_RANGE = value
+ GLOB.MAX_EX_FLASH_RANGE = value
+ GLOB.MAX_EX_FLAME_RANGE = value
diff --git a/code/controllers/master.dm b/code/controllers/master.dm
index 11c460e326..6ed3121179 100644
--- a/code/controllers/master.dm
+++ b/code/controllers/master.dm
@@ -169,7 +169,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
var/start_timeofday = REALTIMEOFDAY
// Initialize subsystems.
- current_ticklimit = config.tick_limit_mc_init
+ current_ticklimit = CONFIG_GET(number/tick_limit_mc_init)
for (var/datum/controller/subsystem/SS in subsystems)
if (SS.flags & SS_NO_INIT)
continue
@@ -189,7 +189,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
sortTim(subsystems, /proc/cmp_subsystem_display)
// Set world options.
world.sleep_offline = 1
- world.fps = config.fps
+ world.fps = CONFIG_GET(number/fps)
var/initialized_tod = REALTIMEOFDAY
sleep(1)
initializations_finished_with_no_players_logged_in = initialized_tod < REALTIMEOFDAY - 10
diff --git a/code/controllers/subsystem/blackbox.dm b/code/controllers/subsystem/blackbox.dm
index 2870305c3e..56238d5b85 100644
--- a/code/controllers/subsystem/blackbox.dm
+++ b/code/controllers/subsystem/blackbox.dm
@@ -38,7 +38,7 @@ SUBSYSTEM_DEF(blackbox)
var/datum/DBQuery/query_record_playercount = SSdbcore.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time, server_ip, server_port, round_id) VALUES ([playercount], [admincount], '[SQLtime()]', INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', '[GLOB.round_id]')")
query_record_playercount.Execute()
- if(config.use_exp_tracking)
+ if(CONFIG_GET(flag/use_exp_tracking))
if((triggertime < 0) || (world.time > (triggertime +3000))) //subsystem fires once at roundstart then once every 10 minutes. a 5 min check skips the first fire. The <0 is midnight rollover check
update_exp(10,FALSE)
diff --git a/code/controllers/subsystem/dbcore.dm b/code/controllers/subsystem/dbcore.dm
index 864274b8fb..12a5342e33 100644
--- a/code/controllers/subsystem/dbcore.dm
+++ b/code/controllers/subsystem/dbcore.dm
@@ -54,32 +54,27 @@ SUBSYSTEM_DEF(dbcore)
if(failed_connections > FAILED_DB_CONNECTION_CUTOFF) //If it failed to establish a connection more than 5 times in a row, don't bother attempting to connect anymore.
return FALSE
- if(!config.sql_enabled)
+ if(!CONFIG_GET(flag/sql_enabled))
return FALSE
- var/user = global.sqlfdbklogin
- var/pass = global.sqlfdbkpass
- var/db = global.sqlfdbkdb
- var/address = global.sqladdress
- var/port = global.sqlport
+ var/user = CONFIG_GET(string/feedback_login)
+ var/pass = CONFIG_GET(string/feedback_password)
+ var/db = CONFIG_GET(string/feedback_database)
+ var/address = CONFIG_GET(string/address)
+ var/port = CONFIG_GET(number/port)
- doConnect("dbi:mysql:[db]:[address]:[port]", user, pass)
+ _dm_db_connect(_db_con, "dbi:mysql:[db]:[address]:[port]", user, pass, Default_Cursor, null)
. = IsConnected()
if (!.)
log_sql("Connect() failed | [ErrorMsg()]")
++failed_connections
-/datum/controller/subsystem/dbcore/proc/doConnect(dbi_handler, user_handler, password_handler)
- if(!config.sql_enabled)
- return FALSE
- return _dm_db_connect(_db_con, dbi_handler, user_handler, password_handler, Default_Cursor, null)
-
/datum/controller/subsystem/dbcore/proc/Disconnect()
failed_connections = 0
return _dm_db_close(_db_con)
/datum/controller/subsystem/dbcore/proc/IsConnected()
- if(!config.sql_enabled)
+ if(!CONFIG_GET(flag/sql_enabled))
return FALSE
return _dm_db_is_connected(_db_con)
@@ -87,7 +82,7 @@ SUBSYSTEM_DEF(dbcore)
return _dm_db_quote(_db_con, str)
/datum/controller/subsystem/dbcore/proc/ErrorMsg()
- if(!config.sql_enabled)
+ if(!CONFIG_GET(flag/sql_enabled))
return "Database disabled by configuration"
return _dm_db_error_msg(_db_con)
diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm
index 7816a6bdf8..f435d7e819 100644
--- a/code/controllers/subsystem/events.dm
+++ b/code/controllers/subsystem/events.dm
@@ -56,7 +56,7 @@ SUBSYSTEM_DEF(events)
//selects a random event based on whether it can occur and it's 'weight'(probability)
/datum/controller/subsystem/events/proc/spawnEvent()
set waitfor = FALSE //for the admin prompt
- if(!config.allow_random_events)
+ if(!CONFIG_GET(flag/allow_random_events))
// var/datum/round_event_control/E = locate(/datum/round_event_control/dust) in control
// if(E) E.runEvent()
return
@@ -171,7 +171,7 @@ SUBSYSTEM_DEF(events)
//sets up the holidays and holidays list
/datum/controller/subsystem/events/proc/getHoliday()
- if(!config.allow_holidays)
+ if(!CONFIG_GET(flag/allow_holidays))
return // Holiday stuff was not enabled in the config!
var/YY = text2num(time2text(world.timeofday, "YY")) // get the current year
diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm
index d64739698a..1eb6c75cc5 100644
--- a/code/controllers/subsystem/job.dm
+++ b/code/controllers/subsystem/job.dm
@@ -16,7 +16,7 @@ SUBSYSTEM_DEF(job)
/datum/controller/subsystem/job/Initialize(timeofday)
if(!occupations.len)
SetupOccupations()
- if(config.load_jobs_from_txt)
+ if(CONFIG_GET(flag/load_jobs_from_txt))
LoadJobs()
..()
@@ -106,7 +106,7 @@ SUBSYSTEM_DEF(job)
if(player.mind && job.title in player.mind.restricted_roles)
Debug("FOC incompatible with antagonist role, Player: [player]")
continue
- if(config.enforce_human_authority && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features))
+ if(CONFIG_GET(flag/enforce_human_authority) && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features))
Debug("FOC non-human failed, Player: [player]")
continue
if(player.client.prefs.GetJobDepartment(job, level) & job.flag)
@@ -143,7 +143,7 @@ SUBSYSTEM_DEF(job)
Debug("GRJ incompatible with antagonist role, Player: [player], Job: [job.title]")
continue
- if(config.enforce_human_authority && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features))
+ if(CONFIG_GET(flag/enforce_human_authority) && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features))
Debug("GRJ non-human failed, Player: [player]")
continue
@@ -245,11 +245,12 @@ SUBSYSTEM_DEF(job)
setup_officer_positions()
//Jobs will have fewer access permissions if the number of players exceeds the threshold defined in game_options.txt
- if(config.minimal_access_threshold)
- if(config.minimal_access_threshold > unassigned.len)
- config.jobs_have_minimal_access = 0
+ var/mat = CONFIG_GET(number/minimal_access_threshold)
+ if(mat)
+ if(mat > unassigned.len)
+ CONFIG_SET(flag/jobs_have_minimal_access, FALSE)
else
- config.jobs_have_minimal_access = 1
+ CONFIG_SET(flag/jobs_have_minimal_access, TRUE)
//Shuffle players and jobs
unassigned = shuffle(unassigned)
@@ -317,7 +318,7 @@ SUBSYSTEM_DEF(job)
Debug("DO incompatible with antagonist role, Player: [player], Job:[job.title]")
continue
- if(config.enforce_human_authority && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features))
+ if(CONFIG_GET(flag/enforce_human_authority) && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features))
Debug("DO non-human failed, Player: [player], Job:[job.title]")
continue
@@ -415,8 +416,8 @@ SUBSYSTEM_DEF(job)
to_chat(M, "To speak on your departments radio, use the :h button. To see others, look closely at your headset. ")
if(job.req_admin_notify)
to_chat(M, "You are playing a job that is important for Game Progression. If you have to disconnect, please notify the admins via adminhelp. ")
- if(config.minimal_access_threshold)
- to_chat(M, "As this station was initially staffed with a [config.jobs_have_minimal_access ? "full crew, only your job's necessities" : "skeleton crew, additional access may"] have been added to your ID card. ")
+ if(CONFIG_GET(number/minimal_access_threshold))
+ to_chat(M, "As this station was initially staffed with a [CONFIG_GET(flag/jobs_have_minimal_access) ? "full crew, only your job's necessities" : "skeleton crew, additional access may"] have been added to your ID card. ")
if(job && H)
job.after_spawn(H, M)
@@ -429,9 +430,10 @@ SUBSYSTEM_DEF(job)
if(!J)
throw EXCEPTION("setup_officer_positions(): Security officer job is missing")
- if(config.security_scaling_coeff > 0)
+ var/ssc = CONFIG_GET(number/security_scaling_coeff)
+ if(ssc > 0)
if(J.spawn_positions > 0)
- var/officer_positions = min(12, max(J.spawn_positions, round(unassigned.len/config.security_scaling_coeff))) //Scale between configured minimum and 12 officers
+ var/officer_positions = min(12, max(J.spawn_positions, round(unassigned.len / ssc))) //Scale between configured minimum and 12 officers
Debug("Setting open security officer positions to [officer_positions]")
J.total_positions = officer_positions
J.spawn_positions = officer_positions
@@ -491,8 +493,10 @@ SUBSYSTEM_DEF(job)
SSblackbox.add_details("job_preferences",tmp_str)
/datum/controller/subsystem/job/proc/PopcapReached()
- if(config.hard_popcap || config.extreme_popcap)
- var/relevent_cap = max(config.hard_popcap, config.extreme_popcap)
+ var/hpc = CONFIG_GET(number/hard_popcap)
+ var/epc = CONFIG_GET(number/extreme_popcap)
+ if(hpc || epc)
+ var/relevent_cap = max(hpc, epc)
if((initial_players_to_assign - unassigned.len) >= relevent_cap)
return 1
return 0
diff --git a/code/controllers/subsystem/lighting.dm b/code/controllers/subsystem/lighting.dm
index 78e8b150c3..989c5b43c4 100644
--- a/code/controllers/subsystem/lighting.dm
+++ b/code/controllers/subsystem/lighting.dm
@@ -16,7 +16,7 @@ SUBSYSTEM_DEF(lighting)
/datum/controller/subsystem/lighting/Initialize(timeofday)
if(!initialized)
- if (config.starlight)
+ if (CONFIG_GET(flag/starlight))
for(var/I in GLOB.sortedAreas)
var/area/A = I
if (A.dynamic_lighting == DYNAMIC_LIGHTING_IFSTARLIGHT)
diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm
index 9549cf7b18..ab2ba54431 100644
--- a/code/controllers/subsystem/mapping.dm
+++ b/code/controllers/subsystem/mapping.dm
@@ -43,7 +43,7 @@ SUBSYSTEM_DEF(mapping)
loading_ruins = TRUE
var/mining_type = config.minetype
if (mining_type == "lavaland")
- seedRuins(list(ZLEVEL_LAVALAND), global.config.lavaland_budget, /area/lavaland/surface/outdoors/unexplored, lava_ruins_templates)
+ seedRuins(list(ZLEVEL_LAVALAND), CONFIG_GET(number/lavaland_budget), /area/lavaland/surface/outdoors/unexplored, lava_ruins_templates)
spawn_rivers()
// deep space ruins
@@ -55,7 +55,7 @@ SUBSYSTEM_DEF(mapping)
else
space_zlevels += i
- seedRuins(space_zlevels, global.config.space_budget, /area/space, space_ruins_templates)
+ seedRuins(space_zlevels, CONFIG_GET(number/space_budget), /area/space, space_ruins_templates)
loading_ruins = FALSE
repopulate_sorted_areas()
// Set up Z-level transistions.
@@ -141,7 +141,8 @@ SUBSYSTEM_DEF(mapping)
var/players = GLOB.clients.len
var/list/mapvotes = list()
//count votes
- if(global.config.allow_map_voting)
+ var/amv = CONFIG_GET(flag/allow_map_voting)
+ if(amv)
for (var/client/c in GLOB.clients)
var/vote = c.prefs.preferred_map
if (!vote)
@@ -174,7 +175,7 @@ SUBSYSTEM_DEF(mapping)
mapvotes.Remove(map)
continue
- if(global.config.allow_map_voting)
+ if(amv)
mapvotes[map] = mapvotes[map]*VM.voteweight
var/pickedmap = pickweight(mapvotes)
diff --git a/code/controllers/subsystem/minimap.dm b/code/controllers/subsystem/minimap.dm
index 4e58212b44..463b82b13e 100644
--- a/code/controllers/subsystem/minimap.dm
+++ b/code/controllers/subsystem/minimap.dm
@@ -9,7 +9,7 @@ SUBSYSTEM_DEF(minimap)
/datum/controller/subsystem/minimap/Initialize(timeofday)
var/hash = md5(SSmapping.config.GetFullMapPath())
- if(config.generate_minimaps)
+ if(CONFIG_GET(flag/generate_minimaps))
if(hash == trim(file2text(hash_path())))
for(var/z in z_levels) //We have these files cached, let's register them
register_asset("minimap_[z].png", fcopy_rsc(map_path(z)))
diff --git a/code/controllers/subsystem/persistence.dm b/code/controllers/subsystem/persistence.dm
index df7121455c..22d0315487 100644
--- a/code/controllers/subsystem/persistence.dm
+++ b/code/controllers/subsystem/persistence.dm
@@ -22,47 +22,54 @@ SUBSYSTEM_DEF(persistence)
/datum/controller/subsystem/persistence/proc/LoadSatchels()
var/placed_satchel = 0
var/path
- var/obj/item/storage/backpack/satchel/flat/F = new()
- if(fexists("data/npc_saves/SecretSatchels.sav")) //legacy compatability to convert old format to new
+ if(fexists("data/npc_saves/SecretSatchels.sav")) //legacy conversion. Will only ever run once.
var/savefile/secret_satchels = new /savefile("data/npc_saves/SecretSatchels.sav")
- var/sav_text
- secret_satchels[SSmapping.config.map_name] >> sav_text
- fdel("data/npc_saves/SecretSatchels.sav")
- if(sav_text)
- old_secret_satchels = splittext(sav_text,"#")
- if(old_secret_satchels.len >= 20)
- var/satchel_string = pick_n_take(old_secret_satchels)
+ for(var/map in secret_satchels)
+ var/json_file = file("data/npc_saves/SecretSatchels[map].json")
+ var/list/legacy_secret_satchels = splittext(secret_satchels[map],"#")
+ var/list/satchels = list()
+ for(var/i=1,i<=legacy_secret_satchels.len,i++)
+ var/satchel_string = legacy_secret_satchels[i]
var/list/chosen_satchel = splittext(satchel_string,"|")
if(chosen_satchel.len == 3)
- F.x = text2num(chosen_satchel[1])
- F.y = text2num(chosen_satchel[2])
- F.z = ZLEVEL_STATION_PRIMARY
- path = text2path(chosen_satchel[3])
- else
- var/json_file = file("data/npc_saves/SecretSatchels[SSmapping.config.map_name].json")
- if(!fexists(json_file))
- return
- var/list/json = json_decode(file2text(json_file))
- old_secret_satchels = json["data"]
- if(old_secret_satchels.len)
- if(old_secret_satchels.len >= 20) //guards against low drop pools assuring that one player cannot reliably find his own gear.
- var/pos = rand(1, old_secret_satchels.len)
- old_secret_satchels.Cut(pos, pos+1)
- F.x = old_secret_satchels[pos]["x"]
- F.y = old_secret_satchels[pos]["y"]
- F.z = ZLEVEL_STATION_PRIMARY
- path = text2path(old_secret_satchels[pos]["saved_obj"])
- if(!ispath(path))
- return
- if(isfloorturf(F.loc) && !istype(F.loc, /turf/open/floor/plating/))
- F.hide(1)
- new path(F)
- placed_satchel++
- var/list/free_satchels = list()
+ var/list/data = list()
+ data["x"] = text2num(chosen_satchel[1])
+ data["y"] = text2num(chosen_satchel[2])
+ data["saved_obj"] = chosen_satchel[3]
+ satchels += list(data)
+ var/list/file_data = list()
+ file_data["data"] = satchels
+ WRITE_FILE(json_file, json_encode(file_data))
+ fdel("data/npc_saves/SecretSatchels.sav")
+
+ var/json_file = file("data/npc_saves/SecretSatchels[SSmapping.config.map_name].json")
+ var/list/json = list()
+ if(fexists(json_file))
+ json = json_decode(file2text(json_file))
+
+ old_secret_satchels = json["data"]
+ var/obj/item/storage/backpack/satchel/flat/F
+ if(old_secret_satchels && old_secret_satchels.len >= 10) //guards against low drop pools assuring that one player cannot reliably find his own gear.
+ var/pos = rand(1, old_secret_satchels.len)
+ F = new()
+ old_secret_satchels.Cut(pos, pos+1 % old_secret_satchels.len)
+ F.x = old_secret_satchels[pos]["x"]
+ F.y = old_secret_satchels[pos]["y"]
+ F.z = ZLEVEL_STATION_PRIMARY
+ path = text2path(old_secret_satchels[pos]["saved_obj"])
+
+ if(F)
+ if(isfloorturf(F.loc) && !istype(F.loc, /turf/open/floor/plating/))
+ F.hide(1)
+ if(ispath(path))
+ new path(F)
+ placed_satchel++
+ var/free_satchels = 0
for(var/turf/T in shuffle(block(locate(TRANSITIONEDGE,TRANSITIONEDGE,ZLEVEL_STATION_PRIMARY), locate(world.maxx-TRANSITIONEDGE,world.maxy-TRANSITIONEDGE,ZLEVEL_STATION_PRIMARY)))) //Nontrivially expensive but it's roundstart only
if(isfloorturf(T) && !istype(T, /turf/open/floor/plating/))
- free_satchels += new /obj/item/storage/backpack/satchel/flat/secret(T)
- if(!isemptylist(free_satchels) && ((free_satchels.len + placed_satchel) >= (50 - old_secret_satchels.len) * 0.1)) //up to six tiles, more than enough to kill anything that moves
+ new /obj/item/storage/backpack/satchel/flat/secret(T)
+ free_satchels++
+ if((free_satchels + placed_satchel) == 10) //ten tiles, more than enough to kill anything that moves
break
/datum/controller/subsystem/persistence/proc/LoadPoly()
@@ -176,8 +183,8 @@ SUBSYSTEM_DEF(persistence)
CollectRoundtype()
/datum/controller/subsystem/persistence/proc/CollectSecretSatchels()
- var/list/satchels = list()
satchel_blacklist = typecacheof(list(/obj/item/stack/tile/plasteel, /obj/item/crowbar))
+ var/list/satchels_to_add = list()
for(var/A in new_secret_satchels)
var/obj/item/storage/backpack/satchel/flat/F = A
if(QDELETED(F) || F.z != ZLEVEL_STATION_PRIMARY || F.invisibility != INVISIBILITY_MAXIMUM)
@@ -196,11 +203,12 @@ SUBSYSTEM_DEF(persistence)
data["x"] = F.x
data["y"] = F.y
data["saved_obj"] = pick(savable_obj)
- satchels += list(data)
+ satchels_to_add += list(data)
+
var/json_file = file("data/npc_saves/SecretSatchels[SSmapping.config.map_name].json")
var/list/file_data = list()
- file_data["data"] = satchels
fdel(json_file)
+ file_data["data"] = old_secret_satchels + satchels_to_add
WRITE_FILE(json_file, json_encode(file_data))
/datum/controller/subsystem/persistence/proc/CollectChiselMessages()
diff --git a/code/controllers/subsystem/server_maint.dm b/code/controllers/subsystem/server_maint.dm
index 87b06cd587..0b8fa750b6 100644
--- a/code/controllers/subsystem/server_maint.dm
+++ b/code/controllers/subsystem/server_maint.dm
@@ -10,7 +10,7 @@ SUBSYSTEM_DEF(server_maint)
var/list/currentrun
/datum/controller/subsystem/server_maint/Initialize(timeofday)
- if (config.hub)
+ if (CONFIG_GET(flag/hub))
world.update_hub_visibility(TRUE)
..()
@@ -21,16 +21,19 @@ SUBSYSTEM_DEF(server_maint)
var/list/currentrun = src.currentrun
var/round_started = SSticker.HasRoundStarted()
+ var/kick_inactive = CONFIG_GET(flag/kick_inactive)
+ var/afk_period
+ if(kick_inactive)
+ afk_period = CONFIG_GET(number/afk_period)
for(var/I in currentrun)
var/client/C = I
//handle kicking inactive players
- if(round_started && config.kick_inactive)
- if(C.is_afk(config.afk_period))
- var/cmob = C.mob
- if(!(isobserver(cmob) || (isdead(cmob) && C.holder)))
- log_access("AFK: [key_name(C)]")
- to_chat(C, "You have been inactive for more than [DisplayTimeText(config.afk_period)] and have been disconnected. ")
- qdel(C)
+ if(round_started && kick_inactive && C.is_afk(afk_period))
+ var/cmob = C.mob
+ if(!(isobserver(cmob) || (isdead(cmob) && C.holder)))
+ log_access("AFK: [key_name(C)]")
+ to_chat(C, "You have been inactive for more than [DisplayTimeText(afk_period)] and have been disconnected. ")
+ qdel(C)
if (!(!C || world.time - C.connection_time < PING_BUFFER_TIME || C.inactivity >= (wait-1)))
winset(C, null, "command=.update_ping+[world.time+world.tick_lag*TICK_USAGE_REAL/100]")
@@ -40,7 +43,7 @@ SUBSYSTEM_DEF(server_maint)
/datum/controller/subsystem/server_maint/Shutdown()
kick_clients_in_lobby("The round came to an end with you in the lobby. ", TRUE) //second parameter ensures only afk clients are kicked
- var/server = config.server
+ var/server = CONFIG_GET(string/server)
for(var/thing in GLOB.clients)
if(!thing)
continue
diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm
index 2b1080049e..705f0dbd81 100644
--- a/code/controllers/subsystem/shuttle.dm
+++ b/code/controllers/subsystem/shuttle.dm
@@ -176,9 +176,9 @@ SUBSYSTEM_DEF(shuttle)
Good luck.")
return
emergency = backup_shuttle
-
- if(world.time - SSticker.round_start_time < config.shuttle_refuel_delay)
- to_chat(user, "The emergency shuttle is refueling. Please wait [DisplayTimeText((world.time - SSticker.round_start_time) - config.shuttle_refuel_delay)] before trying again.")
+ var/srd = CONFIG_GET(number/shuttle_refuel_delay)
+ if(world.time - SSticker.round_start_time < srd)
+ to_chat(user, "The emergency shuttle is refueling. Please wait [DisplayTimeText(srd - (world.time - SSticker.round_start_time))] before trying again.")
return
switch(emergency.mode)
diff --git a/code/controllers/subsystem/squeak.dm b/code/controllers/subsystem/squeak.dm
index 964d970e2b..0148011e8b 100644
--- a/code/controllers/subsystem/squeak.dm
+++ b/code/controllers/subsystem/squeak.dm
@@ -10,7 +10,7 @@ SUBSYSTEM_DEF(squeak)
var/list/exposed_wires = list()
/datum/controller/subsystem/squeak/Initialize(timeofday)
- trigger_migration(config.mice_roundstart)
+ trigger_migration(CONFIG_GET(number/mice_roundstart))
return ..()
/datum/controller/subsystem/squeak/proc/trigger_migration(num_mice=10)
diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm
index 3932eada60..060fe93219 100755
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -79,16 +79,18 @@ SUBSYSTEM_DEF(ticker)
if(!GLOB.syndicate_code_response)
GLOB.syndicate_code_response = generate_code_phrase()
..()
- start_at = world.time + (config.lobby_countdown * 10)
+ start_at = world.time + (CONFIG_GET(number/lobby_countdown) * 10)
/datum/controller/subsystem/ticker/fire()
switch(current_state)
if(GAME_STATE_STARTUP)
if(Master.initializations_finished_with_no_players_logged_in)
- start_at = world.time + (config.lobby_countdown * 10)
+ start_at = world.time + (CONFIG_GET(number/lobby_countdown) * 10)
for(var/client/C in GLOB.clients)
window_flash(C, ignorepref = TRUE) //let them know lobby has opened up.
to_chat(world, "Welcome to [station_name()]! ")
+ if(CONFIG_GET(flag/irc_announce_new_game))
+ SERVER_TOOLS_CHAT_BROADCAST("New round starting on [SSmapping.config.map_name]!")
current_state = GAME_STATE_PREGAME
//Everyone who wants to be an observer is now spawned
create_observers()
@@ -207,7 +209,7 @@ SUBSYSTEM_DEF(ticker)
else
mode.announce()
- if(!config.ooc_during_round)
+ if(!CONFIG_GET(flag/ooc_during_round))
toggle_ooc(FALSE) // Turn it off
CHECK_TICK
@@ -333,6 +335,8 @@ SUBSYSTEM_DEF(ticker)
var/num_shuttle_escapees = 0
to_chat(world, "The round has ended. ")
+ if(LAZYLEN(GLOB.round_end_notifiees))
+ send2irc("Notice", "[GLOB.round_end_notifiees.Join(", ")] the round has ended.")
/* var/nocredits = config.no_credits_round_end
for(var/client/C in GLOB.clients)
@@ -429,7 +433,7 @@ SUBSYSTEM_DEF(ticker)
CHECK_TICK
- if(config.cross_allowed)
+ if(CONFIG_GET(string/cross_server_address))
send_news_report()
CHECK_TICK
@@ -495,7 +499,8 @@ SUBSYSTEM_DEF(ticker)
to_chat(world, "Tip of the round: [html_encode(m)] ")
/datum/controller/subsystem/ticker/proc/check_queue()
- if(!queued_players.len || !config.hard_popcap)
+ var/hpc = CONFIG_GET(number/hard_popcap)
+ if(!queued_players.len || !hpc)
return
queue_delay++
@@ -503,7 +508,7 @@ SUBSYSTEM_DEF(ticker)
switch(queue_delay)
if(5) //every 5 ticks check if there is a slot available
- if(living_player_count() < config.hard_popcap)
+ if(living_player_count() < hpc)
if(next_in_line && next_in_line.client)
to_chat(next_in_line, "A slot has opened! You have approximately 20 seconds to join. \>\>Join Game\<\< ")
SEND_SOUND(next_in_line, sound('sound/misc/notice1.ogg'))
@@ -517,7 +522,7 @@ SUBSYSTEM_DEF(ticker)
queue_delay = 0
/datum/controller/subsystem/ticker/proc/check_maprotate()
- if (!config.maprotation)
+ if (!CONFIG_GET(flag/maprotation))
return
if (SSshuttle.emergency && SSshuttle.emergency.mode != SHUTTLE_ESCAPE || SSshuttle.canRecall())
return
@@ -527,7 +532,7 @@ SUBSYSTEM_DEF(ticker)
maprotatechecked = 1
//map rotate chance defaults to 75% of the length of the round (in minutes)
- if (!prob((world.time/600)*config.maprotatechancedelta))
+ if (!prob((world.time/600)*CONFIG_GET(number/maprotatechancedelta)))
return
INVOKE_ASYNC(SSmapping, /datum/controller/subsystem/mapping/.proc/maprotate)
@@ -687,7 +692,7 @@ SUBSYSTEM_DEF(ticker)
return
if(!delay)
- delay = config.round_end_countdown * 10
+ delay = CONFIG_GET(number/round_end_countdown) * 10
var/skip_delay = check_rights()
if(delay_end && !skip_delay)
diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm
index 0ea16b32d8..d377329312 100644
--- a/code/controllers/subsystem/vote.dm
+++ b/code/controllers/subsystem/vote.dm
@@ -18,7 +18,7 @@ SUBSYSTEM_DEF(vote)
/datum/controller/subsystem/vote/fire() //called by master_controller
if(mode)
- time_remaining = round((started_time + config.vote_period - world.time)/10)
+ time_remaining = round((started_time + CONFIG_GET(number/vote_period) - world.time)/10)
if(time_remaining < 0)
result()
@@ -54,7 +54,7 @@ SUBSYSTEM_DEF(vote)
if(votes > greatest_votes)
greatest_votes = votes
//default-vote for everyone who didn't vote
- if(!config.vote_no_default && choices.len)
+ if(!CONFIG_GET(flag/default_no_vote) && choices.len)
var/list/non_voters = GLOB.directory.Copy()
non_voters -= voted
for (var/non_voter_ckey in non_voters)
@@ -146,7 +146,7 @@ SUBSYSTEM_DEF(vote)
/datum/controller/subsystem/vote/proc/submit_vote(vote)
if(mode)
- if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder)
+ if(CONFIG_GET(flag/no_dead_vote) && usr.stat == DEAD && !usr.client.holder)
return 0
if(!(usr.ckey in voted))
if(vote && 1<=vote && vote<=choices.len)
@@ -158,7 +158,7 @@ SUBSYSTEM_DEF(vote)
/datum/controller/subsystem/vote/proc/initiate_vote(vote_type, initiator_key)
if(!mode)
if(started_time)
- var/next_allowed_time = (started_time + config.vote_delay)
+ var/next_allowed_time = (started_time + CONFIG_GET(number/vote_delay))
if(mode)
to_chat(usr, "There is already a vote in progress! please wait for it to finish. ")
return 0
@@ -198,8 +198,9 @@ SUBSYSTEM_DEF(vote)
if(mode == "custom")
text += "\n[question]"
log_vote(text)
- to_chat(world, "\n[text] \nType vote or click here to place your votes.\nYou have [DisplayTimeText(config.vote_period)] to vote. ")
- time_remaining = round(config.vote_period/10)
+ var/vp = CONFIG_GET(number/vote_period)
+ to_chat(world, "\n[text] \nType vote or click here to place your votes.\nYou have [DisplayTimeText(vp)] to vote. ")
+ time_remaining = round(vp/10)
for(var/c in GLOB.clients)
var/client/C = c
var/datum/action/vote/V = new
@@ -238,20 +239,22 @@ SUBSYSTEM_DEF(vote)
else
. += "Start a vote: "
//restart
- if(trialmin || config.allow_vote_restart)
+ var/avr = CONFIG_GET(flag/allow_vote_restart)
+ if(trialmin || avr)
. += "Restart "
else
. += "Restart (Disallowed) "
if(trialmin)
- . += "\t([config.allow_vote_restart?"Allowed":"Disallowed"] )"
+ . += "\t([avr ? "Allowed" : "Disallowed"] )"
. += " "
//gamemode
- if(trialmin || config.allow_vote_mode)
+ var/avm = CONFIG_GET(flag/allow_vote_mode)
+ if(trialmin || avm)
. += "GameMode "
else
. += "GameMode (Disallowed) "
if(trialmin)
- . += "\t([config.allow_vote_mode?"Allowed":"Disallowed"] )"
+ . += "\t([avm ? "Allowed" : "Disallowed"] )"
. += " "
//custom
@@ -275,15 +278,15 @@ SUBSYSTEM_DEF(vote)
reset()
if("toggle_restart")
if(usr.client.holder)
- config.allow_vote_restart = !config.allow_vote_restart
+ CONFIG_SET(flag/allow_vote_restart, !CONFIG_GET(flag/allow_vote_restart))
if("toggle_gamemode")
if(usr.client.holder)
- config.allow_vote_mode = !config.allow_vote_mode
+ CONFIG_SET(flag/allow_vote_mode, !CONFIG_GET(flag/allow_vote_mode))
if("restart")
- if(config.allow_vote_restart || usr.client.holder)
+ if(CONFIG_GET(flag/allow_vote_restart) || usr.client.holder)
initiate_vote("restart",usr.key)
if("gamemode")
- if(config.allow_vote_mode || usr.client.holder)
+ if(CONFIG_GET(flag/allow_vote_mode) || usr.client.holder)
initiate_vote("gamemode",usr.key)
if("custom")
if(usr.client.holder)
diff --git a/code/datums/action.dm b/code/datums/action.dm
index a65294fa40..cf1046ca8f 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -591,3 +591,50 @@
var/mob/M = owner
var/datum/language_holder/H = M.get_language_holder()
H.open_language_menu(usr)
+
+/datum/action/innate/dash
+ name = "Dash"
+ desc = "Teleport to the targeted location."
+ icon_icon = 'icons/mob/actions/actions_items.dmi'
+ button_icon_state = "jetboot"
+ var/charged = TRUE
+ var/charge_rate = 250
+ var/mob/living/carbon/human/holder
+ var/obj/item/dashing_item
+ var/dash_sound = 'sound/magic/blink.ogg'
+ var/recharge_sound = 'sound/magic/charge.ogg'
+ var/beam_effect = "blur"
+ var/phasein = /obj/effect/temp_visual/dir_setting/ninja/phase
+ var/phaseout = /obj/effect/temp_visual/dir_setting/ninja/phase/out
+
+/datum/action/innate/dash/Grant(mob/user, obj/dasher)
+ . = ..()
+ dashing_item = dasher
+ holder = user
+
+/datum/action/innate/dash/IsAvailable()
+ if(charged)
+ return TRUE
+ else
+ return FALSE
+
+/datum/action/innate/dash/Activate()
+ dashing_item.attack_self(holder) //Used to toggle dash behavior in the dashing item
+
+/datum/action/innate/dash/proc/Teleport(mob/user, atom/target)
+ var/turf/T = get_turf(target)
+ if(target in view(user.client.view, get_turf(user)))
+ var/obj/spot1 = new phaseout(get_turf(user), user.dir)
+ user.forceMove(T)
+ playsound(T, dash_sound, 25, 1)
+ var/obj/spot2 = new phasein(get_turf(user), user.dir)
+ spot1.Beam(spot2,beam_effect,time=20)
+ charged = FALSE
+ holder.update_action_buttons_icon()
+ addtimer(CALLBACK(src, .proc/charge), charge_rate)
+
+/datum/action/innate/dash/proc/charge()
+ charged = TRUE
+ holder.update_action_buttons_icon()
+ playsound(dashing_item, recharge_sound, 50, 1)
+ to_chat(holder, "[dashing_item] is ready for another jaunt. ")
\ No newline at end of file
diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm
index 2222a959bc..8d86507271 100644
--- a/code/datums/ai_laws.dm
+++ b/code/datums/ai_laws.dm
@@ -208,7 +208,8 @@
/* General ai_law functions */
/datum/ai_laws/proc/set_laws_config()
- switch(config.default_laws)
+ var/list/law_ids = CONFIG_GET(keyed_flag_list/random_laws)
+ switch(CONFIG_GET(number/default_laws))
if(0)
add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.")
add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.")
@@ -220,7 +221,7 @@
var/list/randlaws = list()
for(var/lpath in subtypesof(/datum/ai_laws))
var/datum/ai_laws/L = lpath
- if(initial(L.id) in config.lawids)
+ if(initial(L.id) in law_ids)
randlaws += lpath
var/datum/ai_laws/lawtype
if(randlaws.len)
@@ -234,21 +235,14 @@
if(3)
pick_weighted_lawset()
- else:
- log_law("Invalid law config. Please check silicon_laws.txt")
- add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.")
- add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.")
- add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.")
- WARNING("Invalid custom AI laws, check silicon_laws.txt")
-
/datum/ai_laws/proc/pick_weighted_lawset()
var/datum/ai_laws/lawtype
-
- while(!lawtype && config.law_weights.len)
- var/possible_id = pickweight(config.law_weights)
+ var/list/law_weights = CONFIG_GET(keyed_number_list/law_weight)
+ while(!lawtype && law_weights.len)
+ var/possible_id = pickweight(law_weights)
lawtype = lawid_to_type(possible_id)
if(!lawtype)
- config.law_weights -= possible_id
+ law_weights -= possible_id
WARNING("Bad lawid in game_options.txt: [possible_id]")
if(!lawtype)
diff --git a/code/datums/antagonists/datum_traitor.dm b/code/datums/antagonists/datum_traitor.dm
index eeb803ca1e..83b61e4cda 100644
--- a/code/datums/antagonists/datum_traitor.dm
+++ b/code/datums/antagonists/datum_traitor.dm
@@ -85,7 +85,7 @@
if(owner.assigned_role == "Clown")
var/mob/living/carbon/human/traitor_mob = owner.current
if(traitor_mob&&istype(traitor_mob))
- if(!silent)
+ if(!silent)
to_chat(traitor_mob, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.")
traitor_mob.dna.remove_mutation(CLOWNMUT)
@@ -138,10 +138,11 @@
assign_exchange_role(SSticker.mode.exchange_red)
assign_exchange_role(SSticker.mode.exchange_blue)
objective_count += 1 //Exchange counts towards number of objectives
- for(var/i = objective_count, i < config.traitor_objectives_amount, i++)
+ var/toa = CONFIG_GET(number/traitor_objectives_amount)
+ for(var/i = objective_count, i < toa, i++)
forge_single_objective()
- if(is_hijacker && objective_count <= config.traitor_objectives_amount) //Don't assign hijack if it would exceed the number of objectives set in config.traitor_objectives_amount
+ if(is_hijacker && objective_count <= toa) //Don't assign hijack if it would exceed the number of objectives set in config.traitor_objectives_amount
if (!(locate(/datum/objective/hijack) in owner.objectives))
var/datum/objective/hijack/hijack_objective = new
hijack_objective.owner = owner
@@ -173,18 +174,11 @@
if(prob(30))
objective_count += forge_single_objective()
-
- for(var/i = objective_count, i < config.traitor_objectives_amount, i++)
- if(prob(20)) //AI's are less likely to look for a late-joiner than normal traitors
- var/datum/objective/assassinate/late/late_objective = new
- late_objective.owner = owner
- late_objective.find_target()
- add_objective(late_objective)
- else
- var/datum/objective/assassinate/kill_objective = new
- kill_objective.owner = owner
- kill_objective.find_target()
- add_objective(kill_objective)
+ for(var/i = objective_count, i < CONFIG_GET(number/traitor_objectives_amount), i++)
+ var/datum/objective/assassinate/kill_objective = new
+ kill_objective.owner = owner
+ kill_objective.find_target()
+ add_objective(kill_objective)
var/datum/objective/survive/exist/exist_objective = new
exist_objective.owner = owner
@@ -216,10 +210,16 @@
kill_objective.find_target()
add_objective(kill_objective)
else
- var/datum/objective/steal/steal_objective = new
- steal_objective.owner = owner
- steal_objective.find_target()
- add_objective(steal_objective)
+ if(prob(15) && !(locate(/datum/objective/download in owner.objectives)))
+ var/datum/objective/download/download_objective = new
+ download_objective.owner = owner
+ download_objective.gen_amount_goal()
+ add_objective(download_objective)
+ else
+ var/datum/objective/steal/steal_objective = new
+ steal_objective.owner = owner
+ steal_objective.find_target()
+ add_objective(steal_objective)
/datum/antagonist/traitor/AI/forge_single_objective()
.=1
diff --git a/code/datums/antagonists/devil.dm b/code/datums/antagonists/devil.dm
index 14c92f3263..f66fc5a3b2 100644
--- a/code/datums/antagonists/devil.dm
+++ b/code/datums/antagonists/devil.dm
@@ -205,7 +205,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
/datum/antagonist/devil/proc/regress_blood_lizard()
var/mob/living/carbon/true_devil/D = owner.current
to_chat(D, "Your powers weaken, have more contracts be signed to regain power. ")
- D.oldform.loc = D.loc
+ D.oldform.forceMove(D.drop_location())
owner.transfer_to(D.oldform)
give_appropriate_spells()
qdel(D)
@@ -236,7 +236,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
sleep(50)
var/mob/living/carbon/true_devil/A = new /mob/living/carbon/true_devil(owner.current.loc)
A.faction |= "hell"
- owner.current.loc = A
+ owner.current.forceMove(A)
A.oldform = owner.current
owner.transfer_to(A)
A.set_name()
diff --git a/code/datums/components/material_container.dm b/code/datums/components/material_container.dm
index c790dcc1aa..d4b75e3892 100644
--- a/code/datums/components/material_container.dm
+++ b/code/datums/components/material_container.dm
@@ -17,6 +17,7 @@
var/show_on_examine
var/list/allowed_typecache
var/last_inserted_type
+ var/last_inserted_id
var/last_amount_inserted
var/last_insert_success
var/datum/callback/precondition
@@ -116,7 +117,7 @@
if(!amt)
return 0
- insert_materials(S,amt)
+ last_inserted_id = insert_materials(S,amt)
last_inserted_type = S.type
S.use(amt)
last_amount_inserted = amt
@@ -133,17 +134,22 @@
if(!material_amount || !has_space(material_amount))
return 0
- insert_materials(I, multiplier)
+ last_inserted_id = insert_materials(I, multiplier)
last_inserted_type = I.type
last_amount_inserted = material_amount
return material_amount
/datum/component/material_container/proc/insert_materials(obj/item/I, multiplier = 1) //for internal usage only
var/datum/material/M
+ var/primary_mat
+ var/max_mat_value = 0
for(var/MAT in materials)
M = materials[MAT]
M.amount += I.materials[MAT] * multiplier
total_amount += I.materials[MAT] * multiplier
+ if(I.materials[MAT] > max_mat_value)
+ primary_mat = MAT
+ return primary_mat
//For consuming material
//mats is a list of types of material to use and the corresponding amounts, example: list(MAT_METAL=100, MAT_GLASS=200)
diff --git a/code/datums/components/squeek.dm b/code/datums/components/squeek.dm
index ebc9cf0434..7b9a7866ca 100644
--- a/code/datums/components/squeek.dm
+++ b/code/datums/components/squeek.dm
@@ -24,7 +24,7 @@
if(use_delay_override)
use_delay = use_delay_override
- RegisterSignal(list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_BLOB_ACT, COMSIG_ATOM_HULK_ATTACK, COMSIG_PARENT_ATTACKBY, COMSIG_MOVABLE_CROSSED, COMSIG_MOVABLE_COLLIDE, COMSIG_MOVABLE_IMPACT, COMSIG_ITEM_ATTACK, COMSIG_ITEM_ATTACK_OBJ, COMSIG_ITEM_ATTACK_OBJ), .proc/play_squeak)
+ RegisterSignal(list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_BLOB_ACT, COMSIG_ATOM_HULK_ATTACK, COMSIG_PARENT_ATTACKBY, COMSIG_MOVABLE_CROSSED, COMSIG_MOVABLE_COLLIDE, COMSIG_MOVABLE_IMPACT, COMSIG_ITEM_ATTACK, COMSIG_ITEM_ATTACK_OBJ), .proc/play_squeak)
RegisterSignal(COMSIG_ITEM_ATTACK_SELF, .proc/use_squeak)
RegisterSignal(COMSIG_SHOES_STEP_ACTION, .proc/step_squeak)
diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm
index b20381ca85..299f6dbac9 100644
--- a/code/datums/datacore.dm
+++ b/code/datums/datacore.dm
@@ -222,7 +222,7 @@
G.fields["name"] = H.real_name
G.fields["rank"] = assignment
G.fields["age"] = H.age
- if(config.mutant_races)
+ if(CONFIG_GET(flag/join_with_mutant_race))
G.fields["species"] = H.dna.species.name
G.fields["fingerprint"] = md5(H.dna.uni_identity)
G.fields["p_stat"] = "Active"
diff --git a/code/datums/diseases/_MobProcs.dm b/code/datums/diseases/_MobProcs.dm
index 1d3e7f2a12..a00d43ad8f 100644
--- a/code/datums/diseases/_MobProcs.dm
+++ b/code/datums/diseases/_MobProcs.dm
@@ -43,7 +43,7 @@
SSdisease.active_diseases += DD //Add it to the active diseases list, now that it's actually in a mob and being processed.
//Copy properties over. This is so edited diseases persist.
- var/list/skipped = list("affected_mob","holder","carrier","stage","type","parent_type","vars","transformed","symptoms")
+ var/list/skipped = list("affected_mob","holder","carrier","stage","type","parent_type","vars","transformed","symptoms","processing")
for(var/V in DD.vars)
if(V in skipped)
continue
diff --git a/code/datums/diseases/advance/symptoms/viral.dm b/code/datums/diseases/advance/symptoms/viral.dm
index 539c57c92e..ef8822470e 100644
--- a/code/datums/diseases/advance/symptoms/viral.dm
+++ b/code/datums/diseases/advance/symptoms/viral.dm
@@ -68,8 +68,8 @@ Bonus
/datum/symptom/viralreverse
name = "Viral aggressive metabolism"
- desc = "The virus sacrifices its long term survivability to gain a near-instant spread when inside a host. \
- The virus will start at the lastest stage, but will eventually decay and die off by itself."
+ desc = "The virus sacrifices its long term survivability to nearly instantly fully spread inside a host. \
+ The virus will start at the last stage, but will eventually decay and die off by itself."
stealth = -2
resistance = 1
stage_speed = 3
diff --git a/code/datums/diseases/parrotpossession.dm b/code/datums/diseases/parrotpossession.dm
index 0df7e0f7d3..a5d87be980 100644
--- a/code/datums/diseases/parrotpossession.dm
+++ b/code/datums/diseases/parrotpossession.dm
@@ -22,6 +22,6 @@
/datum/disease/parrot_possession/cure()
if(parrot && parrot.loc == affected_mob)
- parrot.loc = affected_mob.loc
+ parrot.forceMove(affected_mob.drop_location())
affected_mob.visible_message("[parrot] is violently driven out of [affected_mob]! ", "[parrot] bursts out of your chest! ")
..()
\ No newline at end of file
diff --git a/code/datums/diseases/wizarditis.dm b/code/datums/diseases/wizarditis.dm
index fbdb107c83..66663162ee 100644
--- a/code/datums/diseases/wizarditis.dm
+++ b/code/datums/diseases/wizarditis.dm
@@ -1,115 +1,115 @@
-/datum/disease/wizarditis
- name = "Wizarditis"
- max_stages = 4
- spread_text = "Airborne"
- cure_text = "The Manly Dorf"
- cures = list("manlydorf")
- cure_chance = 100
- agent = "Rincewindus Vulgaris"
- viable_mobtypes = list(/mob/living/carbon/human)
- disease_flags = CAN_CARRY|CAN_RESIST|CURABLE
- permeability_mod = 0.75
- desc = "Some speculate that this virus is the cause of the Space Wizard Federation's existence. Subjects affected show the signs of mental retardation, yelling obscure sentences or total gibberish. On late stages subjects sometime express the feelings of inner power, and, cite, 'the ability to control the forces of cosmos themselves!' A gulp of strong, manly spirits usually reverts them to normal, humanlike, condition."
- severity = HARMFUL
- required_organs = list(/obj/item/bodypart/head)
-
-/*
-BIRUZ BENNAR
-SCYAR NILA - teleport
-NEC CANTIO - dis techno
-EI NATH - shocking grasp
-AULIE OXIN FIERA - knock
-TARCOL MINTI ZHERI - forcewall
-STI KALY - blind
-*/
-
-/datum/disease/wizarditis/stage_act()
- ..()
-
- switch(stage)
- if(2)
- if(prob(1)&&prob(50))
- affected_mob.say(pick("You shall not pass!", "Expeliarmus!", "By Merlins beard!", "Feel the power of the Dark Side!"))
- if(prob(1)&&prob(50))
- to_chat(affected_mob, "You feel [pick("that you don't have enough mana", "that the winds of magic are gone", "an urge to summon familiar")]. ")
-
-
- if(3)
- if(prob(1)&&prob(50))
- affected_mob.say(pick("NEC CANTIO!","AULIE OXIN FIERA!", "STI KALY!", "TARCOL MINTI ZHERI!"))
- if(prob(1)&&prob(50))
- to_chat(affected_mob, "You feel [pick("the magic bubbling in your veins","that this location gives you a +1 to INT","an urge to summon familiar")]. ")
-
- if(4)
-
- if(prob(1))
- affected_mob.say(pick("NEC CANTIO!","AULIE OXIN FIERA!","STI KALY!","EI NATH!"))
- return
- if(prob(1)&&prob(50))
- to_chat(affected_mob, "You feel [pick("the tidal wave of raw power building inside","that this location gives you a +2 to INT and +1 to WIS","an urge to teleport")]. ")
- spawn_wizard_clothes(50)
- if(prob(1)&&prob(1))
- teleport()
- return
-
-
-
-/datum/disease/wizarditis/proc/spawn_wizard_clothes(chance = 0)
- if(ishuman(affected_mob))
- var/mob/living/carbon/human/H = affected_mob
- if(prob(chance))
- if(!istype(H.head, /obj/item/clothing/head/wizard))
- if(!H.dropItemToGround(H.head))
- qdel(H.head)
- H.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(H), slot_head)
- return
- if(prob(chance))
- if(!istype(H.wear_suit, /obj/item/clothing/suit/wizrobe))
- if(!H.dropItemToGround(H.wear_suit))
- qdel(H.wear_suit)
- H.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(H), slot_wear_suit)
- return
- if(prob(chance))
- if(!istype(H.shoes, /obj/item/clothing/shoes/sandal/magic))
- if(!H.dropItemToGround(H.shoes))
- qdel(H.shoes)
- H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal/magic(H), slot_shoes)
- return
- else
- var/mob/living/carbon/H = affected_mob
- if(prob(chance))
- var/obj/item/staff/S = new(H)
- if(!H.put_in_hands(S))
- qdel(S)
-
-
-/datum/disease/wizarditis/proc/teleport()
- var/list/theareas = get_areas_in_range(80, affected_mob)
- for(var/area/space/S in theareas)
- theareas -= S
-
- if(!theareas||!theareas.len)
- return
-
- var/area/thearea = pick(theareas)
-
- var/list/L = list()
- for(var/turf/T in get_area_turfs(thearea.type))
- if(T.z != affected_mob.z) continue
- if(T.name == "space") continue
- if(!T.density)
- var/clear = 1
- for(var/obj/O in T)
- if(O.density)
- clear = 0
- break
- if(clear)
- L+=T
-
- if(!L)
- return
-
- affected_mob.say("SCYAR NILA [uppertext(thearea.name)]!")
- affected_mob.loc = pick(L)
-
- return
+/datum/disease/wizarditis
+ name = "Wizarditis"
+ max_stages = 4
+ spread_text = "Airborne"
+ cure_text = "The Manly Dorf"
+ cures = list("manlydorf")
+ cure_chance = 100
+ agent = "Rincewindus Vulgaris"
+ viable_mobtypes = list(/mob/living/carbon/human)
+ disease_flags = CAN_CARRY|CAN_RESIST|CURABLE
+ permeability_mod = 0.75
+ desc = "Some speculate that this virus is the cause of the Space Wizard Federation's existence. Subjects affected show the signs of mental retardation, yelling obscure sentences or total gibberish. On late stages subjects sometime express the feelings of inner power, and, cite, 'the ability to control the forces of cosmos themselves!' A gulp of strong, manly spirits usually reverts them to normal, humanlike, condition."
+ severity = HARMFUL
+ required_organs = list(/obj/item/bodypart/head)
+
+/*
+BIRUZ BENNAR
+SCYAR NILA - teleport
+NEC CANTIO - dis techno
+EI NATH - shocking grasp
+AULIE OXIN FIERA - knock
+TARCOL MINTI ZHERI - forcewall
+STI KALY - blind
+*/
+
+/datum/disease/wizarditis/stage_act()
+ ..()
+
+ switch(stage)
+ if(2)
+ if(prob(1)&&prob(50))
+ affected_mob.say(pick("You shall not pass!", "Expeliarmus!", "By Merlins beard!", "Feel the power of the Dark Side!"))
+ if(prob(1)&&prob(50))
+ to_chat(affected_mob, "You feel [pick("that you don't have enough mana", "that the winds of magic are gone", "an urge to summon familiar")]. ")
+
+
+ if(3)
+ if(prob(1)&&prob(50))
+ affected_mob.say(pick("NEC CANTIO!","AULIE OXIN FIERA!", "STI KALY!", "TARCOL MINTI ZHERI!"))
+ if(prob(1)&&prob(50))
+ to_chat(affected_mob, "You feel [pick("the magic bubbling in your veins","that this location gives you a +1 to INT","an urge to summon familiar")]. ")
+
+ if(4)
+
+ if(prob(1))
+ affected_mob.say(pick("NEC CANTIO!","AULIE OXIN FIERA!","STI KALY!","EI NATH!"))
+ return
+ if(prob(1)&&prob(50))
+ to_chat(affected_mob, "You feel [pick("the tidal wave of raw power building inside","that this location gives you a +2 to INT and +1 to WIS","an urge to teleport")]. ")
+ spawn_wizard_clothes(50)
+ if(prob(1)&&prob(1))
+ teleport()
+ return
+
+
+
+/datum/disease/wizarditis/proc/spawn_wizard_clothes(chance = 0)
+ if(ishuman(affected_mob))
+ var/mob/living/carbon/human/H = affected_mob
+ if(prob(chance))
+ if(!istype(H.head, /obj/item/clothing/head/wizard))
+ if(!H.dropItemToGround(H.head))
+ qdel(H.head)
+ H.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(H), slot_head)
+ return
+ if(prob(chance))
+ if(!istype(H.wear_suit, /obj/item/clothing/suit/wizrobe))
+ if(!H.dropItemToGround(H.wear_suit))
+ qdel(H.wear_suit)
+ H.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(H), slot_wear_suit)
+ return
+ if(prob(chance))
+ if(!istype(H.shoes, /obj/item/clothing/shoes/sandal/magic))
+ if(!H.dropItemToGround(H.shoes))
+ qdel(H.shoes)
+ H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal/magic(H), slot_shoes)
+ return
+ else
+ var/mob/living/carbon/H = affected_mob
+ if(prob(chance))
+ var/obj/item/staff/S = new(H)
+ if(!H.put_in_hands(S))
+ qdel(S)
+
+
+/datum/disease/wizarditis/proc/teleport()
+ var/list/theareas = get_areas_in_range(80, affected_mob)
+ for(var/area/space/S in theareas)
+ theareas -= S
+
+ if(!theareas||!theareas.len)
+ return
+
+ var/area/thearea = pick(theareas)
+
+ var/list/L = list()
+ for(var/turf/T in get_area_turfs(thearea.type))
+ if(T.z != affected_mob.z) continue
+ if(T.name == "space") continue
+ if(!T.density)
+ var/clear = 1
+ for(var/obj/O in T)
+ if(O.density)
+ clear = 0
+ break
+ if(clear)
+ L+=T
+
+ if(!L)
+ return
+
+ affected_mob.say("SCYAR NILA [uppertext(thearea.name)]!")
+ affected_mob.forceMove(pick(L))
+
+ return
diff --git a/code/datums/dna.dm b/code/datums/dna.dm
index 27a9338191..12555ee038 100644
--- a/code/datums/dna.dm
+++ b/code/datums/dna.dm
@@ -1,401 +1,398 @@
-
-/////////////////////////// DNA DATUM
-/datum/dna
- var/unique_enzymes
- var/struc_enzymes
- var/uni_identity
- var/blood_type
- var/datum/species/species = new /datum/species/human() //The type of mutant race the player is if applicable (i.e. potato-man)
- var/list/features = list("FFF") //first value is mutant color
- var/real_name //Stores the real name of the person who originally got this dna datum. Used primarely for changelings,
- var/list/mutations = list() //All mutations are from now on here
- var/list/temporary_mutations = list() //Timers for temporary mutations
- var/list/previous = list() //For temporary name/ui/ue/blood_type modifications
- var/mob/living/holder
-
-/datum/dna/New(mob/living/new_holder)
- if(new_holder)
- holder = new_holder
-
-/datum/dna/proc/transfer_identity(mob/living/carbon/destination, transfer_SE = 0)
- if(!istype(destination))
- return
- destination.dna.unique_enzymes = unique_enzymes
- destination.dna.uni_identity = uni_identity
- destination.dna.blood_type = blood_type
- destination.set_species(species.type, icon_update=0)
- destination.dna.features = features.Copy()
- destination.dna.real_name = real_name
- destination.dna.temporary_mutations = temporary_mutations.Copy()
- if(transfer_SE)
- destination.dna.struc_enzymes = struc_enzymes
- if(ishuman(destination))
- var/mob/living/carbon/human/H = destination
- H.give_genitals(TRUE)//This gives the body the genitals of this DNA. Used for any transformations based on DNA
- destination.flavor_text = destination.dna.features["flavor_text"] //Update the flavor_text to use new dna text
-
-/datum/dna/proc/copy_dna(datum/dna/new_dna)
- new_dna.unique_enzymes = unique_enzymes
- new_dna.struc_enzymes = struc_enzymes
- new_dna.uni_identity = uni_identity
- new_dna.blood_type = blood_type
- new_dna.features = features.Copy()
- new_dna.species = new species.type
- new_dna.real_name = real_name
- new_dna.mutations = mutations.Copy()
-
-/datum/dna/proc/add_mutation(mutation_name)
- var/datum/mutation/human/HM = GLOB.mutations_list[mutation_name]
- HM.on_acquiring(holder)
-
-/datum/dna/proc/remove_mutation(mutation_name)
- var/datum/mutation/human/HM = GLOB.mutations_list[mutation_name]
- HM.on_losing(holder)
-
-/datum/dna/proc/check_mutation(mutation_name)
- var/datum/mutation/human/HM = GLOB.mutations_list[mutation_name]
- return mutations.Find(HM)
-
-/datum/dna/proc/remove_all_mutations()
- remove_mutation_group(mutations)
-
-/datum/dna/proc/remove_mutation_group(list/group)
- if(!group)
- return
- for(var/datum/mutation/human/HM in group)
- HM.force_lose(holder)
-
-/datum/dna/proc/generate_uni_identity()
- . = ""
- var/list/L = new /list(DNA_UNI_IDENTITY_BLOCKS)
-
- L[DNA_GENDER_BLOCK] = construct_block((holder.gender!=MALE)+1, 2)
- if(ishuman(holder))
- var/mob/living/carbon/human/H = holder
- if(!GLOB.hair_styles_list.len)
- init_sprite_accessory_subtypes(/datum/sprite_accessory/hair,GLOB.hair_styles_list, GLOB.hair_styles_male_list, GLOB.hair_styles_female_list)
- L[DNA_HAIR_STYLE_BLOCK] = construct_block(GLOB.hair_styles_list.Find(H.hair_style), GLOB.hair_styles_list.len)
- L[DNA_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.hair_color)
- if(!GLOB.facial_hair_styles_list.len)
- init_sprite_accessory_subtypes(/datum/sprite_accessory/facial_hair, GLOB.facial_hair_styles_list, GLOB.facial_hair_styles_male_list, GLOB.facial_hair_styles_female_list)
- L[DNA_FACIAL_HAIR_STYLE_BLOCK] = construct_block(GLOB.facial_hair_styles_list.Find(H.facial_hair_style), GLOB.facial_hair_styles_list.len)
- L[DNA_FACIAL_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.facial_hair_color)
- L[DNA_SKIN_TONE_BLOCK] = construct_block(GLOB.skin_tones.Find(H.skin_tone), GLOB.skin_tones.len)
- L[DNA_EYE_COLOR_BLOCK] = sanitize_hexcolor(H.eye_color)
-
- for(var/i=1, i<=DNA_UNI_IDENTITY_BLOCKS, i++)
- if(L[i])
- . += L[i]
- else
- . += random_string(DNA_BLOCK_SIZE,GLOB.hex_characters)
- return .
-
-/datum/dna/proc/generate_struc_enzymes()
- var/list/sorting = new /list(DNA_STRUC_ENZYMES_BLOCKS)
- var/result = ""
- for(var/datum/mutation/human/A in GLOB.good_mutations + GLOB.bad_mutations + GLOB.not_good_mutations)
- if(A.name == RACEMUT && ismonkey(holder))
- sorting[A.dna_block] = num2hex(A.lowest_value + rand(0, 256 * 6), DNA_BLOCK_SIZE)
- mutations |= A
- else
- sorting[A.dna_block] = random_string(DNA_BLOCK_SIZE, list("0","1","2","3","4","5","6"))
-
- for(var/B in sorting)
- result += B
- return result
-
-/datum/dna/proc/generate_unique_enzymes()
- . = ""
- if(istype(holder))
- real_name = holder.real_name
- . += md5(holder.real_name)
- else
- . += random_string(DNA_UNIQUE_ENZYMES_LEN, GLOB.hex_characters)
- return .
-
-/datum/dna/proc/update_ui_block(blocknumber)
- if(!blocknumber || !ishuman(holder))
- return
- var/mob/living/carbon/human/H = holder
- switch(blocknumber)
- if(DNA_HAIR_COLOR_BLOCK)
- setblock(uni_identity, blocknumber, sanitize_hexcolor(H.hair_color))
- if(DNA_FACIAL_HAIR_COLOR_BLOCK)
- setblock(uni_identity, blocknumber, sanitize_hexcolor(H.facial_hair_color))
- if(DNA_SKIN_TONE_BLOCK)
- setblock(uni_identity, blocknumber, construct_block(GLOB.skin_tones.Find(H.skin_tone), GLOB.skin_tones.len))
- if(DNA_EYE_COLOR_BLOCK)
- setblock(uni_identity, blocknumber, sanitize_hexcolor(H.eye_color))
- if(DNA_GENDER_BLOCK)
- setblock(uni_identity, blocknumber, construct_block((H.gender!=MALE)+1, 2))
- if(DNA_FACIAL_HAIR_STYLE_BLOCK)
- setblock(uni_identity, blocknumber, construct_block(GLOB.facial_hair_styles_list.Find(H.facial_hair_style), GLOB.facial_hair_styles_list.len))
- if(DNA_HAIR_STYLE_BLOCK)
- setblock(uni_identity, blocknumber, construct_block(GLOB.hair_styles_list.Find(H.hair_style), GLOB.hair_styles_list.len))
-
-/datum/dna/proc/mutations_say_mods(message)
- if(message)
- for(var/datum/mutation/human/M in mutations)
- message = M.say_mod(message)
- return message
-
-/datum/dna/proc/mutations_get_spans()
- var/list/spans = list()
- for(var/datum/mutation/human/M in mutations)
- spans |= M.get_spans()
- return spans
-
-/datum/dna/proc/species_get_spans()
- var/list/spans = list()
- if(species)
- spans |= species.get_spans()
- return spans
-
-
-/datum/dna/proc/is_same_as(datum/dna/D)
- if(uni_identity == D.uni_identity && struc_enzymes == D.struc_enzymes && real_name == D.real_name)
- if(species.type == D.species.type && features == D.features && blood_type == D.blood_type)
- return 1
- return 0
-
-//used to update dna UI, UE, and dna.real_name.
-/datum/dna/proc/update_dna_identity()
- uni_identity = generate_uni_identity()
- unique_enzymes = generate_unique_enzymes()
-
-/datum/dna/proc/initialize_dna(newblood_type)
- if(newblood_type)
- blood_type = newblood_type
- unique_enzymes = generate_unique_enzymes()
- uni_identity = generate_uni_identity()
- struc_enzymes = generate_struc_enzymes()
- features = random_features()
-
-
-/datum/dna/stored //subtype used by brain mob's stored_dna
-
-/datum/dna/stored/add_mutation(mutation_name) //no mutation changes on stored dna.
- return
-
-/datum/dna/stored/remove_mutation(mutation_name)
- return
-
-/datum/dna/stored/check_mutation(mutation_name)
- return
-
-/datum/dna/stored/remove_all_mutations()
- return
-
-/datum/dna/stored/remove_mutation_group(list/group)
- return
-
-/////////////////////////// DNA MOB-PROCS //////////////////////
-
-/mob/proc/set_species(datum/species/mrace, icon_update = 1)
- return
-
-/mob/living/brain/set_species(datum/species/mrace, icon_update = 1)
- if(mrace)
- if(ispath(mrace))
- stored_dna.species = new mrace()
- else
- stored_dna.species = mrace //not calling any species update procs since we're a brain, not a monkey/human
-
-
-/mob/living/carbon/set_species(datum/species/mrace, icon_update = 1)
- if(mrace && has_dna())
- dna.species.on_species_loss(src)
- var/old_species = dna.species
- if(ispath(mrace))
- dna.species = new mrace()
- else
- dna.species = mrace
- dna.species.on_species_gain(src, old_species)
-
-/mob/living/carbon/human/set_species(datum/species/mrace, icon_update = 1)
- ..()
- if(icon_update)
- update_body()
- update_hair()
- update_body_parts()
- update_mutations_overlay()// no lizard with human hulk overlay please.
-
-
-/mob/proc/has_dna()
- return
-
-/mob/living/carbon/has_dna()
- return dna
-
-
-/mob/living/carbon/human/proc/hardset_dna(ui, se, newreal_name, newblood_type, datum/species/mrace, newfeatures)
-
- if(newfeatures)
- dna.features = newfeatures
- flavor_text = dna.features["flavor_text"] //Update the flavor_text to use new dna text
-
- if(mrace)
- var/datum/species/newrace = new mrace.type
- newrace.copy_properties_from(mrace)
- set_species(newrace, icon_update=0)
-
- if(newreal_name)
- real_name = newreal_name
- dna.generate_unique_enzymes()
-
- if(newblood_type)
- dna.blood_type = newblood_type
-
- if(ui)
- dna.uni_identity = ui
- updateappearance(icon_update=0)
-
- if(se)
- dna.struc_enzymes = se
- domutcheck()
-
- give_genitals(TRUE)//Give all genitalia that DNA says you should have, remove any pre-existing ones as this is a hardset!
-
- if(mrace || newfeatures || ui)
- update_body()
- update_hair()
- update_body_parts()
- update_mutations_overlay()
-
-
-/mob/living/carbon/proc/create_dna()
- dna = new /datum/dna(src)
- if(!dna.species)
- var/rando_race = pick(config.roundstart_races)
- dna.species = new rando_race()
-
-//proc used to update the mob's appearance after its dna UI has been changed
-/mob/living/carbon/proc/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0)
- if(!has_dna())
- return
- gender = (deconstruct_block(getblock(dna.uni_identity, DNA_GENDER_BLOCK), 2)-1) ? FEMALE : MALE
-
-/mob/living/carbon/human/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0)
- ..()
- var/structure = dna.uni_identity
- hair_color = sanitize_hexcolor(getblock(structure, DNA_HAIR_COLOR_BLOCK))
- facial_hair_color = sanitize_hexcolor(getblock(structure, DNA_FACIAL_HAIR_COLOR_BLOCK))
- skin_tone = GLOB.skin_tones[deconstruct_block(getblock(structure, DNA_SKIN_TONE_BLOCK), GLOB.skin_tones.len)]
- eye_color = sanitize_hexcolor(getblock(structure, DNA_EYE_COLOR_BLOCK))
- facial_hair_style = GLOB.facial_hair_styles_list[deconstruct_block(getblock(structure, DNA_FACIAL_HAIR_STYLE_BLOCK), GLOB.facial_hair_styles_list.len)]
- hair_style = GLOB.hair_styles_list[deconstruct_block(getblock(structure, DNA_HAIR_STYLE_BLOCK), GLOB.hair_styles_list.len)]
- if(icon_update)
- update_body()
- update_hair()
- if(mutcolor_update)
- update_body_parts()
- if(mutations_overlay_update)
- update_mutations_overlay()
-
-
-/mob/proc/domutcheck()
- return
-
-/mob/living/carbon/domutcheck(force_powers=0) //Set force_powers to 1 to bypass the power chance
- if(!has_dna())
- return
-
- for(var/datum/mutation/human/A in GLOB.good_mutations | GLOB.bad_mutations | GLOB.not_good_mutations)
- if(ismob(A.check_block(src, force_powers)))
- return //we got monkeyized/humanized, this mob will be deleted, no need to continue.
-
- update_mutations_overlay()
-
-
-
-/////////////////////////// DNA HELPER-PROCS //////////////////////////////
-/proc/getleftblocks(input,blocknumber,blocksize)
- if(blocknumber > 1)
- return copytext(input,1,((blocksize*blocknumber)-(blocksize-1)))
-
-/proc/getrightblocks(input,blocknumber,blocksize)
- if(blocknumber < (length(input)/blocksize))
- return copytext(input,blocksize*blocknumber+1,length(input)+1)
-
-/proc/getblock(input, blocknumber, blocksize=DNA_BLOCK_SIZE)
- return copytext(input, blocksize*(blocknumber-1)+1, (blocksize*blocknumber)+1)
-
-/proc/setblock(istring, blocknumber, replacement, blocksize=DNA_BLOCK_SIZE)
- if(!istring || !blocknumber || !replacement || !blocksize)
- return 0
- return getleftblocks(istring, blocknumber, blocksize) + replacement + getrightblocks(istring, blocknumber, blocksize)
-
-/mob/living/carbon/proc/randmut(list/candidates, difficulty = 2)
- if(!has_dna())
- return
- var/datum/mutation/human/num = pick(candidates)
- . = num.force_give(src)
-
-/mob/living/carbon/proc/randmutb()
- if(!has_dna())
- return
- var/datum/mutation/human/HM = pick((GLOB.bad_mutations | GLOB.not_good_mutations) - GLOB.mutations_list[RACEMUT])
- . = HM.force_give(src)
-
-/mob/living/carbon/proc/randmutg()
- if(!has_dna())
- return
- var/datum/mutation/human/HM = pick(GLOB.good_mutations)
- . = HM.force_give(src)
-
-/mob/living/carbon/proc/randmutvg()
- if(!has_dna())
- return
- var/datum/mutation/human/HM = pick((GLOB.good_mutations) - GLOB.mutations_list[HULK] - GLOB.mutations_list[DWARFISM])
- . = HM.force_give(src)
-
-/mob/living/carbon/proc/randmuti()
- if(!has_dna())
- return
- var/num = rand(1, DNA_UNI_IDENTITY_BLOCKS)
- var/newdna = setblock(dna.uni_identity, num, random_string(DNA_BLOCK_SIZE, GLOB.hex_characters))
- dna.uni_identity = newdna
- updateappearance(mutations_overlay_update=1)
-
-/mob/living/carbon/proc/clean_dna()
- if(!has_dna())
- return
- dna.remove_all_mutations()
-
-/mob/living/carbon/proc/clean_randmut(list/candidates, difficulty = 2)
- clean_dna()
- randmut(candidates, difficulty)
-
-/proc/scramble_dna(mob/living/carbon/M, ui=FALSE, se=FALSE, probability)
- if(!M.has_dna())
- return 0
- if(se)
- for(var/i=1, i<=DNA_STRUC_ENZYMES_BLOCKS, i++)
- if(prob(probability))
- M.dna.struc_enzymes = setblock(M.dna.struc_enzymes, i, random_string(DNA_BLOCK_SIZE, GLOB.hex_characters))
- M.domutcheck()
- if(ui)
- for(var/i=1, i<=DNA_UNI_IDENTITY_BLOCKS, i++)
- if(prob(probability))
- M.dna.uni_identity = setblock(M.dna.uni_identity, i, random_string(DNA_BLOCK_SIZE, GLOB.hex_characters))
- M.updateappearance(mutations_overlay_update=1)
- return 1
-
-//value in range 1 to values. values must be greater than 0
-//all arguments assumed to be positive integers
-/proc/construct_block(value, values, blocksize=DNA_BLOCK_SIZE)
- var/width = round((16**blocksize)/values)
- if(value < 1)
- value = 1
- value = (value * width) - rand(1,width)
- return num2hex(value, blocksize)
-
-//value is hex
-/proc/deconstruct_block(value, values, blocksize=DNA_BLOCK_SIZE)
- var/width = round((16**blocksize)/values)
- value = round(hex2num(value) / width) + 1
- if(value > values)
- value = values
- return value
-
-/////////////////////////// DNA HELPER-PROCS
\ No newline at end of file
+/////////////////////////// DNA DATUM
+/datum/dna
+ var/unique_enzymes
+ var/struc_enzymes
+ var/uni_identity
+ var/blood_type
+ var/datum/species/species = new /datum/species/human() //The type of mutant race the player is if applicable (i.e. potato-man)
+ var/list/features = list("FFF") //first value is mutant color
+ var/real_name //Stores the real name of the person who originally got this dna datum. Used primarely for changelings,
+ var/list/mutations = list() //All mutations are from now on here
+ var/list/temporary_mutations = list() //Timers for temporary mutations
+ var/list/previous = list() //For temporary name/ui/ue/blood_type modifications
+ var/mob/living/holder
+
+/datum/dna/New(mob/living/new_holder)
+ if(new_holder)
+ holder = new_holder
+
+/datum/dna/proc/transfer_identity(mob/living/carbon/destination, transfer_SE = 0)
+ if(!istype(destination))
+ return
+ destination.dna.unique_enzymes = unique_enzymes
+ destination.dna.uni_identity = uni_identity
+ destination.dna.blood_type = blood_type
+ destination.set_species(species.type, icon_update=0)
+ destination.dna.features = features.Copy()
+ destination.dna.real_name = real_name
+ destination.dna.temporary_mutations = temporary_mutations.Copy()
+ if(transfer_SE)
+ destination.dna.struc_enzymes = struc_enzymes
+ if(ishuman(destination))
+ var/mob/living/carbon/human/H = destination
+ H.give_genitals(TRUE)//This gives the body the genitals of this DNA. Used for any transformations based on DNA
+ destination.flavor_text = destination.dna.features["flavor_text"] //Update the flavor_text to use new dna text
+
+/datum/dna/proc/copy_dna(datum/dna/new_dna)
+ new_dna.unique_enzymes = unique_enzymes
+ new_dna.struc_enzymes = struc_enzymes
+ new_dna.uni_identity = uni_identity
+ new_dna.blood_type = blood_type
+ new_dna.features = features.Copy()
+ new_dna.species = new species.type
+ new_dna.real_name = real_name
+ new_dna.mutations = mutations.Copy()
+
+/datum/dna/proc/add_mutation(mutation_name)
+ var/datum/mutation/human/HM = GLOB.mutations_list[mutation_name]
+ HM.on_acquiring(holder)
+
+/datum/dna/proc/remove_mutation(mutation_name)
+ var/datum/mutation/human/HM = GLOB.mutations_list[mutation_name]
+ HM.on_losing(holder)
+
+/datum/dna/proc/check_mutation(mutation_name)
+ var/datum/mutation/human/HM = GLOB.mutations_list[mutation_name]
+ return mutations.Find(HM)
+
+/datum/dna/proc/remove_all_mutations()
+ remove_mutation_group(mutations)
+
+/datum/dna/proc/remove_mutation_group(list/group)
+ if(!group)
+ return
+ for(var/datum/mutation/human/HM in group)
+ HM.force_lose(holder)
+
+/datum/dna/proc/generate_uni_identity()
+ . = ""
+ var/list/L = new /list(DNA_UNI_IDENTITY_BLOCKS)
+
+ L[DNA_GENDER_BLOCK] = construct_block((holder.gender!=MALE)+1, 2)
+ if(ishuman(holder))
+ var/mob/living/carbon/human/H = holder
+ if(!GLOB.hair_styles_list.len)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/hair,GLOB.hair_styles_list, GLOB.hair_styles_male_list, GLOB.hair_styles_female_list)
+ L[DNA_HAIR_STYLE_BLOCK] = construct_block(GLOB.hair_styles_list.Find(H.hair_style), GLOB.hair_styles_list.len)
+ L[DNA_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.hair_color)
+ if(!GLOB.facial_hair_styles_list.len)
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/facial_hair, GLOB.facial_hair_styles_list, GLOB.facial_hair_styles_male_list, GLOB.facial_hair_styles_female_list)
+ L[DNA_FACIAL_HAIR_STYLE_BLOCK] = construct_block(GLOB.facial_hair_styles_list.Find(H.facial_hair_style), GLOB.facial_hair_styles_list.len)
+ L[DNA_FACIAL_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.facial_hair_color)
+ L[DNA_SKIN_TONE_BLOCK] = construct_block(GLOB.skin_tones.Find(H.skin_tone), GLOB.skin_tones.len)
+ L[DNA_EYE_COLOR_BLOCK] = sanitize_hexcolor(H.eye_color)
+
+ for(var/i=1, i<=DNA_UNI_IDENTITY_BLOCKS, i++)
+ if(L[i])
+ . += L[i]
+ else
+ . += random_string(DNA_BLOCK_SIZE,GLOB.hex_characters)
+ return .
+
+/datum/dna/proc/generate_struc_enzymes()
+ var/list/sorting = new /list(DNA_STRUC_ENZYMES_BLOCKS)
+ var/result = ""
+ for(var/datum/mutation/human/A in GLOB.good_mutations + GLOB.bad_mutations + GLOB.not_good_mutations)
+ if(A.name == RACEMUT && ismonkey(holder))
+ sorting[A.dna_block] = num2hex(A.lowest_value + rand(0, 256 * 6), DNA_BLOCK_SIZE)
+ mutations |= A
+ else
+ sorting[A.dna_block] = random_string(DNA_BLOCK_SIZE, list("0","1","2","3","4","5","6"))
+
+ for(var/B in sorting)
+ result += B
+ return result
+
+/datum/dna/proc/generate_unique_enzymes()
+ . = ""
+ if(istype(holder))
+ real_name = holder.real_name
+ . += md5(holder.real_name)
+ else
+ . += random_string(DNA_UNIQUE_ENZYMES_LEN, GLOB.hex_characters)
+ return .
+
+/datum/dna/proc/update_ui_block(blocknumber)
+ if(!blocknumber || !ishuman(holder))
+ return
+ var/mob/living/carbon/human/H = holder
+ switch(blocknumber)
+ if(DNA_HAIR_COLOR_BLOCK)
+ setblock(uni_identity, blocknumber, sanitize_hexcolor(H.hair_color))
+ if(DNA_FACIAL_HAIR_COLOR_BLOCK)
+ setblock(uni_identity, blocknumber, sanitize_hexcolor(H.facial_hair_color))
+ if(DNA_SKIN_TONE_BLOCK)
+ setblock(uni_identity, blocknumber, construct_block(GLOB.skin_tones.Find(H.skin_tone), GLOB.skin_tones.len))
+ if(DNA_EYE_COLOR_BLOCK)
+ setblock(uni_identity, blocknumber, sanitize_hexcolor(H.eye_color))
+ if(DNA_GENDER_BLOCK)
+ setblock(uni_identity, blocknumber, construct_block((H.gender!=MALE)+1, 2))
+ if(DNA_FACIAL_HAIR_STYLE_BLOCK)
+ setblock(uni_identity, blocknumber, construct_block(GLOB.facial_hair_styles_list.Find(H.facial_hair_style), GLOB.facial_hair_styles_list.len))
+ if(DNA_HAIR_STYLE_BLOCK)
+ setblock(uni_identity, blocknumber, construct_block(GLOB.hair_styles_list.Find(H.hair_style), GLOB.hair_styles_list.len))
+
+/datum/dna/proc/mutations_say_mods(message)
+ if(message)
+ for(var/datum/mutation/human/M in mutations)
+ message = M.say_mod(message)
+ return message
+
+/datum/dna/proc/mutations_get_spans()
+ var/list/spans = list()
+ for(var/datum/mutation/human/M in mutations)
+ spans |= M.get_spans()
+ return spans
+
+/datum/dna/proc/species_get_spans()
+ var/list/spans = list()
+ if(species)
+ spans |= species.get_spans()
+ return spans
+
+
+/datum/dna/proc/is_same_as(datum/dna/D)
+ if(uni_identity == D.uni_identity && struc_enzymes == D.struc_enzymes && real_name == D.real_name)
+ if(species.type == D.species.type && features == D.features && blood_type == D.blood_type)
+ return 1
+ return 0
+
+//used to update dna UI, UE, and dna.real_name.
+/datum/dna/proc/update_dna_identity()
+ uni_identity = generate_uni_identity()
+ unique_enzymes = generate_unique_enzymes()
+
+/datum/dna/proc/initialize_dna(newblood_type)
+ if(newblood_type)
+ blood_type = newblood_type
+ unique_enzymes = generate_unique_enzymes()
+ uni_identity = generate_uni_identity()
+ struc_enzymes = generate_struc_enzymes()
+ features = random_features()
+
+
+/datum/dna/stored //subtype used by brain mob's stored_dna
+
+/datum/dna/stored/add_mutation(mutation_name) //no mutation changes on stored dna.
+ return
+
+/datum/dna/stored/remove_mutation(mutation_name)
+ return
+
+/datum/dna/stored/check_mutation(mutation_name)
+ return
+
+/datum/dna/stored/remove_all_mutations()
+ return
+
+/datum/dna/stored/remove_mutation_group(list/group)
+ return
+
+/////////////////////////// DNA MOB-PROCS //////////////////////
+
+/mob/proc/set_species(datum/species/mrace, icon_update = 1)
+ return
+
+/mob/living/brain/set_species(datum/species/mrace, icon_update = 1)
+ if(mrace)
+ if(ispath(mrace))
+ stored_dna.species = new mrace()
+ else
+ stored_dna.species = mrace //not calling any species update procs since we're a brain, not a monkey/human
+
+
+/mob/living/carbon/set_species(datum/species/mrace, icon_update = 1)
+ if(mrace && has_dna())
+ dna.species.on_species_loss(src)
+ var/old_species = dna.species
+ if(ispath(mrace))
+ dna.species = new mrace()
+ else
+ dna.species = mrace
+ dna.species.on_species_gain(src, old_species)
+
+/mob/living/carbon/human/set_species(datum/species/mrace, icon_update = 1)
+ ..()
+ if(icon_update)
+ update_body()
+ update_hair()
+ update_body_parts()
+ update_mutations_overlay()// no lizard with human hulk overlay please.
+
+
+/mob/proc/has_dna()
+ return
+
+/mob/living/carbon/has_dna()
+ return dna
+
+
+/mob/living/carbon/human/proc/hardset_dna(ui, se, newreal_name, newblood_type, datum/species/mrace, newfeatures)
+
+ if(newfeatures)
+ dna.features = newfeatures
+ flavor_text = dna.features["flavor_text"] //Update the flavor_text to use new dna text
+
+ if(mrace)
+ var/datum/species/newrace = new mrace.type
+ newrace.copy_properties_from(mrace)
+ set_species(newrace, icon_update=0)
+
+ if(newreal_name)
+ real_name = newreal_name
+ dna.generate_unique_enzymes()
+
+ if(newblood_type)
+ dna.blood_type = newblood_type
+
+ if(ui)
+ dna.uni_identity = ui
+ updateappearance(icon_update=0)
+
+ if(se)
+ dna.struc_enzymes = se
+ domutcheck()
+
+ if(mrace || newfeatures || ui)
+ update_body()
+ update_hair()
+ update_body_parts()
+ update_mutations_overlay()
+
+
+/mob/living/carbon/proc/create_dna()
+ dna = new /datum/dna(src)
+ if(!dna.species)
+ var/rando_race = pick(CONFIG_GET(keyed_flag_list/roundstart_races))
+ dna.species = new rando_race()
+
+//proc used to update the mob's appearance after its dna UI has been changed
+/mob/living/carbon/proc/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0)
+ if(!has_dna())
+ return
+ gender = (deconstruct_block(getblock(dna.uni_identity, DNA_GENDER_BLOCK), 2)-1) ? FEMALE : MALE
+
+/mob/living/carbon/human/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0)
+ ..()
+ var/structure = dna.uni_identity
+ hair_color = sanitize_hexcolor(getblock(structure, DNA_HAIR_COLOR_BLOCK))
+ facial_hair_color = sanitize_hexcolor(getblock(structure, DNA_FACIAL_HAIR_COLOR_BLOCK))
+ skin_tone = GLOB.skin_tones[deconstruct_block(getblock(structure, DNA_SKIN_TONE_BLOCK), GLOB.skin_tones.len)]
+ eye_color = sanitize_hexcolor(getblock(structure, DNA_EYE_COLOR_BLOCK))
+ facial_hair_style = GLOB.facial_hair_styles_list[deconstruct_block(getblock(structure, DNA_FACIAL_HAIR_STYLE_BLOCK), GLOB.facial_hair_styles_list.len)]
+ hair_style = GLOB.hair_styles_list[deconstruct_block(getblock(structure, DNA_HAIR_STYLE_BLOCK), GLOB.hair_styles_list.len)]
+ if(icon_update)
+ update_body()
+ update_hair()
+ if(mutcolor_update)
+ update_body_parts()
+ if(mutations_overlay_update)
+ update_mutations_overlay()
+
+
+/mob/proc/domutcheck()
+ return
+
+/mob/living/carbon/domutcheck(force_powers=0) //Set force_powers to 1 to bypass the power chance
+ if(!has_dna())
+ return
+
+ for(var/datum/mutation/human/A in GLOB.good_mutations | GLOB.bad_mutations | GLOB.not_good_mutations)
+ if(ismob(A.check_block(src, force_powers)))
+ return //we got monkeyized/humanized, this mob will be deleted, no need to continue.
+
+ update_mutations_overlay()
+
+
+
+/////////////////////////// DNA HELPER-PROCS //////////////////////////////
+/proc/getleftblocks(input,blocknumber,blocksize)
+ if(blocknumber > 1)
+ return copytext(input,1,((blocksize*blocknumber)-(blocksize-1)))
+
+/proc/getrightblocks(input,blocknumber,blocksize)
+ if(blocknumber < (length(input)/blocksize))
+ return copytext(input,blocksize*blocknumber+1,length(input)+1)
+
+/proc/getblock(input, blocknumber, blocksize=DNA_BLOCK_SIZE)
+ return copytext(input, blocksize*(blocknumber-1)+1, (blocksize*blocknumber)+1)
+
+/proc/setblock(istring, blocknumber, replacement, blocksize=DNA_BLOCK_SIZE)
+ if(!istring || !blocknumber || !replacement || !blocksize)
+ return 0
+ return getleftblocks(istring, blocknumber, blocksize) + replacement + getrightblocks(istring, blocknumber, blocksize)
+
+/mob/living/carbon/proc/randmut(list/candidates, difficulty = 2)
+ if(!has_dna())
+ return
+ var/datum/mutation/human/num = pick(candidates)
+ . = num.force_give(src)
+
+/mob/living/carbon/proc/randmutb()
+ if(!has_dna())
+ return
+ var/datum/mutation/human/HM = pick((GLOB.bad_mutations | GLOB.not_good_mutations) - GLOB.mutations_list[RACEMUT])
+ . = HM.force_give(src)
+
+/mob/living/carbon/proc/randmutg()
+ if(!has_dna())
+ return
+ var/datum/mutation/human/HM = pick(GLOB.good_mutations)
+ . = HM.force_give(src)
+
+/mob/living/carbon/proc/randmutvg()
+ if(!has_dna())
+ return
+ var/datum/mutation/human/HM = pick((GLOB.good_mutations) - GLOB.mutations_list[HULK] - GLOB.mutations_list[DWARFISM])
+ . = HM.force_give(src)
+
+/mob/living/carbon/proc/randmuti()
+ if(!has_dna())
+ return
+ var/num = rand(1, DNA_UNI_IDENTITY_BLOCKS)
+ var/newdna = setblock(dna.uni_identity, num, random_string(DNA_BLOCK_SIZE, GLOB.hex_characters))
+ dna.uni_identity = newdna
+ updateappearance(mutations_overlay_update=1)
+
+/mob/living/carbon/proc/clean_dna()
+ if(!has_dna())
+ return
+ dna.remove_all_mutations()
+
+/mob/living/carbon/proc/clean_randmut(list/candidates, difficulty = 2)
+ clean_dna()
+ randmut(candidates, difficulty)
+
+/proc/scramble_dna(mob/living/carbon/M, ui=FALSE, se=FALSE, probability)
+ if(!M.has_dna())
+ return 0
+ if(se)
+ for(var/i=1, i<=DNA_STRUC_ENZYMES_BLOCKS, i++)
+ if(prob(probability))
+ M.dna.struc_enzymes = setblock(M.dna.struc_enzymes, i, random_string(DNA_BLOCK_SIZE, GLOB.hex_characters))
+ M.domutcheck()
+ if(ui)
+ for(var/i=1, i<=DNA_UNI_IDENTITY_BLOCKS, i++)
+ if(prob(probability))
+ M.dna.uni_identity = setblock(M.dna.uni_identity, i, random_string(DNA_BLOCK_SIZE, GLOB.hex_characters))
+ M.updateappearance(mutations_overlay_update=1)
+ return 1
+
+//value in range 1 to values. values must be greater than 0
+//all arguments assumed to be positive integers
+/proc/construct_block(value, values, blocksize=DNA_BLOCK_SIZE)
+ var/width = round((16**blocksize)/values)
+ if(value < 1)
+ value = 1
+ value = (value * width) - rand(1,width)
+ return num2hex(value, blocksize)
+
+//value is hex
+/proc/deconstruct_block(value, values, blocksize=DNA_BLOCK_SIZE)
+ var/width = round((16**blocksize)/values)
+ value = round(hex2num(value) / width) + 1
+ if(value > values)
+ value = values
+ return value
+
+/////////////////////////// DNA HELPER-PROCS
diff --git a/code/datums/explosion.dm b/code/datums/explosion.dm
index 5e381c0322..9869b43d8f 100644
--- a/code/datums/explosion.dm
+++ b/code/datums/explosion.dm
@@ -140,7 +140,7 @@ GLOBAL_LIST_EMPTY(explosions)
var/list/exploded_this_tick = list() //open turfs that need to be blocked off while we sleep
var/list/affected_turfs = GatherSpiralTurfs(max_range, epicenter)
- var/reactionary = config.reactionary_explosions
+ var/reactionary = CONFIG_GET(flag/reactionary_explosions)
var/list/cached_exp_block
if(reactionary)
diff --git a/code/datums/forced_movement.dm b/code/datums/forced_movement.dm
index 620973487a..e07e4c62ed 100644
--- a/code/datums/forced_movement.dm
+++ b/code/datums/forced_movement.dm
@@ -1,90 +1,90 @@
-//Just new and forget
-/datum/forced_movement
- var/atom/movable/victim
- var/atom/target
- var/last_processed
- var/steps_per_tick
- var/allow_climbing
- var/datum/callback/on_step
- var/moved_at_all = FALSE
- //as fast as ssfastprocess
-/datum/forced_movement/New(atom/movable/_victim, atom/_target, _steps_per_tick = 0.5, _allow_climbing = FALSE, datum/callback/_on_step = null)
- victim = _victim
- target = _target
- steps_per_tick = _steps_per_tick
- allow_climbing = _allow_climbing
- on_step = _on_step
-
- . = ..()
-
- if(_victim && _target && _steps_per_tick && !_victim.force_moving)
- last_processed = world.time
- _victim.force_moving = src
- START_PROCESSING(SSfastprocess, src)
- else
- qdel(src) //if you want to overwrite the current forced movement, call qdel(victim.force_moving) before creating this
-
-/datum/forced_movement/Destroy()
- if(victim.force_moving == src)
- victim.force_moving = null
- if(moved_at_all)
- victim.forceMove(victim.loc) //get the side effects of moving here that require us to currently not be force_moving aka reslipping on ice
- STOP_PROCESSING(SSfastprocess, src)
- victim = null
- target = null
- return ..()
-
-/datum/forced_movement/process()
- if(QDELETED(victim) || !victim.loc || QDELETED(target) || !target.loc)
- qdel(src)
- return
- var/steps_to_take = round(steps_per_tick * (world.time - last_processed))
- if(steps_to_take)
- for(var/i in 1 to steps_to_take)
- if(TryMove())
- moved_at_all = TRUE
- if(on_step)
- on_step.InvokeAsync()
- else
- qdel(src)
- return
- last_processed = world.time
-
-/datum/forced_movement/proc/TryMove(recursive = FALSE)
- var/atom/movable/vic = victim //sanic
- var/atom/tar = target
-
- if(!recursive)
- . = step_towards(vic, tar)
-
- //shit way for getting around corners
- if(!.)
- if(tar.x > vic.x)
- if(step(vic, EAST))
- . = TRUE
- else if(tar.x < vic.x)
- if(step(vic, WEST))
- . = TRUE
-
- if(!.)
- if(tar.y > vic.y)
- if(step(vic, NORTH))
- . = TRUE
- else if(tar.y < vic.y)
- if(step(vic, SOUTH))
- . = TRUE
-
- if(!.)
- if(recursive)
- return FALSE
- else
- . = TryMove(TRUE)
-
- . = . && (vic.loc != tar.loc)
-
+//Just new and forget
+/datum/forced_movement
+ var/atom/movable/victim
+ var/atom/target
+ var/last_processed
+ var/steps_per_tick
+ var/allow_climbing
+ var/datum/callback/on_step
+ var/moved_at_all = FALSE
+ //as fast as ssfastprocess
+/datum/forced_movement/New(atom/movable/_victim, atom/_target, _steps_per_tick = 0.5, _allow_climbing = FALSE, datum/callback/_on_step = null)
+ victim = _victim
+ target = _target
+ steps_per_tick = _steps_per_tick
+ allow_climbing = _allow_climbing
+ on_step = _on_step
+
+ . = ..()
+
+ if(_victim && _target && _steps_per_tick && !_victim.force_moving)
+ last_processed = world.time
+ _victim.force_moving = src
+ START_PROCESSING(SSfastprocess, src)
+ else
+ qdel(src) //if you want to overwrite the current forced movement, call qdel(victim.force_moving) before creating this
+
+/datum/forced_movement/Destroy()
+ if(victim.force_moving == src)
+ victim.force_moving = null
+ if(moved_at_all)
+ victim.forceMove(victim.loc) //get the side effects of moving here that require us to currently not be force_moving aka reslipping on ice
+ STOP_PROCESSING(SSfastprocess, src)
+ victim = null
+ target = null
+ return ..()
+
+/datum/forced_movement/process()
+ if(QDELETED(victim) || !victim.loc || QDELETED(target) || !target.loc)
+ qdel(src)
+ return
+ var/steps_to_take = round(steps_per_tick * (world.time - last_processed))
+ if(steps_to_take)
+ for(var/i in 1 to steps_to_take)
+ if(TryMove())
+ moved_at_all = TRUE
+ if(on_step)
+ on_step.InvokeAsync()
+ else
+ qdel(src)
+ return
+ last_processed = world.time
+
+/datum/forced_movement/proc/TryMove(recursive = FALSE)
+ var/atom/movable/vic = victim //sanic
+ var/atom/tar = target
+
+ if(!recursive)
+ . = step_towards(vic, tar)
+
+ //shit way for getting around corners
+ if(!.)
+ if(tar.x > vic.x)
+ if(step(vic, EAST))
+ . = TRUE
+ else if(tar.x < vic.x)
+ if(step(vic, WEST))
+ . = TRUE
+
+ if(!.)
+ if(tar.y > vic.y)
+ if(step(vic, NORTH))
+ . = TRUE
+ else if(tar.y < vic.y)
+ if(step(vic, SOUTH))
+ . = TRUE
+
+ if(!.)
+ if(recursive)
+ return FALSE
+ else
+ . = TryMove(TRUE)
+
+ . = . && (vic.loc != tar.loc)
+
/mob/Collide(atom/A)
- . = ..()
- if(force_moving && force_moving.allow_climbing && istype(A, /obj/structure))
- var/obj/structure/S = A
- if(S.climbable)
- S.do_climb(src)
+ . = ..()
+ if(force_moving && force_moving.allow_climbing && isstructure(A))
+ var/obj/structure/S = A
+ if(S.climbable)
+ S.do_climb(src)
diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm
index c6958fa997..7b60070fc7 100644
--- a/code/datums/helper_datums/getrev.dm
+++ b/code/datums/helper_datums/getrev.dm
@@ -2,25 +2,10 @@
var/originmastercommit
var/commit
var/list/testmerge = list()
- var/has_pr_details = FALSE //tgs2 support
var/date
/datum/getrev/New()
- if(world.RunningService())
- var/file_name
- if(ServiceVersion()) //will return null for versions < 3.0.91.0
- file_name = SERVICE_PR_TEST_JSON_OLD
- else
- file_name = SERVICE_PR_TEST_JSON
- if(fexists(file_name))
- testmerge = json_decode(file2text(file_name))
-#ifdef SERVERTOOLS
- else if(!world.RunningService() && fexists("../prtestjob.lk")) //tgs2 support
- var/list/tmp = world.file2list("..\\prtestjob.lk")
- for(var/I in tmp)
- if(I)
- testmerge |= I
-#endif
+ testmerge = SERVER_TOOLS_PR_LIST
log_world("Running /tg/ revision:")
var/list/logs = world.file2list(".git/logs/HEAD")
if(logs)
@@ -36,58 +21,24 @@
log_world(commit)
for(var/line in testmerge)
if(line)
- if(world.RunningService())
- var/tmcommit = testmerge[line]["commit"]
- log_world("Test merge active of PR #[line] commit [tmcommit]")
- SSblackbox.add_details("testmerged_prs","[line]|[tmcommit]")
- else //tgs2 support
- log_world("Test merge active of PR #[line]")
- SSblackbox.add_details("testmerged_prs","[line]")
+ var/tmcommit = testmerge[line]["commit"]
+ log_world("Test merge active of PR #[line] commit [tmcommit]")
+ SSblackbox.add_details("testmerged_prs","[line]|[tmcommit]")
log_world("Based off origin/master commit [originmastercommit]")
else
log_world(originmastercommit)
-/datum/getrev/proc/DownloadPRDetails()
- if(!config.githubrepoid)
- if(testmerge.len)
- log_world("PR details download failed: No github repo config set")
- return
- if(!isnum(text2num(config.githubrepoid)))
- log_world("PR details download failed: Invalid github repo id: [config.githubrepoid]")
- return
- for(var/line in testmerge)
- if(!isnum(text2num(line)))
- log_world("PR details download failed: Invalid PR number: [line]")
- return
- var/url = "https://api.github.com/repositories/[config.githubrepoid]/pulls/[line].json"
- GLOB.valid_HTTPSGet = TRUE
- var/json = HTTPSGet(url)
- if(!json)
- return
-
- testmerge[line] = json_decode(json)
-
- if(!testmerge[line])
- log_world("PR details download failed: null details returned")
- return
- CHECK_TICK
- log_world("PR details successfully downloaded")
- has_pr_details = TRUE
/datum/getrev/proc/GetTestMergeInfo(header = TRUE)
if(!testmerge.len)
return ""
. = header ? "The following pull requests are currently test merged: " : ""
for(var/line in testmerge)
- var/details
- if(world.RunningService())
- var/cm = testmerge[line]["commit"]
- details = ": '" + html_encode(testmerge[line]["title"]) + "' by " + html_encode(testmerge[line]["author"]) + " at commit " + html_encode(copytext(cm, 1, min(length(cm), 7)))
- else if(has_pr_details) //tgs2 support
- details = ": '" + html_encode(testmerge[line]["title"]) + "' by " + html_encode(testmerge[line]["user"]["login"])
+ var/cm = testmerge[line]["commit"]
+ var/details = ": '" + html_encode(testmerge[line]["title"]) + "' by " + html_encode(testmerge[line]["author"]) + " at commit " + html_encode(copytext(cm, 1, min(length(cm), 7)))
if(details && findtext(details, "\[s\]") && (!usr || !usr.client.holder))
continue
- . += "#[line][details] "
+ . += "#[line][details] "
/client/verb/showrevinfo()
set category = "OOC"
@@ -101,44 +52,47 @@
to_chat(src, GLOB.revdata.GetTestMergeInfo())
prefix = "Based off origin/master commit: "
var/pc = GLOB.revdata.originmastercommit
- to_chat(src, "[prefix][copytext(pc, 1, min(length(pc), 7))] ")
+ to_chat(src, "[prefix][copytext(pc, 1, min(length(pc), 7))] ")
else
to_chat(src, "Revision unknown")
to_chat(src, "Current Informational Settings: ")
- to_chat(src, "Protect Authority Roles From Traitor: [config.protect_roles_from_antagonist]")
- to_chat(src, "Protect Assistant Role From Traitor: [config.protect_assistant_from_antagonist]")
- to_chat(src, "Enforce Human Authority: [config.enforce_human_authority]")
- to_chat(src, "Allow Latejoin Antagonists: [config.allow_latejoin_antagonists]")
- to_chat(src, "Enforce Continuous Rounds: [config.continuous.len] of [config.modes.len] roundtypes")
- to_chat(src, "Allow Midround Antagonists: [config.midround_antag.len] of [config.modes.len] roundtypes")
- if(config.show_game_type_odds)
+ to_chat(src, "Protect Authority Roles From Traitor: [CONFIG_GET(flag/protect_roles_from_antagonist)]")
+ to_chat(src, "Protect Assistant Role From Traitor: [CONFIG_GET(flag/protect_assistant_from_antagonist)]")
+ to_chat(src, "Enforce Human Authority: [CONFIG_GET(flag/enforce_human_authority)]")
+ to_chat(src, "Allow Latejoin Antagonists: [CONFIG_GET(flag/allow_latejoin_antagonists)]")
+ to_chat(src, "Enforce Continuous Rounds: [length(CONFIG_GET(keyed_flag_list/continuous))] of [config.modes.len] roundtypes")
+ to_chat(src, "Allow Midround Antagonists: [length(CONFIG_GET(keyed_flag_list/midround_antag))] of [config.modes.len] roundtypes")
+ if(CONFIG_GET(flag/show_game_type_odds))
+ var/list/probabilities = CONFIG_GET(keyed_number_list/probability)
if(SSticker.IsRoundInProgress())
var/prob_sum = 0
var/current_odds_differ = FALSE
var/list/probs = list()
var/list/modes = config.gamemode_cache
+ var/list/min_pop = CONFIG_GET(keyed_number_list/min_pop)
+ var/list/max_pop = CONFIG_GET(keyed_number_list/max_pop)
for(var/mode in modes)
var/datum/game_mode/M = mode
var/ctag = initial(M.config_tag)
- if(!(ctag in config.probabilities))
+ if(!(ctag in probabilities))
continue
- if((config.min_pop[ctag] && (config.min_pop[ctag] > SSticker.totalPlayersReady)) || (config.max_pop[ctag] && (config.max_pop[ctag] < SSticker.totalPlayersReady)) || (initial(M.required_players) > SSticker.totalPlayersReady))
+ if((min_pop[ctag] && (min_pop[ctag] > SSticker.totalPlayersReady)) || (max_pop[ctag] && (max_pop[ctag] < SSticker.totalPlayersReady)) || (initial(M.required_players) > SSticker.totalPlayersReady))
current_odds_differ = TRUE
continue
probs[ctag] = 1
- prob_sum += config.probabilities[ctag]
+ prob_sum += probabilities[ctag]
if(current_odds_differ)
to_chat(src, "Game Mode Odds for current round: ")
for(var/ctag in probs)
- if(config.probabilities[ctag] > 0)
- var/percentage = round(config.probabilities[ctag] / prob_sum * 100, 0.1)
+ if(probabilities[ctag] > 0)
+ var/percentage = round(probabilities[ctag] / prob_sum * 100, 0.1)
to_chat(src, "[ctag] [percentage]%")
to_chat(src, "All Game Mode Odds: ")
var/sum = 0
- for(var/ctag in config.probabilities)
- sum += config.probabilities[ctag]
- for(var/ctag in config.probabilities)
- if(config.probabilities[ctag] > 0)
- var/percentage = round(config.probabilities[ctag] / sum * 100, 0.1)
+ for(var/ctag in probabilities)
+ sum += probabilities[ctag]
+ for(var/ctag in probabilities)
+ if(probabilities[ctag] > 0)
+ var/percentage = round(probabilities[ctag] / sum * 100, 0.1)
to_chat(src, "[ctag] [percentage]%")
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 7f909144aa..093e828452 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -63,6 +63,7 @@
var/mob/living/enslaved_to //If this mind's master is another mob (i.e. adamantine golems)
var/datum/language_holder/language_holder
+ var/unconvertable = FALSE
/datum/mind/New(var/key)
src.key = key
@@ -211,7 +212,7 @@
/datum/mind/proc/remove_wizard()
if(src in SSticker.mode.wizards)
SSticker.mode.wizards -= src
- current.spellremove(current)
+ RemoveAllSpells()
special_role = null
remove_antag_equip()
@@ -1505,6 +1506,10 @@
spell_list -= S
qdel(S)
+/datum/mind/proc/RemoveAllSpells()
+ for(var/obj/effect/proc_holder/S in spell_list)
+ RemoveSpell(S)
+
/datum/mind/proc/transfer_martial_arts(mob/living/new_character)
if(!ishuman(new_character))
return
diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm
index 69749475cd..20d218f767 100644
--- a/code/datums/status_effects/buffs.dm
+++ b/code/datums/status_effects/buffs.dm
@@ -71,7 +71,7 @@
/datum/status_effect/vanguard_shield/on_apply()
owner.log_message("gained Vanguard stun immunity", INDIVIDUAL_ATTACK_LOG)
- owner.add_stun_absorption("vanguard", 200, 1, "'s yellow aura momentarily intensifies!", "Your ward absorbs the stun!", " radiating with a soft yellow light!")
+ owner.add_stun_absorption("vanguard", INFINITY, 1, "'s yellow aura momentarily intensifies!", "Your ward absorbs the stun!", " radiating with a soft yellow light!")
owner.visible_message("[owner] begins to faintly glow! ", "You will absorb all stuns for the next twenty seconds. ")
owner.SetStun(0, FALSE)
owner.SetKnockdown(0)
@@ -87,7 +87,8 @@
var/vanguard = owner.stun_absorption["vanguard"]
var/stuns_blocked = 0
if(vanguard)
- stuns_blocked = round(min(vanguard["stuns_absorbed"] * 0.25, 20))
+ stuns_blocked = Floor(min(vanguard["stuns_absorbed"] * 0.25, 400))
+ vanguard["end_time"] = 0 //so it doesn't absorb the stuns we're about to apply
if(owner.stat != DEAD)
var/message_to_owner = "You feel your Vanguard quietly fade... "
var/otheractiveabsorptions = FALSE
@@ -95,7 +96,6 @@
if(owner.stun_absorption[i]["end_time"] > world.time && owner.stun_absorption[i]["priority"] > vanguard["priority"])
otheractiveabsorptions = TRUE
if(!GLOB.ratvar_awakens && stuns_blocked && !otheractiveabsorptions)
- vanguard["end_time"] = 0 //so it doesn't absorb the stuns we're about to apply
owner.Knockdown(stuns_blocked)
message_to_owner = "The weight of the Vanguard's protection crashes down upon you! "
if(stuns_blocked >= 300)
@@ -384,3 +384,31 @@
if(islist(owner.stun_absorption) && owner.stun_absorption["blooddrunk"])
owner.stun_absorption -= "blooddrunk"
+/datum/status_effect/sword_spin
+ id = "Bastard Sword Spin"
+ duration = 50
+ tick_interval = 8
+ alert_type = null
+
+
+/datum/status_effect/sword_spin/on_apply()
+ owner.visible_message("[owner] begins swinging the sword with inhuman strength! ")
+ var/oldcolor = owner.color
+ owner.color = "#ff0000"
+ owner.add_stun_absorption("bloody bastard sword", duration, 2, "doesn't even flinch as the sword's power courses through them!", "You shrug off the stun!", " glowing with a blazing red aura!")
+ owner.spin(duration,1)
+ animate(owner, color = oldcolor, time = duration, easing = EASE_IN)
+ addtimer(CALLBACK(owner, /atom/proc/update_atom_colour), duration)
+ playsound(owner, 'sound/weapons/fwoosh.wav', 75, 0)
+ return ..()
+
+
+/datum/status_effect/sword_spin/tick()
+ playsound(owner, 'sound/weapons/fwoosh.wav', 75, 0)
+ var/obj/item/slashy
+ slashy = owner.get_active_held_item()
+ for(var/mob/living/M in orange(1,owner))
+ slashy.attack(M, owner)
+
+/datum/status_effect/sword_spin/on_remove()
+ owner.visible_message("[owner]'s inhuman strength dissipates and the sword's runes grow cold! ")
diff --git a/code/datums/weather/weather_types/ash_storm.dm b/code/datums/weather/weather_types/ash_storm.dm
index 2c2212fde5..a1dc9ece69 100644
--- a/code/datums/weather/weather_types/ash_storm.dm
+++ b/code/datums/weather/weather_types/ash_storm.dm
@@ -27,7 +27,7 @@
probability = 90
/datum/weather/ash_storm/proc/is_ash_immune(mob/living/L)
- if(istype(L.loc, /obj/mecha)) //Mechs are immune
+ if(ismecha(L.loc)) //Mechs are immune
return TRUE
if(ishuman(L)) //Are you immune?
var/mob/living/carbon/human/H = L
diff --git a/code/datums/wires/wires.dm b/code/datums/wires/wires.dm
index 95267cf927..ae938f18ce 100644
--- a/code/datums/wires/wires.dm
+++ b/code/datums/wires/wires.dm
@@ -1,260 +1,260 @@
-#define MAXIMUM_EMP_WIRES 3
-
-/proc/is_wire_tool(obj/item/I)
- if(istype(I, /obj/item/device/multitool))
- return TRUE
- if(istype(I, /obj/item/wirecutters))
- return TRUE
- if(istype(I, /obj/item/device/assembly))
- var/obj/item/device/assembly/A = I
- if(A.attachable)
- return TRUE
- return
-
-/atom
- var/datum/wires/wires = null
-
-/datum/wires
- var/atom/holder = null // The holder (atom that contains these wires).
- var/holder_type = null // The holder's typepath (used to make wire colors common to all holders).
- var/proper_name = "Unknown" // The display name for the wire set shown in station blueprints. Not used if randomize is true or it's an item NT wouldn't know about (Explosives/Nuke)
-
- var/list/wires = list() // List of wires.
- var/list/cut_wires = list() // List of wires that have been cut.
- var/list/colors = list() // Dictionary of colors to wire.
- var/list/assemblies = list() // List of attached assemblies.
- var/randomize = 0 // If every instance of these wires should be random.
- // Prevents wires from showing up in station blueprints
-
-/datum/wires/New(atom/holder)
- ..()
- if(!istype(holder, holder_type))
- CRASH("Wire holder is not of the expected type!")
- return
-
- src.holder = holder
- if(randomize)
- randomize()
- else
- if(!GLOB.wire_color_directory[holder_type])
- randomize()
- GLOB.wire_color_directory[holder_type] = colors
- GLOB.wire_name_directory[holder_type] = proper_name
- else
- colors = GLOB.wire_color_directory[holder_type]
-
-/datum/wires/Destroy()
- holder = null
- assemblies = list()
- return ..()
-
-/datum/wires/proc/add_duds(duds)
- while(duds)
- var/dud = WIRE_DUD_PREFIX + "[--duds]"
- if(dud in wires)
- continue
- wires += dud
-
-/datum/wires/proc/randomize()
- var/static/list/possible_colors = list(
- "blue",
- "brown",
- "crimson",
- "cyan",
- "gold",
- "grey",
- "green",
- "magenta",
- "orange",
- "pink",
- "purple",
- "red",
- "silver",
- "violet",
- "white",
- "yellow"
- )
-
- var/list/my_possible_colors = possible_colors.Copy()
-
- for(var/wire in shuffle(wires))
- colors[pick_n_take(my_possible_colors)] = wire
-
-/datum/wires/proc/shuffle_wires()
- colors.Cut()
- randomize()
-
-/datum/wires/proc/repair()
- cut_wires.Cut()
-
-/datum/wires/proc/get_wire(color)
- return colors[color]
-
-/datum/wires/proc/get_attached(color)
- if(assemblies[color])
- return assemblies[color]
- return null
-
-/datum/wires/proc/is_attached(color)
- if(assemblies[color])
- return TRUE
-
-/datum/wires/proc/is_cut(wire)
- return (wire in cut_wires)
-
-/datum/wires/proc/is_color_cut(color)
- return is_cut(get_wire(color))
-
-/datum/wires/proc/is_all_cut()
- if(cut_wires.len == wires.len)
- return TRUE
-
-/datum/wires/proc/cut(wire)
- if(is_cut(wire))
- cut_wires -= wire
- on_cut(wire, mend = TRUE)
- else
- cut_wires += wire
- on_cut(wire, mend = FALSE)
-
-/datum/wires/proc/cut_color(color)
- cut(get_wire(color))
-
-/datum/wires/proc/cut_random()
- cut(wires[rand(1, wires.len)])
-
-/datum/wires/proc/cut_all()
- for(var/wire in wires)
- cut(wire)
-
+#define MAXIMUM_EMP_WIRES 3
+
+/proc/is_wire_tool(obj/item/I)
+ if(istype(I, /obj/item/device/multitool))
+ return TRUE
+ if(istype(I, /obj/item/wirecutters))
+ return TRUE
+ if(istype(I, /obj/item/device/assembly))
+ var/obj/item/device/assembly/A = I
+ if(A.attachable)
+ return TRUE
+ return
+
+/atom
+ var/datum/wires/wires = null
+
+/datum/wires
+ var/atom/holder = null // The holder (atom that contains these wires).
+ var/holder_type = null // The holder's typepath (used to make wire colors common to all holders).
+ var/proper_name = "Unknown" // The display name for the wire set shown in station blueprints. Not used if randomize is true or it's an item NT wouldn't know about (Explosives/Nuke)
+
+ var/list/wires = list() // List of wires.
+ var/list/cut_wires = list() // List of wires that have been cut.
+ var/list/colors = list() // Dictionary of colors to wire.
+ var/list/assemblies = list() // List of attached assemblies.
+ var/randomize = 0 // If every instance of these wires should be random.
+ // Prevents wires from showing up in station blueprints
+
+/datum/wires/New(atom/holder)
+ ..()
+ if(!istype(holder, holder_type))
+ CRASH("Wire holder is not of the expected type!")
+ return
+
+ src.holder = holder
+ if(randomize)
+ randomize()
+ else
+ if(!GLOB.wire_color_directory[holder_type])
+ randomize()
+ GLOB.wire_color_directory[holder_type] = colors
+ GLOB.wire_name_directory[holder_type] = proper_name
+ else
+ colors = GLOB.wire_color_directory[holder_type]
+
+/datum/wires/Destroy()
+ holder = null
+ assemblies = list()
+ return ..()
+
+/datum/wires/proc/add_duds(duds)
+ while(duds)
+ var/dud = WIRE_DUD_PREFIX + "[--duds]"
+ if(dud in wires)
+ continue
+ wires += dud
+
+/datum/wires/proc/randomize()
+ var/static/list/possible_colors = list(
+ "blue",
+ "brown",
+ "crimson",
+ "cyan",
+ "gold",
+ "grey",
+ "green",
+ "magenta",
+ "orange",
+ "pink",
+ "purple",
+ "red",
+ "silver",
+ "violet",
+ "white",
+ "yellow"
+ )
+
+ var/list/my_possible_colors = possible_colors.Copy()
+
+ for(var/wire in shuffle(wires))
+ colors[pick_n_take(my_possible_colors)] = wire
+
+/datum/wires/proc/shuffle_wires()
+ colors.Cut()
+ randomize()
+
+/datum/wires/proc/repair()
+ cut_wires.Cut()
+
+/datum/wires/proc/get_wire(color)
+ return colors[color]
+
+/datum/wires/proc/get_attached(color)
+ if(assemblies[color])
+ return assemblies[color]
+ return null
+
+/datum/wires/proc/is_attached(color)
+ if(assemblies[color])
+ return TRUE
+
+/datum/wires/proc/is_cut(wire)
+ return (wire in cut_wires)
+
+/datum/wires/proc/is_color_cut(color)
+ return is_cut(get_wire(color))
+
+/datum/wires/proc/is_all_cut()
+ if(cut_wires.len == wires.len)
+ return TRUE
+
+/datum/wires/proc/cut(wire)
+ if(is_cut(wire))
+ cut_wires -= wire
+ on_cut(wire, mend = TRUE)
+ else
+ cut_wires += wire
+ on_cut(wire, mend = FALSE)
+
+/datum/wires/proc/cut_color(color)
+ cut(get_wire(color))
+
+/datum/wires/proc/cut_random()
+ cut(wires[rand(1, wires.len)])
+
+/datum/wires/proc/cut_all()
+ for(var/wire in wires)
+ cut(wire)
+
/datum/wires/proc/pulse(wire, user)
- if(is_cut(wire))
- return
+ if(is_cut(wire))
+ return
on_pulse(wire, user)
-
+
/datum/wires/proc/pulse_color(color, mob/living/user)
pulse(get_wire(color), user)
-
-/datum/wires/proc/pulse_assembly(obj/item/device/assembly/S)
- for(var/color in assemblies)
- if(S == assemblies[color])
- pulse_color(color)
- return TRUE
-
-/datum/wires/proc/attach_assembly(color, obj/item/device/assembly/S)
- if(S && istype(S) && S.attachable && !is_attached(color))
- assemblies[color] = S
- S.loc = holder
- S.connected = src
- return S
-
-/datum/wires/proc/detach_assembly(color)
- var/obj/item/device/assembly/S = get_attached(color)
- if(S && istype(S))
- assemblies -= color
- S.connected = null
- S.loc = holder.loc
- return S
-
-/datum/wires/proc/emp_pulse()
- var/list/possible_wires = shuffle(wires)
- var/remaining_pulses = MAXIMUM_EMP_WIRES
-
- for(var/wire in possible_wires)
- if(prob(33))
- pulse(wire)
- remaining_pulses--
- if(remaining_pulses >= 0)
- break
-
-// Overridable Procs
-/datum/wires/proc/interactable(mob/user)
- return TRUE
-
-/datum/wires/proc/get_status()
- return list()
-
-/datum/wires/proc/on_cut(wire, mend = FALSE)
- return
-
+
+/datum/wires/proc/pulse_assembly(obj/item/device/assembly/S)
+ for(var/color in assemblies)
+ if(S == assemblies[color])
+ pulse_color(color)
+ return TRUE
+
+/datum/wires/proc/attach_assembly(color, obj/item/device/assembly/S)
+ if(S && istype(S) && S.attachable && !is_attached(color))
+ assemblies[color] = S
+ S.forceMove(holder)
+ S.connected = src
+ return S
+
+/datum/wires/proc/detach_assembly(color)
+ var/obj/item/device/assembly/S = get_attached(color)
+ if(S && istype(S))
+ assemblies -= color
+ S.connected = null
+ S.forceMove(holder.drop_location())
+ return S
+
+/datum/wires/proc/emp_pulse()
+ var/list/possible_wires = shuffle(wires)
+ var/remaining_pulses = MAXIMUM_EMP_WIRES
+
+ for(var/wire in possible_wires)
+ if(prob(33))
+ pulse(wire)
+ remaining_pulses--
+ if(remaining_pulses >= 0)
+ break
+
+// Overridable Procs
+/datum/wires/proc/interactable(mob/user)
+ return TRUE
+
+/datum/wires/proc/get_status()
+ return list()
+
+/datum/wires/proc/on_cut(wire, mend = FALSE)
+ return
+
/datum/wires/proc/on_pulse(wire, user)
- return
-// End Overridable Procs
-
-/datum/wires/proc/interact(mob/user)
- if(!interactable(user))
- return
- ui_interact(user)
- for(var/A in assemblies)
- var/obj/item/I = assemblies[A]
- if(istype(I) && I.on_found(user))
- return
-
-/datum/wires/ui_host()
- return holder
-
-/datum/wires/ui_status(mob/user)
- if(interactable(user))
- return ..()
- return UI_CLOSE
-
+ return
+// End Overridable Procs
+
+/datum/wires/proc/interact(mob/user)
+ if(!interactable(user))
+ return
+ ui_interact(user)
+ for(var/A in assemblies)
+ var/obj/item/I = assemblies[A]
+ if(istype(I) && I.on_found(user))
+ return
+
+/datum/wires/ui_host()
+ return holder
+
+/datum/wires/ui_status(mob/user)
+ if(interactable(user))
+ return ..()
+ return UI_CLOSE
+
/datum/wires/ui_interact(mob/user, ui_key = "wires", datum/tgui/ui = null, force_open = FALSE, \
- datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
- ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
- if (!ui)
- ui = new(user, src, ui_key, "wires", "[holder.name] wires", 350, 150 + wires.len * 30, master_ui, state)
- ui.open()
-
-/datum/wires/ui_data(mob/user)
- var/list/data = list()
- var/list/payload = list()
- for(var/color in colors)
- payload.Add(list(list(
- "color" = color,
- "wire" = (IsAdminGhost(user) || (user.is_holding_item_of_type(/obj/item/device/multitool/abductor)) ? get_wire(color) : null),
- "cut" = is_color_cut(color),
- "attached" = is_attached(color)
- )))
- data["wires"] = payload
- data["status"] = get_status()
- return data
-
-/datum/wires/ui_act(action, params)
- if(..() || !interactable(usr))
- return
- var/target_wire = params["wire"]
- var/mob/living/L = usr
- var/obj/item/I = L.get_active_held_item()
- switch(action)
- if("cut")
- if(istype(I, /obj/item/wirecutters) || IsAdminGhost(usr))
- playsound(holder, I.usesound, 20, 1)
- cut_color(target_wire)
- . = TRUE
- else
- to_chat(L, "You need wirecutters! ")
- if("pulse")
- if(istype(I, /obj/item/device/multitool) || IsAdminGhost(usr))
- playsound(holder, 'sound/weapons/empty.ogg', 20, 1)
+ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
+ ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
+ if (!ui)
+ ui = new(user, src, ui_key, "wires", "[holder.name] wires", 350, 150 + wires.len * 30, master_ui, state)
+ ui.open()
+
+/datum/wires/ui_data(mob/user)
+ var/list/data = list()
+ var/list/payload = list()
+ for(var/color in colors)
+ payload.Add(list(list(
+ "color" = color,
+ "wire" = (IsAdminGhost(user) || (user.is_holding_item_of_type(/obj/item/device/multitool/abductor)) ? get_wire(color) : null),
+ "cut" = is_color_cut(color),
+ "attached" = is_attached(color)
+ )))
+ data["wires"] = payload
+ data["status"] = get_status()
+ return data
+
+/datum/wires/ui_act(action, params)
+ if(..() || !interactable(usr))
+ return
+ var/target_wire = params["wire"]
+ var/mob/living/L = usr
+ var/obj/item/I = L.get_active_held_item()
+ switch(action)
+ if("cut")
+ if(istype(I, /obj/item/wirecutters) || IsAdminGhost(usr))
+ playsound(holder, I.usesound, 20, 1)
+ cut_color(target_wire)
+ . = TRUE
+ else
+ to_chat(L, "You need wirecutters! ")
+ if("pulse")
+ if(istype(I, /obj/item/device/multitool) || IsAdminGhost(usr))
+ playsound(holder, 'sound/weapons/empty.ogg', 20, 1)
pulse_color(target_wire, L)
- . = TRUE
- else
- to_chat(L, "You need a multitool! ")
- if("attach")
- if(is_attached(target_wire))
- var/obj/item/O = detach_assembly(target_wire)
- if(O)
- L.put_in_hands(O)
- . = TRUE
- else
- if(istype(I, /obj/item/device/assembly))
- var/obj/item/device/assembly/A = I
- if(A.attachable)
- if(!L.drop_item())
- return
- attach_assembly(target_wire, A)
- . = TRUE
- else
- to_chat(L, "You need an attachable assembly! ")
-
-#undef MAXIMUM_EMP_WIRES
+ . = TRUE
+ else
+ to_chat(L, "You need a multitool! ")
+ if("attach")
+ if(is_attached(target_wire))
+ var/obj/item/O = detach_assembly(target_wire)
+ if(O)
+ L.put_in_hands(O)
+ . = TRUE
+ else
+ if(istype(I, /obj/item/device/assembly))
+ var/obj/item/device/assembly/A = I
+ if(A.attachable)
+ if(!L.drop_item())
+ return
+ attach_assembly(target_wire, A)
+ . = TRUE
+ else
+ to_chat(L, "You need an attachable assembly! ")
+
+#undef MAXIMUM_EMP_WIRES
diff --git a/code/game/area/Space_Station_13_areas.dm b/code/game/area/Space_Station_13_areas.dm
index 4846cc2bc2..c4b5c5caae 100644
--- a/code/game/area/Space_Station_13_areas.dm
+++ b/code/game/area/Space_Station_13_areas.dm
@@ -151,7 +151,11 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/maintenance/department/medical
name = "Medbay Maintenance"
- icon_state = "asmaint"
+ icon_state = "medbay_maint"
+
+/area/maintenance/department/medical/morgue
+ name = "Morgue Maintenance"
+ icon_state = "morgue_maint"
/area/maintenance/department/science
name = "Science Maintenance"
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index fafd057fea..b062b8f054 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -118,7 +118,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
else if(dynamic_lighting != DYNAMIC_LIGHTING_IFSTARLIGHT)
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
if(dynamic_lighting == DYNAMIC_LIGHTING_IFSTARLIGHT)
- dynamic_lighting = config.starlight ? DYNAMIC_LIGHTING_ENABLED : DYNAMIC_LIGHTING_DISABLED
+ dynamic_lighting = CONFIG_GET(flag/starlight) ? DYNAMIC_LIGHTING_ENABLED : DYNAMIC_LIGHTING_DISABLED
. = ..()
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 508459188b..0774253d47 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -189,6 +189,7 @@
/atom/proc/CollidedWith(atom/movable/AM)
+ set waitfor = FALSE
return
// Convenience proc to see if a container is open for chemistry handling
diff --git a/code/game/gamemodes/blob/blob.dm b/code/game/gamemodes/blob/blob.dm
index 36a23b2bd1..ddb87e20f6 100644
--- a/code/game/gamemodes/blob/blob.dm
+++ b/code/game/gamemodes/blob/blob.dm
@@ -78,7 +78,7 @@ GLOBAL_LIST_EMPTY(blobs_legit) //used for win-score calculations, contains only
var/mob/camera/blob/B = blob.current.become_overmind(TRUE, round(blob_base_starting_points/blob_overminds.len))
B.mind.name = B.name
var/turf/T = pick(GLOB.blobstart)
- B.loc = T
+ B.forceMove(T)
B.base_point_rate = blob_point_rate
SSshuttle.registerHostileEnvironment(src)
diff --git a/code/game/gamemodes/blob/blob_finish.dm b/code/game/gamemodes/blob/blob_finish.dm
index b1cea567a1..6d97fb52f9 100644
--- a/code/game/gamemodes/blob/blob_finish.dm
+++ b/code/game/gamemodes/blob/blob_finish.dm
@@ -7,7 +7,7 @@
if(B.blob_core || !B.placed)
return 0
if(!GLOB.blob_cores.len) //blob is dead
- if(config.continuous["blob"])
+ if(CONFIG_GET(keyed_flag_list/continuous)["blob"])
message_sent = FALSE //disable the win count at this point
continuous_sanity_checked = 1 //Nonstandard definition of "alive" gets past the check otherwise
SSshuttle.clearHostileEnvironment(src)
diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm
index 026183d951..865a58fd81 100644
--- a/code/game/gamemodes/blob/powers.dm
+++ b/code/game/gamemodes/blob/powers.dm
@@ -59,7 +59,7 @@
set name = "Jump to Core"
set desc = "Move your camera to your core."
if(blob_core)
- src.loc = blob_core.loc
+ forceMove(blob_core.drop_location())
/mob/camera/blob/verb/jump_to_node()
set category = "Blob"
diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm
index 8443f3d6f1..183ec88b23 100644
--- a/code/game/gamemodes/blob/theblob.dm
+++ b/code/game/gamemodes/blob/theblob.dm
@@ -190,7 +190,7 @@
B.density = TRUE
if(T.Enter(B,src)) //NOW we can attempt to move into the tile
B.density = initial(B.density)
- B.loc = T
+ B.forceMove(T)
B.update_icon()
if(B.overmind && expand_reaction)
B.overmind.blob_reagent_datum.expand_reaction(src, B, T, controller)
diff --git a/code/game/gamemodes/brother/traitor_bro.dm b/code/game/gamemodes/brother/traitor_bro.dm
index 4e8a0dc6b6..0dd3d6be0f 100644
--- a/code/game/gamemodes/brother/traitor_bro.dm
+++ b/code/game/gamemodes/brother/traitor_bro.dm
@@ -17,7 +17,7 @@
/datum/objective_team/brother_team/proc/forge_brother_objectives()
objectives = list()
var/is_hijacker = prob(10)
- for(var/i = 1 to max(1, config.brother_objectives_amount + (members.len > 2) - is_hijacker))
+ for(var/i = 1 to max(1, CONFIG_GET(number/brother_objectives_amount) + (members.len > 2) - is_hijacker))
forge_single_objective()
if(is_hijacker)
if(!locate(/datum/objective/hijack) in objectives)
@@ -58,16 +58,17 @@
var/meeting_areas = list("The Bar", "Dorms", "Escape Dock", "Arrivals", "Holodeck", "Primary Tool Storage", "Recreation Area", "Chapel", "Library")
/datum/game_mode/traitor/bros/pre_setup()
- if(config.protect_roles_from_antagonist)
+ if(CONFIG_GET(flag/protect_roles_from_antagonist))
restricted_jobs += protected_jobs
- if(config.protect_assistant_from_antagonist)
+ if(CONFIG_GET(flag/protect_assistant_from_antagonist))
restricted_jobs += "Assistant"
var/list/datum/mind/possible_brothers = get_players_for_role(ROLE_BROTHER)
var/num_teams = team_amount
- if(config.brother_scaling_coeff)
- num_teams = max(1, round(num_players()/config.brother_scaling_coeff))
+ var/bsc = CONFIG_GET(number/brother_scaling_coeff)
+ if(bsc)
+ num_teams = max(1, round(num_players() / bsc))
for(var/j = 1 to num_teams)
if(possible_brothers.len < min_team_size || antag_candidates.len <= required_enemies)
diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm
index e67ac26d3a..ae09e8ee12 100644
--- a/code/game/gamemodes/changeling/changeling.dm
+++ b/code/game/gamemodes/changeling/changeling.dm
@@ -52,16 +52,17 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
/datum/game_mode/changeling/pre_setup()
- if(config.protect_roles_from_antagonist)
+ if(CONFIG_GET(flag/protect_roles_from_antagonist))
restricted_jobs += protected_jobs
- if(config.protect_assistant_from_antagonist)
+ if(CONFIG_GET(flag/protect_assistant_from_antagonist))
restricted_jobs += "Assistant"
var/num_changelings = 1
- if(config.changeling_scaling_coeff)
- num_changelings = max(1, min( round(num_players()/(config.changeling_scaling_coeff*2))+2, round(num_players()/config.changeling_scaling_coeff) ))
+ var/csc = CONFIG_GET(number/changeling_scaling_coeff)
+ if(csc)
+ num_changelings = max(1, min(round(num_players() / (csc * 2)) + 2, round(num_players() / csc)))
else
num_changelings = max(1, min(num_players(), changeling_amount))
@@ -102,10 +103,11 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
..()
/datum/game_mode/changeling/make_antag_chance(mob/living/carbon/human/character) //Assigns changeling to latejoiners
- var/changelingcap = min( round(GLOB.joined_player_list.len/(config.changeling_scaling_coeff*2))+2, round(GLOB.joined_player_list.len/config.changeling_scaling_coeff) )
+ var/csc = CONFIG_GET(number/changeling_scaling_coeff)
+ var/changelingcap = min(round(GLOB.joined_player_list.len / (csc * 2)) + 2, round(GLOB.joined_player_list.len / csc))
if(SSticker.mode.changelings.len >= changelingcap) //Caps number of latejoin antagonists
return
- if(SSticker.mode.changelings.len <= (changelingcap - 2) || prob(100 - (config.changeling_scaling_coeff*2)))
+ if(SSticker.mode.changelings.len <= (changelingcap - 2) || prob(100 - (csc * 2)))
if(ROLE_CHANGELING in character.client.prefs.be_special)
if(!jobban_isbanned(character, ROLE_CHANGELING) && !jobban_isbanned(character, "Syndicate"))
if(age_check(character.client))
@@ -131,10 +133,16 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
changeling.objectives += absorb_objective
if(prob(60))
- var/datum/objective/steal/steal_objective = new
- steal_objective.owner = changeling
- steal_objective.find_target()
- changeling.objectives += steal_objective
+ if(prob(85))
+ var/datum/objective/steal/steal_objective = new
+ steal_objective.owner = changeling
+ steal_objective.find_target()
+ changeling.objectives += steal_objective
+ else
+ var/datum/objective/download/download_objective = new
+ download_objective.owner = changeling
+ download_objective.gen_amount_goal()
+ changeling.objectives += download_objective
var/list/active_ais = active_ais()
if(active_ais.len && prob(100/GLOB.joined_player_list.len))
diff --git a/code/game/gamemodes/changeling/powers/headcrab.dm b/code/game/gamemodes/changeling/powers/headcrab.dm
index 94d83e2520..e7f23bc07b 100644
--- a/code/game/gamemodes/changeling/powers/headcrab.dm
+++ b/code/game/gamemodes/changeling/powers/headcrab.dm
@@ -30,7 +30,7 @@
sleep(5) // So it's not killed in explosion
var/mob/living/simple_animal/hostile/headcrab/crab = new(turf)
for(var/obj/item/organ/I in organs)
- I.loc = crab
+ I.forceMove(crab)
crab.origin = M
if(crab.origin)
crab.origin.active = 1
diff --git a/code/game/gamemodes/changeling/powers/tiny_prick.dm b/code/game/gamemodes/changeling/powers/tiny_prick.dm
index ca2fd6f03e..1732e98630 100644
--- a/code/game/gamemodes/changeling/powers/tiny_prick.dm
+++ b/code/game/gamemodes/changeling/powers/tiny_prick.dm
@@ -77,10 +77,10 @@
return
..()
-/obj/effect/proc_holder/changeling/sting/transformation/can_sting(mob/user, mob/target)
+/obj/effect/proc_holder/changeling/sting/transformation/can_sting(mob/user, mob/living/carbon/target)
if(!..())
return
- if((target.disabilities & HUSK) || !target.has_dna())
+ if((target.disabilities & HUSK) || !iscarbon(target) || (NOTRANSSTING in target.dna.species.species_traits))
to_chat(user, "Our sting appears ineffective against its DNA. ")
return 0
return 1
diff --git a/code/game/gamemodes/changeling/traitor_chan.dm b/code/game/gamemodes/changeling/traitor_chan.dm
index af33b649ed..f951e31c08 100644
--- a/code/game/gamemodes/changeling/traitor_chan.dm
+++ b/code/game/gamemodes/changeling/traitor_chan.dm
@@ -25,18 +25,19 @@
return 1
/datum/game_mode/traitor/changeling/pre_setup()
- if(config.protect_roles_from_antagonist)
+ if(CONFIG_GET(flag/protect_roles_from_antagonist))
restricted_jobs += protected_jobs
- if(config.protect_assistant_from_antagonist)
+ if(CONFIG_GET(flag/protect_assistant_from_antagonist))
restricted_jobs += "Assistant"
var/list/datum/mind/possible_changelings = get_players_for_role(ROLE_CHANGELING)
var/num_changelings = 1
- if(config.changeling_scaling_coeff)
- num_changelings = max(1, min( round(num_players()/(config.changeling_scaling_coeff*4))+2, round(num_players()/(config.changeling_scaling_coeff*2)) ))
+ var/csc = CONFIG_GET(number/changeling_scaling_coeff)
+ if(csc)
+ num_changelings = max(1, min(round(num_players() / (csc * 4)) + 2, round(num_players() / (csc * 2))))
else
num_changelings = max(1, min(num_players(), changeling_amount/2))
@@ -64,11 +65,12 @@
return
/datum/game_mode/traitor/changeling/make_antag_chance(mob/living/carbon/human/character) //Assigns changeling to latejoiners
- var/changelingcap = min( round(GLOB.joined_player_list.len/(config.changeling_scaling_coeff*4))+2, round(GLOB.joined_player_list.len/(config.changeling_scaling_coeff*2)) )
+ var/csc = CONFIG_GET(number/changeling_scaling_coeff)
+ var/changelingcap = min( round(GLOB.joined_player_list.len / (csc * 4)) + 2, round(GLOB.joined_player_list.len / (csc * 2)))
if(SSticker.mode.changelings.len >= changelingcap) //Caps number of latejoin antagonists
..()
return
- if(SSticker.mode.changelings.len <= (changelingcap - 2) || prob(100 / (config.changeling_scaling_coeff * 4)))
+ if(SSticker.mode.changelings.len <= (changelingcap - 2) || prob(100 / (csc * 4)))
if(ROLE_CHANGELING in character.client.prefs.be_special)
if(!jobban_isbanned(character, ROLE_CHANGELING) && !jobban_isbanned(character, "Syndicate"))
if(age_check(character.client))
diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm
index 8272a652de..7d6f9bcdd1 100644
--- a/code/game/gamemodes/clock_cult/clock_cult.dm
+++ b/code/game/gamemodes/clock_cult/clock_cult.dm
@@ -53,6 +53,8 @@ Credit where due:
return FALSE
if(M.mind.enslaved_to && !is_servant_of_ratvar(M.mind.enslaved_to))
return FALSE
+ if(M.mind.unconvertable)
+ return FALSE
else
return FALSE
if(iscultist(M) || isconstruct(M) || M.isloyal() || ispAI(M))
@@ -107,9 +109,9 @@ Credit where due:
var/ark_time //In minutes, how long the Ark waits before activation; this is equal to 30 + (number of players / 5) (max 40 mins.)
/datum/game_mode/clockwork_cult/pre_setup()
- if(config.protect_roles_from_antagonist)
+ if(CONFIG_GET(flag/protect_roles_from_antagonist))
restricted_jobs += protected_jobs
- if(config.protect_assistant_from_antagonist)
+ if(CONFIG_GET(flag/protect_assistant_from_antagonist))
restricted_jobs += "Assistant"
var/starter_servants = 4 //Guaranteed four servants
var/number_players = num_players()
diff --git a/code/game/gamemodes/clock_cult/clock_structures/ocular_warden.dm b/code/game/gamemodes/clock_cult/clock_structures/ocular_warden.dm
index 0a7a1b53b0..cdff486eea 100644
--- a/code/game/gamemodes/clock_cult/clock_structures/ocular_warden.dm
+++ b/code/game/gamemodes/clock_cult/clock_structures/ocular_warden.dm
@@ -75,7 +75,7 @@
if(GLOB.ratvar_awakens && L)
L.adjust_fire_stacks(damage_per_tick)
L.IgniteMob()
- else if(istype(target, /obj/mecha))
+ else if(ismecha(target))
var/obj/mecha/M = target
M.take_damage(damage_per_tick * get_efficiency_mod(), BURN, "melee", 1, get_dir(src, M))
@@ -90,7 +90,7 @@
if(isliving(target))
var/mob/living/L = target
to_chat(L, "\"I SEE YOU!\" \n[src]'s gaze [GLOB.ratvar_awakens ? "melts you alive" : "burns you"]! ")
- else if(istype(target, /obj/mecha))
+ else if(ismecha(target))
var/obj/mecha/M = target
to_chat(M.occupant, "\"I SEE YOU!\" " )
else if(prob(0.5)) //Extremely low chance because of how fast the subsystem it uses processes
diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm
index 6406232596..01773f1ea6 100644
--- a/code/game/gamemodes/cult/cult.dm
+++ b/code/game/gamemodes/cult/cult.dm
@@ -21,6 +21,8 @@
return FALSE
if(M.mind.enslaved_to && !iscultist(M.mind.enslaved_to))
return FALSE
+ if(M.mind.unconvertable)
+ return FALSE
else
return FALSE
if(M.isloyal() || issilicon(M) || isbot(M) || isdrone(M) || is_servant_of_ratvar(M))
@@ -55,10 +57,10 @@
/datum/game_mode/cult/pre_setup()
cult_objectives += "sacrifice"
- if(config.protect_roles_from_antagonist)
+ if(CONFIG_GET(flag/protect_roles_from_antagonist))
restricted_jobs += protected_jobs
- if(config.protect_assistant_from_antagonist)
+ if(CONFIG_GET(flag/protect_assistant_from_antagonist))
restricted_jobs += "Assistant"
//cult scaling goes here
diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm
index 55f8ece5e6..876cace14d 100644
--- a/code/game/gamemodes/cult/cult_items.dm
+++ b/code/game/gamemodes/cult/cult_items.dm
@@ -72,6 +72,170 @@
if(is_servant_of_ratvar(C) && C.reagents)
C.reagents.add_reagent("heparin", 1)
+/obj/item/twohanded/required/cult_bastard
+ name = "bloody bastard sword"
+ desc = "An enormous sword used by Nar-Sien cultists to rapidly harvest the souls of non-believers."
+ w_class = WEIGHT_CLASS_HUGE
+ block_chance = 50
+ throwforce = 20
+ force = 35
+ armour_penetration = 45
+ throw_speed = 1
+ throw_range = 3
+ sharpness = IS_SHARP
+ light_color = "#ff0000"
+ attack_verb = list("cleaved", "slashed", "torn", "hacked", "ripped", "diced", "carved")
+ icon_state = "cultbastard"
+ item_state = "cultbastard"
+ hitsound = 'sound/weapons/bladeslice.ogg'
+ lefthand_file = 'icons/mob/inhands/64x64_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/64x64_righthand.dmi'
+ inhand_x_dimension = 64
+ inhand_y_dimension = 64
+ actions_types = list()
+ flags_2 = SLOWS_WHILE_IN_HAND_2
+ var/datum/action/innate/dash/cult/jaunt
+ var/datum/action/innate/cult/spin2win/linked_action
+ var/spinning = FALSE
+ var/spin_cooldown = 250
+ var/list/shards = list()
+ var/dash_toggled = TRUE
+
+/obj/item/twohanded/required/cult_bastard/Initialize()
+ . = ..()
+ set_light(4)
+ jaunt = new(src)
+ linked_action = new(src)
+
+/obj/item/twohanded/required/cult_bastard/can_be_pulled(user)
+ return FALSE
+
+/obj/item/twohanded/required/cult_bastard/attack_self(mob/user)
+ dash_toggled = !dash_toggled
+ if(dash_toggled)
+ to_chat(loc, "You raise the [src] and prepare to jaunt with it. ")
+ else
+ to_chat(loc, "You lower the [src] and prepare to swing it normally. ")
+
+/obj/item/twohanded/required/cult_bastard/pickup(mob/living/user)
+ . = ..()
+ if(!iscultist(user))
+ if(!is_servant_of_ratvar(user))
+ to_chat(user, "\"I wouldn't advise that.\" ")
+ to_chat(user, "An overwhelming sense of nausea overpowers you! ")
+ user.Dizzy(80)
+ user.Knockdown(30)
+ return
+ else
+ to_chat(user, "\"One of Ratvar's toys is trying to play with things [user.p_they()] shouldn't. Cute.\" ")
+ to_chat(user, "A horrible force yanks at your arm! ")
+ user.emote("scream")
+ user.apply_damage(30, BRUTE, pick("l_arm", "r_arm"))
+ user.Knockdown(50)
+ return
+ jaunt.Grant(user, src)
+ linked_action.Grant(user, src)
+ user.update_icons()
+
+/obj/item/twohanded/required/cult_bastard/dropped(mob/user)
+ . = ..()
+ linked_action.Remove(user)
+ jaunt.Remove(user)
+ user.update_icons()
+
+/obj/item/twohanded/required/cult_bastard/IsReflect()
+ if(spinning)
+ playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1)
+ return TRUE
+ else
+ ..()
+
+/obj/item/twohanded/required/cult_bastard/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
+ if(prob(final_block_chance))
+ if(attack_type == PROJECTILE_ATTACK)
+ owner.visible_message("[owner] deflects [attack_text] with [src]! ")
+ playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 100, 1)
+ return TRUE
+ else
+ playsound(src, 'sound/weapons/parry.ogg', 75, 1)
+ owner.visible_message("[owner] parries [attack_text] with [src]! ")
+ return TRUE
+ return FALSE
+
+/obj/item/twohanded/required/cult_bastard/afterattack(atom/target, mob/user, proximity, click_parameters)
+ . = ..()
+ if(dash_toggled && jaunt.IsAvailable())
+ jaunt.Teleport(user, target)
+ return
+ if(!proximity)
+ return
+ if(ishuman(target))
+ var/mob/living/carbon/human/H = target
+ if(H.stat != CONSCIOUS)
+ var/obj/item/device/soulstone/SS = new /obj/item/device/soulstone(src)
+ SS.attack(H, user)
+ shards += SS
+ return
+ if(istype(target, /obj/structure/constructshell) && contents.len)
+ var/obj/item/device/soulstone/SS = contents[1]
+ if(istype(SS) && SS.transfer_soul("CONSTRUCT",target,user))
+ qdel(SS)
+
+/datum/action/innate/dash/cult
+ name = "Rend the Veil"
+ desc = "Use the sword to shear open the flimsy fabric of this reality and teleport to your target."
+ icon_icon = 'icons/mob/actions/actions_cult.dmi'
+ button_icon_state = "phaseshift"
+ dash_sound = 'sound/magic/enter_blood.ogg'
+ recharge_sound = 'sound/magic/exit_blood.ogg'
+ beam_effect = "sendbeam"
+ phasein = /obj/effect/temp_visual/dir_setting/cult/phase
+ phaseout = /obj/effect/temp_visual/dir_setting/cult/phase/out
+
+/datum/action/innate/dash/cult/IsAvailable()
+ if(iscultist(holder) && charged)
+ return TRUE
+ else
+ return FALSE
+
+
+
+/datum/action/innate/cult/spin2win
+ name = "Geometer's Fury"
+ desc = "You draw on the power of the sword's ancient runes, spinning it wildly around you as you become immune to most attacks."
+ background_icon_state = "bg_demon"
+ button_icon_state = "sintouch"
+ var/cooldown = 0
+ var/mob/living/carbon/human/holder
+ var/obj/item/twohanded/required/cult_bastard/sword
+
+/datum/action/innate/cult/spin2win/Grant(mob/user, obj/bastard)
+ . = ..()
+ sword = bastard
+ holder = user
+
+/datum/action/innate/cult/spin2win/IsAvailable()
+ if(iscultist(holder) && cooldown <= world.time)
+ return TRUE
+ else
+ return FALSE
+
+/datum/action/innate/cult/spin2win/Activate()
+ cooldown = world.time + sword.spin_cooldown
+ holder.changeNext_move(50)
+ holder.apply_status_effect(/datum/status_effect/sword_spin)
+ sword.spinning = TRUE
+ sword.block_chance = 100
+ sword.slowdown += 1.5
+ addtimer(CALLBACK(src, .proc/stop_spinning), 50)
+ holder.update_action_buttons_icon()
+
+/datum/action/innate/cult/spin2win/proc/stop_spinning()
+ sword.spinning = FALSE
+ sword.block_chance = 50
+ sword.slowdown -= 1.5
+ sleep(sword.spin_cooldown)
+ holder.update_action_buttons_icon()
/obj/item/restraints/legcuffs/bola/cult
name = "nar'sien bola"
diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm
index ef51a2e01a..8140dffe53 100644
--- a/code/game/gamemodes/cult/cult_structures.dm
+++ b/code/game/gamemodes/cult/cult_structures.dm
@@ -100,17 +100,13 @@
if(cooldowntime > world.time)
to_chat(user, "The magic in [src] is weak, it will be ready to use again in [DisplayTimeText(cooldowntime - world.time)]. ")
return
- var/choice = alert(user,"You study the schematics etched into the forge...",,"Shielded Robe","Flagellant's Robe","Nar-Sien Hardsuit")
+ var/choice = alert(user,"You study the schematics etched into the forge...",,"Shielded Robe","Flagellant's Robe","Bastard Sword")
var/pickedtype
switch(choice)
if("Shielded Robe")
pickedtype = /obj/item/clothing/suit/hooded/cultrobes/cult_shield
if("Flagellant's Robe")
pickedtype = /obj/item/clothing/suit/hooded/cultrobes/berserker
-<<<<<<< HEAD
- if("Nar-Sien Hardsuit")
- pickedtype = /obj/item/clothing/suit/space/hardsuit/cult
-=======
if("Bastard Sword")
if((world.time - SSticker.round_start_time) >= 12000)
pickedtype = /obj/item/twohanded/required/cult_bastard
@@ -119,7 +115,6 @@
to_chat(user, "The forge fires are not yet hot enough for this weapon, give it another [DisplayTimeText(cooldowntime)]. ")
cooldowntime = 0
return
->>>>>>> e997bc4... Merge pull request #31198 from Jordie0608/apparentlythisbuildcompletedthefirsttimeidkhow
if(src && !QDELETED(src) && anchored && pickedtype && Adjacent(user) && !user.incapacitated() && iscultist(user) && cooldowntime <= world.time)
cooldowntime = world.time + 2400
var/obj/item/N = new pickedtype(get_turf(src))
diff --git a/code/game/gamemodes/devil/devil_game_mode.dm b/code/game/gamemodes/devil/devil_game_mode.dm
index 755fdef87f..844b027e93 100644
--- a/code/game/gamemodes/devil/devil_game_mode.dm
+++ b/code/game/gamemodes/devil/devil_game_mode.dm
@@ -20,15 +20,16 @@
+ Crew : Resist the lure of sin and remain pure!"
/datum/game_mode/devil/pre_setup()
- if(config.protect_roles_from_antagonist)
+ if(CONFIG_GET(flag/protect_roles_from_antagonist))
restricted_jobs += protected_jobs
- if(config.protect_assistant_from_antagonist)
+ if(CONFIG_GET(flag/protect_assistant_from_antagonist))
restricted_jobs += "Assistant"
var/num_devils = 1
- if(config.traitor_scaling_coeff)
- num_devils = max(minimum_devils, min( round(num_players()/(config.traitor_scaling_coeff*3))+ 2 + num_modifier, round(num_players()/(config.traitor_scaling_coeff*1.5)) + num_modifier ))
+ var/tsc = CONFIG_GET(number/traitor_scaling_coeff)
+ if(tsc)
+ num_devils = max(minimum_devils, min( round(num_players() / (tsc * 3))+ 2 + num_modifier, round(num_players() / (tsc * 1.5)) + num_modifier))
else
num_devils = max(minimum_devils, min(num_players(), traitors_possible))
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 18a19fb153..9f67693613 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -78,7 +78,7 @@
///Everyone should now be on the station and have their normal gear. This is the place to give the special roles extra things
/datum/game_mode/proc/post_setup(report) //Gamemodes can override the intercept report. Passing TRUE as the argument will force a report.
if(!report)
- report = config.intercept
+ report = !CONFIG_GET(flag/no_intercept_report)
addtimer(CALLBACK(GLOBAL_PROC, .proc/display_roundstart_logout_report), ROUNDSTART_LOGOUT_REPORT_TIME)
if(SSdbcore.Connect())
@@ -113,8 +113,9 @@
for(var/mob/Player in GLOB.mob_list)
if(Player.mind && Player.stat != DEAD && !isnewplayer(Player) && !isbrain(Player) && Player.client)
living_crew += Player
- if(living_crew.len / GLOB.joined_player_list.len <= config.midround_antag_life_check) //If a lot of the player base died, we start fresh
- message_admins("Convert_roundtype failed due to too many dead people. Limit is [config.midround_antag_life_check * 100]% living crew")
+ var/malc = CONFIG_GET(number/midround_antag_life_check)
+ if(living_crew.len / GLOB.joined_player_list.len <= malc) //If a lot of the player base died, we start fresh
+ message_admins("Convert_roundtype failed due to too many dead people. Limit is [malc * 100]% living crew")
return null
var/list/datum/game_mode/runnable_modes = config.get_runnable_midround_modes(living_crew.len)
@@ -138,8 +139,9 @@
if(SSshuttle.emergency.timeLeft(1) < initial(SSshuttle.emergencyCallTime)*0.5)
return 1
- if(world.time >= (config.midround_antag_time_check * 600))
- message_admins("Convert_roundtype failed due to round length. Limit is [config.midround_antag_time_check] minutes.")
+ var/matc = CONFIG_GET(number/midround_antag_time_check)
+ if(world.time >= (matc * 600))
+ message_admins("Convert_roundtype failed due to round length. Limit is [matc] minutes.")
return null
var/list/antag_candidates = list()
@@ -154,9 +156,9 @@
antag_candidates = shuffle(antag_candidates)
- if(config.protect_roles_from_antagonist)
+ if(CONFIG_GET(flag/protect_roles_from_antagonist))
replacementmode.restricted_jobs += replacementmode.protected_jobs
- if(config.protect_assistant_from_antagonist)
+ if(CONFIG_GET(flag/protect_assistant_from_antagonist))
replacementmode.restricted_jobs += "Assistant"
message_admins("The roundtype will be converted. If you have other plans for the station or feel the station is too messed up to inhabit stop the creation of antags or end the round now .")
@@ -168,7 +170,7 @@
round_converted = 0
return
//somewhere between 1 and 3 minutes from now
- if(!config.midround_antag[SSticker.mode.config_tag])
+ if(!CONFIG_GET(keyed_flag_list/midround_antag)[SSticker.mode.config_tag])
round_converted = 0
return 1
for(var/mob/living/carbon/human/H in antag_candidates)
@@ -189,7 +191,9 @@
return TRUE
if(station_was_nuked)
return TRUE
- if(!round_converted && (!config.continuous[config_tag] || (config.continuous[config_tag] && config.midround_antag[config_tag]))) //Non-continuous or continous with replacement antags
+ var/list/continuous = CONFIG_GET(keyed_flag_list/continuous)
+ var/list/midround_antag = CONFIG_GET(keyed_flag_list/midround_antag)
+ if(!round_converted && (!continuous[config_tag] || (continuous[config_tag] && midround_antag[config_tag]))) //Non-continuous or continous with replacement antags
if(!continuous_sanity_checked) //make sure we have antags to be checking in the first place
for(var/mob/Player in GLOB.mob_list)
if(Player.mind)
@@ -198,8 +202,8 @@
return 0
if(!continuous_sanity_checked)
message_admins("The roundtype ([config_tag]) has no antagonists, continuous round has been defaulted to on and midround_antag has been defaulted to off.")
- config.continuous[config_tag] = 1
- config.midround_antag[config_tag] = 0
+ continuous[config_tag] = TRUE
+ midround_antag[config_tag] = FALSE
SSshuttle.clearHostileEnvironment(src)
return 0
@@ -213,7 +217,7 @@
living_antag_player = Player
return 0
- if(!config.continuous[config_tag] || force_ending)
+ if(!continuous[config_tag] || force_ending)
return 1
else
@@ -222,7 +226,7 @@
if(round_ends_with_antag_death)
return 1
else
- config.midround_antag[config_tag] = 0
+ midround_antag[config_tag] = 0
return 0
return 0
@@ -517,7 +521,7 @@
/datum/game_mode/proc/get_remaining_days(client/C)
if(!C)
return 0
- if(!config.use_age_restriction_for_jobs)
+ if(!CONFIG_GET(flag/use_age_restriction_for_jobs))
return 0
if(!isnum(C.player_age))
return 0 //This is only a number if the db connection is established, otherwise it is text: "Requires database", meaning these restrictions cannot be enforced
diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm
index d0bb633f8c..60bbefb7fc 100644
--- a/code/game/gamemodes/meteor/meteors.dm
+++ b/code/game/gamemodes/meteor/meteors.dm
@@ -31,15 +31,16 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
var/max_i = 10//number of tries to spawn meteor.
while(!isspaceturf(pickedstart))
var/startSide = pick(GLOB.cardinals)
- pickedstart = spaceDebrisStartLoc(startSide, ZLEVEL_STATION_PRIMARY)
- pickedgoal = spaceDebrisFinishLoc(startSide, ZLEVEL_STATION_PRIMARY)
+ var/startZ = pick(GLOB.station_z_levels)
+ pickedstart = spaceDebrisStartLoc(startSide, startZ)
+ pickedgoal = spaceDebrisFinishLoc(startSide, startZ)
max_i--
if(max_i<=0)
return
var/Me = pickweight(meteortypes)
var/obj/effect/meteor/M = new Me(pickedstart)
M.dest = pickedgoal
- M.z_original = ZLEVEL_STATION_PRIMARY
+ M.z_original = M.z
spawn(0)
walk_towards(M, M.dest, 1)
diff --git a/code/game/gamemodes/miniantags/abduction/abduction.dm b/code/game/gamemodes/miniantags/abduction/abduction.dm
index ed5c2e9d76..d6f1b775e9 100644
--- a/code/game/gamemodes/miniantags/abduction/abduction.dm
+++ b/code/game/gamemodes/miniantags/abduction/abduction.dm
@@ -34,7 +34,7 @@
to_chat(world, "Crew - don't get abducted and stop the abductors.")
/datum/game_mode/abduction/pre_setup()
- var/num_teams = max(1, min(max_teams, round(num_players() / config.abductor_scaling_coeff)))
+ var/num_teams = max(1, min(max_teams, round(num_players() / CONFIG_GET(number/abductor_scaling_coeff))))
var/possible_teams = max(1, round(antag_candidates.len / 2))
num_teams = min(num_teams, possible_teams)
diff --git a/code/game/gamemodes/miniantags/abduction/gland.dm b/code/game/gamemodes/miniantags/abduction/gland.dm
index 8c408c007e..0458690a40 100644
--- a/code/game/gamemodes/miniantags/abduction/gland.dm
+++ b/code/game/gamemodes/miniantags/abduction/gland.dm
@@ -218,7 +218,7 @@
/obj/structure/spider/cocoon/abductor/proc/Copy(mob/living/carbon/human/H)
var/mob/living/carbon/human/interactive/greytide/clone = new(src)
- clone.hardset_dna(H.dna.uni_identity,H.dna.struc_enzymes,H.real_name, H.dna.blood_type, H.dna.species.type, H.dna.features)
+ clone.hardset_dna(H.dna.uni_identity,H.dna.struc_enzymes,H.real_name, H.dna.blood_type, H.dna.species, H.dna.features)
/obj/structure/spider/cocoon/abductor/proc/Start()
hatch_time = world.time + 600
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm b/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm
index 88bb84fc4a..2b012e5f81 100644
--- a/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm
+++ b/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm
@@ -60,9 +60,8 @@
/obj/machinery/abductor/gland_dispenser/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/organ/heart/gland))
- if(!user.drop_item())
+ if(!user.transferItemToLoc(W, src))
return
- W.loc = src
for(var/i=1,i<=gland_colors.len,i++)
if(gland_types[i] == W.type)
amounts[i]++
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
index 0a7427b610..99059e7a25 100644
--- a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
+++ b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
@@ -62,7 +62,7 @@
/obj/machinery/abductor/experiment/proc/dissection_icon(mob/living/carbon/human/H)
var/icon/photo = null
var/g = (H.gender == FEMALE) ? "f" : "m"
- if(!config.mutant_races || H.dna.species.use_skintones)
+ if(!CONFIG_GET(flag/join_with_mutant_race) || H.dna.species.use_skintones)
photo = icon("icon" = 'icons/mob/human.dmi', "icon_state" = "[H.skin_tone]_[g]")
else
photo = icon("icon" = 'icons/mob/human.dmi', "icon_state" = "[H.dna.species.id]_[g]")
diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
index 8979fb8c78..c125f7648d 100644
--- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
+++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
@@ -468,11 +468,8 @@
return
var/turf/open/floor/F
- switch(z) //Only the station/lavaland
- if(ZLEVEL_STATION_PRIMARY)
- F =find_safe_turf(zlevels = ZLEVEL_STATION_PRIMARY, extended_safety_checks = TRUE)
- if(ZLEVEL_LAVALAND)
- F = find_safe_turf(zlevels = ZLEVEL_LAVALAND, extended_safety_checks = TRUE)
+ F = find_safe_turf(zlevels = z, extended_safety_checks = TRUE)
+
if(!F)
return
// If we're getting rid of a human, slap some energy cuffs on
@@ -502,7 +499,7 @@
var/obj/item/stack/sheet/metal/M = new /obj/item/stack/sheet/metal(target.loc)
M.amount = 5
for(var/obj/item/I in target.component_parts)
- I.loc = M.loc
+ I.forceMove(M.drop_location())
var/obj/effect/temp_visual/swarmer/disintegration/N = new /obj/effect/temp_visual/swarmer/disintegration(get_turf(target))
N.pixel_x = target.pixel_x
N.pixel_y = target.pixel_y
@@ -511,7 +508,7 @@
if(istype(target, /obj/machinery/computer))
var/obj/machinery/computer/C = target
if(C.circuit)
- C.circuit.loc = M.loc
+ C.circuit.forceMove(M.drop_location())
qdel(target)
diff --git a/code/game/gamemodes/miniantags/morph/morph.dm b/code/game/gamemodes/miniantags/morph/morph.dm
index f763f742f7..5e1a97675b 100644
--- a/code/game/gamemodes/miniantags/morph/morph.dm
+++ b/code/game/gamemodes/miniantags/morph/morph.dm
@@ -77,7 +77,7 @@
/mob/living/simple_animal/hostile/morph/proc/eat(atom/movable/A)
if(A && A.loc != src)
visible_message("[src] swallows [A] whole! ")
- A.loc = src
+ A.forceMove(src)
return 1
return 0
@@ -153,7 +153,7 @@
/mob/living/simple_animal/hostile/morph/proc/barf_contents()
for(var/atom/movable/AM in src)
- AM.loc = loc
+ AM.forceMove(loc)
if(prob(90))
step(AM, pick(GLOB.alldirs))
diff --git a/code/game/gamemodes/miniantags/revenant/revenant_spawn_event.dm b/code/game/gamemodes/miniantags/revenant/revenant_spawn_event.dm
index 783cfdd930..fb0bdfb6f9 100644
--- a/code/game/gamemodes/miniantags/revenant/revenant_spawn_event.dm
+++ b/code/game/gamemodes/miniantags/revenant/revenant_spawn_event.dm
@@ -34,17 +34,13 @@
var/list/spawn_locs = list()
- for(var/obj/effect/landmark/L in GLOB.landmarks_list)
+ for(var/obj/effect/landmark/revenantspawn/L in GLOB.landmarks_list)
if(isturf(L.loc))
- switch(L.name)
- if("revenantspawn")
- spawn_locs += L.loc
+ spawn_locs += L.loc
if(!spawn_locs.len) //If we can't find any revenant spawns, try the carp spawns
- for(var/obj/effect/landmark/L in GLOB.landmarks_list)
+ for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
if(isturf(L.loc))
- switch(L.name)
- if("carpspawn")
- spawn_locs += L.loc
+ spawn_locs += L.loc
if(!spawn_locs.len) //If we can't find either, just spawn the revenant at the player's location
spawn_locs += get_turf(selected)
if(!spawn_locs.len) //If we can't find THAT, then just give up and cry
diff --git a/code/game/gamemodes/miniantags/slaughter/slaughterevent.dm b/code/game/gamemodes/miniantags/slaughter/slaughterevent.dm
index 888a10669e..4d85744738 100644
--- a/code/game/gamemodes/miniantags/slaughter/slaughterevent.dm
+++ b/code/game/gamemodes/miniantags/slaughter/slaughterevent.dm
@@ -23,11 +23,9 @@
player_mind.active = 1
var/list/spawn_locs = list()
- for(var/obj/effect/landmark/L in GLOB.landmarks_list)
+ for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
if(isturf(L.loc))
- switch(L.name)
- if("carpspawn")
- spawn_locs += L.loc
+ spawn_locs += L.loc
if(!spawn_locs)
message_admins("No valid spawn locations found, aborting...")
diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm
index acf55e4036..2179177fc1 100644
--- a/code/game/gamemodes/nuclear/nuclear.dm
+++ b/code/game/gamemodes/nuclear/nuclear.dm
@@ -110,7 +110,7 @@
P.info = "The nuclear authorization code is: [nuke_code] "
P.name = "nuclear bomb code"
var/mob/living/carbon/human/H = synd_mind.current
- P.loc = H.loc
+ P.forceMove(H.drop_location())
H.put_in_hands_or_del(P)
H.update_icons()
else
diff --git a/code/game/gamemodes/nuclear/nuclear_challenge.dm b/code/game/gamemodes/nuclear/nuclear_challenge.dm
index f51b9ac914..6e7a567324 100644
--- a/code/game/gamemodes/nuclear/nuclear_challenge.dm
+++ b/code/game/gamemodes/nuclear/nuclear_challenge.dm
@@ -58,7 +58,7 @@
U.hidden_uplink.owner = "[user.key]"
U.hidden_uplink.telecrystals = CHALLENGE_TELECRYSTALS
U.hidden_uplink.set_gamemode(/datum/game_mode/nuclear)
- config.shuttle_refuel_delay = max(config.shuttle_refuel_delay, CHALLENGE_SHUTTLE_DELAY)
+ CONFIG_SET(number/shuttle_refuel_delay, max(CONFIG_GET(number/shuttle_refuel_delay), CHALLENGE_SHUTTLE_DELAY))
SSblackbox.set_val("nuclear_challenge_mode",1)
qdel(src)
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index c00328243a..effe2212a7 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -17,14 +17,6 @@
if(owner)
. += owner
-/datum/objective/proc/considered_alive(var/datum/mind/M)
- if(M && M.current)
- var/mob/living/carbon/human/H
- if(ishuman(M.current))
- H = M.current
- return M.current.stat != DEAD && !issilicon(M.current) && !isbrain(M.current) && (!H || H.dna.species.id != "memezombies")
- return FALSE
-
/datum/objective/proc/considered_escaped(datum/mind/M)
if(!considered_alive(M))
return FALSE
@@ -37,9 +29,6 @@
return FALSE
return location.onCentCom() || location.onSyndieBase()
-/datum/objective/proc/considered_afk(datum/mind/M)
- return !M || !M.current || !M.current.client || M.current.client.is_afk()
-
/datum/objective/proc/check_completion()
return completed
@@ -348,13 +337,14 @@
return FALSE
return TRUE
-//Like survive, but works for silicons and zombies and such.
-/datum/objective/survive/exist/considered_alive(var/datum/mind/M)
- if(M && M.current)
- if(isliving(M.current))
- var/mob/living/L = M.current
- return L.stat != DEAD
- return FALSE
+/datum/objective/survive/exist //Like survive, but works for silicons and zombies and such.
+
+/datum/objective/survive/exist/check_completion()
+ var/list/datum/mind/owners = get_owners()
+ for(var/datum/mind/M in owners)
+ if(!considered_alive(M, FALSE))
+ return FALSE
+ return TRUE
/datum/objective/martyr
explanation_text = "Die a glorious death."
@@ -506,24 +496,31 @@ GLOBAL_LIST_EMPTY(possible_items_special)
explanation_text = "Download [target_amount] research level\s."
return target_amount
-/datum/objective/download/check_completion()//NINJACODE.
- var/current_amount = 0
+/datum/objective/download/check_completion()
+ var/list/current_tech = list()
var/list/datum/mind/owners = get_owners()
- for(var/datum/mind/M in owners)
- if(!ishuman(owner.current))
- continue
- var/mob/living/carbon/human/H = owner.current
- if(!H || H.stat == DEAD || !istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja))
- continue
- var/obj/item/clothing/suit/space/space_ninja/SN = H.wear_suit
- if(!SN.s_initialized)
- continue
- for(var/datum/tech/current_data in SN.stored_research)
- if(current_data.level)
- current_amount += (current_data.level-1)
- return current_amount >= target_amount
-
-
+ for(var/datum/mind/owner in owners)
+ if(ismob(owner.current))
+ var/mob/M = owner.current //Yeah if you get morphed and you eat a quantum tech disk with the RD's latest backup good on you soldier.
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ if(H && (H.stat != DEAD) && istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja))
+ var/obj/item/clothing/suit/space/space_ninja/S = H.wear_suit
+ for(var/datum/tech/T in S.stored_research)
+ current_tech[T.id] = T.level? T.level : 0
+ var/list/otherwise = M.GetAllContents()
+ for(var/obj/item/disk/tech_disk/TD in otherwise)
+ for(var/datum/tech/T in TD.tech_stored)
+ if(!T.id || !T.level)
+ continue
+ else if(!current_tech[T.id])
+ current_tech[T.id] = T.level
+ else if(T.level > current_tech[T.id])
+ current_tech[T.id] = T.level
+ var/total = 0
+ for(var/i in current_tech)
+ total += current_tech[i]
+ return total >= target_amount
/datum/objective/capture
@@ -586,7 +583,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
for(var/datum/mind/M in owners)
if(!owner || !owner.changeling || !owner.changeling.stored_profiles)
continue
- absorbedcount += M.changeling.absorbedcount
+ absorbedcount += M.changeling.absorbedcount
return absorbedcount >= target_amount
diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm
index d538c7f75e..c1b6d13456 100644
--- a/code/game/gamemodes/revolution/revolution.dm
+++ b/code/game/gamemodes/revolution/revolution.dm
@@ -44,10 +44,10 @@
///////////////////////////////////////////////////////////////////////////////
/datum/game_mode/revolution/pre_setup()
- if(config.protect_roles_from_antagonist)
+ if(CONFIG_GET(flag/protect_roles_from_antagonist))
restricted_jobs += protected_jobs
- if(config.protect_assistant_from_antagonist)
+ if(CONFIG_GET(flag/protect_assistant_from_antagonist))
restricted_jobs += "Assistant"
for (var/i=1 to max_headrevs)
@@ -230,7 +230,7 @@
//Checks if the round is over//
///////////////////////////////
/datum/game_mode/revolution/check_finished()
- if(config.continuous["revolution"])
+ if(CONFIG_GET(keyed_flag_list/continuous)["revolution"])
if(finished)
SSshuttle.clearHostileEnvironment(src)
return ..()
@@ -253,12 +253,14 @@
/datum/game_mode/proc/add_revolutionary(datum/mind/rev_mind)
if(rev_mind.assigned_role in GLOB.command_positions)
- return 0
+ return FALSE
var/mob/living/carbon/human/H = rev_mind.current//Check to see if the potential rev is implanted
if(H.isloyal())
- return 0
+ return FALSE
if((rev_mind in revolutionaries) || (rev_mind in head_revolutionaries))
- return 0
+ return FALSE
+ if(rev_mind.unconvertable)
+ return FALSE
revolutionaries += rev_mind
if(iscarbon(rev_mind.current))
var/mob/living/carbon/carbon_mob = rev_mind.current
@@ -271,7 +273,7 @@
update_rev_icons_added(rev_mind)
if(jobban_isbanned(rev_mind.current, ROLE_REV))
INVOKE_ASYNC(src, .proc/replace_jobbaned_player, rev_mind.current, ROLE_REV, ROLE_REV)
- return 1
+ return TRUE
//////////////////////////////////////////////////////////////////////////////
//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.
//////////////////////////////////////////////////////////////////////////////
@@ -329,7 +331,7 @@
/datum/game_mode/revolution/proc/check_heads_victory()
for(var/datum/mind/rev_mind in head_revolutionaries)
var/turf/T = get_turf(rev_mind.current)
- if((rev_mind) && (rev_mind.current) && (rev_mind.current.stat != DEAD) && T && (T.z in GLOB.station_z_levels))
+ if(!considered_afk(rev_mind) && considered_alive(rev_mind) && (T.z in GLOB.station_z_levels))
if(ishuman(rev_mind.current))
return 0
return 1
diff --git a/code/game/gamemodes/sandbox/h_sandbox.dm b/code/game/gamemodes/sandbox/h_sandbox.dm
index 7a17d54b4c..15cd346b2d 100644
--- a/code/game/gamemodes/sandbox/h_sandbox.dm
+++ b/code/game/gamemodes/sandbox/h_sandbox.dm
@@ -1,303 +1,303 @@
-
-
-GLOBAL_VAR_INIT(hsboxspawn, TRUE)
-
-/mob
- var/datum/hSB/sandbox = null
-/mob/proc/CanBuild()
- sandbox = new/datum/hSB
- sandbox.owner = src.ckey
- if(src.client.holder)
- sandbox.admin = 1
- verbs += new/mob/proc/sandbox_panel
-/mob/proc/sandbox_panel()
- set name = "Sandbox Panel"
- if(sandbox)
- sandbox.update()
-
-/datum/hSB
- var/owner = null
- var/admin = 0
-
+
+
+GLOBAL_VAR_INIT(hsboxspawn, TRUE)
+
+/mob
+ var/datum/hSB/sandbox = null
+/mob/proc/CanBuild()
+ sandbox = new/datum/hSB
+ sandbox.owner = src.ckey
+ if(src.client.holder)
+ sandbox.admin = 1
+ verbs += new/mob/proc/sandbox_panel
+/mob/proc/sandbox_panel()
+ set name = "Sandbox Panel"
+ if(sandbox)
+ sandbox.update()
+
+/datum/hSB
+ var/owner = null
+ var/admin = 0
+
var/static/clothinfo = null
var/static/reaginfo = null
var/static/objinfo = null
- var/canisterinfo = null
- var/hsbinfo = null
- //items that shouldn't spawn on the floor because they would bug or act weird
- var/global/list/spawn_forbidden = list(
- /obj/item/tk_grab, /obj/item/implant, // not implanter, the actual thing that is inside you
+ var/canisterinfo = null
+ var/hsbinfo = null
+ //items that shouldn't spawn on the floor because they would bug or act weird
+ var/global/list/spawn_forbidden = list(
+ /obj/item/tk_grab, /obj/item/implant, // not implanter, the actual thing that is inside you
/obj/item/assembly, /obj/item/device/onetankbomb, /obj/item/radio, /obj/item/device/pda/ai,
- /obj/item/device/uplink, /obj/item/smallDelivery, /obj/item/projectile,
+ /obj/item/device/uplink, /obj/item/smallDelivery, /obj/item/projectile,
/obj/item/borg/sight, /obj/item/borg/stun, /obj/item/robot_module)
-
-/datum/hSB/proc/update()
- var/global/list/hrefs = list(
- "Space Gear",
- "Suit Up (Space Travel Gear)" = "hsbsuit",
- "Spawn Gas Mask" = "hsbspawn&path=[/obj/item/clothing/mask/gas]",
- "Spawn Emergency Air Tank" = "hsbspawn&path=[/obj/item/tank/internals/emergency_oxygen/double]",
-
- "Standard Tools",
- "Spawn Flashlight" = "hsbspawn&path=[/obj/item/device/flashlight]",
- "Spawn Toolbox" = "hsbspawn&path=[/obj/item/storage/toolbox/mechanical]",
- "Spawn Light Replacer" = "hsbspawn&path=[/obj/item/device/lightreplacer]",
- "Spawn Medical Kit" = "hsbspawn&path=[/obj/item/storage/firstaid/regular]",
- "Spawn All-Access ID" = "hsbaaid",
-
- "Building Supplies",
- "Spawn 50 Wood" = "hsbwood",
- "Spawn 50 Metal" = "hsbmetal",
- "Spawn 50 Plasteel" = "hsbplasteel",
- "Spawn 50 Reinforced Glass" = "hsbrglass",
- "Spawn 50 Glass" = "hsbglass",
- "Spawn Full Cable Coil" = "hsbspawn&path=[/obj/item/stack/cable_coil]",
- "Spawn Hyper Capacity Power Cell" = "hsbspawn&path=[/obj/item/stock_parts/cell/hyper]",
- "Spawn Inf. Capacity Power Cell" = "hsbspawn&path=[/obj/item/stock_parts/cell/infinite]",
- "Spawn Rapid Construction Device" = "hsbrcd",
- "Spawn RCD Ammo" = "hsb_safespawn&path=[/obj/item/rcd_ammo]",
- "Spawn Airlock" = "hsbairlock",
-
- "Miscellaneous",
- "Spawn Air Scrubber" = "hsbscrubber",
- "Spawn Welding Fuel Tank" = "hsbspawn&path=[/obj/structure/reagent_dispensers/fueltank]",
- "Spawn Water Tank" = "hsbspawn&path=[/obj/structure/reagent_dispensers/watertank]",
-
- "Bots",
- "Spawn Cleanbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/cleanbot]",
- "Spawn Floorbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/floorbot]",
- "Spawn Medbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/medbot]",
-
- "Canisters",
- "Spawn O2 Canister" = "hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/oxygen]",
- "Spawn Air Canister" = "hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/air]")
-
-
- if(!hsbinfo)
- hsbinfo = "Sandbox Panel "
- if(admin)
- hsbinfo += "Administration "
- hsbinfo += "- Toggle Object Spawning "
- hsbinfo += "- Toggle Item Spawn Panel Auto-close "
- hsbinfo += "Canister Spawning "
- hsbinfo += "- Spawn Plasma Canister "
- hsbinfo += "- Spawn CO2 Canister "
- hsbinfo += "- Spawn Nitrogen Canister "
- hsbinfo += "- Spawn N2O Canister "
- else
- hsbinfo += "Some item spawning may be disabled by the administrators. "
- hsbinfo += "Only administrators may spawn dangerous canisters. "
- for(var/T in hrefs)
- var/href = hrefs[T]
- if(href)
- hsbinfo += "- [T] "
- else
- hsbinfo += "[T] "
- hsbinfo += " "
- hsbinfo += "- Spawn Clothing... "
- hsbinfo += "- Spawn Reagent Container... "
- hsbinfo += "- Spawn Other Item... "
-
- usr << browse(hsbinfo, "window=hsbpanel")
-
-/datum/hSB/Topic(href, href_list)
- if(!usr || !src || !(src.owner == usr.ckey))
- if(usr)
- usr << browse(null,"window=sandbox")
- return
-
- if(href_list["hsb"])
- switch(href_list["hsb"])
- //
- // Admin: toggle spawning
- //
- if("hsbtobj")
- if(!admin) return
- if(GLOB.hsboxspawn)
- to_chat(world, "Sandbox: \black[usr.key] has disabled object spawning! ")
- GLOB.hsboxspawn = FALSE
- return
- else
- to_chat(world, "Sandbox: \black[usr.key] has enabled object spawning! ")
- GLOB.hsboxspawn = TRUE
- return
- //
- // Admin: Toggle auto-close
- //
- if("hsbtac")
- if(!admin) return
- if(config.sandbox_autoclose)
- to_chat(world, "Sandbox: \black [usr.key] has removed the object spawn limiter. ")
- config.sandbox_autoclose = FALSE
- else
- to_chat(world, "Sandbox: \black [usr.key] has added a limiter to object spawning. The window will now auto-close after use. ")
- config.sandbox_autoclose = TRUE
- return
- //
- // Spacesuit with full air jetpack set as internals
- //
- if("hsbsuit")
- var/mob/living/carbon/human/P = usr
- if(!istype(P)) return
- if(P.wear_suit)
- P.wear_suit.loc = P.loc
- P.wear_suit.layer = initial(P.wear_suit.layer)
- P.wear_suit.plane = initial(P.wear_suit.plane)
- P.wear_suit = null
- P.wear_suit = new/obj/item/clothing/suit/space(P)
- P.wear_suit.layer = ABOVE_HUD_LAYER
- P.wear_suit.plane = ABOVE_HUD_PLANE
- P.update_inv_wear_suit()
- if(P.head)
- P.head.loc = P.loc
- P.head.layer = initial(P.head.layer)
- P.head.plane = initial(P.head.plane)
- P.head = null
- P.head = new/obj/item/clothing/head/helmet/space(P)
- P.head.layer = ABOVE_HUD_LAYER
- P.head.plane = ABOVE_HUD_PLANE
- P.update_inv_head()
- if(P.wear_mask)
- P.wear_mask.loc = P.loc
- P.wear_mask.layer = initial(P.wear_mask.layer)
- P.wear_mask.plane = initial(P.wear_mask.plane)
- P.wear_mask = null
- P.wear_mask = new/obj/item/clothing/mask/gas(P)
- P.wear_mask.layer = ABOVE_HUD_LAYER
- P.wear_mask.plane = ABOVE_HUD_PLANE
- P.update_inv_wear_mask()
- if(P.back)
- P.back.loc = P.loc
- P.back.layer = initial(P.back.layer)
- P.back.plane = initial(P.back.plane)
- P.back = null
- P.back = new/obj/item/tank/jetpack/oxygen(P)
- P.back.layer = ABOVE_HUD_LAYER
- P.back.plane = ABOVE_HUD_PLANE
- P.update_inv_back()
- P.internal = P.back
- P.update_internals_hud_icon(1)
-
- if("hsbscrubber") // This is beyond its normal capability but this is sandbox and you spawned one, I assume you need it
- var/obj/hsb = new/obj/machinery/portable_atmospherics/scrubber{volume_rate=50*ONE_ATMOSPHERE;on=1}(usr.loc)
- hsb.update_icon() // hackish but it wasn't meant to be spawned I guess?
-
- //
- // Stacked Materials
- //
-
- if("hsbrglass")
- new/obj/item/stack/sheet/rglass{amount=50}(usr.loc)
-
- if("hsbmetal")
- new/obj/item/stack/sheet/metal{amount=50}(usr.loc)
-
- if("hsbplasteel")
- new/obj/item/stack/sheet/plasteel{amount=50}(usr.loc)
-
- if("hsbglass")
- new/obj/item/stack/sheet/glass{amount=50}(usr.loc)
-
- if("hsbwood")
- new/obj/item/stack/sheet/mineral/wood{amount=50}(usr.loc)
-
- //
- // All access ID
- //
- if("hsbaaid")
- var/obj/item/card/id/gold/ID = new(usr.loc)
- ID.registered_name = usr.real_name
- ID.assignment = "Sandbox"
- ID.access = get_all_accesses()
- ID.update_label()
-
- //
- // RCD - starts with full clip
- // Spawn check due to grief potential (destroying floors, walls, etc)
- //
- if("hsbrcd")
- if(!GLOB.hsboxspawn) return
-
- new/obj/item/construction/rcd/combat(usr.loc)
-
- //
- // New sandbox airlock maker
- //
- if("hsbairlock")
- new /datum/airlock_maker(usr.loc)
-
- //
- // Object spawn window
- //
-
- // Clothing
- if("hsbcloth")
- if(!GLOB.hsboxspawn) return
-
- if(!clothinfo)
- clothinfo = "Clothing (Reagent Containers) (Other Items) "
- var/list/all_items = subtypesof(/obj/item/clothing)
- for(var/typekey in spawn_forbidden)
- all_items -= typesof(typekey)
- for(var/O in reverseRange(all_items))
- clothinfo += "[O] "
-
- usr << browse(clothinfo,"window=sandbox")
-
- // Reagent containers
- if("hsbreag")
- if(!GLOB.hsboxspawn) return
-
- if(!reaginfo)
- reaginfo = "Reagent Containers (Clothing) (Other Items) "
- var/list/all_items = subtypesof(/obj/item/reagent_containers)
- for(var/typekey in spawn_forbidden)
- all_items -= typesof(typekey)
- for(var/O in reverseRange(all_items))
- reaginfo += "[O] "
-
- usr << browse(reaginfo,"window=sandbox")
-
- // Other items
- if("hsbobj")
- if(!GLOB.hsboxspawn) return
-
- if(!objinfo)
- objinfo = "Other Items (Clothing) (Reagent Containers) "
- var/list/all_items = subtypesof(/obj/item/) - typesof(/obj/item/clothing) - typesof(/obj/item/reagent_containers)
- for(var/typekey in spawn_forbidden)
- all_items -= typesof(typekey)
-
- for(var/O in reverseRange(all_items))
- objinfo += "[O] "
-
- usr << browse(objinfo,"window=sandbox")
-
- //
- // Safespawn checks to see if spawning is disabled.
- //
- if("hsb_safespawn")
- if(!GLOB.hsboxspawn)
- usr << browse(null,"window=sandbox")
- return
-
- var/typepath = text2path(href_list["path"])
- if(!typepath)
- to_chat(usr, "Bad path: \"[href_list["path"]]\"")
- return
- new typepath(usr.loc)
-
- if(config.sandbox_autoclose)
- usr << browse(null,"window=sandbox")
- //
- // For everything else in the href list
- //
- if("hsbspawn")
- var/typepath = text2path(href_list["path"])
- if(!typepath)
- to_chat(usr, "Bad path: \"[href_list["path"]]\"")
- return
- new typepath(usr.loc)
-
- if(config.sandbox_autoclose)
- usr << browse(null,"window=sandbox")
+
+/datum/hSB/proc/update()
+ var/global/list/hrefs = list(
+ "Space Gear",
+ "Suit Up (Space Travel Gear)" = "hsbsuit",
+ "Spawn Gas Mask" = "hsbspawn&path=[/obj/item/clothing/mask/gas]",
+ "Spawn Emergency Air Tank" = "hsbspawn&path=[/obj/item/tank/internals/emergency_oxygen/double]",
+
+ "Standard Tools",
+ "Spawn Flashlight" = "hsbspawn&path=[/obj/item/device/flashlight]",
+ "Spawn Toolbox" = "hsbspawn&path=[/obj/item/storage/toolbox/mechanical]",
+ "Spawn Light Replacer" = "hsbspawn&path=[/obj/item/device/lightreplacer]",
+ "Spawn Medical Kit" = "hsbspawn&path=[/obj/item/storage/firstaid/regular]",
+ "Spawn All-Access ID" = "hsbaaid",
+
+ "Building Supplies",
+ "Spawn 50 Wood" = "hsbwood",
+ "Spawn 50 Metal" = "hsbmetal",
+ "Spawn 50 Plasteel" = "hsbplasteel",
+ "Spawn 50 Reinforced Glass" = "hsbrglass",
+ "Spawn 50 Glass" = "hsbglass",
+ "Spawn Full Cable Coil" = "hsbspawn&path=[/obj/item/stack/cable_coil]",
+ "Spawn Hyper Capacity Power Cell" = "hsbspawn&path=[/obj/item/stock_parts/cell/hyper]",
+ "Spawn Inf. Capacity Power Cell" = "hsbspawn&path=[/obj/item/stock_parts/cell/infinite]",
+ "Spawn Rapid Construction Device" = "hsbrcd",
+ "Spawn RCD Ammo" = "hsb_safespawn&path=[/obj/item/rcd_ammo]",
+ "Spawn Airlock" = "hsbairlock",
+
+ "Miscellaneous",
+ "Spawn Air Scrubber" = "hsbscrubber",
+ "Spawn Welding Fuel Tank" = "hsbspawn&path=[/obj/structure/reagent_dispensers/fueltank]",
+ "Spawn Water Tank" = "hsbspawn&path=[/obj/structure/reagent_dispensers/watertank]",
+
+ "Bots",
+ "Spawn Cleanbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/cleanbot]",
+ "Spawn Floorbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/floorbot]",
+ "Spawn Medbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/medbot]",
+
+ "Canisters",
+ "Spawn O2 Canister" = "hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/oxygen]",
+ "Spawn Air Canister" = "hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/air]")
+
+
+ if(!hsbinfo)
+ hsbinfo = "Sandbox Panel "
+ if(admin)
+ hsbinfo += "Administration "
+ hsbinfo += "- Toggle Object Spawning "
+ hsbinfo += "- Toggle Item Spawn Panel Auto-close "
+ hsbinfo += "Canister Spawning "
+ hsbinfo += "- Spawn Plasma Canister "
+ hsbinfo += "- Spawn CO2 Canister "
+ hsbinfo += "- Spawn Nitrogen Canister "
+ hsbinfo += "- Spawn N2O Canister "
+ else
+ hsbinfo += "Some item spawning may be disabled by the administrators. "
+ hsbinfo += "Only administrators may spawn dangerous canisters. "
+ for(var/T in hrefs)
+ var/href = hrefs[T]
+ if(href)
+ hsbinfo += "- [T] "
+ else
+ hsbinfo += "[T] "
+ hsbinfo += " "
+ hsbinfo += "- Spawn Clothing... "
+ hsbinfo += "- Spawn Reagent Container... "
+ hsbinfo += "- Spawn Other Item... "
+
+ usr << browse(hsbinfo, "window=hsbpanel")
+
+/datum/hSB/Topic(href, href_list)
+ if(!usr || !src || !(src.owner == usr.ckey))
+ if(usr)
+ usr << browse(null,"window=sandbox")
+ return
+
+ if(href_list["hsb"])
+ switch(href_list["hsb"])
+ //
+ // Admin: toggle spawning
+ //
+ if("hsbtobj")
+ if(!admin) return
+ if(GLOB.hsboxspawn)
+ to_chat(world, "Sandbox: \black[usr.key] has disabled object spawning! ")
+ GLOB.hsboxspawn = FALSE
+ return
+ else
+ to_chat(world, "Sandbox: \black[usr.key] has enabled object spawning! ")
+ GLOB.hsboxspawn = TRUE
+ return
+ //
+ // Admin: Toggle auto-close
+ //
+ if("hsbtac")
+ if(!admin) return
+ var/sbac = CONFIG_GET(flag/sandbox_autoclose)
+ if(sbac)
+ to_chat(world, "Sandbox: \black [usr.key] has removed the object spawn limiter. ")
+ else
+ to_chat(world, "Sandbox: \black [usr.key] has added a limiter to object spawning. The window will now auto-close after use. ")
+ CONFIG_SET(flag/sandbox_autoclose, !sbac)
+ return
+ //
+ // Spacesuit with full air jetpack set as internals
+ //
+ if("hsbsuit")
+ var/mob/living/carbon/human/P = usr
+ if(!istype(P)) return
+ if(P.wear_suit)
+ P.wear_suit.forceMove(P.drop_location())
+ P.wear_suit.layer = initial(P.wear_suit.layer)
+ P.wear_suit.plane = initial(P.wear_suit.plane)
+ P.wear_suit = null
+ P.wear_suit = new/obj/item/clothing/suit/space(P)
+ P.wear_suit.layer = ABOVE_HUD_LAYER
+ P.wear_suit.plane = ABOVE_HUD_PLANE
+ P.update_inv_wear_suit()
+ if(P.head)
+ P.head.forceMove(P.drop_location())
+ P.head.layer = initial(P.head.layer)
+ P.head.plane = initial(P.head.plane)
+ P.head = null
+ P.head = new/obj/item/clothing/head/helmet/space(P)
+ P.head.layer = ABOVE_HUD_LAYER
+ P.head.plane = ABOVE_HUD_PLANE
+ P.update_inv_head()
+ if(P.wear_mask)
+ P.wear_mask.forceMove(P.drop_location())
+ P.wear_mask.layer = initial(P.wear_mask.layer)
+ P.wear_mask.plane = initial(P.wear_mask.plane)
+ P.wear_mask = null
+ P.wear_mask = new/obj/item/clothing/mask/gas(P)
+ P.wear_mask.layer = ABOVE_HUD_LAYER
+ P.wear_mask.plane = ABOVE_HUD_PLANE
+ P.update_inv_wear_mask()
+ if(P.back)
+ P.back.forceMove(P.drop_location())
+ P.back.layer = initial(P.back.layer)
+ P.back.plane = initial(P.back.plane)
+ P.back = null
+ P.back = new/obj/item/tank/jetpack/oxygen(P)
+ P.back.layer = ABOVE_HUD_LAYER
+ P.back.plane = ABOVE_HUD_PLANE
+ P.update_inv_back()
+ P.internal = P.back
+ P.update_internals_hud_icon(1)
+
+ if("hsbscrubber") // This is beyond its normal capability but this is sandbox and you spawned one, I assume you need it
+ var/obj/hsb = new/obj/machinery/portable_atmospherics/scrubber{volume_rate=50*ONE_ATMOSPHERE;on=1}(usr.loc)
+ hsb.update_icon() // hackish but it wasn't meant to be spawned I guess?
+
+ //
+ // Stacked Materials
+ //
+
+ if("hsbrglass")
+ new/obj/item/stack/sheet/rglass{amount=50}(usr.loc)
+
+ if("hsbmetal")
+ new/obj/item/stack/sheet/metal{amount=50}(usr.loc)
+
+ if("hsbplasteel")
+ new/obj/item/stack/sheet/plasteel{amount=50}(usr.loc)
+
+ if("hsbglass")
+ new/obj/item/stack/sheet/glass{amount=50}(usr.loc)
+
+ if("hsbwood")
+ new/obj/item/stack/sheet/mineral/wood{amount=50}(usr.loc)
+
+ //
+ // All access ID
+ //
+ if("hsbaaid")
+ var/obj/item/card/id/gold/ID = new(usr.loc)
+ ID.registered_name = usr.real_name
+ ID.assignment = "Sandbox"
+ ID.access = get_all_accesses()
+ ID.update_label()
+
+ //
+ // RCD - starts with full clip
+ // Spawn check due to grief potential (destroying floors, walls, etc)
+ //
+ if("hsbrcd")
+ if(!GLOB.hsboxspawn) return
+
+ new/obj/item/construction/rcd/combat(usr.loc)
+
+ //
+ // New sandbox airlock maker
+ //
+ if("hsbairlock")
+ new /datum/airlock_maker(usr.loc)
+
+ //
+ // Object spawn window
+ //
+
+ // Clothing
+ if("hsbcloth")
+ if(!GLOB.hsboxspawn) return
+
+ if(!clothinfo)
+ clothinfo = "Clothing (Reagent Containers) (Other Items) "
+ var/list/all_items = subtypesof(/obj/item/clothing)
+ for(var/typekey in spawn_forbidden)
+ all_items -= typesof(typekey)
+ for(var/O in reverseRange(all_items))
+ clothinfo += "[O] "
+
+ usr << browse(clothinfo,"window=sandbox")
+
+ // Reagent containers
+ if("hsbreag")
+ if(!GLOB.hsboxspawn) return
+
+ if(!reaginfo)
+ reaginfo = "Reagent Containers (Clothing) (Other Items) "
+ var/list/all_items = subtypesof(/obj/item/reagent_containers)
+ for(var/typekey in spawn_forbidden)
+ all_items -= typesof(typekey)
+ for(var/O in reverseRange(all_items))
+ reaginfo += "[O] "
+
+ usr << browse(reaginfo,"window=sandbox")
+
+ // Other items
+ if("hsbobj")
+ if(!GLOB.hsboxspawn) return
+
+ if(!objinfo)
+ objinfo = "Other Items (Clothing) (Reagent Containers) "
+ var/list/all_items = subtypesof(/obj/item/) - typesof(/obj/item/clothing) - typesof(/obj/item/reagent_containers)
+ for(var/typekey in spawn_forbidden)
+ all_items -= typesof(typekey)
+
+ for(var/O in reverseRange(all_items))
+ objinfo += "[O] "
+
+ usr << browse(objinfo,"window=sandbox")
+
+ //
+ // Safespawn checks to see if spawning is disabled.
+ //
+ if("hsb_safespawn")
+ if(!GLOB.hsboxspawn)
+ usr << browse(null,"window=sandbox")
+ return
+
+ var/typepath = text2path(href_list["path"])
+ if(!typepath)
+ to_chat(usr, "Bad path: \"[href_list["path"]]\"")
+ return
+ new typepath(usr.loc)
+
+ if(CONFIG_GET(flag/sandbox_autoclose))
+ usr << browse(null,"window=sandbox")
+ //
+ // For everything else in the href list
+ //
+ if("hsbspawn")
+ var/typepath = text2path(href_list["path"])
+ if(!typepath)
+ to_chat(usr, "Bad path: \"[href_list["path"]]\"")
+ return
+ new typepath(usr.loc)
+
+ if(CONFIG_GET(flag/sandbox_autoclose))
+ usr << browse(null,"window=sandbox")
diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm
index 77b91a8571..64d4f84eec 100644
--- a/code/game/gamemodes/traitor/traitor.dm
+++ b/code/game/gamemodes/traitor/traitor.dm
@@ -31,16 +31,17 @@
/datum/game_mode/traitor/pre_setup()
- if(config.protect_roles_from_antagonist)
+ if(CONFIG_GET(flag/protect_roles_from_antagonist))
restricted_jobs += protected_jobs
- if(config.protect_assistant_from_antagonist)
+ if(CONFIG_GET(flag/protect_assistant_from_antagonist))
restricted_jobs += "Assistant"
var/num_traitors = 1
- if(config.traitor_scaling_coeff)
- num_traitors = max(1, min( round(num_players()/(config.traitor_scaling_coeff*2))+ 2 + num_modifier, round(num_players()/(config.traitor_scaling_coeff)) + num_modifier ))
+ var/tsc = CONFIG_GET(number/traitor_scaling_coeff)
+ if(tsc)
+ num_traitors = max(1, min(round(num_players() / (tsc * 2)) + 2 + num_modifier, round(num_players() / tsc) + num_modifier))
else
num_traitors = max(1, min(num_players(), traitors_possible))
@@ -68,10 +69,11 @@
return 1
/datum/game_mode/traitor/make_antag_chance(mob/living/carbon/human/character) //Assigns traitor to latejoiners
- var/traitorcap = min(round(GLOB.joined_player_list.len / (config.traitor_scaling_coeff * 2)) + 2 + num_modifier, round(GLOB.joined_player_list.len/config.traitor_scaling_coeff) + num_modifier )
+ var/tsc = CONFIG_GET(number/traitor_scaling_coeff)
+ var/traitorcap = min(round(GLOB.joined_player_list.len / (tsc * 2)) + 2 + num_modifier, round(GLOB.joined_player_list.len / tsc) + num_modifier)
if((SSticker.mode.traitors.len + pre_traitors.len) >= traitorcap) //Upper cap for number of latejoin antagonists
return
- if((SSticker.mode.traitors.len + pre_traitors.len) <= (traitorcap - 2) || prob(100 / (config.traitor_scaling_coeff * 2)))
+ if((SSticker.mode.traitors.len + pre_traitors.len) <= (traitorcap - 2) || prob(100 / (tsc * 2)))
if(ROLE_TRAITOR in character.client.prefs.be_special)
if(!jobban_isbanned(character, ROLE_TRAITOR) && !jobban_isbanned(character, "Syndicate"))
if(age_check(character.client))
diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm
index f4847e30a7..42d676c29b 100644
--- a/code/game/gamemodes/wizard/artefact.dm
+++ b/code/game/gamemodes/wizard/artefact.dm
@@ -234,11 +234,10 @@
if(!link)
if(I.loc == user && istype(I) && I.w_class <= WEIGHT_CLASS_SMALL)
- user.drop_item()
- I.loc = src
- link = I
- to_chat(user, "You attach [I] to the doll.")
- update_targets()
+ if (user.transferItemToLoc(I,src))
+ link = I
+ to_chat(user, "You attach [I] to the doll.")
+ update_targets()
/obj/item/voodoo/check_eye(mob/user)
if(loc != user)
diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm
index aae0261320..149c2ae912 100644
--- a/code/game/gamemodes/wizard/soulstone.dm
+++ b/code/game/gamemodes/wizard/soulstone.dm
@@ -164,7 +164,7 @@
if(contents.len)
to_chat(user, "Capture failed! : The soulstone is full! Free an existing soul to make room.")
else
- T.loc = src //put shade in stone
+ T.forceMove(src) //put shade in stone
T.status_flags |= GODMODE
T.canmove = 0
T.health = T.maxHealth
@@ -199,7 +199,6 @@
SSticker.mode.cult -= A.mind
SSticker.mode.update_cult_icons_removed(A.mind)
qdel(T)
- user.drop_item()
qdel(src)
else
to_chat(user, "Creation failed! : The soul stone is empty! Go kill someone!")
diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm
index 31060fffc3..5e22aaac42 100644
--- a/code/game/gamemodes/wizard/spellbook.dm
+++ b/code/game/gamemodes/wizard/spellbook.dm
@@ -478,7 +478,7 @@
/datum/spellbook_entry/summon/guns/IsAvailible()
if(!SSticker.mode) // In case spellbook is placed on map
return 0
- return (!config.no_summon_guns)
+ return !CONFIG_GET(flag/no_summon_guns)
/datum/spellbook_entry/summon/guns/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
SSblackbox.add_details("wizard_spell_learned", name)
@@ -495,7 +495,7 @@
/datum/spellbook_entry/summon/magic/IsAvailible()
if(!SSticker.mode) // In case spellbook is placed on map
return 0
- return (!config.no_summon_magic)
+ return !CONFIG_GET(flag/no_summon_magic)
/datum/spellbook_entry/summon/magic/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
SSblackbox.add_details("wizard_spell_learned", name)
@@ -513,7 +513,7 @@
/datum/spellbook_entry/summon/events/IsAvailible()
if(!SSticker.mode) // In case spellbook is placed on map
return 0
- return (!config.no_summon_events)
+ return !CONFIG_GET(flag/no_summon_events)
/datum/spellbook_entry/summon/events/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
SSblackbox.add_details("wizard_spell_learned", name)
diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm
index eea7afcb4b..8256d0aaf0 100644
--- a/code/game/gamemodes/wizard/wizard.dm
+++ b/code/game/gamemodes/wizard/wizard.dm
@@ -30,7 +30,7 @@
to_chat(wizard.current, "A starting location for you could not be found, please report this bug! ")
return 0
for(var/datum/mind/wiz in wizards)
- wiz.current.loc = pick(GLOB.wizardstart)
+ wiz.current.forceMove(pick(GLOB.wizardstart))
return 1
@@ -245,15 +245,6 @@
//OTHER PROCS
-//To batch-remove wizard spells. Linked to mind.dm.
-/mob/proc/spellremove(mob/M)
- if(!mind)
- return
- for(var/X in src.mind.spell_list)
- var/obj/effect/proc_holder/spell/spell_to_remove = X
- qdel(spell_to_remove)
- mind.spell_list -= spell_to_remove
-
//returns whether the mob is a wizard (or apprentice)
/proc/iswizard(mob/living/M)
return istype(M) && M.mind && SSticker && SSticker.mode && ((M.mind in SSticker.mode.wizards) || (M.mind in SSticker.mode.apprentices))
diff --git a/code/game/machinery/Beacon.dm b/code/game/machinery/Beacon.dm
index 80400fee05..48eafce3c5 100644
--- a/code/game/machinery/Beacon.dm
+++ b/code/game/machinery/Beacon.dm
@@ -44,10 +44,10 @@
var/turf/T = loc
Beacon = new /obj/item/device/radio/beacon
Beacon.invisibility = INVISIBILITY_MAXIMUM
- Beacon.loc = T
+ Beacon.forceMove(T)
if(Beacon)
if(Beacon.loc != loc)
- Beacon.loc = loc
+ Beacon.forceMove(loc)
updateicon()
diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm
index b070de1b1c..23b398605c 100644
--- a/code/game/machinery/_machinery.dm
+++ b/code/game/machinery/_machinery.dm
@@ -95,6 +95,7 @@ Class Procs:
/obj/machinery
name = "machinery"
icon = 'icons/obj/stationobjs.dmi'
+ desc = "Some kind of machine."
verb_say = "beeps"
verb_yell = "blares"
pressure_resistance = 15
@@ -429,7 +430,7 @@ Class Procs:
W.handle_item_insertion(A, 1)
component_parts -= A
component_parts += B
- B.loc = null
+ B.moveToNullspace()
to_chat(user, "[A.name] replaced with [B.name]. ")
shouldplaysound = 1 //Only play the sound when parts are actually replaced!
break
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index 9fa53765ed..4894952a69 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -134,12 +134,11 @@
if(ispath(lit, /obj/item/ore/bluespace_crystal))
use_power(max(500,M.last_amount_inserted/10))
else
- var/obj/item/stack/S = lit
- var/list/initmats = initial(S.materials)
- if (initmats[MAT_METAL])
- flick("autolathe_o",src)//plays metal insertion animation
- if (initmats[MAT_GLASS])
- flick("autolathe_r",src)//plays glass insertion animation
+ switch(M.last_inserted_id)
+ if (MAT_METAL)
+ flick("autolathe_o",src)//plays metal insertion animation
+ if (MAT_GLASS)
+ flick("autolathe_r",src)//plays glass insertion animation
use_power(M.last_amount_inserted*100)
updateUsrDialog()
diff --git a/code/game/machinery/bank_machine.dm b/code/game/machinery/bank_machine.dm
index de07fc9c2d..9d446aa77c 100644
--- a/code/game/machinery/bank_machine.dm
+++ b/code/game/machinery/bank_machine.dm
@@ -43,7 +43,7 @@
say("Station funds depleted. Halting siphon.")
siphoning = FALSE
else
- new /obj/item/stack/spacecash/c200(get_turf(src)) // will autostack
+ new /obj/item/stack/spacecash/c200(drop_location()) // will autostack
playsound(src.loc, 'sound/items/poster_being_created.ogg', 100, 1)
SSshuttle.points -= 200
if(next_warning < world.time && prob(15))
diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm
index 7c1904d2fe..8a118b8d08 100644
--- a/code/game/machinery/buttons.dm
+++ b/code/game/machinery/buttons.dm
@@ -127,10 +127,10 @@
if(panel_open)
if(device || board)
if(device)
- device.loc = get_turf(src)
+ device.forceMove(drop_location())
device = null
if(board)
- board.loc = get_turf(src)
+ board.forceMove(drop_location())
req_access = list()
req_one_access = list()
board = null
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index d7832622c5..7d3c40a0d9 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -246,7 +246,7 @@
if(disassembled)
if(!assembly)
assembly = new()
- assembly.loc = src.loc
+ assembly.forceMove(drop_location())
assembly.state = 1
assembly.setDir(dir)
assembly = null
diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm
index 340277b441..1e6fe4c532 100644
--- a/code/game/machinery/camera/camera_assembly.dm
+++ b/code/game/machinery/camera/camera_assembly.dm
@@ -1,145 +1,145 @@
-/obj/item/wallframe/camera
- name = "camera assembly"
- desc = "The basic construction for Nanotrasen-Always-Watching-You cameras."
- icon = 'icons/obj/monitors.dmi'
- icon_state = "cameracase"
- materials = list(MAT_METAL=400, MAT_GLASS=250)
- result_path = /obj/structure/camera_assembly
-
-
-/obj/structure/camera_assembly
- name = "camera assembly"
- desc = "The basic construction for Nanotrasen-Always-Watching-You cameras."
- icon = 'icons/obj/monitors.dmi'
- icon_state = "camera1"
- max_integrity = 150
- // Motion, EMP-Proof, X-Ray
- var/static/list/possible_upgrades = typecacheof(list(/obj/item/device/assembly/prox_sensor, /obj/item/stack/sheet/mineral/plasma, /obj/item/device/analyzer))
- var/list/upgrades
- var/state = 1
-
- /*
- 1 = Wrenched in place
- 2 = Welded in place
- 3 = Wires attached to it (you can now attach/dettach upgrades)
- 4 = Screwdriver panel closed and is fully built (you cannot attach upgrades)
- */
-
-/obj/structure/camera_assembly/Initialize(mapload, ndir, building)
- . = ..()
- if(building)
- setDir(ndir)
- upgrades = list()
-
-/obj/structure/camera_assembly/Destroy()
- QDEL_LIST(upgrades)
- return ..()
-
-/obj/structure/camera_assembly/attackby(obj/item/W, mob/living/user, params)
- switch(state)
- if(1)
- // State 1
- if(istype(W, /obj/item/weldingtool))
- if(weld(W, user))
- to_chat(user, "You weld the assembly securely into place. ")
+/obj/item/wallframe/camera
+ name = "camera assembly"
+ desc = "The basic construction for Nanotrasen-Always-Watching-You cameras."
+ icon = 'icons/obj/monitors.dmi'
+ icon_state = "cameracase"
+ materials = list(MAT_METAL=400, MAT_GLASS=250)
+ result_path = /obj/structure/camera_assembly
+
+
+/obj/structure/camera_assembly
+ name = "camera assembly"
+ desc = "The basic construction for Nanotrasen-Always-Watching-You cameras."
+ icon = 'icons/obj/monitors.dmi'
+ icon_state = "camera1"
+ max_integrity = 150
+ // Motion, EMP-Proof, X-Ray
+ var/static/list/possible_upgrades = typecacheof(list(/obj/item/device/assembly/prox_sensor, /obj/item/stack/sheet/mineral/plasma, /obj/item/device/analyzer))
+ var/list/upgrades
+ var/state = 1
+
+ /*
+ 1 = Wrenched in place
+ 2 = Welded in place
+ 3 = Wires attached to it (you can now attach/dettach upgrades)
+ 4 = Screwdriver panel closed and is fully built (you cannot attach upgrades)
+ */
+
+/obj/structure/camera_assembly/Initialize(mapload, ndir, building)
+ . = ..()
+ if(building)
+ setDir(ndir)
+ upgrades = list()
+
+/obj/structure/camera_assembly/Destroy()
+ QDEL_LIST(upgrades)
+ return ..()
+
+/obj/structure/camera_assembly/attackby(obj/item/W, mob/living/user, params)
+ switch(state)
+ if(1)
+ // State 1
+ if(istype(W, /obj/item/weldingtool))
+ if(weld(W, user))
+ to_chat(user, "You weld the assembly securely into place. ")
anchored = TRUE
- state = 2
- return
-
- else if(istype(W, /obj/item/wrench))
- playsound(src.loc, W.usesound, 50, 1)
- to_chat(user, "You unattach the assembly from its place. ")
- new /obj/item/wallframe/camera(get_turf(src))
- qdel(src)
- return
-
- if(2)
- // State 2
- if(istype(W, /obj/item/stack/cable_coil))
- var/obj/item/stack/cable_coil/C = W
- if(C.use(2))
- to_chat(user, "You add wires to the assembly. ")
- state = 3
- else
- to_chat(user, "You need two lengths of cable to wire a camera! ")
- return
- return
-
- else if(istype(W, /obj/item/weldingtool))
-
- if(weld(W, user))
- to_chat(user, "You unweld the assembly from its place. ")
- state = 1
+ state = 2
+ return
+
+ else if(istype(W, /obj/item/wrench))
+ playsound(src.loc, W.usesound, 50, 1)
+ to_chat(user, "You unattach the assembly from its place. ")
+ new /obj/item/wallframe/camera(get_turf(src))
+ qdel(src)
+ return
+
+ if(2)
+ // State 2
+ if(istype(W, /obj/item/stack/cable_coil))
+ var/obj/item/stack/cable_coil/C = W
+ if(C.use(2))
+ to_chat(user, "You add wires to the assembly. ")
+ state = 3
+ else
+ to_chat(user, "You need two lengths of cable to wire a camera! ")
+ return
+ return
+
+ else if(istype(W, /obj/item/weldingtool))
+
+ if(weld(W, user))
+ to_chat(user, "You unweld the assembly from its place. ")
+ state = 1
anchored = TRUE
- return
-
-
- if(3)
- // State 3
- if(istype(W, /obj/item/screwdriver))
- playsound(src.loc, W.usesound, 50, 1)
-
+ return
+
+
+ if(3)
+ // State 3
+ if(istype(W, /obj/item/screwdriver))
+ playsound(src.loc, W.usesound, 50, 1)
+
var/input = stripped_input(user, "Which networks would you like to connect this camera to? Separate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Set Network", "SS13")
- if(!input)
- to_chat(user, "No input found, please hang up and try your call again! ")
- return
-
- var/list/tempnetwork = splittext(input, ",")
- if(tempnetwork.len < 1)
- to_chat(user, "No network found, please hang up and try your call again! ")
- return
-
- state = 4
- var/obj/machinery/camera/C = new(src.loc)
- src.loc = C
- C.assembly = src
- C.setDir(src.dir)
-
- C.network = tempnetwork
- var/area/A = get_area(src)
- C.c_tag = "[A.name] ([rand(1, 999)])"
-
-
- else if(istype(W, /obj/item/wirecutters))
- new/obj/item/stack/cable_coil(get_turf(src), 2)
- playsound(src.loc, W.usesound, 50, 1)
- to_chat(user, "You cut the wires from the circuits. ")
- state = 2
- return
-
- // Upgrades!
- if(is_type_in_typecache(W, possible_upgrades) && !is_type_in_list(W, upgrades)) // Is a possible upgrade and isn't in the camera already.
- if(!user.drop_item(W))
- return
- to_chat(user, "You attach \the [W] into the assembly inner circuits. ")
- upgrades += W
- W.forceMove(src)
- return
-
- // Taking out upgrades
- else if(istype(W, /obj/item/crowbar) && upgrades.len)
- var/obj/U = locate(/obj) in upgrades
- if(U)
- to_chat(user, "You unattach an upgrade from the assembly. ")
- playsound(src.loc, W.usesound, 50, 1)
- U.loc = get_turf(src)
- upgrades -= U
- return
-
- return ..()
-
-/obj/structure/camera_assembly/proc/weld(obj/item/weldingtool/WT, mob/living/user)
- if(!WT.remove_fuel(0, user))
- return 0
- to_chat(user, "You start to weld \the [src]... ")
- playsound(src.loc, WT.usesound, 50, 1)
- if(do_after(user, 20*WT.toolspeed, target = src))
- if(WT.isOn())
- playsound(loc, 'sound/items/welder2.ogg', 50, 1)
- return 1
- return 0
-
-/obj/structure/camera_assembly/deconstruct(disassembled = TRUE)
+ if(!input)
+ to_chat(user, "No input found, please hang up and try your call again! ")
+ return
+
+ var/list/tempnetwork = splittext(input, ",")
+ if(tempnetwork.len < 1)
+ to_chat(user, "No network found, please hang up and try your call again! ")
+ return
+
+ state = 4
+ var/obj/machinery/camera/C = new(src.loc)
+ forceMove(C)
+ C.assembly = src
+ C.setDir(src.dir)
+
+ C.network = tempnetwork
+ var/area/A = get_area(src)
+ C.c_tag = "[A.name] ([rand(1, 999)])"
+
+
+ else if(istype(W, /obj/item/wirecutters))
+ new/obj/item/stack/cable_coil(get_turf(src), 2)
+ playsound(src.loc, W.usesound, 50, 1)
+ to_chat(user, "You cut the wires from the circuits. ")
+ state = 2
+ return
+
+ // Upgrades!
+ if(is_type_in_typecache(W, possible_upgrades) && !is_type_in_list(W, upgrades)) // Is a possible upgrade and isn't in the camera already.
+ if(!user.drop_item(W))
+ return
+ to_chat(user, "You attach \the [W] into the assembly inner circuits. ")
+ upgrades += W
+ W.forceMove(src)
+ return
+
+ // Taking out upgrades
+ else if(istype(W, /obj/item/crowbar) && upgrades.len)
+ var/obj/U = locate(/obj) in upgrades
+ if(U)
+ to_chat(user, "You unattach an upgrade from the assembly. ")
+ playsound(src.loc, W.usesound, 50, 1)
+ U.forceMove(drop_location())
+ upgrades -= U
+ return
+
+ return ..()
+
+/obj/structure/camera_assembly/proc/weld(obj/item/weldingtool/WT, mob/living/user)
+ if(!WT.remove_fuel(0, user))
+ return 0
+ to_chat(user, "You start to weld \the [src]... ")
+ playsound(src.loc, WT.usesound, 50, 1)
+ if(do_after(user, 20*WT.toolspeed, target = src))
+ if(WT.isOn())
+ playsound(loc, 'sound/items/welder2.ogg', 50, 1)
+ return 1
+ return 0
+
+/obj/structure/camera_assembly/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
- new /obj/item/stack/sheet/metal(loc)
- qdel(src)
+ new /obj/item/stack/sheet/metal(loc)
+ qdel(src)
diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm
index 3f95d2a780..63c63ce120 100644
--- a/code/game/machinery/cell_charger.dm
+++ b/code/game/machinery/cell_charger.dm
@@ -45,14 +45,13 @@
if(!isarea(a))
return
if(a.power_equip == 0) // There's no APC in this area, don't try to cheat power!
- to_chat(user, "The [name] blinks red as you try to insert the cell! ")
+ to_chat(user, "The [src] blinks red as you try to insert the cell! ")
return
- if(!user.drop_item())
+ if(!user.transferItemToLoc(W,src))
return
- W.loc = src
charging = W
- user.visible_message("[user] inserts a cell into the charger.", "You insert a cell into the charger. ")
+ user.visible_message("[user] inserts a cell into [src].", "You insert a cell into [src]. ")
chargelevel = -1
updateicon()
else if(istype(W, /obj/item/wrench))
@@ -61,7 +60,7 @@
return
anchored = !anchored
- to_chat(user, "You [anchored ? "attach" : "detach"] the cell charger [anchored ? "to" : "from"] the ground ")
+ to_chat(user, "You [anchored ? "attach" : "detach"] [src] [anchored ? "to" : "from"] the ground ")
playsound(src.loc, W.usesound, 75, 1)
else
return ..()
@@ -80,7 +79,7 @@
user.put_in_hands(charging)
charging.add_fingerprint(user)
- user.visible_message("[user] removes the cell from the charger.", "You remove the cell from the charger. ")
+ user.visible_message("[user] removes [charging] from [src].", "You remove [charging] from [src]. ")
removecell()
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index 88941c2344..86e69b8973 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -231,9 +231,9 @@
else if(mob_occupant.cloneloss > (100 - heal_level))
mob_occupant.Unconscious(80)
-
+ var/dmg_mult = CONFIG_GET(number/damage_multiplier)
//Slowly get that clone healed and finished.
- mob_occupant.adjustCloneLoss(-((speed_coeff/2) * config.damage_multiplier))
+ mob_occupant.adjustCloneLoss(-((speed_coeff / 2) * dmg_mult))
var/progress = CLONE_INITIAL_DAMAGE - mob_occupant.getCloneLoss()
// To avoid the default cloner making incomplete clones
progress += (100 - MINIMUM_HEAL_LEVEL)
@@ -251,7 +251,7 @@
BP.attach_limb(mob_occupant)
//Premature clones may have brain damage.
- mob_occupant.adjustBrainLoss(-((speed_coeff/2) * config.damage_multiplier))
+ mob_occupant.adjustBrainLoss(-((speed_coeff / 2) * dmg_mult))
check_brine()
diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm
index d9371d5678..b590763ffe 100644
--- a/code/game/machinery/computer/aifixer.dm
+++ b/code/game/machinery/computer/aifixer.dm
@@ -1,146 +1,146 @@
-/obj/machinery/computer/aifixer
- name = "\improper AI system integrity restorer"
- desc = "Used with intelliCards containing nonfunctioning AIs to restore them to working order."
- req_access = list(ACCESS_CAPTAIN, ACCESS_ROBOTICS, ACCESS_HEADS)
- var/mob/living/silicon/ai/occupier = null
- var/active = 0
- circuit = /obj/item/circuitboard/computer/aifixer
- icon_keyboard = "tech_key"
- icon_screen = "ai-fixer"
- light_color = LIGHT_COLOR_PINK
-
-/obj/machinery/computer/aifixer/attackby(obj/I, mob/user, params)
- if(occupier && istype(I, /obj/item/screwdriver))
- if(stat & (NOPOWER|BROKEN))
- to_chat(user, "The screws on [name]'s screen won't budge. ")
- else
- to_chat(user, "The screws on [name]'s screen won't budge and it emits a warning beep. ")
- else
- return ..()
-
-/obj/machinery/computer/aifixer/attack_hand(mob/user)
- if(..())
- return
- interact(user)
-
-/obj/machinery/computer/aifixer/interact(mob/user)
-
- var/dat = ""
-
- if (src.occupier)
- var/laws
- dat += "Stored AI: [src.occupier.name] "
- dat += "System integrity: [(src.occupier.health+100)/2]% "
-
- if (src.occupier.laws.zeroth)
- laws += "0: [src.occupier.laws.zeroth] "
-
- for (var/index = 1, index <= src.occupier.laws.ion.len, index++)
- var/law = src.occupier.laws.ion[index]
- if (length(law) > 0)
- var/num = ionnum()
- laws += "[num]: [law] "
-
- var/number = 1
- for (var/index = 1, index <= src.occupier.laws.inherent.len, index++)
- var/law = src.occupier.laws.inherent[index]
- if (length(law) > 0)
- laws += "[number]: [law] "
- number++
-
- for (var/index = 1, index <= src.occupier.laws.supplied.len, index++)
- var/law = src.occupier.laws.supplied[index]
- if (length(law) > 0)
- laws += "[number]: [law] "
- number++
-
- dat += "Laws: [laws] "
-
- if (src.occupier.stat == DEAD)
- dat += "AI non-functional "
- else
- dat += "AI functional "
- if (!src.active)
- dat += {"Begin Reconstruction "}
- else
- dat += " Reconstruction in process, please wait. "
- dat += {"Close "}
- var/datum/browser/popup = new(user, "computer", "AI System Integrity Restorer", 400, 500)
- popup.set_content(dat)
- popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
- popup.open()
- return
-
-/obj/machinery/computer/aifixer/proc/Fix()
- use_power(1000)
- occupier.adjustOxyLoss(-1, 0)
- occupier.adjustFireLoss(-1, 0)
- occupier.adjustToxLoss(-1, 0)
- occupier.adjustBruteLoss(-1, 0)
- occupier.updatehealth()
- occupier.updatehealth()
- if(occupier.health >= 0 && occupier.stat == DEAD)
- occupier.revive()
- return occupier.health < 100
-
-/obj/machinery/computer/aifixer/process()
- if(..())
- if(active)
- active = Fix()
- updateDialog()
- update_icon()
-
-/obj/machinery/computer/aifixer/Topic(href, href_list)
- if(..())
- return
- if(href_list["fix"])
- to_chat(usr, "Reconstruction in progress. This will take several minutes. ")
- playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 25, 0)
- active = TRUE
- add_fingerprint(usr)
-
-/obj/machinery/computer/aifixer/update_icon()
- ..()
- if(stat & (NOPOWER|BROKEN))
- return
- else
- if(active)
- add_overlay("ai-fixer-on")
- if (occupier)
- switch (occupier.stat)
- if (0)
- add_overlay("ai-fixer-full")
- if (2)
- add_overlay("ai-fixer-404")
- else
- add_overlay("ai-fixer-empty")
-
-/obj/machinery/computer/aifixer/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/device/aicard/card)
- if(!..())
- return
- //Downloading AI from card to terminal.
- if(interaction == AI_TRANS_FROM_CARD)
- if(stat & (NOPOWER|BROKEN))
- to_chat(user, "[src] is offline and cannot take an AI at this time!")
- return
- AI.forceMove(src)
- occupier = AI
- AI.control_disabled = 1
- AI.radio_enabled = 0
- to_chat(AI, "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here.")
- to_chat(user, "Transfer successful : [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed.")
- card.AI = null
- update_icon()
-
- else //Uploading AI from terminal to card
- if(occupier && !active)
- to_chat(occupier, "You have been downloaded to a mobile storage device. Still no remote access.")
- to_chat(user, "Transfer successful : [occupier.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory.")
- occupier.loc = card
- card.AI = occupier
- occupier = null
- update_icon()
- else if (active)
- to_chat(user, "ERROR : Reconstruction in progress.")
- else if (!occupier)
- to_chat(user, "ERROR : Unable to locate artificial intelligence.")
+/obj/machinery/computer/aifixer
+ name = "\improper AI system integrity restorer"
+ desc = "Used with intelliCards containing nonfunctioning AIs to restore them to working order."
+ req_access = list(ACCESS_CAPTAIN, ACCESS_ROBOTICS, ACCESS_HEADS)
+ var/mob/living/silicon/ai/occupier = null
+ var/active = 0
+ circuit = /obj/item/circuitboard/computer/aifixer
+ icon_keyboard = "tech_key"
+ icon_screen = "ai-fixer"
+ light_color = LIGHT_COLOR_PINK
+
+/obj/machinery/computer/aifixer/attackby(obj/I, mob/user, params)
+ if(occupier && istype(I, /obj/item/screwdriver))
+ if(stat & (NOPOWER|BROKEN))
+ to_chat(user, "The screws on [name]'s screen won't budge. ")
+ else
+ to_chat(user, "The screws on [name]'s screen won't budge and it emits a warning beep. ")
+ else
+ return ..()
+
+/obj/machinery/computer/aifixer/attack_hand(mob/user)
+ if(..())
+ return
+ interact(user)
+
+/obj/machinery/computer/aifixer/interact(mob/user)
+
+ var/dat = ""
+
+ if (src.occupier)
+ var/laws
+ dat += "Stored AI: [src.occupier.name] "
+ dat += "System integrity: [(src.occupier.health+100)/2]% "
+
+ if (src.occupier.laws.zeroth)
+ laws += "0: [src.occupier.laws.zeroth] "
+
+ for (var/index = 1, index <= src.occupier.laws.ion.len, index++)
+ var/law = src.occupier.laws.ion[index]
+ if (length(law) > 0)
+ var/num = ionnum()
+ laws += "[num]: [law] "
+
+ var/number = 1
+ for (var/index = 1, index <= src.occupier.laws.inherent.len, index++)
+ var/law = src.occupier.laws.inherent[index]
+ if (length(law) > 0)
+ laws += "[number]: [law] "
+ number++
+
+ for (var/index = 1, index <= src.occupier.laws.supplied.len, index++)
+ var/law = src.occupier.laws.supplied[index]
+ if (length(law) > 0)
+ laws += "[number]: [law] "
+ number++
+
+ dat += "Laws: [laws] "
+
+ if (src.occupier.stat == DEAD)
+ dat += "AI non-functional "
+ else
+ dat += "AI functional "
+ if (!src.active)
+ dat += {"Begin Reconstruction "}
+ else
+ dat += " Reconstruction in process, please wait. "
+ dat += {"Close "}
+ var/datum/browser/popup = new(user, "computer", "AI System Integrity Restorer", 400, 500)
+ popup.set_content(dat)
+ popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
+ popup.open()
+ return
+
+/obj/machinery/computer/aifixer/proc/Fix()
+ use_power(1000)
+ occupier.adjustOxyLoss(-1, 0)
+ occupier.adjustFireLoss(-1, 0)
+ occupier.adjustToxLoss(-1, 0)
+ occupier.adjustBruteLoss(-1, 0)
+ occupier.updatehealth()
+ occupier.updatehealth()
+ if(occupier.health >= 0 && occupier.stat == DEAD)
+ occupier.revive()
+ return occupier.health < 100
+
+/obj/machinery/computer/aifixer/process()
+ if(..())
+ if(active)
+ active = Fix()
+ updateDialog()
+ update_icon()
+
+/obj/machinery/computer/aifixer/Topic(href, href_list)
+ if(..())
+ return
+ if(href_list["fix"])
+ to_chat(usr, "Reconstruction in progress. This will take several minutes. ")
+ playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 25, 0)
+ active = TRUE
+ add_fingerprint(usr)
+
+/obj/machinery/computer/aifixer/update_icon()
+ ..()
+ if(stat & (NOPOWER|BROKEN))
+ return
+ else
+ if(active)
+ add_overlay("ai-fixer-on")
+ if (occupier)
+ switch (occupier.stat)
+ if (0)
+ add_overlay("ai-fixer-full")
+ if (2)
+ add_overlay("ai-fixer-404")
+ else
+ add_overlay("ai-fixer-empty")
+
+/obj/machinery/computer/aifixer/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/device/aicard/card)
+ if(!..())
+ return
+ //Downloading AI from card to terminal.
+ if(interaction == AI_TRANS_FROM_CARD)
+ if(stat & (NOPOWER|BROKEN))
+ to_chat(user, "[src] is offline and cannot take an AI at this time!")
+ return
+ AI.forceMove(src)
+ occupier = AI
+ AI.control_disabled = 1
+ AI.radio_enabled = 0
+ to_chat(AI, "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here.")
+ to_chat(user, "Transfer successful : [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed.")
+ card.AI = null
+ update_icon()
+
+ else //Uploading AI from terminal to card
+ if(occupier && !active)
+ to_chat(occupier, "You have been downloaded to a mobile storage device. Still no remote access.")
+ to_chat(user, "Transfer successful : [occupier.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory.")
+ occupier.forceMove(card)
+ card.AI = occupier
+ occupier = null
+ update_icon()
+ else if (active)
+ to_chat(user, "ERROR : Reconstruction in progress.")
+ else if (!occupier)
+ to_chat(user, "ERROR : Unable to locate artificial intelligence.")
diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm
index db2bfedd7c..209bf5e47f 100644
--- a/code/game/machinery/computer/buildandrepair.dm
+++ b/code/game/machinery/computer/buildandrepair.dm
@@ -19,7 +19,7 @@
var/obj/item/weldingtool/WT = P
if(!WT.remove_fuel(0, user))
if(!WT.isOn())
- to_chat(user, "The welding tool must be on to complete this task! ")
+ to_chat(user, "[WT] must be on to complete this task! ")
return
playsound(src.loc, P.usesound, 50, 1)
to_chat(user, "You start deconstructing the frame... ")
@@ -40,14 +40,13 @@
state = 0
return
if(istype(P, /obj/item/circuitboard/computer) && !circuit)
- if(!user.drop_item())
+ if(!user.transferItemToLoc(P, null))
return
playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
- to_chat(user, "You place the circuit board inside the frame. ")
+ to_chat(user, "You place [P] inside the frame. ")
icon_state = "1"
circuit = P
circuit.add_fingerprint(user)
- P.loc = null
return
else if(istype(P, /obj/item/circuitboard) && !circuit)
@@ -55,16 +54,16 @@
return
if(istype(P, /obj/item/screwdriver) && circuit)
playsound(src.loc, P.usesound, 50, 1)
- to_chat(user, "You screw the circuit board into place. ")
+ to_chat(user, "You screw [circuit] into place. ")
state = 2
icon_state = "2"
return
if(istype(P, /obj/item/crowbar) && circuit)
playsound(src.loc, P.usesound, 50, 1)
- to_chat(user, "You remove the circuit board. ")
+ to_chat(user, "You remove [circuit]. ")
state = 1
icon_state = "0"
- circuit.loc = src.loc
+ circuit.forceMove(drop_location())
circuit.add_fingerprint(user)
circuit = null
return
diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm
index 0548d94f3d..e5869310ad 100644
--- a/code/game/machinery/computer/card.dm
+++ b/code/game/machinery/computer/card.dm
@@ -47,29 +47,26 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
/obj/machinery/computer/card/Initialize()
. = ..()
- change_position_cooldown = config.id_console_jobslot_delay
+ change_position_cooldown = CONFIG_GET(number/id_console_jobslot_delay)
/obj/machinery/computer/card/attackby(obj/O, mob/user, params)//TODO:SANITY
if(istype(O, /obj/item/card/id))
var/obj/item/card/id/idcard = O
if(check_access(idcard))
if(!scan)
- if(!usr.drop_item())
+ if (!user.transferItemToLoc(idcard,src))
return
- idcard.loc = src
scan = idcard
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
else if(!modify)
- if(!usr.drop_item())
+ if (!user.transferItemToLoc(idcard,src))
return
- idcard.loc = src
modify = idcard
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
else
if(!modify)
- if(!usr.drop_item())
+ if (!user.transferItemToLoc(idcard,src))
return
- idcard.loc = src
modify = idcard
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
else
@@ -95,10 +92,10 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
/obj/machinery/computer/card/on_deconstruction()
if(scan)
- scan.forceMove(loc)
+ scan.forceMove(drop_location())
scan = null
if(modify)
- modify.forceMove(loc)
+ modify.forceMove(drop_location())
modify = null
//Check if you can't open a new position for a certain job
@@ -355,7 +352,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
if (modify)
GLOB.data_core.manifest_modify(modify.registered_name, modify.assignment)
modify.update_label()
- modify.loc = loc
+ modify.forceMove(drop_location())
modify.verb_pickup()
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
modify = null
@@ -364,26 +361,24 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
else
var/obj/item/I = usr.get_active_held_item()
if (istype(I, /obj/item/card/id))
- if(!usr.drop_item())
+ if (!usr.transferItemToLoc(I,src))
return
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
- I.loc = src
modify = I
authenticated = 0
if ("scan")
if (scan)
- scan.loc = src.loc
+ scan.forceMove(drop_location())
scan.verb_pickup()
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
scan = null
else
var/obj/item/I = usr.get_active_held_item()
if (istype(I, /obj/item/card/id))
- if(!usr.drop_item())
+ if (!usr.transferItemToLoc(I,src))
return
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
- I.loc = src
scan = I
authenticated = 0
if ("auth")
diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm
index ab7a639818..31126a6c08 100644
--- a/code/game/machinery/computer/cloning.dm
+++ b/code/game/machinery/computer/cloning.dm
@@ -1,502 +1,501 @@
-/obj/machinery/computer/cloning
- name = "cloning console"
- desc = "Used to clone people and manage DNA."
- icon_screen = "dna"
- icon_keyboard = "med_key"
- circuit = /obj/item/circuitboard/computer/cloning
+/obj/machinery/computer/cloning
+ name = "cloning console"
+ desc = "Used to clone people and manage DNA."
+ icon_screen = "dna"
+ icon_keyboard = "med_key"
+ circuit = /obj/item/circuitboard/computer/cloning
req_access = list(ACCESS_HEADS) //ONLY USED FOR RECORD DELETION RIGHT NOW.
- var/obj/machinery/dna_scannernew/scanner = null //Linked scanner. For scanning.
- var/list/pods //Linked cloning pods
- var/temp = "Inactive"
- var/scantemp_ckey
- var/scantemp = "Ready to Scan"
- var/menu = 1 //Which menu screen to display
- var/list/records = list()
- var/datum/data/record/active_record = null
- var/obj/item/disk/data/diskette = null //Mostly so the geneticist can steal everything.
- var/loading = 0 // Nice loading text
- var/autoprocess = 0
-
- light_color = LIGHT_COLOR_BLUE
-
-/obj/machinery/computer/cloning/Initialize()
+ var/obj/machinery/dna_scannernew/scanner = null //Linked scanner. For scanning.
+ var/list/pods //Linked cloning pods
+ var/temp = "Inactive"
+ var/scantemp_ckey
+ var/scantemp = "Ready to Scan"
+ var/menu = 1 //Which menu screen to display
+ var/list/records = list()
+ var/datum/data/record/active_record = null
+ var/obj/item/disk/data/diskette = null //Mostly so the geneticist can steal everything.
+ var/loading = 0 // Nice loading text
+ var/autoprocess = 0
+
+ light_color = LIGHT_COLOR_BLUE
+
+/obj/machinery/computer/cloning/Initialize()
. = ..()
- updatemodules(TRUE)
-
-/obj/machinery/computer/cloning/Destroy()
- if(pods)
- for(var/P in pods)
- DetachCloner(P)
- pods = null
- return ..()
-
-/obj/machinery/computer/cloning/proc/GetAvailablePod(mind = null)
- if(pods)
- for(var/P in pods)
- var/obj/machinery/clonepod/pod = P
- if(pod.occupant && pod.clonemind == mind)
- return null
- if(pod.is_operational() && !(pod.occupant || pod.mess))
- return pod
-
-/obj/machinery/computer/cloning/proc/HasEfficientPod()
- if(pods)
- for(var/P in pods)
- var/obj/machinery/clonepod/pod = P
- if(pod.is_operational() && pod.efficiency > 5)
- return TRUE
-
-/obj/machinery/computer/cloning/proc/GetAvailableEfficientPod(mind = null)
- if(pods)
- for(var/P in pods)
- var/obj/machinery/clonepod/pod = P
- if(pod.occupant && pod.clonemind == mind)
- return pod
- else if(!. && pod.is_operational() && !(pod.occupant || pod.mess) && pod.efficiency > 5)
- . = pod
-
-/obj/machinery/computer/cloning/process()
- if(!(scanner && LAZYLEN(pods) && autoprocess))
- return
-
- if(scanner.occupant && scanner.scan_level > 2)
- scan_occupant(scanner.occupant)
-
- for(var/datum/data/record/R in records)
- var/obj/machinery/clonepod/pod = GetAvailableEfficientPod(R.fields["mind"])
-
- if(!pod)
- return
-
- if(pod.occupant)
- continue //how though?
-
- if(pod.growclone(R.fields["ckey"], R.fields["name"], R.fields["UI"], R.fields["SE"], R.fields["mind"], R.fields["mrace"], R.fields["features"], R.fields["factions"]))
- records -= R
-
-/obj/machinery/computer/cloning/proc/updatemodules(findfirstcloner)
- src.scanner = findscanner()
- if(findfirstcloner && !LAZYLEN(pods))
- findcloner()
-
-/obj/machinery/computer/cloning/proc/findscanner()
- var/obj/machinery/dna_scannernew/scannerf = null
-
- // Loop through every direction
- for(dir in list(NORTH,EAST,SOUTH,WEST))
-
- // Try to find a scanner in that direction
- scannerf = locate(/obj/machinery/dna_scannernew, get_step(src, dir))
-
- // If found and operational, return the scanner
- if (!isnull(scannerf) && scannerf.is_operational())
- return scannerf
-
- // If no scanner was found, it will return null
- return null
-
-/obj/machinery/computer/cloning/proc/findcloner()
- var/obj/machinery/clonepod/podf = null
-
- for(dir in list(NORTH,EAST,SOUTH,WEST))
-
- podf = locate(/obj/machinery/clonepod, get_step(src, dir))
-
- if (!isnull(podf) && podf.is_operational())
- AttachCloner(podf)
-
-/obj/machinery/computer/cloning/proc/AttachCloner(obj/machinery/clonepod/pod)
- if(!pod.connected)
- pod.connected = src
- LAZYADD(pods, pod)
-
-/obj/machinery/computer/cloning/proc/DetachCloner(obj/machinery/clonepod/pod)
- pod.connected = null
- LAZYREMOVE(pods, pod)
-
-/obj/machinery/computer/cloning/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/disk/data)) //INSERT SOME DISKETTES
- if (!src.diskette)
- if(!user.drop_item())
- return
- W.loc = src
- src.diskette = W
- to_chat(user, "You insert [W]. ")
- playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
- src.updateUsrDialog()
+ updatemodules(TRUE)
+
+/obj/machinery/computer/cloning/Destroy()
+ if(pods)
+ for(var/P in pods)
+ DetachCloner(P)
+ pods = null
+ return ..()
+
+/obj/machinery/computer/cloning/proc/GetAvailablePod(mind = null)
+ if(pods)
+ for(var/P in pods)
+ var/obj/machinery/clonepod/pod = P
+ if(pod.occupant && pod.clonemind == mind)
+ return null
+ if(pod.is_operational() && !(pod.occupant || pod.mess))
+ return pod
+
+/obj/machinery/computer/cloning/proc/HasEfficientPod()
+ if(pods)
+ for(var/P in pods)
+ var/obj/machinery/clonepod/pod = P
+ if(pod.is_operational() && pod.efficiency > 5)
+ return TRUE
+
+/obj/machinery/computer/cloning/proc/GetAvailableEfficientPod(mind = null)
+ if(pods)
+ for(var/P in pods)
+ var/obj/machinery/clonepod/pod = P
+ if(pod.occupant && pod.clonemind == mind)
+ return pod
+ else if(!. && pod.is_operational() && !(pod.occupant || pod.mess) && pod.efficiency > 5)
+ . = pod
+
+/obj/machinery/computer/cloning/process()
+ if(!(scanner && LAZYLEN(pods) && autoprocess))
+ return
+
+ if(scanner.occupant && scanner.scan_level > 2)
+ scan_occupant(scanner.occupant)
+
+ for(var/datum/data/record/R in records)
+ var/obj/machinery/clonepod/pod = GetAvailableEfficientPod(R.fields["mind"])
+
+ if(!pod)
+ return
+
+ if(pod.occupant)
+ continue //how though?
+
+ if(pod.growclone(R.fields["ckey"], R.fields["name"], R.fields["UI"], R.fields["SE"], R.fields["mind"], R.fields["mrace"], R.fields["features"], R.fields["factions"]))
+ records -= R
+
+/obj/machinery/computer/cloning/proc/updatemodules(findfirstcloner)
+ src.scanner = findscanner()
+ if(findfirstcloner && !LAZYLEN(pods))
+ findcloner()
+
+/obj/machinery/computer/cloning/proc/findscanner()
+ var/obj/machinery/dna_scannernew/scannerf = null
+
+ // Loop through every direction
+ for(dir in list(NORTH,EAST,SOUTH,WEST))
+
+ // Try to find a scanner in that direction
+ scannerf = locate(/obj/machinery/dna_scannernew, get_step(src, dir))
+
+ // If found and operational, return the scanner
+ if (!isnull(scannerf) && scannerf.is_operational())
+ return scannerf
+
+ // If no scanner was found, it will return null
+ return null
+
+/obj/machinery/computer/cloning/proc/findcloner()
+ var/obj/machinery/clonepod/podf = null
+
+ for(dir in list(NORTH,EAST,SOUTH,WEST))
+
+ podf = locate(/obj/machinery/clonepod, get_step(src, dir))
+
+ if (!isnull(podf) && podf.is_operational())
+ AttachCloner(podf)
+
+/obj/machinery/computer/cloning/proc/AttachCloner(obj/machinery/clonepod/pod)
+ if(!pod.connected)
+ pod.connected = src
+ LAZYADD(pods, pod)
+
+/obj/machinery/computer/cloning/proc/DetachCloner(obj/machinery/clonepod/pod)
+ pod.connected = null
+ LAZYREMOVE(pods, pod)
+
+/obj/machinery/computer/cloning/attackby(obj/item/W, mob/user, params)
+ if(istype(W, /obj/item/disk/data)) //INSERT SOME DISKETTES
+ if (!src.diskette)
+ if (!user.transferItemToLoc(W,src))
+ return
+ src.diskette = W
+ to_chat(user, "You insert [W]. ")
+ playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
+ src.updateUsrDialog()
else if(istype(W, /obj/item/device/multitool))
- var/obj/item/device/multitool/P = W
-
- if(istype(P.buffer, /obj/machinery/clonepod))
- if(get_area(P.buffer) != get_area(src))
- to_chat(user, "-% Cannot link machines across power zones. Buffer cleared %- ")
- P.buffer = null
- return
- to_chat(user, "-% Successfully linked [P.buffer] with [src] %- ")
- var/obj/machinery/clonepod/pod = P.buffer
- if(pod.connected)
- pod.connected.DetachCloner(pod)
- AttachCloner(pod)
- else
- P.buffer = src
- to_chat(user, "-% Successfully stored \ref[P.buffer] [P.buffer.name] in buffer %- ")
- return
- else
- return ..()
-
-/obj/machinery/computer/cloning/attack_hand(mob/user)
- if(..())
- return
- interact(user)
-
-/obj/machinery/computer/cloning/interact(mob/user)
- user.set_machine(src)
- add_fingerprint(user)
-
- if(..())
- return
-
- updatemodules(TRUE)
-
- var/dat = ""
- dat += "Refresh "
-
- if(scanner && HasEfficientPod() && scanner.scan_level > 2)
- if(!autoprocess)
- dat += "Autoprocess "
- else
- dat += "Stop autoprocess "
- else
- dat += "Autoprocess "
- dat += "Cloning Pod Status "
- dat += "[temp]
"
-
- switch(src.menu)
- if(1)
- // Modules
- if (isnull(src.scanner) || !LAZYLEN(pods))
- dat += "Modules "
- //dat += "Reload Modules "
- if (isnull(src.scanner))
- dat += "ERROR: No Scanner detected! "
- if (!LAZYLEN(pods))
- dat += "ERROR: No Pod detected "
-
- // Scanner
- if (!isnull(src.scanner))
- var/mob/living/scanner_occupant = get_mob_or_brainmob(scanner.occupant)
-
- dat += "Scanner Functions "
-
- dat += ""
- if(!scanner_occupant)
- dat += "Scanner Unoccupied"
- else if(loading)
- dat += "[scanner_occupant] => Scanning..."
- else
- if(scanner_occupant.ckey != scantemp_ckey)
- scantemp = "Ready to Scan"
- scantemp_ckey = scanner_occupant.ckey
- dat += "[scanner_occupant] => [scantemp]"
- dat += "
"
-
- if(scanner_occupant)
- dat += "Start Scan "
- dat += "[src.scanner.locked ? "Unlock Scanner" : "Lock Scanner"] "
- else
- dat += "Start Scan "
-
- // Database
- dat += "Database Functions "
- if (src.records.len && src.records.len > 0)
- dat += "View Records ([src.records.len]) "
- else
- dat += "View Records (0) "
- if (src.diskette)
- dat += "Eject Disk "
-
-
-
- if(2)
- dat += "Current records "
- dat += "<< Back "
- for(var/datum/data/record/R in records)
- dat += "[R.fields["name"]] Scan ID [R.fields["id"]] View Record "
- if(3)
- dat += "Selected Record "
- dat += "<< Back "
-
- if (!src.active_record)
- dat += "Record not found. "
- else
- dat += "[src.active_record.fields["name"]] "
- dat += "Scan ID [src.active_record.fields["id"]] Clone "
-
- var/obj/item/implant/health/H = locate(src.active_record.fields["imp"])
-
- if ((H) && (istype(H)))
- dat += "Health Implant Data: [H.sensehealth()] "
- else
- dat += "Unable to locate Health Implant. "
-
- dat += "Unique Identifier: [src.active_record.fields["UI"]] "
- dat += "Structural Enzymes: [src.active_record.fields["SE"]] "
-
- if(diskette && diskette.fields)
- dat += ""
- dat += "
Inserted Disk "
- dat += "
Contents: "
- var/list/L = list()
- if(diskette.fields["UI"])
- L += "Unique Identifier"
- if(diskette.fields["UE"] && diskette.fields["name"] && diskette.fields["blood_type"])
- L += "Unique Enzymes"
- if(diskette.fields["SE"])
- L += "Structural Enzymes"
- dat += english_list(L, "Empty", " + ", " + ")
- dat += "
Load from Disk "
-
- dat += "
Save to Disk "
- dat += "
"
-
- dat += "Delete Record "
-
- if(4)
- if (!src.active_record)
- src.menu = 2
- dat = "[src.temp] "
- dat += "Confirm Record Deletion "
-
- dat += "Scan card to confirm. "
- dat += "Cancel "
-
-
- var/datum/browser/popup = new(user, "cloning", "Cloning System Control")
- popup.set_content(dat)
- popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
- popup.open()
-
-/obj/machinery/computer/cloning/Topic(href, href_list)
- if(..())
- return
-
- if(loading)
- return
-
- if(href_list["task"])
- switch(href_list["task"])
- if("autoprocess")
- autoprocess = 1
- playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
- if("stopautoprocess")
- autoprocess = 0
- playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
-
- else if ((href_list["scan"]) && !isnull(scanner) && scanner.is_operational())
- scantemp = ""
-
- loading = 1
- src.updateUsrDialog()
- playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
- say("Initiating scan...")
-
- spawn(20)
- src.scan_occupant(scanner.occupant)
-
- loading = 0
- src.updateUsrDialog()
- playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
-
-
- //No locking an open scanner.
- else if ((href_list["lock"]) && !isnull(scanner) && scanner.is_operational())
- if ((!scanner.locked) && (scanner.occupant))
+ var/obj/item/device/multitool/P = W
+
+ if(istype(P.buffer, /obj/machinery/clonepod))
+ if(get_area(P.buffer) != get_area(src))
+ to_chat(user, "-% Cannot link machines across power zones. Buffer cleared %- ")
+ P.buffer = null
+ return
+ to_chat(user, "-% Successfully linked [P.buffer] with [src] %- ")
+ var/obj/machinery/clonepod/pod = P.buffer
+ if(pod.connected)
+ pod.connected.DetachCloner(pod)
+ AttachCloner(pod)
+ else
+ P.buffer = src
+ to_chat(user, "-% Successfully stored \ref[P.buffer] [P.buffer.name] in buffer %- ")
+ return
+ else
+ return ..()
+
+/obj/machinery/computer/cloning/attack_hand(mob/user)
+ if(..())
+ return
+ interact(user)
+
+/obj/machinery/computer/cloning/interact(mob/user)
+ user.set_machine(src)
+ add_fingerprint(user)
+
+ if(..())
+ return
+
+ updatemodules(TRUE)
+
+ var/dat = ""
+ dat += "Refresh "
+
+ if(scanner && HasEfficientPod() && scanner.scan_level > 2)
+ if(!autoprocess)
+ dat += "Autoprocess "
+ else
+ dat += "Stop autoprocess "
+ else
+ dat += "Autoprocess "
+ dat += "Cloning Pod Status "
+ dat += "[temp]
"
+
+ switch(src.menu)
+ if(1)
+ // Modules
+ if (isnull(src.scanner) || !LAZYLEN(pods))
+ dat += "Modules "
+ //dat += "Reload Modules "
+ if (isnull(src.scanner))
+ dat += "ERROR: No Scanner detected! "
+ if (!LAZYLEN(pods))
+ dat += "ERROR: No Pod detected "
+
+ // Scanner
+ if (!isnull(src.scanner))
+ var/mob/living/scanner_occupant = get_mob_or_brainmob(scanner.occupant)
+
+ dat += "Scanner Functions "
+
+ dat += ""
+ if(!scanner_occupant)
+ dat += "Scanner Unoccupied"
+ else if(loading)
+ dat += "[scanner_occupant] => Scanning..."
+ else
+ if(scanner_occupant.ckey != scantemp_ckey)
+ scantemp = "Ready to Scan"
+ scantemp_ckey = scanner_occupant.ckey
+ dat += "[scanner_occupant] => [scantemp]"
+ dat += "
"
+
+ if(scanner_occupant)
+ dat += "Start Scan "
+ dat += "[src.scanner.locked ? "Unlock Scanner" : "Lock Scanner"] "
+ else
+ dat += "Start Scan "
+
+ // Database
+ dat += "Database Functions "
+ if (src.records.len && src.records.len > 0)
+ dat += "View Records ([src.records.len]) "
+ else
+ dat += "View Records (0) "
+ if (src.diskette)
+ dat += "Eject Disk "
+
+
+
+ if(2)
+ dat += "Current records "
+ dat += "<< Back "
+ for(var/datum/data/record/R in records)
+ dat += "[R.fields["name"]] Scan ID [R.fields["id"]] View Record "
+ if(3)
+ dat += "Selected Record "
+ dat += "<< Back "
+
+ if (!src.active_record)
+ dat += "Record not found. "
+ else
+ dat += "[src.active_record.fields["name"]] "
+ dat += "Scan ID [src.active_record.fields["id"]] Clone "
+
+ var/obj/item/implant/health/H = locate(src.active_record.fields["imp"])
+
+ if ((H) && (istype(H)))
+ dat += "Health Implant Data: [H.sensehealth()] "
+ else
+ dat += "Unable to locate Health Implant. "
+
+ dat += "Unique Identifier: [src.active_record.fields["UI"]] "
+ dat += "Structural Enzymes: [src.active_record.fields["SE"]] "
+
+ if(diskette && diskette.fields)
+ dat += ""
+ dat += "
Inserted Disk "
+ dat += "
Contents: "
+ var/list/L = list()
+ if(diskette.fields["UI"])
+ L += "Unique Identifier"
+ if(diskette.fields["UE"] && diskette.fields["name"] && diskette.fields["blood_type"])
+ L += "Unique Enzymes"
+ if(diskette.fields["SE"])
+ L += "Structural Enzymes"
+ dat += english_list(L, "Empty", " + ", " + ")
+ dat += "
Load from Disk "
+
+ dat += "
Save to Disk "
+ dat += "
"
+
+ dat += "Delete Record "
+
+ if(4)
+ if (!src.active_record)
+ src.menu = 2
+ dat = "[src.temp] "
+ dat += "Confirm Record Deletion "
+
+ dat += "Scan card to confirm. "
+ dat += "Cancel "
+
+
+ var/datum/browser/popup = new(user, "cloning", "Cloning System Control")
+ popup.set_content(dat)
+ popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
+ popup.open()
+
+/obj/machinery/computer/cloning/Topic(href, href_list)
+ if(..())
+ return
+
+ if(loading)
+ return
+
+ if(href_list["task"])
+ switch(href_list["task"])
+ if("autoprocess")
+ autoprocess = 1
+ playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
+ if("stopautoprocess")
+ autoprocess = 0
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
+
+ else if ((href_list["scan"]) && !isnull(scanner) && scanner.is_operational())
+ scantemp = ""
+
+ loading = 1
+ src.updateUsrDialog()
+ playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
+ say("Initiating scan...")
+
+ spawn(20)
+ src.scan_occupant(scanner.occupant)
+
+ loading = 0
+ src.updateUsrDialog()
+ playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
+
+
+ //No locking an open scanner.
+ else if ((href_list["lock"]) && !isnull(scanner) && scanner.is_operational())
+ if ((!scanner.locked) && (scanner.occupant))
scanner.locked = TRUE
- playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
- else
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
+ else
scanner.locked = FALSE
- playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
-
- else if(href_list["view_rec"])
- playsound(src, "terminal_type", 25, 0)
- src.active_record = find_record("id", href_list["view_rec"], records)
- if(active_record)
- if(!active_record.fields["ckey"])
- records -= active_record
- active_record = null
- src.temp = "Record Corrupt "
- else
- src.menu = 3
- else
- src.temp = "Record missing."
-
- else if (href_list["del_rec"])
- if ((!src.active_record) || (src.menu < 3))
- return
- if (src.menu == 3) //If we are viewing a record, confirm deletion
- src.temp = "Delete record?"
- src.menu = 4
- playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
-
- else if (src.menu == 4)
- var/obj/item/card/id/C = usr.get_active_held_item()
- if (istype(C)||istype(C, /obj/item/device/pda))
- if(src.check_access(C))
- src.temp = "[src.active_record.fields["name"]] => Record deleted."
- src.records.Remove(active_record)
- active_record = null
- playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
- src.menu = 2
- else
- src.temp = "Access Denied. "
- playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
-
- else if (href_list["disk"]) //Load or eject.
- switch(href_list["disk"])
- if("load")
- if (!diskette || !istype(diskette.fields) || !diskette.fields["name"] || !diskette.fields)
- src.temp = "Load error. "
- src.updateUsrDialog()
- playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
- return
- if (!src.active_record)
- src.temp = "Record error. "
- src.menu = 1
- src.updateUsrDialog()
- playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
- return
-
- for(var/key in diskette.fields)
- src.active_record.fields[key] = diskette.fields[key]
- src.temp = "Load successful."
- playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
-
- if("eject")
- if(src.diskette)
- src.diskette.loc = src.loc
- src.diskette = null
- playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
- if("save")
- if(!diskette || diskette.read_only || !active_record || !active_record.fields)
- src.temp = "Save error. "
- src.updateUsrDialog()
- playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
- return
-
- diskette.fields = active_record.fields.Copy()
- diskette.name = "data disk - '[src.diskette.fields["name"]]'"
- src.temp = "Save successful."
- playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
-
- else if (href_list["refresh"])
- src.updateUsrDialog()
- playsound(src, "terminal_type", 25, 0)
-
- else if (href_list["clone"])
- var/datum/data/record/C = find_record("id", href_list["clone"], records)
- //Look for that player! They better be dead!
- if(C)
- var/obj/machinery/clonepod/pod = GetAvailablePod()
- //Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs.
- if(!LAZYLEN(pods))
- temp = "No Clonepods detected. "
- playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
- else if(!pod)
- temp = "No Clonepods available. "
- playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
- else if(!config.revival_cloning)
- temp = "Unable to initiate cloning cycle. "
- playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
- else if(pod.occupant)
- temp = "Cloning cycle already in progress. "
- playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
- else if(pod.growclone(C.fields["ckey"], C.fields["name"], C.fields["UI"], C.fields["SE"], C.fields["mind"], C.fields["mrace"], C.fields["features"], C.fields["factions"]))
- temp = "[C.fields["name"]] => Cloning cycle in progress... "
- playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
- records.Remove(C)
- if(active_record == C)
- active_record = null
- menu = 1
- else
- temp = "[C.fields["name"]] => Initialisation failure. "
- playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
-
- else
- temp = "Data corruption. "
- playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
-
- else if (href_list["menu"])
- src.menu = text2num(href_list["menu"])
- playsound(src, "terminal_type", 25, 0)
-
- src.add_fingerprint(usr)
- src.updateUsrDialog()
- return
-
-/obj/machinery/computer/cloning/proc/scan_occupant(occupant)
- var/mob/living/mob_occupant = get_mob_or_brainmob(occupant)
- var/datum/dna/dna
- if(iscarbon(mob_occupant))
- var/mob/living/carbon/C = mob_occupant
- dna = C.has_dna()
- if(isbrain(mob_occupant))
- var/mob/living/brain/B = mob_occupant
- dna = B.stored_dna
-
- if(!istype(dna))
- scantemp = "Unable to locate valid genetic data. "
- playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
- return
- if(mob_occupant.suiciding || mob_occupant.hellbound)
- scantemp = "Subject's brain is not responding to scanning stimuli. "
- playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
- return
- if((mob_occupant.disabilities & NOCLONE) && (src.scanner.scan_level < 2))
- scantemp = "Subject no longer contains the fundamental materials required to create a living clone. "
- playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0)
- return
- if ((!mob_occupant.ckey) || (!mob_occupant.client))
- scantemp = "Mental interface failure. "
- playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
- return
- if (find_record("ckey", mob_occupant.ckey, records))
- scantemp = "Subject already in database. "
- playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
- return
-
- var/datum/data/record/R = new()
- if(dna.species)
- // We store the instance rather than the path, because some
- // species (abductors, slimepeople) store state in their
- // species datums
- R.fields["mrace"] = dna.species
- else
- var/datum/species/rando_race = pick(config.roundstart_races)
- R.fields["mrace"] = rando_race.type
-
- R.fields["ckey"] = mob_occupant.ckey
- R.fields["name"] = mob_occupant.real_name
- R.fields["id"] = copytext(md5(mob_occupant.real_name), 2, 6)
- R.fields["UE"] = dna.unique_enzymes
- R.fields["UI"] = dna.uni_identity
- R.fields["SE"] = dna.struc_enzymes
- R.fields["blood_type"] = dna.blood_type
- R.fields["features"] = dna.features
- R.fields["factions"] = mob_occupant.faction
-
- if (!isnull(mob_occupant.mind)) //Save that mind so traitors can continue traitoring after cloning.
- R.fields["mind"] = "\ref[mob_occupant.mind]"
-
- //Add an implant if needed
- var/obj/item/implant/health/imp
- for(var/obj/item/implant/health/HI in mob_occupant.implants)
- imp = HI
- break
- if(!imp)
- imp = new /obj/item/implant/health(mob_occupant)
- imp.implant(mob_occupant)
- R.fields["imp"] = "\ref[imp]"
-
- src.records += R
- scantemp = "Subject successfully scanned."
- playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
+ playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
+
+ else if(href_list["view_rec"])
+ playsound(src, "terminal_type", 25, 0)
+ src.active_record = find_record("id", href_list["view_rec"], records)
+ if(active_record)
+ if(!active_record.fields["ckey"])
+ records -= active_record
+ active_record = null
+ src.temp = "Record Corrupt "
+ else
+ src.menu = 3
+ else
+ src.temp = "Record missing."
+
+ else if (href_list["del_rec"])
+ if ((!src.active_record) || (src.menu < 3))
+ return
+ if (src.menu == 3) //If we are viewing a record, confirm deletion
+ src.temp = "Delete record?"
+ src.menu = 4
+ playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
+
+ else if (src.menu == 4)
+ var/obj/item/card/id/C = usr.get_active_held_item()
+ if (istype(C)||istype(C, /obj/item/device/pda))
+ if(src.check_access(C))
+ src.temp = "[src.active_record.fields["name"]] => Record deleted."
+ src.records.Remove(active_record)
+ active_record = null
+ playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
+ src.menu = 2
+ else
+ src.temp = "Access Denied. "
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
+
+ else if (href_list["disk"]) //Load or eject.
+ switch(href_list["disk"])
+ if("load")
+ if (!diskette || !istype(diskette.fields) || !diskette.fields["name"] || !diskette.fields)
+ src.temp = "Load error. "
+ src.updateUsrDialog()
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
+ return
+ if (!src.active_record)
+ src.temp = "Record error. "
+ src.menu = 1
+ src.updateUsrDialog()
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
+ return
+
+ for(var/key in diskette.fields)
+ src.active_record.fields[key] = diskette.fields[key]
+ src.temp = "Load successful."
+ playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
+
+ if("eject")
+ if(src.diskette)
+ src.diskette.forceMove(drop_location())
+ src.diskette = null
+ playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
+ if("save")
+ if(!diskette || diskette.read_only || !active_record || !active_record.fields)
+ src.temp = "Save error. "
+ src.updateUsrDialog()
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
+ return
+
+ diskette.fields = active_record.fields.Copy()
+ diskette.name = "data disk - '[src.diskette.fields["name"]]'"
+ src.temp = "Save successful."
+ playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
+
+ else if (href_list["refresh"])
+ src.updateUsrDialog()
+ playsound(src, "terminal_type", 25, 0)
+
+ else if (href_list["clone"])
+ var/datum/data/record/C = find_record("id", href_list["clone"], records)
+ //Look for that player! They better be dead!
+ if(C)
+ var/obj/machinery/clonepod/pod = GetAvailablePod()
+ //Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs.
+ if(!LAZYLEN(pods))
+ temp = "No Clonepods detected. "
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
+ else if(!pod)
+ temp = "No Clonepods available. "
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
+ else if(!CONFIG_GET(flag/revival_cloning))
+ temp = "Unable to initiate cloning cycle. "
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
+ else if(pod.occupant)
+ temp = "Cloning cycle already in progress. "
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
+ else if(pod.growclone(C.fields["ckey"], C.fields["name"], C.fields["UI"], C.fields["SE"], C.fields["mind"], C.fields["mrace"], C.fields["features"], C.fields["factions"]))
+ temp = "[C.fields["name"]] => Cloning cycle in progress... "
+ playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
+ records.Remove(C)
+ if(active_record == C)
+ active_record = null
+ menu = 1
+ else
+ temp = "[C.fields["name"]] => Initialisation failure. "
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
+
+ else
+ temp = "Data corruption. "
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
+
+ else if (href_list["menu"])
+ src.menu = text2num(href_list["menu"])
+ playsound(src, "terminal_type", 25, 0)
+
+ src.add_fingerprint(usr)
+ src.updateUsrDialog()
+ return
+
+/obj/machinery/computer/cloning/proc/scan_occupant(occupant)
+ var/mob/living/mob_occupant = get_mob_or_brainmob(occupant)
+ var/datum/dna/dna
+ if(iscarbon(mob_occupant))
+ var/mob/living/carbon/C = mob_occupant
+ dna = C.has_dna()
+ if(isbrain(mob_occupant))
+ var/mob/living/brain/B = mob_occupant
+ dna = B.stored_dna
+
+ if(!istype(dna))
+ scantemp = "Unable to locate valid genetic data. "
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
+ return
+ if(mob_occupant.suiciding || mob_occupant.hellbound)
+ scantemp = "Subject's brain is not responding to scanning stimuli. "
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
+ return
+ if((mob_occupant.disabilities & NOCLONE) && (src.scanner.scan_level < 2))
+ scantemp = "Subject no longer contains the fundamental materials required to create a living clone. "
+ playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0)
+ return
+ if ((!mob_occupant.ckey) || (!mob_occupant.client))
+ scantemp = "Mental interface failure. "
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
+ return
+ if (find_record("ckey", mob_occupant.ckey, records))
+ scantemp = "Subject already in database. "
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
+ return
+
+ var/datum/data/record/R = new()
+ if(dna.species)
+ // We store the instance rather than the path, because some
+ // species (abductors, slimepeople) store state in their
+ // species datums
+ R.fields["mrace"] = dna.species
+ else
+ var/datum/species/rando_race = pick(CONFIG_GET(keyed_flag_list/roundstart_races))
+ R.fields["mrace"] = rando_race.type
+
+ R.fields["ckey"] = mob_occupant.ckey
+ R.fields["name"] = mob_occupant.real_name
+ R.fields["id"] = copytext(md5(mob_occupant.real_name), 2, 6)
+ R.fields["UE"] = dna.unique_enzymes
+ R.fields["UI"] = dna.uni_identity
+ R.fields["SE"] = dna.struc_enzymes
+ R.fields["blood_type"] = dna.blood_type
+ R.fields["features"] = dna.features
+ R.fields["factions"] = mob_occupant.faction
+
+ if (!isnull(mob_occupant.mind)) //Save that mind so traitors can continue traitoring after cloning.
+ R.fields["mind"] = "\ref[mob_occupant.mind]"
+
+ //Add an implant if needed
+ var/obj/item/implant/health/imp
+ for(var/obj/item/implant/health/HI in mob_occupant.implants)
+ imp = HI
+ break
+ if(!imp)
+ imp = new /obj/item/implant/health(mob_occupant)
+ imp.implant(mob_occupant)
+ R.fields["imp"] = "\ref[imp]"
+
+ src.records += R
+ scantemp = "Subject successfully scanned."
+ playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
index bd203772cb..89b2bc4620 100755
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -454,7 +454,7 @@
if (src.authenticated==2)
dat += "Captain Functions "
dat += " \[ Make a Captain's Announcement \]"
- if(config.cross_allowed)
+ if(CONFIG_GET(string/cross_server_address))
dat += " \[ Send a message to an allied station \]"
if(SSmapping.config.allow_custom_shuttles == "yes")
dat += " \[ Purchase Shuttle \]"
diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm
index 105fb64042..cfc3c13cfc 100644
--- a/code/game/machinery/computer/dna_console.dm
+++ b/code/game/machinery/computer/dna_console.dm
@@ -43,9 +43,8 @@
/obj/machinery/computer/scan_consolenew/attackby(obj/item/I, mob/user, params)
if (istype(I, /obj/item/disk/data)) //INSERT SOME DISKETTES
if (!src.diskette)
- if(!user.drop_item())
+ if (!user.transferItemToLoc(I,src))
return
- I.loc = src
src.diskette = I
to_chat(user, "You insert [I]. ")
src.updateUsrDialog()
@@ -169,7 +168,7 @@
if("working")
temp_html += status
temp_html += "System Busy "
- temp_html += "Working ... Please wait ([DisplayTimeText(radduration)])"
+ temp_html += "Working ... Please wait ([DisplayTimeText(radduration*10)])"
if("buffer")
temp_html += status
temp_html += buttons
@@ -448,7 +447,7 @@
diskette.fields = buffer_slot.Copy()
if("ejectdisk")
if(diskette)
- diskette.loc = get_turf(src)
+ diskette.forceMove(drop_location())
diskette = null
if("setdelayed")
if(num)
diff --git a/code/game/machinery/computer/gulag_teleporter.dm b/code/game/machinery/computer/gulag_teleporter.dm
index c416d93e58..d80dc73f15 100644
--- a/code/game/machinery/computer/gulag_teleporter.dm
+++ b/code/game/machinery/computer/gulag_teleporter.dm
@@ -27,9 +27,8 @@
/obj/machinery/computer/gulag_teleporter_computer/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/card/id/prisoner))
if(!id)
- if(!user.drop_item())
+ if (!user.transferItemToLoc(W,src))
return
- W.forceMove(src)
id = W
to_chat(user, "You insert [W]. ")
return
diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm
index f2ea3238ef..6ec144d257 100644
--- a/code/game/machinery/computer/medical.dm
+++ b/code/game/machinery/computer/medical.dm
@@ -124,7 +124,7 @@
dat += "ID: [active1.fields["id"]] "
dat += "Sex: [active1.fields["sex"]] "
dat += "Age: [active1.fields["age"]] "
- if(config.mutant_races)
+ if(CONFIG_GET(flag/join_with_mutant_race))
dat += "Species: [active1.fields["species"]] "
dat += "Fingerprint: [active1.fields["fingerprint"]] "
dat += "Physical Status: [active1.fields["p_stat"]] "
@@ -543,7 +543,7 @@
P.info = "Medical Record - (MR-[GLOB.data_core.medicalPrintCount]) "
if(active1 in GLOB.data_core.general)
P.info += text("Name: [] ID: [] \nSex: [] \nAge: [] ", src.active1.fields["name"], src.active1.fields["id"], src.active1.fields["sex"], src.active1.fields["age"])
- if(config.mutant_races)
+ if(CONFIG_GET(flag/join_with_mutant_race))
P.info += "\nSpecies: [active1.fields["species"]] "
P.info += text("\nFingerprint: [] \nPhysical Status: [] \nMental Status: [] ", src.active1.fields["fingerprint"], src.active1.fields["p_stat"], src.active1.fields["m_stat"])
else
diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm
index 00787f10e2..1a74c44c30 100644
--- a/code/game/machinery/computer/security.dm
+++ b/code/game/machinery/computer/security.dm
@@ -186,7 +186,7 @@
ID: [active1.fields["id"]]
Sex: [active1.fields["sex"]]
Age: [active1.fields["age"]] "}
- if(config.mutant_races)
+ if(CONFIG_GET(flag/join_with_mutant_race))
dat += "Species: [active1.fields["species"]] "
dat += {"Rank: [active1.fields["rank"]]
Fingerprint: [active1.fields["fingerprint"]]
@@ -373,7 +373,7 @@ What a mess.*/
P.info = "Security Record - (SR-[GLOB.data_core.securityPrintCount]) "
if((istype(active1, /datum/data/record) && GLOB.data_core.general.Find(active1)))
P.info += text("Name: [] ID: [] \nSex: [] \nAge: [] ", active1.fields["name"], active1.fields["id"], active1.fields["sex"], active1.fields["age"])
- if(config.mutant_races)
+ if(CONFIG_GET(flag/join_with_mutant_race))
P.info += "\nSpecies: [active1.fields["species"]] "
P.info += text("\nFingerprint: [] \nPhysical Status: [] \nMental Status: [] ", active1.fields["fingerprint"], active1.fields["p_stat"], active1.fields["m_stat"])
else
@@ -519,7 +519,7 @@ What a mess.*/
G.fields["rank"] = "Unassigned"
G.fields["sex"] = "Male"
G.fields["age"] = "Unknown"
- if(config.mutant_races)
+ if(CONFIG_GET(flag/join_with_mutant_race))
G.fields["species"] = "Human"
G.fields["photo_front"] = new /icon()
G.fields["photo_side"] = new /icon()
@@ -604,7 +604,7 @@ What a mess.*/
active1.fields["age"] = t1
if("species")
if(istype(active1, /datum/data/record))
- var/t1 = input("Select a species", "Species Selection") as null|anything in GLOB.roundstart_species
+ var/t1 = input("Select a species", "Species Selection") as null|anything in CONFIG_GET(keyed_flag_list/roundstart_races)
if(!canUseSecurityRecordsConsole(usr, t1, a1))
return
active1.fields["species"] = t1
@@ -772,7 +772,7 @@ What a mess.*/
if(6)
R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable")
if(7)
- R.fields["species"] = pick(GLOB.roundstart_species)
+ R.fields["species"] = pick(CONFIG_GET(keyed_flag_list/roundstart_races))
if(8)
var/datum/data/record/G = pick(GLOB.data_core.general)
R.fields["photo_front"] = G.fields["photo_front"]
diff --git a/code/game/machinery/doors/airlock_electronics.dm b/code/game/machinery/doors/airlock_electronics.dm
index f27e3da2dc..f52ffd42fe 100644
--- a/code/game/machinery/doors/airlock_electronics.dm
+++ b/code/game/machinery/doors/airlock_electronics.dm
@@ -5,6 +5,10 @@
var/list/accesses = list()
var/one_access = 0
+/obj/item/electronics/airlock/examine(mob/user)
+ ..()
+ to_chat(user, "Has a neat selection menu for modifying airlock access levels. ")
+
/obj/item/electronics/airlock/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state)
SStgui.try_update_ui(user, src, ui_key, ui, force_open)
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index 65a92c0b1a..883cc3986f 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -33,6 +33,10 @@
var/damage_deflection = 10
var/real_explosion_block //ignore this, just use explosion_block
+/obj/machinery/door/examine(mob/user)
+ ..()
+ to_chat(user, "Its maintenance panel is screwed in place. ")
+
/obj/machinery/door/New()
..()
if(density)
@@ -79,7 +83,7 @@
bumpopen(M)
return
- if(istype(AM, /obj/mecha))
+ if(ismecha(AM))
var/obj/mecha/mecha = AM
if(density)
if(mecha.occupant)
diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm
index f76412199c..4809f3ff49 100644
--- a/code/game/machinery/doors/windowdoor.dm
+++ b/code/game/machinery/doors/windowdoor.dm
@@ -62,7 +62,7 @@
if( operating || !src.density )
return
if (!( ismob(AM) ))
- if(istype(AM, /obj/mecha))
+ if(ismecha(AM))
var/obj/mecha/mecha = AM
if(mecha.occupant && src.allowed(mecha.occupant))
open_and_close()
diff --git a/code/game/machinery/embedded_controller/access_controller.dm b/code/game/machinery/embedded_controller/access_controller.dm
index c23f4d0ba8..5e0d018554 100644
--- a/code/game/machinery/embedded_controller/access_controller.dm
+++ b/code/game/machinery/embedded_controller/access_controller.dm
@@ -42,6 +42,7 @@
icon = 'icons/obj/airlock_machines.dmi'
icon_state = "access_button_standby"
name = "access button"
+ desc = "A button used for the explicit purpose of opening an airlock."
var/idDoor
var/obj/machinery/door/airlock/door
var/obj/machinery/doorButtons/airlock_controller/controller
@@ -107,6 +108,7 @@
icon = 'icons/obj/airlock_machines.dmi'
icon_state = "access_control_standby"
name = "access console"
+ desc = "A small console that can cycle opening between two airlocks."
var/obj/machinery/door/airlock/interiorAirlock
var/obj/machinery/door/airlock/exteriorAirlock
var/idInterior
diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm
index a979ba6398..102be57f9b 100644
--- a/code/game/machinery/lightswitch.dm
+++ b/code/game/machinery/lightswitch.dm
@@ -6,6 +6,7 @@
icon = 'icons/obj/power.dmi'
icon_state = "light1"
anchored = TRUE
+ desc = "Make dark."
var/on = TRUE
var/area/area = null
var/otherarea = null
diff --git a/code/game/machinery/mass_driver.dm b/code/game/machinery/mass_driver.dm
index 17f573fe6d..9acd4730d8 100644
--- a/code/game/machinery/mass_driver.dm
+++ b/code/game/machinery/mass_driver.dm
@@ -20,7 +20,7 @@
var/O_limit
var/atom/target = get_edge_target_turf(src, dir)
for(var/atom/movable/O in loc)
- if(!O.anchored || istype(O, /obj/mecha)) //Mechs need their launch platforms.
+ if(!O.anchored || ismecha(O)) //Mechs need their launch platforms.
O_limit++
if(O_limit >= 20)
audible_message("[src] lets out a screech, it doesn't seem to be able to handle the load. ")
diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm
index 39b3760f7e..cedb94b7b3 100644
--- a/code/game/machinery/pipe/pipe_dispenser.dm
+++ b/code/game/machinery/pipe/pipe_dispenser.dm
@@ -2,6 +2,7 @@
name = "pipe dispenser"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "pipe_d"
+ desc = "Dispenses countless types of pipes. Very useful if you need pipes."
density = TRUE
anchored = TRUE
var/wait = 0
@@ -108,6 +109,7 @@
name = "disposal pipe dispenser"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "pipe_d"
+ desc = "Dispenses pipes that will ultimately be used to move trash around."
density = TRUE
anchored = TRUE
@@ -183,6 +185,7 @@ Nah
icon = 'icons/obj/stationobjs.dmi'
icon_state = "pipe_d"
density = TRUE
+ desc = "Dispenses pipes that will move beings around."
anchored = TRUE
/obj/machinery/pipedispenser/disposal/transit_tube/attack_hand(mob/user)
diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm
index b84de7cf18..8f8202fe19 100644
--- a/code/game/machinery/porta_turret/portable_turret.dm
+++ b/code/game/machinery/porta_turret/portable_turret.dm
@@ -12,6 +12,7 @@
layer = OBJ_LAYER
invisibility = INVISIBILITY_OBSERVER //the turret is invisible if it's inside its cover
density = TRUE
+ desc = "A covered turret that shoots at its enemies."
use_power = IDLE_POWER_USE //this turret uses and requires power
idle_power_usage = 50 //when inactive, this turret takes up constant 50 Equipment power
active_power_usage = 300 //when active, this turret takes up constant 300 Equipment power
@@ -389,7 +390,7 @@
if(!in_faction(C))
targets += C
- if(istype(A, /obj/mecha))
+ if(ismecha(A))
var/obj/mecha/M = A
//If there is a user and they're not in our faction
if(M.occupant && !in_faction(M.occupant))
@@ -552,6 +553,7 @@
base_icon_state = "syndie"
faction = "syndicate"
emp_vunerable = 0
+ desc = "A ballistic machine gun auto-turret."
/obj/machinery/porta_turret/syndicate/energy
icon_state = "standard_stun"
@@ -560,6 +562,7 @@
stun_projectile_sound = 'sound/weapons/taser.ogg'
lethal_projectile = /obj/item/projectile/beam/laser/heavylaser
lethal_projectile_sound = 'sound/weapons/lasercannonfire.ogg'
+ desc = "An energy blaster auto-turret."
/obj/machinery/porta_turret/syndicate/setup()
return
diff --git a/code/game/machinery/porta_turret/portable_turret_construct.dm b/code/game/machinery/porta_turret/portable_turret_construct.dm
index 1dbdc52b1e..7eace08636 100644
--- a/code/game/machinery/porta_turret/portable_turret_construct.dm
+++ b/code/game/machinery/porta_turret/portable_turret_construct.dm
@@ -12,6 +12,7 @@
name = "turret frame"
icon = 'icons/obj/turrets.dmi'
icon_state = "turret_frame"
+ desc = "An unfinished covered turret frame."
density = TRUE
var/build_step = PTURRET_UNSECURED //the current step in the building process
var/finish_name = "turret" //the name applied to the product turret
diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm
index fbe02dca37..d2ea1a4fd6 100644
--- a/code/game/machinery/recycler.dm
+++ b/code/game/machinery/recycler.dm
@@ -1,197 +1,198 @@
-#define SAFETY_COOLDOWN 100
-
-/obj/machinery/recycler
- name = "recycler"
- desc = "A large crushing machine used to recycle small items inefficiently. There are lights on the side."
- icon = 'icons/obj/recycling.dmi'
- icon_state = "grinder-o0"
- layer = ABOVE_ALL_MOB_LAYER // Overhead
- anchored = TRUE
- density = TRUE
- circuit = /obj/item/circuitboard/machine/recycler
- var/safety_mode = FALSE // Temporarily stops machine if it detects a mob
- var/icon_name = "grinder-o"
- var/blood = 0
- var/eat_dir = WEST
- var/amount_produced = 50
- var/crush_damage = 1000
- var/eat_victim_items = TRUE
- var/item_recycle_sound = 'sound/items/welder.ogg'
-
-/obj/machinery/recycler/Initialize()
- AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_PLASMA, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM))
- . = ..()
- update_icon()
-
-/obj/machinery/recycler/RefreshParts()
- var/amt_made = 0
- var/mat_mod = 0
- for(var/obj/item/stock_parts/matter_bin/B in component_parts)
- mat_mod = 2 * B.rating
- mat_mod *= 50000
- for(var/obj/item/stock_parts/manipulator/M in component_parts)
- amt_made = 12.5 * M.rating //% of materials salvaged
- GET_COMPONENT(materials, /datum/component/material_container)
- materials.max_amount = mat_mod
- amount_produced = min(50, amt_made) + 50
-
-/obj/machinery/recycler/examine(mob/user)
- ..()
- to_chat(user, "The power light is [(stat & NOPOWER) ? "off" : "on"].")
- to_chat(user, "The safety-mode light is [safety_mode ? "on" : "off"].")
- to_chat(user, "The safety-sensors status light is [emagged ? "off" : "on"].")
-
-/obj/machinery/recycler/power_change()
- ..()
- update_icon()
-
-
-/obj/machinery/recycler/attackby(obj/item/I, mob/user, params)
- if(default_deconstruction_screwdriver(user, "grinder-oOpen", "grinder-o0", I))
- return
-
- if(exchange_parts(user, I))
- return
-
- if(default_pry_open(I))
- return
-
- if(default_unfasten_wrench(user, I))
- return
-
- if(default_deconstruction_crowbar(I))
- return
- return ..()
-
-/obj/machinery/recycler/emag_act(mob/user)
- if(emagged)
- return
- emagged = TRUE
- if(safety_mode)
- safety_mode = FALSE
- update_icon()
- playsound(src, "sparks", 75, 1, -1)
- to_chat(user, "You use the cryptographic sequencer on the [src]. ")
-
-/obj/machinery/recycler/update_icon()
- ..()
- var/is_powered = !(stat & (BROKEN|NOPOWER))
- if(safety_mode)
- is_powered = FALSE
- icon_state = icon_name + "[is_powered]" + "[(blood ? "bld" : "")]" // add the blood tag at the end
-
-/obj/machinery/recycler/CollidedWith(atom/movable/AM)
-
- if(stat & (BROKEN|NOPOWER))
- return
- if(!anchored)
- return
- if(safety_mode)
- return
-
- var/move_dir = get_dir(loc, AM.loc)
- if(move_dir == eat_dir)
- eat(AM)
-
-/obj/machinery/recycler/proc/eat(atom/AM0, sound=TRUE)
- var/list/to_eat
- if(istype(AM0, /obj/item))
- to_eat = AM0.GetAllContents()
- else
- to_eat = list(AM0)
-
- var/items_recycled = 0
-
- for(var/i in to_eat)
- var/atom/movable/AM = i
- var/obj/item/bodypart/head/as_head = AM
- var/obj/item/device/mmi/as_mmi = AM
- var/brain_holder = istype(AM, /obj/item/organ/brain) || (istype(as_head) && as_head.brain) || (istype(as_mmi) && as_mmi.brain) || istype(AM, /mob/living/brain)
- if(isliving(AM) || brain_holder)
- if(emagged)
- if(!brain_holder)
- crush_living(AM)
- else
- emergency_stop(AM)
- else if(istype(AM, /obj/item))
- recycle_item(AM)
- items_recycled++
- else
- playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
- AM.loc = src.loc
-
- if(items_recycled && sound)
- playsound(src.loc, item_recycle_sound, 50, 1)
-
-/obj/machinery/recycler/proc/recycle_item(obj/item/I)
- I.loc = src.loc
-
- GET_COMPONENT(materials, /datum/component/material_container)
- var/material_amount = materials.get_item_material_amount(I)
- if(!material_amount)
- qdel(I)
- return
- materials.insert_item(I, multiplier = (amount_produced / 100))
- qdel(I)
- materials.retrieve_all()
-
-
-/obj/machinery/recycler/proc/emergency_stop(mob/living/L)
- playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
- safety_mode = TRUE
- update_icon()
- L.loc = src.loc
- addtimer(CALLBACK(src, .proc/reboot), SAFETY_COOLDOWN)
-
-/obj/machinery/recycler/proc/reboot()
- playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
- safety_mode = FALSE
- update_icon()
-
-/obj/machinery/recycler/proc/crush_living(mob/living/L)
-
- L.loc = src.loc
-
- if(issilicon(L))
- playsound(src.loc, 'sound/items/welder.ogg', 50, 1)
- else
- playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
-
- var/gib = TRUE
- // By default, the emagged recycler will gib all non-carbons. (human simple animal mobs don't count)
- if(iscarbon(L))
- gib = FALSE
- if(L.stat == CONSCIOUS)
- L.say("ARRRRRRRRRRRGH!!!")
- add_mob_blood(L)
-
- if(!blood && !issilicon(L))
- blood = TRUE
- update_icon()
-
- // Remove and recycle the equipped items
- if(eat_victim_items)
- for(var/obj/item/I in L.get_equipped_items())
- if(L.dropItemToGround(I))
- eat(I, sound=FALSE)
-
- // Instantly lie down, also go unconscious from the pain, before you die.
- L.Unconscious(100)
-
- // For admin fun, var edit emagged to 2.
- if(gib || emagged == 2)
- L.gib()
- else if(emagged == 1)
- L.adjustBruteLoss(crush_damage)
-
-/obj/machinery/recycler/deathtrap
- name = "dangerous old crusher"
- emagged = TRUE
- crush_damage = 120
- flags_1 = NODECONSTRUCT_1
-
-/obj/item/paper/guides/recycler
- name = "paper - 'garbage duty instructions'"
- info = "New Assignment You have been assigned to collect garbage from trash bins, located around the station. The crewmembers will put their trash into it and you will collect the said trash. There is a recycling machine near your closet, inside maintenance; use it to recycle the trash for a small chance to get useful minerals. Then deliver these minerals to cargo or engineering. You are our last hope for a clean station, do not screw this up!"
-
-#undef SAFETY_COOLDOWN
+#define SAFETY_COOLDOWN 100
+
+/obj/machinery/recycler
+ name = "recycler"
+ desc = "A large crushing machine used to recycle small items inefficiently. There are lights on the side."
+ icon = 'icons/obj/recycling.dmi'
+ icon_state = "grinder-o0"
+ layer = ABOVE_ALL_MOB_LAYER // Overhead
+ anchored = TRUE
+ density = TRUE
+ circuit = /obj/item/circuitboard/machine/recycler
+ var/safety_mode = FALSE // Temporarily stops machine if it detects a mob
+ var/icon_name = "grinder-o"
+ var/blood = 0
+ var/eat_dir = WEST
+ var/amount_produced = 50
+ var/crush_damage = 1000
+ var/eat_victim_items = TRUE
+ var/item_recycle_sound = 'sound/items/welder.ogg'
+
+/obj/machinery/recycler/Initialize()
+ AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_PLASMA, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM))
+ . = ..()
+ update_icon()
+
+/obj/machinery/recycler/RefreshParts()
+ var/amt_made = 0
+ var/mat_mod = 0
+ for(var/obj/item/stock_parts/matter_bin/B in component_parts)
+ mat_mod = 2 * B.rating
+ mat_mod *= 50000
+ for(var/obj/item/stock_parts/manipulator/M in component_parts)
+ amt_made = 12.5 * M.rating //% of materials salvaged
+ GET_COMPONENT(materials, /datum/component/material_container)
+ materials.max_amount = mat_mod
+ amount_produced = min(50, amt_made) + 50
+
+/obj/machinery/recycler/examine(mob/user)
+ ..()
+ to_chat(user, "The power light is [(stat & NOPOWER) ? "off" : "on"].")
+ to_chat(user, "The safety-mode light is [safety_mode ? "on" : "off"].")
+ to_chat(user, "The safety-sensors status light is [emagged ? "off" : "on"].")
+
+/obj/machinery/recycler/power_change()
+ ..()
+ update_icon()
+
+
+/obj/machinery/recycler/attackby(obj/item/I, mob/user, params)
+ if(default_deconstruction_screwdriver(user, "grinder-oOpen", "grinder-o0", I))
+ return
+
+ if(exchange_parts(user, I))
+ return
+
+ if(default_pry_open(I))
+ return
+
+ if(default_unfasten_wrench(user, I))
+ return
+
+ if(default_deconstruction_crowbar(I))
+ return
+ return ..()
+
+/obj/machinery/recycler/emag_act(mob/user)
+ if(emagged)
+ return
+ emagged = TRUE
+ if(safety_mode)
+ safety_mode = FALSE
+ update_icon()
+ playsound(src, "sparks", 75, 1, -1)
+ to_chat(user, "You use the cryptographic sequencer on the [src]. ")
+
+/obj/machinery/recycler/update_icon()
+ ..()
+ var/is_powered = !(stat & (BROKEN|NOPOWER))
+ if(safety_mode)
+ is_powered = FALSE
+ icon_state = icon_name + "[is_powered]" + "[(blood ? "bld" : "")]" // add the blood tag at the end
+
+/obj/machinery/recycler/CollidedWith(atom/movable/AM)
+
+ if(stat & (BROKEN|NOPOWER))
+ return
+ if(!anchored)
+ return
+ if(safety_mode)
+ return
+
+ var/move_dir = get_dir(loc, AM.loc)
+ if(move_dir == eat_dir)
+ eat(AM)
+
+/obj/machinery/recycler/proc/eat(atom/AM0, sound=TRUE)
+ var/list/to_eat
+ if(istype(AM0, /obj/item))
+ to_eat = AM0.GetAllContents()
+ else
+ to_eat = list(AM0)
+
+ var/items_recycled = 0
+
+ for(var/i in to_eat)
+ var/atom/movable/AM = i
+ var/obj/item/bodypart/head/as_head = AM
+ var/obj/item/device/mmi/as_mmi = AM
+ var/brain_holder = istype(AM, /obj/item/organ/brain) || (istype(as_head) && as_head.brain) || (istype(as_mmi) && as_mmi.brain) || istype(AM, /mob/living/brain)
+ if(brain_holder)
+ emergency_stop(AM)
+ else if(isliving(AM))
+ if(emagged)
+ crush_living(AM)
+ else
+ emergency_stop(AM)
+ else if(istype(AM, /obj/item))
+ recycle_item(AM)
+ items_recycled++
+ else
+ playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 0)
+ AM.forceMove(loc)
+
+ if(items_recycled && sound)
+ playsound(src, item_recycle_sound, 50, 1)
+
+/obj/machinery/recycler/proc/recycle_item(obj/item/I)
+ I.forceMove(loc)
+
+ GET_COMPONENT(materials, /datum/component/material_container)
+ var/material_amount = materials.get_item_material_amount(I)
+ if(!material_amount)
+ qdel(I)
+ return
+ materials.insert_item(I, multiplier = (amount_produced / 100))
+ qdel(I)
+ materials.retrieve_all()
+
+
+/obj/machinery/recycler/proc/emergency_stop(mob/living/L)
+ playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 0)
+ safety_mode = TRUE
+ update_icon()
+ L.forceMove(loc)
+ addtimer(CALLBACK(src, .proc/reboot), SAFETY_COOLDOWN)
+
+/obj/machinery/recycler/proc/reboot()
+ playsound(src, 'sound/machines/ping.ogg', 50, 0)
+ safety_mode = FALSE
+ update_icon()
+
+/obj/machinery/recycler/proc/crush_living(mob/living/L)
+
+ L.forceMove(loc)
+
+ if(issilicon(L))
+ playsound(src, 'sound/items/welder.ogg', 50, 1)
+ else
+ playsound(src, 'sound/effects/splat.ogg', 50, 1)
+
+ var/gib = TRUE
+ // By default, the emagged recycler will gib all non-carbons. (human simple animal mobs don't count)
+ if(iscarbon(L))
+ gib = FALSE
+ if(L.stat == CONSCIOUS)
+ L.say("ARRRRRRRRRRRGH!!!")
+ add_mob_blood(L)
+
+ if(!blood && !issilicon(L))
+ blood = TRUE
+ update_icon()
+
+ // Remove and recycle the equipped items
+ if(eat_victim_items)
+ for(var/obj/item/I in L.get_equipped_items())
+ if(L.dropItemToGround(I))
+ eat(I, sound=FALSE)
+
+ // Instantly lie down, also go unconscious from the pain, before you die.
+ L.Unconscious(100)
+
+ // For admin fun, var edit emagged to 2.
+ if(gib || emagged == 2)
+ L.gib()
+ else if(emagged == 1)
+ L.adjustBruteLoss(crush_damage)
+
+/obj/machinery/recycler/deathtrap
+ name = "dangerous old crusher"
+ emagged = TRUE
+ crush_damage = 120
+ flags_1 = NODECONSTRUCT_1
+
+/obj/item/paper/guides/recycler
+ name = "paper - 'garbage duty instructions'"
+ info = "New Assignment You have been assigned to collect garbage from trash bins, located around the station. The crewmembers will put their trash into it and you will collect the said trash. There is a recycling machine near your closet, inside maintenance; use it to recycle the trash for a small chance to get useful minerals. Then deliver these minerals to cargo or engineering. You are our last hope for a clean station, do not screw this up!"
+
+#undef SAFETY_COOLDOWN
diff --git a/code/game/machinery/telecomms/computers/logbrowser.dm b/code/game/machinery/telecomms/computers/logbrowser.dm
index 92a4edfcd2..590c8d03a5 100644
--- a/code/game/machinery/telecomms/computers/logbrowser.dm
+++ b/code/game/machinery/telecomms/computers/logbrowser.dm
@@ -3,6 +3,7 @@
/obj/machinery/computer/telecomms/server
name = "telecommunications server monitoring console"
icon_screen = "comm_logs"
+ desc = "Has full access to all details and record of the telecommunications network it's monitoring."
var/screen = 0 // the screen number:
var/list/servers = list() // the servers located by the computer
diff --git a/code/game/machinery/telecomms/computers/telemonitor.dm b/code/game/machinery/telecomms/computers/telemonitor.dm
index bccbfd96fd..cb3ae78e72 100644
--- a/code/game/machinery/telecomms/computers/telemonitor.dm
+++ b/code/game/machinery/telecomms/computers/telemonitor.dm
@@ -8,6 +8,7 @@
/obj/machinery/computer/telecomms/monitor
name = "telecommunications monitoring console"
icon_screen = "comm_monitor"
+ desc = "Monitors the details of the telecommunications network it's synced with."
var/screen = 0 // the screen number:
var/list/machinelist = list() // the machines located by the computer
diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm
index 8efc14d966..747647b1a5 100644
--- a/code/game/mecha/mech_fabricator.dm
+++ b/code/game/mecha/mech_fabricator.dm
@@ -420,13 +420,7 @@
var/datum/component/material_container/M = C
if(!M.last_insert_success)
return
- var/lit = M.last_inserted_type
- var/stack_name
- if(ispath(lit, /obj/item/ore/bluespace_crystal))
- stack_name = "bluespace"
- else
- var/obj/item/stack/S = lit
- stack_name = material2name(initial(S.materials)[1])
+ var/stack_name = material2name(M.last_inserted_id)
add_overlay("fab-load-[stack_name]")
addtimer(CALLBACK(src, /atom/proc/cut_overlay, "fab-load-[stack_name]"), 10)
updateUsrDialog()
diff --git a/code/game/mecha/mecha_control_console.dm b/code/game/mecha/mecha_control_console.dm
index 6f1348c741..431768500e 100644
--- a/code/game/mecha/mecha_control_console.dm
+++ b/code/game/mecha/mecha_control_console.dm
@@ -1,137 +1,137 @@
-/obj/machinery/computer/mecha
- name = "exosuit control console"
- desc = "Used to remotely locate or lockdown exosuits."
- icon_screen = "mecha"
- icon_keyboard = "tech_key"
+/obj/machinery/computer/mecha
+ name = "exosuit control console"
+ desc = "Used to remotely locate or lockdown exosuits."
+ icon_screen = "mecha"
+ icon_keyboard = "tech_key"
req_access = list(ACCESS_ROBOTICS)
- circuit = /obj/item/circuitboard/computer/mecha_control
- var/list/located = list()
- var/screen = 0
- var/stored_data
-
-/obj/machinery/computer/mecha/attack_hand(mob/user)
- if(..())
- return
- user.set_machine(src)
- var/dat = "[src.name] "
- if(screen == 0)
- dat += "Tracking beacons data "
- var/list/trackerlist = list()
- for(var/obj/mecha/MC in GLOB.mechas_list)
- trackerlist += MC.trackers
- for(var/obj/item/mecha_parts/mecha_tracking/TR in trackerlist)
- var/answer = TR.get_mecha_info()
- if(answer)
- dat += {" [answer]
- Send message
- Show exosuit log | (EMP pulse) "}
-
- if(screen==1)
- dat += "Log contents "
- dat += "Return "
- dat += "[stored_data]"
-
- dat += "(Refresh) "
- dat += ""
-
- user << browse(dat, "window=computer;size=400x500")
- onclose(user, "computer")
- return
-
-/obj/machinery/computer/mecha/Topic(href, href_list)
- if(..())
- return
- var/datum/topic_input/filter = new /datum/topic_input(href,href_list)
- if(href_list["send_message"])
- var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("send_message")
- var/message = stripped_input(usr,"Input message","Transmit message")
- var/obj/mecha/M = MT.in_mecha()
- if(trim(message) && M)
- M.occupant_message(message)
- return
- if(href_list["shock"])
- var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("shock")
- MT.shock()
- if(href_list["get_log"])
- var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("get_log")
- stored_data = MT.get_mecha_log()
- screen = 1
- if(href_list["return"])
- screen = 0
- updateUsrDialog()
- return
-
-/obj/item/mecha_parts/mecha_tracking
- name = "exosuit tracking beacon"
- desc = "Device used to transmit exosuit data."
- icon = 'icons/obj/device.dmi'
- icon_state = "motion2"
- w_class = WEIGHT_CLASS_SMALL
- origin_tech = "programming=2;magnets=2"
- var/ai_beacon = FALSE //If this beacon allows for AI control. Exists to avoid using istype() on checking.
-
-/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_info()
- if(!in_mecha())
- return 0
- var/obj/mecha/M = src.loc
- var/cell_charge = M.get_charge()
- var/answer = {"Name: [M.name]
-Integrity: [M.obj_integrity/M.max_integrity*100]%
-Cell charge: [isnull(cell_charge)?"Not found":"[M.cell.percent()]%"]
-Airtank: [M.return_pressure()]kPa
-Pilot: [M.occupant||"None"]
-Location: [get_area(M)||"Unknown"]
-Active equipment: [M.selected||"None"] "}
- if(istype(M, /obj/mecha/working/ripley))
- var/obj/mecha/working/ripley/RM = M
- answer += "Used cargo space: [RM.cargo.len/RM.cargo_capacity*100]% "
-
- return answer
-
-/obj/item/mecha_parts/mecha_tracking/emp_act()
- qdel(src)
-
-/obj/item/mecha_parts/mecha_tracking/Destroy()
- if(istype(loc, /obj/mecha))
- var/obj/mecha/M = loc
- if(src in M.trackers)
- M.trackers -= src
- return ..()
-
-/obj/item/mecha_parts/mecha_tracking/proc/in_mecha()
- if(istype(src.loc, /obj/mecha))
- return src.loc
- return 0
-
-/obj/item/mecha_parts/mecha_tracking/proc/shock()
- var/obj/mecha/M = in_mecha()
- if(M)
+ circuit = /obj/item/circuitboard/computer/mecha_control
+ var/list/located = list()
+ var/screen = 0
+ var/stored_data
+
+/obj/machinery/computer/mecha/attack_hand(mob/user)
+ if(..())
+ return
+ user.set_machine(src)
+ var/dat = "[src.name] "
+ if(screen == 0)
+ dat += "Tracking beacons data "
+ var/list/trackerlist = list()
+ for(var/obj/mecha/MC in GLOB.mechas_list)
+ trackerlist += MC.trackers
+ for(var/obj/item/mecha_parts/mecha_tracking/TR in trackerlist)
+ var/answer = TR.get_mecha_info()
+ if(answer)
+ dat += {" [answer]
+ Send message
+ Show exosuit log | (EMP pulse) "}
+
+ if(screen==1)
+ dat += "Log contents "
+ dat += "Return "
+ dat += "[stored_data]"
+
+ dat += "(Refresh) "
+ dat += ""
+
+ user << browse(dat, "window=computer;size=400x500")
+ onclose(user, "computer")
+ return
+
+/obj/machinery/computer/mecha/Topic(href, href_list)
+ if(..())
+ return
+ var/datum/topic_input/filter = new /datum/topic_input(href,href_list)
+ if(href_list["send_message"])
+ var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("send_message")
+ var/message = stripped_input(usr,"Input message","Transmit message")
+ var/obj/mecha/M = MT.in_mecha()
+ if(trim(message) && M)
+ M.occupant_message(message)
+ return
+ if(href_list["shock"])
+ var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("shock")
+ MT.shock()
+ if(href_list["get_log"])
+ var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("get_log")
+ stored_data = MT.get_mecha_log()
+ screen = 1
+ if(href_list["return"])
+ screen = 0
+ updateUsrDialog()
+ return
+
+/obj/item/mecha_parts/mecha_tracking
+ name = "exosuit tracking beacon"
+ desc = "Device used to transmit exosuit data."
+ icon = 'icons/obj/device.dmi'
+ icon_state = "motion2"
+ w_class = WEIGHT_CLASS_SMALL
+ origin_tech = "programming=2;magnets=2"
+ var/ai_beacon = FALSE //If this beacon allows for AI control. Exists to avoid using istype() on checking.
+
+/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_info()
+ if(!in_mecha())
+ return 0
+ var/obj/mecha/M = src.loc
+ var/cell_charge = M.get_charge()
+ var/answer = {"Name: [M.name]
+Integrity: [M.obj_integrity/M.max_integrity*100]%
+Cell charge: [isnull(cell_charge)?"Not found":"[M.cell.percent()]%"]
+Airtank: [M.return_pressure()]kPa
+Pilot: [M.occupant||"None"]
+Location: [get_area(M)||"Unknown"]
+Active equipment: [M.selected||"None"] "}
+ if(istype(M, /obj/mecha/working/ripley))
+ var/obj/mecha/working/ripley/RM = M
+ answer += "Used cargo space: [RM.cargo.len/RM.cargo_capacity*100]% "
+
+ return answer
+
+/obj/item/mecha_parts/mecha_tracking/emp_act()
+ qdel(src)
+
+/obj/item/mecha_parts/mecha_tracking/Destroy()
+ if(ismecha(loc))
+ var/obj/mecha/M = loc
+ if(src in M.trackers)
+ M.trackers -= src
+ return ..()
+
+/obj/item/mecha_parts/mecha_tracking/proc/in_mecha()
+ if(ismecha(loc))
+ return loc
+ return 0
+
+/obj/item/mecha_parts/mecha_tracking/proc/shock()
+ var/obj/mecha/M = in_mecha()
+ if(M)
M.emp_act(EMP_LIGHT)
- qdel(src)
-
-/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_log()
- if(!istype(loc, /obj/mecha))
- return 0
- var/obj/mecha/M = src.loc
- return M.get_log_html()
-
-
-/obj/item/mecha_parts/mecha_tracking/ai_control
- name = "exosuit AI control beacon"
- desc = "A device used to transmit exosuit data. Also allows active AI units to take control of said exosuit."
- origin_tech = "programming=3;magnets=2;engineering=2"
- ai_beacon = TRUE
-
-
-/obj/item/storage/box/mechabeacons
- name = "exosuit tracking beacons"
-
-/obj/item/storage/box/mechabeacons/New()
- ..()
- new /obj/item/mecha_parts/mecha_tracking(src)
- new /obj/item/mecha_parts/mecha_tracking(src)
- new /obj/item/mecha_parts/mecha_tracking(src)
- new /obj/item/mecha_parts/mecha_tracking(src)
- new /obj/item/mecha_parts/mecha_tracking(src)
- new /obj/item/mecha_parts/mecha_tracking(src)
- new /obj/item/mecha_parts/mecha_tracking(src)
+ qdel(src)
+
+/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_log()
+ if(!ismecha(loc))
+ return 0
+ var/obj/mecha/M = src.loc
+ return M.get_log_html()
+
+
+/obj/item/mecha_parts/mecha_tracking/ai_control
+ name = "exosuit AI control beacon"
+ desc = "A device used to transmit exosuit data. Also allows active AI units to take control of said exosuit."
+ origin_tech = "programming=3;magnets=2;engineering=2"
+ ai_beacon = TRUE
+
+
+/obj/item/storage/box/mechabeacons
+ name = "exosuit tracking beacons"
+
+/obj/item/storage/box/mechabeacons/New()
+ ..()
+ new /obj/item/mecha_parts/mecha_tracking(src)
+ new /obj/item/mecha_parts/mecha_tracking(src)
+ new /obj/item/mecha_parts/mecha_tracking(src)
+ new /obj/item/mecha_parts/mecha_tracking(src)
+ new /obj/item/mecha_parts/mecha_tracking(src)
+ new /obj/item/mecha_parts/mecha_tracking(src)
+ new /obj/item/mecha_parts/mecha_tracking(src)
diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm
index 97d00c339f..8bf0580e15 100644
--- a/code/game/objects/effects/portals.dm
+++ b/code/game/objects/effects/portals.dm
@@ -1,156 +1,154 @@
-
-/proc/create_portal_pair(turf/source, turf/destination, _creator = null, _lifespan = 300, accuracy = 0, newtype = /obj/effect/portal)
- if(!istype(source) || !istype(destination))
- return
- var/turf/actual_destination = get_teleport_turf(destination, accuracy)
- var/obj/effect/portal/P1 = new newtype(source, _creator, _lifespan, null, FALSE)
- var/obj/effect/portal/P2 = new newtype(actual_destination, _creator, _lifespan, P1, TRUE)
- if(!istype(P1)||!istype(P2))
- return
- P1.link_portal(P2)
- P1.hardlinked = TRUE
- return list(P1, P2)
-
-/obj/effect/portal
- name = "portal"
- desc = "Looks unstable. Best to test it with the clown."
- icon = 'icons/obj/stationobjs.dmi'
- icon_state = "portal"
- anchored = TRUE
- var/mech_sized = FALSE
- var/obj/effect/portal/linked
- var/hardlinked = TRUE //Requires a linked portal at all times. Destroy if there's no linked portal, if there is destroy it when this one is deleted.
- var/creator
- var/turf/hard_target //For when a portal needs a hard target and isn't to be linked.
- var/atmos_link = FALSE //Link source/destination atmos.
- var/turf/open/atmos_source //Atmos link source
- var/turf/open/atmos_destination //Atmos link destination
-
-/obj/effect/portal/anom
- name = "wormhole"
- icon = 'icons/obj/objects.dmi'
- icon_state = "anom"
- mech_sized = TRUE
-
-/obj/effect/portal/Move(newloc)
- for(var/T in newloc)
- if(istype(T, /obj/effect/portal))
- return FALSE
- return ..()
-
-/obj/effect/portal/attackby(obj/item/W, mob/user, params)
- if(user && Adjacent(user))
- teleport(user)
-
-/obj/effect/portal/Crossed(atom/movable/AM, oldloc)
- if(get_turf(oldloc) == get_turf(linked))
- return ..()
- if(!teleport(AM))
- return ..()
-
-/obj/effect/portal/attack_tk(mob/user)
- return
-
-/obj/effect/portal/attack_hand(mob/user)
- if(Adjacent(user))
- teleport(user)
-
-/obj/effect/portal/Initialize(mapload, _creator, _lifespan = 0, obj/effect/portal/_linked, automatic_link = FALSE, turf/hard_target_override, atmos_link_override)
- . = ..()
- GLOB.portals += src
- if(!istype(_linked) && automatic_link)
- . = INITIALIZE_HINT_QDEL
- CRASH("Somebody fucked up.")
- if(_lifespan > 0)
- QDEL_IN(src, _lifespan)
- if(!isnull(atmos_link_override))
- atmos_link = atmos_link_override
- link_portal(_linked)
- hardlinked = automatic_link
- creator = _creator
- if(isturf(hard_target_override))
- hard_target = hard_target_override
-
-/obj/effect/portal/proc/link_portal(obj/effect/portal/newlink)
- linked = newlink
- if(atmos_link)
- link_atmos()
-
-/obj/effect/portal/proc/link_atmos()
- if(atmos_source || atmos_destination)
- unlink_atmos()
- if(!isopenturf(get_turf(src)))
- return FALSE
- if(linked)
- if(isopenturf(get_turf(linked)))
- atmos_source = get_turf(src)
- atmos_destination = get_turf(linked)
- else if(hard_target)
- if(isopenturf(hard_target))
- atmos_source = get_turf(src)
- atmos_destination = hard_target
- else
- return FALSE
- if(!istype(atmos_source) || !istype(atmos_destination))
- return FALSE
- LAZYINITLIST(atmos_source.atmos_adjacent_turfs)
- LAZYINITLIST(atmos_destination.atmos_adjacent_turfs)
- if(atmos_source.atmos_adjacent_turfs[atmos_destination] || atmos_destination.atmos_adjacent_turfs[atmos_source]) //Already linked!
- return FALSE
- atmos_source.atmos_adjacent_turfs[atmos_destination] = TRUE
- atmos_destination.atmos_adjacent_turfs[atmos_source] = TRUE
- atmos_source.air_update_turf(FALSE)
- atmos_destination.air_update_turf(FALSE)
-
-/obj/effect/portal/proc/unlink_atmos()
- if(istype(atmos_source))
- if(istype(atmos_destination) && !atmos_source.Adjacent(atmos_destination) && !CANATMOSPASS(atmos_destination, atmos_source))
- LAZYREMOVE(atmos_source.atmos_adjacent_turfs, atmos_destination)
- atmos_source = null
- if(istype(atmos_destination))
- if(istype(atmos_source) && !atmos_destination.Adjacent(atmos_source) && !CANATMOSPASS(atmos_source, atmos_destination))
- LAZYREMOVE(atmos_destination.atmos_adjacent_turfs, atmos_source)
- atmos_destination = null
-
-/obj/effect/portal/Destroy() //Calls on_portal_destroy(destroyed portal, location of destroyed portal) on creator if creator has such call.
- if(creator && hascall(creator, "on_portal_destroy"))
- call(creator, "on_portal_destroy")(src, src.loc)
- creator = null
- GLOB.portals -= src
- unlink_atmos()
- if(hardlinked && !QDELETED(linked))
- QDEL_NULL(linked)
- else
- linked = null
- return ..()
-
-/obj/effect/portal/proc/teleport(atom/movable/M)
- if(!istype(M) || istype(M, /obj/effect) || (istype(M, /obj/mecha) && !mech_sized) || (!isobj(M) && !ismob(M))) //Things that shouldn't teleport.
- return
- var/turf/real_target = get_link_target_turf()
- if(!istype(real_target))
- return FALSE
- if(ismegafauna(M))
- message_admins("[M] has used a portal at [ADMIN_COORDJMP(src)] made by [usr].")
- if(do_teleport(M, real_target, 0))
- if(istype(M, /obj/item/projectile))
- var/obj/item/projectile/P = M
- P.ignore_source_check = TRUE
- return TRUE
- return FALSE
-
-/obj/effect/portal/proc/get_link_target_turf()
- var/turf/real_target
- if(!istype(linked) || QDELETED(linked))
- if(hardlinked)
- qdel(src)
- if(!istype(hard_target) || QDELETED(hard_target))
- hard_target = null
- return
- else
- real_target = hard_target
- linked = null
- else
- real_target = get_turf(linked)
- return real_target
-
+/proc/create_portal_pair(turf/source, turf/destination, _creator = null, _lifespan = 300, accuracy = 0, newtype = /obj/effect/portal)
+ if(!istype(source) || !istype(destination))
+ return
+ var/turf/actual_destination = get_teleport_turf(destination, accuracy)
+ var/obj/effect/portal/P1 = new newtype(source, _creator, _lifespan, null, FALSE)
+ var/obj/effect/portal/P2 = new newtype(actual_destination, _creator, _lifespan, P1, TRUE)
+ if(!istype(P1)||!istype(P2))
+ return
+ P1.link_portal(P2)
+ P1.hardlinked = TRUE
+ return list(P1, P2)
+
+/obj/effect/portal
+ name = "portal"
+ desc = "Looks unstable. Best to test it with the clown."
+ icon = 'icons/obj/stationobjs.dmi'
+ icon_state = "portal"
+ anchored = TRUE
+ var/mech_sized = FALSE
+ var/obj/effect/portal/linked
+ var/hardlinked = TRUE //Requires a linked portal at all times. Destroy if there's no linked portal, if there is destroy it when this one is deleted.
+ var/creator
+ var/turf/hard_target //For when a portal needs a hard target and isn't to be linked.
+ var/atmos_link = FALSE //Link source/destination atmos.
+ var/turf/open/atmos_source //Atmos link source
+ var/turf/open/atmos_destination //Atmos link destination
+
+/obj/effect/portal/anom
+ name = "wormhole"
+ icon = 'icons/obj/objects.dmi'
+ icon_state = "anom"
+ mech_sized = TRUE
+
+/obj/effect/portal/Move(newloc)
+ for(var/T in newloc)
+ if(istype(T, /obj/effect/portal))
+ return FALSE
+ return ..()
+
+/obj/effect/portal/attackby(obj/item/W, mob/user, params)
+ if(user && Adjacent(user))
+ user.forceMove(get_turf(src))
+
+/obj/effect/portal/Crossed(atom/movable/AM, oldloc)
+ if(linked && (get_turf(oldloc) == get_turf(linked)))
+ return ..()
+ if(!teleport(AM))
+ return ..()
+
+/obj/effect/portal/attack_tk(mob/user)
+ return
+
+/obj/effect/portal/attack_hand(mob/user)
+ if(Adjacent(user))
+ user.forceMove(get_turf(src))
+
+/obj/effect/portal/Initialize(mapload, _creator, _lifespan = 0, obj/effect/portal/_linked, automatic_link = FALSE, turf/hard_target_override, atmos_link_override)
+ . = ..()
+ GLOB.portals += src
+ if(!istype(_linked) && automatic_link)
+ . = INITIALIZE_HINT_QDEL
+ CRASH("Somebody fucked up.")
+ if(_lifespan > 0)
+ QDEL_IN(src, _lifespan)
+ if(!isnull(atmos_link_override))
+ atmos_link = atmos_link_override
+ link_portal(_linked)
+ hardlinked = automatic_link
+ creator = _creator
+ if(isturf(hard_target_override))
+ hard_target = hard_target_override
+
+/obj/effect/portal/proc/link_portal(obj/effect/portal/newlink)
+ linked = newlink
+ if(atmos_link)
+ link_atmos()
+
+/obj/effect/portal/proc/link_atmos()
+ if(atmos_source || atmos_destination)
+ unlink_atmos()
+ if(!isopenturf(get_turf(src)))
+ return FALSE
+ if(linked)
+ if(isopenturf(get_turf(linked)))
+ atmos_source = get_turf(src)
+ atmos_destination = get_turf(linked)
+ else if(hard_target)
+ if(isopenturf(hard_target))
+ atmos_source = get_turf(src)
+ atmos_destination = hard_target
+ else
+ return FALSE
+ if(!istype(atmos_source) || !istype(atmos_destination))
+ return FALSE
+ LAZYINITLIST(atmos_source.atmos_adjacent_turfs)
+ LAZYINITLIST(atmos_destination.atmos_adjacent_turfs)
+ if(atmos_source.atmos_adjacent_turfs[atmos_destination] || atmos_destination.atmos_adjacent_turfs[atmos_source]) //Already linked!
+ return FALSE
+ atmos_source.atmos_adjacent_turfs[atmos_destination] = TRUE
+ atmos_destination.atmos_adjacent_turfs[atmos_source] = TRUE
+ atmos_source.air_update_turf(FALSE)
+ atmos_destination.air_update_turf(FALSE)
+
+/obj/effect/portal/proc/unlink_atmos()
+ if(istype(atmos_source))
+ if(istype(atmos_destination) && !atmos_source.Adjacent(atmos_destination) && !CANATMOSPASS(atmos_destination, atmos_source))
+ LAZYREMOVE(atmos_source.atmos_adjacent_turfs, atmos_destination)
+ atmos_source = null
+ if(istype(atmos_destination))
+ if(istype(atmos_source) && !atmos_destination.Adjacent(atmos_source) && !CANATMOSPASS(atmos_source, atmos_destination))
+ LAZYREMOVE(atmos_destination.atmos_adjacent_turfs, atmos_source)
+ atmos_destination = null
+
+/obj/effect/portal/Destroy() //Calls on_portal_destroy(destroyed portal, location of destroyed portal) on creator if creator has such call.
+ if(creator && hascall(creator, "on_portal_destroy"))
+ call(creator, "on_portal_destroy")(src, src.loc)
+ creator = null
+ GLOB.portals -= src
+ unlink_atmos()
+ if(hardlinked && !QDELETED(linked))
+ QDEL_NULL(linked)
+ else
+ linked = null
+ return ..()
+
+/obj/effect/portal/proc/teleport(atom/movable/M)
+ if(!istype(M) || istype(M, /obj/effect) || (ismecha(M) && !mech_sized) || (!isobj(M) && !ismob(M))) //Things that shouldn't teleport.
+ return
+ var/turf/real_target = get_link_target_turf()
+ if(!istype(real_target))
+ return FALSE
+ if(ismegafauna(M))
+ message_admins("[M] has used a portal at [ADMIN_COORDJMP(src)] made by [usr].")
+ if(do_teleport(M, real_target, 0))
+ if(istype(M, /obj/item/projectile))
+ var/obj/item/projectile/P = M
+ P.ignore_source_check = TRUE
+ return TRUE
+ return FALSE
+
+/obj/effect/portal/proc/get_link_target_turf()
+ var/turf/real_target
+ if(!istype(linked) || QDELETED(linked))
+ if(hardlinked)
+ qdel(src)
+ if(!istype(hard_target) || QDELETED(hard_target))
+ hard_target = null
+ return
+ else
+ real_target = hard_target
+ linked = null
+ else
+ real_target = get_turf(linked)
+ return real_target
diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm
index 8b2d95f373..dfc5fb94d5 100644
--- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm
+++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm
@@ -213,7 +213,7 @@
/obj/effect/temp_visual/fire
icon = 'icons/effects/fire.dmi'
icon_state = "3"
- light_range = 3
+ light_range = LIGHT_RANGE_FIRE
light_color = LIGHT_COLOR_FIRE
duration = 10
diff --git a/code/game/objects/items/AI_modules.dm b/code/game/objects/items/AI_modules.dm
index fd7a87ac8c..45788b77b9 100644
--- a/code/game/objects/items/AI_modules.dm
+++ b/code/game/objects/items/AI_modules.dm
@@ -54,7 +54,7 @@ AI MODULES
for(var/mylaw in lawlist)
if(mylaw != "")
tot_laws++
- if(tot_laws > config.silicon_max_law_amount && !bypass_law_amt_check)//allows certain boards to avoid this check, eg: reset
+ if(tot_laws > CONFIG_GET(number/silicon_max_law_amount) && !bypass_law_amt_check)//allows certain boards to avoid this check, eg: reset
to_chat(user, "Not enough memory allocated to [law_datum.owner ? law_datum.owner : "the AI core"]'s law processor to handle this amount of laws. ")
message_admins("[key_name_admin(user)] tried to upload laws to [law_datum.owner ? key_name_admin(law_datum.owner) : "an AI core"] that would exceed the law cap.")
overflow = TRUE
diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm
index ca5fa2c28b..23905200e9 100644
--- a/code/game/objects/items/crayons.dm
+++ b/code/game/objects/items/crayons.dm
@@ -72,16 +72,15 @@
user.visible_message("[user] is jamming [src] up [user.p_their()] nose and into [user.p_their()] brain. It looks like [user.p_theyre()] trying to commit suicide! ")
return (BRUTELOSS|OXYLOSS)
-/obj/item/toy/crayon/New()
- ..()
+/obj/item/toy/crayon/Initialize()
+ . = ..()
// Makes crayons identifiable in things like grinders
if(name == "crayon")
name = "[item_color] crayon"
- if(config)
- if(config.mutant_races == 1)
- graffiti |= "antilizard"
- graffiti |= "prolizard"
+ if(CONFIG_GET(flag/join_with_mutant_race))
+ graffiti |= "antilizard"
+ graffiti |= "prolizard"
all_drawables = graffiti + letters + numerals + oriented + runes + graffiti_large_h
drawtype = pick(all_drawables)
diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm
index 8b27659ada..513ffb8d2b 100644
--- a/code/game/objects/items/devices/radio/electropack.dm
+++ b/code/game/objects/items/devices/radio/electropack.dm
@@ -143,4 +143,82 @@ Code:
"}
user << browse(dat, "window=radio")
onclose(user, "radio")
- return
\ No newline at end of file
+ return
+
+/obj/item/device/electropack/shockcollar
+ name = "shock collar"
+ desc = "A reinforced metal collar. It seems to have some form of wiring near the front. Strange.."
+ icon = 'icons/obj/clothing/neck.dmi'
+ icon_state = "shockcollar"
+ item_state = "shockcollar"
+ body_parts_covered = NECK
+ slot_flags = SLOT_NECK
+ w_class = WEIGHT_CLASS_SMALL
+ strip_delay = 60
+ equip_delay_other = 60
+ materials = list(MAT_METAL=5000, MAT_GLASS=2000)
+ var/tagname = null
+
+/obj/item/device/electropack/shockcollar/attack_hand(mob/user)
+ if(loc == user)
+ if(slot_flags == SLOT_NECK)
+ to_chat(user, "The collar is fastened tight! You'll need help taking this off! ")
+ return
+ ..()
+
+/obj/item/device/electropack/shockcollar/receive_signal(datum/signal/signal)
+ if(!signal || signal.encryption != code)
+ return
+
+ if(isliving(loc) && on)
+ if(shock_cooldown != 0)
+ return
+ shock_cooldown = 1
+ spawn(100)
+ shock_cooldown = 0
+ var/mob/living/L = loc
+ step(L, pick(GLOB.cardinals))
+
+ to_chat(L, "You feel a sharp shock from the collar! ")
+ var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
+ s.set_up(3, 1, L)
+ s.start()
+
+ L.Knockdown(100)
+
+ if(master)
+ master.receive_signal()
+ return
+
+/obj/item/device/electropack/shockcollar/attack_self(mob/user) //Turns out can't fully source this from the parent item, spritepath gets confused if power toggled. Will come back to this when I know how to code better and readd powertoggle..
+ var/option = "Change Name"
+ option = input(user, "What do you want to do?", "[src]", option) as null|anything in list("Change Name", "Change Frequency")
+ switch(option)
+ if("Change Name")
+ var/t = input(user, "Would you like to change the name on the tag?", "Name your new pet", tagname ? tagname : "Spot") as null|text
+ if(t)
+ tagname = copytext(sanitize(t), 1, MAX_NAME_LEN)
+ name = "[initial(name)] - [tagname]"
+ if("Change Frequency")
+ if(!ishuman(user))
+ return
+ user.set_machine(src)
+ var/dat = {"
+ Frequency/Code for shock collar:
+ Frequency:
+ -
+ - [format_frequency(frequency)]
+ +
+ +
+
+ Code:
+ -
+ - [code]
+ +
+ +
+ "}
+
+ user << browse(dat, "window=radio")
+ onclose(user, "radio")
+ return
+
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index 0f59d00ab8..83d29457f6 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -4,6 +4,7 @@
suffix = "\[3\]"
icon_state = "walkietalkie"
item_state = "walkietalkie"
+ desc = "A basic handheld radio that communicates with local telecommunication networks."
dog_fashion = /datum/dog_fashion/back
var/on = TRUE // 0 for off
var/last_transmission
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index e9a622365a..e55c728121 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -73,6 +73,7 @@ MASS SPECTROMETER
origin_tech = "magnets=1;biotech=1"
var/mode = 1
var/scanmode = 0
+ var/advanced = FALSE
/obj/item/device/healthanalyzer/attack_self(mob/user)
if(!scanmode)
@@ -97,7 +98,7 @@ MASS SPECTROMETER
user.visible_message("[user] has analyzed [M]'s vitals. ")
if(scanmode == 0)
- healthscan(user, M, mode)
+ healthscan(user, M, mode, advanced)
else if(scanmode == 1)
chemscan(user, M)
@@ -105,7 +106,7 @@ MASS SPECTROMETER
// Used by the PDA medical scanner too
-/proc/healthscan(mob/living/user, mob/living/M, mode = 1)
+/proc/healthscan(mob/living/user, mob/living/M, mode = 1, advanced = FALSE)
if(user.incapacitated() || user.eye_blind)
return
//Damage specifics
@@ -115,8 +116,8 @@ MASS SPECTROMETER
var/brute_loss = M.getBruteLoss()
var/mob_status = (M.stat == DEAD ? "Deceased " : "[round(M.health/M.maxHealth,0.01)*100] % healthy ")
- if(M.status_flags & FAKEDEATH)
- mob_status = "Deceased "
+ if(M.status_flags & FAKEDEATH && !advanced)
+ mob_status = "Deceased "
oxy_loss = max(rand(1, 40), oxy_loss, (300 - (tox_loss + fire_loss + brute_loss))) // Random oxygen loss
if(ishuman(M))
@@ -141,19 +142,77 @@ MASS SPECTROMETER
if(oxy_loss > 10)
to_chat(user, "\t[oxy_loss > 50 ? "Severe" : "Minor"] oxygen deprivation detected. ")
if(tox_loss > 10)
- to_chat(user, "\t[tox_loss > 50 ? "Critical" : "Dangerous"] amount of toxins detected. ")
+ to_chat(user, "\t[tox_loss > 50 ? "Severe" : "Minor"] amount of toxin damage detected. ")
if(M.getStaminaLoss())
to_chat(user, "\tSubject appears to be suffering from fatigue. ")
+ if(advanced)
+ to_chat(user, "\tFatigue Level: [M.getStaminaLoss()]%. ")
if (M.getCloneLoss())
to_chat(user, "\tSubject appears to have [M.getCloneLoss() > 30 ? "severe" : "minor"] cellular damage. ")
- if (M.reagents && M.reagents.get_reagent_amount("epinephrine"))
- to_chat(user, "\tBloodstream analysis located [M.reagents.get_reagent_amount("epinephrine")] units of rejuvenation chemicals. ")
+ if(advanced)
+ to_chat(user, "\tCellular Damage Level: [M.getCloneLoss()]. ")
if (M.getBrainLoss() >= 100 || !M.getorgan(/obj/item/organ/brain))
to_chat(user, "\tSubject brain function is non-existent. ")
else if (M.getBrainLoss() >= 60)
to_chat(user, "\tSevere brain damage detected. Subject likely to have mental retardation. ")
else if (M.getBrainLoss() >= 10)
to_chat(user, "\tBrain damage detected. Subject may have had a concussion. ")
+ if(advanced)
+ to_chat(user, "\tBrain Activity Level: [100 - M.getBrainLoss()]%. ")
+ if (M.radiation)
+ to_chat(user, "\tSubject is irradiated. ")
+ if(advanced)
+ to_chat(user, "\tRadiation Level: [M.radiation]%. ")
+
+ if(advanced && M.hallucinating())
+ to_chat(user, "\tSubject is hallucinating. ")
+
+ //Eyes and ears
+ if(advanced)
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ var/obj/item/organ/ears/ears = C.getorganslot("ears")
+ to_chat(user, "\t==EAR STATUS== ")
+ if(istype(ears))
+ var/healthy = TRUE
+ if(C.disabilities & DEAF)
+ healthy = FALSE
+ to_chat(user, "\tSubject is genetically deaf. ")
+ else
+ if(ears.ear_damage)
+ to_chat(user, "\tSubject has [ears.ear_damage > UNHEALING_EAR_DAMAGE? "permanent ": "temporary "]hearing damage. ")
+ healthy = FALSE
+ if(ears.deaf)
+ to_chat(user, "\tSubject is [ears.ear_damage > UNHEALING_EAR_DAMAGE ? "permanently ": "temporarily "] deaf. ")
+ healthy = FALSE
+ if(healthy)
+ to_chat(user, "\tHealthy. ")
+ else
+ to_chat(user, "\tSubject does not have ears. ")
+ var/obj/item/organ/eyes/eyes = C.getorganslot("eye_sight")
+ to_chat(user, "\t==EYE STATUS== ")
+ if(istype(eyes))
+ var/healthy = TRUE
+ if(C.disabilities & BLIND)
+ to_chat(user, "\tSubject is blind. ")
+ healthy = FALSE
+ if(C.disabilities & NEARSIGHT)
+ to_chat(user, "\tSubject is nearsighted. ")
+ healthy = FALSE
+ if(eyes.eye_damage > 30)
+ to_chat(user, "\tSubject has severe eye damage. ")
+ healthy = FALSE
+ else if(eyes.eye_damage > 20)
+ to_chat(user, "\tSubject has significant eye damage. ")
+ healthy = FALSE
+ else if(eyes.eye_damage)
+ to_chat(user, "\tSubject has minor eye damage. ")
+ healthy = FALSE
+ if(healthy)
+ to_chat(user, "\tHealthy. ")
+ else
+ to_chat(user, "\tSubject does not have eyes. ")
+
if(ishuman(M))
var/mob/living/carbon/human/H = M
@@ -177,7 +236,7 @@ MASS SPECTROMETER
to_chat(user, "Body temperature: [round(M.bodytemperature-T0C,0.1)] °C ([round(M.bodytemperature*1.8-459.67,0.1)] °F) ")
// Time of death
- if(M.tod && (M.stat == DEAD || (M.status_flags & FAKEDEATH)))
+ if(M.tod && (M.stat == DEAD || ((M.status_flags & FAKEDEATH) && !advanced)))
to_chat(user, "Time of Death: [M.tod]")
var/tdelta = round(world.time - M.timeofdeath)
if(tdelta < (DEFIB_TIME_LIMIT * 10))
@@ -251,6 +310,12 @@ MASS SPECTROMETER
if(0)
to_chat(usr, "The scanner no longer shows limb damage.")
+/obj/item/device/healthanalyzer/advanced
+ name = "advanced health analyzer"
+ icon_state = "health_adv"
+ desc = "A hand-held body scanner able to distinguish vital signs of the subject with high accuracy."
+ origin_tech = "magnets=3;biotech=3"
+ advanced = TRUE
/obj/item/device/analyzer
desc = "A hand-held environmental scanner which reports current gas levels."
diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm
index 1badef90cf..634fbee9d2 100644
--- a/code/game/objects/items/holy_weapons.dm
+++ b/code/game/objects/items/holy_weapons.dm
@@ -335,8 +335,8 @@
/obj/item/nullrod/carp
name = "carp-sie plushie"
desc = "An adorable stuffed toy that resembles the god of all carp. The teeth look pretty sharp. Activate it to receive the blessing of Carp-Sie."
- icon = 'icons/obj/toy.dmi'
- icon_state = "carpplushie"
+ icon = 'icons/obj/plushes.dmi'
+ icon_state = "carpplush"
item_state = "carp_plushie"
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
diff --git a/code/game/objects/items/implants/implant_loyality.dm b/code/game/objects/items/implants/implant_loyality.dm
index a1e9a0e4d5..ffaebf5a63 100644
--- a/code/game/objects/items/implants/implant_loyality.dm
+++ b/code/game/objects/items/implants/implant_loyality.dm
@@ -19,12 +19,12 @@
/obj/item/implant/mindshield/implant(mob/living/target, mob/user, silent = 0)
if(..())
- if((target.mind in (SSticker.mode.head_revolutionaries)))
+ if((target.mind in (SSticker.mode.head_revolutionaries)) || target.mind.unconvertable)
if(!silent)
target.visible_message("[target] seems to resist the implant! ", "You feel something interfering with your mental conditioning, but you resist it! ")
removed(target, 1)
qdel(src)
- return 0
+ return FALSE
if(target.mind in SSticker.mode.revolutionaries)
SSticker.mode.remove_revolutionary(target.mind, FALSE, user)
if(!silent)
@@ -32,8 +32,8 @@
to_chat(target, "You feel something interfering with your mental conditioning, but you resist it! ")
else
to_chat(target, "You feel a sense of peace and security. You are now protected from brainwashing. ")
- return 1
- return 0
+ return TRUE
+ return FALSE
/obj/item/implant/mindshield/removed(mob/target, silent = 0, special = 0)
if(..())
diff --git a/code/game/objects/items/manuals.dm b/code/game/objects/items/manuals.dm
index 7ee1f49a48..c0298d8122 100644
--- a/code/game/objects/items/manuals.dm
+++ b/code/game/objects/items/manuals.dm
@@ -882,7 +882,8 @@
..()
/obj/item/book/manual/wiki/proc/initialize_wikibook()
- if(config.wikiurl)
+ var/wikiurl = CONFIG_GET(string/wikiurl)
+ if(wikiurl)
dat = {"
@@ -900,7 +901,7 @@
}
You start skimming through the manual...
-
+
diff --git a/code/game/objects/items/shooting_range.dm b/code/game/objects/items/shooting_range.dm
index 28d4d13967..c8249024f8 100644
--- a/code/game/objects/items/shooting_range.dm
+++ b/code/game/objects/items/shooting_range.dm
@@ -41,7 +41,7 @@
/obj/item/target/syndicate
icon_state = "target_s"
- desc = "A shooting target that looks like a syndicate scum."
+ desc = "A shooting target that looks like syndicate scum."
hp = 2600
/obj/item/target/alien
diff --git a/code/game/objects/items/signs.dm b/code/game/objects/items/signs.dm
index c492b752f0..350daa0fc3 100644
--- a/code/game/objects/items/signs.dm
+++ b/code/game/objects/items/signs.dm
@@ -1,7 +1,7 @@
/obj/item/picket_sign
icon_state = "picket"
name = "blank picket sign"
- desc = "It's blank"
+ desc = "It's blank."
force = 5
w_class = WEIGHT_CLASS_BULKY
attack_verb = list("bashed","smacked")
diff --git a/code/game/objects/items/storage/book.dm b/code/game/objects/items/storage/book.dm
index dc6993cdbe..28856e17d8 100644
--- a/code/game/objects/items/storage/book.dm
+++ b/code/game/objects/items/storage/book.dm
@@ -156,6 +156,24 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
var/unholy2clean = A.reagents.get_reagent_amount("unholywater")
A.reagents.del_reagent("unholywater")
A.reagents.add_reagent("holywater",unholy2clean)
+ if(istype(A, /obj/item/twohanded/required/cult_bastard))
+ var/obj/item/twohanded/required/cult_bastard/sword = A
+ to_chat(user, "You begin to exorcise [sword]. ")
+ playsound(src,'sound/hallucinations/veryfar_noise.ogg',40,1)
+ if(do_after(user, 40, target = sword))
+ playsound(src,'sound/effects/pray_chaplain.ogg',60,1)
+ for(var/obj/item/device/soulstone/SS in sword.shards)
+ SS.usability = TRUE
+ for(var/mob/living/simple_animal/shade/EX in SS)
+ SSticker.mode.remove_cultist(EX.mind, 1, 0)
+ EX.icon_state = "ghost1"
+ EX.name = "Purified [EX.name]"
+ SS.release_shades(user)
+ qdel(SS)
+ new /obj/item/nullrod/claymore(get_turf(sword))
+ user.visible_message("[user] has purified the [sword]!! ")
+ qdel(sword)
+
/obj/item/storage/book/bible/booze
desc = "To be applied to the head repeatedly."
diff --git a/code/game/objects/items/storage/fancy.dm b/code/game/objects/items/storage/fancy.dm
index b5417e8f8e..435bc64c41 100644
--- a/code/game/objects/items/storage/fancy.dm
+++ b/code/game/objects/items/storage/fancy.dm
@@ -17,6 +17,7 @@
icon = 'icons/obj/food/containers.dmi'
icon_state = "donutbox6"
name = "donut box"
+ desc = "Mmm. Donuts."
resistance_flags = FLAMMABLE
var/icon_type = "donut"
var/spawn_type = null
diff --git a/code/game/objects/items/storage/lockbox.dm b/code/game/objects/items/storage/lockbox.dm
index 385a069c00..50898e72e1 100644
--- a/code/game/objects/items/storage/lockbox.dm
+++ b/code/game/objects/items/storage/lockbox.dm
@@ -177,6 +177,14 @@
for(var/i in 1 to 3)
new /obj/item/clothing/accessory/medal/silver/security(src)
+/obj/item/storage/lockbox/medal/cargo
+ name = "cargo award box"
+ desc = "A locked box used to store awards to be given to members of the cargo department."
+ req_access = list(ACCESS_QM)
+
+/obj/item/storage/lockbox/medal/cargo/PopulateContents()
+ new /obj/item/clothing/accessory/medal/ribbon/cargo(src)
+
/obj/item/storage/lockbox/medal/sci
name = "science medal box"
desc = "A locked box used to store medals to be given to members of the science department."
diff --git a/code/game/objects/items/storage/secure.dm b/code/game/objects/items/storage/secure.dm
index ef65f2dac3..4d56b6a8e8 100644
--- a/code/game/objects/items/storage/secure.dm
+++ b/code/game/objects/items/storage/secure.dm
@@ -25,6 +25,7 @@
w_class = WEIGHT_CLASS_NORMAL
max_w_class = WEIGHT_CLASS_SMALL
max_combined_w_class = 14
+ desc = "This shouldn't exist. If it does, create an issue report."
/obj/item/storage/secure/examine(mob/user)
..()
@@ -177,6 +178,7 @@
icon_opened = "safe0"
icon_locking = "safeb"
icon_sparking = "safespark"
+ desc = "Excellent for securing things away from grubby hands."
force = 8
w_class = WEIGHT_CLASS_GIGANTIC
max_w_class = 8
diff --git a/code/game/objects/items/storage/storage.dm b/code/game/objects/items/storage/storage.dm
index 5a2b52184a..9a3769206c 100644
--- a/code/game/objects/items/storage/storage.dm
+++ b/code/game/objects/items/storage/storage.dm
@@ -34,7 +34,7 @@
if(!over_object)
return
- if (istype(usr.loc, /obj/mecha)) // stops inventory actions in a mech
+ if (ismecha(M.loc)) // stops inventory actions in a mech
return
// this must come before the screen objects only block, dunno why it wasn't before
diff --git a/code/game/objects/items/vending_items.dm b/code/game/objects/items/vending_items.dm
index b062c39ee5..e84295f8ed 100644
--- a/code/game/objects/items/vending_items.dm
+++ b/code/game/objects/items/vending_items.dm
@@ -5,6 +5,7 @@
icon = 'icons/obj/vending_restock.dmi'
icon_state = "refill_snack"
item_state = "restock_unit"
+ desc = "A vending machine restock cart."
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
flags_1 = CONDUCT_1
diff --git a/code/game/objects/structures/ai_core.dm b/code/game/objects/structures/ai_core.dm
index 0a7b9eb312..d01cd5a191 100644
--- a/code/game/objects/structures/ai_core.dm
+++ b/code/game/objects/structures/ai_core.dm
@@ -4,6 +4,7 @@
name = "\improper AI core"
icon = 'icons/mob/ai.dmi'
icon_state = "0"
+ desc = "The framework for an artificial intelligence core."
max_integrity = 500
var/state = 0
var/datum/ai_laws/laws = new()
@@ -134,7 +135,7 @@
to_chat(user, "Sticking an inactive [M.name] into the frame would sort of defeat the purpose. ")
return
- if((config) && (!config.allow_ai) || jobban_isbanned(M.brainmob, "AI"))
+ if(!CONFIG_GET(flag/allow_ai) || jobban_isbanned(M.brainmob, "AI"))
to_chat(user, "This [M.name] does not seem to fit! ")
return
diff --git a/code/game/objects/structures/beds_chairs/bed.dm b/code/game/objects/structures/beds_chairs/bed.dm
index 935b62f46a..5c36c5a6ba 100644
--- a/code/game/objects/structures/beds_chairs/bed.dm
+++ b/code/game/objects/structures/beds_chairs/bed.dm
@@ -21,6 +21,10 @@
var/buildstacktype = /obj/item/stack/sheet/metal
var/buildstackamount = 2
+/obj/structure/bed/examine(mob/user)
+ ..()
+ to_chat(user, "It's held together by a couple of bolts . ")
+
/obj/structure/bed/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
if(buildstacktype)
diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm
index 39a075b045..9d6985c620 100644
--- a/code/game/objects/structures/beds_chairs/chair.dm
+++ b/code/game/objects/structures/beds_chairs/chair.dm
@@ -1,6 +1,6 @@
/obj/structure/chair
name = "chair"
- desc = "You sit in this. Either by will or force.\nDrag your sprite to sit in the chair. Alt-click to rotate it clockwise. "
+ desc = "You sit in this. Either by will or force."
icon = 'icons/obj/chairs.dmi'
icon_state = "chair"
anchored = TRUE
@@ -14,6 +14,14 @@
var/item_chair = /obj/item/chair // if null it can't be picked up
layer = OBJ_LAYER
+/obj/structure/chair/examine(mob/user)
+ ..()
+ to_chat(user, "It's held together by a couple of bolts . ")
+ if(!has_buckled_mobs())
+ to_chat(user, "Drag your sprite to sit in it. Alt-click to rotate. ")
+ else
+ to_chat(user, "Alt-click to rotate. ")
+
/obj/structure/chair/Initialize()
. = ..()
if(!anchored) //why would you put these on the shuttle?
@@ -98,7 +106,7 @@
set category = "Object"
set src in oview(1)
- if(config.ghost_interaction)
+ if(CONFIG_GET(flag/ghost_interaction))
spin()
else
if(!usr || !isturf(usr.loc))
@@ -140,7 +148,7 @@
/obj/structure/chair/comfy
name = "comfy chair"
- desc = "It looks comfy.\nAlt-click to rotate it clockwise. "
+ desc = "It looks comfy."
icon_state = "comfychair"
color = rgb(255,255,255)
resistance_flags = FLAMMABLE
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index c7b63be32b..3d77be1bb5 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -76,8 +76,12 @@
/obj/structure/closet/examine(mob/user)
..()
+ if(welded)
+ to_chat(user, "It's welded shut. ")
if(anchored)
- to_chat(user, "It is anchored to the ground.")
+ to_chat(user, "It is bolted to the ground. ")
+ if(opened)
+ to_chat(user, "The parts are welded together. ")
else if(secure && !opened)
to_chat(user, "Alt-click to [locked ? "unlock" : "lock"]. ")
@@ -453,4 +457,4 @@
/obj/structure/closet/return_temperature()
- return
\ No newline at end of file
+ return
diff --git a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm
index a920a53c7f..1bf7daf2e2 100644
--- a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm
+++ b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm
@@ -23,7 +23,7 @@
return
move_delay = 1
if(step(src, direction))
- spawn(config.walk_speed*move_speed_multiplier)
+ spawn(CONFIG_GET(number/walk_delay) * move_speed_multiplier)
move_delay = 0
else
move_delay = 0
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm
index 77723e3e41..4e83a709b9 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm
@@ -1,19 +1,20 @@
-/obj/structure/closet/secure_closet/quartermaster
- name = "\proper quartermaster's locker"
+/obj/structure/closet/secure_closet/quartermaster
+ name = "\proper quartermaster's locker"
req_access = list(ACCESS_QM)
- icon_state = "qm"
-
-/obj/structure/closet/secure_closet/quartermaster/PopulateContents()
- ..()
- new /obj/item/clothing/neck/cloak/qm(src)
- new /obj/item/clothing/under/rank/cargo(src)
- new /obj/item/clothing/shoes/sneakers/brown(src)
- new /obj/item/device/radio/headset/headset_cargo(src)
- new /obj/item/clothing/suit/fire/firefighter(src)
- new /obj/item/clothing/gloves/fingerless(src)
- new /obj/item/device/megaphone/cargo(src)
- new /obj/item/tank/internals/emergency_oxygen(src)
- new /obj/item/clothing/mask/gas(src)
- new /obj/item/clothing/head/soft(src)
- new /obj/item/device/export_scanner(src)
- new /obj/item/door_remote/quartermaster(src)
+ icon_state = "qm"
+
+/obj/structure/closet/secure_closet/quartermaster/PopulateContents()
+ ..()
+ new /obj/item/clothing/neck/cloak/qm(src)
+ new /obj/item/storage/lockbox/medal/cargo/(src)
+ new /obj/item/clothing/under/rank/cargo(src)
+ new /obj/item/clothing/shoes/sneakers/brown(src)
+ new /obj/item/device/radio/headset/headset_cargo(src)
+ new /obj/item/clothing/suit/fire/firefighter(src)
+ new /obj/item/clothing/gloves/fingerless(src)
+ new /obj/item/device/megaphone/cargo(src)
+ new /obj/item/tank/internals/emergency_oxygen(src)
+ new /obj/item/clothing/mask/gas(src)
+ new /obj/item/clothing/head/soft(src)
+ new /obj/item/device/export_scanner(src)
+ new /obj/item/door_remote/quartermaster(src)
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 a2a055f464..ee9ecfc908 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm
@@ -1,93 +1,94 @@
-/obj/structure/closet/secure_closet/medical1
- name = "medicine closet"
- desc = "Filled to the brim with medical junk."
- icon_state = "med"
+/obj/structure/closet/secure_closet/medical1
+ name = "medicine closet"
+ desc = "Filled to the brim with medical junk."
+ icon_state = "med"
req_access = list(ACCESS_MEDICAL)
-
-/obj/structure/closet/secure_closet/medical1/PopulateContents()
- ..()
- new /obj/item/reagent_containers/glass/beaker(src)
- new /obj/item/reagent_containers/glass/beaker(src)
- new /obj/item/reagent_containers/dropper(src)
- new /obj/item/reagent_containers/dropper(src)
- new /obj/item/storage/belt/medical(src)
- new /obj/item/storage/box/syringes(src)
- new /obj/item/reagent_containers/glass/bottle/toxin(src)
- new /obj/item/reagent_containers/glass/bottle/morphine(src)
- new /obj/item/reagent_containers/glass/bottle/morphine(src)
- for(var/i in 1 to 3)
- new /obj/item/reagent_containers/glass/bottle/epinephrine(src)
- for(var/i in 1 to 3)
- new /obj/item/reagent_containers/glass/bottle/charcoal(src)
- new /obj/item/storage/box/rxglasses(src)
-
-/obj/structure/closet/secure_closet/medical2
- name = "anesthetic closet"
- desc = "Used to knock people out."
+
+/obj/structure/closet/secure_closet/medical1/PopulateContents()
+ ..()
+ new /obj/item/reagent_containers/glass/beaker(src)
+ new /obj/item/reagent_containers/glass/beaker(src)
+ new /obj/item/reagent_containers/dropper(src)
+ new /obj/item/reagent_containers/dropper(src)
+ new /obj/item/storage/belt/medical(src)
+ new /obj/item/storage/box/syringes(src)
+ new /obj/item/reagent_containers/glass/bottle/toxin(src)
+ new /obj/item/reagent_containers/glass/bottle/morphine(src)
+ new /obj/item/reagent_containers/glass/bottle/morphine(src)
+ for(var/i in 1 to 3)
+ new /obj/item/reagent_containers/glass/bottle/epinephrine(src)
+ for(var/i in 1 to 3)
+ new /obj/item/reagent_containers/glass/bottle/charcoal(src)
+ new /obj/item/storage/box/rxglasses(src)
+
+/obj/structure/closet/secure_closet/medical2
+ name = "anesthetic closet"
+ desc = "Used to knock people out."
req_access = list(ACCESS_SURGERY)
-
-/obj/structure/closet/secure_closet/medical2/PopulateContents()
- ..()
- for(var/i in 1 to 3)
- new /obj/item/tank/internals/anesthetic(src)
- for(var/i in 1 to 3)
- new /obj/item/clothing/mask/breath/medical(src)
-
-/obj/structure/closet/secure_closet/medical3
- name = "medical doctor's locker"
+
+/obj/structure/closet/secure_closet/medical2/PopulateContents()
+ ..()
+ for(var/i in 1 to 3)
+ new /obj/item/tank/internals/anesthetic(src)
+ for(var/i in 1 to 3)
+ new /obj/item/clothing/mask/breath/medical(src)
+
+/obj/structure/closet/secure_closet/medical3
+ name = "medical doctor's locker"
req_access = list(ACCESS_SURGERY)
- icon_state = "med_secure"
-
-/obj/structure/closet/secure_closet/medical3/PopulateContents()
- ..()
- new /obj/item/device/radio/headset/headset_med(src)
- new /obj/item/defibrillator/loaded(src)
- new /obj/item/clothing/gloves/color/latex/nitrile(src)
- new /obj/item/storage/belt/medical(src)
- new /obj/item/clothing/glasses/hud/health(src)
- return
-
-/obj/structure/closet/secure_closet/CMO
- name = "\proper chief medical officer's locker"
+ icon_state = "med_secure"
+
+/obj/structure/closet/secure_closet/medical3/PopulateContents()
+ ..()
+ new /obj/item/device/radio/headset/headset_med(src)
+ new /obj/item/defibrillator/loaded(src)
+ new /obj/item/clothing/gloves/color/latex/nitrile(src)
+ new /obj/item/storage/belt/medical(src)
+ new /obj/item/clothing/glasses/hud/health(src)
+ return
+
+/obj/structure/closet/secure_closet/CMO
+ name = "\proper chief medical officer's locker"
req_access = list(ACCESS_CMO)
- icon_state = "cmo"
-
-/obj/structure/closet/secure_closet/CMO/PopulateContents()
- ..()
- new /obj/item/clothing/neck/cloak/cmo(src)
- new /obj/item/storage/backpack/duffelbag/med(src)
- new /obj/item/clothing/suit/bio_suit/cmo(src)
- new /obj/item/clothing/head/bio_hood/cmo(src)
- new /obj/item/clothing/suit/toggle/labcoat/cmo(src)
- new /obj/item/clothing/under/rank/chief_medical_officer(src)
- new /obj/item/clothing/shoes/sneakers/brown (src)
- new /obj/item/cartridge/cmo(src)
- new /obj/item/device/radio/headset/heads/cmo(src)
- new /obj/item/device/megaphone/command(src)
- new /obj/item/defibrillator/compact/loaded(src)
- new /obj/item/clothing/gloves/color/latex/nitrile(src)
- new /obj/item/storage/belt/medical(src)
- new /obj/item/device/assembly/flash/handheld(src)
- new /obj/item/reagent_containers/hypospray/CMO(src)
- new /obj/item/device/autosurgeon/cmo(src)
- new /obj/item/door_remote/chief_medical_officer(src)
-
-/obj/structure/closet/secure_closet/animal
- name = "animal control"
+ icon_state = "cmo"
+
+/obj/structure/closet/secure_closet/CMO/PopulateContents()
+ ..()
+ new /obj/item/clothing/neck/cloak/cmo(src)
+ new /obj/item/storage/backpack/duffelbag/med(src)
+ new /obj/item/clothing/suit/bio_suit/cmo(src)
+ new /obj/item/clothing/head/bio_hood/cmo(src)
+ new /obj/item/clothing/suit/toggle/labcoat/cmo(src)
+ new /obj/item/clothing/under/rank/chief_medical_officer(src)
+ new /obj/item/clothing/shoes/sneakers/brown (src)
+ new /obj/item/cartridge/cmo(src)
+ new /obj/item/device/radio/headset/heads/cmo(src)
+ new /obj/item/device/megaphone/command(src)
+ new /obj/item/defibrillator/compact/loaded(src)
+ new /obj/item/clothing/gloves/color/latex/nitrile(src)
+ new /obj/item/storage/belt/medical(src)
+ new /obj/item/device/healthanalyzer/advanced(src)
+ new /obj/item/device/assembly/flash/handheld(src)
+ new /obj/item/reagent_containers/hypospray/CMO(src)
+ new /obj/item/device/autosurgeon/cmo(src)
+ new /obj/item/door_remote/chief_medical_officer(src)
+
+/obj/structure/closet/secure_closet/animal
+ name = "animal control"
req_access = list(ACCESS_SURGERY)
-
-/obj/structure/closet/secure_closet/animal/PopulateContents()
- ..()
- new /obj/item/device/assembly/signaler(src)
- for(var/i in 1 to 3)
- new /obj/item/device/electropack(src)
-
-/obj/structure/closet/secure_closet/chemical
- name = "chemical closet"
- desc = "Store dangerous chemicals in here."
- icon_door = "chemical"
-
-/obj/structure/closet/secure_closet/chemical/PopulateContents()
- ..()
- new /obj/item/storage/box/pillbottles(src)
- new /obj/item/storage/box/pillbottles(src)
+
+/obj/structure/closet/secure_closet/animal/PopulateContents()
+ ..()
+ new /obj/item/device/assembly/signaler(src)
+ for(var/i in 1 to 3)
+ new /obj/item/device/electropack(src)
+
+/obj/structure/closet/secure_closet/chemical
+ name = "chemical closet"
+ desc = "Store dangerous chemicals in here."
+ icon_door = "chemical"
+
+/obj/structure/closet/secure_closet/chemical/PopulateContents()
+ ..()
+ new /obj/item/storage/box/pillbottles(src)
+ new /obj/item/storage/box/pillbottles(src)
diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm
index 1183618d5a..a5173a5f80 100644
--- a/code/game/objects/structures/door_assembly.dm
+++ b/code/game/objects/structures/door_assembly.dm
@@ -6,6 +6,7 @@
anchored = FALSE
density = TRUE
max_integrity = 200
+ desc = "The mechanical framework for an airlock."
var/state = 0
var/mineral = null
var/typetext = ""
@@ -363,6 +364,23 @@
anchored = TRUE
state = 1
+/obj/structure/door_assembly/examine(mob/user)
+ ..()
+ switch(state)
+ if(0)
+ if(anchored)
+ to_chat(user, "The anchoring bolts are wrenched in place, but the maintenance panel lacks wiring . ")
+ else
+ to_chat(user, "The assembly is welded together , but the anchoring bolts are unwrenched . ")
+ if(1)
+ to_chat(user, "The maintenance panel is wired , but the circuit slot is empty . ")
+ if(2)
+ to_chat(user, "The circuit is connected loosely to its slot, but the maintenance panel is unscrewed and open . ")
+ if(!mineral || !material)
+ to_chat(user, "There is a small paper placard on the assembly. There are empty slots for glass windows or mineral covers. ")
+ else
+ to_chat(user, "There is a small paper placard on the assembly. ")
+
/obj/structure/door_assembly/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/pen))
var/t = stripped_input(user, "Enter the name for the door.", src.name, src.created_name,MAX_NAME_LEN)
diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm
index 5d6e6f3d77..b81aa7d4d8 100644
--- a/code/game/objects/structures/false_walls.dm
+++ b/code/game/objects/structures/false_walls.dm
@@ -123,9 +123,12 @@
else
return ..()
-/obj/structure/falsewall/proc/dismantle(mob/user, disassembled = TRUE)
- user.visible_message("[user] dismantles the false wall. ", "You dismantle the false wall. ")
- playsound(src, 'sound/items/welder.ogg', 100, 1)
+/obj/structure/falsewall/proc/dismantle(mob/user, disassembled=TRUE, obj/item/tool = null)
+ user.visible_message("[user] dismantles the false wall.", "You dismantle the false wall. ")
+ if(tool)
+ playsound(src, tool.usesound, 100, 1)
+ else
+ playsound(src, 'sound/items/welder.ogg', 100, 1)
deconstruct(disassembled)
/obj/structure/falsewall/deconstruct(disassembled = TRUE)
@@ -141,6 +144,7 @@
return null
/obj/structure/falsewall/examine_status(mob/user) //So you can't detect falsewalls by examine.
+ to_chat(user, "The outer plating is welded firmly in place. ")
return null
/*
@@ -155,6 +159,15 @@
walltype = /turf/closed/wall/r_wall
mineral = /obj/item/stack/sheet/plasteel
+/obj/structure/falsewall/reinforced/examine_status(mob/user)
+ to_chat(user, "The outer grille is fully intact. ")
+ return null
+
+/obj/structure/falsewall/reinforced/attackby(obj/item/tool, mob/user)
+ ..()
+ if(istype(tool, /obj/item/wirecutters))
+ dismantle(user, TRUE, tool)
+
/*
* Uranium Falsewalls
*/
diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm
index 6aa338f047..c1b6c56bf5 100644
--- a/code/game/objects/structures/flora.dm
+++ b/code/game/objects/structures/flora.dm
@@ -6,6 +6,7 @@
//trees
/obj/structure/flora/tree
name = "tree"
+ desc = "A large tree."
density = TRUE
pixel_x = -16
layer = FLY_LAYER
@@ -40,6 +41,7 @@
/obj/structure/flora/tree/pine
name = "pine tree"
+ desc = "A coniferous pine tree."
icon = 'icons/obj/flora/pinetrees.dmi'
icon_state = "pine_1"
@@ -49,6 +51,7 @@
/obj/structure/flora/tree/pine/xmas
name = "xmas tree"
+ desc = "A wondrous decorated Christmas tree."
icon_state = "pine_c"
/obj/structure/flora/tree/pine/xmas/Initialize()
@@ -57,10 +60,12 @@
/obj/structure/flora/tree/dead
icon = 'icons/obj/flora/deadtrees.dmi'
+ desc = "A dead tree. How it died, you know not."
icon_state = "tree_1"
/obj/structure/flora/tree/palm
icon = 'icons/misc/beach2.dmi'
+ desc = "A tree straight from the tropics."
icon_state = "palm1"
/obj/structure/flora/tree/palm/Initialize()
@@ -98,6 +103,7 @@
//grass
/obj/structure/flora/grass
name = "grass"
+ desc = "A patch of overgrown grass."
icon = 'icons/obj/flora/snowflora.dmi'
gender = PLURAL //"this is grass" not "this is a grass"
@@ -127,6 +133,7 @@
//bushes
/obj/structure/flora/bush
name = "bush"
+ desc = "Some type of shrub."
icon = 'icons/obj/flora/snowflora.dmi'
icon_state = "snowbush1"
anchored = TRUE
@@ -139,6 +146,7 @@
/obj/structure/flora/ausbushes
name = "bush"
+ desc = "Some kind of plant."
icon = 'icons/obj/flora/ausflora.dmi'
icon_state = "firstbush_1"
@@ -256,6 +264,7 @@
name = "potted plant"
icon = 'icons/obj/flora/plants.dmi'
icon_state = "plant-01"
+ desc = "A little bit of nature contained in a pot."
layer = ABOVE_MOB_LAYER
w_class = WEIGHT_CLASS_HUGE
force = 10
@@ -365,6 +374,7 @@
/obj/structure/flora/junglebush
name = "bush"
+ desc = "A wild plant that is found in jungles."
icon = 'icons/obj/flora/jungleflora.dmi'
icon_state = "busha"
diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm
index 02f6d784df..3d7e9be21a 100644
--- a/code/game/objects/structures/girders.dm
+++ b/code/game/objects/structures/girders.dm
@@ -1,6 +1,7 @@
/obj/structure/girder
name = "girder"
icon_state = "girder"
+ desc = "A large structural assembly made out of metal; It requires a layer of metal before it can be considered a wall."
anchored = TRUE
density = TRUE
layer = BELOW_OBJ_LAYER
diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm
index 914be24cfd..1683ac00e6 100644
--- a/code/game/objects/structures/grille.dm
+++ b/code/game/objects/structures/grille.dm
@@ -1,5 +1,5 @@
/obj/structure/grille
- desc = "A flimsy lattice of metal rods, with screws to secure it to the floor."
+ desc = "A flimsy framework of metal rods."
name = "grille"
icon = 'icons/obj/structures.dmi'
icon_state = "grille"
@@ -17,6 +17,13 @@
var/grille_type = null
var/broken_type = /obj/structure/grille/broken
+/obj/structure/grille/examine(mob/user)
+ ..()
+ if(anchored)
+ to_chat(user, "It's secured in place with screws . The rods look like they could be cut through. ")
+ if(!anchored)
+ to_chat(user, "The anchoring screws are unscrewed . The rods look like they could be cut through. ")
+
/obj/structure/grille/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
switch(the_rcd.mode)
if(RCD_DECONSTRUCT)
diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm
index 225d634a7f..c0dcd866d8 100644
--- a/code/game/objects/structures/lattice.dm
+++ b/code/game/objects/structures/lattice.dm
@@ -16,6 +16,13 @@
smooth = SMOOTH_MORE
// flags_1 = CONDUCT_1
+/obj/structure/lattice/examine(mob/user)
+ ..()
+ deconstruction_hints(user)
+
+/obj/structure/lattice/proc/deconstruction_hints(mob/user)
+ to_chat(user, "The rods look like they could be cut . There's space for more rods or a tile . ")
+
/obj/structure/lattice/Initialize(mapload)
. = ..()
for(var/obj/structure/lattice/LAT in loc)
@@ -26,12 +33,11 @@
return
/obj/structure/lattice/ratvar_act()
- if(IsEven(x + y))
- new /obj/structure/lattice/clockwork(loc)
- else
- new /obj/structure/lattice/clockwork/large(loc)
+ new /obj/structure/lattice/clockwork(loc)
/obj/structure/lattice/attackby(obj/item/C, mob/user, params)
+ if(resistance_flags & INDESTRUCTIBLE)
+ return
if(istype(C, /obj/item/wirecutters))
to_chat(user, "Slicing [name] joints ... ")
deconstruct()
@@ -45,7 +51,6 @@
qdel(src)
/obj/structure/lattice/singularity_pull(S, current_size)
- ..()
if(current_size >= STAGE_FOUR)
deconstruct()
@@ -55,22 +60,22 @@
icon = 'icons/obj/smooth_structures/lattice_clockwork.dmi'
/obj/structure/lattice/clockwork/Initialize(mapload)
+ canSmoothWith += /turf/open/indestructible/clock_spawn_room //list overrides are a terrible thing
. = ..()
ratvar_act()
+ if(z == ZLEVEL_CITYOFCOGS)
+ resistance_flags |= INDESTRUCTIBLE
/obj/structure/lattice/clockwork/ratvar_act()
if(IsOdd(x+y))
- new /obj/structure/lattice/clockwork/large(loc) // deletes old one
-
-/obj/structure/lattice/clockwork/large/Initialize(mapload)
- . = ..()
- icon = 'icons/obj/smooth_structures/lattice_clockwork_large.dmi'
- pixel_x = -9
- pixel_y = -9
-
-/obj/structure/lattice/clockwork/large/ratvar_act()
- if(IsEven(x + y))
- new /obj/structure/lattice/clockwork(loc)
+ icon = 'icons/obj/smooth_structures/lattice_clockwork_large.dmi'
+ pixel_x = -9
+ pixel_y = -9
+ else
+ icon = 'icons/obj/smooth_structures/lattice_clockwork.dmi'
+ pixel_x = 0
+ pixel_y = 0
+ return TRUE
/obj/structure/lattice/catwalk
name = "catwalk"
@@ -81,6 +86,9 @@
smooth = SMOOTH_TRUE
canSmoothWith = null
+/obj/structure/lattice/catwalk/deconstruction_hints(mob/user)
+ to_chat(user, "The supporting rods look like they could be cut . ")
+
/obj/structure/lattice/catwalk/ratvar_act()
new /obj/structure/lattice/catwalk/clockwork(loc)
@@ -99,11 +107,29 @@
/obj/structure/lattice/catwalk/clockwork
name = "clockwork catwalk"
icon = 'icons/obj/smooth_structures/catwalk_clockwork.dmi'
+ canSmoothWith = list(/obj/structure/lattice,
+ /turf/open/floor,
+ /turf/open/indestructible/clock_spawn_room,
+ /turf/closed/wall,
+ /obj/structure/falsewall)
+ smooth = SMOOTH_MORE
/obj/structure/lattice/catwalk/clockwork/Initialize(mapload)
. = ..()
- new /obj/effect/temp_visual/ratvar/floor/catwalk(loc)
- new /obj/effect/temp_visual/ratvar/beam/catwalk(loc)
+ ratvar_act()
+ if(!mapload)
+ new /obj/effect/temp_visual/ratvar/floor/catwalk(loc)
+ new /obj/effect/temp_visual/ratvar/beam/catwalk(loc)
+ if(z == ZLEVEL_CITYOFCOGS)
+ resistance_flags |= INDESTRUCTIBLE
/obj/structure/lattice/catwalk/clockwork/ratvar_act()
- return
+ if(IsOdd(x+y))
+ icon = 'icons/obj/smooth_structures/catwalk_clockwork_large.dmi'
+ pixel_x = -9
+ pixel_y = -9
+ else
+ icon = 'icons/obj/smooth_structures/catwalk_clockwork.dmi'
+ pixel_x = 0
+ pixel_y = 0
+ return TRUE
diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm
index 2e1f0af991..c767dd1c68 100644
--- a/code/game/objects/structures/mineral_doors.dm
+++ b/code/game/objects/structures/mineral_doors.dm
@@ -1,232 +1,232 @@
-//NOT using the existing /obj/machinery/door type, since that has some complications on its own, mainly based on its
-//machineryness
-
-/obj/structure/mineral_door
- name = "metal door"
+//NOT using the existing /obj/machinery/door type, since that has some complications on its own, mainly based on its
+//machineryness
+
+/obj/structure/mineral_door
+ name = "metal door"
density = TRUE
anchored = TRUE
- opacity = TRUE
-
- icon = 'icons/obj/doors/mineral_doors.dmi'
- icon_state = "metal"
-
- var/initial_state
- var/state = 0 //closed, 1 == open
- var/isSwitchingStates = 0
- var/close_delay = -1 //-1 if does not auto close.
- max_integrity = 200
- armor = list(melee = 10, bullet = 0, laser = 0, energy = 100, bomb = 10, bio = 100, rad = 100, fire = 50, acid = 50)
- var/sheetType = /obj/item/stack/sheet/metal
- var/sheetAmount = 7
- var/openSound = 'sound/effects/stonedoor_openclose.ogg'
- var/closeSound = 'sound/effects/stonedoor_openclose.ogg'
- CanAtmosPass = ATMOS_PASS_DENSITY
-
-/obj/structure/mineral_door/New(location)
- ..()
- initial_state = icon_state
- air_update_turf(1)
-
-/obj/structure/mineral_door/Destroy()
+ opacity = TRUE
+
+ icon = 'icons/obj/doors/mineral_doors.dmi'
+ icon_state = "metal"
+
+ var/initial_state
+ var/state = 0 //closed, 1 == open
+ var/isSwitchingStates = 0
+ var/close_delay = -1 //-1 if does not auto close.
+ max_integrity = 200
+ armor = list(melee = 10, bullet = 0, laser = 0, energy = 100, bomb = 10, bio = 100, rad = 100, fire = 50, acid = 50)
+ var/sheetType = /obj/item/stack/sheet/metal
+ var/sheetAmount = 7
+ var/openSound = 'sound/effects/stonedoor_openclose.ogg'
+ var/closeSound = 'sound/effects/stonedoor_openclose.ogg'
+ CanAtmosPass = ATMOS_PASS_DENSITY
+
+/obj/structure/mineral_door/New(location)
+ ..()
+ initial_state = icon_state
+ air_update_turf(1)
+
+/obj/structure/mineral_door/Destroy()
density = FALSE
- air_update_turf(1)
- return ..()
-
-/obj/structure/mineral_door/Move()
- var/turf/T = loc
- ..()
- move_update_air(T)
-
+ air_update_turf(1)
+ return ..()
+
+/obj/structure/mineral_door/Move()
+ var/turf/T = loc
+ ..()
+ move_update_air(T)
+
/obj/structure/mineral_door/CollidedWith(atom/movable/AM)
- ..()
- if(!state)
+ ..()
+ if(!state)
return TryToSwitchState(AM)
-
-/obj/structure/mineral_door/attack_ai(mob/user) //those aren't machinery, they're just big fucking slabs of a mineral
- if(isAI(user)) //so the AI can't open it
- return
- else if(iscyborg(user)) //but cyborgs can
- if(get_dist(user,src) <= 1) //not remotely though
- return TryToSwitchState(user)
-
-/obj/structure/mineral_door/attack_paw(mob/user)
- return TryToSwitchState(user)
-
-/obj/structure/mineral_door/attack_hand(mob/user)
- return TryToSwitchState(user)
-
+
+/obj/structure/mineral_door/attack_ai(mob/user) //those aren't machinery, they're just big fucking slabs of a mineral
+ if(isAI(user)) //so the AI can't open it
+ return
+ else if(iscyborg(user)) //but cyborgs can
+ if(get_dist(user,src) <= 1) //not remotely though
+ return TryToSwitchState(user)
+
+/obj/structure/mineral_door/attack_paw(mob/user)
+ return TryToSwitchState(user)
+
+/obj/structure/mineral_door/attack_hand(mob/user)
+ return TryToSwitchState(user)
+
/obj/structure/mineral_door/CanPass(atom/movable/mover, turf/target)
- if(istype(mover, /obj/effect/beam))
- return !opacity
- return !density
-
-/obj/structure/mineral_door/proc/TryToSwitchState(atom/user)
- if(isSwitchingStates)
- return
- if(isliving(user))
- var/mob/living/M = user
- if(world.time - M.last_bumped <= 60)
- return //NOTE do we really need that?
- if(M.client)
- if(iscarbon(M))
- var/mob/living/carbon/C = M
- if(!C.handcuffed)
- SwitchState()
- else
- SwitchState()
- else if(istype(user, /obj/mecha))
- SwitchState()
-
-/obj/structure/mineral_door/proc/SwitchState()
- if(state)
- Close()
- else
- Open()
-
-/obj/structure/mineral_door/proc/Open()
- isSwitchingStates = 1
- playsound(src, openSound, 100, 1)
- set_opacity(FALSE)
- flick("[initial_state]opening",src)
- sleep(10)
+ if(istype(mover, /obj/effect/beam))
+ return !opacity
+ return !density
+
+/obj/structure/mineral_door/proc/TryToSwitchState(atom/user)
+ if(isSwitchingStates)
+ return
+ if(isliving(user))
+ var/mob/living/M = user
+ if(world.time - M.last_bumped <= 60)
+ return //NOTE do we really need that?
+ if(M.client)
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ if(!C.handcuffed)
+ SwitchState()
+ else
+ SwitchState()
+ else if(ismecha(user))
+ SwitchState()
+
+/obj/structure/mineral_door/proc/SwitchState()
+ if(state)
+ Close()
+ else
+ Open()
+
+/obj/structure/mineral_door/proc/Open()
+ isSwitchingStates = 1
+ playsound(src, openSound, 100, 1)
+ set_opacity(FALSE)
+ flick("[initial_state]opening",src)
+ sleep(10)
density = FALSE
- state = 1
- air_update_turf(1)
- update_icon()
- isSwitchingStates = 0
-
- if(close_delay != -1)
- addtimer(CALLBACK(src, .proc/Close), close_delay)
-
-/obj/structure/mineral_door/proc/Close()
- if(isSwitchingStates || state != 1)
- return
- var/turf/T = get_turf(src)
- for(var/mob/living/L in T)
- return
- isSwitchingStates = 1
- playsound(loc, closeSound, 100, 1)
- flick("[initial_state]closing",src)
- sleep(10)
+ state = 1
+ air_update_turf(1)
+ update_icon()
+ isSwitchingStates = 0
+
+ if(close_delay != -1)
+ addtimer(CALLBACK(src, .proc/Close), close_delay)
+
+/obj/structure/mineral_door/proc/Close()
+ if(isSwitchingStates || state != 1)
+ return
+ var/turf/T = get_turf(src)
+ for(var/mob/living/L in T)
+ return
+ isSwitchingStates = 1
+ playsound(loc, closeSound, 100, 1)
+ flick("[initial_state]closing",src)
+ sleep(10)
density = TRUE
- set_opacity(TRUE)
- state = 0
- air_update_turf(1)
- update_icon()
- isSwitchingStates = 0
-
-/obj/structure/mineral_door/update_icon()
- if(state)
- icon_state = "[initial_state]open"
- else
- icon_state = initial_state
-
-/obj/structure/mineral_door/attackby(obj/item/W, mob/user, params)
+ set_opacity(TRUE)
+ state = 0
+ air_update_turf(1)
+ update_icon()
+ isSwitchingStates = 0
+
+/obj/structure/mineral_door/update_icon()
+ if(state)
+ icon_state = "[initial_state]open"
+ else
+ icon_state = initial_state
+
+/obj/structure/mineral_door/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/pickaxe))
- var/obj/item/pickaxe/digTool = W
- to_chat(user, "You start digging the [name]... ")
- if(do_after(user,digTool.digspeed*(1+round(max_integrity*0.01)), target = src) && src)
- to_chat(user, "You finish digging. ")
- deconstruct(TRUE)
- else if(user.a_intent != INTENT_HARM)
- attack_hand(user)
- else
- return ..()
-
-/obj/structure/mineral_door/deconstruct(disassembled = TRUE)
- var/turf/T = get_turf(src)
- if(disassembled)
- new sheetType(T, sheetAmount)
- else
- new sheetType(T, max(sheetAmount - 2, 1))
- qdel(src)
-
-/obj/structure/mineral_door/iron
- name = "iron door"
- max_integrity = 300
-
-/obj/structure/mineral_door/silver
- name = "silver door"
- icon_state = "silver"
- sheetType = /obj/item/stack/sheet/mineral/silver
- max_integrity = 300
-
-/obj/structure/mineral_door/gold
- name = "gold door"
- icon_state = "gold"
- sheetType = /obj/item/stack/sheet/mineral/gold
-
-/obj/structure/mineral_door/uranium
- name = "uranium door"
- icon_state = "uranium"
- sheetType = /obj/item/stack/sheet/mineral/uranium
- max_integrity = 300
- light_range = 2
-
-/obj/structure/mineral_door/sandstone
- name = "sandstone door"
- icon_state = "sandstone"
- sheetType = /obj/item/stack/sheet/mineral/sandstone
- max_integrity = 100
-
-/obj/structure/mineral_door/transparent
- opacity = FALSE
-
-/obj/structure/mineral_door/transparent/Close()
- ..()
- set_opacity(FALSE)
-
-/obj/structure/mineral_door/transparent/plasma
- name = "plasma door"
- icon_state = "plasma"
- sheetType = /obj/item/stack/sheet/mineral/plasma
-
-/obj/structure/mineral_door/transparent/plasma/attackby(obj/item/W, mob/user, params)
- if(W.is_hot())
- var/turf/T = get_turf(src)
- message_admins("Plasma mineral door ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_COORDJMP(T)]",0,1)
- log_game("Plasma mineral door ignited by [key_name(user)] in [COORD(T)]")
- TemperatureAct()
- else
- return ..()
-
-/obj/structure/mineral_door/transparent/plasma/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
- if(exposed_temperature > 300)
- TemperatureAct()
-
-/obj/structure/mineral_door/transparent/plasma/proc/TemperatureAct()
- atmos_spawn_air("plasma=500;TEMP=1000")
- deconstruct(FALSE)
-
-/obj/structure/mineral_door/transparent/diamond
- name = "diamond door"
- icon_state = "diamond"
- sheetType = /obj/item/stack/sheet/mineral/diamond
- max_integrity = 1000
-
-/obj/structure/mineral_door/wood
- name = "wood door"
- icon_state = "wood"
- openSound = 'sound/effects/doorcreaky.ogg'
- closeSound = 'sound/effects/doorcreaky.ogg'
- sheetType = /obj/item/stack/sheet/mineral/wood
- resistance_flags = FLAMMABLE
- max_integrity = 200
-
-/obj/structure/mineral_door/paperframe
- name = "paper frame door"
- icon_state = "paperframe"
- openSound = 'sound/effects/doorcreaky.ogg'
- closeSound = 'sound/effects/doorcreaky.ogg'
- sheetType = /obj/item/stack/sheet/paperframes
- sheetAmount = 3
- resistance_flags = FLAMMABLE
- max_integrity = 20
-
-/obj/structure/mineral_door/paperframe/Initialize()
- . = ..()
- queue_smooth_neighbors(src)
-
-/obj/structure/mineral_door/paperframe/Destroy()
- queue_smooth_neighbors(src)
- return ..()
+ var/obj/item/pickaxe/digTool = W
+ to_chat(user, "You start digging the [name]... ")
+ if(do_after(user,digTool.digspeed*(1+round(max_integrity*0.01)), target = src) && src)
+ to_chat(user, "You finish digging. ")
+ deconstruct(TRUE)
+ else if(user.a_intent != INTENT_HARM)
+ attack_hand(user)
+ else
+ return ..()
+
+/obj/structure/mineral_door/deconstruct(disassembled = TRUE)
+ var/turf/T = get_turf(src)
+ if(disassembled)
+ new sheetType(T, sheetAmount)
+ else
+ new sheetType(T, max(sheetAmount - 2, 1))
+ qdel(src)
+
+/obj/structure/mineral_door/iron
+ name = "iron door"
+ max_integrity = 300
+
+/obj/structure/mineral_door/silver
+ name = "silver door"
+ icon_state = "silver"
+ sheetType = /obj/item/stack/sheet/mineral/silver
+ max_integrity = 300
+
+/obj/structure/mineral_door/gold
+ name = "gold door"
+ icon_state = "gold"
+ sheetType = /obj/item/stack/sheet/mineral/gold
+
+/obj/structure/mineral_door/uranium
+ name = "uranium door"
+ icon_state = "uranium"
+ sheetType = /obj/item/stack/sheet/mineral/uranium
+ max_integrity = 300
+ light_range = 2
+
+/obj/structure/mineral_door/sandstone
+ name = "sandstone door"
+ icon_state = "sandstone"
+ sheetType = /obj/item/stack/sheet/mineral/sandstone
+ max_integrity = 100
+
+/obj/structure/mineral_door/transparent
+ opacity = FALSE
+
+/obj/structure/mineral_door/transparent/Close()
+ ..()
+ set_opacity(FALSE)
+
+/obj/structure/mineral_door/transparent/plasma
+ name = "plasma door"
+ icon_state = "plasma"
+ sheetType = /obj/item/stack/sheet/mineral/plasma
+
+/obj/structure/mineral_door/transparent/plasma/attackby(obj/item/W, mob/user, params)
+ if(W.is_hot())
+ var/turf/T = get_turf(src)
+ message_admins("Plasma mineral door ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_COORDJMP(T)]",0,1)
+ log_game("Plasma mineral door ignited by [key_name(user)] in [COORD(T)]")
+ TemperatureAct()
+ else
+ return ..()
+
+/obj/structure/mineral_door/transparent/plasma/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+ if(exposed_temperature > 300)
+ TemperatureAct()
+
+/obj/structure/mineral_door/transparent/plasma/proc/TemperatureAct()
+ atmos_spawn_air("plasma=500;TEMP=1000")
+ deconstruct(FALSE)
+
+/obj/structure/mineral_door/transparent/diamond
+ name = "diamond door"
+ icon_state = "diamond"
+ sheetType = /obj/item/stack/sheet/mineral/diamond
+ max_integrity = 1000
+
+/obj/structure/mineral_door/wood
+ name = "wood door"
+ icon_state = "wood"
+ openSound = 'sound/effects/doorcreaky.ogg'
+ closeSound = 'sound/effects/doorcreaky.ogg'
+ sheetType = /obj/item/stack/sheet/mineral/wood
+ resistance_flags = FLAMMABLE
+ max_integrity = 200
+
+/obj/structure/mineral_door/paperframe
+ name = "paper frame door"
+ icon_state = "paperframe"
+ openSound = 'sound/effects/doorcreaky.ogg'
+ closeSound = 'sound/effects/doorcreaky.ogg'
+ sheetType = /obj/item/stack/sheet/paperframes
+ sheetAmount = 3
+ resistance_flags = FLAMMABLE
+ max_integrity = 20
+
+/obj/structure/mineral_door/paperframe/Initialize()
+ . = ..()
+ queue_smooth_neighbors(src)
+
+/obj/structure/mineral_door/paperframe/Destroy()
+ queue_smooth_neighbors(src)
+ return ..()
diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm
index a32db59bc5..296e4ba757 100644
--- a/code/game/objects/structures/mirror.dm
+++ b/code/game/objects/structures/mirror.dm
@@ -1,225 +1,226 @@
-//wip wip wup
-/obj/structure/mirror
- name = "mirror"
- desc = "Mirror mirror on the wall, who's the most robust of them all?"
- icon = 'icons/obj/watercloset.dmi'
- icon_state = "mirror"
- density = FALSE
- anchored = TRUE
- max_integrity = 200
- integrity_failure = 100
-
-
-/obj/structure/mirror/attack_hand(mob/user)
- if(broken || !Adjacent(user))
- return
-
- if(ishuman(user))
- var/mob/living/carbon/human/H = user
-
- var/userloc = H.loc
-
- //see code/modules/mob/dead/new_player/preferences.dm at approx line 545 for comments!
- //this is largely copypasted from there.
-
- //handle facial hair (if necessary)
- if(H.gender == MALE)
- var/new_style = input(user, "Select a facial hair style", "Grooming") as null|anything in GLOB.facial_hair_styles_list
- if(userloc != H.loc)
- return //no tele-grooming
- if(new_style)
- H.facial_hair_style = new_style
- else
- H.facial_hair_style = "Shaved"
-
- //handle normal hair
- var/new_style = input(user, "Select a hair style", "Grooming") as null|anything in GLOB.hair_styles_list
- if(userloc != H.loc)
- return //no tele-grooming
- if(new_style)
- H.hair_style = new_style
-
- H.update_hair()
-
-/obj/structure/mirror/examine_status(mob/user)
- if(broken)
- return // no message spam
- ..()
-
-/obj/structure/mirror/obj_break(damage_flag)
- if(!broken && !(flags_1 & NODECONSTRUCT_1))
- icon_state = "mirror_broke"
- playsound(src, "shatter", 70, 1)
- desc = "Oh no, seven years of bad luck!"
- broken = 1
-
-/obj/structure/mirror/deconstruct(disassembled = TRUE)
- if(!(flags_1 & NODECONSTRUCT_1))
- if(!disassembled)
- new /obj/item/shard( src.loc )
- qdel(src)
-
-/obj/structure/mirror/attackby(obj/item/I, mob/living/user, params)
- if(istype(I, /obj/item/weldingtool) && user.a_intent != INTENT_HARM)
- var/obj/item/weldingtool/WT = I
- if(broken)
- user.changeNext_move(CLICK_CD_MELEE)
- if(WT.remove_fuel(0, user))
- to_chat(user, "You begin repairing [src]... ")
- playsound(src, 'sound/items/welder.ogg', 100, 1)
- if(do_after(user, 10*I.toolspeed, target = src))
- if(!user || !WT || !WT.isOn())
- return
- to_chat(user, "You repair [src]. ")
- broken = 0
- icon_state = initial(icon_state)
- desc = initial(desc)
- else
- return ..()
-
-/obj/structure/mirror/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
- switch(damage_type)
- if(BRUTE)
- playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
- if(BURN)
- playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
-
-
-/obj/structure/mirror/magic
- name = "magic mirror"
- desc = "Turn and face the strange... face."
- icon_state = "magic_mirror"
- var/list/races_blacklist = list("skeleton", "agent", "angel", "military_synth", "memezombie")
- var/list/choosable_races = list()
-
-/obj/structure/mirror/magic/New()
- if(!choosable_races.len)
- for(var/speciestype in subtypesof(/datum/species))
- var/datum/species/S = new speciestype()
- if(!(S.id in races_blacklist))
- choosable_races += S.id
- ..()
-
-/obj/structure/mirror/magic/lesser/New()
- choosable_races = GLOB.roundstart_species
- ..()
-
-/obj/structure/mirror/magic/badmin/New()
- for(var/speciestype in subtypesof(/datum/species))
- var/datum/species/S = new speciestype()
- choosable_races += S.id
- ..()
-
-/obj/structure/mirror/magic/attack_hand(mob/user)
- if(!ishuman(user))
- return
-
- var/mob/living/carbon/human/H = user
-
- var/choice = input(user, "Something to change?", "Magical Grooming") as null|anything in list("name", "race", "gender", "hair", "eyes")
-
- if(!Adjacent(user))
- return
-
- switch(choice)
- if("name")
- var/newname = copytext(sanitize(input(H, "Who are we again?", "Name change", H.name) as null|text),1,MAX_NAME_LEN)
-
- if(!newname)
- return
- if(!Adjacent(user))
- return
- H.real_name = newname
- H.name = newname
- if(H.dna)
- H.dna.real_name = newname
- if(H.mind)
- H.mind.name = newname
-
- if("race")
- var/newrace
- var/racechoice = input(H, "What are we again?", "Race change") as null|anything in choosable_races
- newrace = GLOB.species_list[racechoice]
-
- if(!newrace)
- return
- if(!Adjacent(user))
- return
- H.set_species(newrace, icon_update=0)
-
- if(H.dna.species.use_skintones)
- var/new_s_tone = input(user, "Choose your skin tone:", "Race change") as null|anything in GLOB.skin_tones
-
- if(new_s_tone)
- H.skin_tone = new_s_tone
- H.dna.update_ui_block(DNA_SKIN_TONE_BLOCK)
-
- if(MUTCOLORS in H.dna.species.species_traits)
- var/new_mutantcolor = input(user, "Choose your skin color:", "Race change") as color|null
- if(new_mutantcolor)
- var/temp_hsv = RGBtoHSV(new_mutantcolor)
-
- if(ReadHSV(temp_hsv)[3] >= ReadHSV("#7F7F7F")[3]) // mutantcolors must be bright
- H.dna.features["mcolor"] = sanitize_hexcolor(new_mutantcolor)
-
- else
- to_chat(H, "Invalid color. Your color is not bright enough. ")
-
- H.update_body()
- H.update_hair()
- H.update_body_parts()
- H.update_mutations_overlay() // no hulk lizard
-
- if("gender")
- if(!(H.gender in list("male", "female"))) //blame the patriarchy
- return
- if(!Adjacent(user))
- return
- if(H.gender == "male")
- if(alert(H, "Become a Witch?", "Confirmation", "Yes", "No") == "Yes")
- H.gender = "female"
- to_chat(H, "Man, you feel like a woman! ")
- else
- return
-
- else
- if(alert(H, "Become a Warlock?", "Confirmation", "Yes", "No") == "Yes")
- H.gender = "male"
- to_chat(H, "Whoa man, you feel like a man! ")
- else
- return
- H.dna.update_ui_block(DNA_GENDER_BLOCK)
- H.update_body()
- H.update_mutations_overlay() //(hulk male/female)
-
- if("hair")
- var/hairchoice = alert(H, "Hair style or hair color?", "Change Hair", "Style", "Color")
- if(!Adjacent(user))
- return
- if(hairchoice == "Style") //So you just want to use a mirror then?
- ..()
- else
- var/new_hair_color = input(H, "Choose your hair color", "Hair Color") as null|color
- if(new_hair_color)
- H.hair_color = sanitize_hexcolor(new_hair_color)
- H.dna.update_ui_block(DNA_HAIR_COLOR_BLOCK)
- if(H.gender == "male")
- var/new_face_color = input(H, "Choose your facial hair color", "Hair Color") as null|color
- if(new_face_color)
- H.facial_hair_color = sanitize_hexcolor(new_face_color)
- H.dna.update_ui_block(DNA_FACIAL_HAIR_COLOR_BLOCK)
- H.update_hair()
-
- if("eyes")
- var/new_eye_color = input(H, "Choose your eye color", "Eye Color") as null|color
- if(!Adjacent(user))
- return
- if(new_eye_color)
- H.eye_color = sanitize_hexcolor(new_eye_color)
- H.dna.update_ui_block(DNA_EYE_COLOR_BLOCK)
- H.update_body()
- if(choice)
- curse(user)
-
-/obj/structure/mirror/magic/proc/curse(mob/living/user)
- return
+//wip wip wup
+/obj/structure/mirror
+ name = "mirror"
+ desc = "Mirror mirror on the wall, who's the most robust of them all?"
+ icon = 'icons/obj/watercloset.dmi'
+ icon_state = "mirror"
+ density = FALSE
+ anchored = TRUE
+ max_integrity = 200
+ integrity_failure = 100
+
+
+/obj/structure/mirror/attack_hand(mob/user)
+ if(broken || !Adjacent(user))
+ return
+
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+
+ var/userloc = H.loc
+
+ //see code/modules/mob/dead/new_player/preferences.dm at approx line 545 for comments!
+ //this is largely copypasted from there.
+
+ //handle facial hair (if necessary)
+ if(H.gender == MALE)
+ var/new_style = input(user, "Select a facial hair style", "Grooming") as null|anything in GLOB.facial_hair_styles_list
+ if(userloc != H.loc)
+ return //no tele-grooming
+ if(new_style)
+ H.facial_hair_style = new_style
+ else
+ H.facial_hair_style = "Shaved"
+
+ //handle normal hair
+ var/new_style = input(user, "Select a hair style", "Grooming") as null|anything in GLOB.hair_styles_list
+ if(userloc != H.loc)
+ return //no tele-grooming
+ if(new_style)
+ H.hair_style = new_style
+
+ H.update_hair()
+
+/obj/structure/mirror/examine_status(mob/user)
+ if(broken)
+ return // no message spam
+ ..()
+
+/obj/structure/mirror/obj_break(damage_flag)
+ if(!broken && !(flags_1 & NODECONSTRUCT_1))
+ icon_state = "mirror_broke"
+ playsound(src, "shatter", 70, 1)
+ desc = "Oh no, seven years of bad luck!"
+ broken = 1
+
+/obj/structure/mirror/deconstruct(disassembled = TRUE)
+ if(!(flags_1 & NODECONSTRUCT_1))
+ if(!disassembled)
+ new /obj/item/shard( src.loc )
+ qdel(src)
+
+/obj/structure/mirror/attackby(obj/item/I, mob/living/user, params)
+ if(istype(I, /obj/item/weldingtool) && user.a_intent != INTENT_HARM)
+ var/obj/item/weldingtool/WT = I
+ if(broken)
+ user.changeNext_move(CLICK_CD_MELEE)
+ if(WT.remove_fuel(0, user))
+ to_chat(user, "You begin repairing [src]... ")
+ playsound(src, 'sound/items/welder.ogg', 100, 1)
+ if(do_after(user, 10*I.toolspeed, target = src))
+ if(!user || !WT || !WT.isOn())
+ return
+ to_chat(user, "You repair [src]. ")
+ broken = 0
+ icon_state = initial(icon_state)
+ desc = initial(desc)
+ else
+ return ..()
+
+/obj/structure/mirror/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
+ switch(damage_type)
+ if(BRUTE)
+ playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
+ if(BURN)
+ playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
+
+
+/obj/structure/mirror/magic
+ name = "magic mirror"
+ desc = "Turn and face the strange... face."
+ icon_state = "magic_mirror"
+ var/list/races_blacklist = list("skeleton", "agent", "angel", "military_synth", "memezombie")
+ var/list/choosable_races = list()
+
+/obj/structure/mirror/magic/New()
+ if(!choosable_races.len)
+ for(var/speciestype in subtypesof(/datum/species))
+ var/datum/species/S = new speciestype()
+ if(!(S.id in races_blacklist))
+ choosable_races += S.id
+ ..()
+
+/obj/structure/mirror/magic/lesser/New()
+ var/list/L = CONFIG_GET(keyed_flag_list/roundstart_races)
+ choosable_races = L.Copy()
+ ..()
+
+/obj/structure/mirror/magic/badmin/New()
+ for(var/speciestype in subtypesof(/datum/species))
+ var/datum/species/S = new speciestype()
+ choosable_races += S.id
+ ..()
+
+/obj/structure/mirror/magic/attack_hand(mob/user)
+ if(!ishuman(user))
+ return
+
+ var/mob/living/carbon/human/H = user
+
+ var/choice = input(user, "Something to change?", "Magical Grooming") as null|anything in list("name", "race", "gender", "hair", "eyes")
+
+ if(!Adjacent(user))
+ return
+
+ switch(choice)
+ if("name")
+ var/newname = copytext(sanitize(input(H, "Who are we again?", "Name change", H.name) as null|text),1,MAX_NAME_LEN)
+
+ if(!newname)
+ return
+ if(!Adjacent(user))
+ return
+ H.real_name = newname
+ H.name = newname
+ if(H.dna)
+ H.dna.real_name = newname
+ if(H.mind)
+ H.mind.name = newname
+
+ if("race")
+ var/newrace
+ var/racechoice = input(H, "What are we again?", "Race change") as null|anything in choosable_races
+ newrace = GLOB.species_list[racechoice]
+
+ if(!newrace)
+ return
+ if(!Adjacent(user))
+ return
+ H.set_species(newrace, icon_update=0)
+
+ if(H.dna.species.use_skintones)
+ var/new_s_tone = input(user, "Choose your skin tone:", "Race change") as null|anything in GLOB.skin_tones
+
+ if(new_s_tone)
+ H.skin_tone = new_s_tone
+ H.dna.update_ui_block(DNA_SKIN_TONE_BLOCK)
+
+ if(MUTCOLORS in H.dna.species.species_traits)
+ var/new_mutantcolor = input(user, "Choose your skin color:", "Race change") as color|null
+ if(new_mutantcolor)
+ var/temp_hsv = RGBtoHSV(new_mutantcolor)
+
+ if(ReadHSV(temp_hsv)[3] >= ReadHSV("#7F7F7F")[3]) // mutantcolors must be bright
+ H.dna.features["mcolor"] = sanitize_hexcolor(new_mutantcolor)
+
+ else
+ to_chat(H, "Invalid color. Your color is not bright enough. ")
+
+ H.update_body()
+ H.update_hair()
+ H.update_body_parts()
+ H.update_mutations_overlay() // no hulk lizard
+
+ if("gender")
+ if(!(H.gender in list("male", "female"))) //blame the patriarchy
+ return
+ if(!Adjacent(user))
+ return
+ if(H.gender == "male")
+ if(alert(H, "Become a Witch?", "Confirmation", "Yes", "No") == "Yes")
+ H.gender = "female"
+ to_chat(H, "Man, you feel like a woman! ")
+ else
+ return
+
+ else
+ if(alert(H, "Become a Warlock?", "Confirmation", "Yes", "No") == "Yes")
+ H.gender = "male"
+ to_chat(H, "Whoa man, you feel like a man! ")
+ else
+ return
+ H.dna.update_ui_block(DNA_GENDER_BLOCK)
+ H.update_body()
+ H.update_mutations_overlay() //(hulk male/female)
+
+ if("hair")
+ var/hairchoice = alert(H, "Hair style or hair color?", "Change Hair", "Style", "Color")
+ if(!Adjacent(user))
+ return
+ if(hairchoice == "Style") //So you just want to use a mirror then?
+ ..()
+ else
+ var/new_hair_color = input(H, "Choose your hair color", "Hair Color") as null|color
+ if(new_hair_color)
+ H.hair_color = sanitize_hexcolor(new_hair_color)
+ H.dna.update_ui_block(DNA_HAIR_COLOR_BLOCK)
+ if(H.gender == "male")
+ var/new_face_color = input(H, "Choose your facial hair color", "Hair Color") as null|color
+ if(new_face_color)
+ H.facial_hair_color = sanitize_hexcolor(new_face_color)
+ H.dna.update_ui_block(DNA_FACIAL_HAIR_COLOR_BLOCK)
+ H.update_hair()
+
+ if("eyes")
+ var/new_eye_color = input(H, "Choose your eye color", "Eye Color") as null|color
+ if(!Adjacent(user))
+ return
+ if(new_eye_color)
+ H.eye_color = sanitize_hexcolor(new_eye_color)
+ H.dna.update_ui_block(DNA_EYE_COLOR_BLOCK)
+ H.update_body()
+ if(choice)
+ curse(user)
+
+/obj/structure/mirror/magic/proc/curse(mob/living/user)
+ return
diff --git a/code/game/objects/structures/plasticflaps.dm b/code/game/objects/structures/plasticflaps.dm
index aa9e8364c4..16e77c1141 100644
--- a/code/game/objects/structures/plasticflaps.dm
+++ b/code/game/objects/structures/plasticflaps.dm
@@ -76,7 +76,7 @@
if(C.move_delay)
return 0
- if(istype(A, /obj/mecha))
+ if(ismecha(A))
return 0
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index 116ced183f..c54661066a 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -34,6 +34,13 @@
smooth = SMOOTH_TRUE
canSmoothWith = list(/obj/structure/table, /obj/structure/table/reinforced)
+/obj/structure/table/examine(mob/user)
+ ..()
+ deconstruction_hints(user)
+
+/obj/structure/table/proc/deconstruction_hints(mob/user)
+ to_chat(user, "The top is screwed on, but the main bolts are also visible. ")
+
/obj/structure/table/Initialize()
. = ..()
for(var/obj/structure/table/T in src.loc)
@@ -285,7 +292,7 @@
*/
/obj/structure/table/reinforced
name = "reinforced table"
- desc = "A reinforced version of the four legged table, much harder to simply deconstruct."
+ desc = "A reinforced version of the four legged table."
icon = 'icons/obj/smooth_structures/reinforced_table.dmi'
icon_state = "r_table"
deconstruction_ready = 0
@@ -295,6 +302,12 @@
integrity_failure = 50
armor = list(melee = 10, bullet = 30, laser = 30, energy = 100, bomb = 20, bio = 0, rad = 0, fire = 80, acid = 70)
+/obj/structure/table/reinforced/deconstruction_hints(mob/user)
+ if(deconstruction_ready)
+ to_chat(user, "The top cover has been welded loose and the main frame's bolts are exposed. ")
+ else
+ to_chat(user, "The top cover is firmly welded on. ")
+
/obj/structure/table/reinforced/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/weldingtool))
var/obj/item/weldingtool/WT = W
@@ -405,6 +418,10 @@
pass_flags = LETPASSTHROW //You can throw objects over this, despite it's density.
max_integrity = 20
+/obj/structure/rack/examine(mob/user)
+ ..()
+ to_chat(user, "It's held together by a couple of bolts . ")
+
/obj/structure/rack/CanPass(atom/movable/mover, turf/target)
if(src.density == 0) //Because broken racks -Agouri |TODO: SPRITE!|
return 1
diff --git a/code/game/objects/structures/transit_tubes/station.dm b/code/game/objects/structures/transit_tubes/station.dm
index ffc62ac127..1c2c0c326e 100644
--- a/code/game/objects/structures/transit_tubes/station.dm
+++ b/code/game/objects/structures/transit_tubes/station.dm
@@ -7,6 +7,7 @@
/obj/structure/transit_tube/station
name = "station tube station"
icon_state = "closed_station0"
+ desc = "The lynchpin of the transit system."
exit_delay = 1
enter_delay = 2
tube_construction = /obj/structure/c_transit_tube/station
diff --git a/code/game/objects/structures/transit_tubes/transit_tube.dm b/code/game/objects/structures/transit_tubes/transit_tube.dm
index 10d883d392..e409eb533b 100644
--- a/code/game/objects/structures/transit_tubes/transit_tube.dm
+++ b/code/game/objects/structures/transit_tubes/transit_tube.dm
@@ -3,6 +3,7 @@
name = "transit tube"
icon = 'icons/obj/atmospherics/pipes/transit_tube.dmi'
icon_state = "straight"
+ desc = "A transit tube for moving things around."
density = TRUE
layer = LOW_ITEM_LAYER
anchored = TRUE
diff --git a/code/game/objects/structures/transit_tubes/transit_tube_construction.dm b/code/game/objects/structures/transit_tubes/transit_tube_construction.dm
index a1f7bcc8de..62e46e49dd 100644
--- a/code/game/objects/structures/transit_tubes/transit_tube_construction.dm
+++ b/code/game/objects/structures/transit_tubes/transit_tube_construction.dm
@@ -1,158 +1,159 @@
-// transit tube construction
-
-// normal transit tubes
-/obj/structure/c_transit_tube
- name = "unattached transit tube"
- icon = 'icons/obj/atmospherics/pipes/transit_tube.dmi'
- icon_state = "straight"
+// transit tube construction
+
+// normal transit tubes
+/obj/structure/c_transit_tube
+ name = "unattached transit tube"
+ icon = 'icons/obj/atmospherics/pipes/transit_tube.dmi'
+ icon_state = "straight"
+ desc = "An unattached segment of transit tube."
density = FALSE
- layer = LOW_ITEM_LAYER //same as the built tube
+ layer = LOW_ITEM_LAYER //same as the built tube
anchored = FALSE
- var/flipped = 0
- var/build_type = /obj/structure/transit_tube
- var/flipped_build_type
- var/base_icon
-
-/obj/structure/c_transit_tube/examine(mob/user)
- ..()
- to_chat(user, "Alt-click to rotate it clockwise. ")
-
-/obj/structure/c_transit_tube/proc/tube_rotate()
- setDir(turn(dir, -90))
-
-/obj/structure/c_transit_tube/proc/tube_flip()
- if(flipped_build_type)
- flipped = !flipped
- var/cur_flip = initial(flipped) ? !flipped : flipped
- if(cur_flip)
- build_type = flipped_build_type
- else
- build_type = initial(build_type)
- icon_state = "[base_icon][flipped]"
- else
- setDir(turn(dir, 180))
-
-// disposals-style flip and rotate verbs
-/obj/structure/c_transit_tube/verb/rotate()
- set name = "Rotate Tube"
- set category = "Object"
- set src in view(1)
-
- if(usr.incapacitated())
- return
-
- tube_rotate()
-
-/obj/structure/c_transit_tube/AltClick(mob/user)
- ..()
- if(user.incapacitated())
- to_chat(user, "You can't do that right now! ")
- return
- if(!in_range(src, user))
- return
- tube_rotate()
-
-/obj/structure/c_transit_tube/verb/flip()
- set name = "Flip"
- set category = "Object"
- set src in view(1)
-
- if(usr.incapacitated())
- return
- tube_flip()
-
-
-/obj/structure/c_transit_tube/attackby(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/wrench))
- to_chat(user, "You start attaching the [name]... ")
- add_fingerprint(user)
- playsound(src.loc, I.usesound, 50, 1)
- if(do_after(user, 40*I.toolspeed, target = src))
- if(QDELETED(src))
- return
- to_chat(user, "You attach the [name]. ")
- var/obj/structure/transit_tube/R = new build_type(loc, dir)
- transfer_fingerprints_to(R)
- qdel(src)
- else
- return ..()
-
-// transit tube station
-/obj/structure/c_transit_tube/station
- name = "unattached through station"
- icon_state = "closed_station0"
- build_type = /obj/structure/transit_tube/station
- flipped_build_type = /obj/structure/transit_tube/station/flipped
- base_icon = "closed_station"
-
-/obj/structure/c_transit_tube/station/flipped
- icon_state = "closed_station1"
- flipped = 1
- build_type = /obj/structure/transit_tube/station/flipped
- flipped_build_type = /obj/structure/transit_tube/station
-
-
-// reverser station, used for the terminus
-/obj/structure/c_transit_tube/station/reverse
- name = "unattached terminus station"
- icon_state = "closed_terminus0"
- build_type = /obj/structure/transit_tube/station/reverse
- flipped_build_type = /obj/structure/transit_tube/station/reverse/flipped
- base_icon = "closed_terminus"
-
-/obj/structure/c_transit_tube/station/reverse/flipped
- icon_state = "closed_terminus1"
- flipped = 1
- build_type = /obj/structure/transit_tube/station/reverse/flipped
- flipped_build_type = /obj/structure/transit_tube/station/reverse
-
-
-/obj/structure/c_transit_tube/crossing
- icon_state = "crossing"
- build_type = /obj/structure/transit_tube/crossing
-
-
-/obj/structure/c_transit_tube/diagonal
- icon_state = "diagonal"
- build_type = /obj/structure/transit_tube/diagonal
-
-/obj/structure/c_transit_tube/diagonal/crossing
- icon_state = "diagonal_crossing"
- build_type = /obj/structure/transit_tube/diagonal/crossing
-
-
-/obj/structure/c_transit_tube/curved
- icon_state = "curved0"
- build_type = /obj/structure/transit_tube/curved
- flipped_build_type = /obj/structure/transit_tube/curved/flipped
- base_icon = "curved"
-
-/obj/structure/c_transit_tube/curved/flipped
- icon_state = "curved1"
- build_type = /obj/structure/transit_tube/curved/flipped
- flipped_build_type = /obj/structure/transit_tube/curved
- flipped = 1
-
-
-/obj/structure/c_transit_tube/junction
- icon_state = "junction0"
- build_type = /obj/structure/transit_tube/junction
- flipped_build_type = /obj/structure/transit_tube/junction/flipped
- base_icon = "junction"
-
-
-/obj/structure/c_transit_tube/junction/flipped
- icon_state = "junction1"
- flipped = 1
- build_type = /obj/structure/transit_tube/junction/flipped
- flipped_build_type = /obj/structure/transit_tube/junction
-
-
-//transit tube pod
-//see station.dm for the logic
-/obj/structure/c_transit_tube_pod
- name = "unattached transit tube pod"
- icon = 'icons/obj/atmospherics/pipes/transit_tube.dmi'
- icon_state = "pod"
+ var/flipped = 0
+ var/build_type = /obj/structure/transit_tube
+ var/flipped_build_type
+ var/base_icon
+
+/obj/structure/c_transit_tube/examine(mob/user)
+ ..()
+ to_chat(user, "Alt-click to rotate it clockwise. ")
+
+/obj/structure/c_transit_tube/proc/tube_rotate()
+ setDir(turn(dir, -90))
+
+/obj/structure/c_transit_tube/proc/tube_flip()
+ if(flipped_build_type)
+ flipped = !flipped
+ var/cur_flip = initial(flipped) ? !flipped : flipped
+ if(cur_flip)
+ build_type = flipped_build_type
+ else
+ build_type = initial(build_type)
+ icon_state = "[base_icon][flipped]"
+ else
+ setDir(turn(dir, 180))
+
+// disposals-style flip and rotate verbs
+/obj/structure/c_transit_tube/verb/rotate()
+ set name = "Rotate Tube"
+ set category = "Object"
+ set src in view(1)
+
+ if(usr.incapacitated())
+ return
+
+ tube_rotate()
+
+/obj/structure/c_transit_tube/AltClick(mob/user)
+ ..()
+ if(user.incapacitated())
+ to_chat(user, "You can't do that right now! ")
+ return
+ if(!in_range(src, user))
+ return
+ tube_rotate()
+
+/obj/structure/c_transit_tube/verb/flip()
+ set name = "Flip"
+ set category = "Object"
+ set src in view(1)
+
+ if(usr.incapacitated())
+ return
+ tube_flip()
+
+
+/obj/structure/c_transit_tube/attackby(obj/item/I, mob/user, params)
+ if(istype(I, /obj/item/wrench))
+ to_chat(user, "You start attaching the [name]... ")
+ add_fingerprint(user)
+ playsound(src.loc, I.usesound, 50, 1)
+ if(do_after(user, 40*I.toolspeed, target = src))
+ if(QDELETED(src))
+ return
+ to_chat(user, "You attach the [name]. ")
+ var/obj/structure/transit_tube/R = new build_type(loc, dir)
+ transfer_fingerprints_to(R)
+ qdel(src)
+ else
+ return ..()
+
+// transit tube station
+/obj/structure/c_transit_tube/station
+ name = "unattached through station"
+ icon_state = "closed_station0"
+ build_type = /obj/structure/transit_tube/station
+ flipped_build_type = /obj/structure/transit_tube/station/flipped
+ base_icon = "closed_station"
+
+/obj/structure/c_transit_tube/station/flipped
+ icon_state = "closed_station1"
+ flipped = 1
+ build_type = /obj/structure/transit_tube/station/flipped
+ flipped_build_type = /obj/structure/transit_tube/station
+
+
+// reverser station, used for the terminus
+/obj/structure/c_transit_tube/station/reverse
+ name = "unattached terminus station"
+ icon_state = "closed_terminus0"
+ build_type = /obj/structure/transit_tube/station/reverse
+ flipped_build_type = /obj/structure/transit_tube/station/reverse/flipped
+ base_icon = "closed_terminus"
+
+/obj/structure/c_transit_tube/station/reverse/flipped
+ icon_state = "closed_terminus1"
+ flipped = 1
+ build_type = /obj/structure/transit_tube/station/reverse/flipped
+ flipped_build_type = /obj/structure/transit_tube/station/reverse
+
+
+/obj/structure/c_transit_tube/crossing
+ icon_state = "crossing"
+ build_type = /obj/structure/transit_tube/crossing
+
+
+/obj/structure/c_transit_tube/diagonal
+ icon_state = "diagonal"
+ build_type = /obj/structure/transit_tube/diagonal
+
+/obj/structure/c_transit_tube/diagonal/crossing
+ icon_state = "diagonal_crossing"
+ build_type = /obj/structure/transit_tube/diagonal/crossing
+
+
+/obj/structure/c_transit_tube/curved
+ icon_state = "curved0"
+ build_type = /obj/structure/transit_tube/curved
+ flipped_build_type = /obj/structure/transit_tube/curved/flipped
+ base_icon = "curved"
+
+/obj/structure/c_transit_tube/curved/flipped
+ icon_state = "curved1"
+ build_type = /obj/structure/transit_tube/curved/flipped
+ flipped_build_type = /obj/structure/transit_tube/curved
+ flipped = 1
+
+
+/obj/structure/c_transit_tube/junction
+ icon_state = "junction0"
+ build_type = /obj/structure/transit_tube/junction
+ flipped_build_type = /obj/structure/transit_tube/junction/flipped
+ base_icon = "junction"
+
+
+/obj/structure/c_transit_tube/junction/flipped
+ icon_state = "junction1"
+ flipped = 1
+ build_type = /obj/structure/transit_tube/junction/flipped
+ flipped_build_type = /obj/structure/transit_tube/junction
+
+
+//transit tube pod
+//see station.dm for the logic
+/obj/structure/c_transit_tube_pod
+ name = "unattached transit tube pod"
+ icon = 'icons/obj/atmospherics/pipes/transit_tube.dmi'
+ icon_state = "pod"
anchored = FALSE
density = FALSE
diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm
index 6503acf6d3..c4a0d48dde 100644
--- a/code/game/objects/structures/windoor_assembly.dm
+++ b/code/game/objects/structures/windoor_assembly.dm
@@ -1,370 +1,371 @@
-/* Windoor (window door) assembly -Nodrak
- * Step 1: Create a windoor out of rglass
- * Step 2: Add r-glass to the assembly to make a secure windoor (Optional)
- * Step 3: Rotate or Flip the assembly to face and open the way you want
- * Step 4: Wrench the assembly in place
- * Step 5: Add cables to the assembly
- * Step 6: Set access for the door.
- * Step 7: Screwdriver the door to complete
- */
-
-
-/obj/structure/windoor_assembly
- icon = 'icons/obj/doors/windoor.dmi'
-
- name = "windoor Assembly"
- icon_state = "l_windoor_assembly01"
+/* Windoor (window door) assembly -Nodrak
+ * Step 1: Create a windoor out of rglass
+ * Step 2: Add r-glass to the assembly to make a secure windoor (Optional)
+ * Step 3: Rotate or Flip the assembly to face and open the way you want
+ * Step 4: Wrench the assembly in place
+ * Step 5: Add cables to the assembly
+ * Step 6: Set access for the door.
+ * Step 7: Screwdriver the door to complete
+ */
+
+
+/obj/structure/windoor_assembly
+ icon = 'icons/obj/doors/windoor.dmi'
+
+ name = "windoor Assembly"
+ icon_state = "l_windoor_assembly01"
+ desc = "A small glass and wire assembly for windoors."
anchored = FALSE
density = FALSE
- dir = NORTH
-
- var/ini_dir
- var/obj/item/electronics/airlock/electronics = null
- var/created_name = null
-
- //Vars to help with the icon's name
- var/facing = "l" //Does the windoor open to the left or right?
+ dir = NORTH
+
+ var/ini_dir
+ var/obj/item/electronics/airlock/electronics = null
+ var/created_name = null
+
+ //Vars to help with the icon's name
+ var/facing = "l" //Does the windoor open to the left or right?
var/secure = FALSE //Whether or not this creates a secure windoor
- var/state = "01" //How far the door assembly has progressed
- CanAtmosPass = ATMOS_PASS_PROC
-
-/obj/structure/windoor_assembly/examine(mob/user)
- ..()
- to_chat(user, "Alt-click to rotate it clockwise. ")
-
-/obj/structure/windoor_assembly/New(loc, set_dir)
- ..()
- if(set_dir)
- dir = set_dir
- ini_dir = dir
- air_update_turf(1)
-
-/obj/structure/windoor_assembly/Destroy()
+ var/state = "01" //How far the door assembly has progressed
+ CanAtmosPass = ATMOS_PASS_PROC
+
+/obj/structure/windoor_assembly/examine(mob/user)
+ ..()
+ to_chat(user, "Alt-click to rotate it clockwise. ")
+
+/obj/structure/windoor_assembly/New(loc, set_dir)
+ ..()
+ if(set_dir)
+ dir = set_dir
+ ini_dir = dir
+ air_update_turf(1)
+
+/obj/structure/windoor_assembly/Destroy()
density = FALSE
- air_update_turf(1)
- return ..()
-
-/obj/structure/windoor_assembly/Move()
- var/turf/T = loc
- ..()
- setDir(ini_dir)
- move_update_air(T)
-
-/obj/structure/windoor_assembly/update_icon()
- icon_state = "[facing]_[secure ? "secure_" : ""]windoor_assembly[state]"
-
+ air_update_turf(1)
+ return ..()
+
+/obj/structure/windoor_assembly/Move()
+ var/turf/T = loc
+ ..()
+ setDir(ini_dir)
+ move_update_air(T)
+
+/obj/structure/windoor_assembly/update_icon()
+ icon_state = "[facing]_[secure ? "secure_" : ""]windoor_assembly[state]"
+
/obj/structure/windoor_assembly/CanPass(atom/movable/mover, turf/target)
- if(istype(mover) && mover.checkpass(PASSGLASS))
- return 1
- if(get_dir(loc, target) == dir) //Make sure looking at appropriate border
- return !density
- if(istype(mover, /obj/structure/window))
- var/obj/structure/window/W = mover
- if(!valid_window_location(loc, W.ini_dir))
- return FALSE
- else if(istype(mover, /obj/structure/windoor_assembly))
- var/obj/structure/windoor_assembly/W = mover
- if(!valid_window_location(loc, W.ini_dir))
- return FALSE
- else if(istype(mover, /obj/machinery/door/window) && !valid_window_location(loc, mover.dir))
- return FALSE
- return 1
-
-/obj/structure/windoor_assembly/CanAtmosPass(turf/T)
- if(get_dir(loc, T) == dir)
- return !density
- else
- return 1
-
-/obj/structure/windoor_assembly/CheckExit(atom/movable/mover as mob|obj, turf/target)
- if(istype(mover) && mover.checkpass(PASSGLASS))
- return 1
- if(get_dir(loc, target) == dir)
- return !density
- else
- return 1
-
-
-/obj/structure/windoor_assembly/attackby(obj/item/W, mob/user, params)
- //I really should have spread this out across more states but thin little windoors are hard to sprite.
- add_fingerprint(user)
- switch(state)
- if("01")
- if(istype(W, /obj/item/weldingtool) && !anchored )
- var/obj/item/weldingtool/WT = W
- if (WT.remove_fuel(0,user))
- user.visible_message("[user] disassembles the windoor assembly.", "You start to disassemble the windoor assembly... ")
- playsound(loc, 'sound/items/welder2.ogg', 50, 1)
-
- if(do_after(user, 40*W.toolspeed, target = src))
- if(!src || !WT.isOn()) return
- to_chat(user, "You disassemble the windoor assembly. ")
- var/obj/item/stack/sheet/rglass/RG = new (get_turf(src), 5)
- RG.add_fingerprint(user)
- if(secure)
- var/obj/item/stack/rods/R = new (get_turf(src), 4)
- R.add_fingerprint(user)
- qdel(src)
- else
- return
-
- //Wrenching an unsecure assembly anchors it in place. Step 4 complete
- if(istype(W, /obj/item/wrench) && !anchored)
- for(var/obj/machinery/door/window/WD in loc)
- if(WD.dir == dir)
- to_chat(user, "There is already a windoor in that location! ")
- return
- playsound(loc, W.usesound, 100, 1)
- user.visible_message("[user] secures the windoor assembly to the floor.", "You start to secure the windoor assembly to the floor... ")
-
- if(do_after(user, 40*W.toolspeed, target = src))
- if(!src || anchored)
- return
- for(var/obj/machinery/door/window/WD in loc)
- if(WD.dir == dir)
- to_chat(user, "There is already a windoor in that location! ")
- return
- to_chat(user, "You secure the windoor assembly. ")
+ if(istype(mover) && mover.checkpass(PASSGLASS))
+ return 1
+ if(get_dir(loc, target) == dir) //Make sure looking at appropriate border
+ return !density
+ if(istype(mover, /obj/structure/window))
+ var/obj/structure/window/W = mover
+ if(!valid_window_location(loc, W.ini_dir))
+ return FALSE
+ else if(istype(mover, /obj/structure/windoor_assembly))
+ var/obj/structure/windoor_assembly/W = mover
+ if(!valid_window_location(loc, W.ini_dir))
+ return FALSE
+ else if(istype(mover, /obj/machinery/door/window) && !valid_window_location(loc, mover.dir))
+ return FALSE
+ return 1
+
+/obj/structure/windoor_assembly/CanAtmosPass(turf/T)
+ if(get_dir(loc, T) == dir)
+ return !density
+ else
+ return 1
+
+/obj/structure/windoor_assembly/CheckExit(atom/movable/mover as mob|obj, turf/target)
+ if(istype(mover) && mover.checkpass(PASSGLASS))
+ return 1
+ if(get_dir(loc, target) == dir)
+ return !density
+ else
+ return 1
+
+
+/obj/structure/windoor_assembly/attackby(obj/item/W, mob/user, params)
+ //I really should have spread this out across more states but thin little windoors are hard to sprite.
+ add_fingerprint(user)
+ switch(state)
+ if("01")
+ if(istype(W, /obj/item/weldingtool) && !anchored )
+ var/obj/item/weldingtool/WT = W
+ if (WT.remove_fuel(0,user))
+ user.visible_message("[user] disassembles the windoor assembly.", "You start to disassemble the windoor assembly... ")
+ playsound(loc, 'sound/items/welder2.ogg', 50, 1)
+
+ if(do_after(user, 40*W.toolspeed, target = src))
+ if(!src || !WT.isOn()) return
+ to_chat(user, "You disassemble the windoor assembly. ")
+ var/obj/item/stack/sheet/rglass/RG = new (get_turf(src), 5)
+ RG.add_fingerprint(user)
+ if(secure)
+ var/obj/item/stack/rods/R = new (get_turf(src), 4)
+ R.add_fingerprint(user)
+ qdel(src)
+ else
+ return
+
+ //Wrenching an unsecure assembly anchors it in place. Step 4 complete
+ if(istype(W, /obj/item/wrench) && !anchored)
+ for(var/obj/machinery/door/window/WD in loc)
+ if(WD.dir == dir)
+ to_chat(user, "There is already a windoor in that location! ")
+ return
+ playsound(loc, W.usesound, 100, 1)
+ user.visible_message("[user] secures the windoor assembly to the floor.", "You start to secure the windoor assembly to the floor... ")
+
+ if(do_after(user, 40*W.toolspeed, target = src))
+ if(!src || anchored)
+ return
+ for(var/obj/machinery/door/window/WD in loc)
+ if(WD.dir == dir)
+ to_chat(user, "There is already a windoor in that location! ")
+ return
+ to_chat(user, "You secure the windoor assembly. ")
anchored = TRUE
- if(secure)
- name = "secure anchored windoor assembly"
- else
- name = "anchored windoor assembly"
-
- //Unwrenching an unsecure assembly un-anchors it. Step 4 undone
- else if(istype(W, /obj/item/wrench) && anchored)
- playsound(loc, W.usesound, 100, 1)
- user.visible_message("[user] unsecures the windoor assembly to the floor.", "You start to unsecure the windoor assembly to the floor... ")
-
- if(do_after(user, 40*W.toolspeed, target = src))
- if(!src || !anchored)
- return
- to_chat(user, "You unsecure the windoor assembly. ")
+ if(secure)
+ name = "secure anchored windoor assembly"
+ else
+ name = "anchored windoor assembly"
+
+ //Unwrenching an unsecure assembly un-anchors it. Step 4 undone
+ else if(istype(W, /obj/item/wrench) && anchored)
+ playsound(loc, W.usesound, 100, 1)
+ user.visible_message("[user] unsecures the windoor assembly to the floor.", "You start to unsecure the windoor assembly to the floor... ")
+
+ if(do_after(user, 40*W.toolspeed, target = src))
+ if(!src || !anchored)
+ return
+ to_chat(user, "You unsecure the windoor assembly. ")
anchored = FALSE
- if(secure)
- name = "secure windoor assembly"
- else
- name = "windoor assembly"
-
- //Adding plasteel makes the assembly a secure windoor assembly. Step 2 (optional) complete.
- else if(istype(W, /obj/item/stack/sheet/plasteel) && !secure)
- var/obj/item/stack/sheet/plasteel/P = W
- if(P.get_amount() < 2)
- to_chat(user, "You need more plasteel to do this! ")
- return
- to_chat(user, "You start to reinforce the windoor with plasteel... ")
-
- if(do_after(user,40, target = src))
- if(!src || secure || P.get_amount() < 2)
- return
-
- P.use(2)
- to_chat(user, "You reinforce the windoor. ")
+ if(secure)
+ name = "secure windoor assembly"
+ else
+ name = "windoor assembly"
+
+ //Adding plasteel makes the assembly a secure windoor assembly. Step 2 (optional) complete.
+ else if(istype(W, /obj/item/stack/sheet/plasteel) && !secure)
+ var/obj/item/stack/sheet/plasteel/P = W
+ if(P.get_amount() < 2)
+ to_chat(user, "You need more plasteel to do this! ")
+ return
+ to_chat(user, "You start to reinforce the windoor with plasteel... ")
+
+ if(do_after(user,40, target = src))
+ if(!src || secure || P.get_amount() < 2)
+ return
+
+ P.use(2)
+ to_chat(user, "You reinforce the windoor. ")
secure = TRUE
- if(anchored)
- name = "secure anchored windoor assembly"
- else
- name = "secure windoor assembly"
-
- //Adding cable to the assembly. Step 5 complete.
- else if(istype(W, /obj/item/stack/cable_coil) && anchored)
- user.visible_message("[user] wires the windoor assembly.", "You start to wire the windoor assembly... ")
-
- if(do_after(user, 40, target = src))
- if(!src || !anchored || src.state != "01")
- return
- var/obj/item/stack/cable_coil/CC = W
- if(!CC.use(1))
- to_chat(user, "You need more cable to do this! ")
- return
- to_chat(user, "You wire the windoor. ")
- state = "02"
- if(secure)
- name = "secure wired windoor assembly"
- else
- name = "wired windoor assembly"
- else
- return ..()
-
- if("02")
-
- //Removing wire from the assembly. Step 5 undone.
- if(istype(W, /obj/item/wirecutters))
- playsound(loc, W.usesound, 100, 1)
- user.visible_message("[user] cuts the wires from the airlock assembly.", "You start to cut the wires from airlock assembly... ")
-
- if(do_after(user, 40*W.toolspeed, target = src))
- if(!src || state != "02")
- return
-
- to_chat(user, "You cut the windoor wires. ")
- new/obj/item/stack/cable_coil(get_turf(user), 1)
- state = "01"
- if(secure)
- name = "secure anchored windoor assembly"
- else
- name = "anchored windoor assembly"
-
- //Adding airlock electronics for access. Step 6 complete.
- else if(istype(W, /obj/item/electronics/airlock))
- if(!user.drop_item())
- return
- playsound(loc, W.usesound, 100, 1)
- user.visible_message("[user] installs the electronics into the airlock assembly.", "You start to install electronics into the airlock assembly... ")
- W.loc = src
-
- if(do_after(user, 40, target = src))
- if(!src || electronics)
- W.loc = src.loc
- return
- to_chat(user, "You install the airlock electronics. ")
- name = "near finished windoor assembly"
- electronics = W
- else
- W.loc = loc
-
- //Screwdriver to remove airlock electronics. Step 6 undone.
- else if(istype(W, /obj/item/screwdriver))
- if(!electronics)
- return
-
- playsound(loc, W.usesound, 100, 1)
- user.visible_message("[user] removes the electronics from the airlock assembly.", "You start to uninstall electronics from the airlock assembly... ")
-
- if(do_after(user, 40*W.toolspeed, target = src))
- if(!src || !electronics)
- return
- to_chat(user, "You remove the airlock electronics. ")
- name = "wired windoor assembly"
- var/obj/item/electronics/airlock/ae
- ae = electronics
- electronics = null
- ae.loc = loc
-
- else if(istype(W, /obj/item/pen))
- var/t = stripped_input(user, "Enter the name for the door.", name, created_name,MAX_NAME_LEN)
- if(!t)
- return
- if(!in_range(src, usr) && loc != usr)
- return
- created_name = t
- return
-
-
-
- //Crowbar to complete the assembly, Step 7 complete.
- else if(istype(W, /obj/item/crowbar))
- if(!electronics)
- to_chat(usr, "The assembly is missing electronics! ")
- return
- usr << browse(null, "window=windoor_access")
- playsound(loc, W.usesound, 100, 1)
- user.visible_message("[user] pries the windoor into the frame.", "You start prying the windoor into the frame... ")
-
- if(do_after(user, 40*W.toolspeed, target = src))
-
- if(loc && electronics)
-
+ if(anchored)
+ name = "secure anchored windoor assembly"
+ else
+ name = "secure windoor assembly"
+
+ //Adding cable to the assembly. Step 5 complete.
+ else if(istype(W, /obj/item/stack/cable_coil) && anchored)
+ user.visible_message("[user] wires the windoor assembly.", "You start to wire the windoor assembly... ")
+
+ if(do_after(user, 40, target = src))
+ if(!src || !anchored || src.state != "01")
+ return
+ var/obj/item/stack/cable_coil/CC = W
+ if(!CC.use(1))
+ to_chat(user, "You need more cable to do this! ")
+ return
+ to_chat(user, "You wire the windoor. ")
+ state = "02"
+ if(secure)
+ name = "secure wired windoor assembly"
+ else
+ name = "wired windoor assembly"
+ else
+ return ..()
+
+ if("02")
+
+ //Removing wire from the assembly. Step 5 undone.
+ if(istype(W, /obj/item/wirecutters))
+ playsound(loc, W.usesound, 100, 1)
+ user.visible_message("[user] cuts the wires from the airlock assembly.", "You start to cut the wires from airlock assembly... ")
+
+ if(do_after(user, 40*W.toolspeed, target = src))
+ if(!src || state != "02")
+ return
+
+ to_chat(user, "You cut the windoor wires. ")
+ new/obj/item/stack/cable_coil(get_turf(user), 1)
+ state = "01"
+ if(secure)
+ name = "secure anchored windoor assembly"
+ else
+ name = "anchored windoor assembly"
+
+ //Adding airlock electronics for access. Step 6 complete.
+ else if(istype(W, /obj/item/electronics/airlock))
+ if(!user.drop_item())
+ return
+ playsound(loc, W.usesound, 100, 1)
+ user.visible_message("[user] installs the electronics into the airlock assembly.", "You start to install electronics into the airlock assembly... ")
+ W.loc = src
+
+ if(do_after(user, 40, target = src))
+ if(!src || electronics)
+ W.loc = src.loc
+ return
+ to_chat(user, "You install the airlock electronics. ")
+ name = "near finished windoor assembly"
+ electronics = W
+ else
+ W.loc = loc
+
+ //Screwdriver to remove airlock electronics. Step 6 undone.
+ else if(istype(W, /obj/item/screwdriver))
+ if(!electronics)
+ return
+
+ playsound(loc, W.usesound, 100, 1)
+ user.visible_message("[user] removes the electronics from the airlock assembly.", "You start to uninstall electronics from the airlock assembly... ")
+
+ if(do_after(user, 40*W.toolspeed, target = src))
+ if(!src || !electronics)
+ return
+ to_chat(user, "You remove the airlock electronics. ")
+ name = "wired windoor assembly"
+ var/obj/item/electronics/airlock/ae
+ ae = electronics
+ electronics = null
+ ae.loc = loc
+
+ else if(istype(W, /obj/item/pen))
+ var/t = stripped_input(user, "Enter the name for the door.", name, created_name,MAX_NAME_LEN)
+ if(!t)
+ return
+ if(!in_range(src, usr) && loc != usr)
+ return
+ created_name = t
+ return
+
+
+
+ //Crowbar to complete the assembly, Step 7 complete.
+ else if(istype(W, /obj/item/crowbar))
+ if(!electronics)
+ to_chat(usr, "The assembly is missing electronics! ")
+ return
+ usr << browse(null, "window=windoor_access")
+ playsound(loc, W.usesound, 100, 1)
+ user.visible_message("[user] pries the windoor into the frame.", "You start prying the windoor into the frame... ")
+
+ if(do_after(user, 40*W.toolspeed, target = src))
+
+ if(loc && electronics)
+
density = TRUE //Shouldn't matter but just incase
- to_chat(user, "You finish the windoor. ")
-
- if(secure)
- var/obj/machinery/door/window/brigdoor/windoor = new /obj/machinery/door/window/brigdoor(loc)
- if(facing == "l")
- windoor.icon_state = "leftsecureopen"
- windoor.base_state = "leftsecure"
- else
- windoor.icon_state = "rightsecureopen"
- windoor.base_state = "rightsecure"
- windoor.setDir(dir)
+ to_chat(user, "You finish the windoor. ")
+
+ if(secure)
+ var/obj/machinery/door/window/brigdoor/windoor = new /obj/machinery/door/window/brigdoor(loc)
+ if(facing == "l")
+ windoor.icon_state = "leftsecureopen"
+ windoor.base_state = "leftsecure"
+ else
+ windoor.icon_state = "rightsecureopen"
+ windoor.base_state = "rightsecure"
+ windoor.setDir(dir)
windoor.density = FALSE
-
- if(electronics.one_access)
- windoor.req_one_access = electronics.accesses
- else
- windoor.req_access = electronics.accesses
- windoor.electronics = electronics
- electronics.loc = windoor
- if(created_name)
- windoor.name = created_name
- qdel(src)
- windoor.close()
-
-
- else
- var/obj/machinery/door/window/windoor = new /obj/machinery/door/window(loc)
- if(facing == "l")
- windoor.icon_state = "leftopen"
- windoor.base_state = "left"
- else
- windoor.icon_state = "rightopen"
- windoor.base_state = "right"
- windoor.setDir(dir)
+
+ if(electronics.one_access)
+ windoor.req_one_access = electronics.accesses
+ else
+ windoor.req_access = electronics.accesses
+ windoor.electronics = electronics
+ electronics.loc = windoor
+ if(created_name)
+ windoor.name = created_name
+ qdel(src)
+ windoor.close()
+
+
+ else
+ var/obj/machinery/door/window/windoor = new /obj/machinery/door/window(loc)
+ if(facing == "l")
+ windoor.icon_state = "leftopen"
+ windoor.base_state = "left"
+ else
+ windoor.icon_state = "rightopen"
+ windoor.base_state = "right"
+ windoor.setDir(dir)
windoor.density = FALSE
-
- windoor.req_access = electronics.accesses
- windoor.electronics = electronics
- electronics.loc = windoor
- if(created_name)
- windoor.name = created_name
- qdel(src)
- windoor.close()
-
-
- else
- return ..()
-
- //Update to reflect changes(if applicable)
- update_icon()
-
-
-//Rotates the windoor assembly clockwise
-/obj/structure/windoor_assembly/verb/revrotate()
- set name = "Rotate Windoor Assembly"
- set category = "Object"
- set src in oview(1)
- if(usr.stat || !usr.canmove || usr.restrained())
- return
- if(anchored)
- to_chat(usr, "[src] cannot be rotated while it is fastened to the floor! ")
- return FALSE
-
- var/target_dir = turn(dir, 270)
-
- if(!valid_window_location(loc, target_dir))
- to_chat(usr, "[src] cannot be rotated in that direction! ")
- return FALSE
-
- setDir(target_dir)
-
- ini_dir = dir
- update_icon()
- return TRUE
-
-/obj/structure/windoor_assembly/AltClick(mob/user)
- ..()
- if(user.incapacitated())
- to_chat(user, "You can't do that right now! ")
- return
- if(!in_range(src, user))
- return
- else
- revrotate()
-
-//Flips the windoor assembly, determines whather the door opens to the left or the right
-/obj/structure/windoor_assembly/verb/flip()
- set name = "Flip Windoor Assembly"
- set category = "Object"
- set src in oview(1)
- if(usr.stat || !usr.canmove || usr.restrained())
- return
-
- if(facing == "l")
- to_chat(usr, "The windoor will now slide to the right. ")
- facing = "r"
- else
- facing = "l"
- to_chat(usr, "The windoor will now slide to the left. ")
-
- update_icon()
- return
+
+ windoor.req_access = electronics.accesses
+ windoor.electronics = electronics
+ electronics.loc = windoor
+ if(created_name)
+ windoor.name = created_name
+ qdel(src)
+ windoor.close()
+
+
+ else
+ return ..()
+
+ //Update to reflect changes(if applicable)
+ update_icon()
+
+
+//Rotates the windoor assembly clockwise
+/obj/structure/windoor_assembly/verb/revrotate()
+ set name = "Rotate Windoor Assembly"
+ set category = "Object"
+ set src in oview(1)
+ if(usr.stat || !usr.canmove || usr.restrained())
+ return
+ if(anchored)
+ to_chat(usr, "[src] cannot be rotated while it is fastened to the floor! ")
+ return FALSE
+
+ var/target_dir = turn(dir, 270)
+
+ if(!valid_window_location(loc, target_dir))
+ to_chat(usr, "[src] cannot be rotated in that direction! ")
+ return FALSE
+
+ setDir(target_dir)
+
+ ini_dir = dir
+ update_icon()
+ return TRUE
+
+/obj/structure/windoor_assembly/AltClick(mob/user)
+ ..()
+ if(user.incapacitated())
+ to_chat(user, "You can't do that right now! ")
+ return
+ if(!in_range(src, user))
+ return
+ else
+ revrotate()
+
+//Flips the windoor assembly, determines whather the door opens to the left or the right
+/obj/structure/windoor_assembly/verb/flip()
+ set name = "Flip Windoor Assembly"
+ set category = "Object"
+ set src in oview(1)
+ if(usr.stat || !usr.canmove || usr.restrained())
+ return
+
+ if(facing == "l")
+ to_chat(usr, "The windoor will now slide to the right. ")
+ facing = "r"
+ else
+ facing = "l"
+ to_chat(usr, "The windoor will now slide to the left. ")
+
+ update_icon()
+ return
diff --git a/code/game/shuttle_engines.dm b/code/game/shuttle_engines.dm
index 4722991309..80329f20a1 100644
--- a/code/game/shuttle_engines.dm
+++ b/code/game/shuttle_engines.dm
@@ -12,6 +12,7 @@
/obj/structure/shuttle/engine
name = "engine"
+ desc = "A bluespace engine used to make shuttles move."
density = TRUE
anchored = TRUE
var/engine_power = 1
@@ -81,18 +82,21 @@
M.alter_engines(mod)
/obj/structure/shuttle/engine/heater
- name = "heater"
+ name = "engine heater"
icon_state = "heater"
+ desc = "Directs energy into compressed particles in order to power engines."
engine_power = 0 // todo make these into 2x1 parts
/obj/structure/shuttle/engine/platform
- name = "platform"
+ name = "engine platform"
icon_state = "platform"
+ desc = "A platform for engine components."
engine_power = 0
/obj/structure/shuttle/engine/propulsion
name = "propulsion engine"
icon_state = "propulsion"
+ desc = "A standard reliable bluespace engine used by many forms of shuttles."
opacity = 1
/obj/structure/shuttle/engine/propulsion/left
@@ -105,6 +109,7 @@
/obj/structure/shuttle/engine/propulsion/burst
name = "burst engine"
+ desc = "An engine that releases a large bluespace burst to propel it."
/obj/structure/shuttle/engine/propulsion/burst/cargo
state = ENGINE_UNWRENCHED
@@ -119,14 +124,16 @@
icon_state = "burst_r"
/obj/structure/shuttle/engine/router
- name = "router"
+ name = "engine router"
icon_state = "router"
+ desc = "Redirects around energized particles in engine structures."
/obj/structure/shuttle/engine/large
name = "engine"
opacity = 1
icon = 'icons/obj/2x2.dmi'
icon_state = "large_engine"
+ desc = "A very large bluespace engine used to propel very large ships."
bound_width = 64
bound_height = 64
appearance_flags = 0
@@ -136,6 +143,7 @@
opacity = 1
icon = 'icons/obj/3x3.dmi'
icon_state = "huge_engine"
+ desc = "An extremely large bluespace engine used to propel extremely large ships."
bound_width = 96
bound_height = 96
- appearance_flags = 0
\ No newline at end of file
+ appearance_flags = 0
diff --git a/code/game/turfs/closed.dm b/code/game/turfs/closed.dm
index 155373d30f..c9eb1a6762 100644
--- a/code/game/turfs/closed.dm
+++ b/code/game/turfs/closed.dm
@@ -155,8 +155,8 @@
icon_state = "wall"
/turf/closed/bullet_act(obj/item/projectile/Proj)
- ..()
- if(!Proj.nodamage && (Proj.damage_type == BRUTE || Proj.damage_type == BURN))
+ . = ..()
+ if((. != -1) && !Proj.nodamage && (Proj.damage_type == BRUTE || Proj.damage_type == BURN))
var/mutable_appearance/bullet_hole = mutable_appearance('icons/effects/effects.dmi', "bullet_hole", BULLET_HOLE_LAYER)
var/random_x = rand(-13, 13)
@@ -165,4 +165,4 @@
var/random_y = rand(-13, 13)
bullet_hole.pixel_y += random_y
- add_overlay(bullet_hole, TRUE)
\ No newline at end of file
+ add_overlay(bullet_hole, TRUE)
diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm
index 02206646d2..97634f7629 100644
--- a/code/game/turfs/simulated/floor.dm
+++ b/code/game/turfs/simulated/floor.dm
@@ -161,10 +161,10 @@
broken = 0
burnt = 0
if(user && !silent)
- to_chat(user, "You remove the broken plating. ")
+ to_chat(user, "You remove the broken plating. ")
else
if(user && !silent)
- to_chat(user, "You remove the floor tile. ")
+ to_chat(user, "You remove the floor tile. ")
if(floor_tile && make_tile)
new floor_tile(src)
return make_plating()
diff --git a/code/game/turfs/simulated/floor/fancy_floor.dm b/code/game/turfs/simulated/floor/fancy_floor.dm
index a24642c735..428c965197 100644
--- a/code/game/turfs/simulated/floor/fancy_floor.dm
+++ b/code/game/turfs/simulated/floor/fancy_floor.dm
@@ -8,10 +8,15 @@
*/
/turf/open/floor/wood
+ desc = "Stylish dark wood."
icon_state = "wood"
floor_tile = /obj/item/stack/tile/wood
broken_states = list("wood-broken", "wood-broken2", "wood-broken3", "wood-broken4", "wood-broken5", "wood-broken6", "wood-broken7")
+/turf/open/floor/wood/examine(mob/user)
+ ..()
+ to_chat(user, "There's a few screws and a small crack visible. ")
+
/turf/open/floor/wood/attackby(obj/item/C, mob/user, params)
if(..())
return
@@ -42,16 +47,16 @@
broken = 0
burnt = 0
if(user && !silent)
- to_chat(user, "You remove the broken planks. ")
+ to_chat(user, "You remove the broken planks. ")
else
if(make_tile)
if(user && !silent)
- to_chat(user, "You unscrew the planks. ")
+ to_chat(user, "You unscrew the planks. ")
if(floor_tile)
new floor_tile(src)
else
if(user && !silent)
- to_chat(user, "You forcefully pry off the planks, destroying them in the process. ")
+ to_chat(user, "You forcefully pry off the planks, destroying them in the process. ")
return make_plating()
/turf/open/floor/wood/cold
@@ -78,7 +83,7 @@
if(istype(C, /obj/item/shovel) && params)
new ore_type(src)
new ore_type(src) //Make some sand if you shovel grass
- user.visible_message("[user] digs up [src]. ", "You [src.turfverb] [src]. ")
+ user.visible_message("[user] digs up [src].", "You [src.turfverb] [src]. ")
playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1)
make_plating()
if(..())
@@ -143,6 +148,10 @@
canSmoothWith = list(/turf/open/floor/carpet)
flags_1 = NONE
+/turf/open/floor/carpet/examine(mob/user)
+ ..()
+ to_chat(user, "There's a small crack on the edge of it. ")
+
/turf/open/floor/carpet/Initialize()
. = ..()
update_icon()
diff --git a/code/game/turfs/simulated/floor/light_floor.dm b/code/game/turfs/simulated/floor/light_floor.dm
index 247382d03c..0dd3673f6a 100644
--- a/code/game/turfs/simulated/floor/light_floor.dm
+++ b/code/game/turfs/simulated/floor/light_floor.dm
@@ -12,6 +12,10 @@
var/can_modify_colour = TRUE
+/turf/open/floor/light/examine(mob/user)
+ ..()
+ to_chat(user, "There's a small crack on the edge of it. ")
+
/turf/open/floor/light/Initialize()
. = ..()
update_icon()
diff --git a/code/game/turfs/simulated/floor/misc_floor.dm b/code/game/turfs/simulated/floor/misc_floor.dm
index 801f34dbff..794b886537 100644
--- a/code/game/turfs/simulated/floor/misc_floor.dm
+++ b/code/game/turfs/simulated/floor/misc_floor.dm
@@ -142,6 +142,7 @@
name = "clockwork floor"
desc = "Tightly-pressed brass tiles. They emit minute vibration."
icon_state = "plating"
+ baseturf = /turf/open/floor/clockwork
var/uses_overlay = TRUE
var/obj/effect/clockwork/overlay/floor/realappearence
@@ -152,18 +153,16 @@
new /obj/effect/temp_visual/ratvar/beam(src)
realappearence = new /obj/effect/clockwork/overlay/floor(src)
realappearence.linked = src
- change_construction_value(1)
/turf/open/floor/clockwork/Destroy()
STOP_PROCESSING(SSobj, src)
- if(uses_overlay)
- change_construction_value(-1)
- if(realappearence)
- qdel(realappearence)
- realappearence = null
+ if(uses_overlay && realappearence)
+ QDEL_NULL(realappearence)
return ..()
/turf/open/floor/clockwork/ReplaceWithLattice()
+ if(baseturf == type)
+ return
..()
for(var/obj/structure/lattice/L in src)
L.ratvar_act()
@@ -197,6 +196,8 @@
L.adjustToxLoss(-3, TRUE, TRUE)
/turf/open/floor/clockwork/attackby(obj/item/I, mob/living/user, params)
+ if(baseturf == type)
+ return
if(istype(I, /obj/item/crowbar))
user.visible_message("[user] begins slowly prying up [src]... ", "You begin painstakingly prying up [src]... ")
playsound(src, I.usesound, 20, 1)
diff --git a/code/game/turfs/simulated/floor/plasteel_floor.dm b/code/game/turfs/simulated/floor/plasteel_floor.dm
index 63c883f88c..b194127de8 100644
--- a/code/game/turfs/simulated/floor/plasteel_floor.dm
+++ b/code/game/turfs/simulated/floor/plasteel_floor.dm
@@ -4,6 +4,10 @@
broken_states = list("damaged1", "damaged2", "damaged3", "damaged4", "damaged5")
burnt_states = list("floorscorched1", "floorscorched2")
+/turf/open/floor/plasteel/examine(mob/user)
+ ..()
+ to_chat(user, "There's a small crack on the edge of it. ")
+
/turf/open/floor/plasteel/update_icon()
if(!..())
return 0
diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm
index 8ad6657784..3e16da8b9f 100644
--- a/code/game/turfs/simulated/floor/plating.dm
+++ b/code/game/turfs/simulated/floor/plating.dm
@@ -12,6 +12,13 @@
icon_state = "plating"
intact = FALSE
+/turf/open/floor/plating/examine(mob/user)
+ ..()
+ if(broken || burnt)
+ to_chat(user, "It looks like the dents could be welded smooth. ")
+ return
+ to_chat(user, "There are few attachment holes for a new tile or reinforcement rods . ")
+
/turf/open/floor/plating/Initialize()
if (!broken_states)
broken_states = list("platingdmg1", "platingdmg2", "platingdmg3")
diff --git a/code/game/turfs/simulated/floor/plating/asteroid.dm b/code/game/turfs/simulated/floor/plating/asteroid.dm
index 2649a3a14d..848a7e8219 100644
--- a/code/game/turfs/simulated/floor/plating/asteroid.dm
+++ b/code/game/turfs/simulated/floor/plating/asteroid.dm
@@ -193,7 +193,7 @@
var/list/L = list(45)
if(IsOdd(dir2angle(dir))) // We're going at an angle and we want thick angled tunnels.
- L += -45
+ L -= 45
// Expand the edges of our tunnel
for(var/edge_angle in L)
diff --git a/code/game/turfs/simulated/floor/reinf_floor.dm b/code/game/turfs/simulated/floor/reinf_floor.dm
index 04c97aa7d5..74354e78c7 100644
--- a/code/game/turfs/simulated/floor/reinf_floor.dm
+++ b/code/game/turfs/simulated/floor/reinf_floor.dm
@@ -1,11 +1,16 @@
/turf/open/floor/engine
name = "reinforced floor"
+ desc = "Extremely sturdy."
icon_state = "engine"
thermal_conductivity = 0.025
heat_capacity = INFINITY
floor_tile = /obj/item/stack/rods
+/turf/open/floor/engine/examine(mob/user)
+ ..()
+ to_chat(user, "The reinforcement rods are wrenched firmly in place. ")
+
/turf/open/floor/engine/airless
initial_gas_mix = "TEMP=2.7"
diff --git a/code/game/turfs/simulated/minerals.dm b/code/game/turfs/simulated/minerals.dm
index 630ded7daa..a597022448 100644
--- a/code/game/turfs/simulated/minerals.dm
+++ b/code/game/turfs/simulated/minerals.dm
@@ -111,12 +111,6 @@
if(istype(R.module_active, /obj/item/pickaxe))
src.attackby(R.module_active,R)
return
-/* else if(istype(AM, /obj/mecha))
- var/obj/mecha/M = AM
- if(istype(M.selected, /obj/item/mecha_parts/mecha_equipment/drill))
- src.attackby(M.selected,M)
- return*/
-//Aparantly mechs are just TOO COOL to call Collide())
else
return
diff --git a/code/game/turfs/simulated/reebe_void.dm b/code/game/turfs/simulated/reebe_void.dm
new file mode 100644
index 0000000000..2e0246df83
--- /dev/null
+++ b/code/game/turfs/simulated/reebe_void.dm
@@ -0,0 +1,47 @@
+/turf/open/indestructible/reebe_void
+ name = "void"
+ icon_state = "reebemap"
+ layer = SPACE_LAYER
+ baseturf = /turf/open/indestructible/reebe_void
+ planetary_atmos = TRUE
+
+/turf/open/indestructible/reebe_void/Initialize(mapload)
+ . = ..()
+ icon_state = "reebegame"
+
+/turf/open/indestructible/reebe_void/spawning
+ icon_state = "reebespawn"
+
+/turf/open/indestructible/reebe_void/spawning/Initialize(mapload)
+ . = ..()
+ if(mapload)
+ for(var/i in 1 to 3)
+ if(prob(1))
+ new /obj/item/clockwork/alloy_shards/large(src)
+ if(prob(2))
+ new /obj/item/clockwork/alloy_shards/medium(src)
+ if(prob(3))
+ new /obj/item/clockwork/alloy_shards/small(src)
+
+/turf/open/indestructible/reebe_void/spawning/lattices
+ icon_state = "reebelattice"
+
+/turf/open/indestructible/reebe_void/spawning/lattices/Initialize(mapload)
+ . = ..()
+ if(mapload)
+ if(prob(2.5))
+ new /obj/structure/lattice/catwalk/clockwork(src)
+ else if(prob(5))
+ new /obj/structure/lattice/clockwork(src)
+
+/turf/open/indestructible/reebe_void/Enter(atom/movable/AM, atom/old_loc)
+ if(!..())
+ return FALSE
+ else
+ if(istype(AM, /obj/structure/window))
+ return FALSE
+ if(istype(AM, /obj/item/projectile))
+ return TRUE
+ if((locate(/obj/structure/lattice) in src))
+ return TRUE
+ return FALSE
diff --git a/code/game/turfs/simulated/wall/misc_walls.dm b/code/game/turfs/simulated/wall/misc_walls.dm
index 280eacf167..e39c791cee 100644
--- a/code/game/turfs/simulated/wall/misc_walls.dm
+++ b/code/game/turfs/simulated/wall/misc_walls.dm
@@ -55,6 +55,7 @@
sheet_type = /obj/item/stack/tile/brass
sheet_amount = 1
girder_type = /obj/structure/destructible/clockwork/wall_gear
+ baseturf = /turf/open/floor/clockwork/reebe
var/obj/effect/clockwork/overlay/wall/realappearence
/turf/closed/wall/clockwork/Initialize()
@@ -63,15 +64,8 @@
new /obj/effect/temp_visual/ratvar/beam(src)
realappearence = new /obj/effect/clockwork/overlay/wall(src)
realappearence.linked = src
- change_construction_value(5)
-
-/turf/closed/wall/clockwork/examine(mob/user)
- ..()
- if((is_servant_of_ratvar(user) || isobserver(user)))
- to_chat(user, "It is linked to a Tinkerer's Cache, generating components! ")
/turf/closed/wall/clockwork/Destroy()
- change_construction_value(-5)
if(realappearence)
qdel(realappearence)
realappearence = null
diff --git a/code/game/turfs/simulated/wall/reinf_walls.dm b/code/game/turfs/simulated/wall/reinf_walls.dm
index 5ebe1d632a..5c95d108b4 100644
--- a/code/game/turfs/simulated/wall/reinf_walls.dm
+++ b/code/game/turfs/simulated/wall/reinf_walls.dm
@@ -13,8 +13,7 @@
girder_type = /obj/structure/girder/reinforced
explosion_block = 2
-/turf/closed/wall/r_wall/examine(mob/user)
- ..()
+/turf/closed/wall/r_wall/deconstruction_hints(mob/user)
switch(d_state)
if(INTACT)
to_chat(user, "The outer grille is fully intact. ")
diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm
index 9171c7f54c..baee3b31c1 100644
--- a/code/game/turfs/simulated/walls.dm
+++ b/code/game/turfs/simulated/walls.dm
@@ -25,6 +25,13 @@
/turf/closed/wall/clockwork)
smooth = SMOOTH_TRUE
+/turf/closed/wall/examine(mob/user)
+ ..()
+ deconstruction_hints(user)
+
+/turf/closed/wall/proc/deconstruction_hints(mob/user)
+ to_chat(user, "The outer plating is welded firmly in place. ")
+
/turf/closed/wall/attack_tk()
return
@@ -287,4 +294,4 @@
to_chat(user, "You deconstruct the wall. ")
ChangeTurf(/turf/open/floor/plating)
return TRUE
- return FALSE
\ No newline at end of file
+ return FALSE
diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm
index b1b00b3e55..a51030be2b 100644
--- a/code/game/turfs/space/space.dm
+++ b/code/game/turfs/space/space.dm
@@ -14,6 +14,7 @@
var/global/datum/gas_mixture/immutable/space/space_gas = new
plane = PLANE_SPACE
+ layer = SPACE_LAYER
light_power = 0.25
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
@@ -66,7 +67,7 @@
return
/turf/open/space/proc/update_starlight()
- if(config.starlight)
+ if(CONFIG_GET(flag/starlight))
for(var/t in RANGE_TURFS(1,src)) //RANGE_TURFS is in code\__HELPERS\game.dm
if(isspaceturf(t))
//let's NOT update this that much pls
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 5bb90f618b..b02444281c 100755
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -121,8 +121,6 @@
return FALSE
/turf/Enter(atom/movable/mover as mob|obj, atom/forget as mob|obj|turf|area)
- if (!mover)
- return TRUE
// First, make sure it can leave its square
if(isturf(mover.loc))
// Nothing but border objects stop you from leaving a tile, only one loop is needed
@@ -131,32 +129,28 @@
mover.Collide(obstacle)
return FALSE
- var/list/large_dense = list()
-
- //Next, check objects to block entry that are on the border
- for(var/atom/movable/border_obstacle in src)
- if(border_obstacle.flags_1 & ON_BORDER_1)
- if(!border_obstacle.CanPass(mover, mover.loc, 1) && (forget != border_obstacle))
- mover.Collide(border_obstacle)
- return FALSE
- else
- large_dense += border_obstacle
-
//Then, check the turf itself
if (!src.CanPass(mover, src))
mover.Collide(src)
return FALSE
- //Finally, check objects/mobs to block entry that are not on the border
- var/atom/movable/tompost_bump
+
+ var/atom/movable/topmost_bump
var/top_layer = FALSE
- for(var/atom/movable/obstacle in large_dense)
+
+ //Next, check objects to block entry that are on the border
+ for(var/atom/movable/obstacle in src)
if(!obstacle.CanPass(mover, mover.loc, 1) && (forget != obstacle))
- if(obstacle.layer > top_layer)
- tompost_bump = obstacle
- top_layer = obstacle.layer
- if(tompost_bump)
- mover.Collide(tompost_bump)
+ if(obstacle.flags_1 & ON_BORDER_1)
+ mover.Collide(obstacle)
+ return FALSE
+ else
+ if(obstacle.layer > top_layer)
+ topmost_bump = obstacle
+ top_layer = obstacle.layer
+
+ if(topmost_bump)
+ mover.Collide(topmost_bump)
return FALSE
return TRUE //Nothing found to block so return success!
diff --git a/code/game/world.dm b/code/game/world.dm
index 3763a408ac..bd04008ea3 100644
--- a/code/game/world.dm
+++ b/code/game/world.dm
@@ -1,3 +1,6 @@
+#define PR_ANNOUNCEMENTS_PER_ROUND 5 //The number of unique PR announcements allowed per round
+ //This makes sure that a single person can only spam 3 reopens and 3 closes before being ignored
+
GLOBAL_VAR(security_mode)
GLOBAL_PROTECT(security_mode)
@@ -12,29 +15,27 @@ GLOBAL_PROTECT(security_mode)
make_datum_references_lists() //initialises global lists for referencing frequently used datums (so that we only ever do it once)
- config = new
+ new /datum/controller/configuration
CheckSchemaVersion()
SetRoundID()
SetupLogs()
- if(!RunningService()) //tgs2 support
- GLOB.revdata.DownloadPRDetails()
+ SERVER_TOOLS_ON_NEW
load_motd()
load_admins()
LoadVerbs(/datum/verbs/menu)
- if(config.usewhitelist)
+ if(CONFIG_GET(flag/usewhitelist))
load_whitelist()
LoadBans()
+ reload_custom_roundstart_items_list()
GLOB.timezoneOffset = text2num(time2text(0,"hh")) * 36000
Master.Initialize(10, FALSE)
- if(config.irc_announce_new_game)
- IRCBroadcast("New round starting on [SSmapping.config.map_name]!")
/world/proc/SetupExternalRSC()
#if (PRELOAD_RSC == 0)
@@ -48,7 +49,7 @@ GLOBAL_PROTECT(security_mode)
#endif
/world/proc/CheckSchemaVersion()
- if(config.sql_enabled)
+ if(CONFIG_GET(flag/sql_enabled))
if(SSdbcore.Connect())
log_world("Database connection established.")
var/datum/DBQuery/query_db_version = SSdbcore.NewQuery("SELECT major, minor FROM [format_table_name("schema_revision")] ORDER BY date DESC LIMIT 1")
@@ -68,7 +69,7 @@ GLOBAL_PROTECT(security_mode)
log_world("Your server failed to establish a connection with the database.")
/world/proc/SetRoundID()
- if(config.sql_enabled)
+ if(CONFIG_GET(flag/sql_enabled))
if(SSdbcore.Connect())
var/datum/DBQuery/query_round_start = SSdbcore.NewQuery("INSERT INTO [format_table_name("round")] (start_datetime, server_ip, server_port) VALUES (Now(), INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]')")
query_round_start.Execute()
@@ -122,12 +123,13 @@ GLOBAL_PROTECT(security_mode)
var/pinging = ("ping" in input)
var/playing = ("players" in input)
- if(!pinging && !playing && config && config.log_world_topic)
+ if(!pinging && !playing && config && CONFIG_GET(flag/log_world_topic))
WRITE_FILE(GLOB.world_game_log, "TOPIC: \"[T]\", from:[addr], master:[master], key:[key]")
- if(input[SERVICE_CMD_PARAM_KEY])
- return ServiceCommand(input)
- var/key_valid = (global.comms_allowed && input["key"] == global.comms_key)
+ SERVER_TOOLS_ON_TOPIC //redirect to server tools if necessary
+
+ var/comms_key = CONFIG_GET(string/comms_key)
+ var/key_valid = (comms_key && input["key"] == comms_key)
if(pinging)
var/x = 1
@@ -142,25 +144,14 @@ GLOBAL_PROTECT(security_mode)
n++
return n
- else if("ircstatus" in input) //tgs2 support
- var/static/last_irc_status = 0
- if(world.time - last_irc_status < 50)
- return
- var/list/adm = get_admin_counts()
- var/list/allmins = adm["total"]
- var/status = "Admins: [allmins.len] (Active: [english_list(adm["present"])] AFK: [english_list(adm["afk"])] Stealth: [english_list(adm["stealth"])] Skipped: [english_list(adm["noflags"])]). "
- status += "Players: [GLOB.clients.len] (Active: [get_active_player_count(0,1,0)]). Mode: [SSticker.mode.name]."
- send2irc("Status", status)
- last_irc_status = world.time
-
else if("status" in input)
var/list/s = list()
s["version"] = GLOB.game_version
s["mode"] = GLOB.master_mode
- s["respawn"] = config ? GLOB.abandon_allowed : 0
+ s["respawn"] = config ? !CONFIG_GET(flag/norespawn) : FALSE
s["enter"] = GLOB.enter_allowed
- s["vote"] = config.allow_vote_mode
- s["ai"] = config.allow_ai
+ s["vote"] = CONFIG_GET(flag/allow_vote_mode)
+ s["ai"] = CONFIG_GET(flag/allow_ai)
s["host"] = host ? host : null
s["active_players"] = get_active_player_count()
s["players"] = GLOB.clients.len
@@ -210,24 +201,6 @@ GLOBAL_PROTECT(security_mode)
if(input["crossmessage"] == "News_Report")
minor_announce(input["message"], "Breaking Update From [input["message_sender"]]")
- else if("adminmsg" in input) //tgs2 support
- if(!key_valid)
- return "Bad Key"
- else
- return IrcPm(input["adminmsg"],input["msg"],input["sender"])
-
- else if("namecheck" in input) //tgs2 support
- if(!key_valid)
- return "Bad Key"
- else
- log_admin("IRC Name Check: [input["sender"]] on [input["namecheck"]]")
- message_admins("IRC name checking on [input["namecheck"]] from [input["sender"]]")
- return keywords_lookup(input["namecheck"],1)
- else if("adminwho" in input) //tgs2 support
- if(!key_valid)
- return "Bad Key"
- else
- return ircadminwho()
else if("server_hop" in input)
show_server_hop_transfer_screen(input["server_hop"])
@@ -246,7 +219,7 @@ GLOBAL_PROTECT(security_mode)
C.AnnouncePR(final_composed)
/world/Reboot(reason = 0, fast_track = FALSE)
- ServiceReboot() //handles alternative actions if necessary
+ SERVER_TOOLS_ON_REBOOT
if (reason || fast_track) //special reboot, do none of the normal stuff
if (usr)
log_admin("[key_name(usr)] Has requested an immediate world restart via client side debugging tools")
@@ -262,17 +235,6 @@ GLOBAL_PROTECT(security_mode)
GLOB.join_motd = file2text("config/motd.txt") + " " + GLOB.revdata.GetTestMergeInfo()
/world/proc/update_status()
- var/s = ""
-
- if (config && config.server_name)
- s += "[config.server_name] — "
-
- s += "[station_name()] ";
- s += " ("
- s += "" //Change this to wherever you want the hub to link to.
- s += "Default" //Replace this with something else. Or ever better, delete it and uncomment the game version.
- s += " "
- s += ")"
var/list/features = list()
@@ -282,13 +244,25 @@ GLOBAL_PROTECT(security_mode)
if (!GLOB.enter_allowed)
features += "closed"
- features += GLOB.abandon_allowed ? "respawn" : "no respawn"
+ var/s = ""
+ var/hostedby
+ if(config)
+ var/server_name = CONFIG_GET(string/servername)
+ if (server_name)
+ s += "[server_name] — "
+ features += "[CONFIG_GET(flag/norespawn) ? "no " : ""]respawn"
+ if(CONFIG_GET(flag/allow_vote_mode))
+ features += "vote"
+ if(CONFIG_GET(flag/allow_ai))
+ features += "AI allowed"
+ hostedby = CONFIG_GET(string/hostedby)
- if (config && config.allow_vote_mode)
- features += "vote"
-
- if (config && config.allow_ai)
- features += "AI allowed"
+ s += "[station_name()] ";
+ s += " ("
+ s += "" //Change this to wherever you want the hub to link to.
+ s += "Default" //Replace this with something else. Or ever better, delete it and uncomment the game version.
+ s += " "
+ s += ")"
var/n = 0
for (var/mob/M in GLOB.player_list)
@@ -300,8 +274,8 @@ GLOBAL_PROTECT(security_mode)
else if (n > 0)
features += "~[n] player"
- if (!host && config && config.hostedby)
- features += "hosted by [config.hostedby] "
+ if (!host && hostedby)
+ features += "hosted by [hostedby] "
if (features)
s += ": [jointext(features, ", ")]"
diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm
index 39a465d2b4..10a3774ae1 100644
--- a/code/modules/admin/IsBanned.dm
+++ b/code/modules/admin/IsBanned.dm
@@ -20,7 +20,7 @@
admin = 1
//Whitelist
- if(config.usewhitelist)
+ if(CONFIG_GET(flag/usewhitelist))
if(!check_whitelist(ckey(key)))
if (admin)
log_admin("The admin [key] has been allowed to bypass the whitelist")
@@ -32,19 +32,20 @@
//Guest Checking
if(IsGuestKey(key))
- if (!GLOB.guests_allowed)
+ if (CONFIG_GET(flag/guest_ban))
log_access("Failed Login: [key] - Guests not allowed")
return list("reason"="guest", "desc"="\nReason: Guests not allowed. Please sign in with a byond account.")
- if (config.panic_bunker && SSdbcore && SSdbcore.IsConnected())
+ if (CONFIG_GET(flag/panic_bunker) && SSdbcore.Connect())
log_access("Failed Login: [key] - Guests not allowed during panic bunker")
return list("reason"="guest", "desc"="\nReason: Sorry but the server is currently not accepting connections from never before seen players or guests. If you have played on this server with a byond account before, please log in to the byond account you have played from.")
//Population Cap Checking
- if(config.extreme_popcap && living_player_count() >= config.extreme_popcap && !admin)
+ var/extreme_popcap = CONFIG_GET(number/extreme_popcap)
+ if(extreme_popcap && living_player_count() >= extreme_popcap && !admin)
log_access("Failed Login: [key] - Population cap reached")
- return list("reason"="popcap", "desc"= "\nReason: [config.extreme_popcap_message]")
+ return list("reason"="popcap", "desc"= "\nReason: [CONFIG_GET(string/extreme_popcap_message)]")
- if(config.ban_legacy_system)
+ if(CONFIG_GET(flag/ban_legacy_system))
//Ban Checking
. = CheckBan( ckey(key), computer_id, address )
diff --git a/code/modules/admin/NewBan.dm b/code/modules/admin/NewBan.dm
index 5ea980a91d..27d5502edf 100644
--- a/code/modules/admin/NewBan.dm
+++ b/code/modules/admin/NewBan.dm
@@ -11,8 +11,9 @@ GLOBAL_PROTECT(Banlist)
. = list()
var/appeal
- if(config && config.banappeals)
- appeal = "\nFor more information on your ban, or to appeal, head to [config.banappeals] "
+ var/bran = CONFIG_GET(string/banappeals)
+ if(bran)
+ appeal = "\nFor more information on your ban, or to appeal, head to [bran] "
GLOB.Banlist.cd = "/base"
if( "[ckey][id]" in GLOB.Banlist.dir )
GLOB.Banlist.cd = "[ckey][id]"
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index b56caa4e9a..a64cd8f40e 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -31,7 +31,7 @@
if(M.client)
body += " played by [M.client] "
body += "\[[M.client.holder ? M.client.holder.rank : "Player"] \]"
- if(config.use_exp_tracking)
+ if(CONFIG_GET(flag/use_exp_tracking))
body += "\[" + M.client.get_exp_living() + " \]"
if(isnewplayer(M))
@@ -421,8 +421,8 @@
return
var/list/options = list("Regular Restart", "Hard Restart (No Delay/Feeback Reason)", "Hardest Restart (No actions, just reboot)")
- if(world.RunningService())
- options += "Service Restart (Force restart DD)";
+ if(SERVER_TOOLS_PRESENT)
+ options += "Server Restart (Kill and restart DD)";
var/rebootconfirm
if(SSticker.admin_delay_notice)
@@ -434,16 +434,19 @@
var/result = input(usr, "Select reboot method", "World Reboot", options[1]) as null|anything in options
if(result)
SSblackbox.add_details("admin_verb","Reboot World") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ var/init_by = "Initiated by [usr.client.holder.fakekey ? "Admin" : usr.key]."
switch(result)
if("Regular Restart")
- SSticker.Reboot("Initiated by [usr.client.holder.fakekey ? "Admin" : usr.key].", "admin reboot - by [usr.key] [usr.client.holder.fakekey ? "(stealth)" : ""]", 10)
+ SSticker.Reboot(init_by, "admin reboot - by [usr.key] [usr.client.holder.fakekey ? "(stealth)" : ""]", 10)
if("Hard Restart (No Delay, No Feeback Reason)")
+ to_chat(world, "World reboot - [init_by]")
world.Reboot()
if("Hardest Restart (No actions, just reboot)")
+ to_chat(world, "Hard world reboot - [init_by]")
world.Reboot(fast_track = TRUE)
- if("Service Restart (Force restart DD)")
- GLOB.reboot_mode = REBOOT_MODE_HARD
- world.ServiceReboot()
+ if("Server Restart (Kill and restart DD)")
+ to_chat(world, "Server restart - [init_by]")
+ SERVER_TOOLS_REBOOT_BYOND
/datum/admins/proc/end_round()
set category = "Server"
@@ -555,28 +558,30 @@
set category = "Server"
set desc="People can't be AI"
set name="Toggle AI"
- config.allow_ai = !( config.allow_ai )
- if (!( config.allow_ai ))
+ var/alai = CONFIG_GET(flag/allow_ai)
+ CONFIG_SET(flag/allow_ai, !alai)
+ if (alai)
to_chat(world, "The AI job is no longer chooseable. ")
else
to_chat(world, "The AI job is chooseable now. ")
log_admin("[key_name(usr)] toggled AI allowed.")
world.update_status()
- SSblackbox.add_details("admin_toggle","Toggle AI|[config.allow_ai]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ SSblackbox.add_details("admin_toggle","Toggle AI|[!alai]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/toggleaban()
set category = "Server"
set desc="Respawn basically"
set name="Toggle Respawn"
- GLOB.abandon_allowed = !( GLOB.abandon_allowed )
- if (GLOB.abandon_allowed)
+ var/new_nores = !CONFIG_GET(flag/norespawn)
+ CONFIG_SET(flag/norespawn, new_nores)
+ if (!new_nores)
to_chat(world, "You may now respawn. ")
else
to_chat(world, "You may no longer respawn :( ")
- message_admins("[key_name_admin(usr)] toggled respawn to [GLOB.abandon_allowed ? "On" : "Off"]. ")
- log_admin("[key_name(usr)] toggled respawn to [GLOB.abandon_allowed ? "On" : "Off"].")
+ message_admins("[key_name_admin(usr)] toggled respawn to [!new_nores ? "On" : "Off"]. ")
+ log_admin("[key_name(usr)] toggled respawn to [!new_nores ? "On" : "Off"].")
world.update_status()
- SSblackbox.add_details("admin_toggle","Toggle Respawn|[GLOB.abandon_allowed]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ SSblackbox.add_details("admin_toggle","Toggle Respawn|[!new_nores]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/delay()
set category = "Server"
@@ -683,14 +688,15 @@
set category = "Server"
set desc="Guests can't enter"
set name="Toggle guests"
- GLOB.guests_allowed = !( GLOB.guests_allowed )
- if (!( GLOB.guests_allowed ))
+ var/new_guest_ban = !CONFIG_GET(flag/guest_ban)
+ CONFIG_SET(flag/guest_ban, new_guest_ban)
+ if (new_guest_ban)
to_chat(world, "Guests may no longer enter the game. ")
else
to_chat(world, "Guests may now enter the game. ")
- log_admin("[key_name(usr)] toggled guests game entering [GLOB.guests_allowed?"":"dis"]allowed.")
- message_admins("[key_name_admin(usr)] toggled guests game entering [GLOB.guests_allowed?"":"dis"]allowed. ")
- SSblackbox.add_details("admin_toggle","Toggle Guests|[GLOB.guests_allowed]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ log_admin("[key_name(usr)] toggled guests game entering [!new_guest_ban ? "" : "dis"]allowed.")
+ message_admins("[key_name_admin(usr)] toggled guests game entering [!new_guest_ban ? "" : "dis"]allowed. ")
+ SSblackbox.add_details("admin_toggle","Toggle Guests|[!new_guest_ban]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/output_ai_laws()
var/ai_number = 0
@@ -828,10 +834,10 @@
/client/proc/adminGreet(logout)
if(SSticker.HasRoundStarted())
var/string
- if(logout && config && config.announce_admin_logout)
+ if(logout && CONFIG_GET(flag/announce_admin_logout))
string = pick(
"Admin logout: [key_name(src)]")
- else if(!logout && config && config.announce_admin_login && (prefs.toggles & ANNOUNCE_LOGIN))
+ else if(!logout && CONFIG_GET(flag/announce_admin_login) && (prefs.toggles & ANNOUNCE_LOGIN))
string = pick(
"Admin login: [key_name(src)]")
if(string)
diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm
index 67d0b4dbf7..be9e423a17 100644
--- a/code/modules/admin/admin_ranks.dm
+++ b/code/modules/admin/admin_ranks.dm
@@ -117,7 +117,7 @@ GLOBAL_PROTECT(admin_ranks)
return
GLOB.admin_ranks.Cut()
- if(config.admin_legacy_system)
+ if(CONFIG_GET(flag/admin_legacy_system))
var/previous_rights = 0
//load text from file and process each line separately
for(var/line in world.file2list("config/admin_ranks.txt"))
@@ -143,7 +143,7 @@ GLOBAL_PROTECT(admin_ranks)
if(!SSdbcore.Connect())
log_world("Failed to connect to database in load_admin_ranks(). Reverting to legacy system.")
WRITE_FILE(GLOB.world_game_log, "Failed to connect to database in load_admin_ranks(). Reverting to legacy system.")
- config.admin_legacy_system = 1
+ CONFIG_SET(flag/admin_legacy_system, TRUE)
load_admin_ranks()
return
@@ -191,7 +191,7 @@ GLOBAL_PROTECT(admin_ranks)
for(var/datum/admin_rank/R in GLOB.admin_ranks)
rank_names[R.name] = R
- if(config.admin_legacy_system)
+ if(CONFIG_GET(flag/admin_legacy_system))
//load text from file
var/list/lines = world.file2list("config/admins.txt")
@@ -219,7 +219,7 @@ GLOBAL_PROTECT(admin_ranks)
if(!SSdbcore.Connect())
log_world("Failed to connect to database in load_admins(). Reverting to legacy system.")
WRITE_FILE(GLOB.world_game_log, "Failed to connect to database in load_admins(). Reverting to legacy system.")
- config.admin_legacy_system = 1
+ CONFIG_SET(flag/admin_legacy_system, TRUE)
load_admins()
return
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 526d05b76b..0f2702f3b6 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -262,7 +262,7 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list(
verbs += GLOB.admin_verbs_poll
if(rights & R_SOUNDS)
verbs += GLOB.admin_verbs_sounds
- if(config.invoke_youtubedl)
+ if(CONFIG_GET(string/invoke_youtubedl))
verbs += /client/proc/play_web_sound
if(rights & R_SPAWN)
verbs += GLOB.admin_verbs_spawn
@@ -399,7 +399,7 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list(
set name = "Unban Panel"
set category = "Admin"
if(holder)
- if(config.ban_legacy_system)
+ if(CONFIG_GET(flag/ban_legacy_system))
holder.unbanpanel()
else
holder.DB_ban_panel()
diff --git a/code/modules/admin/chat_commands.dm b/code/modules/admin/chat_commands.dm
new file mode 100644
index 0000000000..f24e03aabc
--- /dev/null
+++ b/code/modules/admin/chat_commands.dm
@@ -0,0 +1,76 @@
+#define IRC_STATUS_THROTTLE 5
+
+/datum/server_tools_command/ircstatus
+ name = "status"
+ help_text = "Gets the admincount, playercount, gamemode, and true game mode of the server"
+ admin_only = TRUE
+ var/static/last_irc_status = 0
+
+/datum/server_tools_command/ircstatus/Run(sender, params)
+ var/rtod = REALTIMEOFDAY
+ if(rtod - last_irc_status < IRC_STATUS_THROTTLE)
+ return
+ last_irc_status = rtod
+ var/list/adm = get_admin_counts()
+ var/list/allmins = adm["total"]
+ var/status = "Admins: [allmins.len] (Active: [english_list(adm["present"])] AFK: [english_list(adm["afk"])] Stealth: [english_list(adm["stealth"])] Skipped: [english_list(adm["noflags"])]). "
+ status += "Players: [GLOB.clients.len] (Active: [get_active_player_count(0,1,0)]). Mode: [SSticker.mode ? SSticker.mode.name : "Not started"]."
+ return status
+
+/datum/server_tools_command/irccheck
+ name = "check"
+ help_text = "Gets the playercount, gamemode, and address of the server"
+ var/static/last_irc_check = 0
+
+/datum/server_tools_command/irccheck/Run(sender, params)
+ var/rtod = REALTIMEOFDAY
+ if(rtod - last_irc_check < IRC_STATUS_THROTTLE)
+ return
+ last_irc_check = rtod
+ var/server = CONFIG_GET(string/server)
+ return "[GLOB.round_id ? "Round #[GLOB.round_id]: " : ""][GLOB.clients.len] players on [SSmapping.config.map_name], Mode: [GLOB.master_mode]; Round [SSticker.HasRoundStarted() ? (SSticker.IsRoundInProgress() ? "Active" : "Finishing") : "Starting"] -- [server ? server : "[world.internet_address]:[world.port]"]"
+
+/datum/server_tools_command/ahelp
+ name = "ahelp"
+ help_text = " |list>>"
+ required_parameters = 2
+ admin_only = TRUE
+
+/datum/server_tools_command/ahelp/Run(sender, params)
+ var/list/all_params = splittext(params, " ")
+ var/target = all_params[1]
+ all_params.Cut(1, 2)
+ return IrcPm(target, all_params.Join(" "), sender)
+
+/datum/server_tools_command/namecheck
+ name = "namecheck"
+ help_text = "Returns info on the specified target"
+ required_parameters = 1
+ admin_only = TRUE
+
+/datum/server_tools_command/namecheck/Run(sender, params)
+ log_admin("IRC Name Check: [sender] on [params]")
+ message_admins("IRC name checking on [params] from [sender]")
+ return keywords_lookup(params, 1)
+
+/datum/server_tools_command/adminwho
+ name = "adminwho"
+ help_text = "Lists administrators currently on the server"
+ admin_only = TRUE
+
+/datum/server_tools_command/adminwho/Run(sender, params)
+ return ircadminwho()
+
+GLOBAL_LIST(round_end_notifiees)
+
+/datum/server_tools_command/notify
+ name = "notify"
+ help_text = "Pings the invoker when the round ends"
+ admin_only = TRUE
+
+/datum/server_tools_command/notify/Run(sender, params)
+ if(!SSticker.IsRoundInProgress() && SSticker.HasRoundStarted())
+ return "[sender], the round has already ended!"
+ LAZYINITLIST(GLOB.round_end_notifiees)
+ GLOB.round_end_notifiees[sender] = TRUE
+ return "I will notify [sender] when the round ends."
\ No newline at end of file
diff --git a/code/modules/admin/ipintel.dm b/code/modules/admin/ipintel.dm
index 50f81e01c3..fa9951f276 100644
--- a/code/modules/admin/ipintel.dm
+++ b/code/modules/admin/ipintel.dm
@@ -14,18 +14,18 @@
. = FALSE
if (intel < 0)
return
- if (intel <= config.ipintel_rating_bad)
- if (world.realtime < cacherealtime+(config.ipintel_save_good*60*60*10))
+ if (intel <= CONFIG_GET(number/ipintel_rating_bad))
+ if (world.realtime < cacherealtime + (CONFIG_GET(number/ipintel_save_good) * 60 * 60 * 10))
return TRUE
else
- if (world.realtime < cacherealtime+(config.ipintel_save_bad*60*60*10))
+ if (world.realtime < cacherealtime + (CONFIG_GET(number/ipintel_save_bad) * 60 * 60 * 10))
return TRUE
/proc/get_ip_intel(ip, bypasscache = FALSE, updatecache = TRUE)
var/datum/ipintel/res = new()
res.ip = ip
. = res
- if (!ip || !config.ipintel_email || !SSipintel.enabled)
+ if (!ip || !CONFIG_GET(string/ipintel_email) || !SSipintel.enabled)
return
if (!bypasscache)
var/datum/ipintel/cachedintel = SSipintel.cache[ip]
@@ -34,19 +34,20 @@
return cachedintel
if(SSdbcore.Connect())
+ var/rating_bad = CONFIG_GET(number/ipintel_rating_bad)
var/datum/DBQuery/query_get_ip_intel = SSdbcore.NewQuery({"
SELECT date, intel, TIMESTAMPDIFF(MINUTE,date,NOW())
FROM [format_table_name("ipintel")]
WHERE
ip = INET_ATON('[ip]')
AND ((
- intel < [config.ipintel_rating_bad]
+ intel < [rating_bad]
AND
- date + INTERVAL [config.ipintel_save_good] HOUR > NOW()
+ date + INTERVAL [CONFIG_GET(number/ipintel_save_good)] HOUR > NOW()
) OR (
- intel >= [config.ipintel_rating_bad]
+ intel >= [rating_bad]
AND
- date + INTERVAL [config.ipintel_save_bad] HOUR > NOW()
+ date + INTERVAL [CONFIG_GET(number/ipintel_save_bad)] HOUR > NOW()
))
"})
if(!query_get_ip_intel.Execute())
@@ -77,7 +78,7 @@
if (!SSipintel.enabled)
return
- var/list/http[] = world.Export("http://[config.ipintel_domain]/check.php?ip=[ip]&contact=[config.ipintel_email]&format=json&flags_1=f")
+ var/list/http[] = world.Export("http://[CONFIG_GET(string/ipintel_domain)]/check.php?ip=[ip]&contact=[CONFIG_GET(string/ipintel_email)]&format=json&flags=f")
if (http)
var/status = text2num(http["STATUS"])
diff --git a/code/modules/admin/permissionverbs/permissionedit.dm b/code/modules/admin/permissionverbs/permissionedit.dm
index f0f263f815..24a53eff2b 100644
--- a/code/modules/admin/permissionverbs/permissionedit.dm
+++ b/code/modules/admin/permissionverbs/permissionedit.dm
@@ -51,7 +51,7 @@
usr << browse(output,"window=editrights;size=900x650")
/datum/admins/proc/log_admin_rank_modification(adm_ckey, new_rank)
- if(config.admin_legacy_system)
+ if(CONFIG_GET(flag/admin_legacy_system))
return
if(!usr.client)
@@ -105,7 +105,7 @@
/datum/admins/proc/log_admin_permission_modification(adm_ckey, new_permission)
- if(config.admin_legacy_system)
+ if(CONFIG_GET(flag/admin_legacy_system))
return
if(!usr.client)
return
diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm
index 39e07e0a9f..95f4bd55c7 100644
--- a/code/modules/admin/player_panel.dm
+++ b/code/modules/admin/player_panel.dm
@@ -329,14 +329,14 @@
else
dat += "ETA: [(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)] "
dat += "Continuous Round Status "
- dat += "[config.continuous[SSticker.mode.config_tag] ? "Continue if antagonists die" : "End on antagonist death"] "
- if(config.continuous[SSticker.mode.config_tag])
- dat += ", [config.midround_antag[SSticker.mode.config_tag] ? "creating replacement antagonists" : "not creating new antagonists"] "
+ dat += "[CONFIG_GET(keyed_flag_list/continuous)[SSticker.mode.config_tag] ? "Continue if antagonists die" : "End on antagonist death"] "
+ if(CONFIG_GET(keyed_flag_list/continuous)[SSticker.mode.config_tag])
+ dat += ", [CONFIG_GET(keyed_flag_list/midround_antag)[SSticker.mode.config_tag] ? "creating replacement antagonists" : "not creating new antagonists"] "
else
dat += " "
- if(config.midround_antag[SSticker.mode.config_tag])
- dat += "Time limit: [config.midround_antag_time_check] minutes into round "
- dat += "Living crew limit: [config.midround_antag_life_check * 100]% of crew alive "
+ if(CONFIG_GET(keyed_flag_list/midround_antag)[SSticker.mode.config_tag])
+ dat += "Time limit: [CONFIG_GET(number/midround_antag_time_check)] minutes into round "
+ dat += "Living crew limit: [CONFIG_GET(number/midround_antag_life_check) * 100]% of crew alive "
dat += "If limits past: [SSticker.mode.round_ends_with_antag_death ? "End The Round" : "Continue As Extended"] "
dat += "End Round Now "
dat += "[SSticker.delay_end ? "End Round Normally" : "Delay Round End"] "
@@ -530,7 +530,7 @@
else
dat += "[brother.name]([brother.key]) Brother body destroyed! "
dat += "PM "
- dat += ""
+ dat += ""
if(SSticker.mode.abductors.len)
dat += "Abductors "
diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm
index 99f95cd6f4..9fd49ed497 100644
--- a/code/modules/admin/secrets.dm
+++ b/code/modules/admin/secrets.dm
@@ -354,16 +354,9 @@
SSblackbox.add_details("admin_secrets_fun_used","Bomb Cap")
var/newBombCap = input(usr,"What would you like the new bomb cap to be. (entered as the light damage range (the 3rd number in common (1,2,3) notation)) Must be above 4)", "New Bomb Cap", GLOB.MAX_EX_LIGHT_RANGE) as num|null
- if (newBombCap < 4)
+ if (!CONFIG_SET(number/bombcap, newBombCap))
return
- GLOB.MAX_EX_DEVESTATION_RANGE = round(newBombCap/4)
- GLOB.MAX_EX_HEAVY_RANGE = round(newBombCap/2)
- GLOB.MAX_EX_LIGHT_RANGE = newBombCap
- //I don't know why these are their own variables, but fuck it, they are.
- GLOB.MAX_EX_FLASH_RANGE = newBombCap
- GLOB.MAX_EX_FLAME_RANGE = newBombCap
-
message_admins("[key_name_admin(usr)] changed the bomb cap to [GLOB.MAX_EX_DEVESTATION_RANGE], [GLOB.MAX_EX_HEAVY_RANGE], [GLOB.MAX_EX_LIGHT_RANGE] ")
log_admin("[key_name(usr)] changed the bomb cap to [GLOB.MAX_EX_DEVESTATION_RANGE], [GLOB.MAX_EX_HEAVY_RANGE], [GLOB.MAX_EX_LIGHT_RANGE]")
diff --git a/code/modules/admin/sql_message_system.dm b/code/modules/admin/sql_message_system.dm
index 50236c548d..587bd6b26c 100644
--- a/code/modules/admin/sql_message_system.dm
+++ b/code/modules/admin/sql_message_system.dm
@@ -33,8 +33,9 @@
if(!timestamp)
timestamp = SQLtime()
if(!server)
- if (config && config.server_sql_name)
- server = config.server_sql_name
+ var/ssqlname = CONFIG_GET(string/serversqlname)
+ if (ssqlname)
+ server = ssqlname
server = sanitizeSQL(server)
if(isnull(secret))
switch(alert("Hide note from being viewed by players?", "Secret note?","Yes","No","Cancel"))
@@ -216,8 +217,10 @@
var/editor_ckey = query_get_messages.item[8]
var/age = text2num(query_get_messages.item[9])
var/alphatext = ""
- if (agegate && type == "note" && isnum(config.note_stale_days) && isnum(config.note_fresh_days) && config.note_stale_days > config.note_fresh_days)
- var/alpha = Clamp(100 - (age - config.note_fresh_days) * (85 / (config.note_stale_days - config.note_fresh_days)), 15, 100)
+ var/nsd = CONFIG_GET(number/note_stale_days)
+ var/nfd = CONFIG_GET(number/note_fresh_days)
+ if (agegate && type == "note" && isnum(nsd) && isnum(nfd) && nsd > nfd)
+ var/alpha = Clamp(100 - (age - nfd) * (85 / (nsd - nfd)), 15, 100)
if (alpha < 100)
if (alpha <= 15)
if (skipped)
@@ -353,8 +356,9 @@ proc/get_message_output(type, target_ckey)
var/notetext
notesfile >> notetext
var/server
- if(config && config.server_sql_name)
- server = config.server_sql_name
+ var/ssqlname = CONFIG_GET(string/serversqlname)
+ if (ssqlname)
+ server = ssqlname
var/regex/note = new("^(\\d{2}-\\w{3}-\\d{4}) \\| (.+) ~(\\w+)$", "i")
note.Find(notetext)
var/timestamp = note.group[1]
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 7f9f5a7d27..c182107a6a 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -5,7 +5,7 @@
return
var/msg = !auth ? "no" : "a bad"
message_admins("[key_name_admin(usr)] clicked an href with [msg] authorization key!")
- if(config.debug_admin_hrefs)
+ if(CONFIG_GET(flag/debug_admin_hrefs))
message_admins("Debug mode enabled, call not blocked. Please ask your coders to review this round's logs.")
log_world("UAH: [href]")
return TRUE
@@ -318,35 +318,36 @@
else if(href_list["toggle_continuous"])
if(!check_rights(R_ADMIN))
return
-
- if(!config.continuous[SSticker.mode.config_tag])
- config.continuous[SSticker.mode.config_tag] = 1
+ var/list/continuous = CONFIG_GET(keyed_flag_list/continuous)
+ if(!continuous[SSticker.mode.config_tag])
+ continuous[SSticker.mode.config_tag] = TRUE
else
- config.continuous[SSticker.mode.config_tag] = 0
+ continuous[SSticker.mode.config_tag] = FALSE
- message_admins("[key_name_admin(usr)] toggled the round to [config.continuous[SSticker.mode.config_tag] ? "continue if all antagonists die" : "end with the antagonists"]. ")
+ message_admins("[key_name_admin(usr)] toggled the round to [continuous[SSticker.mode.config_tag] ? "continue if all antagonists die" : "end with the antagonists"]. ")
check_antagonists()
else if(href_list["toggle_midround_antag"])
if(!check_rights(R_ADMIN))
return
- if(!config.midround_antag[SSticker.mode.config_tag])
- config.midround_antag[SSticker.mode.config_tag] = 1
+ var/list/midround_antag = CONFIG_GET(keyed_flag_list/midround_antag)
+ if(!midround_antag[SSticker.mode.config_tag])
+ midround_antag[SSticker.mode.config_tag] = TRUE
else
- config.midround_antag[SSticker.mode.config_tag] = 0
+ midround_antag[SSticker.mode.config_tag] = FALSE
- message_admins("[key_name_admin(usr)] toggled the round to [config.midround_antag[SSticker.mode.config_tag] ? "use" : "skip"] the midround antag system. ")
+ message_admins("[key_name_admin(usr)] toggled the round to [midround_antag[SSticker.mode.config_tag] ? "use" : "skip"] the midround antag system. ")
check_antagonists()
else if(href_list["alter_midround_time_limit"])
if(!check_rights(R_ADMIN))
return
- var/timer = input("Enter new maximum time",, config.midround_antag_time_check ) as num|null
+ var/timer = input("Enter new maximum time",, CONFIG_GET(number/midround_antag_time_check)) as num|null
if(!timer)
return
- config.midround_antag_time_check = timer
+ CONFIG_SET(number/midround_antag_time_check, timer)
message_admins("[key_name_admin(usr)] edited the maximum midround antagonist time to [timer] minutes. ")
check_antagonists()
@@ -354,9 +355,10 @@
if(!check_rights(R_ADMIN))
return
- var/ratio = input("Enter new life ratio",, config.midround_antag_life_check*100) as num
- if(ratio)
- config.midround_antag_life_check = ratio/100
+ var/ratio = input("Enter new life ratio",, CONFIG_GET(number/midround_antag_life_check) * 100) as num
+ if(!ratio)
+ return
+ CONFIG_SET(number/midround_antag_life_check, ratio / 100)
message_admins("[key_name_admin(usr)] edited the midround antagonist living crew ratio to [ratio]% alive. ")
check_antagonists()
@@ -586,8 +588,9 @@
to_chat(M, "You have been appearance banned by [usr.client.ckey]. ")
to_chat(M, "The reason is: [reason] ")
to_chat(M, "Appearance ban can be lifted only upon request. ")
- if(config.banappeals)
- to_chat(M, "To try to resolve this matter head to [config.banappeals] ")
+ var/bran = CONFIG_GET(string/banappeals)
+ if(bran)
+ to_chat(M, "To try to resolve this matter head to [bran] ")
else
to_chat(M, "No ban appeals URL has been set. ")
if("No")
@@ -1156,8 +1159,9 @@
to_chat(M, "This is a temporary ban, it will be removed in [mins] minutes. ")
SSblackbox.inc("ban_tmp",1)
SSblackbox.inc("ban_tmp_mins",mins)
- if(config.banappeals)
- to_chat(M, "To try to resolve this matter head to [config.banappeals] ")
+ var/bran = CONFIG_GET(string/banappeals)
+ if(bran)
+ to_chat(M, "To try to resolve this matter head to [bran] ")
else
to_chat(M, "No ban appeals URL has been set. ")
log_admin_private("[key_name(usr)] has banned [M.ckey].\nReason: [key_name(M)]\nThis will be removed in [mins] minutes.")
@@ -1180,8 +1184,9 @@
AddBan(M.ckey, M.computer_id, reason, usr.ckey, 0, 0)
to_chat(M, "You have been banned by [usr.client.ckey].\nReason: [reason] ")
to_chat(M, "This is a permanent ban. ")
- if(config.banappeals)
- to_chat(M, "To try to resolve this matter head to [config.banappeals] ")
+ var/bran = CONFIG_GET(string/banappeals)
+ if(bran)
+ to_chat(M, "To try to resolve this matter head to [bran] ")
else
to_chat(M, "No ban appeals URL has been set. ")
if(!DB_ban_record(BANTYPE_PERMA, M, -1, reason))
diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm
index 7922a89c80..c9784dcf18 100644
--- a/code/modules/admin/verbs/adminhelp.dm
+++ b/code/modules/admin/verbs/adminhelp.dm
@@ -242,7 +242,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
/datum/admin_help/proc/LinkedReplyName(ref_src)
if(!ref_src)
ref_src = "\ref[src]"
- return "[initiator_key_name] "
+ return "[initiator_key_name] "
//private
/datum/admin_help/proc/TicketHref(msg, ref_src, action = "ticket")
@@ -587,21 +587,20 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
/proc/send2irc(msg,msg2)
- if(world.RunningService())
- world.ExportService("[SERVICE_REQUEST_IRC_ADMIN_CHANNEL_MESSAGE] [msg] | [msg2]")
- else if(config.useircbot)
- shell("python nudge.py [msg] [msg2]")
+ if(SERVER_TOOLS_PRESENT)
+ SERVER_TOOLS_RELAY_BROADCAST("[msg] | [msg2]")
/proc/send2otherserver(source,msg,type = "Ahelp")
- if(config.cross_allowed)
+ var/comms_key = CONFIG_GET(string/comms_key)
+ if(comms_key)
var/list/message = list()
message["message_sender"] = source
message["message"] = msg
- message["source"] = "([config.cross_name])"
- message["key"] = global.comms_key
+ message["source"] = "([CONFIG_GET(string/cross_comms_name)])"
+ message["key"] = comms_key
message["crossmessage"] = type
- world.Export("[config.cross_address]?[list2params(message)]")
+ world.Export("[CONFIG_GET(string/cross_server_address)]?[list2params(message)]")
/proc/ircadminwho()
diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm
index db29021463..038e454a24 100644
--- a/code/modules/admin/verbs/adminpm.dm
+++ b/code/modules/admin/verbs/adminpm.dm
@@ -185,7 +185,7 @@
SEND_SOUND(recipient, sound('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)
+ if(CONFIG_GET(flag/popup_admin_pm))
spawn() //so we don't hold the caller proc up
var/sender = src
var/sendername = key
@@ -277,7 +277,7 @@
return "Error: Ticket could not be found"
var/static/stealthkey
- var/adminname = config.showircname ? irc_tagged : "Administrator"
+ var/adminname = CONFIG_GET(flag/show_irc_name) ? irc_tagged : "Administrator"
if(!C)
return "Error: No client"
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index cb5ce19d68..cff80e6117 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -845,11 +845,11 @@ GLOBAL_PROTECT(LastAdminCalledProc)
if(!holder)
return
- global.medals_enabled = !global.medals_enabled
+ GLOB.medals_enabled = !GLOB.medals_enabled
- message_admins("[key_name_admin(src)] [global.medals_enabled ? "disabled" : "enabled"] the medal hub lockout. ")
+ message_admins("[key_name_admin(src)] [GLOB.medals_enabled ? "disabled" : "enabled"] the medal hub lockout. ")
SSblackbox.add_details("admin_verb","Toggle Medal Disable") // If...
- log_admin("[key_name(src)] [global.medals_enabled ? "disabled" : "enabled"] the medal hub lockout.")
+ log_admin("[key_name(src)] [GLOB.medals_enabled ? "disabled" : "enabled"] the medal hub lockout.")
/client/proc/view_runtimes()
set category = "Debug"
diff --git a/code/modules/admin/verbs/fps.dm b/code/modules/admin/verbs/fps.dm
index bedcd0a6e5..f893c43e08 100644
--- a/code/modules/admin/verbs/fps.dm
+++ b/code/modules/admin/verbs/fps.dm
@@ -7,13 +7,14 @@
if(!check_rights(R_DEBUG))
return
- var/new_fps = round(input("Sets game frames-per-second. Can potentially break the game (default: [config.fps])","FPS", world.fps) as num|null)
+ var/cfg_fps = CONFIG_GET(number/fps)
+ var/new_fps = round(input("Sets game frames-per-second. Can potentially break the game (default: [cfg_fps])","FPS", world.fps) as num|null)
if(new_fps <= 0)
to_chat(src, "Error: set_server_fps(): Invalid world.fps value. No changes made. ")
return
- if(new_fps > config.fps*1.5)
- if(alert(src, "You are setting fps to a high value:\n\t[new_fps] frames-per-second\n\tconfig.fps = [config.fps]","Warning!","Confirm","ABORT-ABORT-ABORT") != "Confirm")
+ if(new_fps > cfg_fps * 1.5)
+ if(alert(src, "You are setting fps to a high value:\n\t[new_fps] frames-per-second\n\tconfig.fps = [cfg_fps]","Warning!","Confirm","ABORT-ABORT-ABORT") != "Confirm")
return
var/msg = "[key_name(src)] has modified world.fps to [new_fps]"
@@ -21,4 +22,5 @@
message_admins(msg, 0)
SSblackbox.add_details("admin_toggle","Set Server FPS|[new_fps]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ CONFIG_SET(number/fps, new_fps)
world.fps = new_fps
diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm
index e8ba7c8bab..3021f9badd 100644
--- a/code/modules/admin/verbs/one_click_antag.dm
+++ b/code/modules/admin/verbs/one_click_antag.dm
@@ -28,27 +28,39 @@
popup.set_content(dat)
popup.open()
+/datum/admins/proc/isReadytoRumble(mob/living/carbon/human/applicant, targetrole, onstation = TRUE, conscious = TRUE)
+ if(applicant.mind.special_role)
+ return FALSE
+ if(!(targetrole in applicant.client.prefs.be_special))
+ return FALSE
+ if(onstation)
+ var/turf/T = get_turf(applicant)
+ if(!(T.z in GLOB.station_z_levels))
+ return FALSE
+ if(conscious && applicant.stat) //incase you don't care about a certain antag being unconcious when made, ie if they have selfhealing abilities.
+ return FALSE
+ if(!considered_alive(applicant.mind) || considered_afk(applicant.mind)) //makes sure the player isn't a zombie, brain, or just afk all together
+ return FALSE
+ return (!jobban_isbanned(applicant, targetrole) && !jobban_isbanned(applicant, "Syndicate"))
+
+
/datum/admins/proc/makeTraitors()
var/datum/game_mode/traitor/temp = new
- if(config.protect_roles_from_antagonist)
+ if(CONFIG_GET(flag/protect_roles_from_antagonist))
temp.restricted_jobs += temp.protected_jobs
- if(config.protect_assistant_from_antagonist)
+ if(CONFIG_GET(flag/protect_assistant_from_antagonist))
temp.restricted_jobs += "Assistant"
var/list/mob/living/carbon/human/candidates = list()
var/mob/living/carbon/human/H = null
for(var/mob/living/carbon/human/applicant in GLOB.player_list)
- if(ROLE_TRAITOR in applicant.client.prefs.be_special)
- if(!applicant.stat)
- if(applicant.mind)
- if (!applicant.mind.special_role)
- if(!jobban_isbanned(applicant, ROLE_TRAITOR) && !jobban_isbanned(applicant, "Syndicate"))
- if(temp.age_check(applicant.client))
- if(!(applicant.job in temp.restricted_jobs))
- candidates += applicant
+ if(isReadytoRumble(applicant, ROLE_TRAITOR, FALSE))
+ if(temp.age_check(applicant.client))
+ if(!(applicant.job in temp.restricted_jobs))
+ candidates += applicant
if(candidates.len)
var/numTraitors = min(candidates.len, 3)
@@ -67,23 +79,20 @@
/datum/admins/proc/makeChanglings()
var/datum/game_mode/changeling/temp = new
- if(config.protect_roles_from_antagonist)
+ if(CONFIG_GET(flag/protect_roles_from_antagonist))
temp.restricted_jobs += temp.protected_jobs
- if(config.protect_assistant_from_antagonist)
+ if(CONFIG_GET(flag/protect_assistant_from_antagonist))
temp.restricted_jobs += "Assistant"
var/list/mob/living/carbon/human/candidates = list()
var/mob/living/carbon/human/H = null
for(var/mob/living/carbon/human/applicant in GLOB.player_list)
- if(ROLE_CHANGELING in applicant.client.prefs.be_special)
- var/turf/T = get_turf(applicant)
- if(applicant.stat == CONSCIOUS && applicant.mind && !applicant.mind.special_role && (T.z in GLOB.station_z_levels))
- if(!jobban_isbanned(applicant, ROLE_CHANGELING) && !jobban_isbanned(applicant, "Syndicate"))
- if(temp.age_check(applicant.client))
- if(!(applicant.job in temp.restricted_jobs))
- candidates += applicant
+ if(isReadytoRumble(applicant, ROLE_CHANGELING))
+ if(temp.age_check(applicant.client))
+ if(!(applicant.job in temp.restricted_jobs))
+ candidates += applicant
if(candidates.len)
var/numChanglings = min(candidates.len, 3)
@@ -100,23 +109,20 @@
/datum/admins/proc/makeRevs()
var/datum/game_mode/revolution/temp = new
- if(config.protect_roles_from_antagonist)
+ if(CONFIG_GET(flag/protect_roles_from_antagonist))
temp.restricted_jobs += temp.protected_jobs
- if(config.protect_assistant_from_antagonist)
+ if(CONFIG_GET(flag/protect_assistant_from_antagonist))
temp.restricted_jobs += "Assistant"
var/list/mob/living/carbon/human/candidates = list()
var/mob/living/carbon/human/H = null
for(var/mob/living/carbon/human/applicant in GLOB.player_list)
- if(ROLE_REV in applicant.client.prefs.be_special)
- var/turf/T = get_turf(applicant)
- if(applicant.stat == CONSCIOUS && applicant.mind && !applicant.mind.special_role && (T.z in GLOB.station_z_levels))
- if(!jobban_isbanned(applicant, ROLE_REV) && !jobban_isbanned(applicant, "Syndicate"))
- if(temp.age_check(applicant.client))
- if(!(applicant.job in temp.restricted_jobs))
- candidates += applicant
+ if(isReadytoRumble(applicant, ROLE_REV))
+ if(temp.age_check(applicant.client))
+ if(!(applicant.job in temp.restricted_jobs))
+ candidates += applicant
if(candidates.len)
var/numRevs = min(candidates.len, 3)
@@ -142,23 +148,20 @@
/datum/admins/proc/makeCult()
var/datum/game_mode/cult/temp = new
- if(config.protect_roles_from_antagonist)
+ if(CONFIG_GET(flag/protect_roles_from_antagonist))
temp.restricted_jobs += temp.protected_jobs
- if(config.protect_assistant_from_antagonist)
+ if(CONFIG_GET(flag/protect_assistant_from_antagonist))
temp.restricted_jobs += "Assistant"
var/list/mob/living/carbon/human/candidates = list()
var/mob/living/carbon/human/H = null
for(var/mob/living/carbon/human/applicant in GLOB.player_list)
- if(ROLE_CULTIST in applicant.client.prefs.be_special)
- var/turf/T = get_turf(applicant)
- if(applicant.stat == CONSCIOUS && applicant.mind && !applicant.mind.special_role && (T.z in GLOB.station_z_levels))
- if(!jobban_isbanned(applicant, ROLE_CULTIST) && !jobban_isbanned(applicant, "Syndicate"))
- if(temp.age_check(applicant.client))
- if(!(applicant.job in temp.restricted_jobs))
- candidates += applicant
+ if(isReadytoRumble(applicant, ROLE_CULTIST))
+ if(temp.age_check(applicant.client))
+ if(!(applicant.job in temp.restricted_jobs))
+ candidates += applicant
if(candidates.len)
var/numCultists = min(candidates.len, 4)
@@ -175,23 +178,20 @@
/datum/admins/proc/makeClockCult()
var/datum/game_mode/clockwork_cult/temp = new
- if(config.protect_roles_from_antagonist)
+ if(CONFIG_GET(flag/protect_roles_from_antagonist))
temp.restricted_jobs += temp.protected_jobs
- if(config.protect_assistant_from_antagonist)
+ if(CONFIG_GET(flag/protect_assistant_from_antagonist))
temp.restricted_jobs += "Assistant"
var/list/mob/living/carbon/human/candidates = list()
var/mob/living/carbon/human/H = null
for(var/mob/living/carbon/human/applicant in GLOB.player_list)
- if(ROLE_SERVANT_OF_RATVAR in applicant.client.prefs.be_special)
- var/turf/T = get_turf(applicant)
- if(applicant.stat == CONSCIOUS && applicant.mind && !applicant.mind.special_role && (T.z in GLOB.station_z_levels))
- if(!jobban_isbanned(applicant, ROLE_SERVANT_OF_RATVAR) && !jobban_isbanned(applicant, "Syndicate"))
- if(temp.age_check(applicant.client))
- if(!(applicant.job in temp.restricted_jobs))
- candidates += applicant
+ if(isReadytoRumble(applicant, ROLE_SERVANT_OF_RATVAR))
+ if(temp.age_check(applicant.client))
+ if(!(applicant.job in temp.restricted_jobs))
+ candidates += applicant
if(candidates.len)
var/numCultists = min(candidates.len, 4)
@@ -340,7 +340,7 @@
missiondesc += "Your Mission : [mission]"
to_chat(Commando, missiondesc)
- if(config.enforce_human_authority)
+ if(CONFIG_GET(flag/enforce_human_authority))
Commando.set_species(/datum/species/human)
//Logging and cleanup
@@ -382,7 +382,7 @@
missionobj.completed = 1
newmob.mind.objectives += missionobj
- if(config.enforce_human_authority)
+ if(CONFIG_GET(flag/enforce_human_authority))
newmob.set_species(/datum/species/human)
//Greet the official
@@ -497,7 +497,7 @@
missiondesc += "Your Mission : [mission]"
to_chat(ERTOperative, missiondesc)
- if(config.enforce_human_authority)
+ if(CONFIG_GET(flag/enforce_human_authority))
ERTOperative.set_species(/datum/species/human)
//Logging and cleanup
diff --git a/code/modules/admin/verbs/panicbunker.dm b/code/modules/admin/verbs/panicbunker.dm
index 3da486be78..b159445963 100644
--- a/code/modules/admin/verbs/panicbunker.dm
+++ b/code/modules/admin/verbs/panicbunker.dm
@@ -1,15 +1,16 @@
/client/proc/panicbunker()
set category = "Server"
set name = "Toggle Panic Bunker"
- if (!config.sql_enabled)
+ if (!CONFIG_GET(flag/sql_enabled))
to_chat(usr, "The Database is not enabled! ")
return
- config.panic_bunker = (!config.panic_bunker)
+ var/new_pb = !CONFIG_GET(flag/panic_bunker)
+ CONFIG_SET(flag/panic_bunker, new_pb)
- log_admin("[key_name(usr)] has toggled the Panic Bunker, it is now [(config.panic_bunker?"on":"off")]")
- message_admins("[key_name_admin(usr)] has toggled the Panic Bunker, it is now [(config.panic_bunker?"enabled":"disabled")].")
- if (config.panic_bunker && (!SSdbcore || !SSdbcore.IsConnected()))
+ log_admin("[key_name(usr)] has toggled the Panic Bunker, it is now [new_pb ? "on" : "off"]")
+ message_admins("[key_name_admin(usr)] has toggled the Panic Bunker, it is now [new_pb ? "enabled" : "disabled"].")
+ if (new_pb && !SSdbcore.Connect())
message_admins("The Database is not connected! Panic bunker will not work until the connection is reestablished.")
- SSblackbox.add_details("admin_toggle","Toggle Panic Bunker|[config.panic_bunker]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ SSblackbox.add_details("admin_toggle","Toggle Panic Bunker|[new_pb]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/admin/verbs/playsound.dm b/code/modules/admin/verbs/playsound.dm
index 61df0cb8d1..0cc1f72256 100644
--- a/code/modules/admin/verbs/playsound.dm
+++ b/code/modules/admin/verbs/playsound.dm
@@ -62,7 +62,8 @@
if(!check_rights(R_SOUNDS))
return
- if(!config.invoke_youtubedl)
+ var/ytdl = CONFIG_GET(string/invoke_youtubedl)
+ if(!ytdl)
to_chat(src, "Youtube-dl was not configured, action unavailable ") //Check config.txt for the INVOKE_YOUTUBEDL value
return
@@ -79,7 +80,7 @@
to_chat(src, "For youtube-dl shortcuts like ytsearch: please use the appropriate full url from the website. ")
return
var/shell_scrubbed_input = shell_url_scrub(web_sound_input)
- var/list/output = world.shelleo("[config.invoke_youtubedl] --format \"bestaudio\[ext=mp3]/best\[ext=mp4]\[height<=360]/bestaudio\[ext=m4a]/bestaudio\[ext=aac]\" --get-url \"[shell_scrubbed_input]\"")
+ var/list/output = world.shelleo("[ytdl] --format \"bestaudio\[ext=mp3]/best\[ext=mp4]\[height<=360]/bestaudio\[ext=m4a]/bestaudio\[ext=aac]\" --get-url \"[shell_scrubbed_input]\"")
var/errorlevel = output[SHELLEO_ERRORLEVEL]
var/stdout = output[SHELLEO_STDOUT]
var/stderr = output[SHELLEO_STDERR]
@@ -91,8 +92,7 @@
if(SSevents.holidays && SSevents.holidays[APRIL_FOOLS])
pitch = pick(0.5, 0.7, 0.8, 0.85, 0.9, 0.95, 1.1, 1.2, 1.4, 1.6, 2.0, 2.5)
to_chat(src, "You feel the Honkmother messing with your song...")
-
- SSblackbox.add_details("played_url", web_sound_input)
+ SSblackbox.add_details("played_url", "[web_sound_input]|[ckey]")
log_admin("[key_name(src)] played web sound: [web_sound_input]")
message_admins("[key_name(src)] played web sound: [web_sound_input]")
else
diff --git a/code/modules/admin/verbs/possess.dm b/code/modules/admin/verbs/possess.dm
index e271cdb3a7..483c9470a2 100644
--- a/code/modules/admin/verbs/possess.dm
+++ b/code/modules/admin/verbs/possess.dm
@@ -2,7 +2,7 @@
set name = "Possess Obj"
set category = "Object"
- if(O.dangerous_possession && config.forbid_singulo_possession)
+ if(O.dangerous_possession && CONFIG_GET(flag/forbid_singulo_possession))
to_chat(usr, "[O] is too powerful for you to possess.")
return
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index 975e8aa731..e354d26ab0 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -1,1259 +1,1259 @@
-/client/proc/cmd_admin_drop_everything(mob/M in GLOB.mob_list)
- set category = null
- set name = "Drop Everything"
- if(!holder)
- to_chat(src, "Only administrators may use this command.")
- return
-
- var/confirm = alert(src, "Make [M] drop everything?", "Message", "Yes", "No")
- if(confirm != "Yes")
- return
-
- for(var/obj/item/W in M)
- if(!M.dropItemToGround(W))
- qdel(W)
- M.regenerate_icons()
-
- log_admin("[key_name(usr)] made [key_name(M)] drop everything!")
- var/msg = "[key_name_admin(usr)] made [key_name_admin(M)] drop everything!"
- message_admins(msg)
- admin_ticket_log(M, msg)
- SSblackbox.add_details("admin_verb","Drop Everything") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/cmd_admin_subtle_message(mob/M in GLOB.mob_list)
- set category = "Special Verbs"
- set name = "Subtle Message"
-
- if(!ismob(M))
- return
- if (!holder)
- to_chat(src, "Only administrators may use this command.")
- return
-
- message_admins("[key_name_admin(src)] has started answering [key_name(M.key, 0, 0)]'s prayer.")
- var/msg = input("Message:", text("Subtle PM to [M.key]")) as text
-
- if (!msg)
- message_admins("[key_name_admin(src)] decided not to answer [key_name(M.key, 0, 0)]'s prayer")
- return
- if(usr)
- if (usr.client)
- if(usr.client.holder)
- to_chat(M, "You hear a voice in your head... [msg] ")
-
- log_admin("SubtlePM: [key_name(usr)] -> [key_name(M)] : [msg]")
- msg = " SubtleMessage: [key_name_admin(usr)] -> [key_name_admin(M)] : [msg] "
- message_admins(msg)
- admin_ticket_log(M, msg)
- SSblackbox.add_details("admin_verb","Subtle Message") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/cmd_admin_world_narrate()
- set category = "Special Verbs"
- set name = "Global Narrate"
-
- if (!holder)
- to_chat(src, "Only administrators may use this command.")
- return
-
- var/msg = input("Message:", text("Enter the text you wish to appear to everyone:")) as text
-
- if (!msg)
- return
- to_chat(world, "[msg]")
- log_admin("GlobalNarrate: [key_name(usr)] : [msg]")
- message_admins("[key_name_admin(usr)] Sent a global narrate ")
- SSblackbox.add_details("admin_verb","Global Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/cmd_admin_direct_narrate(mob/M)
- set category = "Special Verbs"
- set name = "Direct Narrate"
-
- if(!holder)
- to_chat(src, "Only administrators may use this command.")
- return
-
- if(!M)
- M = input("Direct narrate to whom?", "Active Players") as null|anything in GLOB.player_list
-
- if(!M)
- return
-
- var/msg = input("Message:", text("Enter the text you wish to appear to your target:")) as text
-
- if( !msg )
- return
-
- to_chat(M, msg)
- log_admin("DirectNarrate: [key_name(usr)] to ([M.name]/[M.key]): [msg]")
- msg = " DirectNarrate: [key_name(usr)] to ([M.name]/[M.key]): [msg] "
- message_admins(msg)
- admin_ticket_log(M, msg)
- SSblackbox.add_details("admin_verb","Direct Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/cmd_admin_local_narrate(atom/A)
- set category = "Special Verbs"
- set name = "Local Narrate"
-
- if (!holder)
- to_chat(src, "Only administrators may use this command.")
- return
- if(!A)
- return
- var/range = input("Range:", "Narrate to mobs within how many tiles:", 7) as num
- if(!range)
- return
- var/msg = input("Message:", text("Enter the text you wish to appear to everyone within view:")) as text
- if (!msg)
- return
- for(var/mob/M in view(range,A))
- to_chat(M, msg)
-
- log_admin("LocalNarrate: [key_name(usr)] at [get_area(A)][COORD(A)]: [msg]")
- message_admins(" LocalNarrate: [key_name_admin(usr)] at [get_area(A)][ADMIN_JMP(A)]: [msg] ")
- SSblackbox.add_details("admin_verb","Local Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/cmd_admin_godmode(mob/M in GLOB.mob_list)
- set category = "Special Verbs"
- set name = "Godmode"
- if(!holder)
- to_chat(src, "Only administrators may use this command.")
- return
- M.status_flags ^= GODMODE
- to_chat(usr, "Toggled [(M.status_flags & GODMODE) ? "ON" : "OFF"] ")
-
- log_admin("[key_name(usr)] has toggled [key_name(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]")
- var/msg = "[key_name_admin(usr)] has toggled [key_name_admin(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]"
- message_admins(msg)
- admin_ticket_log(M, msg)
- SSblackbox.add_details("admin_toggle","Godmode|[M.status_flags & GODMODE]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-
-/proc/cmd_admin_mute(whom, mute_type, automute = 0)
- if(!whom)
- return
-
- var/muteunmute
- var/mute_string
- var/feedback_string
- switch(mute_type)
- if(MUTE_IC)
- mute_string = "IC (say and emote)"
- feedback_string = "IC"
- if(MUTE_OOC)
- mute_string = "OOC"
- feedback_string = "OOC"
- if(MUTE_PRAY)
- mute_string = "pray"
- feedback_string = "Pray"
- if(MUTE_ADMINHELP)
- mute_string = "adminhelp, admin PM and ASAY"
- feedback_string = "Adminhelp"
- if(MUTE_DEADCHAT)
- mute_string = "deadchat and DSAY"
- feedback_string = "Deadchat"
- if(MUTE_ALL)
- mute_string = "everything"
- feedback_string = "Everything"
- else
- return
-
- var/client/C
- if(istype(whom, /client))
- C = whom
- else if(istext(whom))
- C = GLOB.directory[whom]
- else
- return
-
- var/datum/preferences/P
- if(C)
- P = C.prefs
- else
- P = GLOB.preferences_datums[whom]
- if(!P)
- return
-
- if(automute)
- if(!config.automute_on)
- return
- else
- if(!check_rights())
- return
-
- if(automute)
- muteunmute = "auto-muted"
- P.muted |= mute_type
- log_admin("SPAM AUTOMUTE: [muteunmute] [key_name(whom)] from [mute_string]")
- message_admins("SPAM AUTOMUTE: [muteunmute] [key_name_admin(whom)] from [mute_string].")
- if(C)
- to_chat(C, "You have been [muteunmute] from [mute_string] by the SPAM AUTOMUTE system. Contact an admin.")
- SSblackbox.add_details("admin_toggle","Auto Mute [feedback_string]|1") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
- return
-
- if(P.muted & mute_type)
- muteunmute = "unmuted"
- P.muted &= ~mute_type
- else
- muteunmute = "muted"
- P.muted |= mute_type
-
- log_admin("[key_name(usr)] has [muteunmute] [key_name(whom)] from [mute_string]")
- message_admins("[key_name_admin(usr)] has [muteunmute] [key_name_admin(whom)] from [mute_string].")
- if(C)
- to_chat(C, "You have been [muteunmute] from [mute_string] by [key_name(usr, include_name = FALSE)].")
- SSblackbox.add_details("admin_toggle","Mute [feedback_string]|[P.muted & mute_type]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-
-//I use this proc for respawn character too. /N
-/proc/create_xeno(ckey)
- if(!ckey)
- var/list/candidates = list()
- for(var/mob/M in GLOB.player_list)
- if(M.stat != DEAD)
- continue //we are not dead!
- if(!(ROLE_ALIEN in M.client.prefs.be_special))
- continue //we don't want to be an alium
- if(M.client.is_afk())
- continue //we are afk
- if(M.mind && M.mind.current && M.mind.current.stat != DEAD)
- continue //we have a live body we are tied to
- candidates += M.ckey
- if(candidates.len)
- ckey = input("Pick the player you want to respawn as a xeno.", "Suitable Candidates") as null|anything in candidates
- else
- to_chat(usr, "Error: create_xeno(): no suitable candidates. ")
- if(!istext(ckey))
- return 0
-
- var/alien_caste = input(usr, "Please choose which caste to spawn.","Pick a caste",null) as null|anything in list("Queen","Praetorian","Hunter","Sentinel","Drone","Larva")
- var/obj/effect/landmark/spawn_here = GLOB.xeno_spawn.len ? pick(GLOB.xeno_spawn) : null
- var/mob/living/carbon/alien/new_xeno
- switch(alien_caste)
- if("Queen")
- new_xeno = new /mob/living/carbon/alien/humanoid/royal/queen(spawn_here)
- if("Praetorian")
- new_xeno = new /mob/living/carbon/alien/humanoid/royal/praetorian(spawn_here)
- if("Hunter")
- new_xeno = new /mob/living/carbon/alien/humanoid/hunter(spawn_here)
- if("Sentinel")
- new_xeno = new /mob/living/carbon/alien/humanoid/sentinel(spawn_here)
- if("Drone")
- new_xeno = new /mob/living/carbon/alien/humanoid/drone(spawn_here)
- if("Larva")
- new_xeno = new /mob/living/carbon/alien/larva(spawn_here)
- else
- return 0
- if(!spawn_here)
- SSjob.SendToLateJoin(new_xeno, FALSE)
-
- new_xeno.ckey = ckey
- var/msg = "[key_name_admin(usr)] has spawned [ckey] as a filthy xeno [alien_caste]. "
- message_admins(msg)
- admin_ticket_log(new_xeno, msg)
- return 1
-
-/*
-If a guy was gibbed and you want to revive him, this is a good way to do so.
-Works kind of like entering the game with a new character. Character receives a new mind if they didn't have one.
-Traitors and the like can also be revived with the previous role mostly intact.
-/N */
-/client/proc/respawn_character()
- set category = "Special Verbs"
- set name = "Respawn Character"
- set desc = "Respawn a person that has been gibbed/dusted/killed. They must be a ghost for this to work and preferably should not have a body to go back into."
- if(!holder)
- to_chat(src, "Only administrators may use this command.")
- return
- var/input = ckey(input(src, "Please specify which key will be respawned.", "Key", ""))
- if(!input)
- return
-
- var/mob/dead/observer/G_found
- for(var/mob/dead/observer/G in GLOB.player_list)
- if(G.ckey == input)
- G_found = G
- break
-
- if(!G_found)//If a ghost was not found.
- to_chat(usr, "There is no active key like that in the game or the person is not currently a ghost. ")
- return
-
- if(G_found.mind && !G_found.mind.active) //mind isn't currently in use by someone/something
- //Check if they were an alien
- if(G_found.mind.assigned_role=="Alien")
- if(alert("This character appears to have been an alien. Would you like to respawn them as such?",,"Yes","No")=="Yes")
- var/turf/T
- if(GLOB.xeno_spawn.len)
- T = pick(GLOB.xeno_spawn)
-
- var/mob/living/carbon/alien/new_xeno
- switch(G_found.mind.special_role)//If they have a mind, we can determine which caste they were.
- if("Hunter")
- new_xeno = new /mob/living/carbon/alien/humanoid/hunter(T)
- if("Sentinel")
- new_xeno = new /mob/living/carbon/alien/humanoid/sentinel(T)
- if("Drone")
- new_xeno = new /mob/living/carbon/alien/humanoid/drone(T)
- if("Praetorian")
- new_xeno = new /mob/living/carbon/alien/humanoid/royal/praetorian(T)
- if("Queen")
- new_xeno = new /mob/living/carbon/alien/humanoid/royal/queen(T)
- else//If we don't know what special role they have, for whatever reason, or they're a larva.
- create_xeno(G_found.ckey)
- return
-
- if(!T)
- SSjob.SendToLateJoin(new_xeno, FALSE)
-
- //Now to give them their mind back.
- G_found.mind.transfer_to(new_xeno) //be careful when doing stuff like this! I've already checked the mind isn't in use
- new_xeno.key = G_found.key
- to_chat(new_xeno, "You have been fully respawned. Enjoy the game.")
- var/msg = "[key_name_admin(usr)] has respawned [new_xeno.key] as a filthy xeno. "
- message_admins(msg)
- admin_ticket_log(new_xeno, msg)
- return //all done. The ghost is auto-deleted
-
- //check if they were a monkey
- else if(findtext(G_found.real_name,"monkey"))
- if(alert("This character appears to have been a monkey. Would you like to respawn them as such?",,"Yes","No")=="Yes")
- var/mob/living/carbon/monkey/new_monkey = new
- SSjob.SendToLateJoin(new_monkey)
- G_found.mind.transfer_to(new_monkey) //be careful when doing stuff like this! I've already checked the mind isn't in use
- new_monkey.key = G_found.key
- to_chat(new_monkey, "You have been fully respawned. Enjoy the game.")
- var/msg = "[key_name_admin(usr)] has respawned [new_monkey.key] as a filthy xeno. "
- message_admins(msg)
- admin_ticket_log(new_monkey, msg)
- return //all done. The ghost is auto-deleted
-
-
- //Ok, it's not a xeno or a monkey. So, spawn a human.
- var/mob/living/carbon/human/new_character = new//The mob being spawned.
- SSjob.SendToLateJoin(new_character)
-
- var/datum/data/record/record_found //Referenced to later to either randomize or not randomize the character.
- if(G_found.mind && !G_found.mind.active) //mind isn't currently in use by someone/something
- /*Try and locate a record for the person being respawned through GLOB.data_core.
- This isn't an exact science but it does the trick more often than not.*/
- var/id = md5("[G_found.real_name][G_found.mind.assigned_role]")
-
- record_found = find_record("id", id, GLOB.data_core.locked)
-
- 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.age = record_found.fields["age"]
- new_character.hardset_dna(record_found.fields["identity"], record_found.fields["enzymes"], record_found.fields["name"], record_found.fields["blood_type"], record_found.fields["species"], record_found.fields["features"])
- else
- var/datum/preferences/A = new()
- A.copy_to(new_character)
- A.real_name = G_found.real_name
- new_character.dna.update_dna_identity()
-
- new_character.name = new_character.real_name
-
- if(G_found.mind && !G_found.mind.active)
- G_found.mind.transfer_to(new_character) //be careful when doing stuff like this! I've already checked the mind isn't in use
- else
- new_character.mind_initialize()
- if(!new_character.mind.assigned_role)
- new_character.mind.assigned_role = "Assistant"//If they somehow got a null assigned role.
-
- new_character.key = G_found.key
-
- /*
- The code below functions with the assumption that the mob is already a traitor if they have a special role.
- So all it does is re-equip the mob with powers and/or items. Or not, if they have no special role.
- If they don't have a mind, they obviously don't have a special role.
- */
-
- //Two variables to properly announce later on.
- var/admin = key_name_admin(src)
- var/player_key = G_found.key
-
- //Now for special roles and equipment.
- var/datum/antagonist/traitor/traitordatum = new_character.mind.has_antag_datum(ANTAG_DATUM_TRAITOR)
- if(traitordatum)
- SSjob.EquipRank(new_character, new_character.mind.assigned_role, 1)
- traitordatum.equip()
-
-
- switch(new_character.mind.special_role)
- if("Wizard")
- new_character.loc = pick(GLOB.wizardstart)
- //SSticker.mode.learn_basic_spells(new_character)
- SSticker.mode.equip_wizard(new_character)
- if("Syndicate")
- var/obj/effect/landmark/synd_spawn = locate("landmark*Syndicate-Spawn")
- if(synd_spawn)
- new_character.loc = get_turf(synd_spawn)
- call(/datum/game_mode/proc/equip_syndicate)(new_character)
- if("Space Ninja")
- var/list/ninja_spawn = list()
- for(var/obj/effect/landmark/L in GLOB.landmarks_list)
- if(L.name=="carpspawn")
- ninja_spawn += L
- var/datum/antagonist/ninja/ninjadatum = new_character.mind.has_antag_datum(ANTAG_DATUM_NINJA)
- ninjadatum.equip_space_ninja()
- if(ninja_spawn.len)
- var/obj/effect/landmark/ninja_spawn_here = pick(ninja_spawn)
- new_character.loc = ninja_spawn_here.loc
-
- else//They may also be a cyborg or AI.
- switch(new_character.mind.assigned_role)
- if("Cyborg")//More rigging to make em' work and check if they're traitor.
- new_character = new_character.Robotize()
- if("AI")
- new_character = new_character.AIize()
- else
- SSjob.EquipRank(new_character, new_character.mind.assigned_role, 1)//Or we simply equip them.
-
- //Announces the character on all the systems, based on the record.
- if(!issilicon(new_character))//If they are not a cyborg/AI.
- if(!record_found&&new_character.mind.assigned_role!=new_character.mind.special_role)//If there are no records for them. If they have a record, this info is already in there. MODE people are not announced anyway.
- //Power to the user!
- if(alert(new_character,"Warning: No data core entry detected. Would you like to announce the arrival of this character by adding them to various databases, such as medical records?",,"No","Yes")=="Yes")
- GLOB.data_core.manifest_inject(new_character)
-
- if(alert(new_character,"Would you like an active AI to announce this character?",,"No","Yes")=="Yes")
- AnnounceArrival(new_character, new_character.mind.assigned_role)
-
- var/msg = "[admin] has respawned [player_key] as [new_character.real_name]. "
- message_admins(msg)
- admin_ticket_log(new_character, msg)
-
- to_chat(new_character, "You have been fully respawned. Enjoy the game.")
-
- SSblackbox.add_details("admin_verb","Respawn Character") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
- return new_character
-
-/client/proc/cmd_admin_add_freeform_ai_law()
- set category = "Fun"
- set name = "Add Custom AI law"
- if(!holder)
- to_chat(src, "Only administrators may use this command.")
- return
- var/input = input(usr, "Please enter anything you want the AI to do. Anything. Serious.", "What?", "") as text|null
- if(!input)
- return
-
- log_admin("Admin [key_name(usr)] has added a new AI law - [input]")
- message_admins("Admin [key_name_admin(usr)] has added a new AI law - [input]")
-
- var/show_log = alert(src, "Show ion message?", "Message", "Yes", "No")
- var/announce_ion_laws = (show_log == "Yes" ? 1 : -1)
-
- var/datum/round_event/ion_storm/add_law_only/ion = new()
- ion.announceEvent = announce_ion_laws
- ion.ionMessage = input
-
- SSblackbox.add_details("admin_verb","Add Custom AI Law") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/cmd_admin_rejuvenate(mob/living/M in GLOB.mob_list)
- set category = "Special Verbs"
- set name = "Rejuvenate"
- if(!holder)
- to_chat(src, "Only administrators may use this command.")
- return
- if(!mob)
- return
- if(!istype(M))
- alert("Cannot revive a ghost")
- return
- M.revive(full_heal = 1, admin_revive = 1)
-
- log_admin("[key_name(usr)] healed / revived [key_name(M)]")
- var/msg = "Admin [key_name_admin(usr)] healed / revived [key_name_admin(M)]! "
- message_admins(msg)
- admin_ticket_log(M, msg)
- SSblackbox.add_details("admin_verb","Rejuvinate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/cmd_admin_create_centcom_report()
- set category = "Special Verbs"
- set name = "Create Command Report"
- if(!holder)
- to_chat(src, "Only administrators may use this command.")
- return
- var/input = input(usr, "Please enter anything you want. Anything. Serious.", "What?", "") as message|null
- if(!input)
- return
-
- var/confirm = alert(src, "Do you want to announce the contents of the report to the crew?", "Announce", "Yes", "No", "Cancel")
- var/announce_command_report = TRUE
- switch(confirm)
- if("Yes")
- priority_announce(input, null, 'sound/ai/commandreport.ogg')
- announce_command_report = FALSE
- if("Cancel")
- return
-
- print_command_report(input, "[announce_command_report ? "Classified " : ""][command_name()] Update", announce_command_report)
-
- log_admin("[key_name(src)] has created a command report: [input]")
- message_admins("[key_name_admin(src)] has created a command report")
- SSblackbox.add_details("admin_verb","Create Command Report") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/cmd_change_command_name()
- set category = "Special Verbs"
- set name = "Change Command Name"
- if(!holder)
- to_chat(src, "Only administrators may use this command.")
- return
- var/input = input(usr, "Please input a new name for Central Command.", "What?", "") as text|null
- if(!input)
- return
- change_command_name(input)
- message_admins("[key_name_admin(src)] has changed Central Command's name to [input]")
- log_admin("[key_name(src)] has changed the Central Command name to: [input]")
-
-/client/proc/cmd_admin_delete(atom/A as obj|mob|turf in world)
- set category = "Admin"
- set name = "Delete"
-
- if (!holder)
- to_chat(src, "Only administrators may use this command.")
- return
-
- admin_delete(A)
-
-/client/proc/admin_delete(datum/D)
- var/atom/A = D
- var/coords = istype(A) ? " at ([A.x], [A.y], [A.z])" : ""
- if (alert(src, "Are you sure you want to delete:\n[D]\nat[coords]?", "Confirmation", "Yes", "No") == "Yes")
- log_admin("[key_name(usr)] deleted [D][coords]")
- message_admins("[key_name_admin(usr)] deleted [D][coords]")
- SSblackbox.add_details("admin_verb","Delete") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
- if(isturf(D))
- var/turf/T = D
- T.ChangeTurf(T.baseturf)
- else
- qdel(D)
-
-/client/proc/cmd_admin_list_open_jobs()
- set category = "Admin"
- set name = "Manage Job Slots"
-
- if (!holder)
- to_chat(src, "Only administrators may use this command.")
- return
- holder.manage_free_slots()
- SSblackbox.add_details("admin_verb","Manage Job Slots") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/cmd_admin_explosion(atom/O as obj|mob|turf in world)
- set category = "Special Verbs"
- set name = "Explosion"
-
- if (!holder)
- to_chat(src, "Only administrators may use this command.")
- return
-
- var/devastation = input("Range of total devastation. -1 to none", text("Input")) as num|null
- if(devastation == null) return
- var/heavy = input("Range of heavy impact. -1 to none", text("Input")) as num|null
- if(heavy == null) return
- var/light = input("Range of light impact. -1 to none", text("Input")) as num|null
- if(light == null) return
- var/flash = input("Range of flash. -1 to none", text("Input")) as num|null
- if(flash == null) return
- var/flames = input("Range of flames. -1 to none", text("Input")) as num|null
- if(flames == null) return
-
- if ((devastation != -1) || (heavy != -1) || (light != -1) || (flash != -1) || (flames != -1))
- if ((devastation > 20) || (heavy > 20) || (light > 20) || (flames > 20))
- if (alert(src, "Are you sure you want to do this? It will laaag.", "Confirmation", "Yes", "No") == "No")
- return
-
- explosion(O, devastation, heavy, light, flash, null, null,flames)
- log_admin("[key_name(usr)] created an explosion ([devastation],[heavy],[light],[flames]) at ([O.x],[O.y],[O.z])")
- message_admins("[key_name_admin(usr)] created an explosion ([devastation],[heavy],[light],[flames]) at ([O.x],[O.y],[O.z])")
- SSblackbox.add_details("admin_verb","Explosion") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
- return
- else
- return
-
-/client/proc/cmd_admin_emp(atom/O as obj|mob|turf in world)
- set category = "Special Verbs"
- set name = "EM Pulse"
-
- if (!holder)
- to_chat(src, "Only administrators may use this command.")
- return
-
- var/heavy = input("Range of heavy pulse.", text("Input")) as num|null
- if(heavy == null) return
- var/light = input("Range of light pulse.", text("Input")) as num|null
- if(light == null) return
-
- if (heavy || light)
-
- empulse(O, heavy, light)
- log_admin("[key_name(usr)] created an EM Pulse ([heavy],[light]) at ([O.x],[O.y],[O.z])")
- message_admins("[key_name_admin(usr)] created an EM Pulse ([heavy],[light]) at ([O.x],[O.y],[O.z])")
- SSblackbox.add_details("admin_verb","EM Pulse") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
- return
- else
- return
-
-/client/proc/cmd_admin_gib(mob/M in GLOB.mob_list)
- set category = "Special Verbs"
- set name = "Gib"
-
- if (!holder)
- to_chat(src, "Only administrators may use this command.")
- return
-
- var/confirm = alert(src, "Drop a brain?", "Confirm", "Yes", "No","Cancel")
- if(confirm == "Cancel")
- return
- //Due to the delay here its easy for something to have happened to the mob
- if(!M)
- return
-
- log_admin("[key_name(usr)] has gibbed [key_name(M)]")
- message_admins("[key_name_admin(usr)] has gibbed [key_name_admin(M)]")
-
- if(isobserver(M))
- new /obj/effect/gibspawner/generic(get_turf(M))
- return
- if(confirm == "Yes")
- M.gib()
- else
- M.gib(1)
- SSblackbox.add_details("admin_verb","Gib") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/cmd_admin_gib_self()
- set name = "Gibself"
- set category = "Fun"
-
- var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
- if(confirm == "Yes")
- log_admin("[key_name(usr)] used gibself.")
- message_admins("[key_name_admin(usr)] used gibself. ")
- SSblackbox.add_details("admin_verb","Gib Self") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
- mob.gib(1, 1, 1)
-
-/client/proc/cmd_admin_check_contents(mob/living/M in GLOB.mob_list)
- set category = "Special Verbs"
- set name = "Check Contents"
-
- var/list/L = M.get_contents()
- for(var/t in L)
- to_chat(usr, "[t]")
- SSblackbox.add_details("admin_verb","Check Contents") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/toggle_view_range()
- set category = "Special Verbs"
- set name = "Change View Range"
- set desc = "switches between 1x and custom views"
-
- if(view == world.view)
- change_view(input("Select view range:", "FUCK YE", 7) in list(1,2,3,4,5,6,7,8,9,10,11,12,13,14,128))
- else
- change_view(world.view)
-
- log_admin("[key_name(usr)] changed their view range to [view].")
- //message_admins("\blue [key_name_admin(usr)] changed their view range to [view].") //why? removed by order of XSI
-
- SSblackbox.add_details("admin_toggle","Change View Range|[view]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/admin_call_shuttle()
-
- set category = "Admin"
- set name = "Call Shuttle"
-
- if(EMERGENCY_AT_LEAST_DOCKED)
- return
-
- if (!holder)
- to_chat(src, "Only administrators may use this command.")
- return
-
- var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
- if(confirm != "Yes")
- return
-
- SSshuttle.emergency.request()
- SSblackbox.add_details("admin_verb","Call Shuttle") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
- log_admin("[key_name(usr)] admin-called the emergency shuttle.")
- message_admins("[key_name_admin(usr)] admin-called the emergency shuttle. ")
- return
-
-/client/proc/admin_cancel_shuttle()
- set category = "Admin"
- set name = "Cancel Shuttle"
- if(!check_rights(0))
- return
- if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes")
- return
-
- if(EMERGENCY_AT_LEAST_DOCKED)
- return
-
- SSshuttle.emergency.cancel()
- SSblackbox.add_details("admin_verb","Cancel Shuttle") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
- log_admin("[key_name(usr)] admin-recalled the emergency shuttle.")
- message_admins("[key_name_admin(usr)] admin-recalled the emergency shuttle. ")
-
- return
-
-/client/proc/everyone_random()
- set category = "Fun"
- set name = "Make Everyone Random"
- set desc = "Make everyone have a random appearance. You can only use this before rounds!"
-
- if(SSticker.HasRoundStarted())
- to_chat(usr, "Nope you can't do this, the game's already started. This only works before rounds!")
- return
-
- if(config.force_random_names)
- config.force_random_names = 0
- message_admins("Admin [key_name_admin(usr)] has disabled \"Everyone is Special\" mode.")
- to_chat(usr, "Disabled.")
- return
-
-
- var/notifyplayers = alert(src, "Do you want to notify the players?", "Options", "Yes", "No", "Cancel")
- if(notifyplayers == "Cancel")
- return
-
- log_admin("Admin [key_name(src)] has forced the players to have random appearances.")
- message_admins("Admin [key_name_admin(usr)] has forced the players to have random appearances.")
-
- if(notifyplayers == "Yes")
- to_chat(world, "Admin [usr.key] has forced the players to have completely random identities! ")
-
- to_chat(usr, "Remember: you can always disable the randomness by using the verb again, assuming the round hasn't started yet .")
-
- config.force_random_names = 1
- SSblackbox.add_details("admin_verb","Make Everyone Random") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-
-/client/proc/toggle_random_events()
- set category = "Server"
- set name = "Toggle random events on/off"
- set desc = "Toggles random events such as meteors, black holes, blob (but not space dust) on/off"
- if(!config.allow_random_events)
- config.allow_random_events = 1
- to_chat(usr, "Random events enabled")
- message_admins("Admin [key_name_admin(usr)] has enabled random events.")
- else
- config.allow_random_events = 0
- to_chat(usr, "Random events disabled")
- message_admins("Admin [key_name_admin(usr)] has disabled random events.")
- SSblackbox.add_details("admin_toggle","Toggle Random Events|[config.allow_random_events]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-
-/client/proc/admin_change_sec_level()
- set category = "Special Verbs"
- set name = "Set Security Level"
- set desc = "Changes the security level. Announcement only, i.e. setting to Delta won't activate nuke"
-
- if (!holder)
- to_chat(src, "Only administrators may use this command.")
- return
-
- var/level = input("Select security level to change to","Set Security Level") as null|anything in list("green","blue","red","delta")
- if(level)
- set_security_level(level)
-
- log_admin("[key_name(usr)] changed the security level to [level]")
- message_admins("[key_name_admin(usr)] changed the security level to [level]")
- SSblackbox.add_details("admin_verb","Set Security Level [capitalize(level)]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/toggle_nuke(obj/machinery/nuclearbomb/N in GLOB.nuke_list)
- set name = "Toggle Nuke"
- set category = "Fun"
- set popup_menu = 0
- if(!check_rights(R_DEBUG))
- return
-
- if(!N.timing)
- var/newtime = input(usr, "Set activation timer.", "Activate Nuke", "[N.timer_set]") as num
- if(!newtime)
- return
- N.timer_set = newtime
- N.set_safety()
- N.set_active()
-
- log_admin("[key_name(usr)] [N.timing ? "activated" : "deactivated"] a nuke at ([N.x],[N.y],[N.z]).")
- message_admins("[ADMIN_LOOKUPFLW(usr)] [N.timing ? "activated" : "deactivated"] a nuke at [ADMIN_COORDJMP(N)].")
- SSblackbox.add_details("admin_toggle","Toggle Nuke|[N.timing]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
-
-/client/proc/create_outfits()
- set category = "Debug"
- set name = "Create Custom Outfit"
-
- if(!check_rights(R_DEBUG))
- return
-
- holder.create_outfit()
-
-/datum/admins/proc/create_outfit()
- var/list/uniforms = typesof(/obj/item/clothing/under)
- var/list/suits = typesof(/obj/item/clothing/suit)
- var/list/gloves = typesof(/obj/item/clothing/gloves)
- var/list/shoes = typesof(/obj/item/clothing/shoes)
- var/list/headwear = typesof(/obj/item/clothing/head)
- var/list/glasses = typesof(/obj/item/clothing/glasses)
- var/list/masks = typesof(/obj/item/clothing/mask)
- var/list/ids = typesof(/obj/item/card/id)
-
- var/uniform_select = "None "
- for(var/path in uniforms)
- uniform_select += "[path] "
- uniform_select += " "
-
- var/suit_select = "None "
- for(var/path in suits)
- suit_select += "[path] "
- suit_select += " "
-
- var/gloves_select = "None "
- for(var/path in gloves)
- gloves_select += "[path] "
- gloves_select += " "
-
- var/shoes_select = "None "
- for(var/path in shoes)
- shoes_select += "[path] "
- shoes_select += " "
-
- var/head_select = "None "
- for(var/path in headwear)
- head_select += "[path] "
- head_select += " "
-
- var/glasses_select = "None "
- for(var/path in glasses)
- glasses_select += "[path] "
- glasses_select += " "
-
- var/mask_select = "None "
- for(var/path in masks)
- mask_select += "[path] "
- mask_select += " "
-
- var/id_select = "None "
- for(var/path in ids)
- id_select += "[path] "
- id_select += " "
-
- var/dat = {"
- Create Outfit
-
- "}
- usr << browse(dat, "window=dressup;size=550x600")
-
-/client/proc/toggle_antag_hud()
- set category = "Admin"
- set name = "Toggle AntagHUD"
- set desc = "Toggles the Admin AntagHUD"
-
- if(!holder) return
-
- var/adding_hud = !has_antag_hud()
-
- for(var/datum/atom_hud/H in GLOB.huds)
- if(istype(H, /datum/atom_hud/antag))
- (adding_hud) ? H.add_hud_to(usr) : H.remove_hud_from(usr)
-
- to_chat(usr, "You toggled your admin antag HUD [adding_hud ? "ON" : "OFF"].")
- message_admins("[key_name_admin(usr)] toggled their admin antag HUD [adding_hud ? "ON" : "OFF"].")
- log_admin("[key_name(usr)] toggled their admin antag HUD [adding_hud ? "ON" : "OFF"].")
- SSblackbox.add_details("admin_toggle","Toggle Antag HUD|[adding_hud]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/has_antag_hud()
- var/datum/atom_hud/A = GLOB.huds[ANTAG_HUD_TRAITOR]
- return A.hudusers[mob]
-
-/client/proc/open_shuttle_manipulator()
- set category = "Admin"
- set name = "Shuttle Manipulator"
- set desc = "Opens the shuttle manipulator UI."
-
- for(var/obj/machinery/shuttle_manipulator/M in GLOB.machines)
- M.ui_interact(usr)
-
-/client/proc/mass_zombie_infection()
- set category = "Fun"
- set name = "Mass Zombie Infection"
- set desc = "Infects all humans with a latent organ that will zombify \
- them on death."
-
- if(!holder)
- return
-
- var/confirm = alert(src, "Please confirm you want to add latent zombie organs in all humans?", "Confirm Zombies", "Yes", "No")
- if(confirm != "Yes")
- return
-
- for(var/mob/living/carbon/human/H in GLOB.mob_list)
- new /obj/item/organ/zombie_infection(H)
-
- message_admins("[key_name_admin(usr)] added a latent zombie infection to all humans.")
- log_admin("[key_name(usr)] added a latent zombie infection to all humans.")
- SSblackbox.add_details("admin_verb","Mass Zombie Infection")
-
-/client/proc/mass_zombie_cure()
- set category = "Fun"
- set name = "Mass Zombie Cure"
- set desc = "Removes the zombie infection from all humans, returning them to normal."
- if(!holder)
- return
-
- var/confirm = alert(src, "Please confirm you want to cure all zombies?", "Confirm Zombie Cure", "Yes", "No")
- if(confirm != "Yes")
- return
-
- for(var/obj/item/organ/zombie_infection/I in GLOB.zombie_infection_list)
- qdel(I)
-
- message_admins("[key_name_admin(usr)] cured all zombies.")
- log_admin("[key_name(usr)] cured all zombies.")
- SSblackbox.add_details("admin_verb","Mass Zombie Cure")
-
-/client/proc/polymorph_all()
- set category = "Fun"
- set name = "Polymorph All"
- set desc = "Applies the effects of the bolt of change to every single mob."
-
- if(!holder)
- return
-
- var/confirm = alert(src, "Please confirm you want polymorph all mobs?", "Confirm Polymorph", "Yes", "No")
- if(confirm != "Yes")
- return
-
- var/list/mobs = shuffle(GLOB.living_mob_list.Copy()) // might change while iterating
- var/who_did_it = key_name_admin(usr)
-
- message_admins("[key_name_admin(usr)] started polymorphed all living mobs.")
- log_admin("[key_name(usr)] polymorphed all living mobs.")
- SSblackbox.add_details("admin_verb","Polymorph All")
-
- for(var/mob/living/M in mobs)
- CHECK_TICK
-
- if(!M)
- continue
-
- M.audible_message("...wabbajack...wabbajack... ")
- playsound(M.loc, 'sound/magic/staff_change.ogg', 50, 1, -1)
-
- wabbajack(M)
-
- message_admins("Mass polymorph started by [who_did_it] is complete.")
-
-
-/client/proc/show_tip()
- set category = "Admin"
- set name = "Show Tip"
- set desc = "Sends a tip (that you specify) to all players. After all \
- you're the experienced player here."
-
- if(!holder)
- return
-
- var/input = input(usr, "Please specify your tip that you want to send to the players.", "Tip", "") as message|null
- if(!input)
- return
-
- if(!SSticker)
- return
-
- SSticker.selected_tip = input
-
- // If we've already tipped, then send it straight away.
- if(SSticker.tipped)
- SSticker.send_tip_of_the_round()
-
-
- message_admins("[key_name_admin(usr)] sent a tip of the round.")
- log_admin("[key_name(usr)] sent \"[input]\" as the Tip of the Round.")
- SSblackbox.add_details("admin_verb","Show Tip")
-
-#define ON_PURRBATION(H) (!(H.dna.features["tail_human"] == "None" && H.dna.features["ears"] == "None"))
-
-/proc/mass_purrbation()
- for(var/M in GLOB.mob_list)
- if(ishumanbasic(M))
- purrbation_apply(M)
- CHECK_TICK
-
-/proc/mass_remove_purrbation()
- for(var/M in GLOB.mob_list)
- if(ishumanbasic(M))
- purrbation_remove(M)
- CHECK_TICK
-
-/proc/purrbation_toggle(mob/living/carbon/human/H)
- if(!ishumanbasic(H))
- return
- if(!ON_PURRBATION(H))
- purrbation_apply(H)
- . = TRUE
- else
- purrbation_remove(H)
- . = FALSE
-
-/proc/purrbation_apply(mob/living/carbon/human/H)
- if(!ishuman(H))
- return
- if(ON_PURRBATION(H))
- return
- to_chat(H, "Something is nya~t right.")
- H.dna.features["tail_human"] = "Cat"
- H.dna.features["ears"] = "Cat"
- H.regenerate_icons()
- playsound(get_turf(H), 'sound/effects/meow1.ogg', 50, 1, -1)
-
-/proc/purrbation_remove(mob/living/carbon/human/H)
- if(!ishuman(H))
- return
- if(!ON_PURRBATION(H))
- return
- to_chat(H, "You are no longer a cat.")
- H.dna.features["tail_human"] = "None"
- H.dna.features["ears"] = "None"
- H.regenerate_icons()
-
-#undef ON_PURRBATION
-
-/client/proc/modify_goals()
- set category = "Debug"
- set name = "Modify goals"
-
- if(!check_rights(R_ADMIN))
- return
-
- holder.modify_goals()
-
-/datum/admins/proc/modify_goals()
- var/dat = ""
- for(var/datum/station_goal/S in SSticker.mode.station_goals)
- dat += "[S.name] - Announce | Remove "
- dat += "Add New Goal "
- usr << browse(dat, "window=goals;size=400x400")
-
-
-/client/proc/toggle_hub()
- set category = "Server"
- set name = "Toggle Hub"
-
- world.update_hub_visibility(!GLOB.hub_visibility)
-
- log_admin("[key_name(usr)] has toggled the server's hub status for the round, it is now [(GLOB.hub_visibility?"on":"off")] the hub.")
- message_admins("[key_name_admin(usr)] has toggled the server's hub status for the round, it is now [(GLOB.hub_visibility?"on":"off")] the hub.")
- if (GLOB.hub_visibility && !world.reachable)
- message_admins("WARNING: The server will not show up on the hub because byond is detecting that a filewall is blocking incoming connections.")
-
- SSblackbox.add_details("admin_toggle","Toggled Hub Visibility|[GLOB.hub_visibility]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/smite(mob/living/carbon/human/target as mob)
- set name = "Smite"
- set category = "Fun"
- if(!holder)
- return
-
- var/list/punishment_list = list(ADMIN_PUNISHMENT_LIGHTNING, ADMIN_PUNISHMENT_BRAINDAMAGE, ADMIN_PUNISHMENT_GIB, ADMIN_PUNISHMENT_BSA)
-
- var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in punishment_list
-
- if(QDELETED(target) || !punishment)
- return
-
- switch(punishment)
- if(ADMIN_PUNISHMENT_LIGHTNING)
- var/turf/T = get_step(get_step(target, NORTH), NORTH)
- T.Beam(target, icon_state="lightning[rand(1,12)]", time = 5)
- target.adjustFireLoss(75)
- target.electrocution_animation(40)
- to_chat(target, "The gods have punished you for your sins! ")
- if(ADMIN_PUNISHMENT_BRAINDAMAGE)
- target.adjustBrainLoss(75)
- if(ADMIN_PUNISHMENT_GIB)
- target.gib(FALSE)
- if(ADMIN_PUNISHMENT_BSA)
- bluespace_artillery(target)
-
- var/msg = "[key_name_admin(usr)] punished [key_name_admin(target)] with [punishment]."
- message_admins(msg)
- admin_ticket_log(target, msg)
- log_admin("[key_name(usr)] punished [key_name(target)] with [punishment].")
-
-
-/client/proc/trigger_centcom_recall()
- if(!holder)
- return
- var/message = pick(GLOB.admiral_messages)
- message = input("Enter message from the on-call admiral to be put in the recall report.", "Admiral Message", message) as text|null
-
- if(!message)
- return
-
- message_admins("[key_name_admin(usr)] triggered a CentCom recall, with the admiral message of: [message]")
- log_game("[key_name(usr)] triggered a CentCom recall, with the message of: [message]")
- SSshuttle.centcom_recall(SSshuttle.emergency.timer, message)
-
-/client/proc/cmd_admin_check_player_exp() //Allows admins to determine who the newer players are.
- set category = "Admin"
- set name = "Player Playtime"
- if(!check_rights(R_ADMIN))
- return
-
- var/list/msg = list()
- msg += "Playtime Report Playtime: "
- src << browse(msg.Join(), "window=Player_playtime_check")
-
-/datum/admins/proc/cmd_show_exp_panel(client/C)
- if(!check_rights(R_ADMIN))
- return
- if(!C)
- to_chat(usr, "ERROR: Client not found. ")
- return
-
- var/list/body = list()
- body += "Playtime for [C.key] Playtime:"
- body += C.get_exp_report()
- body += "Toggle Exempt status "
- body += ""
- usr << browse(body.Join(), "window=playerplaytime[C.ckey];size=550x615")
-
-/datum/admins/proc/toggle_exempt_status(client/C)
- if(!check_rights(R_ADMIN))
- return
- if(!C)
- to_chat(usr, "ERROR: Client not found. ")
- return
-
- if(!C.set_db_player_flags())
- to_chat(usr, "ERROR: Unable read player flags from database. Please check logs. ")
- var/dbflags = C.prefs.db_flags
- var/newstate = FALSE
- if(dbflags & DB_FLAG_EXEMPT)
- newstate = FALSE
- else
- newstate = TRUE
-
- if(C.update_flag_db(DB_FLAG_EXEMPT, newstate))
- to_chat(usr, "ERROR: Unable to update player flags. Please check logs. ")
- else
- message_admins("[key_name_admin(usr)] has [newstate ? "activated" : "deactivated"] job exp exempt status on [key_name_admin(C)]")
+/client/proc/cmd_admin_drop_everything(mob/M in GLOB.mob_list)
+ set category = null
+ set name = "Drop Everything"
+ if(!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+
+ var/confirm = alert(src, "Make [M] drop everything?", "Message", "Yes", "No")
+ if(confirm != "Yes")
+ return
+
+ for(var/obj/item/W in M)
+ if(!M.dropItemToGround(W))
+ qdel(W)
+ M.regenerate_icons()
+
+ log_admin("[key_name(usr)] made [key_name(M)] drop everything!")
+ var/msg = "[key_name_admin(usr)] made [key_name_admin(M)] drop everything!"
+ message_admins(msg)
+ admin_ticket_log(M, msg)
+ SSblackbox.add_details("admin_verb","Drop Everything") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/cmd_admin_subtle_message(mob/M in GLOB.mob_list)
+ set category = "Special Verbs"
+ set name = "Subtle Message"
+
+ if(!ismob(M))
+ return
+ if (!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+
+ message_admins("[key_name_admin(src)] has started answering [key_name(M.key, 0, 0)]'s prayer.")
+ var/msg = input("Message:", text("Subtle PM to [M.key]")) as text
+
+ if (!msg)
+ message_admins("[key_name_admin(src)] decided not to answer [key_name(M.key, 0, 0)]'s prayer")
+ return
+ if(usr)
+ if (usr.client)
+ if(usr.client.holder)
+ to_chat(M, "You hear a voice in your head... [msg] ")
+
+ log_admin("SubtlePM: [key_name(usr)] -> [key_name(M)] : [msg]")
+ msg = " SubtleMessage: [key_name_admin(usr)] -> [key_name_admin(M)] : [msg] "
+ message_admins(msg)
+ admin_ticket_log(M, msg)
+ SSblackbox.add_details("admin_verb","Subtle Message") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/cmd_admin_world_narrate()
+ set category = "Special Verbs"
+ set name = "Global Narrate"
+
+ if (!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+
+ var/msg = input("Message:", text("Enter the text you wish to appear to everyone:")) as text
+
+ if (!msg)
+ return
+ to_chat(world, "[msg]")
+ log_admin("GlobalNarrate: [key_name(usr)] : [msg]")
+ message_admins("[key_name_admin(usr)] Sent a global narrate ")
+ SSblackbox.add_details("admin_verb","Global Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/cmd_admin_direct_narrate(mob/M)
+ set category = "Special Verbs"
+ set name = "Direct Narrate"
+
+ if(!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+
+ if(!M)
+ M = input("Direct narrate to whom?", "Active Players") as null|anything in GLOB.player_list
+
+ if(!M)
+ return
+
+ var/msg = input("Message:", text("Enter the text you wish to appear to your target:")) as text
+
+ if( !msg )
+ return
+
+ to_chat(M, msg)
+ log_admin("DirectNarrate: [key_name(usr)] to ([M.name]/[M.key]): [msg]")
+ msg = " DirectNarrate: [key_name(usr)] to ([M.name]/[M.key]): [msg] "
+ message_admins(msg)
+ admin_ticket_log(M, msg)
+ SSblackbox.add_details("admin_verb","Direct Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/cmd_admin_local_narrate(atom/A)
+ set category = "Special Verbs"
+ set name = "Local Narrate"
+
+ if (!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+ if(!A)
+ return
+ var/range = input("Range:", "Narrate to mobs within how many tiles:", 7) as num
+ if(!range)
+ return
+ var/msg = input("Message:", text("Enter the text you wish to appear to everyone within view:")) as text
+ if (!msg)
+ return
+ for(var/mob/M in view(range,A))
+ to_chat(M, msg)
+
+ log_admin("LocalNarrate: [key_name(usr)] at [get_area(A)][COORD(A)]: [msg]")
+ message_admins(" LocalNarrate: [key_name_admin(usr)] at [get_area(A)][ADMIN_JMP(A)]: [msg] ")
+ SSblackbox.add_details("admin_verb","Local Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/cmd_admin_godmode(mob/M in GLOB.mob_list)
+ set category = "Special Verbs"
+ set name = "Godmode"
+ if(!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+ M.status_flags ^= GODMODE
+ to_chat(usr, "Toggled [(M.status_flags & GODMODE) ? "ON" : "OFF"] ")
+
+ log_admin("[key_name(usr)] has toggled [key_name(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]")
+ var/msg = "[key_name_admin(usr)] has toggled [key_name_admin(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]"
+ message_admins(msg)
+ admin_ticket_log(M, msg)
+ SSblackbox.add_details("admin_toggle","Godmode|[M.status_flags & GODMODE]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+
+/proc/cmd_admin_mute(whom, mute_type, automute = 0)
+ if(!whom)
+ return
+
+ var/muteunmute
+ var/mute_string
+ var/feedback_string
+ switch(mute_type)
+ if(MUTE_IC)
+ mute_string = "IC (say and emote)"
+ feedback_string = "IC"
+ if(MUTE_OOC)
+ mute_string = "OOC"
+ feedback_string = "OOC"
+ if(MUTE_PRAY)
+ mute_string = "pray"
+ feedback_string = "Pray"
+ if(MUTE_ADMINHELP)
+ mute_string = "adminhelp, admin PM and ASAY"
+ feedback_string = "Adminhelp"
+ if(MUTE_DEADCHAT)
+ mute_string = "deadchat and DSAY"
+ feedback_string = "Deadchat"
+ if(MUTE_ALL)
+ mute_string = "everything"
+ feedback_string = "Everything"
+ else
+ return
+
+ var/client/C
+ if(istype(whom, /client))
+ C = whom
+ else if(istext(whom))
+ C = GLOB.directory[whom]
+ else
+ return
+
+ var/datum/preferences/P
+ if(C)
+ P = C.prefs
+ else
+ P = GLOB.preferences_datums[whom]
+ if(!P)
+ return
+
+ if(automute)
+ if(!CONFIG_GET(flag/automute_on))
+ return
+ else
+ if(!check_rights())
+ return
+
+ if(automute)
+ muteunmute = "auto-muted"
+ P.muted |= mute_type
+ log_admin("SPAM AUTOMUTE: [muteunmute] [key_name(whom)] from [mute_string]")
+ message_admins("SPAM AUTOMUTE: [muteunmute] [key_name_admin(whom)] from [mute_string].")
+ if(C)
+ to_chat(C, "You have been [muteunmute] from [mute_string] by the SPAM AUTOMUTE system. Contact an admin.")
+ SSblackbox.add_details("admin_toggle","Auto Mute [feedback_string]|1") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ return
+
+ if(P.muted & mute_type)
+ muteunmute = "unmuted"
+ P.muted &= ~mute_type
+ else
+ muteunmute = "muted"
+ P.muted |= mute_type
+
+ log_admin("[key_name(usr)] has [muteunmute] [key_name(whom)] from [mute_string]")
+ message_admins("[key_name_admin(usr)] has [muteunmute] [key_name_admin(whom)] from [mute_string].")
+ if(C)
+ to_chat(C, "You have been [muteunmute] from [mute_string] by [key_name(usr, include_name = FALSE)].")
+ SSblackbox.add_details("admin_toggle","Mute [feedback_string]|[P.muted & mute_type]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+
+//I use this proc for respawn character too. /N
+/proc/create_xeno(ckey)
+ if(!ckey)
+ var/list/candidates = list()
+ for(var/mob/M in GLOB.player_list)
+ if(M.stat != DEAD)
+ continue //we are not dead!
+ if(!(ROLE_ALIEN in M.client.prefs.be_special))
+ continue //we don't want to be an alium
+ if(M.client.is_afk())
+ continue //we are afk
+ if(M.mind && M.mind.current && M.mind.current.stat != DEAD)
+ continue //we have a live body we are tied to
+ candidates += M.ckey
+ if(candidates.len)
+ ckey = input("Pick the player you want to respawn as a xeno.", "Suitable Candidates") as null|anything in candidates
+ else
+ to_chat(usr, "Error: create_xeno(): no suitable candidates. ")
+ if(!istext(ckey))
+ return 0
+
+ var/alien_caste = input(usr, "Please choose which caste to spawn.","Pick a caste",null) as null|anything in list("Queen","Praetorian","Hunter","Sentinel","Drone","Larva")
+ var/obj/effect/landmark/spawn_here = GLOB.xeno_spawn.len ? pick(GLOB.xeno_spawn) : null
+ var/mob/living/carbon/alien/new_xeno
+ switch(alien_caste)
+ if("Queen")
+ new_xeno = new /mob/living/carbon/alien/humanoid/royal/queen(spawn_here)
+ if("Praetorian")
+ new_xeno = new /mob/living/carbon/alien/humanoid/royal/praetorian(spawn_here)
+ if("Hunter")
+ new_xeno = new /mob/living/carbon/alien/humanoid/hunter(spawn_here)
+ if("Sentinel")
+ new_xeno = new /mob/living/carbon/alien/humanoid/sentinel(spawn_here)
+ if("Drone")
+ new_xeno = new /mob/living/carbon/alien/humanoid/drone(spawn_here)
+ if("Larva")
+ new_xeno = new /mob/living/carbon/alien/larva(spawn_here)
+ else
+ return 0
+ if(!spawn_here)
+ SSjob.SendToLateJoin(new_xeno, FALSE)
+
+ new_xeno.ckey = ckey
+ var/msg = "[key_name_admin(usr)] has spawned [ckey] as a filthy xeno [alien_caste]. "
+ message_admins(msg)
+ admin_ticket_log(new_xeno, msg)
+ return 1
+
+/*
+If a guy was gibbed and you want to revive him, this is a good way to do so.
+Works kind of like entering the game with a new character. Character receives a new mind if they didn't have one.
+Traitors and the like can also be revived with the previous role mostly intact.
+/N */
+/client/proc/respawn_character()
+ set category = "Special Verbs"
+ set name = "Respawn Character"
+ set desc = "Respawn a person that has been gibbed/dusted/killed. They must be a ghost for this to work and preferably should not have a body to go back into."
+ if(!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+ var/input = ckey(input(src, "Please specify which key will be respawned.", "Key", ""))
+ if(!input)
+ return
+
+ var/mob/dead/observer/G_found
+ for(var/mob/dead/observer/G in GLOB.player_list)
+ if(G.ckey == input)
+ G_found = G
+ break
+
+ if(!G_found)//If a ghost was not found.
+ to_chat(usr, "There is no active key like that in the game or the person is not currently a ghost. ")
+ return
+
+ if(G_found.mind && !G_found.mind.active) //mind isn't currently in use by someone/something
+ //Check if they were an alien
+ if(G_found.mind.assigned_role=="Alien")
+ if(alert("This character appears to have been an alien. Would you like to respawn them as such?",,"Yes","No")=="Yes")
+ var/turf/T
+ if(GLOB.xeno_spawn.len)
+ T = pick(GLOB.xeno_spawn)
+
+ var/mob/living/carbon/alien/new_xeno
+ switch(G_found.mind.special_role)//If they have a mind, we can determine which caste they were.
+ if("Hunter")
+ new_xeno = new /mob/living/carbon/alien/humanoid/hunter(T)
+ if("Sentinel")
+ new_xeno = new /mob/living/carbon/alien/humanoid/sentinel(T)
+ if("Drone")
+ new_xeno = new /mob/living/carbon/alien/humanoid/drone(T)
+ if("Praetorian")
+ new_xeno = new /mob/living/carbon/alien/humanoid/royal/praetorian(T)
+ if("Queen")
+ new_xeno = new /mob/living/carbon/alien/humanoid/royal/queen(T)
+ else//If we don't know what special role they have, for whatever reason, or they're a larva.
+ create_xeno(G_found.ckey)
+ return
+
+ if(!T)
+ SSjob.SendToLateJoin(new_xeno, FALSE)
+
+ //Now to give them their mind back.
+ G_found.mind.transfer_to(new_xeno) //be careful when doing stuff like this! I've already checked the mind isn't in use
+ new_xeno.key = G_found.key
+ to_chat(new_xeno, "You have been fully respawned. Enjoy the game.")
+ var/msg = "[key_name_admin(usr)] has respawned [new_xeno.key] as a filthy xeno. "
+ message_admins(msg)
+ admin_ticket_log(new_xeno, msg)
+ return //all done. The ghost is auto-deleted
+
+ //check if they were a monkey
+ else if(findtext(G_found.real_name,"monkey"))
+ if(alert("This character appears to have been a monkey. Would you like to respawn them as such?",,"Yes","No")=="Yes")
+ var/mob/living/carbon/monkey/new_monkey = new
+ SSjob.SendToLateJoin(new_monkey)
+ G_found.mind.transfer_to(new_monkey) //be careful when doing stuff like this! I've already checked the mind isn't in use
+ new_monkey.key = G_found.key
+ to_chat(new_monkey, "You have been fully respawned. Enjoy the game.")
+ var/msg = "[key_name_admin(usr)] has respawned [new_monkey.key] as a filthy xeno. "
+ message_admins(msg)
+ admin_ticket_log(new_monkey, msg)
+ return //all done. The ghost is auto-deleted
+
+
+ //Ok, it's not a xeno or a monkey. So, spawn a human.
+ var/mob/living/carbon/human/new_character = new//The mob being spawned.
+ SSjob.SendToLateJoin(new_character)
+
+ var/datum/data/record/record_found //Referenced to later to either randomize or not randomize the character.
+ if(G_found.mind && !G_found.mind.active) //mind isn't currently in use by someone/something
+ /*Try and locate a record for the person being respawned through GLOB.data_core.
+ This isn't an exact science but it does the trick more often than not.*/
+ var/id = md5("[G_found.real_name][G_found.mind.assigned_role]")
+
+ record_found = find_record("id", id, GLOB.data_core.locked)
+
+ 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.age = record_found.fields["age"]
+ new_character.hardset_dna(record_found.fields["identity"], record_found.fields["enzymes"], record_found.fields["name"], record_found.fields["blood_type"], new record_found.fields["species"], record_found.fields["features"])
+ else
+ var/datum/preferences/A = new()
+ A.copy_to(new_character)
+ A.real_name = G_found.real_name
+ new_character.dna.update_dna_identity()
+
+ new_character.name = new_character.real_name
+
+ if(G_found.mind && !G_found.mind.active)
+ G_found.mind.transfer_to(new_character) //be careful when doing stuff like this! I've already checked the mind isn't in use
+ else
+ new_character.mind_initialize()
+ if(!new_character.mind.assigned_role)
+ new_character.mind.assigned_role = "Assistant"//If they somehow got a null assigned role.
+
+ new_character.key = G_found.key
+
+ /*
+ The code below functions with the assumption that the mob is already a traitor if they have a special role.
+ So all it does is re-equip the mob with powers and/or items. Or not, if they have no special role.
+ If they don't have a mind, they obviously don't have a special role.
+ */
+
+ //Two variables to properly announce later on.
+ var/admin = key_name_admin(src)
+ var/player_key = G_found.key
+
+ //Now for special roles and equipment.
+ var/datum/antagonist/traitor/traitordatum = new_character.mind.has_antag_datum(ANTAG_DATUM_TRAITOR)
+ if(traitordatum)
+ SSjob.EquipRank(new_character, new_character.mind.assigned_role, 1)
+ traitordatum.equip()
+
+
+ switch(new_character.mind.special_role)
+ if("Wizard")
+ new_character.loc = pick(GLOB.wizardstart)
+ //SSticker.mode.learn_basic_spells(new_character)
+ SSticker.mode.equip_wizard(new_character)
+ if("Syndicate")
+ var/obj/effect/landmark/synd_spawn = locate("landmark*Syndicate-Spawn")
+ if(synd_spawn)
+ new_character.loc = get_turf(synd_spawn)
+ call(/datum/game_mode/proc/equip_syndicate)(new_character)
+ if("Space Ninja")
+ var/list/ninja_spawn = list()
+ for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
+ ninja_spawn += L
+ var/datum/antagonist/ninja/ninjadatum = new_character.mind.has_antag_datum(ANTAG_DATUM_NINJA)
+ ninjadatum.equip_space_ninja()
+ if(ninja_spawn.len)
+ var/obj/effect/landmark/ninja_spawn_here = pick(ninja_spawn)
+ new_character.loc = ninja_spawn_here.loc
+
+ else//They may also be a cyborg or AI.
+ switch(new_character.mind.assigned_role)
+ if("Cyborg")//More rigging to make em' work and check if they're traitor.
+ new_character = new_character.Robotize()
+ if("AI")
+ new_character = new_character.AIize()
+ else
+ SSjob.EquipRank(new_character, new_character.mind.assigned_role, 1)//Or we simply equip them.
+
+ //Announces the character on all the systems, based on the record.
+ if(!issilicon(new_character))//If they are not a cyborg/AI.
+ if(!record_found&&new_character.mind.assigned_role!=new_character.mind.special_role)//If there are no records for them. If they have a record, this info is already in there. MODE people are not announced anyway.
+ //Power to the user!
+ if(alert(new_character,"Warning: No data core entry detected. Would you like to announce the arrival of this character by adding them to various databases, such as medical records?",,"No","Yes")=="Yes")
+ GLOB.data_core.manifest_inject(new_character)
+
+ if(alert(new_character,"Would you like an active AI to announce this character?",,"No","Yes")=="Yes")
+ AnnounceArrival(new_character, new_character.mind.assigned_role)
+
+ var/msg = "[admin] has respawned [player_key] as [new_character.real_name]. "
+ message_admins(msg)
+ admin_ticket_log(new_character, msg)
+
+ to_chat(new_character, "You have been fully respawned. Enjoy the game.")
+
+ SSblackbox.add_details("admin_verb","Respawn Character") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ return new_character
+
+/client/proc/cmd_admin_add_freeform_ai_law()
+ set category = "Fun"
+ set name = "Add Custom AI law"
+ if(!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+ var/input = input(usr, "Please enter anything you want the AI to do. Anything. Serious.", "What?", "") as text|null
+ if(!input)
+ return
+
+ log_admin("Admin [key_name(usr)] has added a new AI law - [input]")
+ message_admins("Admin [key_name_admin(usr)] has added a new AI law - [input]")
+
+ var/show_log = alert(src, "Show ion message?", "Message", "Yes", "No")
+ var/announce_ion_laws = (show_log == "Yes" ? 1 : -1)
+
+ var/datum/round_event/ion_storm/add_law_only/ion = new()
+ ion.announceEvent = announce_ion_laws
+ ion.ionMessage = input
+
+ SSblackbox.add_details("admin_verb","Add Custom AI Law") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/cmd_admin_rejuvenate(mob/living/M in GLOB.mob_list)
+ set category = "Special Verbs"
+ set name = "Rejuvenate"
+ if(!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+ if(!mob)
+ return
+ if(!istype(M))
+ alert("Cannot revive a ghost")
+ return
+ M.revive(full_heal = 1, admin_revive = 1)
+
+ log_admin("[key_name(usr)] healed / revived [key_name(M)]")
+ var/msg = "Admin [key_name_admin(usr)] healed / revived [key_name_admin(M)]! "
+ message_admins(msg)
+ admin_ticket_log(M, msg)
+ SSblackbox.add_details("admin_verb","Rejuvinate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/cmd_admin_create_centcom_report()
+ set category = "Special Verbs"
+ set name = "Create Command Report"
+ if(!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+ var/input = input(usr, "Please enter anything you want. Anything. Serious.", "What?", "") as message|null
+ if(!input)
+ return
+
+ var/confirm = alert(src, "Do you want to announce the contents of the report to the crew?", "Announce", "Yes", "No", "Cancel")
+ var/announce_command_report = TRUE
+ switch(confirm)
+ if("Yes")
+ priority_announce(input, null, 'sound/ai/commandreport.ogg')
+ announce_command_report = FALSE
+ if("Cancel")
+ return
+
+ print_command_report(input, "[announce_command_report ? "Classified " : ""][command_name()] Update", announce_command_report)
+
+ log_admin("[key_name(src)] has created a command report: [input]")
+ message_admins("[key_name_admin(src)] has created a command report")
+ SSblackbox.add_details("admin_verb","Create Command Report") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/cmd_change_command_name()
+ set category = "Special Verbs"
+ set name = "Change Command Name"
+ if(!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+ var/input = input(usr, "Please input a new name for Central Command.", "What?", "") as text|null
+ if(!input)
+ return
+ change_command_name(input)
+ message_admins("[key_name_admin(src)] has changed Central Command's name to [input]")
+ log_admin("[key_name(src)] has changed the Central Command name to: [input]")
+
+/client/proc/cmd_admin_delete(atom/A as obj|mob|turf in world)
+ set category = "Admin"
+ set name = "Delete"
+
+ if (!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+
+ admin_delete(A)
+
+/client/proc/admin_delete(datum/D)
+ var/atom/A = D
+ var/coords = istype(A) ? " at ([A.x], [A.y], [A.z])" : ""
+ if (alert(src, "Are you sure you want to delete:\n[D]\nat[coords]?", "Confirmation", "Yes", "No") == "Yes")
+ log_admin("[key_name(usr)] deleted [D][coords]")
+ message_admins("[key_name_admin(usr)] deleted [D][coords]")
+ SSblackbox.add_details("admin_verb","Delete") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ if(isturf(D))
+ var/turf/T = D
+ T.ChangeTurf(T.baseturf)
+ else
+ qdel(D)
+
+/client/proc/cmd_admin_list_open_jobs()
+ set category = "Admin"
+ set name = "Manage Job Slots"
+
+ if (!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+ holder.manage_free_slots()
+ SSblackbox.add_details("admin_verb","Manage Job Slots") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/cmd_admin_explosion(atom/O as obj|mob|turf in world)
+ set category = "Special Verbs"
+ set name = "Explosion"
+
+ if (!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+
+ var/devastation = input("Range of total devastation. -1 to none", text("Input")) as num|null
+ if(devastation == null) return
+ var/heavy = input("Range of heavy impact. -1 to none", text("Input")) as num|null
+ if(heavy == null) return
+ var/light = input("Range of light impact. -1 to none", text("Input")) as num|null
+ if(light == null) return
+ var/flash = input("Range of flash. -1 to none", text("Input")) as num|null
+ if(flash == null) return
+ var/flames = input("Range of flames. -1 to none", text("Input")) as num|null
+ if(flames == null) return
+
+ if ((devastation != -1) || (heavy != -1) || (light != -1) || (flash != -1) || (flames != -1))
+ if ((devastation > 20) || (heavy > 20) || (light > 20) || (flames > 20))
+ if (alert(src, "Are you sure you want to do this? It will laaag.", "Confirmation", "Yes", "No") == "No")
+ return
+
+ explosion(O, devastation, heavy, light, flash, null, null,flames)
+ log_admin("[key_name(usr)] created an explosion ([devastation],[heavy],[light],[flames]) at ([O.x],[O.y],[O.z])")
+ message_admins("[key_name_admin(usr)] created an explosion ([devastation],[heavy],[light],[flames]) at ([O.x],[O.y],[O.z])")
+ SSblackbox.add_details("admin_verb","Explosion") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ return
+ else
+ return
+
+/client/proc/cmd_admin_emp(atom/O as obj|mob|turf in world)
+ set category = "Special Verbs"
+ set name = "EM Pulse"
+
+ if (!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+
+ var/heavy = input("Range of heavy pulse.", text("Input")) as num|null
+ if(heavy == null) return
+ var/light = input("Range of light pulse.", text("Input")) as num|null
+ if(light == null) return
+
+ if (heavy || light)
+
+ empulse(O, heavy, light)
+ log_admin("[key_name(usr)] created an EM Pulse ([heavy],[light]) at ([O.x],[O.y],[O.z])")
+ message_admins("[key_name_admin(usr)] created an EM Pulse ([heavy],[light]) at ([O.x],[O.y],[O.z])")
+ SSblackbox.add_details("admin_verb","EM Pulse") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+ return
+ else
+ return
+
+/client/proc/cmd_admin_gib(mob/M in GLOB.mob_list)
+ set category = "Special Verbs"
+ set name = "Gib"
+
+ if (!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+
+ var/confirm = alert(src, "Drop a brain?", "Confirm", "Yes", "No","Cancel")
+ if(confirm == "Cancel")
+ return
+ //Due to the delay here its easy for something to have happened to the mob
+ if(!M)
+ return
+
+ log_admin("[key_name(usr)] has gibbed [key_name(M)]")
+ message_admins("[key_name_admin(usr)] has gibbed [key_name_admin(M)]")
+
+ if(isobserver(M))
+ new /obj/effect/gibspawner/generic(get_turf(M))
+ return
+ if(confirm == "Yes")
+ M.gib()
+ else
+ M.gib(1)
+ SSblackbox.add_details("admin_verb","Gib") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/cmd_admin_gib_self()
+ set name = "Gibself"
+ set category = "Fun"
+
+ var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
+ if(confirm == "Yes")
+ log_admin("[key_name(usr)] used gibself.")
+ message_admins("[key_name_admin(usr)] used gibself. ")
+ SSblackbox.add_details("admin_verb","Gib Self") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ mob.gib(1, 1, 1)
+
+/client/proc/cmd_admin_check_contents(mob/living/M in GLOB.mob_list)
+ set category = "Special Verbs"
+ set name = "Check Contents"
+
+ var/list/L = M.get_contents()
+ for(var/t in L)
+ to_chat(usr, "[t]")
+ SSblackbox.add_details("admin_verb","Check Contents") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/toggle_view_range()
+ set category = "Special Verbs"
+ set name = "Change View Range"
+ set desc = "switches between 1x and custom views"
+
+ if(view == world.view)
+ change_view(input("Select view range:", "FUCK YE", 7) in list(1,2,3,4,5,6,7,8,9,10,11,12,13,14,128))
+ else
+ change_view(world.view)
+
+ log_admin("[key_name(usr)] changed their view range to [view].")
+ //message_admins("\blue [key_name_admin(usr)] changed their view range to [view].") //why? removed by order of XSI
+
+ SSblackbox.add_details("admin_toggle","Change View Range|[view]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/admin_call_shuttle()
+
+ set category = "Admin"
+ set name = "Call Shuttle"
+
+ if(EMERGENCY_AT_LEAST_DOCKED)
+ return
+
+ if (!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+
+ var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
+ if(confirm != "Yes")
+ return
+
+ SSshuttle.emergency.request()
+ SSblackbox.add_details("admin_verb","Call Shuttle") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ log_admin("[key_name(usr)] admin-called the emergency shuttle.")
+ message_admins("[key_name_admin(usr)] admin-called the emergency shuttle. ")
+ return
+
+/client/proc/admin_cancel_shuttle()
+ set category = "Admin"
+ set name = "Cancel Shuttle"
+ if(!check_rights(0))
+ return
+ if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes")
+ return
+
+ if(EMERGENCY_AT_LEAST_DOCKED)
+ return
+
+ SSshuttle.emergency.cancel()
+ SSblackbox.add_details("admin_verb","Cancel Shuttle") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ log_admin("[key_name(usr)] admin-recalled the emergency shuttle.")
+ message_admins("[key_name_admin(usr)] admin-recalled the emergency shuttle. ")
+
+ return
+
+/client/proc/everyone_random()
+ set category = "Fun"
+ set name = "Make Everyone Random"
+ set desc = "Make everyone have a random appearance. You can only use this before rounds!"
+
+ if(SSticker.HasRoundStarted())
+ to_chat(usr, "Nope you can't do this, the game's already started. This only works before rounds!")
+ return
+
+ var/frn = CONFIG_GET(flag/force_random_names)
+ if(frn)
+ CONFIG_SET(flag/force_random_names, FALSE)
+ message_admins("Admin [key_name_admin(usr)] has disabled \"Everyone is Special\" mode.")
+ to_chat(usr, "Disabled.")
+ return
+
+
+ var/notifyplayers = alert(src, "Do you want to notify the players?", "Options", "Yes", "No", "Cancel")
+ if(notifyplayers == "Cancel")
+ return
+
+ log_admin("Admin [key_name(src)] has forced the players to have random appearances.")
+ message_admins("Admin [key_name_admin(usr)] has forced the players to have random appearances.")
+
+ if(notifyplayers == "Yes")
+ to_chat(world, "Admin [usr.key] has forced the players to have completely random identities! ")
+
+ to_chat(usr, "Remember: you can always disable the randomness by using the verb again, assuming the round hasn't started yet .")
+
+ CONFIG_SET(flag/force_random_names, TRUE)
+ SSblackbox.add_details("admin_verb","Make Everyone Random") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+
+/client/proc/toggle_random_events()
+ set category = "Server"
+ set name = "Toggle random events on/off"
+ set desc = "Toggles random events such as meteors, black holes, blob (but not space dust) on/off"
+ var/new_are = !CONFIG_GET(flag/allow_random_events)
+ CONFIG_SET(flag/allow_random_events, new_are)
+ if(new_are)
+ to_chat(usr, "Random events enabled")
+ message_admins("Admin [key_name_admin(usr)] has enabled random events.")
+ else
+ to_chat(usr, "Random events disabled")
+ message_admins("Admin [key_name_admin(usr)] has disabled random events.")
+ SSblackbox.add_details("admin_toggle","Toggle Random Events|[new_are]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+
+/client/proc/admin_change_sec_level()
+ set category = "Special Verbs"
+ set name = "Set Security Level"
+ set desc = "Changes the security level. Announcement only, i.e. setting to Delta won't activate nuke"
+
+ if (!holder)
+ to_chat(src, "Only administrators may use this command.")
+ return
+
+ var/level = input("Select security level to change to","Set Security Level") as null|anything in list("green","blue","red","delta")
+ if(level)
+ set_security_level(level)
+
+ log_admin("[key_name(usr)] changed the security level to [level]")
+ message_admins("[key_name_admin(usr)] changed the security level to [level]")
+ SSblackbox.add_details("admin_verb","Set Security Level [capitalize(level)]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/toggle_nuke(obj/machinery/nuclearbomb/N in GLOB.nuke_list)
+ set name = "Toggle Nuke"
+ set category = "Fun"
+ set popup_menu = 0
+ if(!check_rights(R_DEBUG))
+ return
+
+ if(!N.timing)
+ var/newtime = input(usr, "Set activation timer.", "Activate Nuke", "[N.timer_set]") as num
+ if(!newtime)
+ return
+ N.timer_set = newtime
+ N.set_safety()
+ N.set_active()
+
+ log_admin("[key_name(usr)] [N.timing ? "activated" : "deactivated"] a nuke at ([N.x],[N.y],[N.z]).")
+ message_admins("[ADMIN_LOOKUPFLW(usr)] [N.timing ? "activated" : "deactivated"] a nuke at [ADMIN_COORDJMP(N)].")
+ SSblackbox.add_details("admin_toggle","Toggle Nuke|[N.timing]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
+
+/client/proc/create_outfits()
+ set category = "Debug"
+ set name = "Create Custom Outfit"
+
+ if(!check_rights(R_DEBUG))
+ return
+
+ holder.create_outfit()
+
+/datum/admins/proc/create_outfit()
+ var/list/uniforms = typesof(/obj/item/clothing/under)
+ var/list/suits = typesof(/obj/item/clothing/suit)
+ var/list/gloves = typesof(/obj/item/clothing/gloves)
+ var/list/shoes = typesof(/obj/item/clothing/shoes)
+ var/list/headwear = typesof(/obj/item/clothing/head)
+ var/list/glasses = typesof(/obj/item/clothing/glasses)
+ var/list/masks = typesof(/obj/item/clothing/mask)
+ var/list/ids = typesof(/obj/item/card/id)
+
+ var/uniform_select = "None "
+ for(var/path in uniforms)
+ uniform_select += "[path] "
+ uniform_select += " "
+
+ var/suit_select = "None "
+ for(var/path in suits)
+ suit_select += "[path] "
+ suit_select += " "
+
+ var/gloves_select = "None "
+ for(var/path in gloves)
+ gloves_select += "[path] "
+ gloves_select += " "
+
+ var/shoes_select = "None "
+ for(var/path in shoes)
+ shoes_select += "[path] "
+ shoes_select += " "
+
+ var/head_select = "None "
+ for(var/path in headwear)
+ head_select += "[path] "
+ head_select += " "
+
+ var/glasses_select = "None "
+ for(var/path in glasses)
+ glasses_select += "[path] "
+ glasses_select += " "
+
+ var/mask_select = "None "
+ for(var/path in masks)
+ mask_select += "[path] "
+ mask_select += " "
+
+ var/id_select = "None "
+ for(var/path in ids)
+ id_select += "[path] "
+ id_select += " "
+
+ var/dat = {"
+ Create Outfit
+
+ "}
+ usr << browse(dat, "window=dressup;size=550x600")
+
+/client/proc/toggle_antag_hud()
+ set category = "Admin"
+ set name = "Toggle AntagHUD"
+ set desc = "Toggles the Admin AntagHUD"
+
+ if(!holder) return
+
+ var/adding_hud = !has_antag_hud()
+
+ for(var/datum/atom_hud/H in GLOB.huds)
+ if(istype(H, /datum/atom_hud/antag))
+ (adding_hud) ? H.add_hud_to(usr) : H.remove_hud_from(usr)
+
+ to_chat(usr, "You toggled your admin antag HUD [adding_hud ? "ON" : "OFF"].")
+ message_admins("[key_name_admin(usr)] toggled their admin antag HUD [adding_hud ? "ON" : "OFF"].")
+ log_admin("[key_name(usr)] toggled their admin antag HUD [adding_hud ? "ON" : "OFF"].")
+ SSblackbox.add_details("admin_toggle","Toggle Antag HUD|[adding_hud]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/has_antag_hud()
+ var/datum/atom_hud/A = GLOB.huds[ANTAG_HUD_TRAITOR]
+ return A.hudusers[mob]
+
+/client/proc/open_shuttle_manipulator()
+ set category = "Admin"
+ set name = "Shuttle Manipulator"
+ set desc = "Opens the shuttle manipulator UI."
+
+ for(var/obj/machinery/shuttle_manipulator/M in GLOB.machines)
+ M.ui_interact(usr)
+
+/client/proc/mass_zombie_infection()
+ set category = "Fun"
+ set name = "Mass Zombie Infection"
+ set desc = "Infects all humans with a latent organ that will zombify \
+ them on death."
+
+ if(!holder)
+ return
+
+ var/confirm = alert(src, "Please confirm you want to add latent zombie organs in all humans?", "Confirm Zombies", "Yes", "No")
+ if(confirm != "Yes")
+ return
+
+ for(var/mob/living/carbon/human/H in GLOB.mob_list)
+ new /obj/item/organ/zombie_infection(H)
+
+ message_admins("[key_name_admin(usr)] added a latent zombie infection to all humans.")
+ log_admin("[key_name(usr)] added a latent zombie infection to all humans.")
+ SSblackbox.add_details("admin_verb","Mass Zombie Infection")
+
+/client/proc/mass_zombie_cure()
+ set category = "Fun"
+ set name = "Mass Zombie Cure"
+ set desc = "Removes the zombie infection from all humans, returning them to normal."
+ if(!holder)
+ return
+
+ var/confirm = alert(src, "Please confirm you want to cure all zombies?", "Confirm Zombie Cure", "Yes", "No")
+ if(confirm != "Yes")
+ return
+
+ for(var/obj/item/organ/zombie_infection/I in GLOB.zombie_infection_list)
+ qdel(I)
+
+ message_admins("[key_name_admin(usr)] cured all zombies.")
+ log_admin("[key_name(usr)] cured all zombies.")
+ SSblackbox.add_details("admin_verb","Mass Zombie Cure")
+
+/client/proc/polymorph_all()
+ set category = "Fun"
+ set name = "Polymorph All"
+ set desc = "Applies the effects of the bolt of change to every single mob."
+
+ if(!holder)
+ return
+
+ var/confirm = alert(src, "Please confirm you want polymorph all mobs?", "Confirm Polymorph", "Yes", "No")
+ if(confirm != "Yes")
+ return
+
+ var/list/mobs = shuffle(GLOB.living_mob_list.Copy()) // might change while iterating
+ var/who_did_it = key_name_admin(usr)
+
+ message_admins("[key_name_admin(usr)] started polymorphed all living mobs.")
+ log_admin("[key_name(usr)] polymorphed all living mobs.")
+ SSblackbox.add_details("admin_verb","Polymorph All")
+
+ for(var/mob/living/M in mobs)
+ CHECK_TICK
+
+ if(!M)
+ continue
+
+ M.audible_message("...wabbajack...wabbajack... ")
+ playsound(M.loc, 'sound/magic/staff_change.ogg', 50, 1, -1)
+
+ wabbajack(M)
+
+ message_admins("Mass polymorph started by [who_did_it] is complete.")
+
+
+/client/proc/show_tip()
+ set category = "Admin"
+ set name = "Show Tip"
+ set desc = "Sends a tip (that you specify) to all players. After all \
+ you're the experienced player here."
+
+ if(!holder)
+ return
+
+ var/input = input(usr, "Please specify your tip that you want to send to the players.", "Tip", "") as message|null
+ if(!input)
+ return
+
+ if(!SSticker)
+ return
+
+ SSticker.selected_tip = input
+
+ // If we've already tipped, then send it straight away.
+ if(SSticker.tipped)
+ SSticker.send_tip_of_the_round()
+
+
+ message_admins("[key_name_admin(usr)] sent a tip of the round.")
+ log_admin("[key_name(usr)] sent \"[input]\" as the Tip of the Round.")
+ SSblackbox.add_details("admin_verb","Show Tip")
+
+#define ON_PURRBATION(H) (!(H.dna.features["tail_human"] == "None" && H.dna.features["ears"] == "None"))
+
+/proc/mass_purrbation()
+ for(var/M in GLOB.mob_list)
+ if(ishumanbasic(M))
+ purrbation_apply(M)
+ CHECK_TICK
+
+/proc/mass_remove_purrbation()
+ for(var/M in GLOB.mob_list)
+ if(ishumanbasic(M))
+ purrbation_remove(M)
+ CHECK_TICK
+
+/proc/purrbation_toggle(mob/living/carbon/human/H)
+ if(!ishumanbasic(H))
+ return
+ if(!ON_PURRBATION(H))
+ purrbation_apply(H)
+ . = TRUE
+ else
+ purrbation_remove(H)
+ . = FALSE
+
+/proc/purrbation_apply(mob/living/carbon/human/H)
+ if(!ishuman(H))
+ return
+ if(ON_PURRBATION(H))
+ return
+ to_chat(H, "Something is nya~t right.")
+ H.dna.features["tail_human"] = "Cat"
+ H.dna.features["ears"] = "Cat"
+ H.regenerate_icons()
+ playsound(get_turf(H), 'sound/effects/meow1.ogg', 50, 1, -1)
+
+/proc/purrbation_remove(mob/living/carbon/human/H)
+ if(!ishuman(H))
+ return
+ if(!ON_PURRBATION(H))
+ return
+ to_chat(H, "You are no longer a cat.")
+ H.dna.features["tail_human"] = "None"
+ H.dna.features["ears"] = "None"
+ H.regenerate_icons()
+
+#undef ON_PURRBATION
+
+/client/proc/modify_goals()
+ set category = "Debug"
+ set name = "Modify goals"
+
+ if(!check_rights(R_ADMIN))
+ return
+
+ holder.modify_goals()
+
+/datum/admins/proc/modify_goals()
+ var/dat = ""
+ for(var/datum/station_goal/S in SSticker.mode.station_goals)
+ dat += "[S.name] - Announce | Remove "
+ dat += "Add New Goal "
+ usr << browse(dat, "window=goals;size=400x400")
+
+
+/client/proc/toggle_hub()
+ set category = "Server"
+ set name = "Toggle Hub"
+
+ world.update_hub_visibility(!GLOB.hub_visibility)
+
+ log_admin("[key_name(usr)] has toggled the server's hub status for the round, it is now [(GLOB.hub_visibility?"on":"off")] the hub.")
+ message_admins("[key_name_admin(usr)] has toggled the server's hub status for the round, it is now [(GLOB.hub_visibility?"on":"off")] the hub.")
+ if (GLOB.hub_visibility && !world.reachable)
+ message_admins("WARNING: The server will not show up on the hub because byond is detecting that a filewall is blocking incoming connections.")
+
+ SSblackbox.add_details("admin_toggle","Toggled Hub Visibility|[GLOB.hub_visibility]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/smite(mob/living/carbon/human/target as mob)
+ set name = "Smite"
+ set category = "Fun"
+ if(!holder)
+ return
+
+ var/list/punishment_list = list(ADMIN_PUNISHMENT_LIGHTNING, ADMIN_PUNISHMENT_BRAINDAMAGE, ADMIN_PUNISHMENT_GIB, ADMIN_PUNISHMENT_BSA)
+
+ var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in punishment_list
+
+ if(QDELETED(target) || !punishment)
+ return
+
+ switch(punishment)
+ if(ADMIN_PUNISHMENT_LIGHTNING)
+ var/turf/T = get_step(get_step(target, NORTH), NORTH)
+ T.Beam(target, icon_state="lightning[rand(1,12)]", time = 5)
+ target.adjustFireLoss(75)
+ target.electrocution_animation(40)
+ to_chat(target, "The gods have punished you for your sins! ")
+ if(ADMIN_PUNISHMENT_BRAINDAMAGE)
+ target.adjustBrainLoss(75)
+ if(ADMIN_PUNISHMENT_GIB)
+ target.gib(FALSE)
+ if(ADMIN_PUNISHMENT_BSA)
+ bluespace_artillery(target)
+
+ var/msg = "[key_name_admin(usr)] punished [key_name_admin(target)] with [punishment]."
+ message_admins(msg)
+ admin_ticket_log(target, msg)
+ log_admin("[key_name(usr)] punished [key_name(target)] with [punishment].")
+
+
+/client/proc/trigger_centcom_recall()
+ if(!holder)
+ return
+ var/message = pick(GLOB.admiral_messages)
+ message = input("Enter message from the on-call admiral to be put in the recall report.", "Admiral Message", message) as text|null
+
+ if(!message)
+ return
+
+ message_admins("[key_name_admin(usr)] triggered a CentCom recall, with the admiral message of: [message]")
+ log_game("[key_name(usr)] triggered a CentCom recall, with the message of: [message]")
+ SSshuttle.centcom_recall(SSshuttle.emergency.timer, message)
+
+/client/proc/cmd_admin_check_player_exp() //Allows admins to determine who the newer players are.
+ set category = "Admin"
+ set name = "Player Playtime"
+ if(!check_rights(R_ADMIN))
+ return
+
+ var/list/msg = list()
+ msg += "Playtime Report Playtime: "
+ src << browse(msg.Join(), "window=Player_playtime_check")
+
+/datum/admins/proc/cmd_show_exp_panel(client/C)
+ if(!check_rights(R_ADMIN))
+ return
+ if(!C)
+ to_chat(usr, "ERROR: Client not found. ")
+ return
+
+ var/list/body = list()
+ body += "Playtime for [C.key] Playtime:"
+ body += C.get_exp_report()
+ body += "Toggle Exempt status "
+ body += ""
+ usr << browse(body.Join(), "window=playerplaytime[C.ckey];size=550x615")
+
+/datum/admins/proc/toggle_exempt_status(client/C)
+ if(!check_rights(R_ADMIN))
+ return
+ if(!C)
+ to_chat(usr, "ERROR: Client not found. ")
+ return
+
+ if(!C.set_db_player_flags())
+ to_chat(usr, "ERROR: Unable read player flags from database. Please check logs. ")
+ var/dbflags = C.prefs.db_flags
+ var/newstate = FALSE
+ if(dbflags & DB_FLAG_EXEMPT)
+ newstate = FALSE
+ else
+ newstate = TRUE
+
+ if(C.update_flag_db(DB_FLAG_EXEMPT, newstate))
+ to_chat(usr, "ERROR: Unable to update player flags. Please check logs. ")
+ else
+ message_admins("[key_name_admin(usr)] has [newstate ? "activated" : "deactivated"] job exp exempt status on [key_name_admin(C)]")
log_admin("[key_name(usr)] has [newstate ? "activated" : "deactivated"] job exp exempt status on [key_name(C)]")
\ No newline at end of file
diff --git a/code/modules/admin/verbs/reestablish_db_connection.dm b/code/modules/admin/verbs/reestablish_db_connection.dm
index 3578e98b1b..5c5edf6d17 100644
--- a/code/modules/admin/verbs/reestablish_db_connection.dm
+++ b/code/modules/admin/verbs/reestablish_db_connection.dm
@@ -1,7 +1,7 @@
/client/proc/reestablish_db_connection()
set category = "Special Verbs"
set name = "Reestablish DB Connection"
- if (!config.sql_enabled)
+ if (!CONFIG_GET(flag/sql_enabled))
to_chat(usr, "The Database is not enabled! ")
return
diff --git a/code/modules/atmospherics/environmental/LINDA_fire.dm b/code/modules/atmospherics/environmental/LINDA_fire.dm
index a39a9059f3..93862f16b4 100644
--- a/code/modules/atmospherics/environmental/LINDA_fire.dm
+++ b/code/modules/atmospherics/environmental/LINDA_fire.dm
@@ -49,7 +49,7 @@
icon = 'icons/effects/fire.dmi'
icon_state = "1"
layer = ABOVE_OPEN_TURF_LAYER
- light_range = 3
+ light_range = LIGHT_RANGE_FIRE
light_color = LIGHT_COLOR_FIRE
var/volume = 125
@@ -175,3 +175,15 @@
..()
if(isliving(L))
L.fire_act(temperature, volume)
+
+/obj/effect/dummy/fire
+ name = "fire"
+ desc = "OWWWWWW. IT BURNS. Tell a coder if you're seeing this."
+ icon_state = "nothing"
+ light_color = LIGHT_COLOR_FIRE
+ light_range = LIGHT_RANGE_FIRE
+
+/obj/effect/dummy/fire/Initialize()
+ . = ..()
+ if(!isliving(loc))
+ qdel(src)
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/valve.dm b/code/modules/atmospherics/machinery/components/binary_devices/valve.dm
index 7ef6cf2142..dbe1343667 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/valve.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/valve.dm
@@ -5,7 +5,7 @@ It's like a regular ol' straight pipe, but you can turn it on and off.
/obj/machinery/atmospherics/components/binary/valve
icon_state = "mvalve_map"
name = "manual valve"
- desc = "A pipe valve"
+ desc = "A pipe with a valve that can be used to disable flow of gas through it."
can_unwrench = TRUE
diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm
index c777e5fe17..2b5a94ef64 100644
--- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm
+++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm
@@ -1,6 +1,7 @@
/obj/machinery/atmospherics/components/trinary/filter
name = "gas filter"
icon_state = "filter_off"
+ desc = "Very useful for filtering gasses."
density = FALSE
can_unwrench = TRUE
var/on = FALSE
diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
index cb515ec75f..1fb8b072c6 100644
--- a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
+++ b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
@@ -4,6 +4,7 @@
name = "gas mixer"
can_unwrench = TRUE
+ desc = "Very useful for mixing gasses."
var/on = FALSE
diff --git a/code/modules/atmospherics/machinery/other/zvent.dm b/code/modules/atmospherics/machinery/other/zvent.dm
index 3490c972d9..d12c6196ec 100644
--- a/code/modules/atmospherics/machinery/other/zvent.dm
+++ b/code/modules/atmospherics/machinery/other/zvent.dm
@@ -5,6 +5,7 @@
icon_state = "vent_map"
density = FALSE
anchored=1
+ desc = "This may be needed some day."
var/on = FALSE
var/volume_rate = 800
diff --git a/code/modules/awaymissions/capture_the_flag.dm b/code/modules/awaymissions/capture_the_flag.dm
index 2dc38a48f2..0307a6b58e 100644
--- a/code/modules/awaymissions/capture_the_flag.dm
+++ b/code/modules/awaymissions/capture_the_flag.dm
@@ -320,7 +320,7 @@
for(var/atm in A)
if(!is_type_in_typecache(atm, ctf_object_typecache))
qdel(atm)
- if(istype(atm, /obj/structure))
+ if(isstructure(atm))
var/obj/structure/S = atm
S.obj_integrity = S.max_integrity
diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm
index 9a721bee62..12f99f3c50 100644
--- a/code/modules/awaymissions/gateway.dm
+++ b/code/modules/awaymissions/gateway.dm
@@ -80,7 +80,7 @@ GLOBAL_DATUM(the_gateway, /obj/machinery/gateway/centerstation)
if(!GLOB.the_gateway)
GLOB.the_gateway = src
update_icon()
- wait = world.time + config.gateway_delay //+ thirty minutes default
+ wait = world.time + CONFIG_GET(number/gateway_delay) //+ thirty minutes default
awaygate = locate(/obj/machinery/gateway/centeraway)
/obj/machinery/gateway/centerstation/Destroy()
diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm
index 6fbc7d552f..60936aa5fb 100644
--- a/code/modules/client/client_procs.dm
+++ b/code/modules/client/client_procs.dm
@@ -42,7 +42,8 @@
to_chat(src, "An error has been detected in how your client is receiving resources. Attempting to correct.... (If you keep seeing these messages you might want to close byond and reconnect) ")
src << browse("...", "window=asset_cache_browser")
- if (!holder && config.minutetopiclimit)
+ var/mtl = CONFIG_GET(number/minute_topic_limit)
+ if (!holder && mtl)
var/minute = round(world.time, 600)
if (!topiclimiter)
topiclimiter = new(LIMITER_SIZE)
@@ -50,17 +51,18 @@
topiclimiter[CURRENT_MINUTE] = minute
topiclimiter[MINUTE_COUNT] = 0
topiclimiter[MINUTE_COUNT] += 1
- if (topiclimiter[MINUTE_COUNT] > config.minutetopiclimit)
+ if (topiclimiter[MINUTE_COUNT] > mtl)
var/msg = "Your previous action was ignored because you've done too many in a minute."
if (minute != topiclimiter[ADMINSWARNED_AT]) //only one admin message per-minute. (if they spam the admins can just boot/ban them)
topiclimiter[ADMINSWARNED_AT] = minute
msg += " Administrators have been informed."
- log_game("[key_name(src)] Has hit the per-minute topic limit of [config.minutetopiclimit] topic calls in a given game minute")
- message_admins("[key_name_admin(src)] [ADMIN_FLW(usr)] [ADMIN_KICK(usr)] Has hit the per-minute topic limit of [config.minutetopiclimit] topic calls in a given game minute")
+ log_game("[key_name(src)] Has hit the per-minute topic limit of [mtl] topic calls in a given game minute")
+ message_admins("[key_name_admin(src)] [ADMIN_FLW(usr)] [ADMIN_KICK(usr)] Has hit the per-minute topic limit of [mtl] topic calls in a given game minute")
to_chat(src, "[msg] ")
return
- if (!holder && config.secondtopiclimit)
+ var/stl = CONFIG_GET(number/second_topic_limit)
+ if (!holder && stl)
var/second = round(world.time, 10)
if (!topiclimiter)
topiclimiter = new(LIMITER_SIZE)
@@ -68,7 +70,7 @@
topiclimiter[CURRENT_SECOND] = second
topiclimiter[SECOND_COUNT] = 0
topiclimiter[SECOND_COUNT] += 1
- if (topiclimiter[SECOND_COUNT] > config.secondtopiclimit)
+ if (topiclimiter[SECOND_COUNT] > stl)
to_chat(src, "Your previous action was ignored because you've done too many in a second ")
return
@@ -110,7 +112,7 @@
return 1
/client/proc/handle_spam_prevention(message, mute_type)
- if(config.automute_on && !holder && src.last_message == message)
+ if(CONFIG_GET(flag/automute_on) && !holder && last_message == message)
src.last_message_count++
if(src.last_message_count >= SPAM_TRIGGER_AUTOMUTE)
to_chat(src, "You have exceeded the spam filter limit for identical messages. An auto-mute was applied. ")
@@ -174,11 +176,11 @@ GLOBAL_LIST(external_rsc_urls)
if(localhost_rank)
var/datum/admins/localhost_holder = new(localhost_rank, ckey)
localhost_holder.associate(src)
- if(config.autoadmin)
+ if(CONFIG_GET(flag/autoadmin))
if(!GLOB.admin_datums[ckey])
var/datum/admin_rank/autorank
for(var/datum/admin_rank/R in GLOB.admin_ranks)
- if(R.name == config.autoadmin_rank)
+ if(R.name == CONFIG_GET(string/autoadmin_rank))
autorank = R
break
if(!autorank)
@@ -206,7 +208,7 @@ GLOBAL_LIST(external_rsc_urls)
log_access("Login: [key_name(src)] from [address ? address : "localhost"]-[computer_id] || BYOND v[byond_version]")
var/alert_mob_dupe_login = FALSE
- if(config.log_access)
+ if(CONFIG_GET(flag/log_access))
for(var/I in GLOB.clients)
if(!I || I == src)
continue
@@ -240,30 +242,32 @@ GLOBAL_LIST(external_rsc_urls)
connection_realtime = world.realtime
connection_timeofday = world.timeofday
winset(src, null, "command=\".configure graphics-hwmode on\"")
- if (byond_version < config.client_error_version) //Out of date client.
+ var/cev = CONFIG_GET(number/client_error_version)
+ var/cwv = CONFIG_GET(number/client_warn_version)
+ if (byond_version < cev) //Out of date client.
to_chat(src, "Your version of byond is too old: ")
- to_chat(src, config.client_error_message)
+ to_chat(src, CONFIG_GET(string/client_error_message))
to_chat(src, "Your version: [byond_version]")
- to_chat(src, "Required version: [config.client_error_version] or later")
+ to_chat(src, "Required version: [cev] or later")
to_chat(src, "Visit http://www.byond.com/download/ to get the latest version of byond.")
if (holder)
to_chat(src, "Because you are an admin, you are being allowed to walk past this limitation, But it is still STRONGLY suggested you upgrade")
else
qdel(src)
return 0
- else if (byond_version < config.client_warn_version) //We have words for this client.
+ else if (byond_version < cwv) //We have words for this client.
to_chat(src, "Your version of byond may be getting out of date: ")
- to_chat(src, config.client_warn_message)
+ to_chat(src, CONFIG_GET(string/client_warn_message))
to_chat(src, "Your version: [byond_version]")
- to_chat(src, "Required version to remove this message: [config.client_warn_version] or later")
+ to_chat(src, "Required version to remove this message: [cwv] or later")
to_chat(src, "Visit http://www.byond.com/download/ to get the latest version of byond.")
if (connection == "web" && !holder)
- if (!config.allowwebclient)
+ if (!CONFIG_GET(flag/allow_webclient))
to_chat(src, "Web client is disabled")
qdel(src)
return 0
- if (config.webclientmembersonly && !IsByondMember())
+ if (CONFIG_GET(flag/webclient_only_byond_members) && !IsByondMember())
to_chat(src, "Sorry, but the web client is restricted to byond members only.")
qdel(src)
return 0
@@ -276,25 +280,24 @@ GLOBAL_LIST(external_rsc_urls)
add_admin_verbs()
to_chat(src, get_message_output("memo"))
adminGreet()
- if((global.comms_key == "default_pwd" || length(global.comms_key) <= 6) && global.comms_allowed) //It's the default value or less than 6 characters long, but it somehow didn't disable comms.
- to_chat(src, "The server's API key is either too short or is the default value! Consider changing it immediately! ")
add_verbs_from_config()
var/cached_player_age = set_client_age_from_db(tdata) //we have to cache this because other shit may change it and we need it's current value now down below.
if (isnum(cached_player_age) && cached_player_age == -1) //first connection
player_age = 0
+ var/nnpa = CONFIG_GET(number/notify_new_player_age)
if (isnum(cached_player_age) && cached_player_age == -1) //first connection
- if (config.notify_new_player_age >= 0)
+ if (nnpa >= 0)
message_admins("New user: [key_name_admin(src)] is connecting here for the first time.")
- if (config.irc_first_connection_alert)
+ if (CONFIG_GET(flag/irc_first_connection_alert))
send2irc_adminless_only("New-user", "[key_name(src)] is connecting for the first time!")
- else if (isnum(cached_player_age) && cached_player_age < config.notify_new_player_age)
+ else if (isnum(cached_player_age) && cached_player_age < nnpa)
message_admins("New user: [key_name_admin(src)] just connected with an age of [cached_player_age] day[(player_age==1?"":"s")]")
- if(config.use_account_age_for_jobs && account_age >= 0)
+ if(CONFIG_GET(flag/use_account_age_for_jobs) && account_age >= 0)
player_age = account_age
- if(account_age >= 0 && account_age < config.notify_new_player_account_age)
+ if(account_age >= 0 && account_age < nnpa)
message_admins("[key_name_admin(src)] (IP: [address], ID: [computer_id]) is a new BYOND account [account_age] day[(account_age==1?"":"s")] old, created on [account_join_date].")
- if (config.irc_first_connection_alert)
+ if (CONFIG_GET(flag/irc_first_connection_alert))
send2irc_adminless_only("new_byond_user", "[key_name(src)] (IP: [address], ID: [computer_id]) is a new BYOND account [account_age] day[(account_age==1?"":"s")] old, created on [account_join_date].")
get_message_output("watchlist entry", ckey)
check_ip_intel()
@@ -306,7 +309,7 @@ GLOBAL_LIST(external_rsc_urls)
if(prefs.lastchangelog != GLOB.changelog_hash) //bolds the changelog button on the interface so we know there are updates.
to_chat(src, "You have unread updates in the changelog. ")
- if(config.aggressive_changelog)
+ if(CONFIG_GET(flag/aggressive_changelog))
changelog()
else
winset(src, "infowindow.changelog", "font-style=bold")
@@ -316,7 +319,7 @@ GLOBAL_LIST(external_rsc_urls)
to_chat(src, message)
GLOB.clientmessages.Remove(ckey)
- if(config && config.autoconvert_notes)
+ if(CONFIG_GET(flag/autoconvert_notes))
convert_notes_sql(ckey)
to_chat(src, get_message_output("message", ckey))
if(!winexists(src, "asset_cache_browser")) // The client is using a custom skin, tell them.
@@ -432,15 +435,17 @@ GLOBAL_LIST(external_rsc_urls)
if(!query_client_in_db.Execute())
return
if(!query_client_in_db.NextRow())
- if (config.panic_bunker && !holder && !(ckey in GLOB.deadmins))
+ if (CONFIG_GET(flag/panic_bunker) && !holder && !(ckey in GLOB.deadmins))
log_access("Failed Login: [key] - New account attempting to connect during panic bunker")
message_admins("Failed Login: [key] - New account attempting to connect during panic bunker ")
to_chat(src, "Sorry but the server is currently not accepting connections from never before seen players.")
var/list/connectiontopic_a = params2list(connectiontopic)
- if(config.panic_address && !connectiontopic_a["redirect"])
- to_chat(src, "Sending you to [config.panic_server_name ? config.panic_server_name : config.panic_address]. ")
+ var/list/panic_addr = CONFIG_GET(string/panic_address)
+ if(panic_addr && !connectiontopic_a["redirect"])
+ var/panic_name = CONFIG_GET(string/panic_server_name)
+ to_chat(src, "Sending you to [panic_name ? panic_name : panic_addr]. ")
winset(src, null, "command=.options")
- src << link("[config.panic_address]?redirect=1")
+ src << link("[panic_addr]?redirect=1")
qdel(src)
return
@@ -501,7 +506,7 @@ GLOBAL_LIST(external_rsc_urls)
if (connection != "seeker")
return
topic = params2list(topic)
- if (!config.check_randomizer)
+ if (!CONFIG_GET(flag/check_randomizer))
return
var/static/cidcheck = list()
var/static/tokens = list()
@@ -594,15 +599,15 @@ GLOBAL_LIST(external_rsc_urls)
/client/proc/check_ip_intel()
set waitfor = 0 //we sleep when getting the intel, no need to hold up the client connection while we sleep
- if (config.ipintel_email)
+ if (CONFIG_GET(string/ipintel_email))
var/datum/ipintel/res = get_ip_intel(address)
- if (res.intel >= config.ipintel_rating_bad)
+ if (res.intel >= CONFIG_GET(number/ipintel_rating_bad))
message_admins("Proxy Detection: [key_name_admin(src)] IP intel rated [res.intel*100]% likely to be a Proxy/VPN. ")
ip_intel = res.intel
/client/proc/add_verbs_from_config()
- if(config.see_own_notes)
+ if(CONFIG_GET(flag/see_own_notes))
verbs += /client/proc/self_notes
@@ -612,7 +617,7 @@ GLOBAL_LIST(external_rsc_urls)
//checks if a client is afk
//3000 frames = 5 minutes
-/client/proc/is_afk(duration = config.inactivity_period)
+/client/proc/is_afk(duration = CONFIG_GET(number/inactivity_period))
if(inactivity > duration)
return inactivity
return FALSE
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index 15b0bd95df..38e0b0bd90 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -46,7 +46,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/preferred_map = null
var/uses_glasses_colour = 0
-
+
var/screenshake = 100
var/damagescreenshake = 2
@@ -277,6 +277,168 @@ GLOBAL_LIST_EMPTY(preferences_datums)
// dat += "Size: [character_size] "
dat += " "
+ dat += "Body "
+ dat += "Random Body "
+ dat += "Always Random Body: [be_random_body ? "Yes" : "No"] "
+
+ dat += ""
+
+ if(CONFIG_GET(flag/join_with_mutant_race))
+ dat += "Species: [pref_species.name] "
+ else
+ dat += "Species: Human "
+
+ dat += "Underwear: [underwear] "
+ dat += "Undershirt: [undershirt] "
+ dat += "Socks: [socks] "
+ dat += "Backpack: [backbag] "
+ dat += "Uplink Spawn Location: [uplink_spawn_loc] "
+
+ if(pref_species.use_skintones)
+
+ dat += ""
+
+ dat += "Skin Tone "
+
+ dat += "[skin_tone] "
+
+ dat += " "
+
+ if(HAIR in pref_species.species_traits)
+
+ dat += ""
+
+ dat += "Hair Style "
+
+ dat += "[hair_style] "
+ dat += "< > "
+ dat += " Change "
+
+
+ dat += " "
+
+ dat += "Facial Hair Style "
+
+ dat += "[facial_hair_style] "
+ dat += "< > "
+ dat += " Change "
+
+ dat += " "
+
+ if(EYECOLOR in pref_species.species_traits)
+
+ dat += ""
+
+ dat += "Eye Color "
+
+ dat += " Change "
+
+ dat += " "
+
+ if(CONFIG_GET(flag/join_with_mutant_race)) //We don't allow mutant bodyparts for humans either unless this is true.
+
+ if((MUTCOLORS in pref_species.species_traits) || (MUTCOLORS_PARTSONLY in pref_species.species_traits))
+
+ dat += ""
+
+ dat += "Mutant Color "
+
+ dat += " Change "
+
+ dat += " "
+
+ if("tail_lizard" in pref_species.mutant_bodyparts)
+ dat += ""
+
+ dat += "Tail "
+
+ dat += "[features["tail_lizard"]] "
+
+ dat += " "
+
+ if("snout" in pref_species.mutant_bodyparts)
+ dat += ""
+
+ dat += "Snout "
+
+ dat += "[features["snout"]] "
+
+ dat += " "
+
+ if("horns" in pref_species.mutant_bodyparts)
+ dat += ""
+
+ dat += "Horns "
+
+ dat += "[features["horns"]] "
+
+ dat += " "
+
+ if("frills" in pref_species.mutant_bodyparts)
+ dat += ""
+
+ dat += "Frills "
+
+ dat += "[features["frills"]] "
+
+ dat += " "
+
+ if("spines" in pref_species.mutant_bodyparts)
+ dat += ""
+
+ dat += "Spines "
+
+ dat += "[features["spines"]] "
+
+ dat += " "
+
+ if("body_markings" in pref_species.mutant_bodyparts)
+ dat += ""
+
+ dat += "Body Markings "
+
+ dat += "[features["body_markings"]] "
+
+ dat += " "
+ if("legs" in pref_species.mutant_bodyparts)
+ dat += ""
+
+ dat += "Legs "
+
+ dat += "[features["legs"]] "
+
+ dat += " "
+ if(CONFIG_GET(flag/join_with_mutant_humans))
+
+ if("tail_human" in pref_species.mutant_bodyparts)
+ dat += ""
+
+ dat += "Tail "
+
+ dat += "[features["tail_human"]] "
+
+ dat += " "
+
+ if("ears" in pref_species.mutant_bodyparts)
+ dat += ""
+
+ dat += "Ears "
+
+ dat += "[features["ears"]] "
+
+ dat += " "
+
+ if("wings" in pref_species.mutant_bodyparts && GLOB.r_wings_list.len >1)
+ dat += ""
+
+ dat += "Wings "
+
+ dat += "[features["wings"]] "
+
+ dat += " "
+
+ dat += "
"
+
if (1) // Game Preferences
dat += ""
dat += "General Settings "
@@ -295,7 +457,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "Ghost pda: [(chat_toggles & CHAT_GHOSTPDA) ? "All Messages" : "Nearest Creatures"] "
dat += "Pull requests: [(chat_toggles & CHAT_PULLR) ? "Yes" : "No"] "
dat += "Midround Antagonist: [(toggles & MIDROUND_ANTAG) ? "Yes" : "No"] "
- if(config.allow_Metadata)
+ if(CONFIG_GET(flag/allow_metadata))
dat += "OOC Notes: Edit "
if(user.client)
@@ -332,7 +494,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "Ghosts of Others: [button_name] "
- if (config.maprotation)
+ if (CONFIG_GET(flag/maprotation))
var/p_map = preferred_map
if (!p_map)
p_map = "Default"
@@ -347,7 +509,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
p_map = VM.map_name
else
p_map += " (No longer exists)"
- if(config.allow_map_voting)
+ if(CONFIG_GET(flag/allow_map_voting))
dat += "Preferred Map: [p_map] "
dat += "FPS: [clientfps] "
@@ -385,7 +547,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "Be [capitalize(i)]: BANNED "
else
var/days_remaining = null
- if(config.use_age_restriction_for_jobs && ispath(GLOB.special_roles[i])) //If it's a game mode antag, check if the player meets the minimum age
+ if(ispath(GLOB.special_roles[i]) && CONFIG_GET(flag/use_age_restriction_for_jobs)) //If it's a game mode antag, check if the player meets the minimum age
var/mode_path = GLOB.special_roles[i]
var/datum/game_mode/temp_mode = new mode_path
days_remaining = temp_mode.get_remaining_days(user.client)
@@ -409,7 +571,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "[features["flavor_text"]]"
else
dat += "[TextPreview(features["flavor_text"])]... "
- if(config.mutant_races)//really don't need this check, but fuck un-tabbing all those lines
+ if(CONFIG_GET(flag/join_with_mutant_race))//really don't need this check, but fuck un-tabbing all those lines
dat += "Body "
dat += "Gender: [gender == MALE ? "Male" : "Female"] "
dat += "Species: [pref_species.id] "
@@ -599,7 +761,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if((job_civilian_low & ASSISTANT) && (rank != "Assistant") && !jobban_isbanned(user, "Assistant"))
HTML += "[rank] "
continue
- if(config.enforce_human_authority && !user.client.prefs.pref_species.qualifies_for_rank(rank, user.client.prefs.features))
+ if(CONFIG_GET(flag/enforce_human_authority) && !user.client.prefs.pref_species.qualifies_for_rank(rank, user.client.prefs.features))
if(user.client.prefs.pref_species.id == "human")
HTML += "[rank] \[MUTANT\] "
else
@@ -1023,10 +1185,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if("species")
- var/result = input(user, "Select a species", "Species Selection") as null|anything in GLOB.roundstart_species
+ var/result = input(user, "Select a species", "Species Selection") as null|anything in CONFIG_GET(keyed_flag_list/roundstart_races)
if(result)
- var/newtype = GLOB.roundstart_species[result]
+ var/newtype = GLOB.species_list[result]
pref_species = new newtype()
//Now that we changed our species, we must verify that the mutant colour is still allowed.
var/temp_hsv = RGBtoHSV(features["mcolor"])
@@ -1622,7 +1784,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(be_random_body)
random_character(gender)
- if(config.humans_need_surnames)
+ if(CONFIG_GET(flag/humans_need_surnames))
var/firstspace = findtext(real_name, " ")
var/name_length = length(real_name)
if(!firstspace) //we need a surname
@@ -1657,7 +1819,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
character.dna.features = features.Copy() //Flavor text is now a DNA feature
character.dna.real_name = character.real_name
var/datum/species/chosen_species
- if(pref_species != /datum/species/human && config.mutant_races)
+ if(pref_species != /datum/species/human && CONFIG_GET(flag/join_with_mutant_race))
chosen_species = pref_species.type
else
chosen_species = /datum/species/human
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index 9daad5cae7..d58d1cec77 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -290,11 +290,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
//Species
var/species_id
S["species"] >> species_id
- if(config.mutant_races && species_id && (species_id in GLOB.roundstart_species))
- var/newtype = GLOB.roundstart_species[species_id]
+ var/list/roundstart_races = CONFIG_GET(keyed_flag_list/roundstart_races)
+ if(species_id && (species_id in roundstart_races) && CONFIG_GET(flag/join_with_mutant_race))
+ var/newtype = GLOB.species_list[species_id]
pref_species = new newtype()
- else if (config.roundstart_races.len)
- var/rando_race = pick(config.roundstart_races)
+ else if (roundstart_races.len)
+ var/rando_race = pick(roundstart_races)
if (rando_race)
pref_species = new rando_race()
@@ -327,8 +328,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["feature_lizard_spines"] >> features["spines"]
S["feature_lizard_body_markings"] >> features["body_markings"]
S["feature_lizard_legs"] >> features["legs"]
- S["feature_human_tail"] >> features["tail_human"]
- S["feature_human_ears"] >> features["ears"]
+ if(!CONFIG_GET(flag/join_with_mutant_humans))
+ features["tail_human"] = "none"
+ features["ears"] = "none"
+ else
+ S["feature_human_tail"] >> features["tail_human"]
+ S["feature_human_ears"] >> features["ears"]
S["clown_name"] >> custom_names["clown"]
S["mime_name"] >> custom_names["mime"]
S["ai_name"] >> custom_names["ai"]
diff --git a/code/modules/client/verbs/ooc.dm b/code/modules/client/verbs/ooc.dm
index 7715362c06..e2022729be 100644
--- a/code/modules/client/verbs/ooc.dm
+++ b/code/modules/client/verbs/ooc.dm
@@ -62,7 +62,7 @@
if(holder)
if(!holder.fakekey || C.holder)
if(check_rights_for(src, R_ADMIN))
- to_chat(C, "[config.allow_admin_ooccolor && prefs.ooccolor ? "" :"" ]OOC: [keyname][holder.fakekey ? "/([holder.fakekey])" : ""]: [msg] ")
+ to_chat(C, "[CONFIG_GET(flag/allow_admin_ooccolor) && prefs.ooccolor ? "" :"" ]OOC: [keyname][holder.fakekey ? "/([holder.fakekey])" : ""]: [msg] ")
else
to_chat(C, "OOC: [keyname][holder.fakekey ? "/([holder.fakekey])" : ""]: [msg] ")
else
@@ -239,7 +239,7 @@ GLOBAL_VAR_INIT(normal_ooc_colour, OOC_COLOR)
set category = "OOC"
set desc = "View the notes that admins have written about you"
- if(!config.see_own_notes)
+ if(!CONFIG_GET(flag/see_own_notes))
to_chat(usr, "Sorry, that function is not enabled on this server. ")
return
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index 9d8b25cebf..237714eb8e 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -48,7 +48,7 @@
if(pockets && over_object == M)
return pockets.MouseDrop(over_object)
- if(istype(usr.loc, /obj/mecha)) // stops inventory actions in a mech
+ if(ismecha(M.loc)) // stops inventory actions in a mech
return
if(!M.incapacitated() && loc == M && istype(over_object, /obj/screen/inventory/hand))
diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm
index cf7dc9eb5f..9c0b78e1d1 100644
--- a/code/modules/clothing/glasses/glasses.dm
+++ b/code/modules/clothing/glasses/glasses.dm
@@ -4,7 +4,7 @@
var/glass_colour_type = null //colors your vision when worn
/obj/item/clothing/glasses/examine(mob/user)
- ..()
+ ..()
if(glass_colour_type && ishuman(user))
to_chat(user, "Alt-click to toggle its colors. ")
@@ -90,6 +90,7 @@
item_state = "glasses"
origin_tech = "materials=4;magnets=4;plasmatech=4;engineering=4"
darkness_view = 8
+ vision_flags = SEE_BLACKNESS
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
glass_colour_type = /datum/client_colour/glass_colour/green
diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm
index db3bcd3538..87106d65b4 100644
--- a/code/modules/clothing/head/misc.dm
+++ b/code/modules/clothing/head/misc.dm
@@ -283,7 +283,7 @@
/obj/item/clothing/head/crown/fancy
name = "magnificent crown"
- desc = "A crown worn by only the highest emperors of the land."
+ desc = "A crown worn by only the highest emperors of the land space."
icon_state = "fancycrown"
/obj/item/clothing/head/scarecrow_hat
diff --git a/code/modules/clothing/under/accessories.dm b/code/modules/clothing/under/accessories.dm
index 3e6a5ad371..c5e68ebcec 100644
--- a/code/modules/clothing/under/accessories.dm
+++ b/code/modules/clothing/under/accessories.dm
@@ -151,6 +151,16 @@
desc = "A bronze heart-shaped medal awarded for sacrifice. It is often awarded posthumously or for severe injury in the line of duty."
icon_state = "bronze_heart"
+/obj/item/clothing/accessory/medal/ribbon
+ name = "ribbon"
+ desc = "A ribbon"
+ icon_state = "cargo"
+ item_color = "cargo"
+
+/obj/item/clothing/accessory/medal/ribbon/cargo
+ name = "\"cargo tech of the shift\" award"
+ desc = "An award bestowed only upon those cargotechs who have exhibited devotion to their duty in keeping with the highest traditions of Cargonia."
+
/obj/item/clothing/accessory/medal/silver
name = "silver medal"
desc = "A silver medal."
diff --git a/code/modules/emoji/emoji_parse.dm b/code/modules/emoji/emoji_parse.dm
index 58f261f8cc..7d1953738f 100644
--- a/code/modules/emoji/emoji_parse.dm
+++ b/code/modules/emoji/emoji_parse.dm
@@ -1,6 +1,6 @@
/proc/emoji_parse(text)
. = text
- if(!config.emojis)
+ if(!CONFIG_GET(flag/emojis))
return
var/static/list/emojis = icon_states(icon('icons/emoji.dmi'))
var/parsed = ""
diff --git a/code/modules/error_handler/error_handler.dm b/code/modules/error_handler/error_handler.dm
index c0c8cf5b74..17ac8b3628 100644
--- a/code/modules/error_handler/error_handler.dm
+++ b/code/modules/error_handler/error_handler.dm
@@ -33,14 +33,20 @@ GLOBAL_VAR_INIT(total_runtimes_skipped, 0)
// We can runtime before config is initialized because BYOND initialize objs/map before a bunch of other stuff happens.
// This is a bunch of workaround code for that. Hooray!
-
- var/configured_error_cooldown = initial(config.error_cooldown)
- var/configured_error_limit = initial(config.error_limit)
- var/configured_error_silence_time = initial(config.error_silence_time)
+ var/configured_error_cooldown
+ var/configured_error_limit
+ var/configured_error_silence_time
if(config)
- configured_error_cooldown = config.error_cooldown
- configured_error_limit = config.error_limit
- configured_error_silence_time = config.error_silence_time
+ configured_error_cooldown = CONFIG_GET(number/error_cooldown)
+ configured_error_limit = CONFIG_GET(number/error_limit)
+ configured_error_silence_time = CONFIG_GET(number/error_silence_time)
+ else
+ var/datum/config_entry/CE = /datum/config_entry/number/error_cooldown
+ configured_error_cooldown = initial(CE.value)
+ CE = /datum/config_entry/number/error_limit
+ configured_error_limit = initial(CE.value)
+ CE = /datum/config_entry/number/error_silence_time
+ configured_error_silence_time = initial(CE.value)
//Each occurence of a unique error adds to its cooldown time...
diff --git a/code/modules/error_handler/error_viewer.dm b/code/modules/error_handler/error_viewer.dm
index dddff75bb2..b19153956f 100644
--- a/code/modules/error_handler/error_viewer.dm
+++ b/code/modules/error_handler/error_viewer.dm
@@ -119,9 +119,10 @@ GLOBAL_DATUM(error_cache, /datum/error_viewer/error_cache)
//log_debug("Runtime in [e.file] , line [e.line] : [html_encode(e.name)] [error_entry.make_link(viewtext)]")
var/err_msg_delay
if(config)
- err_msg_delay = config.error_msg_delay
+ err_msg_delay = CONFIG_GET(number/error_msg_delay)
else
- err_msg_delay = initial(config.error_msg_delay)
+ var/datum/config_entry/CE = /datum/config_entry/number/error_msg_delay
+ err_msg_delay = initial(CE.value)
error_source.next_message_at = world.time + err_msg_delay
/datum/error_viewer/error_source
diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm
index 92399f8934..c33bb463b3 100644
--- a/code/modules/events/_event.dm
+++ b/code/modules/events/_event.dm
@@ -29,8 +29,8 @@
/datum/round_event_control/New()
if(config && !wizardevent) // Magic is unaffected by configs
- earliest_start = Ceiling(earliest_start * config.events_min_time_mul)
- min_players = Ceiling(min_players * config.events_min_players_mul)
+ earliest_start = Ceiling(earliest_start * CONFIG_GET(number/events_min_time_mul))
+ min_players = Ceiling(min_players * CONFIG_GET(number/events_min_players_mul))
/datum/round_event_control/wizard
wizardevent = 1
@@ -157,19 +157,28 @@
return
if(activeFor == startWhen)
+ processing = FALSE
start()
+ processing = TRUE
if(activeFor == announceWhen)
+ processing = FALSE
announce()
+ processing = TRUE
if(startWhen < activeFor && activeFor < endWhen)
+ processing = FALSE
tick()
+ processing = TRUE
if(activeFor == endWhen)
+ processing = FALSE
end()
+ processing = TRUE
// Everything is done, let's clean up.
if(activeFor >= endWhen && activeFor >= announceWhen && activeFor >= startWhen)
+ processing = FALSE
kill()
activeFor++
diff --git a/code/modules/events/carp_migration.dm b/code/modules/events/carp_migration.dm
index 34e5d5e9a2..ca6cd782fc 100644
--- a/code/modules/events/carp_migration.dm
+++ b/code/modules/events/carp_migration.dm
@@ -1,28 +1,25 @@
-/datum/round_event_control/carp_migration
- name = "Carp Migration"
- typepath = /datum/round_event/carp_migration
- weight = 15
- min_players = 2
- earliest_start = 6000
- max_occurrences = 6
-
-/datum/round_event/carp_migration
- announceWhen = 3
- startWhen = 50
-
-/datum/round_event/carp_migration/setup()
- startWhen = rand(40, 60)
-
-/datum/round_event/carp_migration/announce()
- priority_announce("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert")
-
-
-/datum/round_event/carp_migration/start()
- for(var/obj/effect/landmark/C in GLOB.landmarks_list)
- if(C.name == "carpspawn")
- if(prob(95))
- new /mob/living/simple_animal/hostile/carp(C.loc)
- else
- new /mob/living/simple_animal/hostile/carp/megacarp(C.loc)
-
-
+/datum/round_event_control/carp_migration
+ name = "Carp Migration"
+ typepath = /datum/round_event/carp_migration
+ weight = 15
+ min_players = 2
+ earliest_start = 6000
+ max_occurrences = 6
+
+/datum/round_event/carp_migration
+ announceWhen = 3
+ startWhen = 50
+
+/datum/round_event/carp_migration/setup()
+ startWhen = rand(40, 60)
+
+/datum/round_event/carp_migration/announce()
+ priority_announce("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert")
+
+
+/datum/round_event/carp_migration/start()
+ for(var/obj/effect/landmark/carpspawn/C in GLOB.landmarks_list)
+ if(prob(95))
+ new /mob/living/simple_animal/hostile/carp(C.loc)
+ else
+ new /mob/living/simple_animal/hostile/carp/megacarp(C.loc)
diff --git a/code/modules/events/electrical_storm.dm b/code/modules/events/electrical_storm.dm
index 0f1af1f8f9..a10e42d754 100644
--- a/code/modules/events/electrical_storm.dm
+++ b/code/modules/events/electrical_storm.dm
@@ -1,36 +1,36 @@
-/datum/round_event_control/electrical_storm
- name = "Electrical Storm"
- typepath = /datum/round_event/electrical_storm
- earliest_start = 6000
- min_players = 5
- weight = 40
- alertadmins = 0
-
-/datum/round_event/electrical_storm
- var/lightsoutAmount = 1
- var/lightsoutRange = 25
- announceWhen = 1
-
-/datum/round_event/electrical_storm/announce()
- priority_announce("An electrical storm has been detected in your area, please repair potential electronic overloads.", "Electrical Storm Alert")
-
-
-/datum/round_event/electrical_storm/start()
- var/list/epicentreList = list()
-
- for(var/i=1, i <= lightsoutAmount, i++)
- var/list/possibleEpicentres = list()
- for(var/obj/effect/landmark/newEpicentre in GLOB.landmarks_list)
- if(newEpicentre.name == "lightsout" && !(newEpicentre in epicentreList))
- possibleEpicentres += newEpicentre
- if(possibleEpicentres.len)
- epicentreList += pick(possibleEpicentres)
- else
- break
-
- if(!epicentreList.len)
- return
-
- for(var/obj/effect/landmark/epicentre in epicentreList)
- for(var/obj/machinery/power/apc/apc in urange(lightsoutRange, epicentre))
- apc.overload_lighting()
+/datum/round_event_control/electrical_storm
+ name = "Electrical Storm"
+ typepath = /datum/round_event/electrical_storm
+ earliest_start = 6000
+ min_players = 5
+ weight = 40
+ alertadmins = 0
+
+/datum/round_event/electrical_storm
+ var/lightsoutAmount = 1
+ var/lightsoutRange = 25
+ announceWhen = 1
+
+/datum/round_event/electrical_storm/announce()
+ priority_announce("An electrical storm has been detected in your area, please repair potential electronic overloads.", "Electrical Storm Alert")
+
+
+/datum/round_event/electrical_storm/start()
+ var/list/epicentreList = list()
+
+ for(var/i=1, i <= lightsoutAmount, i++)
+ var/list/possibleEpicentres = list()
+ for(var/obj/effect/landmark/lightsout/newEpicentre in GLOB.landmarks_list)
+ if(!(newEpicentre in epicentreList))
+ possibleEpicentres += newEpicentre
+ if(possibleEpicentres.len)
+ epicentreList += pick(possibleEpicentres)
+ else
+ break
+
+ if(!epicentreList.len)
+ return
+
+ for(var/obj/effect/landmark/epicentre in epicentreList)
+ for(var/obj/machinery/power/apc/apc in urange(lightsoutRange, epicentre))
+ apc.overload_lighting()
diff --git a/code/modules/events/holiday/halloween.dm b/code/modules/events/holiday/halloween.dm
index 843f043bfa..5415eab386 100644
--- a/code/modules/events/holiday/halloween.dm
+++ b/code/modules/events/holiday/halloween.dm
@@ -1,138 +1,137 @@
-/datum/round_event_control/spooky
- name = "2 SPOOKY! (Halloween)"
- holidayID = HALLOWEEN
- typepath = /datum/round_event/spooky
- weight = -1 //forces it to be called, regardless of weight
- max_occurrences = 1
- earliest_start = 0
-
-/datum/round_event/spooky/start()
- ..()
- for(var/mob/living/carbon/human/H in GLOB.mob_list)
- var/obj/item/storage/backpack/b = locate() in H.contents
- new /obj/item/storage/spooky(b)
- if(ishuman(H) || islizard(H))
- if(prob(50))
- H.set_species(/datum/species/skeleton)
- else
- H.set_species(/datum/species/zombie)
-
- for(var/mob/living/simple_animal/pet/dog/corgi/Ian/Ian in GLOB.mob_list)
- Ian.place_on_head(new /obj/item/bedsheet(Ian))
- for(var/mob/living/simple_animal/parrot/Poly/Poly in GLOB.mob_list)
- new /mob/living/simple_animal/parrot/Poly/ghost(Poly.loc)
- qdel(Poly)
-
-/datum/round_event/spooky/announce()
- priority_announce(pick("RATTLE ME BONES!","THE RIDE NEVER ENDS!", "A SKELETON POPS OUT!", "SPOOKY SCARY SKELETONS!", "CREWMEMBERS BEWARE, YOU'RE IN FOR A SCARE!") , "THE CALL IS COMING FROM INSIDE THE HOUSE")
-
-//Eyeball migration
-/datum/round_event_control/carp_migration/eyeballs
- name = "Eyeball Migration"
- typepath = /datum/round_event/carp_migration/eyeballs
- holidayID = HALLOWEEN
- weight = 25
- earliest_start = 0
-
-/datum/round_event/carp_migration/eyeballs/start()
- for(var/obj/effect/landmark/C in GLOB.landmarks_list)
- if(C.name == "carpspawn")
- new /mob/living/simple_animal/hostile/carp/eyeball(C.loc)
-
-//Pumpking meteors waves
-/datum/round_event_control/meteor_wave/spooky
- name = "Pumpkin Wave"
- typepath = /datum/round_event/meteor_wave/spooky
- holidayID = HALLOWEEN
- weight = 20
- max_occurrences = 2
-
-/datum/round_event/meteor_wave/spooky
- endWhen = 40
-
-/datum/round_event/meteor_wave/spooky/tick()
- if(IsMultiple(activeFor, 4))
- spawn_meteors(3, GLOB.meteorsSPOOKY) //meteor list types defined in gamemode/meteor/meteors.dm
-
-//Creepy clown invasion
-/datum/round_event_control/creepy_clowns
- name = "Clowns"
- typepath = /datum/round_event/creepy_clowns
- holidayID = HALLOWEEN
- weight = 20
- earliest_start = 0
-
-/datum/round_event/creepy_clowns
- endWhen = 40
-
-/datum/round_event/creepy_clowns/start()
- for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
- if(!H.client || !istype(H))
- return
- to_chat(H, "Honk... ")
+/datum/round_event_control/spooky
+ name = "2 SPOOKY! (Halloween)"
+ holidayID = HALLOWEEN
+ typepath = /datum/round_event/spooky
+ weight = -1 //forces it to be called, regardless of weight
+ max_occurrences = 1
+ earliest_start = 0
+
+/datum/round_event/spooky/start()
+ ..()
+ for(var/mob/living/carbon/human/H in GLOB.mob_list)
+ var/obj/item/storage/backpack/b = locate() in H.contents
+ new /obj/item/storage/spooky(b)
+ if(ishuman(H) || islizard(H))
+ if(prob(50))
+ H.set_species(/datum/species/skeleton)
+ else
+ H.set_species(/datum/species/zombie)
+
+ for(var/mob/living/simple_animal/pet/dog/corgi/Ian/Ian in GLOB.mob_list)
+ Ian.place_on_head(new /obj/item/bedsheet(Ian))
+ for(var/mob/living/simple_animal/parrot/Poly/Poly in GLOB.mob_list)
+ new /mob/living/simple_animal/parrot/Poly/ghost(Poly.loc)
+ qdel(Poly)
+
+/datum/round_event/spooky/announce()
+ priority_announce(pick("RATTLE ME BONES!","THE RIDE NEVER ENDS!", "A SKELETON POPS OUT!", "SPOOKY SCARY SKELETONS!", "CREWMEMBERS BEWARE, YOU'RE IN FOR A SCARE!") , "THE CALL IS COMING FROM INSIDE THE HOUSE")
+
+//Eyeball migration
+/datum/round_event_control/carp_migration/eyeballs
+ name = "Eyeball Migration"
+ typepath = /datum/round_event/carp_migration/eyeballs
+ holidayID = HALLOWEEN
+ weight = 25
+ earliest_start = 0
+
+/datum/round_event/carp_migration/eyeballs/start()
+ for(var/obj/effect/landmark/carpspawn/C in GLOB.landmarks_list)
+ new /mob/living/simple_animal/hostile/carp/eyeball(C.loc)
+
+//Pumpking meteors waves
+/datum/round_event_control/meteor_wave/spooky
+ name = "Pumpkin Wave"
+ typepath = /datum/round_event/meteor_wave/spooky
+ holidayID = HALLOWEEN
+ weight = 20
+ max_occurrences = 2
+
+/datum/round_event/meteor_wave/spooky
+ endWhen = 40
+
+/datum/round_event/meteor_wave/spooky/tick()
+ if(IsMultiple(activeFor, 4))
+ spawn_meteors(3, GLOB.meteorsSPOOKY) //meteor list types defined in gamemode/meteor/meteors.dm
+
+//Creepy clown invasion
+/datum/round_event_control/creepy_clowns
+ name = "Clowns"
+ typepath = /datum/round_event/creepy_clowns
+ holidayID = HALLOWEEN
+ weight = 20
+ earliest_start = 0
+
+/datum/round_event/creepy_clowns
+ endWhen = 40
+
+/datum/round_event/creepy_clowns/start()
+ for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
+ if(!H.client || !istype(H))
+ return
+ to_chat(H, "Honk... ")
SEND_SOUND(H, sound('sound/spookoween/scary_clown_appear.ogg'))
- var/turf/T = get_turf(H)
- if(T)
- new /obj/effect/hallucination/simple/clown(T, H, 50)
-
-/datum/round_event/creepy_clowns/tick()
- if(IsMultiple(activeFor, 4))
- for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
- if (prob(66))
- playsound(H.loc, pick('sound/spookoween/scary_horn.ogg','sound/spookoween/scary_horn2.ogg', 'sound/spookoween/scary_horn3.ogg'), 100, 1)
- if (prob(33))
- var/turf/T = get_turf(H)
- if(T)
- new /obj/effect/hallucination/simple/clown(T, H, 25)
- else if (prob(25))
- var/turf/T = get_turf(H)
- if(T)
- new /obj/effect/hallucination/simple/clown/scary(T, H, 25)
- else if (prob(5))
- var/turf/T = get_turf(H)
- if(T)
- spawn_atom_to_turf(/obj/effect/mob_spawn/human/clown/corpse, H, 1)
- else if (prob(1))
- spawn_atom_to_turf(/mob/living/simple_animal/hostile/retaliate/clown, H, 1)
-
-/datum/round_event/creepy_clowns/announce()
- priority_announce("Honk... Honk... honk... HONK! HONK! HONKHONKHONKHONKHONK", "HONK!", 'sound/spookoween/scary_horn.ogg')
-
-//spooky foods (you can't actually make these when it's not halloween)
-/obj/item/reagent_containers/food/snacks/sugarcookie/spookyskull
- name = "skull cookie"
- desc = "Spooky! It's got delicious calcium flavouring!"
- icon = 'icons/obj/halloween_items.dmi'
- icon_state = "skeletoncookie"
-
-/obj/item/reagent_containers/food/snacks/sugarcookie/spookycoffin
- name = "coffin cookie"
- desc = "Spooky! It's got delicious coffee flavouring!"
- icon = 'icons/obj/halloween_items.dmi'
- icon_state = "coffincookie"
-
-
-//spooky items
-
-/obj/item/storage/spooky
- name = "trick-o-treat bag"
- desc = "A pumpkin-shaped bag that holds all sorts of goodies!"
- icon = 'icons/obj/halloween_items.dmi'
- icon_state = "treatbag"
-
-/obj/item/storage/spooky/New()
- ..()
- for(var/distrobuteinbag=0 to 5)
- var/type = pick(/obj/item/reagent_containers/food/snacks/sugarcookie/spookyskull,
- /obj/item/reagent_containers/food/snacks/sugarcookie/spookycoffin,
- /obj/item/reagent_containers/food/snacks/candy_corn,
- /obj/item/reagent_containers/food/snacks/candy,
- /obj/item/reagent_containers/food/snacks/candiedapple,
- /obj/item/reagent_containers/food/snacks/chocolatebar,
- /obj/item/organ/brain ) // OH GOD THIS ISN'T CANDY!
- new type(src)
-
-/obj/item/card/emag/halloween
- name = "hack-o'-lantern"
- desc = "It's a pumpkin with a cryptographic sequencer sticking out."
- icon_state = "hack_o_lantern"
+ var/turf/T = get_turf(H)
+ if(T)
+ new /obj/effect/hallucination/simple/clown(T, H, 50)
+
+/datum/round_event/creepy_clowns/tick()
+ if(IsMultiple(activeFor, 4))
+ for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
+ if (prob(66))
+ playsound(H.loc, pick('sound/spookoween/scary_horn.ogg','sound/spookoween/scary_horn2.ogg', 'sound/spookoween/scary_horn3.ogg'), 100, 1)
+ if (prob(33))
+ var/turf/T = get_turf(H)
+ if(T)
+ new /obj/effect/hallucination/simple/clown(T, H, 25)
+ else if (prob(25))
+ var/turf/T = get_turf(H)
+ if(T)
+ new /obj/effect/hallucination/simple/clown/scary(T, H, 25)
+ else if (prob(5))
+ var/turf/T = get_turf(H)
+ if(T)
+ spawn_atom_to_turf(/obj/effect/mob_spawn/human/clown/corpse, H, 1)
+ else if (prob(1))
+ spawn_atom_to_turf(/mob/living/simple_animal/hostile/retaliate/clown, H, 1)
+
+/datum/round_event/creepy_clowns/announce()
+ priority_announce("Honk... Honk... honk... HONK! HONK! HONKHONKHONKHONKHONK", "HONK!", 'sound/spookoween/scary_horn.ogg')
+
+//spooky foods (you can't actually make these when it's not halloween)
+/obj/item/reagent_containers/food/snacks/sugarcookie/spookyskull
+ name = "skull cookie"
+ desc = "Spooky! It's got delicious calcium flavouring!"
+ icon = 'icons/obj/halloween_items.dmi'
+ icon_state = "skeletoncookie"
+
+/obj/item/reagent_containers/food/snacks/sugarcookie/spookycoffin
+ name = "coffin cookie"
+ desc = "Spooky! It's got delicious coffee flavouring!"
+ icon = 'icons/obj/halloween_items.dmi'
+ icon_state = "coffincookie"
+
+
+//spooky items
+
+/obj/item/storage/spooky
+ name = "trick-o-treat bag"
+ desc = "A pumpkin-shaped bag that holds all sorts of goodies!"
+ icon = 'icons/obj/halloween_items.dmi'
+ icon_state = "treatbag"
+
+/obj/item/storage/spooky/New()
+ ..()
+ for(var/distrobuteinbag=0 to 5)
+ var/type = pick(/obj/item/reagent_containers/food/snacks/sugarcookie/spookyskull,
+ /obj/item/reagent_containers/food/snacks/sugarcookie/spookycoffin,
+ /obj/item/reagent_containers/food/snacks/candy_corn,
+ /obj/item/reagent_containers/food/snacks/candy,
+ /obj/item/reagent_containers/food/snacks/candiedapple,
+ /obj/item/reagent_containers/food/snacks/chocolatebar,
+ /obj/item/organ/brain ) // OH GOD THIS ISN'T CANDY!
+ new type(src)
+
+/obj/item/card/emag/halloween
+ name = "hack-o'-lantern"
+ desc = "It's a pumpkin with a cryptographic sequencer sticking out."
+ icon_state = "hack_o_lantern"
diff --git a/code/modules/events/operative.dm b/code/modules/events/operative.dm
index 4db2029ce7..0841a2fdbb 100644
--- a/code/modules/events/operative.dm
+++ b/code/modules/events/operative.dm
@@ -16,9 +16,8 @@
var/mob/dead/selected = pick_n_take(candidates)
var/list/spawn_locs = list()
- for(var/obj/effect/landmark/L in GLOB.landmarks_list)
- if(L.name in list("ninjaspawn","carpspawn"))
- spawn_locs += L.loc
+ for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
+ spawn_locs += L.loc
if(!spawn_locs.len)
return MAP_ERROR
diff --git a/code/modules/events/wizard/magicarp.dm b/code/modules/events/wizard/magicarp.dm
index cc632d9c87..5cebc55cbd 100644
--- a/code/modules/events/wizard/magicarp.dm
+++ b/code/modules/events/wizard/magicarp.dm
@@ -16,12 +16,11 @@
priority_announce("Unknown magical entities have been detected near [station_name()], please stand-by.", "Lifesign Alert")
/datum/round_event/wizard/magicarp/start()
- for(var/obj/effect/landmark/C in GLOB.landmarks_list)
- if(C.name == "carpspawn")
- if(prob(5))
- new /mob/living/simple_animal/hostile/carp/ranged/chaos(C.loc)
- else
- new /mob/living/simple_animal/hostile/carp/ranged(C.loc)
+ for(var/obj/effect/landmark/carpspawn/C in GLOB.landmarks_list)
+ if(prob(5))
+ new /mob/living/simple_animal/hostile/carp/ranged/chaos(C.loc)
+ else
+ new /mob/living/simple_animal/hostile/carp/ranged(C.loc)
/mob/living/simple_animal/hostile/carp/ranged
name = "magicarp"
diff --git a/code/modules/events/wizard/summons.dm b/code/modules/events/wizard/summons.dm
index dfdcd889ca..64778ae65d 100644
--- a/code/modules/events/wizard/summons.dm
+++ b/code/modules/events/wizard/summons.dm
@@ -6,7 +6,7 @@
earliest_start = 0
/datum/round_event_control/wizard/summonguns/New()
- if(config.no_summon_guns)
+ if(CONFIG_GET(flag/no_summon_guns))
weight = 0
..()
@@ -21,7 +21,7 @@
earliest_start = 0
/datum/round_event_control/wizard/summonmagic/New()
- if(config.no_summon_magic)
+ if(CONFIG_GET(flag/no_summon_magic))
weight = 0
..()
diff --git a/code/modules/events/wormholes.dm b/code/modules/events/wormholes.dm
index 6404307d34..74169df074 100644
--- a/code/modules/events/wormholes.dm
+++ b/code/modules/events/wormholes.dm
@@ -26,7 +26,7 @@
for(var/i = 1, i <= number_of_wormholes, i++)
var/turf/T = pick(pick_turfs)
- wormholes += new /obj/effect/portal/wormhole(T, null, 300, null, FALSE)
+ wormholes += new /obj/effect/portal/wormhole(T, null, 0, null, FALSE)
/datum/round_event/wormholes/announce()
priority_announce("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert", 'sound/ai/spanomalies.ogg')
@@ -40,6 +40,7 @@
/datum/round_event/wormholes/end()
QDEL_LIST(wormholes)
+ wormholes = null
/obj/effect/portal/wormhole
name = "wormhole"
@@ -48,17 +49,11 @@
icon_state = "anom"
mech_sized = TRUE
-/obj/effect/portal/wormhole/attack_hand(mob/user)
- teleport(user)
-
-/obj/effect/portal/wormhole/attackby(obj/item/I, mob/user, params)
- teleport(user)
-
/obj/effect/portal/wormhole/teleport(atom/movable/M)
if(istype(M, /obj/effect)) //sparks don't teleport
return
if(M.anchored)
- if(!(istype(M, /obj/mecha) && mech_sized))
+ if(!(ismecha(M) && mech_sized))
return
if(ismovableatom(M))
diff --git a/code/modules/food_and_drinks/food/snacks_meat.dm b/code/modules/food_and_drinks/food/snacks_meat.dm
index 7c8db01bcc..11426a4e04 100644
--- a/code/modules/food_and_drinks/food/snacks_meat.dm
+++ b/code/modules/food_and_drinks/food/snacks_meat.dm
@@ -185,7 +185,9 @@
/obj/item/reagent_containers/food/snacks/monkeycube/proc/Expand()
visible_message("[src] expands! ")
- new /mob/living/carbon/monkey(get_turf(src))
+ var/mob/spammer = get_mob_by_key(src.fingerprintslast)
+ var/mob/living/carbon/monkey/bananas = new(get_turf(src))
+ bananas.log_message("Spawned via [src] at [COORD(src)], Last attached mob: [key_name(spammer)].", INDIVIDUAL_ATTACK_LOG)
qdel(src)
/obj/item/reagent_containers/food/snacks/enchiladas
diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm
index 5f5752deec..d5cac19f32 100644
--- a/code/modules/hydroponics/grown.dm
+++ b/code/modules/hydroponics/grown.dm
@@ -17,9 +17,9 @@
resistance_flags = FLAMMABLE
origin_tech = "biotech=1"
-/obj/item/reagent_containers/food/snacks/grown/New(newloc, var/obj/item/seeds/new_seed = null)
- tastes = list(name = 1) // apples taste of apple, silly.
- ..()
+/obj/item/reagent_containers/food/snacks/grown/Initialize(mapload, obj/item/seeds/new_seed)
+ . = ..()
+ tastes = list("[name]" = 1) // apples taste of apple, silly.
if(new_seed)
seed = new_seed.Copy()
else if(ispath(seed))
@@ -35,7 +35,7 @@
if(seed)
for(var/datum/plant_gene/trait/T in seed.genes)
- T.on_new(src, newloc)
+ T.on_new(src, loc)
seed.prepare_result(src)
transform *= TransformUsingVariable(seed.potency, 100, 0.5) //Makes the resulting produce's sprite larger or smaller based on potency!
add_juice()
diff --git a/code/modules/hydroponics/grown/replicapod.dm b/code/modules/hydroponics/grown/replicapod.dm
index 3c332b950c..bb928c6fa5 100644
--- a/code/modules/hydroponics/grown/replicapod.dm
+++ b/code/modules/hydroponics/grown/replicapod.dm
@@ -55,7 +55,7 @@
var/obj/machinery/hydroponics/parent = loc
var/make_podman = 0
var/ckey_holder = null
- if(config.revival_pod_plants)
+ if(CONFIG_GET(flag/revival_pod_plants))
if(ckey)
for(var/mob/M in GLOB.player_list)
if(isobserver(M))
@@ -99,7 +99,7 @@
podman.faction |= factions
if(!features["mcolor"])
features["mcolor"] = "#59CE00"
- podman.hardset_dna(null,null,podman.real_name,blood_type, /datum/species/pod,features)//Discard SE's and UI's, podman cloning is inaccurate, and always make them a podman
+ podman.hardset_dna(null,null,podman.real_name,blood_type, new /datum/species/pod,features)//Discard SE's and UI's, podman cloning is inaccurate, and always make them a podman
podman.set_cloned_appearance()
else //else, one packet of seeds. maybe two
diff --git a/code/modules/hydroponics/growninedible.dm b/code/modules/hydroponics/growninedible.dm
index 6058088f75..a77808f006 100644
--- a/code/modules/hydroponics/growninedible.dm
+++ b/code/modules/hydroponics/growninedible.dm
@@ -1,64 +1,64 @@
-// **********************
-// Other harvested materials from plants (that are not food)
-// **********************
-
-/obj/item/grown // Grown weapons
- name = "grown_weapon"
- icon = 'icons/obj/hydroponics/harvest.dmi'
- resistance_flags = FLAMMABLE
- var/obj/item/seeds/seed = null // type path, gets converted to item on New(). It's safe to assume it's always a seed item.
-
-/obj/item/grown/New(newloc, var/obj/item/seeds/new_seed = null)
- ..()
- create_reagents(50)
-
- if(new_seed)
- seed = new_seed.Copy()
- else if(ispath(seed))
- // This is for adminspawn or map-placed growns. They get the default stats of their seed type.
- seed = new seed()
- seed.adjust_potency(50-seed.potency)
-
- pixel_x = rand(-5, 5)
- pixel_y = rand(-5, 5)
-
- if(seed)
- for(var/datum/plant_gene/trait/T in seed.genes)
- T.on_new(src, newloc)
-
- if(istype(src, seed.product)) // no adding reagents if it is just a trash item
- seed.prepare_result(src)
- transform *= TransformUsingVariable(seed.potency, 100, 0.5)
- add_juice()
-
-
-/obj/item/grown/attackby(obj/item/O, mob/user, params)
- ..()
- if (istype(O, /obj/item/device/plant_analyzer))
- var/msg = "*---------*\n This is \a [src] \n"
- if(seed)
- msg += seed.get_analyzer_text()
- msg += " "
- to_chat(usr, msg)
- return
-
-/obj/item/grown/proc/add_juice()
- if(reagents)
- return 1
- return 0
-
-
-/obj/item/grown/Crossed(atom/movable/AM)
- if(seed)
- for(var/datum/plant_gene/trait/T in seed.genes)
- T.on_cross(src, AM)
- ..()
-
-/obj/item/grown/throw_impact(atom/hit_atom)
- if(!..()) //was it caught by a mob?
- if(seed)
- for(var/datum/plant_gene/trait/T in seed.genes)
- T.on_throw_impact(src, hit_atom)
-
-/obj/item/grown/microwave_act(obj/machine/microwave/M)
- return
+// **********************
+// Other harvested materials from plants (that are not food)
+// **********************
+
+/obj/item/grown // Grown weapons
+ name = "grown_weapon"
+ icon = 'icons/obj/hydroponics/harvest.dmi'
+ resistance_flags = FLAMMABLE
+ var/obj/item/seeds/seed = null // type path, gets converted to item on New(). It's safe to assume it's always a seed item.
+
+/obj/item/grown/Initialize(newloc, obj/item/seeds/new_seed)
+ . = ..()
+ create_reagents(50)
+
+ if(new_seed)
+ seed = new_seed.Copy()
+ else if(ispath(seed))
+ // This is for adminspawn or map-placed growns. They get the default stats of their seed type.
+ seed = new seed()
+ seed.adjust_potency(50-seed.potency)
+
+ pixel_x = rand(-5, 5)
+ pixel_y = rand(-5, 5)
+
+ if(seed)
+ for(var/datum/plant_gene/trait/T in seed.genes)
+ T.on_new(src, newloc)
+
+ if(istype(src, seed.product)) // no adding reagents if it is just a trash item
+ seed.prepare_result(src)
+ transform *= TransformUsingVariable(seed.potency, 100, 0.5)
+ add_juice()
+
+
+/obj/item/grown/attackby(obj/item/O, mob/user, params)
+ ..()
+ if (istype(O, /obj/item/device/plant_analyzer))
+ var/msg = "*---------*\n This is \a [src] \n"
+ if(seed)
+ msg += seed.get_analyzer_text()
+ msg += " "
+ to_chat(usr, msg)
+ return
+
+/obj/item/grown/proc/add_juice()
+ if(reagents)
+ return 1
+ return 0
+
+
+/obj/item/grown/Crossed(atom/movable/AM)
+ if(seed)
+ for(var/datum/plant_gene/trait/T in seed.genes)
+ T.on_cross(src, AM)
+ ..()
+
+/obj/item/grown/throw_impact(atom/hit_atom)
+ if(!..()) //was it caught by a mob?
+ if(seed)
+ for(var/datum/plant_gene/trait/T in seed.genes)
+ T.on_throw_impact(src, hit_atom)
+
+/obj/item/grown/microwave_act(obj/machine/microwave/M)
+ return
diff --git a/code/modules/jobs/job_exp.dm b/code/modules/jobs/job_exp.dm
index f7679898d4..220fa2e9ac 100644
--- a/code/modules/jobs/job_exp.dm
+++ b/code/modules/jobs/job_exp.dm
@@ -6,13 +6,13 @@ GLOBAL_PROTECT(exp_to_update)
/datum/job/proc/required_playtime_remaining(client/C)
if(!C)
return 0
- if(!config.use_exp_tracking)
+ if(!CONFIG_GET(flag/use_exp_tracking))
return 0
if(!exp_requirements || !exp_type)
return 0
if(!job_is_xp_locked(src.title))
return 0
- if(config.use_exp_restrictions_admin_bypass && check_rights(R_ADMIN, FALSE, C.mob))
+ if(CONFIG_GET(flag/use_exp_restrictions_admin_bypass) && check_rights(R_ADMIN, FALSE, C.mob))
return 0
var/isexempt = C.prefs.db_flags & DB_FLAG_EXEMPT
if(isexempt)
@@ -26,20 +26,21 @@ GLOBAL_PROTECT(exp_to_update)
/datum/job/proc/get_exp_req_amount()
if(title in GLOB.command_positions)
- if(config.use_exp_restrictions_heads_hours)
- return config.use_exp_restrictions_heads_hours * 60
+ var/uerhh = CONFIG_GET(number/use_exp_restrictions_heads_hours)
+ if(uerhh)
+ return uerhh * 60
return exp_requirements
/datum/job/proc/get_exp_req_type()
if(title in GLOB.command_positions)
- if(config.use_exp_restrictions_heads_department && exp_type_department)
+ if(CONFIG_GET(flag/use_exp_restrictions_heads_department) && exp_type_department)
return exp_type_department
return exp_type
/proc/job_is_xp_locked(jobtitle)
- if(!config.use_exp_restrictions_heads && jobtitle in GLOB.command_positions)
+ if(!CONFIG_GET(flag/use_exp_restrictions_heads) && jobtitle in GLOB.command_positions)
return FALSE
- if(!config.use_exp_restrictions_other && !(jobtitle in GLOB.command_positions))
+ if(!CONFIG_GET(flag/use_exp_restrictions_other) && !(jobtitle in GLOB.command_positions))
return FALSE
return TRUE
@@ -55,7 +56,7 @@ GLOBAL_PROTECT(exp_to_update)
return amount
/client/proc/get_exp_report()
- if(!config.use_exp_tracking)
+ if(!CONFIG_GET(flag/use_exp_tracking))
return "Tracking is disabled in the server configuration file."
var/list/play_records = prefs.exp
if(!play_records.len)
@@ -86,7 +87,7 @@ GLOBAL_PROTECT(exp_to_update)
return_text += "[dep] [get_exp_format(exp_data[dep])] ([percentage]%) "
else
return_text += "[dep] [get_exp_format(exp_data[dep])] "
- if(config.use_exp_restrictions_admin_bypass && check_rights(R_ADMIN, 0, mob))
+ if(CONFIG_GET(flag/use_exp_restrictions_admin_bypass) && check_rights(R_ADMIN, 0, mob))
return_text += "Admin (all jobs auto-unlocked) "
return_text += ""
var/list/jobs_locked = list()
@@ -139,7 +140,7 @@ GLOBAL_PROTECT(exp_to_update)
//resets a client's exp to what was in the db.
/client/proc/set_exp_from_db()
- if(!config.use_exp_tracking)
+ if(!CONFIG_GET(flag/use_exp_tracking))
return -1
if(!SSdbcore.Connect())
return -1
@@ -181,7 +182,7 @@ GLOBAL_PROTECT(exp_to_update)
/client/proc/update_exp_list(minutes, announce_changes = FALSE)
- if(!config.use_exp_tracking)
+ if(!CONFIG_GET(flag/use_exp_tracking))
return -1
if(!SSdbcore.Connect())
return -1
diff --git a/code/modules/jobs/job_types/assistant.dm b/code/modules/jobs/job_types/assistant.dm
index 41c3cd0a94..26d57d1e76 100644
--- a/code/modules/jobs/job_types/assistant.dm
+++ b/code/modules/jobs/job_types/assistant.dm
@@ -1,42 +1,43 @@
-/*
-Assistant
-*/
-/datum/job/assistant
- title = "Assistant"
- flag = ASSISTANT
- department_flag = CIVILIAN
- faction = "Station"
- total_positions = -1
- spawn_positions = -1
- supervisors = "absolutely everyone"
- selection_color = "#dddddd"
- access = list() //See /datum/job/assistant/get_access()
- minimal_access = list() //See /datum/job/assistant/get_access()
- outfit = /datum/outfit/job/assistant
-
-
-/datum/job/assistant/get_access()
- if((config.jobs_have_maint_access & ASSISTANTS_HAVE_MAINT_ACCESS) || !config.jobs_have_minimal_access) //Config has assistant maint access set
- . = ..()
+/*
+Assistant
+*/
+/datum/job/assistant
+ title = "Assistant"
+ flag = ASSISTANT
+ department_flag = CIVILIAN
+ faction = "Station"
+ total_positions = -1
+ spawn_positions = -1
+ supervisors = "absolutely everyone"
+ selection_color = "#dddddd"
+ access = list() //See /datum/job/assistant/get_access()
+ minimal_access = list() //See /datum/job/assistant/get_access()
+ outfit = /datum/outfit/job/assistant
+
+
+/datum/job/assistant/get_access()
+ if(CONFIG_GET(flag/assistants_have_maint_access) || !CONFIG_GET(flag/jobs_have_minimal_access)) //Config has assistant maint access set
+ . = ..()
. |= list(ACCESS_MAINT_TUNNELS)
- else
- return ..()
-
-/datum/job/assistant/config_check()
- if(config && !(config.assistant_cap == 0))
- total_positions = config.assistant_cap
- spawn_positions = config.assistant_cap
- return 1
- return 0
-
-
-/datum/outfit/job/assistant
- name = "Assistant"
- jobtype = /datum/job/assistant
-
-/datum/outfit/job/assistant/pre_equip(mob/living/carbon/human/H)
- ..()
- if (config.grey_assistants)
- uniform = /obj/item/clothing/under/color/grey
- else
- uniform = /obj/item/clothing/under/color/random
+ else
+ return ..()
+
+/datum/job/assistant/config_check()
+ var/ac = CONFIG_GET(number/assistant_cap)
+ if(ac != 0)
+ total_positions = ac
+ spawn_positions = ac
+ return 1
+ return 0
+
+
+/datum/outfit/job/assistant
+ name = "Assistant"
+ jobtype = /datum/job/assistant
+
+/datum/outfit/job/assistant/pre_equip(mob/living/carbon/human/H)
+ ..()
+ if (CONFIG_GET(flag/grey_assistants))
+ uniform = /obj/item/clothing/under/color/grey
+ else
+ uniform = /obj/item/clothing/under/color/random
diff --git a/code/modules/jobs/job_types/job.dm b/code/modules/jobs/job_types/job.dm
index 6b736db7fe..2e18807541 100644
--- a/code/modules/jobs/job_types/job.dm
+++ b/code/modules/jobs/job_types/job.dm
@@ -75,7 +75,7 @@
if(!visualsOnly && announce)
announce(H)
- if(config.enforce_human_authority && (title in GLOB.command_positions))
+ if(CONFIG_GET(flag/enforce_human_authority) && (title in GLOB.command_positions))
H.dna.features["tail_human"] = "None"
H.dna.features["ears"] = "None"
H.regenerate_icons()
@@ -86,12 +86,12 @@
. = list()
- if(config.jobs_have_minimal_access)
+ if(CONFIG_GET(flag/jobs_have_minimal_access))
. = src.minimal_access.Copy()
else
. = src.access.Copy()
- if(config.jobs_have_maint_access & EVERYONE_HAS_MAINT_ACCESS) //Config has global maint access set
+ if(CONFIG_GET(flag/everyone_has_maint_access)) //Config has global maint access set
. |= list(ACCESS_MAINT_TUNNELS)
/datum/job/proc/announce_head(var/mob/living/carbon/human/H, var/channels) //tells the given channel that the given mob is the new department head. See communications.dm for valid channels.
@@ -109,7 +109,7 @@
/datum/job/proc/available_in_days(client/C)
if(!C)
return 0
- if(!config.use_age_restriction_for_jobs)
+ if(!CONFIG_GET(flag/use_age_restriction_for_jobs))
return 0
if(!isnum(C.player_age))
return 0 //This is only a number if the db connection is established, otherwise it is text: "Requires database", meaning these restrictions cannot be enforced
diff --git a/code/modules/jobs/job_types/security.dm b/code/modules/jobs/job_types/security.dm
index 67a705455c..442b75c972 100644
--- a/code/modules/jobs/job_types/security.dm
+++ b/code/modules/jobs/job_types/security.dm
@@ -1,6 +1,6 @@
//Warden and regular officers add this result to their get_access()
/datum/job/proc/check_config_for_sec_maint()
- if(config.jobs_have_maint_access & SECURITY_HAS_MAINT_ACCESS)
+ if(CONFIG_GET(flag/security_has_maint_access))
return list(ACCESS_MAINT_TUNNELS)
return list()
@@ -246,7 +246,7 @@ GLOBAL_LIST_INIT(available_depts, list(SEC_DEPT_ENGINEERING, SEC_DEPT_MEDICAL, S
W.access |= dep_access
var/teleport = 0
- if(!config.sec_start_brig)
+ if(!CONFIG_GET(flag/sec_start_brig))
if(destination || spawn_point)
teleport = 1
if(teleport)
diff --git a/code/modules/jobs/job_types/silicon.dm b/code/modules/jobs/job_types/silicon.dm
index 2e0a710d41..bc3b31b2bf 100644
--- a/code/modules/jobs/job_types/silicon.dm
+++ b/code/modules/jobs/job_types/silicon.dm
@@ -1,57 +1,55 @@
-/*
-AI
-*/
-/datum/job/ai
- title = "AI"
- flag = AI_JF
- department_flag = ENGSEC
- faction = "Station"
- total_positions = 0
- spawn_positions = 1
- selection_color = "#ccffcc"
- supervisors = "your laws"
- req_admin_notify = 1
- minimal_player_age = 30
+/*
+AI
+*/
+/datum/job/ai
+ title = "AI"
+ flag = AI_JF
+ department_flag = ENGSEC
+ faction = "Station"
+ total_positions = 0
+ spawn_positions = 1
+ selection_color = "#ccffcc"
+ supervisors = "your laws"
+ req_admin_notify = 1
+ minimal_player_age = 30
exp_requirements = 180
exp_type = EXP_TYPE_CREW
-
-/datum/job/ai/equip(mob/living/carbon/human/H)
- return H.AIize(FALSE)
-
-/datum/job/ai/after_spawn(mob/living/silicon/ai/AI, mob/M)
- AI.rename_self("ai", M.client)
-
- //we may have been created after our borg
- if(SSticker.current_state == GAME_STATE_SETTING_UP)
- for(var/mob/living/silicon/robot/R in GLOB.silicon_mobs)
- if(!R.connected_ai)
- R.TryConnectToAI()
-
-
-/datum/job/ai/config_check()
- if(config && config.allow_ai)
- return 1
- return 0
-
-/*
-Cyborg
-*/
-/datum/job/cyborg
- title = "Cyborg"
- flag = CYBORG
- department_flag = ENGSEC
- faction = "Station"
- total_positions = 0
- spawn_positions = 1
- supervisors = "your laws and the AI" //Nodrak
- selection_color = "#ddffdd"
- minimal_player_age = 21
+
+/datum/job/ai/equip(mob/living/carbon/human/H)
+ return H.AIize(FALSE)
+
+/datum/job/ai/after_spawn(mob/living/silicon/ai/AI, mob/M)
+ AI.rename_self("ai", M.client)
+
+ //we may have been created after our borg
+ if(SSticker.current_state == GAME_STATE_SETTING_UP)
+ for(var/mob/living/silicon/robot/R in GLOB.silicon_mobs)
+ if(!R.connected_ai)
+ R.TryConnectToAI()
+
+
+/datum/job/ai/config_check()
+ return CONFIG_GET(flag/allow_ai)
+
+/*
+Cyborg
+*/
+/datum/job/cyborg
+ title = "Cyborg"
+ flag = CYBORG
+ department_flag = ENGSEC
+ faction = "Station"
+ total_positions = 0
+ spawn_positions = 1
+ supervisors = "your laws and the AI" //Nodrak
+ selection_color = "#ddffdd"
+ minimal_player_age = 21
exp_requirements = 120
exp_type = EXP_TYPE_CREW
-
-/datum/job/cyborg/equip(mob/living/carbon/human/H)
- return H.Robotize(FALSE, FALSE)
-
-/datum/job/cyborg/after_spawn(mob/living/silicon/robot/R, mob/M)
- if(config.rename_cyborg) //name can't be set in robot/New without the client
- R.rename_self("cyborg", M.client)
\ No newline at end of file
+
+/datum/job/cyborg/equip(mob/living/carbon/human/H)
+ return H.Robotize(FALSE, FALSE)
+
+/datum/job/cyborg/after_spawn(mob/living/silicon/robot/R, mob/M)
+ if(CONFIG_GET(flag/rename_cyborg)) //name can't be set in robot/New without the client
+ R.rename_self("cyborg", M.client)
diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm
index 17d626b3a0..33f02bc759 100644
--- a/code/modules/library/lib_items.dm
+++ b/code/modules/library/lib_items.dm
@@ -1,320 +1,338 @@
-/* Library Items
- *
- * Contains:
- * Bookcase
- * Book
- * Barcode Scanner
- */
-
-/*
- * Bookcase
- */
-
-/obj/structure/bookcase
- name = "bookcase"
- icon = 'icons/obj/library.dmi'
- icon_state = "bookempty"
- anchored = FALSE
- density = TRUE
- opacity = 0
- resistance_flags = FLAMMABLE
- max_integrity = 200
- armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 0)
- var/state = 0
- var/list/allowed_books = list(/obj/item/book, /obj/item/spellbook, /obj/item/storage/book) //Things allowed in the bookcase
-
-
-/obj/structure/bookcase/Initialize(mapload)
- . = ..()
- if(!mapload)
- return
- state = 2
- icon_state = "book-0"
- anchored = TRUE
- for(var/obj/item/I in loc)
- if(istype(I, /obj/item/book))
- I.loc = src
- update_icon()
-
-
-/obj/structure/bookcase/attackby(obj/item/I, mob/user, params)
- switch(state)
- if(0)
- if(istype(I, /obj/item/wrench))
- playsound(loc, I.usesound, 100, 1)
- if(do_after(user, 20*I.toolspeed, target = src))
- to_chat(user, "You wrench the frame into place. ")
- anchored = TRUE
- state = 1
- if(istype(I, /obj/item/crowbar))
- playsound(loc, I.usesound, 100, 1)
- if(do_after(user, 20*I.toolspeed, target = src))
- to_chat(user, "You pry the frame apart. ")
- deconstruct(TRUE)
-
- if(1)
- if(istype(I, /obj/item/stack/sheet/mineral/wood))
- var/obj/item/stack/sheet/mineral/wood/W = I
- if(W.get_amount() >= 2)
- W.use(2)
- to_chat(user, "You add a shelf. ")
- state = 2
- icon_state = "book-0"
- if(istype(I, /obj/item/wrench))
- playsound(loc, I.usesound, 100, 1)
- to_chat(user, "You unwrench the frame. ")
- anchored = FALSE
- state = 0
-
- if(2)
- if(is_type_in_list(I, allowed_books))
- if(!user.drop_item())
- return
- I.loc = src
- update_icon()
- else if(istype(I, /obj/item/storage/bag/books))
- var/obj/item/storage/bag/books/B = I
- for(var/obj/item/T in B.contents)
- if(istype(T, /obj/item/book) || istype(T, /obj/item/spellbook))
- B.remove_from_storage(T, src)
- to_chat(user, "You empty \the [I] into \the [src]. ")
- update_icon()
- else if(istype(I, /obj/item/pen))
- var/newname = stripped_input(user, "What would you like to title this bookshelf?")
- if(!newname)
- return
- else
- name = ("bookcase ([sanitize(newname)])")
- else if(istype(I, /obj/item/crowbar))
- if(contents.len)
- to_chat(user, "You need to remove the books first! ")
- else
- playsound(loc, I.usesound, 100, 1)
- to_chat(user, "You pry the shelf out. ")
- new /obj/item/stack/sheet/mineral/wood(loc, 2)
- state = 1
- icon_state = "bookempty"
- else
- return ..()
-
-
-/obj/structure/bookcase/attack_hand(mob/user)
- if(contents.len)
- var/obj/item/book/choice = input("Which book would you like to remove from the shelf?") as null|obj in contents
- if(choice)
- if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
- return
- if(ishuman(user))
- if(!user.get_active_held_item())
- user.put_in_hands(choice)
- else
- choice.loc = get_turf(src)
- update_icon()
-
-
-/obj/structure/bookcase/deconstruct(disassembled = TRUE)
- new /obj/item/stack/sheet/mineral/wood(loc, 4)
- for(var/obj/item/book/B in contents)
- B.forceMove(get_turf(src))
- qdel(src)
-
-
-/obj/structure/bookcase/update_icon()
- if(contents.len < 5)
- icon_state = "book-[contents.len]"
- else
- icon_state = "book-5"
-
-
-/obj/structure/bookcase/manuals/medical
- name = "medical manuals bookcase"
-
-/obj/structure/bookcase/manuals/medical/New()
- ..()
- new /obj/item/book/manual/medical_cloning(src)
- update_icon()
-
-
-/obj/structure/bookcase/manuals/engineering
- name = "engineering manuals bookcase"
-
-/obj/structure/bookcase/manuals/engineering/New()
- ..()
- new /obj/item/book/manual/wiki/engineering_construction(src)
- new /obj/item/book/manual/engineering_particle_accelerator(src)
- new /obj/item/book/manual/wiki/engineering_hacking(src)
- new /obj/item/book/manual/wiki/engineering_guide(src)
- new /obj/item/book/manual/engineering_singularity_safety(src)
- new /obj/item/book/manual/robotics_cyborgs(src)
- update_icon()
-
-
-/obj/structure/bookcase/manuals/research_and_development
- name = "\improper R&D manuals bookcase"
-
-/obj/structure/bookcase/manuals/research_and_development/New()
- ..()
- new /obj/item/book/manual/research_and_development(src)
- update_icon()
-
-
-/*
- * Book
- */
-/obj/item/book
- name = "book"
- icon = 'icons/obj/library.dmi'
- icon_state ="book"
- throw_speed = 1
- throw_range = 5
- w_class = WEIGHT_CLASS_NORMAL //upped to three because books are, y'know, pretty big. (and you could hide them inside eachother recursively forever)
- attack_verb = list("bashed", "whacked", "educated")
- resistance_flags = FLAMMABLE
- var/dat //Actual page content
- var/due_date = 0 //Game time in 1/10th seconds
- var/author //Who wrote the thing, can be changed by pen or PC. It is not automatically assigned
- var/unique = 0 //0 - Normal book, 1 - Should not be treated as normal book, unable to be copied, unable to be modified
- var/title //The real name of the book.
- var/window_size = null // Specific window size for the book, i.e: "1920x1080", Size x Width
-
-/obj/item/book/attack_self(mob/user)
- if(is_blind(user))
- to_chat(user, "As you are trying to read, you suddenly feel very stupid! ")
- return
- if(ismonkey(user))
- to_chat(user, "You skim through the book but can't comprehend any of it. ")
- return
- if(dat)
- user << browse("Penned by [author]. " + "[dat]", "window=book[window_size != null ? ";size=[window_size]" : ""]")
- user.visible_message("[user] opens a book titled \"[title]\" and begins reading intently.")
- onclose(user, "book")
- else
- to_chat(user, "This book is completely blank! ")
-
-
-/obj/item/book/attackby(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/pen))
- if(is_blind(user))
- to_chat(user, " As you are trying to write on the book, you suddenly feel very stupid! ")
- return
- if(unique)
- to_chat(user, "These pages don't seem to take the ink well! Looks like you can't modify it. ")
- return
- var/choice = input("What would you like to change?") in list("Title", "Contents", "Author", "Cancel")
- switch(choice)
- if("Title")
- var/newtitle = reject_bad_text(stripped_input(usr, "Write a new title:"))
- if (length(newtitle) > 20)
- to_chat(usr, "That title won't fit on the cover!")
- return
- if(!newtitle)
- to_chat(usr, "That title is invalid.")
- return
- else
- name = newtitle
- title = newtitle
- if("Contents")
- var/content = stripped_input(usr, "Write your book's contents (HTML NOT allowed):","","",8192)
- if(!content)
- to_chat(usr, "The content is invalid.")
- return
- else
- dat += content
- if("Author")
- var/newauthor = stripped_input(usr, "Write the author's name:")
- if(!newauthor)
- to_chat(usr, "The name is invalid.")
- return
- else
- author = newauthor
- else
- return
-
- else if(istype(I, /obj/item/barcodescanner))
- var/obj/item/barcodescanner/scanner = I
- if(!scanner.computer)
- to_chat(user, "[I]'s screen flashes: 'No associated computer found!'")
- else
- switch(scanner.mode)
- if(0)
- scanner.book = src
- to_chat(user, "[I]'s screen flashes: 'Book stored in buffer.'")
- if(1)
- scanner.book = src
- scanner.computer.buffer_book = name
- to_chat(user, "[I]'s screen flashes: 'Book stored in buffer. Book title stored in associated computer buffer.'")
- if(2)
- scanner.book = src
- for(var/datum/borrowbook/b in scanner.computer.checkouts)
- if(b.bookname == name)
- scanner.computer.checkouts.Remove(b)
- to_chat(user, "[I]'s screen flashes: 'Book stored in buffer. Book has been checked in.'")
- return
- to_chat(user, "[I]'s screen flashes: 'Book stored in buffer. No active check-out record found for current title.'")
- if(3)
- scanner.book = src
- for(var/obj/item/book in scanner.computer.inventory)
- if(book == src)
- to_chat(user, "[I]'s screen flashes: 'Book stored in buffer. Title already present in inventory, aborting to avoid duplicate entry.'")
- return
- scanner.computer.inventory.Add(src)
- to_chat(user, "[I]'s screen flashes: 'Book stored in buffer. Title added to general inventory.'")
-
- else if(istype(I, /obj/item/kitchen/knife) || istype(I, /obj/item/wirecutters))
- to_chat(user, "You begin to carve out [title]... ")
- if(do_after(user, 30, target = src))
- to_chat(user, "You carve out the pages from [title]! You didn't want to read it anyway. ")
- var/obj/item/storage/book/B = new
- B.name = src.name
- B.title = src.title
- B.icon_state = src.icon_state
- if(user.is_holding(src))
- qdel(src)
- user.put_in_hands(B)
- return
- else
- B.loc = src.loc
- qdel(src)
- return
- return
- else
- ..()
-
-
-/*
- * Barcode Scanner
- */
-/obj/item/barcodescanner
- name = "barcode scanner"
- icon = 'icons/obj/library.dmi'
- icon_state ="scanner"
- throw_speed = 3
- throw_range = 5
- w_class = WEIGHT_CLASS_TINY
- var/obj/machinery/computer/libraryconsole/bookmanagement/computer //Associated computer - Modes 1 to 3 use this
- var/obj/item/book/book //Currently scanned book
- var/mode = 0 //0 - Scan only, 1 - Scan and Set Buffer, 2 - Scan and Attempt to Check In, 3 - Scan and Attempt to Add to Inventory
-
-/obj/item/barcodescanner/attack_self(mob/user)
- mode += 1
- if(mode > 3)
- mode = 0
- to_chat(user, "[src] Status Display:")
- var/modedesc
- switch(mode)
- if(0)
- modedesc = "Scan book to local buffer."
- if(1)
- modedesc = "Scan book to local buffer and set associated computer buffer to match."
- if(2)
- modedesc = "Scan book to local buffer, attempt to check in scanned book."
- if(3)
- modedesc = "Scan book to local buffer, attempt to add book to general inventory."
- else
- modedesc = "ERROR"
- to_chat(user, " - Mode [mode] : [modedesc]")
- if(computer)
- to_chat(user, "Computer has been associated with this unit. ")
- else
- to_chat(user, "No associated computer found. Only local scans will function properly. ")
- to_chat(user, "\n")
\ No newline at end of file
+/* Library Items
+ *
+ * Contains:
+ * Bookcase
+ * Book
+ * Barcode Scanner
+ */
+
+/*
+ * Bookcase
+ */
+
+/obj/structure/bookcase
+ name = "bookcase"
+ icon = 'icons/obj/library.dmi'
+ icon_state = "bookempty"
+ desc = "A great place for storing knowledge."
+ anchored = FALSE
+ density = TRUE
+ opacity = 0
+ resistance_flags = FLAMMABLE
+ max_integrity = 200
+ armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 0)
+ var/state = 0
+ var/list/allowed_books = list(/obj/item/book, /obj/item/spellbook, /obj/item/storage/book) //Things allowed in the bookcase
+
+
+/obj/structure/bookcase/examine(mob/user)
+ ..()
+ if(!anchored)
+ to_chat(user, "The bolts on the bottom are unsecured. ")
+ if(anchored)
+ to_chat(user, "It's secured in place with bolts . ")
+ switch(state)
+ if(0)
+ to_chat(user, "There's a small crack visible on the back panel. ")
+ if(1)
+ to_chat(user, "There's space inside for a wooden shelf. ")
+ if(2)
+ to_chat(user, "There's a small crack visible on the shelf. ")
+
+
+/obj/structure/bookcase/Initialize(mapload)
+ . = ..()
+ if(!mapload)
+ return
+ state = 2
+ icon_state = "book-0"
+ anchored = TRUE
+ for(var/obj/item/I in loc)
+ if(istype(I, /obj/item/book))
+ I.loc = src
+ update_icon()
+
+
+/obj/structure/bookcase/attackby(obj/item/I, mob/user, params)
+ switch(state)
+ if(0)
+ if(istype(I, /obj/item/wrench))
+ playsound(loc, I.usesound, 100, 1)
+ if(do_after(user, 20*I.toolspeed, target = src))
+ to_chat(user, "You wrench the frame into place. ")
+ anchored = TRUE
+ state = 1
+ if(istype(I, /obj/item/crowbar))
+ playsound(loc, I.usesound, 100, 1)
+ if(do_after(user, 20*I.toolspeed, target = src))
+ to_chat(user, "You pry the frame apart. ")
+ deconstruct(TRUE)
+
+ if(1)
+ if(istype(I, /obj/item/stack/sheet/mineral/wood))
+ var/obj/item/stack/sheet/mineral/wood/W = I
+ if(W.get_amount() >= 2)
+ W.use(2)
+ to_chat(user, "You add a shelf. ")
+ state = 2
+ icon_state = "book-0"
+ if(istype(I, /obj/item/wrench))
+ playsound(loc, I.usesound, 100, 1)
+ to_chat(user, "You unwrench the frame. ")
+ anchored = FALSE
+ state = 0
+
+ if(2)
+ if(is_type_in_list(I, allowed_books))
+ if(!user.drop_item())
+ return
+ I.loc = src
+ update_icon()
+ else if(istype(I, /obj/item/storage/bag/books))
+ var/obj/item/storage/bag/books/B = I
+ for(var/obj/item/T in B.contents)
+ if(istype(T, /obj/item/book) || istype(T, /obj/item/spellbook))
+ B.remove_from_storage(T, src)
+ to_chat(user, "You empty \the [I] into \the [src]. ")
+ update_icon()
+ else if(istype(I, /obj/item/pen))
+ var/newname = stripped_input(user, "What would you like to title this bookshelf?")
+ if(!newname)
+ return
+ else
+ name = ("bookcase ([sanitize(newname)])")
+ else if(istype(I, /obj/item/crowbar))
+ if(contents.len)
+ to_chat(user, "You need to remove the books first! ")
+ else
+ playsound(loc, I.usesound, 100, 1)
+ to_chat(user, "You pry the shelf out. ")
+ new /obj/item/stack/sheet/mineral/wood(loc, 2)
+ state = 1
+ icon_state = "bookempty"
+ else
+ return ..()
+
+
+/obj/structure/bookcase/attack_hand(mob/user)
+ if(contents.len)
+ var/obj/item/book/choice = input("Which book would you like to remove from the shelf?") as null|obj in contents
+ if(choice)
+ if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
+ return
+ if(ishuman(user))
+ if(!user.get_active_held_item())
+ user.put_in_hands(choice)
+ else
+ choice.loc = get_turf(src)
+ update_icon()
+
+
+/obj/structure/bookcase/deconstruct(disassembled = TRUE)
+ new /obj/item/stack/sheet/mineral/wood(loc, 4)
+ for(var/obj/item/book/B in contents)
+ B.forceMove(get_turf(src))
+ qdel(src)
+
+
+/obj/structure/bookcase/update_icon()
+ if(contents.len < 5)
+ icon_state = "book-[contents.len]"
+ else
+ icon_state = "book-5"
+
+
+/obj/structure/bookcase/manuals/medical
+ name = "medical manuals bookcase"
+
+/obj/structure/bookcase/manuals/medical/New()
+ ..()
+ new /obj/item/book/manual/medical_cloning(src)
+ update_icon()
+
+
+/obj/structure/bookcase/manuals/engineering
+ name = "engineering manuals bookcase"
+
+/obj/structure/bookcase/manuals/engineering/New()
+ ..()
+ new /obj/item/book/manual/wiki/engineering_construction(src)
+ new /obj/item/book/manual/engineering_particle_accelerator(src)
+ new /obj/item/book/manual/wiki/engineering_hacking(src)
+ new /obj/item/book/manual/wiki/engineering_guide(src)
+ new /obj/item/book/manual/engineering_singularity_safety(src)
+ new /obj/item/book/manual/robotics_cyborgs(src)
+ update_icon()
+
+
+/obj/structure/bookcase/manuals/research_and_development
+ name = "\improper R&D manuals bookcase"
+
+/obj/structure/bookcase/manuals/research_and_development/New()
+ ..()
+ new /obj/item/book/manual/research_and_development(src)
+ update_icon()
+
+
+/*
+ * Book
+ */
+/obj/item/book
+ name = "book"
+ icon = 'icons/obj/library.dmi'
+ icon_state ="book"
+ desc = "Crack it open, inhale the musk of its pages, and learn something new."
+ throw_speed = 1
+ throw_range = 5
+ w_class = WEIGHT_CLASS_NORMAL //upped to three because books are, y'know, pretty big. (and you could hide them inside eachother recursively forever)
+ attack_verb = list("bashed", "whacked", "educated")
+ resistance_flags = FLAMMABLE
+ var/dat //Actual page content
+ var/due_date = 0 //Game time in 1/10th seconds
+ var/author //Who wrote the thing, can be changed by pen or PC. It is not automatically assigned
+ var/unique = 0 //0 - Normal book, 1 - Should not be treated as normal book, unable to be copied, unable to be modified
+ var/title //The real name of the book.
+ var/window_size = null // Specific window size for the book, i.e: "1920x1080", Size x Width
+
+/obj/item/book/attack_self(mob/user)
+ if(is_blind(user))
+ to_chat(user, "As you are trying to read, you suddenly feel very stupid! ")
+ return
+ if(ismonkey(user))
+ to_chat(user, "You skim through the book but can't comprehend any of it. ")
+ return
+ if(dat)
+ user << browse("Penned by [author]. " + "[dat]", "window=book[window_size != null ? ";size=[window_size]" : ""]")
+ user.visible_message("[user] opens a book titled \"[title]\" and begins reading intently.")
+ onclose(user, "book")
+ else
+ to_chat(user, "This book is completely blank! ")
+
+
+/obj/item/book/attackby(obj/item/I, mob/user, params)
+ if(istype(I, /obj/item/pen))
+ if(is_blind(user))
+ to_chat(user, " As you are trying to write on the book, you suddenly feel very stupid! ")
+ return
+ if(unique)
+ to_chat(user, "These pages don't seem to take the ink well! Looks like you can't modify it. ")
+ return
+ var/choice = input("What would you like to change?") in list("Title", "Contents", "Author", "Cancel")
+ switch(choice)
+ if("Title")
+ var/newtitle = reject_bad_text(stripped_input(usr, "Write a new title:"))
+ if (length(newtitle) > 20)
+ to_chat(usr, "That title won't fit on the cover!")
+ return
+ if(!newtitle)
+ to_chat(usr, "That title is invalid.")
+ return
+ else
+ name = newtitle
+ title = newtitle
+ if("Contents")
+ var/content = stripped_input(usr, "Write your book's contents (HTML NOT allowed):","","",8192)
+ if(!content)
+ to_chat(usr, "The content is invalid.")
+ return
+ else
+ dat += content
+ if("Author")
+ var/newauthor = stripped_input(usr, "Write the author's name:")
+ if(!newauthor)
+ to_chat(usr, "The name is invalid.")
+ return
+ else
+ author = newauthor
+ else
+ return
+
+ else if(istype(I, /obj/item/barcodescanner))
+ var/obj/item/barcodescanner/scanner = I
+ if(!scanner.computer)
+ to_chat(user, "[I]'s screen flashes: 'No associated computer found!'")
+ else
+ switch(scanner.mode)
+ if(0)
+ scanner.book = src
+ to_chat(user, "[I]'s screen flashes: 'Book stored in buffer.'")
+ if(1)
+ scanner.book = src
+ scanner.computer.buffer_book = name
+ to_chat(user, "[I]'s screen flashes: 'Book stored in buffer. Book title stored in associated computer buffer.'")
+ if(2)
+ scanner.book = src
+ for(var/datum/borrowbook/b in scanner.computer.checkouts)
+ if(b.bookname == name)
+ scanner.computer.checkouts.Remove(b)
+ to_chat(user, "[I]'s screen flashes: 'Book stored in buffer. Book has been checked in.'")
+ return
+ to_chat(user, "[I]'s screen flashes: 'Book stored in buffer. No active check-out record found for current title.'")
+ if(3)
+ scanner.book = src
+ for(var/obj/item/book in scanner.computer.inventory)
+ if(book == src)
+ to_chat(user, "[I]'s screen flashes: 'Book stored in buffer. Title already present in inventory, aborting to avoid duplicate entry.'")
+ return
+ scanner.computer.inventory.Add(src)
+ to_chat(user, "[I]'s screen flashes: 'Book stored in buffer. Title added to general inventory.'")
+
+ else if(istype(I, /obj/item/kitchen/knife) || istype(I, /obj/item/wirecutters))
+ to_chat(user, "You begin to carve out [title]... ")
+ if(do_after(user, 30, target = src))
+ to_chat(user, "You carve out the pages from [title]! You didn't want to read it anyway. ")
+ var/obj/item/storage/book/B = new
+ B.name = src.name
+ B.title = src.title
+ B.icon_state = src.icon_state
+ if(user.is_holding(src))
+ qdel(src)
+ user.put_in_hands(B)
+ return
+ else
+ B.loc = src.loc
+ qdel(src)
+ return
+ return
+ else
+ ..()
+
+
+/*
+ * Barcode Scanner
+ */
+/obj/item/barcodescanner
+ name = "barcode scanner"
+ icon = 'icons/obj/library.dmi'
+ icon_state ="scanner"
+ desc = "A fabulous tool if you need to scan a barcode."
+ throw_speed = 3
+ throw_range = 5
+ w_class = WEIGHT_CLASS_TINY
+ var/obj/machinery/computer/libraryconsole/bookmanagement/computer //Associated computer - Modes 1 to 3 use this
+ var/obj/item/book/book //Currently scanned book
+ var/mode = 0 //0 - Scan only, 1 - Scan and Set Buffer, 2 - Scan and Attempt to Check In, 3 - Scan and Attempt to Add to Inventory
+
+/obj/item/barcodescanner/attack_self(mob/user)
+ mode += 1
+ if(mode > 3)
+ mode = 0
+ to_chat(user, "[src] Status Display:")
+ var/modedesc
+ switch(mode)
+ if(0)
+ modedesc = "Scan book to local buffer."
+ if(1)
+ modedesc = "Scan book to local buffer and set associated computer buffer to match."
+ if(2)
+ modedesc = "Scan book to local buffer, attempt to check in scanned book."
+ if(3)
+ modedesc = "Scan book to local buffer, attempt to add book to general inventory."
+ else
+ modedesc = "ERROR"
+ to_chat(user, " - Mode [mode] : [modedesc]")
+ if(computer)
+ to_chat(user, "Computer has been associated with this unit. ")
+ else
+ to_chat(user, "No associated computer found. Only local scans will function properly. ")
+ to_chat(user, "\n")
diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm
index 99127cd595..dc48bbae2d 100644
--- a/code/modules/library/lib_machines.dm
+++ b/code/modules/library/lib_machines.dm
@@ -20,6 +20,7 @@
icon_screen = "library"
icon_keyboard = null
circuit = /obj/item/circuitboard/computer/libraryconsole
+ desc = "Checked out books MUST be returned on time."
var/screenstate = 0
var/title
var/category = "Any"
@@ -161,6 +162,7 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
// It's December 25th, 2014, and this is STILL here, and it's STILL relevant. Kill me
/obj/machinery/computer/libraryconsole/bookmanagement
name = "book inventory management console"
+ desc = "Librarian's command station."
var/arcanecheckout = 0
screenstate = 0 // 0 - Main Menu, 1 - Inventory, 2 - Checked Out, 3 - Check Out a Book
verb_say = "beeps"
@@ -498,6 +500,7 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
name = "scanner control interface"
icon = 'icons/obj/library.dmi'
icon_state = "bigscanner"
+ desc = "It servers the purpose of scanning stuff."
anchored = TRUE
density = TRUE
var/obj/item/book/cache // Last scanned book
@@ -554,6 +557,7 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
name = "book binder"
icon = 'icons/obj/library.dmi'
icon_state = "binder"
+ desc = "Only intended for binding paper products."
anchored = TRUE
density = TRUE
var/busy = FALSE
diff --git a/code/modules/mining/equipment/wormhole_jaunter.dm b/code/modules/mining/equipment/wormhole_jaunter.dm
index e0197cc4e3..d72d0e5f73 100644
--- a/code/modules/mining/equipment/wormhole_jaunter.dm
+++ b/code/modules/mining/equipment/wormhole_jaunter.dm
@@ -94,7 +94,7 @@
if(!ismob(M) && !isobj(M)) //No don't teleport lighting and effects!
return
- if(M.anchored && (!ismob(M) || (istype(M, /obj/mecha) && !mech_sized)))
+ if(M.anchored && (!ismob(M) || (ismecha(M) && !mech_sized)))
return
if(do_teleport(M, hard_target, 6))
diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm
index 58c971024f..e16077fec1 100644
--- a/code/modules/mining/lavaland/necropolis_chests.dm
+++ b/code/modules/mining/lavaland/necropolis_chests.dm
@@ -435,7 +435,7 @@
if(!over_object)
return
- if (istype(usr.loc, /obj/mecha))
+ if(ismecha(usr.loc))
return
if(!M.incapacitated())
diff --git a/code/modules/mining/machine_stacking.dm b/code/modules/mining/machine_stacking.dm
index 96589fb575..0c9bcdc170 100644
--- a/code/modules/mining/machine_stacking.dm
+++ b/code/modules/mining/machine_stacking.dm
@@ -4,6 +4,7 @@
name = "stacking machine console"
icon = 'icons/obj/machines/mining_machines.dmi'
icon_state = "console"
+ desc = "Controls a stacking machine... in theory."
density = FALSE
anchored = TRUE
var/obj/machinery/mineral/stacking_machine/machine = null
@@ -60,6 +61,7 @@
name = "stacking machine"
icon = 'icons/obj/machines/mining_machines.dmi'
icon_state = "stacker"
+ desc = "A machine that automatically stacks acquired materials. Controlled by a nearby console."
density = TRUE
anchored = TRUE
var/obj/machinery/mineral/stacking_unit_console/CONSOLE
@@ -90,4 +92,4 @@
var/obj/item/stack/sheet/out = new inp.type()
out.amount = stack_amt
unload_mineral(out)
- storage.amount -= stack_amt
\ No newline at end of file
+ storage.amount -= stack_amt
diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm
index 8a6250403f..26b671dd96 100644
--- a/code/modules/mob/dead/dead.dm
+++ b/code/modules/mob/dead/dead.dm
@@ -11,7 +11,7 @@ INITIALIZE_IMMEDIATE(/mob/dead)
prepare_huds()
- if(config.cross_allowed)
+ if(CONFIG_GET(string/cross_server_address))
verbs += /mob/dead/proc/server_hop
return INITIALIZE_HINT_NORMAL
@@ -32,19 +32,20 @@ INITIALIZE_IMMEDIATE(/mob/dead)
set desc= "Jump to the other server"
if(notransform)
return
- if(!config.cross_allowed)
+ var/csa = CONFIG_GET(string/cross_server_address)
+ if(csa)
verbs -= /mob/dead/proc/server_hop
to_chat(src, "Server Hop has been disabled. ")
return
- if (alert(src, "Jump to server running at [config.cross_address]?", "Server Hop", "Yes", "No") != "Yes")
+ if (alert(src, "Jump to server running at [csa]?", "Server Hop", "Yes", "No") != "Yes")
return 0
- if (client && config.cross_allowed)
- to_chat(src, "Sending you to [config.cross_address]. ")
+ if (client && csa)
+ to_chat(src, "Sending you to [csa]. ")
new /obj/screen/splash(client)
notransform = TRUE
sleep(29) //let the animation play
notransform = FALSE
winset(src, null, "command=.options") //other wise the user never knows if byond is downloading resources
- client << link(config.cross_address + "?server_hop=[key]")
+ client << link(csa + "?server_hop=[key]")
else
to_chat(src, "There is no other server configured! ")
diff --git a/code/modules/mob/dead/new_player/login.dm b/code/modules/mob/dead/new_player/login.dm
index 1e3561c8a0..26d05c6ff0 100644
--- a/code/modules/mob/dead/new_player/login.dm
+++ b/code/modules/mob/dead/new_player/login.dm
@@ -1,5 +1,5 @@
/mob/dead/new_player/Login()
- if(config.use_exp_tracking)
+ if(CONFIG_GET(flag/use_exp_tracking))
client.set_exp_from_db()
client.set_db_player_flags()
if(!mind)
@@ -15,20 +15,12 @@
if(GLOB.admin_notice)
to_chat(src, "Admin Notice: \n \t [GLOB.admin_notice] ")
- if(config.soft_popcap && living_player_count() >= config.soft_popcap)
- to_chat(src, "Server Notice: \n \t [config.soft_popcap_message] ")
+ var/spc = CONFIG_GET(number/soft_popcap)
+ if(spc && living_player_count() >= spc)
+ to_chat(src, "Server Notice: \n \t [CONFIG_GET(string/soft_popcap_message)] ")
sight |= SEE_TURFS
-/*
- var/list/watch_locations = list()
- for(var/obj/effect/landmark/landmark in landmarks_list)
- if(landmark.tag == "landmark*new_player")
- watch_locations += landmark.loc
-
- if(watch_locations.len>0)
- loc = pick(watch_locations)
-*/
new_player_panel()
client.playtitlemusic()
if(SSticker.current_state < GAME_STATE_SETTING_UP)
diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm
index 4ecf2845db..aca1d9b63f 100644
--- a/code/modules/mob/dead/new_player/new_player.dm
+++ b/code/modules/mob/dead/new_player/new_player.dm
@@ -97,10 +97,12 @@
//Determines Relevent Population Cap
var/relevant_cap
- if(config.hard_popcap && config.extreme_popcap)
- relevant_cap = min(config.hard_popcap, config.extreme_popcap)
+ var/hpc = CONFIG_GET(number/hard_popcap)
+ var/epc = CONFIG_GET(number/extreme_popcap)
+ if(hpc && epc)
+ relevant_cap = min(hpc, epc)
else
- relevant_cap = max(config.hard_popcap, config.extreme_popcap)
+ relevant_cap = max(hpc, epc)
if(href_list["show_preferences"])
client.prefs.ShowChoices(src)
@@ -133,7 +135,7 @@
return
if(SSticker.queued_players.len || (relevant_cap && living_player_count() >= relevant_cap && !(ckey(key) in GLOB.admin_datums)))
- to_chat(usr, "[config.hard_popcap_message] ")
+ to_chat(usr, "[CONFIG_GET(string/hard_popcap_message)] ")
var/queue_position = SSticker.queued_players.Find(usr)
if(queue_position == 1)
@@ -309,7 +311,7 @@
return 0
if(job.required_playtime_remaining(client))
return 0
- if(config.enforce_human_authority && !client.prefs.pref_species.qualifies_for_rank(rank, client.prefs.features))
+ if(CONFIG_GET(flag/enforce_human_authority) && !client.prefs.pref_species.qualifies_for_rank(rank, client.prefs.features))
return 0
return 1
@@ -326,11 +328,11 @@
var/arrivals_docked = TRUE
if(SSshuttle.arrivals)
close_spawn_windows() //In case we get held up
- if(SSshuttle.arrivals.damaged && config.arrivals_shuttle_require_safe_latejoin)
+ if(SSshuttle.arrivals.damaged && CONFIG_GET(flag/arrivals_shuttle_require_safe_latejoin))
src << alert("The arrivals shuttle is currently malfunctioning! You cannot join.")
return FALSE
- if(config.arrivals_shuttle_require_undocked)
+ if(CONFIG_GET(flag/arrivals_shuttle_require_undocked))
SSshuttle.arrivals.RequireUndocked(src)
arrivals_docked = SSshuttle.arrivals.mode != SHUTTLE_CALL
@@ -374,7 +376,7 @@
GLOB.joined_player_list += character.ckey
GLOB.latejoiners += character
- if(config.allow_latejoin_antagonists && humanc) //Borgs aren't allowed to be antags. Will need to be tweaked if we get true latejoin ais.
+ if(CONFIG_GET(flag/allow_latejoin_antagonists) && humanc) //Borgs aren't allowed to be antags. Will need to be tweaked if we get true latejoin ais.
if(SSshuttle.emergency)
switch(SSshuttle.emergency.mode)
if(SHUTTLE_RECALL, SHUTTLE_IDLE)
@@ -458,7 +460,7 @@
var/mob/living/carbon/human/H = new(loc)
- if(config.force_random_names || jobban_isbanned(src, "appearance"))
+ if(CONFIG_GET(flag/force_random_names) || jobban_isbanned(src, "appearance"))
client.prefs.random_character()
client.prefs.real_name = client.prefs.pref_species.random_name(gender,1)
client.prefs.copy_to(H)
diff --git a/code/modules/mob/dead/new_player/preferences_setup.dm b/code/modules/mob/dead/new_player/preferences_setup.dm
index 0a8dc6c733..831fde141e 100644
--- a/code/modules/mob/dead/new_player/preferences_setup.dm
+++ b/code/modules/mob/dead/new_player/preferences_setup.dm
@@ -14,7 +14,7 @@
facial_hair_color = hair_color
eye_color = random_eye_color()
if(!pref_species)
- var/rando_race = pick(config.roundstart_races)
+ var/rando_race = pick(CONFIG_GET(keyed_flag_list/roundstart_races))
pref_species = new rando_race()
features = random_features()
age = rand(AGE_MIN,AGE_MAX)
@@ -59,6 +59,7 @@
if(previewJob && !nude)
mannequin.job = previewJob.title
previewJob.equip(mannequin, TRUE)
+ mannequin.compile_overlays()
CHECK_TICK
preview_icon = icon('icons/effects/effects.dmi', "nothing")
preview_icon.Scale(48+32, 16+32)
diff --git a/code/modules/mob/dead/new_player/sprite_accessories.dm b/code/modules/mob/dead/new_player/sprite_accessories.dm
index 03b7fd53ec..1eb1379dce 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories.dm
@@ -67,317 +67,30 @@
/datum/sprite_accessory/hair
icon = 'icons/mob/human_face.dmi' // default icon for all hairs
-//Place in order by major style E.G "Afro, Bun, Ponytail"
-//Place different versions under the same style E.G "Bun > Large Bun, Ponytail > Long Ponytail"
-//A
+/datum/sprite_accessory/hair/short
+ name = "Short Hair" // try to capatilize the names please~ // try to spell
+ icon_state = "hair_a" // you do not need to define _s or _l sub-states, game automatically does this for you
-/datum/sprite_accessory/hair/afro
- name = "Afro" // try to capatilize the names please~ // try to spell
- icon_state = "hair_afro" // you do not need to define _s or _l sub-states, game automatically does this for you
+/datum/sprite_accessory/hair/shorthair2
+ name = "Short Hair 2"
+ icon_state = "hair_shorthair2"
-/datum/sprite_accessory/hair/afro2
- name = "Afro 2"
- icon_state = "hair_afro2"
-
-/datum/sprite_accessory/hair/afro_large
- name = "Big Afro"
- icon_state = "hair_bigafro"
-
-/datum/sprite_accessory/hair/antenna
- name = "Ahoge"
- icon_state = "hair_antenna"
-//B
-
-/datum/sprite_accessory/hair/bald
- name = "Bald"
- icon_state = null
-
-/datum/sprite_accessory/hair/balding
- name = "Balding Hair"
- icon_state = "hair_e"
-
-/datum/sprite_accessory/hair/longbangs
- name = "Long Bangs"
- icon_state = "hair_lbangs"
-
-/datum/sprite_accessory/hair/bedhead
- name = "Bedhead"
- icon_state = "hair_bedhead"
-
-/datum/sprite_accessory/hair/bedhead2
- name = "Bedhead 2"
- icon_state = "hair_bedheadv2"
-
-/datum/sprite_accessory/hair/bedhead3
- name = "Bedhead 3"
- icon_state = "hair_bedheadv3"
-
-/datum/sprite_accessory/hair/beehive
- name = "Beehive"
- icon_state = "hair_beehive"
-
-/datum/sprite_accessory/hair/beehive2
- name = "Beehive 2"
- icon_state = "hair_beehivev2"
-
-/datum/sprite_accessory/hair/bob
- name = "Bob"
- icon_state = "hair_bobcut"
-
-/datum/sprite_accessory/hair/bobcurl
- name = "Bobcurl"
- icon_state = "hair_bobcurl"
-
-/datum/sprite_accessory/hair/bob
- name = "Bob Hair"
- icon_state = "hair_bob"
-
-/datum/sprite_accessory/hair/bob2
- name = "Bob Hair 2"
- icon_state = "hair_bob2"
-
-/datum/sprite_accessory/hair/boddicker
- name = "Boddicker"
- icon_state = "hair_boddicker"
-
-/datum/sprite_accessory/hair/bowl
- name = "Bowl"
- icon_state = "hair_bowlcut"
-
-/datum/sprite_accessory/hair/braided
- name = "Braided"
- icon_state = "hair_braided"
-
-/datum/sprite_accessory/hair/front_braid
- name = "Braided front"
- icon_state = "hair_braidfront"
-
-/datum/sprite_accessory/hair/braidtail
- name = "Braided Tail"
- icon_state = "hair_braidtail"
-
-/datum/sprite_accessory/hair/lowbraid
- name = "Low Braid"
- icon_state = "hair_hbraid"
-
-/datum/sprite_accessory/hair/not_floorlength_braid
- name = "High Braid"
- icon_state = "hair_braid2"
-
-/datum/sprite_accessory/hair/shortbraid
- name = "Short Braid"
- icon_state = "hair_shortbraid"
-
-/datum/sprite_accessory/hair/braid
- name = "Floorlength Braid"
- icon_state = "hair_braid"
-
-/datum/sprite_accessory/hair/business
- name = "Business Hair"
- icon_state = "hair_business"
-
-/datum/sprite_accessory/hair/business2
- name = "Business Hair 2"
- icon_state = "hair_business2"
-
-/datum/sprite_accessory/hair/business3
- name = "Business Hair 3"
- icon_state = "hair_business3"
-
-/datum/sprite_accessory/hair/business4
- name = "Business Hair 4"
- icon_state = "hair_business4"
-
-/datum/sprite_accessory/hair/bun
- name = "Bun Head"
- icon_state = "hair_bun"
-
-/datum/sprite_accessory/hair/bun2
- name = "Bun Head 2"
- icon_state = "hair_bunhead2"
-
-/datum/sprite_accessory/hair/largebun
- name = "Large Bun"
- icon_state = "hair_largebun"
-
-/datum/sprite_accessory/hair/buzz
- name = "Buzzcut"
- icon_state = "hair_buzzcut"
-
-//C
-
-/datum/sprite_accessory/hair/crew
- name = "Crewcut"
- icon_state = "hair_crewcut"
-
-/datum/sprite_accessory/hair/combover
- name = "Combover"
- icon_state = "hair_combover"
-
-/datum/sprite_accessory/hair/curls
- name = "Curls"
- icon_state = "hair_curls"
-
-//D
-
-/datum/sprite_accessory/hair/devillock
- name = "Devil Lock"
- icon_state = "hair_devilock"
-
-/datum/sprite_accessory/hair/dreadlocks
- name = "Dreadlocks"
- icon_state = "hair_dreads"
-
-/datum/sprite_accessory/hair/drillhair
- name = "Drill Hair"
- icon_state = "hair_drillhair"
-
-//E
-
-/datum/sprite_accessory/hair/emo
- name = "Emo"
- icon_state = "hair_emo"
-
-/datum/sprite_accessory/hair/longemo
- name = "Long Emo"
- icon_state = "hair_longemo"
-
-//F
-
-/datum/sprite_accessory/hair/feather
- name = "Feather"
- icon_state = "hair_feather"
-
-/datum/sprite_accessory/hair/sargeant
- name = "Flat Top"
- icon_state = "hair_sargeant"
-
-/datum/sprite_accessory/hair/bigflattop
- name = "Big Flat Top"
- icon_state = "hair_bigflattop"
-
-/datum/sprite_accessory/hair/fag
- name = "Flow Hair"
- icon_state = "hair_f"
-
-/datum/sprite_accessory/hair/longfringe
- name = "Long Fringe"
- icon_state = "hair_longfringe"
-
-/datum/sprite_accessory/hair/longestalt
- name = "Longer Fringe"
- icon_state = "hair_vlongfringe"
-
-//G
-
-/datum/sprite_accessory/hair/gelled
- name = "Gelled Back"
- icon_state = "hair_gelled"
-
-/datum/sprite_accessory/hair/gentle
- name = "Gentle"
- icon_state = "hair_gentle"
-
-//H
+/datum/sprite_accessory/hair/shorthair3
+ name = "Short Hair 3"
+ icon_state = "hair_shorthair3"
/datum/sprite_accessory/hair/cut
name = "Cut Hair"
icon_state = "hair_c"
-/datum/sprite_accessory/hair/halfbang
- name = "Half-banged Hair"
- icon_state = "hair_halfbang"
-
-/datum/sprite_accessory/hair/halfbang2
- name = "Half-banged Hair 2"
- icon_state = "hair_halfbang2"
-
-/datum/sprite_accessory/hair/hedgehog
- name = "Hedgehog Hair"
- icon_state = "hair_hedgehog"
-
-/datum/sprite_accessory/hair/hitop
- name = "Hitop"
- icon_state = "hair_hitop"
-
-/datum/sprite_accessory/hair/himecut
- name = "Hime Cut"
- icon_state = "hair_himecut"
-
-/datum/sprite_accessory/hair/himecut2
- name = "Hime Cut 2"
- icon_state = "hair_himecut2"
-
-/datum/sprite_accessory/hair/himeup
- name = "Hime Updo"
- icon_state = "hair_himeup"
-
-//I
-
-//J
-
-/datum/sprite_accessory/hair/jensen
- name = "Jensen Hair"
- icon_state = "hair_jensen"
-
-//K
-
-/datum/sprite_accessory/hair/keanu
- name = "Keanu Hair"
- icon_state = "hair_keanu"
-
-/datum/sprite_accessory/hair/kusangi
- name = "Kusanagi Hair"
- icon_state = "hair_kusanagi"
-
-//L
+/datum/sprite_accessory/hair/long
+ name = "Shoulder-length Hair"
+ icon_state = "hair_b"
/datum/sprite_accessory/hair/longer
name = "Long Hair"
icon_state = "hair_vlong"
-/datum/sprite_accessory/hair/long
- name = "Long Hair 1"
- icon_state = "hair_long"
-
-/datum/sprite_accessory/hair/long2
- name = "Long Hair 2"
- icon_state = "hair_long2"
-
-/datum/sprite_accessory/hair/longest
- name = "Very Long Hair"
- icon_state = "hair_longest"
-
-//M
-
-/datum/sprite_accessory/hair/megaeyebrows
- name = "Mega Eyebrows"
- icon_state = "hair_megaeyebrows"
-
-/datum/sprite_accessory/hair/messy
- name = "Messy"
- icon_state = "hair_messy"
-
-/datum/sprite_accessory/hair/mohawk
- name = "Mohawk"
- icon_state = "hair_d"
-
-/datum/sprite_accessory/hair/reversemohawk
- name = "Reverse Mohawk"
- icon_state = "hair_reversemohawk"
-
-//N
-
-//O
-
-/datum/sprite_accessory/hair/odango
- name = "Odango"
- icon_state = "hair_odango"
-
-/datum/sprite_accessory/hair/ombre
- name = "Ombre"
- icon_state = "hair_ombre"
-
/datum/sprite_accessory/hair/over_eye
name = "Over Eye"
icon_state = "hair_shortovereye"
@@ -390,39 +103,29 @@
name = "Very Long Over Eye"
icon_state = "hair_longest2"
-//P
+/datum/sprite_accessory/hair/longest
+ name = "Very Long Hair"
+ icon_state = "hair_longest"
-/datum/sprite_accessory/hair/parted
- name = "Parted"
- icon_state = "hair_parted"
+/datum/sprite_accessory/hair/longfringe
+ name = "Long Fringe"
+ icon_state = "hair_longfringe"
-/datum/sprite_accessory/hair/sidepartlongalt
- name = "Long Side Part"
- icon_state = "hair_longsidepart"
+/datum/sprite_accessory/hair/longestalt
+ name = "Longer Fringe"
+ icon_state = "hair_vlongfringe"
-/datum/sprite_accessory/hair/kagami
- name = "Pigtails"
- icon_state = "hair_kagami"
+/datum/sprite_accessory/hair/gentle
+ name = "Gentle"
+ icon_state = "hair_gentle"
-/datum/sprite_accessory/hair/pigtail
- name = "Pigtails 2"
- icon_state = "hair_pigtails"
+/datum/sprite_accessory/hair/halfbang
+ name = "Half-banged Hair"
+ icon_state = "hair_halfbang"
-/datum/sprite_accessory/hair/pigtail
- name = "Pigtails 3"
- icon_state = "hair_pigtails2"
-
-/datum/sprite_accessory/hair/pixie
- name = "Pixie Cut"
- icon_state = "hair_pixie"
-
-/datum/sprite_accessory/hair/pompadour
- name = "Pompadour"
- icon_state = "hair_pompadour"
-
-/datum/sprite_accessory/hair/bigpompadour
- name = "Big Pompadour"
- icon_state = "hair_bigpompadour"
+/datum/sprite_accessory/hair/halfbang2
+ name = "Half-banged Hair 2"
+ icon_state = "hair_halfbang2"
/datum/sprite_accessory/hair/ponytail1
name = "Ponytail"
@@ -444,36 +147,6 @@
name = "Ponytail 5"
icon_state = "hair_ponytail5"
-/datum/sprite_accessory/hair/highponytail
- name = "High Ponytail"
- icon_state = "hair_highponytail"
-
-/datum/sprite_accessory/hair/longponytail
- name = "Long Ponytail"
- icon_state = "hair_longstraightponytail"
-
-//Q
-
-/datum/sprite_accessory/hair/quiff
- name = "Quiff"
- icon_state = "hair_quiff"
-
-
-//R
-
-//S
-
-/datum/sprite_accessory/hair/oneshoulder
- name = "One Shoulder"
- icon_state = "hair_oneshoulder"
-
-/datum/sprite_accessory/hair/tressshoulder
- name = "Tress Shoulder"
- icon_state = "hair_tressshoulder"
-
-/datum/sprite_accessory/hair/sidecut
- name = "Sidecut"
- icon_state = "hair_sidecut"
/datum/sprite_accessory/hair/sidetail
name = "Side Pony"
@@ -491,33 +164,141 @@
name = "Side Pony 4"
icon_state = "hair_sidetail4"
-/datum/sprite_accessory/hair/short
- name = "Short Hair"
- icon_state = "hair_a"
+/datum/sprite_accessory/hair/oneshoulder
+ name = "One Shoulder"
+ icon_state = "hair_oneshoulder"
-/datum/sprite_accessory/hair/shorthair2
- name = "Short Hair 2"
- icon_state = "hair_shorthair2"
-
-/datum/sprite_accessory/hair/shorthair3
- name = "Short Hair 3"
- icon_state = "hair_shorthair3"
-
-/datum/sprite_accessory/hair/long
- name = "Shoulder-length Hair"
- icon_state = "hair_b"
+/datum/sprite_accessory/hair/tressshoulder
+ name = "Tress Shoulder"
+ icon_state = "hair_tressshoulder"
/datum/sprite_accessory/hair/parted
- name = "Side Part"
- icon_state = "hair_part"
+ name = "Parted"
+ icon_state = "hair_parted"
-/datum/sprite_accessory/hair/skinhead
- name = "Skinhead"
- icon_state = "hair_skinhead"
+/datum/sprite_accessory/hair/pompadour
+ name = "Pompadour"
+ icon_state = "hair_pompadour"
-/datum/sprite_accessory/hair/protagonist
- name = "Slightly Long"
- icon_state = "hair_protagonist"
+/datum/sprite_accessory/hair/bigpompadour
+ name = "Big Pompadour"
+ icon_state = "hair_bigpompadour"
+
+/datum/sprite_accessory/hair/quiff
+ name = "Quiff"
+ icon_state = "hair_quiff"
+
+/datum/sprite_accessory/hair/bedhead
+ name = "Bedhead"
+ icon_state = "hair_bedhead"
+
+/datum/sprite_accessory/hair/bedhead2
+ name = "Bedhead 2"
+ icon_state = "hair_bedheadv2"
+
+/datum/sprite_accessory/hair/bedhead3
+ name = "Bedhead 3"
+ icon_state = "hair_bedheadv3"
+
+/datum/sprite_accessory/hair/messy
+ name = "Messy"
+ icon_state = "hair_messy"
+
+/datum/sprite_accessory/hair/beehive
+ name = "Beehive"
+ icon_state = "hair_beehive"
+
+/datum/sprite_accessory/hair/beehive2
+ name = "Beehive 2"
+ icon_state = "hair_beehivev2"
+
+/datum/sprite_accessory/hair/bobcurl
+ name = "Bobcurl"
+ icon_state = "hair_bobcurl"
+
+/datum/sprite_accessory/hair/bob
+ name = "Bob"
+ icon_state = "hair_bobcut"
+
+/datum/sprite_accessory/hair/bowl
+ name = "Bowl"
+ icon_state = "hair_bowlcut"
+
+/datum/sprite_accessory/hair/buzz
+ name = "Buzzcut"
+ icon_state = "hair_buzzcut"
+
+/datum/sprite_accessory/hair/crew
+ name = "Crewcut"
+ icon_state = "hair_crewcut"
+
+/datum/sprite_accessory/hair/combover
+ name = "Combover"
+ icon_state = "hair_combover"
+
+/datum/sprite_accessory/hair/devillock
+ name = "Devil Lock"
+ icon_state = "hair_devilock"
+
+/datum/sprite_accessory/hair/dreadlocks
+ name = "Dreadlocks"
+ icon_state = "hair_dreads"
+
+/datum/sprite_accessory/hair/curls
+ name = "Curls"
+ icon_state = "hair_curls"
+
+/datum/sprite_accessory/hair/afro
+ name = "Afro"
+ icon_state = "hair_afro"
+
+/datum/sprite_accessory/hair/afro2
+ name = "Afro 2"
+ icon_state = "hair_afro2"
+
+/datum/sprite_accessory/hair/afro_large
+ name = "Big Afro"
+ icon_state = "hair_bigafro"
+
+/datum/sprite_accessory/hair/sargeant
+ name = "Flat Top"
+ icon_state = "hair_sargeant"
+
+/datum/sprite_accessory/hair/emo
+ name = "Emo"
+ icon_state = "hair_emo"
+
+/datum/sprite_accessory/hair/longemo
+ name = "Long Emo"
+ icon_state = "hair_longemo"
+
+/datum/sprite_accessory/hair/fag
+ name = "Flow Hair"
+ icon_state = "hair_f"
+
+/datum/sprite_accessory/hair/feather
+ name = "Feather"
+ icon_state = "hair_feather"
+
+/datum/sprite_accessory/hair/hitop
+ name = "Hitop"
+ icon_state = "hair_hitop"
+
+/datum/sprite_accessory/hair/mohawk
+ name = "Mohawk"
+ icon_state = "hair_d"
+
+/datum/sprite_accessory/hair/reversemohawk
+ name = "Reverse Mohawk"
+ icon_state = "hair_reversemohawk"
+
+/datum/sprite_accessory/hair/jensen
+ name = "Jensen Hair"
+ icon_state = "hair_jensen"
+
+/datum/sprite_accessory/hair/gelled
+ name = "Gelled Back"
+ icon_state = "hair_gelled"
/datum/sprite_accessory/hair/spiky
name = "Spiky"
@@ -531,6 +312,122 @@
name = "Spiky 3"
icon_state = "hair_spiky2"
+/datum/sprite_accessory/hair/protagonist
+ name = "Slightly Long"
+ icon_state = "hair_protagonist"
+
+/datum/sprite_accessory/hair/kusangi
+ name = "Kusanagi Hair"
+ icon_state = "hair_kusanagi"
+
+/datum/sprite_accessory/hair/kagami
+ name = "Pigtails"
+ icon_state = "hair_kagami"
+
+/datum/sprite_accessory/hair/pigtail
+ name = "Pigtails 2"
+ icon_state = "hair_pigtails"
+
+/datum/sprite_accessory/hair/pigtail
+ name = "Pigtails 3"
+ icon_state = "hair_pigtails2"
+
+/datum/sprite_accessory/hair/himecut
+ name = "Hime Cut"
+ icon_state = "hair_himecut"
+
+/datum/sprite_accessory/hair/himecut2
+ name = "Hime Cut 2"
+ icon_state = "hair_himecut2"
+
+/datum/sprite_accessory/hair/himeup
+ name = "Hime Updo"
+ icon_state = "hair_himeup"
+
+/datum/sprite_accessory/hair/antenna
+ name = "Ahoge"
+ icon_state = "hair_antenna"
+
+/datum/sprite_accessory/hair/front_braid
+ name = "Braided front"
+ icon_state = "hair_braidfront"
+
+/datum/sprite_accessory/hair/lowbraid
+ name = "Low Braid"
+ icon_state = "hair_hbraid"
+
+/datum/sprite_accessory/hair/not_floorlength_braid
+ name = "High Braid"
+ icon_state = "hair_braid2"
+
+/datum/sprite_accessory/hair/shortbraid
+ name = "Short Braid"
+ icon_state = "hair_shortbraid"
+
+/datum/sprite_accessory/hair/braid
+ name = "Floorlength Braid"
+ icon_state = "hair_braid"
+
+/datum/sprite_accessory/hair/odango
+ name = "Odango"
+ icon_state = "hair_odango"
+
+/datum/sprite_accessory/hair/ombre
+ name = "Ombre"
+ icon_state = "hair_ombre"
+
+/datum/sprite_accessory/hair/updo
+ name = "Updo"
+ icon_state = "hair_updo"
+
+/datum/sprite_accessory/hair/skinhead
+ name = "Skinhead"
+ icon_state = "hair_skinhead"
+
+/datum/sprite_accessory/hair/longbangs
+ name = "Long Bangs"
+ icon_state = "hair_lbangs"
+
+/datum/sprite_accessory/hair/balding
+ name = "Balding Hair"
+ icon_state = "hair_e"
+
+/datum/sprite_accessory/hair/bald
+ name = "Bald"
+ icon_state = null
+
+/datum/sprite_accessory/hair/parted
+ name = "Side Part"
+ icon_state = "hair_part"
+
+/datum/sprite_accessory/hair/braided
+ name = "Braided"
+ icon_state = "hair_braided"
+
+/datum/sprite_accessory/hair/bun
+ name = "Bun Head"
+ icon_state = "hair_bun"
+
+/datum/sprite_accessory/hair/bun2
+ name = "Bun Head 2"
+ icon_state = "hair_bunhead2"
+
+/datum/sprite_accessory/hair/braidtail
+ name = "Braided Tail"
+ icon_state = "hair_braidtail"
+
+/datum/sprite_accessory/hair/bigflattop
+ name = "Big Flat Top"
+ icon_state = "hair_bigflattop"
+
+/datum/sprite_accessory/hair/drillhair
+ name = "Drill Hair"
+ icon_state = "hair_drillhair"
+
+/datum/sprite_accessory/hair/keanu
+ name = "Keanu Hair"
+ icon_state = "hair_keanu"
+
/datum/sprite_accessory/hair/swept
name = "Swept Back Hair"
icon_state = "hair_swept"
@@ -539,24 +436,73 @@
name = "Swept Back Hair 2"
icon_state = "hair_swept2"
-//T
+/datum/sprite_accessory/hair/business
+ name = "Business Hair"
+ icon_state = "hair_business"
-//U
+/datum/sprite_accessory/hair/business2
+ name = "Business Hair 2"
+ icon_state = "hair_business2"
-/datum/sprite_accessory/hair/updo
- name = "Updo"
- icon_state = "hair_updo"
+/datum/sprite_accessory/hair/business3
+ name = "Business Hair 3"
+ icon_state = "hair_business3"
-//V
+/datum/sprite_accessory/hair/business4
+ name = "Business Hair 4"
+ icon_state = "hair_business4"
-//W
+/datum/sprite_accessory/hair/hedgehog
+ name = "Hedgehog Hair"
+ icon_state = "hair_hedgehog"
-//X
+/datum/sprite_accessory/hair/bob
+ name = "Bob Hair"
+ icon_state = "hair_bob"
-//Y
+/datum/sprite_accessory/hair/bob2
+ name = "Bob Hair 2"
+ icon_state = "hair_bob2"
-//Z
+/datum/sprite_accessory/hair/boddicker
+ name = "Boddicker"
+ icon_state = "hair_boddicker"
+/datum/sprite_accessory/hair/long
+ name = "Long Hair 1"
+ icon_state = "hair_long"
+
+/datum/sprite_accessory/hair/long2
+ name = "Long Hair 2"
+ icon_state = "hair_long2"
+
+/datum/sprite_accessory/hair/pixie
+ name = "Pixie Cut"
+ icon_state = "hair_pixie"
+
+/datum/sprite_accessory/hair/megaeyebrows
+ name = "Mega Eyebrows"
+ icon_state = "hair_megaeyebrows"
+
+/datum/sprite_accessory/hair/highponytail
+ name = "High Ponytail"
+ icon_state = "hair_highponytail"
+
+/datum/sprite_accessory/hair/longponytail
+ name = "Long Ponytail"
+ icon_state = "hair_longstraightponytail"
+
+/datum/sprite_accessory/hair/sidepartlongalt
+ name = "Long Side Part"
+ icon_state = "hair_longsidepart"
+
+/datum/sprite_accessory/hair/sidecut
+ name = "Sidecut"
+ icon_state = "hair_sidecut"
+
+/datum/sprite_accessory/hair/largebun
+ name = "Large Bun"
+ icon_state = "hair_largebun"
/////////////////////////////
// Facial Hair Definitions //
@@ -570,81 +516,82 @@
icon_state = null
gender = NEUTER
-/datum/sprite_accessory/facial_hair/abe
- name = "Abraham Lincoln Beard"
- icon_state = "facial_abe"
-
-/datum/sprite_accessory/facial_hair/brokenman
- name = "Broken Man"
- icon_state = "facial_brokenman"
-
-/datum/sprite_accessory/facial_hair/chinstrap
- name = "Chinstrap"
- icon_state = "facial_chin"
-
-/datum/sprite_accessory/facial_hair/dwarf
- name = "Dwarf Beard"
- icon_state = "facial_dwarf"
-
-/datum/sprite_accessory/facial_hair/elvis
- name = "Elvis Sideburns"
- icon_state = "facial_elvis"
-
-/datum/sprite_accessory/facial_hair/fiveoclock
- name = "Five o Clock Shadow"
- icon_state = "facial_fiveoclock"
-
-/datum/sprite_accessory/facial_hair/fullbeard
- name = "Full Beard"
- icon_state = "facial_fullbeard"
-
-/datum/sprite_accessory/facial_hair/fu
- name = "Fu Manchu"
- icon_state = "facial_fumanchu"
-
-/datum/sprite_accessory/facial_hair/gt
- name = "Goatee"
- icon_state = "facial_gt"
-
-/datum/sprite_accessory/facial_hair/hip
- name = "Hipster Beard"
- icon_state = "facial_hip"
+/datum/sprite_accessory/facial_hair/watson
+ name = "Watson Mustache"
+ icon_state = "facial_watson"
/datum/sprite_accessory/facial_hair/hogan
name = "Hulk Hogan Mustache"
icon_state = "facial_hogan" //-Neek
-
-/datum/sprite_accessory/facial_hair/jensen
- name = "Jensen Beard"
- icon_state = "facial_jensen"
-
-/datum/sprite_accessory/facial_hair/longbeard
- name = "Long Beard"
- icon_state = "facial_longbeard"
-
-/datum/sprite_accessory/facial_hair/neckbeard
- name = "Neckbeard"
- icon_state = "facial_neckbeard"
-
-/datum/sprite_accessory/facial_hair/selleck
- name = "Selleck Mustache"
- icon_state = "facial_selleck"
-
-/datum/sprite_accessory/facial_hair/chaplin
- name = "Square Mustache"
- icon_state = "facial_chaplin"
-
+
/datum/sprite_accessory/facial_hair/vandyke
name = "Van Dyke Mustache"
icon_state = "facial_vandyke"
-
+
+/datum/sprite_accessory/facial_hair/chaplin
+ name = "Square Mustache"
+ icon_state = "facial_chaplin"
+
+/datum/sprite_accessory/facial_hair/selleck
+ name = "Selleck Mustache"
+ icon_state = "facial_selleck"
+
+/datum/sprite_accessory/facial_hair/neckbeard
+ name = "Neckbeard"
+ icon_state = "facial_neckbeard"
+
+/datum/sprite_accessory/facial_hair/fullbeard
+ name = "Full Beard"
+ icon_state = "facial_fullbeard"
+
+/datum/sprite_accessory/facial_hair/longbeard
+ name = "Long Beard"
+ icon_state = "facial_longbeard"
+
/datum/sprite_accessory/facial_hair/vlongbeard
name = "Very Long Beard"
icon_state = "facial_wise"
-
-/datum/sprite_accessory/facial_hair/watson
- name = "Watson Mustache"
- icon_state = "facial_watson"
+
+/datum/sprite_accessory/facial_hair/elvis
+ name = "Elvis Sideburns"
+ icon_state = "facial_elvis"
+
+/datum/sprite_accessory/facial_hair/abe
+ name = "Abraham Lincoln Beard"
+ icon_state = "facial_abe"
+
+/datum/sprite_accessory/facial_hair/chinstrap
+ name = "Chinstrap"
+ icon_state = "facial_chin"
+
+/datum/sprite_accessory/facial_hair/hip
+ name = "Hipster Beard"
+ icon_state = "facial_hip"
+
+/datum/sprite_accessory/facial_hair/gt
+ name = "Goatee"
+ icon_state = "facial_gt"
+
+/datum/sprite_accessory/facial_hair/jensen
+ name = "Jensen Beard"
+ icon_state = "facial_jensen"
+
+/datum/sprite_accessory/facial_hair/dwarf
+ name = "Dwarf Beard"
+ icon_state = "facial_dwarf"
+
+/datum/sprite_accessory/facial_hair/fiveoclock
+ name = "Five o Clock Shadow"
+ icon_state = "facial_fiveoclock"
+
+/datum/sprite_accessory/facial_hair/fu
+ name = "Fu Manchu"
+ icon_state = "facial_fumanchu"
+
+/datum/sprite_accessory/facial_hair/brokenman
+ name = "Broken Man"
+ icon_state = "facial_brokenman"
+
///////////////////////////
// Underwear Definitions //
diff --git a/code/modules/mob/living/brain/brain.dm b/code/modules/mob/living/brain/brain.dm
index c437daef48..94ed0129c7 100644
--- a/code/modules/mob/living/brain/brain.dm
+++ b/code/modules/mob/living/brain/brain.dm
@@ -19,7 +19,7 @@
/mob/living/brain/proc/create_dna()
stored_dna = new /datum/dna/stored(src)
if(!stored_dna.species)
- var/rando_race = pick(config.roundstart_races)
+ var/rando_race = pick(CONFIG_GET(keyed_flag_list/roundstart_races))
stored_dna.species = new rando_race()
/mob/living/brain/Destroy()
diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm
index 13a34b6bae..aa15e28e66 100644
--- a/code/modules/mob/living/brain/brain_item.dm
+++ b/code/modules/mob/living/brain/brain_item.dm
@@ -18,12 +18,12 @@
vital = FALSE
decoy_override = TRUE
-/obj/item/organ/brain/Insert(mob/living/carbon/C, special = 0)
+/obj/item/organ/brain/Insert(mob/living/carbon/C, special = 0,no_id_transfer = FALSE)
..()
name = "brain"
- if(C.mind && C.mind.changeling) //congrats, you're trapped in a body you don't control
+ if(C.mind && C.mind.changeling && !no_id_transfer) //congrats, you're trapped in a body you don't control
if(brainmob && !(C.stat == DEAD || (C.status_flags & FAKEDEATH)))
to_chat(brainmob, "You can't feel your body! You're still just a brain! ")
loc = C
@@ -44,13 +44,9 @@
//Update the body's icon so it doesnt appear debrained anymore
C.update_hair()
-/obj/item/organ/brain/Remove(mob/living/carbon/C, special = 0)
+/obj/item/organ/brain/Remove(mob/living/carbon/C, special = 0, no_id_transfer = FALSE)
..()
- if(!special)
- if(C.has_brain_worms())
- var/mob/living/simple_animal/borer/B = C.has_brain_worms()
- B.leave_victim() //Should remove borer if the brain is removed - RR
- if(!gc_destroyed || (owner && !owner.gc_destroyed))
+ if((!gc_destroyed || (owner && !owner.gc_destroyed)) && !no_id_transfer)
transfer_identity(C)
C.update_hair()
diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
index 0a325521b0..9d9e327fec 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
@@ -1,124 +1,126 @@
-/mob/living/carbon/alien/humanoid
- name = "alien"
- icon_state = "alien"
- pass_flags = PASSTABLE
- butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/xeno = 5, /obj/item/stack/sheet/animalhide/xeno = 1)
- possible_a_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, INTENT_HARM)
- limb_destroyer = 1
- var/obj/item/r_store = null
- var/obj/item/l_store = null
- var/caste = ""
- var/alt_icon = 'icons/mob/alienleap.dmi' //used to switch between the two alien icon files.
- var/leap_on_click = 0
- var/pounce_cooldown = 0
- var/pounce_cooldown_time = 30
- var/custom_pixel_x_offset = 0 //for admin fuckery.
- var/custom_pixel_y_offset = 0
- var/sneaking = 0 //For sneaky-sneaky mode and appropriate slowdown
- var/drooling = 0 //For Neruotoxic spit overlays
- bodyparts = list(/obj/item/bodypart/chest/alien, /obj/item/bodypart/head/alien, /obj/item/bodypart/l_arm/alien,
- /obj/item/bodypart/r_arm/alien, /obj/item/bodypart/r_leg/alien, /obj/item/bodypart/l_leg/alien)
- devourable = TRUE
-
-
-//This is fine right now, if we're adding organ specific damage this needs to be updated
-/mob/living/carbon/alien/humanoid/Initialize()
- AddAbility(new/obj/effect/proc_holder/alien/regurgitate(null))
- . = ..()
-
-/mob/living/carbon/alien/humanoid/movement_delay()
- . = ..()
- . += move_delay_add + config.alien_delay + sneaking //move_delay_add is used to slow aliens with stun
-
-/mob/living/carbon/alien/humanoid/restrained(ignore_grab)
- . = handcuffed
-
-
-/mob/living/carbon/alien/humanoid/show_inv(mob/user)
- user.set_machine(src)
- var/list/dat = list()
- dat += {"
-
- [name]
- "}
- for(var/i in 1 to held_items.len)
- var/obj/item/I = get_item_for_held_index(i)
- dat += "[get_held_index_name(i)]: [(I && !(I.flags_1 & ABSTRACT_1)) ? I : "Empty "] "
- dat += "Empty Pouches "
-
- if(handcuffed)
- dat += "Handcuffed "
- if(legcuffed)
- dat += "Legcuffed "
-
- dat += {"
-
- Close
- "}
- user << browse(dat.Join(), "window=mob\ref[src];size=325x500")
- onclose(user, "mob\ref[src]")
-
-
-/mob/living/carbon/alien/humanoid/Topic(href, href_list)
- ..()
- //strip panel
- if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY))
- if(href_list["pouches"])
- visible_message("[usr] tries to empty [src]'s pouches. ", \
- "[usr] tries to empty [src]'s pouches. ")
- if(do_mob(usr, src, POCKET_STRIP_DELAY * 0.5))
- dropItemToGround(r_store)
- dropItemToGround(l_store)
-
-/mob/living/carbon/alien/humanoid/cuff_resist(obj/item/I)
- playsound(src, 'sound/voice/hiss5.ogg', 40, 1, 1) //Alien roars when starting to break free
- ..(I, cuff_break = INSTANT_CUFFBREAK)
-
-/mob/living/carbon/alien/humanoid/resist_grab(moving_resist)
- if(pulledby.grab_state)
- visible_message("[src] has broken free of [pulledby]'s grip! ")
- pulledby.stop_pulling()
- . = 0
-
-/mob/living/carbon/alien/humanoid/get_standard_pixel_y_offset(lying = 0)
- if(leaping)
- return -32
- else if(custom_pixel_y_offset)
- return custom_pixel_y_offset
- else
- return initial(pixel_y)
-
-/mob/living/carbon/alien/humanoid/get_standard_pixel_x_offset(lying = 0)
- if(leaping)
- return -32
- else if(custom_pixel_x_offset)
- return custom_pixel_x_offset
- else
- return initial(pixel_x)
-
-/mob/living/carbon/alien/humanoid/get_permeability_protection()
- return 0.8
-
-/mob/living/carbon/alien/humanoid/alien_evolve(mob/living/carbon/alien/humanoid/new_xeno)
- drop_all_held_items()
- for(var/atom/movable/A in stomach_contents)
- stomach_contents.Remove(A)
- new_xeno.stomach_contents.Add(A)
- A.loc = new_xeno
- ..()
-
-//For alien evolution/promotion/queen finder procs. Checks for an active alien of that type
-/proc/get_alien_type(var/alienpath)
- for(var/mob/living/carbon/alien/humanoid/A in GLOB.living_mob_list)
- if(!istype(A, alienpath))
- continue
- if(!A.key || A.stat == DEAD) //Only living aliens with a ckey are valid.
- continue
- return A
- return FALSE
-
-
-/mob/living/carbon/alien/humanoid/check_breath(datum/gas_mixture/breath)
- if(breath && breath.total_moles() > 0 && !sneaking)
- playsound(get_turf(src), pick('sound/voice/lowHiss2.ogg', 'sound/voice/lowHiss3.ogg', 'sound/voice/lowHiss4.ogg'), 50, 0, -5)
- ..()
\ No newline at end of file
+/mob/living/carbon/alien/humanoid
+ name = "alien"
+ icon_state = "alien"
+ pass_flags = PASSTABLE
+ butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/xeno = 5, /obj/item/stack/sheet/animalhide/xeno = 1)
+ possible_a_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, INTENT_HARM)
+ limb_destroyer = 1
+ var/obj/item/r_store = null
+ var/obj/item/l_store = null
+ var/caste = ""
+ var/alt_icon = 'icons/mob/alienleap.dmi' //used to switch between the two alien icon files.
+ var/leap_on_click = 0
+ var/pounce_cooldown = 0
+ var/pounce_cooldown_time = 30
+ var/custom_pixel_x_offset = 0 //for admin fuckery.
+ var/custom_pixel_y_offset = 0
+ var/sneaking = 0 //For sneaky-sneaky mode and appropriate slowdown
+ var/drooling = 0 //For Neruotoxic spit overlays
+ bodyparts = list(/obj/item/bodypart/chest/alien, /obj/item/bodypart/head/alien, /obj/item/bodypart/l_arm/alien,
+ /obj/item/bodypart/r_arm/alien, /obj/item/bodypart/r_leg/alien, /obj/item/bodypart/l_leg/alien)
+
+
+//This is fine right now, if we're adding organ specific damage this needs to be updated
+/mob/living/carbon/alien/humanoid/Initialize()
+ AddAbility(new/obj/effect/proc_holder/alien/regurgitate(null))
+ . = ..()
+
+/mob/living/carbon/alien/humanoid/movement_delay()
+ . = ..()
+ var/static/config_alien_delay
+ if(isnull(config_alien_delay))
+ config_alien_delay = CONFIG_GET(number/alien_delay)
+ . += move_delay_add + config_alien_delay + sneaking //move_delay_add is used to slow aliens with stun
+
+/mob/living/carbon/alien/humanoid/restrained(ignore_grab)
+ . = handcuffed
+
+
+/mob/living/carbon/alien/humanoid/show_inv(mob/user)
+ user.set_machine(src)
+ var/list/dat = list()
+ dat += {"
+
+ [name]
+ "}
+ for(var/i in 1 to held_items.len)
+ var/obj/item/I = get_item_for_held_index(i)
+ dat += "[get_held_index_name(i)]: [(I && !(I.flags_1 & ABSTRACT_1)) ? I : "Empty "] "
+ dat += "Empty Pouches "
+
+ if(handcuffed)
+ dat += "Handcuffed "
+ if(legcuffed)
+ dat += "Legcuffed "
+
+ dat += {"
+
+ Close
+ "}
+ user << browse(dat.Join(), "window=mob\ref[src];size=325x500")
+ onclose(user, "mob\ref[src]")
+
+
+/mob/living/carbon/alien/humanoid/Topic(href, href_list)
+ ..()
+ //strip panel
+ if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY))
+ if(href_list["pouches"])
+ visible_message("[usr] tries to empty [src]'s pouches. ", \
+ "[usr] tries to empty [src]'s pouches. ")
+ if(do_mob(usr, src, POCKET_STRIP_DELAY * 0.5))
+ dropItemToGround(r_store)
+ dropItemToGround(l_store)
+
+/mob/living/carbon/alien/humanoid/cuff_resist(obj/item/I)
+ playsound(src, 'sound/voice/hiss5.ogg', 40, 1, 1) //Alien roars when starting to break free
+ ..(I, cuff_break = INSTANT_CUFFBREAK)
+
+/mob/living/carbon/alien/humanoid/resist_grab(moving_resist)
+ if(pulledby.grab_state)
+ visible_message("[src] has broken free of [pulledby]'s grip! ")
+ pulledby.stop_pulling()
+ . = 0
+
+/mob/living/carbon/alien/humanoid/get_standard_pixel_y_offset(lying = 0)
+ if(leaping)
+ return -32
+ else if(custom_pixel_y_offset)
+ return custom_pixel_y_offset
+ else
+ return initial(pixel_y)
+
+/mob/living/carbon/alien/humanoid/get_standard_pixel_x_offset(lying = 0)
+ if(leaping)
+ return -32
+ else if(custom_pixel_x_offset)
+ return custom_pixel_x_offset
+ else
+ return initial(pixel_x)
+
+/mob/living/carbon/alien/humanoid/get_permeability_protection()
+ return 0.8
+
+/mob/living/carbon/alien/humanoid/alien_evolve(mob/living/carbon/alien/humanoid/new_xeno)
+ drop_all_held_items()
+ for(var/atom/movable/A in stomach_contents)
+ stomach_contents.Remove(A)
+ new_xeno.stomach_contents.Add(A)
+ A.loc = new_xeno
+ ..()
+
+//For alien evolution/promotion/queen finder procs. Checks for an active alien of that type
+/proc/get_alien_type(var/alienpath)
+ for(var/mob/living/carbon/alien/humanoid/A in GLOB.living_mob_list)
+ if(!istype(A, alienpath))
+ continue
+ if(!A.key || A.stat == DEAD) //Only living aliens with a ckey are valid.
+ continue
+ return A
+ return FALSE
+
+
+/mob/living/carbon/alien/humanoid/check_breath(datum/gas_mixture/breath)
+ if(breath && breath.total_moles() > 0 && !sneaking)
+ playsound(get_turf(src), pick('sound/voice/lowHiss2.ogg', 'sound/voice/lowHiss3.ogg', 'sound/voice/lowHiss4.ogg'), 50, 0, -5)
+ ..()
diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index 6068ef2d66..d90db23679 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -250,6 +250,9 @@
if(health >= 0 && !(status_flags & FAKEDEATH))
if(lying)
+ if(buckled)
+ to_chat(M, "You need to unbuckle [src] first to do that!")
+ return
M.visible_message("[M] shakes [src] trying to get [p_them()] up! ", \
"You shake [src] trying to get [p_them()] up! ")
else if(check_zone(M.zone_selected) == "head")
diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm
index a1b67fbee1..282de04ede 100644
--- a/code/modules/mob/living/carbon/human/death.dm
+++ b/code/modules/mob/living/carbon/human/death.dm
@@ -29,7 +29,7 @@
dizziness = 0
jitteriness = 0
- if(istype(loc, /obj/mecha))
+ if(ismecha(loc))
var/obj/mecha/M = loc
if(M.occupant == src)
M.go_out()
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 74ccdab19c..0ca0bed9fc 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -277,9 +277,11 @@
if(!appears_dead)
if(stat == UNCONSCIOUS)
msg += "[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep.\n"
- else if(getBrainLoss() >= 60)
- msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n"
-
+ else
+ if(getBrainLoss() >= 60)
+ msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n"
+ if(InCritical())
+ msg += "[t_He] is barely concious.\n"
if(getorgan(/obj/item/organ/brain))
if(istype(src, /mob/living/carbon/human/interactive))
var/mob/living/carbon/human/interactive/auto = src
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index d66e6f808a..63b84b9cf3 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -4,6 +4,7 @@
voice_name = "Unknown"
icon = 'icons/mob/human.dmi'
icon_state = "caucasian_m"
+ appearance_flags = KEEP_TOGETHER|TILE_BOUND|PIXEL_SCALE
/mob/living/carbon/human/Initialize()
verbs += /mob/living/proc/mob_sleep
@@ -21,41 +22,12 @@
set_species(dna.species.type)
//initialise organs
- create_internal_organs()
+ create_internal_organs() //most of it is done in set_species now, this is only for parent call
handcrafting = new()
. = ..()
-/mob/living/carbon/human/create_internal_organs()
- if(!(NOHUNGER in dna.species.species_traits))
- internal_organs += new /obj/item/organ/appendix
- if(!(NOBREATH in dna.species.species_traits))
- if(dna.species.mutantlungs)
- internal_organs += new dna.species.mutantlungs()
- else
- internal_organs += new /obj/item/organ/lungs()
- if(!(NOBLOOD in dna.species.species_traits))
- internal_organs += new /obj/item/organ/heart
-
- if(!(NOLIVER in dna.species.species_traits))
- if(dna.species.mutantliver)
- internal_organs += new dna.species.mutantliver()
- else
- internal_organs += new /obj/item/organ/liver()
-
- if(!(NOSTOMACH in dna.species.species_traits))
- if(dna.species.mutantstomach)
- internal_organs += new dna.species.mutantstomach()
- else
- internal_organs += new /obj/item/organ/stomach()
-
- internal_organs += new dna.species.mutanteyes
- internal_organs += new dna.species.mutantears
- internal_organs += new dna.species.mutanttongue
- internal_organs += new /obj/item/organ/brain
- ..()
-
/mob/living/carbon/human/OpenCraftingMenu()
handcrafting.ui_interact(src)
diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm
index 06f3007e6b..4fba96df58 100644
--- a/code/modules/mob/living/carbon/human/human_movement.dm
+++ b/code/modules/mob/living/carbon/human/human_movement.dm
@@ -1,8 +1,9 @@
/mob/living/carbon/human/movement_delay()
. = 0
- . += ..()
- . += config.human_delay
- . += dna.species.movement_delay(src)
+ var/static/config_human_delay
+ if(isnull(config_human_delay))
+ config_human_delay = CONFIG_GET(number/human_delay)
+ . += ..() + config_human_delay + dna.species.movement_delay(src)
/mob/living/carbon/human/slip(knockdown_amount, obj/O, lube)
if(isobj(shoes) && (shoes.flags_1&NOSLIP_1) && !(lube&GALOSHES_DONT_HELP))
diff --git a/code/modules/mob/living/carbon/human/interactive.dm b/code/modules/mob/living/carbon/human/interactive.dm
index 91921f386d..51b65bf44f 100644
--- a/code/modules/mob/living/carbon/human/interactive.dm
+++ b/code/modules/mob/living/carbon/human/interactive.dm
@@ -667,7 +667,7 @@
equip_to_appropriate_slot(MYID)
//THIEVING SKILLS END
//-------------TOUCH ME
- if(istype(TARGET, /obj/structure))
+ if(isstructure(TARGET))
var/obj/structure/STR = TARGET
if(main_hand)
var/obj/item/W = main_hand
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 07f3acea48..34d4ae8e51 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -68,7 +68,8 @@
//Flight and floating
var/override_float = 0
-
+
+ var/obj/item/organ/brain/mutant_brain = /obj/item/organ/brain
var/obj/item/organ/eyes/mutanteyes = /obj/item/organ/eyes
var/obj/item/organ/ears/mutantears = /obj/item/organ/ears
var/obj/item/mutanthands
@@ -123,6 +124,113 @@
return 0
return 1
+//Will regenerate missing organs
+/datum/species/proc/regenerate_organs(mob/living/carbon/C,datum/species/old_species,replace_current=TRUE)
+ var/obj/item/organ/brain/brain = C.getorganslot("brain")
+ var/obj/item/organ/heart/heart = C.getorganslot("heart")
+ var/obj/item/organ/lungs/lungs = C.getorganslot("lungs")
+ var/obj/item/organ/appendix/appendix = C.getorganslot("appendix")
+ var/obj/item/organ/eyes/eyes = C.getorganslot("eye_sight")
+ var/obj/item/organ/ears/ears = C.getorganslot("ears")
+ var/obj/item/organ/tongue/tongue = C.getorganslot("tongue")
+ var/obj/item/organ/liver/liver = C.getorganslot("liver")
+ var/obj/item/organ/stomach/stomach = C.getorganslot("stomach")
+
+ var/should_have_brain = TRUE
+ var/should_have_heart = !(NOBLOOD in species_traits)
+ var/should_have_lungs = !(NOBREATH in species_traits)
+ var/should_have_appendix = !(NOHUNGER in species_traits)
+ var/should_have_eyes = TRUE
+ var/should_have_ears = TRUE
+ var/should_have_tongue = TRUE
+ var/should_have_liver = !(NOLIVER in species_traits)
+ var/should_have_stomach = !(NOSTOMACH in species_traits)
+
+ if(brain && (replace_current || !should_have_brain))
+ if(!brain.decoy_override)//Just keep it if it's fake
+ brain.Remove(C,TRUE,TRUE)
+ QDEL_NULL(brain)
+ if(should_have_brain && !brain)
+ brain = new mutant_brain()
+ brain.Insert(C, TRUE, TRUE)
+
+ if(heart && (!should_have_heart || replace_current))
+ heart.Remove(C,1)
+ QDEL_NULL(heart)
+ if(should_have_heart && !heart)
+ heart = new()
+ heart.Insert(C)
+
+ if(lungs && (replace_current || !should_have_lungs))
+ lungs.Remove(C,1)
+ QDEL_NULL(lungs)
+ if(should_have_lungs && !lungs)
+ if(mutantlungs)
+ lungs = new mutantlungs()
+ else
+ lungs = new()
+ lungs.Insert(C)
+
+ if(liver && (!should_have_liver || replace_current))
+ liver.Remove(C,1)
+ QDEL_NULL(liver)
+ if(should_have_liver && !liver)
+ if(mutantliver)
+ liver = new mutantliver()
+ else
+ liver = new()
+ liver.Insert(C)
+
+ if(stomach && (!should_have_stomach || replace_current))
+ stomach.Remove(C,1)
+ QDEL_NULL(stomach)
+ if(should_have_stomach && !stomach)
+ if(mutantstomach)
+ stomach = new mutantstomach()
+ else
+ stomach = new()
+ stomach.Insert(C)
+
+ if(appendix && (!should_have_appendix || replace_current))
+ appendix.Remove(C,1)
+ QDEL_NULL(appendix)
+ if(should_have_appendix && !appendix)
+ appendix = new()
+ appendix.Insert(C)
+
+ if(C.get_bodypart("head"))
+ if(eyes && (replace_current || !should_have_eyes))
+ eyes.Remove(C,1)
+ QDEL_NULL(eyes)
+ if(should_have_eyes && !eyes)
+ eyes = new mutanteyes
+ eyes.Insert(C)
+
+ if(ears && (replace_current || !should_have_ears))
+ ears.Remove(C,1)
+ QDEL_NULL(ears)
+ if(should_have_ears && !ears)
+ ears = new mutantears
+ ears.Insert(C)
+
+ if(tongue && (replace_current || !should_have_tongue))
+ tongue.Remove(C,1)
+ QDEL_NULL(tongue)
+ if(should_have_tongue && !tongue)
+ tongue = new mutanttongue
+ tongue.Insert(C)
+
+ if(old_species)
+ for(var/mutantorgan in old_species.mutant_organs)
+ var/obj/item/organ/I = C.getorgan(mutantorgan)
+ if(I)
+ I.Remove(C)
+ QDEL_NULL(I)
+
+ for(var/path in mutant_organs)
+ var/obj/item/organ/I = new path()
+ I.Insert(C)
+
/datum/species/proc/on_species_gain(mob/living/carbon/C, datum/species/old_species)
// Drop the items the new species can't wear
for(var/slot_id in no_equip)
@@ -138,79 +246,7 @@
if(DIGITIGRADE in species_traits)
C.Digitigrade_Leg_Swap(FALSE)
- var/obj/item/organ/heart/heart = C.getorganslot("heart")
- var/obj/item/organ/lungs/lungs = C.getorganslot("lungs")
- var/obj/item/organ/appendix/appendix = C.getorganslot("appendix")
- var/obj/item/organ/eyes/eyes = C.getorganslot("eye_sight")
- var/obj/item/organ/ears/ears = C.getorganslot("ears")
- var/obj/item/organ/tongue/tongue = C.getorganslot("tongue")
-
- var/obj/item/organ/liver/liver = C.getorganslot("liver")
- var/obj/item/organ/stomach/stomach = C.getorganslot("stomach")
-
-
-
- if((NOBLOOD in species_traits) && heart)
- heart.Remove(C)
- qdel(heart)
- else if((!(NOBLOOD in species_traits)) && (!heart))
- heart = new()
- heart.Insert(C)
-
- if(lungs)
- qdel(lungs)
- lungs = null
-
- QDEL_NULL(liver)
-
- QDEL_NULL(stomach)
-
- if(C.get_bodypart("head"))
- if(eyes)
- qdel(eyes)
- eyes = new mutanteyes
- eyes.Insert(C)
-
- if(ears)
- qdel(ears)
- ears = new mutantears
- ears.Insert(C)
-
- if(tongue)
- qdel(tongue)
- tongue = new mutanttongue
- tongue.Insert(C)
-
- if((!(NOBREATH in species_traits)) && !lungs)
- if(mutantlungs)
- lungs = new mutantlungs()
- else
- lungs = new()
- lungs.Insert(C)
-
- if((!(NOLIVER in species_traits)) && (!liver))
- if(mutantliver)
- liver = new mutantliver()
- else
- liver = new()
- liver.Insert(C)
-
- if((!(NOSTOMACH in species_traits)) && (!stomach))
- if(mutantstomach)
- stomach = new mutantstomach()
- else
- stomach = new()
- stomach.Insert(C)
-
- if((NOHUNGER in species_traits) && appendix)
- qdel(appendix)
- else if((!(NOHUNGER in species_traits)) && (!appendix))
- appendix = new()
- appendix.Insert(C)
-
- for(var/path in mutant_organs)
- var/obj/item/organ/I = new path()
- I.Insert(C)
+ regenerate_organs(C,old_species)
if(exotic_bloodtype && C.dna.blood_type != exotic_bloodtype)
C.dna.blood_type = exotic_bloodtype
diff --git a/code/modules/mob/living/carbon/human/species_types/podpeople.dm b/code/modules/mob/living/carbon/human/species_types/podpeople.dm
index f5f59ae829..84bf5bdf80 100644
--- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm
@@ -8,10 +8,13 @@
attack_sound = 'sound/weapons/slice.ogg'
miss_sound = 'sound/weapons/slashmiss.ogg'
burnmod = 1.25
- heatmod = 1.5
+ heatmod = 1.55
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/plant
disliked_food = NONE
liked_food = NONE
+ toxic_food = NONE
+ roundstart = TRUE
+
/datum/species/pod/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..()
@@ -34,18 +37,21 @@
if(H.nutrition > NUTRITION_LEVEL_FULL)
H.nutrition = NUTRITION_LEVEL_FULL
if(light_amount > 0.2) //if there's enough light, heal
- H.heal_overall_damage(1,1)
- H.adjustToxLoss(-1)
- H.adjustOxyLoss(-1)
+ H.heal_overall_damage(0.75,0)
+ H.adjustOxyLoss(-0.5)
+
+ if(H.nutrition < NUTRITION_LEVEL_STARVING + 55)
+ H.adjustOxyLoss(5) //can eat to negate this unfortunately
+ H.adjustToxLoss(3)
- if(H.nutrition < NUTRITION_LEVEL_STARVING + 50)
- H.take_overall_damage(2,0)
/datum/species/pod/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
if(chem.id == "plantbgone")
- H.adjustToxLoss(3)
+ H.adjustToxLoss(5)
H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM)
- return 1
+ H.confused = max(H.confused, 1)
+ return TRUE
+
/datum/species/pod/on_hit(obj/item/projectile/P, mob/living/carbon/human/H)
switch(P.type)
diff --git a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
index 5c635fb870..4347a8331c 100644
--- a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
@@ -1,3 +1,5 @@
+#define HEART_RESPAWN_THRESHHOLD 40
+
/datum/species/shadow
// Humans cursed to stay in the darkness, lest their life forces drain. They regain health in shadow and die in light.
name = "???"
@@ -32,31 +34,21 @@
no_equip = list(slot_wear_mask, slot_wear_suit, slot_gloves, slot_shoes, slot_w_uniform, slot_s_store)
species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,NO_UNDERWEAR,NOHUNGER,NO_DNA_COPY,NOTRANSSTING)
mutanteyes = /obj/item/organ/eyes/night_vision/nightmare
- var/obj/effect/proc_holder/spell/targeted/shadowwalk/shadowwalk
+ mutant_organs = list(/obj/item/organ/heart/nightmare)
+ mutant_brain = /obj/item/organ/brain/nightmare
- var/info_text = "You are a Nightmare . The ability shadow walk allows unlimited, unrestricted movement in the dark using. \
- Your light eater will destroy any light producing objects you attack, as well as destroy any lights a living creature may be holding. You will automatically dodge gunfire and melee attacks when on a dark tile."
+ var/info_text = "You are a Nightmare . The ability shadow walk allows unlimited, unrestricted movement in the dark while activated. \
+ Your light eater will destroy any light producing objects you attack, as well as destroy any lights a living creature may be holding. You will automatically dodge gunfire and melee attacks when on a dark tile. If killed, you will eventually revive if left in darkness."
/datum/species/shadow/nightmare/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..()
- var/obj/effect/proc_holder/spell/targeted/shadowwalk/SW = new
- C.AddSpell(SW)
- shadowwalk = SW
- var/obj/item/light_eater/blade = new
- C.put_in_hands(blade)
-
to_chat(C, "[info_text]")
- C.real_name = "Nightmare"
- C.name = "Nightmare"
+ C.real_name = "[pick(GLOB.nightmare_names)]"
+ C.name = C.real_name
if(C.mind)
- C.mind.name = "Nightmare"
- C.dna.real_name = "Nightmare"
-
-/datum/species/shadow/nightmare/on_species_loss(mob/living/carbon/C)
- . = ..()
- if(shadowwalk)
- C.RemoveSpell(shadowwalk)
+ C.mind.name = C.real_name
+ C.dna.real_name = C.real_name
/datum/species/shadow/nightmare/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H)
var/turf/T = H.loc
@@ -68,6 +60,93 @@
return -1
return 0
+
+
+//Organs
+
+/obj/item/organ/brain/nightmare
+ name = "tumorous mass"
+ desc = "A fleshy growth that was dug out of the skull of a Nightmare."
+ icon_state = "brain-x-d"
+ var/obj/effect/proc_holder/spell/targeted/shadowwalk/shadowwalk
+
+/obj/item/organ/brain/nightmare/Insert(mob/living/carbon/M, special = 0)
+ ..()
+ if(M.dna.species.id != "nightmare")
+ M.set_species(/datum/species/shadow/nightmare)
+ visible_message("[M] thrashes as [src] takes root in their body! ")
+ var/obj/effect/proc_holder/spell/targeted/shadowwalk/SW = new
+ M.AddSpell(SW)
+ shadowwalk = SW
+
+
+/obj/item/organ/brain/nightmare/Remove(mob/living/carbon/M, special = 0)
+ if(shadowwalk)
+ M.RemoveSpell(shadowwalk)
+ ..()
+
+
+/obj/item/organ/heart/nightmare
+ name = "heart of darkness"
+ desc = "An alien organ that twists and writhes when exposed to light."
+ icon = 'icons/obj/surgery.dmi'
+ icon_state = "demon_heart-on"
+ color = "#1C1C1C"
+ var/respawn_progress = 0
+ var/obj/item/light_eater/blade
+
+
+/obj/item/organ/heart/nightmare/attack(mob/M, mob/living/carbon/user, obj/target)
+ if(M != user)
+ return ..()
+ user.visible_message("[user] raises [src] to their mouth and tears into it with their teeth! ", \
+ "[src] feels unnaturally cold in your hands. You raise [src] your mouth and devour it! ")
+ playsound(user, 'sound/magic/demon_consume.ogg', 50, 1)
+
+
+ user.visible_message("Blood erupts from [user]'s arm as it reforms into a weapon! ", \
+ "Icy blood pumps through your veins as your arm reforms itself! ")
+ user.temporarilyRemoveItemFromInventory(src, TRUE)
+ Insert(user)
+
+/obj/item/organ/heart/nightmare/Insert(mob/living/carbon/M, special = 0)
+ ..()
+ blade = new/obj/item/light_eater
+ M.put_in_hands(blade)
+ START_PROCESSING(SSobj, src)
+
+/obj/item/organ/heart/nightmare/Remove(mob/living/carbon/M, special = 0)
+ STOP_PROCESSING(SSobj, src)
+ respawn_progress = 0
+ if(blade)
+ QDEL_NULL(blade)
+ M.visible_message("\The [blade] disintegrates! ")
+ ..()
+
+/obj/item/organ/heart/nightmare/Stop()
+ return 0
+
+/obj/item/organ/heart/nightmare/update_icon()
+ return //always beating visually
+
+/obj/item/organ/heart/nightmare/process()
+ if(QDELETED(owner) || owner.stat != DEAD)
+ respawn_progress = 0
+ return
+ var/turf/T = get_turf(owner)
+ if(istype(T))
+ var/light_amount = T.get_lumcount()
+ if(light_amount < SHADOW_SPECIES_LIGHT_THRESHOLD)
+ respawn_progress++
+ playsound(owner,'sound/effects/singlebeat.ogg',40,1)
+ if(respawn_progress >= HEART_RESPAWN_THRESHHOLD)
+ owner.revive(full_heal = TRUE)
+ owner.visible_message("[owner] staggers to their feet! ")
+ playsound(owner, 'sound/hallucinations/far_noise.ogg', 50, 1)
+ respawn_progress = 0
+
+//Weapon
+
/obj/item/light_eater
name = "light eater"
icon_state = "arm_blade"
@@ -113,3 +192,5 @@
visible_message("[O] is disintegrated by [src]! ")
O.burn()
playsound(src, 'sound/items/welder.ogg', 50, 1)
+
+#undef HEART_RESPAWN_THRESHHOLD
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/species_types/skeletons.dm b/code/modules/mob/living/carbon/human/species_types/skeletons.dm
index 4302c43ff8..be03e591aa 100644
--- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm
+++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm
@@ -1,13 +1,13 @@
-/datum/species/skeleton
- // 2spooky
- name = "Spooky Scary Skeleton"
- id = "skeleton"
- say_mod = "rattles"
- blacklisted = 1
- sexes = 0
- meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton
- species_traits = list(NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NOHUNGER,EASYDISMEMBER,EASYLIMBATTACHMENT)
- mutant_organs = list(/obj/item/organ/tongue/bone)
- damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
- disliked_food = NONE
- liked_food = NONE
+/datum/species/skeleton
+ // 2spooky
+ name = "Spooky Scary Skeleton"
+ id = "skeleton"
+ say_mod = "rattles"
+ blacklisted = 1
+ sexes = 0
+ meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton
+ species_traits = list(NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NOHUNGER,EASYDISMEMBER,EASYLIMBATTACHMENT)
+ mutanttongue = /obj/item/organ/tongue/bone
+ damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
+ disliked_food = NONE
+ liked_food = NONE
diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm
index 04123102c0..016a3635ef 100644
--- a/code/modules/mob/living/carbon/human/species_types/zombies.dm
+++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm
@@ -9,7 +9,7 @@
blacklisted = 1
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/zombie
species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,NOZOMBIE,EASYDISMEMBER,EASYLIMBATTACHMENT,NOTRANSSTING)
- mutant_organs = list(/obj/item/organ/tongue/zombie)
+ mutanttongue = /obj/item/organ/tongue/zombie
var/static/list/spooks = list('sound/hallucinations/growl1.ogg','sound/hallucinations/growl2.ogg','sound/hallucinations/growl3.ogg','sound/hallucinations/veryfar_noise.ogg','sound/hallucinations/wail.ogg')
disliked_food = NONE
liked_food = NONE
@@ -37,6 +37,7 @@
C.a_intent = INTENT_HARM // THE SUFFERING MUST FLOW
if(regen_cooldown < world.time)
C.heal_overall_damage(4,4)
+ C.adjustToxLoss(-4)
if(prob(4))
playsound(C, pick(spooks), 50, TRUE, 10)
if(C.InCritical())
@@ -64,6 +65,6 @@
limbs_id = "zombie" //They look like zombies
sexes = 0
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/zombie
- mutant_organs = list(/obj/item/organ/tongue/zombie)
+ mutanttongue = /obj/item/organ/tongue/zombie
#undef REGENERATION_DELAY
diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm
index 81e918e152..2fcfe97d65 100644
--- a/code/modules/mob/living/carbon/monkey/monkey.dm
+++ b/code/modules/mob/living/carbon/monkey/monkey.dm
@@ -62,7 +62,11 @@
if (bodytemperature < 283.222)
. += (283.222 - bodytemperature) / 10 * 1.75
- return . + config.monkey_delay
+
+ var/static/config_monkey_delay
+ if(isnull(config_monkey_delay))
+ config_monkey_delay = CONFIG_GET(number/monkey_delay)
+ . += config_monkey_delay
/mob/living/carbon/monkey/Stat()
..()
diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm
index fccb3ab8dd..8401d92676 100644
--- a/code/modules/mob/living/damage_procs.dm
+++ b/code/modules/mob/living/damage_procs.dm
@@ -157,7 +157,7 @@
/mob/living/proc/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE)
if(!forced && (status_flags & GODMODE))
return FALSE
- bruteloss = Clamp((bruteloss + (amount * config.damage_multiplier)), 0, maxHealth*2)
+ bruteloss = Clamp((bruteloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
if(updating_health)
updatehealth()
return amount
@@ -168,7 +168,7 @@
/mob/living/proc/adjustOxyLoss(amount, updating_health = TRUE, forced = FALSE)
if(!forced && (status_flags & GODMODE))
return FALSE
- oxyloss = Clamp((oxyloss + (amount * config.damage_multiplier)), 0, maxHealth*2)
+ oxyloss = Clamp((oxyloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
if(updating_health)
updatehealth()
return amount
@@ -187,7 +187,7 @@
/mob/living/proc/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE)
if(!forced && (status_flags & GODMODE))
return FALSE
- toxloss = Clamp((toxloss + (amount * config.damage_multiplier)), 0, maxHealth*2)
+ toxloss = Clamp((toxloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
if(updating_health)
updatehealth()
return amount
@@ -206,7 +206,7 @@
/mob/living/proc/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE)
if(!forced && (status_flags & GODMODE))
return FALSE
- fireloss = Clamp((fireloss + (amount * config.damage_multiplier)), 0, maxHealth*2)
+ fireloss = Clamp((fireloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
if(updating_health)
updatehealth()
return amount
@@ -217,7 +217,7 @@
/mob/living/proc/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE)
if(!forced && (status_flags & GODMODE))
return FALSE
- cloneloss = Clamp((cloneloss + (amount * config.damage_multiplier)), 0, maxHealth*2)
+ cloneloss = Clamp((cloneloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
if(updating_health)
updatehealth()
return amount
@@ -236,7 +236,7 @@
/mob/living/proc/adjustBrainLoss(amount)
if(status_flags & GODMODE)
return 0
- brainloss = Clamp((brainloss + (amount * config.damage_multiplier)), 0, maxHealth*2)
+ brainloss = Clamp((brainloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
/mob/living/proc/setBrainLoss(amount)
if(status_flags & GODMODE)
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 1cf99e8d9e..f4e85e40fb 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -412,7 +412,7 @@
set category = "OOC"
set src in view()
- if(config.allow_Metadata)
+ if(CONFIG_GET(flag/allow_metadata))
if(client)
to_chat(src, "[src]'s Metainfo: [client.prefs.metadata]")
else
@@ -460,20 +460,25 @@
makeTrail(newloc, T, old_direction)
/mob/living/movement_delay(ignorewalk = 0)
- . = ..()
+ . = 0
if(isopenturf(loc) && !is_flying())
var/turf/open/T = loc
. += T.slowdown
+ var/static/config_run_delay
+ var/static/config_walk_delay
+ if(isnull(config_run_delay))
+ config_run_delay = CONFIG_GET(number/run_delay)
+ config_walk_delay = CONFIG_GET(number/walk_delay)
if(ignorewalk)
- . += config.run_speed
+ . += config_run_delay
else
switch(m_intent)
if(MOVE_INTENT_RUN)
if(drowsyness > 0)
. += 6
- . += config.run_speed
+ . += config_run_delay
if(MOVE_INTENT_WALK)
- . += config.walk_speed
+ . += config_walk_delay
/mob/living/proc/makeTrail(turf/target_turf, turf/start, direction)
if(!has_gravity())
@@ -879,7 +884,7 @@
on_fire = 1
src.visible_message("[src] catches fire! ", \
"You're set on fire! ")
- src.set_light(3)
+ new/obj/effect/dummy/fire(src)
throw_alert("fire", /obj/screen/alert/fire)
update_fire()
return TRUE
@@ -889,7 +894,8 @@
if(on_fire)
on_fire = 0
fire_stacks = 0
- src.set_light(0)
+ for(var/obj/effect/dummy/fire/F in src)
+ qdel(F)
clear_alert("fire")
update_fire()
diff --git a/code/modules/mob/living/silicon/ai/say.dm b/code/modules/mob/living/silicon/ai/say.dm
index e148bd2763..8429889ebd 100644
--- a/code/modules/mob/living/silicon/ai/say.dm
+++ b/code/modules/mob/living/silicon/ai/say.dm
@@ -15,7 +15,7 @@
return "[radio_freq ? " (" + speaker.GetJob() + ")" : ""]" + "[speaker.GetSource() ? "" : ""]"
/mob/living/silicon/ai/IsVocal()
- return !config.silent_ai
+ return !CONFIG_GET(flag/silent_ai)
/mob/living/silicon/ai/radio(message, message_mode, list/spans, language)
if(incapacitated())
diff --git a/code/modules/mob/living/silicon/damage_procs.dm b/code/modules/mob/living/silicon/damage_procs.dm
index 07e6994db5..0f2c57c4fe 100644
--- a/code/modules/mob/living/silicon/damage_procs.dm
+++ b/code/modules/mob/living/silicon/damage_procs.dm
@@ -15,7 +15,7 @@
/mob/living/silicon/apply_effect(effect = 0,effecttype = STUN, blocked = FALSE)
- return 0 //The only effect that can hit them atm is flashes and they still directly edit so this works for now
+ return FALSE //The only effect that can hit them atm is flashes and they still directly edit so this works for now
/mob/living/silicon/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE) //immune to tox damage
return FALSE
@@ -30,8 +30,13 @@
return FALSE
/mob/living/silicon/adjustStaminaLoss(amount, updating_stamina = 1)//immune to stamina damage.
- return
+ return FALSE
/mob/living/silicon/setStaminaLoss(amount, updating_stamina = 1)
- return
+ return FALSE
+/mob/living/silicon/adjustBrainLoss(amount)
+ return FALSE
+
+/mob/living/silicon/setBrainLoss(amount)
+ return FALSE
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index e264f00cf1..f8e4c4d752 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -211,9 +211,9 @@
"MediHound" = /obj/item/robot_module/medihound, \
"Security K9" = /obj/item/robot_module/k9, \
"Scrub Puppy" = /obj/item/robot_module/scrubpup)
- if(!config.forbid_peaceborg)
+ if(!CONFIG_GET(flag/disable_peaceborg))
modulelist["Peacekeeper"] = /obj/item/robot_module/peacekeeper
- if(!config.forbid_secborg)
+ if(!CONFIG_GET(flag/disable_secborg))
modulelist["Security"] = /obj/item/robot_module/security
var/input_module = input("Please, select a module!", "Robot", null, null) as null|anything in modulelist
@@ -923,6 +923,7 @@
see_invisible = initial(see_invisible)
see_in_dark = initial(see_in_dark)
sight = initial(sight)
+ lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE
if(client.eye != src)
var/atom/A = client.eye
diff --git a/code/modules/mob/living/silicon/robot/robot_movement.dm b/code/modules/mob/living/silicon/robot/robot_movement.dm
index 167137d9d1..762d86dee9 100644
--- a/code/modules/mob/living/silicon/robot/robot_movement.dm
+++ b/code/modules/mob/living/silicon/robot/robot_movement.dm
@@ -5,8 +5,10 @@
/mob/living/silicon/robot/movement_delay()
. = ..()
- . += speed
- . += config.robot_delay
+ var/static/config_robot_delay
+ if(isnull(config_robot_delay))
+ config_robot_delay = CONFIG_GET(number/robot_delay)
+ . += speed + config_robot_delay
/mob/living/silicon/robot/mob_negates_gravity()
return magpulse
diff --git a/code/modules/mob/living/silicon/robot/say.dm b/code/modules/mob/living/silicon/robot/say.dm
index 866debc30e..910373e89b 100644
--- a/code/modules/mob/living/silicon/robot/say.dm
+++ b/code/modules/mob/living/silicon/robot/say.dm
@@ -1,2 +1,2 @@
/mob/living/silicon/robot/IsVocal()
- return !config.silent_borg
+ return !CONFIG_GET(flag/silent_borg)
diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm
index 7b7334befc..bbbe4e310c 100644
--- a/code/modules/mob/living/simple_animal/bot/medbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/medbot.dm
@@ -543,4 +543,4 @@
declare_cooldown = world.time + 200
/obj/machinery/bot_core/medbot
- req_one_access =list(ACCESS_MEDICAL, ACCESS_ROBOTICS)
+ req_one_access = list(ACCESS_MEDICAL, ACCESS_ROBOTICS)
diff --git a/code/modules/mob/living/simple_animal/damage_procs.dm b/code/modules/mob/living/simple_animal/damage_procs.dm
index 01a30e9b04..5405ee03c6 100644
--- a/code/modules/mob/living/simple_animal/damage_procs.dm
+++ b/code/modules/mob/living/simple_animal/damage_procs.dm
@@ -9,33 +9,33 @@
/mob/living/simple_animal/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE)
if(forced)
- . = adjustHealth(amount * config.damage_multiplier, updating_health, forced)
+ . = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced)
else if(damage_coeff[BRUTE])
- . = adjustHealth(amount * damage_coeff[BRUTE] * config.damage_multiplier, updating_health, forced)
+ . = adjustHealth(amount * damage_coeff[BRUTE] * CONFIG_GET(number/damage_multiplier), updating_health, forced)
/mob/living/simple_animal/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE)
if(forced)
- . = adjustHealth(amount * config.damage_multiplier, updating_health, forced)
+ . = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced)
else if(damage_coeff[BURN])
- . = adjustHealth(amount * damage_coeff[BURN] * config.damage_multiplier, updating_health, forced)
+ . = adjustHealth(amount * damage_coeff[BURN] * CONFIG_GET(number/damage_multiplier), updating_health, forced)
/mob/living/simple_animal/adjustOxyLoss(amount, updating_health = TRUE, forced = FALSE)
if(forced)
- . = adjustHealth(amount * config.damage_multiplier, updating_health, forced)
+ . = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced)
else if(damage_coeff[OXY])
- . = adjustHealth(amount * damage_coeff[OXY] * config.damage_multiplier, updating_health, forced)
+ . = adjustHealth(amount * damage_coeff[OXY] * CONFIG_GET(number/damage_multiplier), updating_health, forced)
/mob/living/simple_animal/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE)
if(forced)
- . = adjustHealth(amount * config.damage_multiplier, updating_health, forced)
+ . = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced)
else if(damage_coeff[TOX])
- . = adjustHealth(amount * damage_coeff[TOX] * config.damage_multiplier, updating_health, forced)
+ . = adjustHealth(amount * damage_coeff[TOX] * CONFIG_GET(number/damage_multiplier), updating_health, forced)
/mob/living/simple_animal/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE)
if(forced)
- . = adjustHealth(amount * config.damage_multiplier, updating_health, forced)
+ . = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced)
else if(damage_coeff[CLONE])
- . = adjustHealth(amount * damage_coeff[CLONE] * config.damage_multiplier, updating_health, forced)
+ . = adjustHealth(amount * damage_coeff[CLONE] * CONFIG_GET(number/damage_multiplier), updating_health, forced)
/mob/living/simple_animal/adjustStaminaLoss(amount)
return
diff --git a/code/modules/mob/living/simple_animal/friendly/cockroach.dm b/code/modules/mob/living/simple_animal/friendly/cockroach.dm
index 0218ce5726..77c29cd3cf 100644
--- a/code/modules/mob/living/simple_animal/friendly/cockroach.dm
+++ b/code/modules/mob/living/simple_animal/friendly/cockroach.dm
@@ -42,7 +42,7 @@
else
visible_message("[src] avoids getting crushed. ")
else
- if(istype(AM, /obj/structure))
+ if(isstructure(AM))
if(prob(squish_chance))
AM.visible_message("[src] was crushed under [AM]. ")
adjustBruteLoss(1)
diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm
index b9b526514b..6467990776 100644
--- a/code/modules/mob/living/simple_animal/friendly/dog.dm
+++ b/code/modules/mob/living/simple_animal/friendly/dog.dm
@@ -424,6 +424,41 @@
setDir(i)
sleep(1)
+/mob/living/simple_animal/pet/dog/corgi/Ian/narsie_act()
+ playsound(src, 'sound/magic/demon_dies.ogg', 75, TRUE)
+ var/mob/living/simple_animal/pet/dog/corgi/narsie/N = new(loc)
+ N.setDir(dir)
+ gib()
+
+/mob/living/simple_animal/pet/dog/corgi/narsie
+ name = "Nars-Ian"
+ desc = "Ia! Ia!"
+ icon_state = "narsian"
+ icon_living = "narsian"
+ icon_dead = "narsian_dead"
+ faction = list("dog", "cult")
+ gold_core_spawnable = FALSE
+ nofur = TRUE
+
+/mob/living/simple_animal/pet/dog/corgi/narsie/Life()
+ ..()
+ for(var/mob/living/simple_animal/pet/P in range(1, src))
+ if(P != src && prob(5))
+ visible_message("[src] devours [P]! ", \
+ "DELICIOUS SOULS ")
+ playsound(src, 'sound/magic/demon_attack1.ogg', 75, TRUE)
+ narsie_act()
+ P.gib()
+
+/mob/living/simple_animal/pet/dog/corgi/narsie/update_corgi_fluff()
+ ..()
+ speak = list("Tari'karat-pasnar!", "IA! IA!", "BRRUUURGHGHRHR")
+ speak_emote = list("growls", "barks ominously")
+ emote_hear = list("barks echoingly!", "woofs hauntingly!", "yaps in an eldritch manner.", "mutters something unspeakable.")
+ emote_see = list("communes with the unnameable.", "ponders devouring some souls.", "shakes.")
+
+/mob/living/simple_animal/pet/dog/corgi/narsie/narsie_act()
+ adjustBruteLoss(-maxHealth)
/mob/living/simple_animal/pet/dog/corgi/regenerate_icons()
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm
index 8881eb5407..9900133723 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm
@@ -30,7 +30,7 @@
/obj/item/drone_shell/attack_ghost(mob/user)
if(jobban_isbanned(user,"drone"))
return
- if(config.use_age_restriction_for_jobs)
+ if(CONFIG_GET(flag/use_age_restriction_for_jobs))
if(!isnum(user.client.player_age)) //apparently what happens when there's no DB connected. just don't let anybody be a drone without admin intervention
return
if(user.client.player_age < DRONE_MINIMUM_AGE)
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm
index 3c8c9d217e..a19a6abeb3 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm
@@ -237,3 +237,8 @@
. = ..()
if(.)
update_icons()
+
+/mob/living/simple_animal/drone/cogscarab/update_canmove()
+ . = ..()
+ if(.)
+ update_icons()
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm b/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm
index 259ca4327d..325b971171 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm
@@ -86,7 +86,7 @@
if(istype(head, /obj/item/clothing/mask))
used_head_icon = 'icons/mob/mask.dmi'
var/mutable_appearance/head_overlay = head.build_worn_icon(state = head.icon_state, default_layer = DRONE_HEAD_LAYER, default_icon_file = used_head_icon)
- head_overlay.pixel_y += -15
+ head_overlay.pixel_y -= 15
drone_overlays[DRONE_HEAD_LAYER] = head_overlay
diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm
index 144f7081e0..592679d35b 100644
--- a/code/modules/mob/living/simple_animal/guardian/guardian.dm
+++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm
@@ -180,10 +180,13 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
new /obj/effect/temp_visual/guardian/phase(loc)
/mob/living/simple_animal/hostile/guardian/canSuicide()
- return 0
+ return FALSE
+
+/mob/living/simple_animal/hostile/guardian/proc/is_deployed()
+ return loc != summoner
/mob/living/simple_animal/hostile/guardian/AttackingTarget()
- if(loc == summoner)
+ if(!is_deployed())
to_chat(src, "You must be manifested to attack! ")
return FALSE
else
diff --git a/code/modules/mob/living/simple_animal/guardian/types/support.dm b/code/modules/mob/living/simple_animal/guardian/types/support.dm
index db1581d8cb..a8a31ad89c 100644
--- a/code/modules/mob/living/simple_animal/guardian/types/support.dm
+++ b/code/modules/mob/living/simple_animal/guardian/types/support.dm
@@ -28,7 +28,7 @@
/mob/living/simple_animal/hostile/guardian/healer/AttackingTarget()
. = ..()
- if(. && toggle && iscarbon(target))
+ if(is_deployed() && toggle && iscarbon(target))
var/mob/living/carbon/C = target
C.adjustBruteLoss(-5)
C.adjustFireLoss(-5)
diff --git a/code/modules/mob/living/simple_animal/hostile/bees.dm b/code/modules/mob/living/simple_animal/hostile/bees.dm
index f2d29d3660..9f7a7d1bbf 100644
--- a/code/modules/mob/living/simple_animal/hostile/bees.dm
+++ b/code/modules/mob/living/simple_animal/hostile/bees.dm
@@ -105,22 +105,22 @@
/mob/living/simple_animal/hostile/poison/bees/CanAttack(atom/the_target)
. = ..()
if(!.)
- return 0
+ return FALSE
if(isliving(the_target))
var/mob/living/H = the_target
return !H.bee_friendly()
/mob/living/simple_animal/hostile/poison/bees/Found(atom/A)
+ if(isliving(A))
+ var/mob/living/H = A
+ return !H.bee_friendly()
if(istype(A, /obj/machinery/hydroponics))
var/obj/machinery/hydroponics/Hydro = A
if(Hydro.myseed && !Hydro.dead && !Hydro.recent_bee_visit)
wanted_objects |= typecacheof(/obj/machinery/hydroponics) //so we only hunt them while they're alive/seeded/not visisted
- return 1
- if(isliving(A))
- var/mob/living/H = A
- return !H.bee_friendly()
- return 0
+ return TRUE
+ return FALSE
/mob/living/simple_animal/hostile/poison/bees/AttackingTarget()
@@ -187,7 +187,7 @@
if(loc == beehome)
idle = min(100, ++idle)
if(idle >= BEE_IDLE_ROAMING && prob(BEE_PROB_GOROAM))
- forceMove(get_turf(beehome))
+ forceMove(beehome.drop_location())
else
idle = max(0, --idle)
if(idle <= BEE_IDLE_GOHOME && prob(BEE_PROB_GOHOME))
@@ -200,6 +200,7 @@
continue
BB.bees |= src
beehome = BB
+ break // End loop after the first compatible find.
/mob/living/simple_animal/hostile/poison/bees/toxin/Initialize()
. = ..()
@@ -215,7 +216,7 @@
//the Queen doesn't leave the box on her own, and she CERTAINLY doesn't pollinate by herself
/mob/living/simple_animal/hostile/poison/bees/queen/Found(atom/A)
- return 0
+ return FALSE
//leave pollination for the peasent bees
@@ -234,10 +235,10 @@
/mob/living/simple_animal/hostile/poison/bees/proc/reagent_incompatible(mob/living/simple_animal/hostile/poison/bees/B)
if(!B)
- return 0
+ return FALSE
if(B.beegent && beegent && B.beegent.id != beegent.id || B.beegent && !beegent || !B.beegent && beegent)
- return 1
- return 0
+ return TRUE
+ return FALSE
/obj/item/queen_bee
@@ -255,7 +256,7 @@
if(S.reagents.has_reagent("royal_bee_jelly")) //checked twice, because I really don't want royal bee jelly to be duped
if(S.reagents.has_reagent("royal_bee_jelly",5))
S.reagents.remove_reagent("royal_bee_jelly", 5)
- var/obj/item/queen_bee/qb = new(get_turf(user))
+ var/obj/item/queen_bee/qb = new(user.drop_location())
qb.queen = new(qb)
if(queen && queen.beegent)
qb.queen.assign_reagent(queen.beegent) //Bees use the global singleton instances of reagents, so we don't need to worry about one bee being deleted and her copies losing their reagents.
diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
index 75cc53e0c9..e5ee4f671c 100644
--- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
+++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
@@ -275,7 +275,7 @@
if(O.anchored)
continue
- if(isitem(O) || istype(O, /obj/structure) || istype(O, /obj/machinery))
+ if(isitem(O) || isstructure(O) || istype(O, /obj/machinery))
cocoon_target = O
busy = MOVING_TO_TARGET
stop_automated_movement = 1
diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm
index 86fe54aaeb..d4c9632a03 100644
--- a/code/modules/mob/living/simple_animal/hostile/hostile.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm
@@ -46,9 +46,9 @@
var/search_objects_timer_id //Timer for regaining our old search_objects value after being attacked
var/search_objects_regain_time = 30 //the delay between being attacked and gaining our old search_objects value back
var/list/wanted_objects = list() //A typecache of objects types that will be checked against to attack, should we have search_objects enabled
- var/stat_attack = CONSCIOUS //Mobs with stat_attack to UNCONSCIOUS will attempt to attack things that are unconscious, Mobs with stat_attack set to 2 will attempt to attack the dead.
- var/stat_exclusive = FALSE //Mobs with this set to TRUE will exclusively attack things defined by stat_attack, stat_attack 2 means they will only attack corpses
- var/attack_same = 0 //Set us to 1 to allow us to attack our own faction, or 2, to only ever attack our own faction
+ var/stat_attack = CONSCIOUS //Mobs with stat_attack to UNCONSCIOUS will attempt to attack things that are unconscious, Mobs with stat_attack set to DEAD will attempt to attack the dead.
+ var/stat_exclusive = FALSE //Mobs with this set to TRUE will exclusively attack things defined by stat_attack, stat_attack DEAD means they will only attack corpses
+ var/attack_same = 0 //Set us to 1 to allow us to attack our own faction
var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever)
var/atom/targets_from = null //all range/attack/etc. calculations should be done from this atom, defaults to the mob itself, useful for Vehicles and such
var/attack_all_objects = FALSE //if true, equivalent to having a wanted_objects list containing ALL objects.
@@ -115,7 +115,11 @@
if(can_see(targets_from, HM, vision_range))
. += HM
else
- . = oview(vision_range, targets_from)
+ . = list() // The following code is only very slightly slower than just returning oview(vision_range, targets_from), but it saves us much more work down the line, particularly when bees are involved
+ for (var/obj/A in oview(vision_range, targets_from))
+ . += A
+ for (var/mob/A in oview(vision_range, targets_from))
+ . += A
/mob/living/simple_animal/hostile/proc/FindTarget(var/list/possible_targets, var/HasTargetsList = 0)//Step 2, filter down possible targets to things we actually care about
. = list()
@@ -164,56 +168,55 @@
var/chosen_target = pick(Targets)//Pick the remaining targets (if any) at random
return chosen_target
+// Please do not add one-off mob AIs here, but override this function for your mob
/mob/living/simple_animal/hostile/CanAttack(atom/the_target)//Can we actually attack a possible target?
- if(!the_target)
- return 0
+ if(isturf(the_target) || !the_target || the_target.type == /atom/movable/lighting_object) // bail out on invalids
+ return FALSE
+
if(see_invisible < the_target.invisibility)//Target's invisible to us, forget it
- return 0
+ return FALSE
if(search_objects < 2)
if(isliving(the_target))
var/mob/living/L = the_target
var/faction_check = faction_check_mob(L)
if(robust_searching)
- if(L.stat > stat_attack || L.stat != stat_attack && stat_exclusive)
- return 0
- if(faction_check && !attack_same || !faction_check && attack_same == 2)
- return 0
- if(L in friends)
- return 0
- else
- if(L.stat)
- return 0
if(faction_check && !attack_same)
- return 0
- return 1
+ return FALSE
+ if(L.stat > stat_attack)
+ return FALSE
+ if(L in friends)
+ return FALSE
+ else
+ if((faction_check && !attack_same) || L.stat)
+ return FALSE
+ return TRUE
- if(istype(the_target, /obj/mecha))
+ if(ismecha(the_target))
var/obj/mecha/M = the_target
if(M.occupant)//Just so we don't attack empty mechs
if(CanAttack(M.occupant))
- return 1
+ return TRUE
if(istype(the_target, /obj/machinery/porta_turret))
var/obj/machinery/porta_turret/P = the_target
if(P.faction in faction)
- return 0
+ return FALSE
if(P.has_cover &&!P.raised) //Don't attack invincible turrets
- return 0
+ return FALSE
if(P.stat & BROKEN) //Or turrets that are already broken
- return 0
- return 1
+ return FALSE
+ return TRUE
if(istype(the_target, /obj/structure/destructible/clockwork/ocular_warden))
var/obj/structure/destructible/clockwork/ocular_warden/OW = the_target
if(OW.target != src)
return FALSE
return TRUE
-
-
if(isobj(the_target))
if(attack_all_objects || is_type_in_typecache(the_target, wanted_objects))
- return 1
- return 0
+ return TRUE
+
+ return FALSE
/mob/living/simple_animal/hostile/proc/GiveTarget(new_target)//Step 4, give us our selected target
target = new_target
diff --git a/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm b/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm
index b84f3c8682..378b5d9b8e 100644
--- a/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm
@@ -184,7 +184,7 @@
mecha_face_target(target)
target.mech_melee_attack(mecha)
else
- if(istype(target, /obj/mecha))
+ if(ismecha(target))
var/obj/mecha/M = target
if(is_valid_mecha(M))
enter_mecha(M)
@@ -259,7 +259,7 @@
//Yes they actually try and pull this shit
//~simple animals~
/mob/living/simple_animal/hostile/syndicate/mecha_pilot/CanAttack(atom/the_target)
- if(istype(the_target, /obj/mecha))
+ if(ismecha(the_target))
var/obj/mecha/M = the_target
if(mecha)
if(M == mecha || !CanAttack(M.occupant))
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm
index d1ddfa9a00..b81d58b329 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm
@@ -385,6 +385,7 @@ Difficulty: Medium
melee_damage_lower = 30
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1)
loot = list()
+ butcher_results = list(/obj/item/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/bone = 30)
/mob/living/simple_animal/hostile/megafauna/dragon/lesser/grant_achievement(medaltype,scoretype)
return
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
index a80340c28a..3d2f7cf28e 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
@@ -130,7 +130,7 @@
if(admin_spawned)
return FALSE
- if(global.medal_hub && global.medal_pass && global.medals_enabled)
+ if(MedalsAvailable())
for(var/mob/living/L in view(7,src))
if(L.stat)
continue
@@ -147,10 +147,10 @@
set waitfor = FALSE
if(!player || !medal)
return
- if(global.medal_hub && global.medal_pass && global.medals_enabled)
- var/result = world.SetMedal(medal, player, global.medal_hub, global.medal_pass)
+ if(MedalsAvailable())
+ var/result = world.SetMedal(medal, player, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))
if(isnull(result))
- global.medals_enabled = FALSE
+ GLOB.medals_enabled = FALSE
log_game("MEDAL ERROR: Could not contact hub to award medal:[medal] player:[player.ckey]")
message_admins("Error! Failed to contact hub to award [medal] medal to [player.ckey]!")
else if (result)
@@ -161,9 +161,8 @@
set waitfor = FALSE
if(!score || !player)
return
- if(global.medal_hub && global.medal_pass && global.medals_enabled)
+ if(MedalsAvailable())
var/list/oldscore = GetScore(score,player,1)
-
if(increment)
if(!oldscore[score])
oldscore[score] = 1
@@ -174,10 +173,10 @@
var/newscoreparam = list2params(oldscore)
- var/result = world.SetScores(player.ckey, newscoreparam, global.medal_hub, global.medal_pass)
+ var/result = world.SetScores(player.ckey, newscoreparam, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))
if(isnull(result))
- global.medals_enabled = FALSE
+ GLOB.medals_enabled = FALSE
log_game("SCORE ERROR: Could not contact hub to set score. Score:[score] player:[player.ckey]")
message_admins("Error! Failed to contact hub to set [score] score for [player.ckey]!")
@@ -186,11 +185,11 @@
if(!score || !player)
return
- if(global.medal_hub && global.medal_pass && global.medals_enabled)
+ if(MedalsAvailable())
- var/scoreget = world.GetScores(player.ckey, score, global.medal_hub, global.medal_pass)
+ var/scoreget = world.GetScores(player.ckey, score, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))
if(isnull(scoreget))
- global.medals_enabled = FALSE
+ GLOB.medals_enabled = FALSE
log_game("SCORE ERROR: Could not contact hub to get score. Score:[score] player:[player.ckey]")
message_admins("Error! Failed to contact hub to get score: [score] for [player.ckey]!")
return
@@ -207,12 +206,12 @@
if(!player || !medal)
return
- if(global.medal_hub && global.medal_pass && global.medals_enabled)
+ if(MedalsAvailable())
- var/result = world.GetMedal(medal, player, global.medal_hub, global.medal_pass)
+ var/result = world.GetMedal(medal, player, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))
if(isnull(result))
- global.medals_enabled = FALSE
+ GLOB.medals_enabled = FALSE
log_game("MEDAL ERROR: Could not contact hub to get medal:[medal] player:[player.ckey]")
message_admins("Error! Failed to contact hub to get [medal] medal for [player.ckey]!")
else if (result)
@@ -222,12 +221,12 @@
if(!player || !medal)
return
- if(global.medal_hub && global.medal_pass && global.medals_enabled)
+ if(MedalsAvailable())
- var/result = world.ClearMedal(medal, player, global.medal_hub, global.medal_pass)
+ var/result = world.ClearMedal(medal, player, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))
if(isnull(result))
- global.medals_enabled = FALSE
+ GLOB.medals_enabled = FALSE
log_game("MEDAL ERROR: Could not contact hub to clear medal:[medal] player:[player.ckey]")
message_admins("Error! Failed to contact hub to clear [medal] medal for [player.ckey]!")
else if (result)
@@ -237,6 +236,9 @@
/proc/ClearScore(client/player)
- world.SetScores(player.ckey, "", global.medal_hub, global.medal_pass)
+ world.SetScores(player.ckey, "", CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))
+
+/proc/MedalsAvailable()
+ return CONFIG_GET(string/medal_hub_address) && CONFIG_GET(string/medal_hub_password) && GLOB.medals_enabled
#undef MEDAL_PREFIX
diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm
index abe095779b..b46000c339 100644
--- a/code/modules/mob/living/simple_animal/hostile/mimic.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm
@@ -130,7 +130,7 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca
faction |= "\ref[owner]"
/mob/living/simple_animal/hostile/mimic/copy/proc/CheckObject(obj/O)
- if((isitem(O) || istype(O, /obj/structure)) && !is_type_in_list(O, GLOB.protected_objects))
+ if((isitem(O) || isstructure(O)) && !is_type_in_list(O, GLOB.protected_objects))
return 1
return 0
@@ -144,7 +144,7 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca
icon_living = icon_state
copy_overlays(O)
add_overlay(googly_eyes)
- if(istype(O, /obj/structure) || istype(O, /obj/machinery))
+ if(isstructure(O) || istype(O, /obj/machinery))
health = (anchored * 50) + 50
destroy_objects = 1
if(O.density && O.anchored)
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm
index 11188a9023..04282d12fd 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm
@@ -45,6 +45,28 @@
udder = new()
. = ..()
+/mob/living/simple_animal/hostile/asteroid/gutlunch/CanAttack(atom/the_target) // Gutlunch-specific version of CanAttack to handle stupid stat_exclusive = true crap so we don't have to do it for literally every single simple_animal/hostile except the two that spawn in lavaland
+ if(isturf(the_target) || !the_target || the_target.type == /atom/movable/lighting_object) // bail out on invalids
+ return FALSE
+
+ if(see_invisible < the_target.invisibility)//Target's invisible to us, forget it
+ return FALSE
+
+ if(isliving(the_target))
+ var/mob/living/L = the_target
+
+ if(faction_check_mob(L) && !attack_same)
+ return FALSE
+ if(L.stat > stat_attack || L.stat != stat_attack && stat_exclusive)
+ return FALSE
+
+ return TRUE
+
+ if(isobj(the_target) && is_type_in_typecache(the_target, wanted_objects))
+ return TRUE
+
+ return FALSE
+
/mob/living/simple_animal/hostile/asteroid/gutlunch/Destroy()
QDEL_NULL(udder)
return ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm
index 5a3672af6d..d5d116d678 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm
@@ -55,7 +55,7 @@
last_tendril = FALSE
break
if(last_tendril && !admin_spawned)
- if(global.medal_hub && global.medal_pass && global.medals_enabled)
+ if(MedalsAvailable())
for(var/mob/living/L in view(7,src))
if(L.stat)
continue
diff --git a/code/modules/mob/living/simple_animal/hostile/mushroom.dm b/code/modules/mob/living/simple_animal/hostile/mushroom.dm
index 8c5be75684..01d6c427e8 100644
--- a/code/modules/mob/living/simple_animal/hostile/mushroom.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mushroom.dm
@@ -62,6 +62,25 @@
health = maxHealth
. = ..()
+/mob/living/simple_animal/hostile/mushroom/CanAttack(atom/the_target) // Mushroom-specific version of CanAttack to handle stupid attack_same = 2 crap so we don't have to do it for literally every single simple_animal/hostile because this shit never gets spawned
+ if(!the_target || isturf(the_target) || istype(the_target, /atom/movable/lighting_object))
+ return FALSE
+
+ if(see_invisible < the_target.invisibility)//Target's invisible to us, forget it
+ return FALSE
+
+ if(isliving(the_target))
+ var/mob/living/L = the_target
+
+ if (!faction_check_mob(L) && attack_same == 2)
+ return FALSE
+ if(L.stat > stat_attack)
+ return FALSE
+
+ return TRUE
+
+ return FALSE
+
/mob/living/simple_animal/hostile/mushroom/adjustHealth(amount, updating_health = TRUE, forced = FALSE) //Possibility to flee from a fight just to make it more visually interesting
if(!retreat_distance && prob(33))
retreat_distance = 5
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/retaliate.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/retaliate.dm
index 4aa067c9ab..57df489d4e 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/retaliate.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/retaliate.dm
@@ -1,47 +1,47 @@
-/mob/living/simple_animal/hostile/retaliate
- var/list/enemies = list()
-
-/mob/living/simple_animal/hostile/retaliate/Found(atom/A)
- if(isliving(A))
- var/mob/living/L = A
- if(!L.stat)
- return L
- else
- enemies -= L
- else if(istype(A, /obj/mecha))
- var/obj/mecha/M = A
- if(M.occupant)
- return A
-
-/mob/living/simple_animal/hostile/retaliate/ListTargets()
- if(!enemies.len)
- return list()
- var/list/see = ..()
- see &= enemies // Remove all entries that aren't in enemies
- return see
-
-/mob/living/simple_animal/hostile/retaliate/proc/Retaliate()
- var/list/around = view(src, vision_range)
-
- for(var/atom/movable/A in around)
- if(A == src)
- continue
- if(isliving(A))
- var/mob/living/M = A
- if(faction_check_mob(M) && attack_same || !faction_check_mob(M))
- enemies |= M
- else if(istype(A, /obj/mecha))
- var/obj/mecha/M = A
- if(M.occupant)
- enemies |= M
- enemies |= M.occupant
-
- for(var/mob/living/simple_animal/hostile/retaliate/H in around)
- if(faction_check_mob(H) && !attack_same && !H.attack_same)
- H.enemies |= enemies
- return 0
-
-/mob/living/simple_animal/hostile/retaliate/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
- . = ..()
- if(. > 0 && stat == CONSCIOUS)
- Retaliate()
+/mob/living/simple_animal/hostile/retaliate
+ var/list/enemies = list()
+
+/mob/living/simple_animal/hostile/retaliate/Found(atom/A)
+ if(isliving(A))
+ var/mob/living/L = A
+ if(!L.stat)
+ return L
+ else
+ enemies -= L
+ else if(ismecha(A))
+ var/obj/mecha/M = A
+ if(M.occupant)
+ return A
+
+/mob/living/simple_animal/hostile/retaliate/ListTargets()
+ if(!enemies.len)
+ return list()
+ var/list/see = ..()
+ see &= enemies // Remove all entries that aren't in enemies
+ return see
+
+/mob/living/simple_animal/hostile/retaliate/proc/Retaliate()
+ var/list/around = view(src, vision_range)
+
+ for(var/atom/movable/A in around)
+ if(A == src)
+ continue
+ if(isliving(A))
+ var/mob/living/M = A
+ if(faction_check_mob(M) && attack_same || !faction_check_mob(M))
+ enemies |= M
+ else if(ismecha(A))
+ var/obj/mecha/M = A
+ if(M.occupant)
+ enemies |= M
+ enemies |= M.occupant
+
+ for(var/mob/living/simple_animal/hostile/retaliate/H in around)
+ if(faction_check_mob(H) && !attack_same && !H.attack_same)
+ H.enemies |= enemies
+ return 0
+
+/mob/living/simple_animal/hostile/retaliate/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
+ . = ..()
+ if(. > 0 && stat == CONSCIOUS)
+ Retaliate()
diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm
index 6357f83286..09d9f66f61 100644
--- a/code/modules/mob/living/simple_animal/parrot.dm
+++ b/code/modules/mob/living/simple_animal/parrot.dm
@@ -33,6 +33,7 @@
icon_state = "parrot_fly"
icon_living = "parrot_fly"
icon_dead = "parrot_dead"
+ var/icon_sit = "parrot_sit"
density = FALSE
health = 80
maxHealth = 80
@@ -284,7 +285,7 @@
return
if(!stat && M.a_intent == INTENT_HARM)
- icon_state = "parrot_fly" //It is going to be flying regardless of whether it flees or attacks
+ icon_state = icon_living //It is going to be flying regardless of whether it flees or attacks
if(parrot_state == PARROT_PERCH)
parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched
@@ -320,7 +321,7 @@
if(M.melee_damage_upper > 0 && !stat)
parrot_interest = M
parrot_state = PARROT_SWOOP | PARROT_ATTACK //Attack other animals regardless
- icon_state = "parrot_fly"
+ icon_state = icon_living
//Mobs with objects
/mob/living/simple_animal/parrot/attackby(obj/item/O, mob/living/user, params)
@@ -335,7 +336,7 @@
parrot_state |= PARROT_ATTACK
else
parrot_state |= PARROT_FLEE
- icon_state = "parrot_fly"
+ icon_state = icon_living
drop_held_item(0)
else if(istype(O, /obj/item/reagent_containers/food/snacks/cracker)) //Poly wants a cracker.
qdel(O)
@@ -358,7 +359,7 @@
parrot_interest = null
parrot_state = PARROT_WANDER | PARROT_FLEE //Been shot and survived! RUN LIKE HELL!
//parrot_been_shot += 5
- icon_state = "parrot_fly"
+ icon_state = icon_living
drop_held_item(0)
return
@@ -371,7 +372,7 @@
//Sprite update for when a parrot gets pulled
if(pulledby && stat == CONSCIOUS)
- icon_state = "parrot_fly"
+ icon_state = icon_living
if(!client)
parrot_state = PARROT_WANDER
return
@@ -400,11 +401,11 @@
if(parrot_perch && parrot_perch.loc != src.loc) //Make sure someone hasnt moved our perch on us
if(parrot_perch in view(src))
parrot_state = PARROT_SWOOP | PARROT_RETURN
- icon_state = "parrot_fly"
+ icon_state = icon_living
return
else
parrot_state = PARROT_WANDER
- icon_state = "parrot_fly"
+ icon_state = icon_living
return
if(--parrot_sleep_dur) //Zzz
@@ -445,7 +446,7 @@
if(parrot_interest)
emote("me", 1, "looks in [parrot_interest]'s direction and takes flight.")
parrot_state = PARROT_SWOOP | PARROT_STEAL
- icon_state = "parrot_fly"
+ icon_state = icon_living
return
//-----WANDERING - This is basically a 'I dont know what to do yet' state
@@ -530,7 +531,7 @@
src.loc = parrot_perch.loc
drop_held_item()
parrot_state = PARROT_PERCH
- icon_state = "parrot_sit"
+ icon_state = icon_sit
return
walk_to(src, parrot_perch, 1, parrot_speed)
@@ -603,8 +604,8 @@
*/
/mob/living/simple_animal/parrot/movement_delay()
- if(client && stat == CONSCIOUS && parrot_state != "parrot_fly")
- icon_state = "parrot_fly"
+ if(client && stat == CONSCIOUS && parrot_state != icon_living)
+ icon_state = icon_living
//Because the most appropriate place to set icon_state is movement_delay(), clearly
return ..()
@@ -797,12 +798,12 @@
if(stat || !client)
return
- if(icon_state == "parrot_fly")
+ if(icon_state == icon_living)
for(var/atom/movable/AM in view(src,1))
for(var/perch_path in desired_perches)
if(istype(AM, perch_path))
src.loc = AM.loc
- icon_state = "parrot_sit"
+ icon_state = icon_sit
return
to_chat(src, "There is no perch nearby to sit on! ")
return
@@ -816,7 +817,7 @@
if(stat || !client)
return
- if(icon_state == "parrot_fly")
+ if(icon_state == icon_living)
for(var/mob/living/carbon/human/H in view(src,1))
if(H.has_buckled_mobs() && H.buckled_mobs.len >= H.max_buckled_mobs) //Already has a parrot, or is being eaten by a slime
continue
@@ -824,7 +825,7 @@
return
to_chat(src, "There is nobody nearby that you can sit on! ")
else
- icon_state = "parrot_fly"
+ icon_state = icon_living
parrot_state = PARROT_WANDER
if(buckled)
to_chat(src, "You are no longer sitting on [buckled]'s shoulder. ")
@@ -842,7 +843,7 @@
H.buckle_mob(src, force=1)
pixel_y = 9
pixel_x = pick(-8,8) //pick left or right shoulder
- icon_state = "parrot_sit"
+ icon_state = icon_sit
parrot_state = PARROT_PERCH
to_chat(src, "You sit on [H]'s shoulder. ")
@@ -961,6 +962,12 @@
fdel(json_file)
WRITE_FILE(json_file, json_encode(file_data))
+/mob/living/simple_animal/parrot/Poly/ratvar_act()
+ playsound(src, 'sound/magic/clockwork/fellowship_armory.ogg', 75, TRUE)
+ var/mob/living/simple_animal/parrot/clock_hawk/H = new(loc)
+ H.setDir(dir)
+ dust()
+
/mob/living/simple_animal/parrot/Poly/ghost
name = "The Ghost of Poly"
desc = "Doomed to squawk the earth."
@@ -996,4 +1003,23 @@
loc = H
H.ContractDisease(P)
parrot_interest = null
- H.visible_message("[src] dive bombs into [H]'s chest and vanishes! ", "[src] dive bombs into your chest, vanishing! This can't be good! ")
\ No newline at end of file
+ H.visible_message("[src] dive bombs into [H]'s chest and vanishes! ", "[src] dive bombs into your chest, vanishing! This can't be good! ")
+
+
+/mob/living/simple_animal/parrot/clock_hawk
+ name = "clock hawk"
+ desc = "Cbyl jnaan penpxre! Fdhnnnjx!"
+ icon_state = "clock_hawk_fly"
+ icon_living = "clock_hawk_fly"
+ icon_sit = "clock_hawk_sit"
+ speak = list("Penpxre!", "Ratvar vf n qhzo anzr naljnl!")
+ speak_emote = list("squawks rustily", "says crassly", "yells brassly")
+ emote_hear = list("squawks rustily.", "bawks metallically!")
+ emote_see = list("flutters its metal wings.")
+ faction = list("ratvar")
+ gold_core_spawnable = FALSE
+ del_on_death = TRUE
+ death_sound = 'sound/magic/clockwork/anima_fragment_death.ogg'
+
+/mob/living/simple_animal/parrot/clock_hawk/ratvar_act()
+ return
diff --git a/code/modules/mob/living/simple_animal/shade.dm b/code/modules/mob/living/simple_animal/shade.dm
index 802bd738e9..809e8b80d4 100644
--- a/code/modules/mob/living/simple_animal/shade.dm
+++ b/code/modules/mob/living/simple_animal/shade.dm
@@ -1,66 +1,66 @@
-/mob/living/simple_animal/shade
- name = "Shade"
- real_name = "Shade"
- desc = "A bound spirit"
- gender = PLURAL
- icon = 'icons/mob/mob.dmi'
- icon_state = "shade"
- icon_living = "shade"
- maxHealth = 50
- health = 50
- healable = 0
- speak_emote = list("hisses")
- emote_hear = list("wails.","screeches.")
- response_help = "puts their hand through"
- response_disarm = "flails at"
- response_harm = "punches"
- speak_chance = 1
- melee_damage_lower = 5
- melee_damage_upper = 15
- attacktext = "metaphysically strikes"
- minbodytemp = 0
- maxbodytemp = INFINITY
- atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
- speed = -1
- stop_automated_movement = 1
- status_flags = 0
- faction = list("cult")
- status_flags = CANPUSH
- movement_type = FLYING
- loot = list(/obj/item/ectoplasm)
- del_on_death = TRUE
- initial_language_holder = /datum/language_holder/construct
-
-/mob/living/simple_animal/shade/death()
- deathmessage = "lets out a contented sigh as [p_their()] form unwinds."
- ..()
-
-/mob/living/simple_animal/shade/canSuicide()
- if(istype(loc, /obj/item/device/soulstone)) //do not suicide inside the soulstone
- return 0
- return ..()
-
-/mob/living/simple_animal/shade/Process_Spacemove(movement_dir = 0)
- return TRUE //this doesn't make much sense; you'd thing TRUE would mean it'd process spacemove but it means it doesn't
-
-/mob/living/simple_animal/shade/attack_animal(mob/living/simple_animal/M)
- if(isconstruct(M))
- var/mob/living/simple_animal/hostile/construct/C = M
- if(!C.can_repair_constructs)
- return
- if(health < maxHealth)
- adjustHealth(-25)
- Beam(M,icon_state="sendbeam",time=4)
- M.visible_message("[M] heals \the [src] . ", \
- "You heal [src] , leaving [src] at [health]/[maxHealth] health. ")
- else
- to_chat(M, "You cannot heal [src] , as [p_they()] [p_are()] unharmed! ")
- else if(src != M)
- return ..()
-
-/mob/living/simple_animal/shade/attackby(obj/item/O, mob/user, params) //Marker -Agouri
- if(istype(O, /obj/item/device/soulstone))
- var/obj/item/device/soulstone/SS = O
- SS.transfer_soul("SHADE", src, user)
- else
- ..()
+/mob/living/simple_animal/shade
+ name = "Shade"
+ real_name = "Shade"
+ desc = "A bound spirit"
+ gender = PLURAL
+ icon = 'icons/mob/mob.dmi'
+ icon_state = "shade"
+ icon_living = "shade"
+ maxHealth = 50
+ health = 50
+ healable = 0
+ speak_emote = list("hisses")
+ emote_hear = list("wails.","screeches.")
+ response_help = "puts their hand through"
+ response_disarm = "flails at"
+ response_harm = "punches"
+ speak_chance = 1
+ melee_damage_lower = 5
+ melee_damage_upper = 15
+ attacktext = "metaphysically strikes"
+ minbodytemp = 0
+ maxbodytemp = INFINITY
+ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
+ speed = -1
+ stop_automated_movement = 1
+ status_flags = 0
+ faction = list("cult")
+ status_flags = CANPUSH
+ movement_type = FLYING
+ loot = list(/obj/item/ectoplasm)
+ del_on_death = TRUE
+ initial_language_holder = /datum/language_holder/construct
+
+/mob/living/simple_animal/shade/death()
+ deathmessage = "lets out a contented sigh as [p_their()] form unwinds."
+ ..()
+
+/mob/living/simple_animal/shade/canSuicide()
+ if(istype(loc, /obj/item/device/soulstone)) //do not suicide inside the soulstone
+ return 0
+ return ..()
+
+/mob/living/simple_animal/shade/Process_Spacemove(movement_dir = 0)
+ return TRUE //this doesn't make much sense; you'd thing TRUE would mean it'd process spacemove but it means it doesn't
+
+/mob/living/simple_animal/shade/attack_animal(mob/living/simple_animal/M)
+ if(isconstruct(M))
+ var/mob/living/simple_animal/hostile/construct/C = M
+ if(!C.can_repair_constructs)
+ return
+ if(health < maxHealth)
+ adjustHealth(-25)
+ Beam(M,icon_state="sendbeam",time=4)
+ M.visible_message("[M] heals \the [src] . ", \
+ "You heal [src] , leaving [src] at [health]/[maxHealth] health. ")
+ else
+ to_chat(M, "You cannot heal [src] , as [p_they()] [p_are()] unharmed! ")
+ else if(src != M)
+ return ..()
+
+/mob/living/simple_animal/shade/attackby(obj/item/O, mob/user, params) //Marker -Agouri
+ if(istype(O, /obj/item/device/soulstone))
+ var/obj/item/device/soulstone/SS = O
+ SS.transfer_soul("SHADE", src, user)
+ else
+ . = ..()
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 144fec4a4a..4edf7a6dcb 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -271,11 +271,11 @@
/mob/living/simple_animal/movement_delay()
- . = ..()
-
- . = speed
-
- . += config.animal_delay
+ var/static/config_animal_delay
+ if(isnull(config_animal_delay))
+ config_animal_delay = CONFIG_GET(number/animal_delay)
+ . += config_animal_delay
+ return ..() + speed + config_animal_delay
/mob/living/simple_animal/Stat()
..()
@@ -317,7 +317,7 @@
var/mob/living/L = the_target
if(L.stat != CONSCIOUS)
return 0
- if (istype(the_target, /obj/mecha))
+ if (ismecha(the_target))
var/obj/mecha/M = the_target
if (M.occupant)
return 0
diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm
index 6026a86724..a3c37e9889 100644
--- a/code/modules/mob/living/simple_animal/slime/life.dm
+++ b/code/modules/mob/living/simple_animal/slime/life.dm
@@ -234,7 +234,7 @@
Feedstop(0, 0)
return
- add_nutrition((rand(7,15) * config.damage_multiplier))
+ add_nutrition((rand(7, 15) * CONFIG_GET(number/damage_multiplier)))
//Heal yourself.
adjustBruteLoss(-3)
diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm
index 0e7d7a157e..92d64702bb 100644
--- a/code/modules/mob/living/simple_animal/slime/slime.dm
+++ b/code/modules/mob/living/simple_animal/slime/slime.dm
@@ -146,7 +146,10 @@
if(health <= 0) // if damaged, the slime moves twice as slow
. *= 2
- . += config.slime_delay
+ var/static/config_slime_delay
+ if(isnull(config_slime_delay))
+ config_slime_delay = CONFIG_GET(number/slime_delay)
+ . += config_slime_delay
/mob/living/simple_animal/slime/ObjCollide(obj/O)
if(!client && powerlevel > 0)
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index f768cbe2d2..c75e0a27fb 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -9,8 +9,6 @@
var/mob/dead/observe = M
observe.reset_perspective(null)
qdel(hud_used)
- if(mind && mind.current == src)
- spellremove(src)
QDEL_LIST(viruses)
for(var/cc in client_colours)
qdel(cc)
@@ -162,7 +160,7 @@
for(var/mob/M in get_hearers_in_view(range, src))
M.show_message( message, 2, deaf_message, 1)
-/mob/proc/movement_delay()
+/mob/proc/movement_delay() //update /living/movement_delay() if you change this
return 0
/mob/proc/Life()
@@ -388,7 +386,7 @@
set category = "Object"
set src = usr
- if(istype(loc, /obj/mecha))
+ if(ismecha(loc))
return
if(incapacitated())
@@ -436,7 +434,7 @@
set name = "Respawn"
set category = "OOC"
- if (!( GLOB.abandon_allowed ))
+ if (CONFIG_GET(flag/norespawn))
return
if ((stat != DEAD || !( SSticker )))
to_chat(usr, "You must be dead to use this! ")
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 3396d157de..4da630bb31 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -62,6 +62,8 @@
/client/verb/delete_key_pressed()
set hidden = 1
+ if(!isliving(usr))
+ return
if(!usr.pulling)
to_chat(usr, "You are not pulling anything. ")
return
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index f9763cde7d..dc87736e5d 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -329,16 +329,14 @@
continue
loc_landmark = sloc.loc
if(!loc_landmark)
- for(var/obj/effect/landmark/tripai in GLOB.landmarks_list)
- if(tripai.name == "tripai")
- if(locate(/mob/living/silicon/ai) in tripai.loc)
- continue
- loc_landmark = tripai.loc
+ for(var/obj/effect/landmark/tripai/L in GLOB.landmarks_list)
+ if(locate(/mob/living/silicon/ai) in L.loc)
+ continue
+ loc_landmark = L.loc
if(!loc_landmark)
to_chat(src, "Oh god sorry we can't find an unoccupied AI spawn location, so we're spawning you on top of someone.")
- for(var/obj/effect/landmark/start/sloc in GLOB.landmarks_list)
- if (sloc.name == "AI")
- loc_landmark = sloc.loc
+ for(var/obj/effect/landmark/start/ai/sloc in GLOB.landmarks_list)
+ loc_landmark = sloc.loc
if(!transfer_after)
mind.active = FALSE
@@ -383,7 +381,7 @@
else if(transfer_after)
R.key = key
- if (config.rename_cyborg)
+ if (CONFIG_GET(flag/rename_cyborg))
R.rename_self("cyborg")
if(R.mmi)
diff --git a/code/modules/modular_computers/file_system/programs/card.dm b/code/modules/modular_computers/file_system/programs/card.dm
index 5dd6d16d54..ead6a35eea 100644
--- a/code/modules/modular_computers/file_system/programs/card.dm
+++ b/code/modules/modular_computers/file_system/programs/card.dm
@@ -44,7 +44,7 @@
addtimer(CALLBACK(src, .proc/SetConfigCooldown), 0)
/datum/computer_file/program/card_mod/proc/SetConfigCooldown()
- change_position_cooldown = config.id_console_jobslot_delay
+ change_position_cooldown = CONFIG_GET(number/id_console_jobslot_delay)
/datum/computer_file/program/card_mod/event_idremoved(background, slot)
if(!slot || slot == 2)// slot being false means both are removed
diff --git a/code/modules/ninja/ninja_event.dm b/code/modules/ninja/ninja_event.dm
index a3184cbb20..1656a43505 100644
--- a/code/modules/ninja/ninja_event.dm
+++ b/code/modules/ninja/ninja_event.dm
@@ -39,11 +39,9 @@ Contents:
//selecting a spawn_loc
if(!spawn_loc)
var/list/spawn_locs = list()
- for(var/obj/effect/landmark/L in GLOB.landmarks_list)
+ for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
if(isturf(L.loc))
- switch(L.name)
- if("ninjaspawn","carpspawn")
- spawn_locs += L.loc
+ spawn_locs += L.loc
if(!spawn_locs.len)
return kill()
spawn_loc = pick(spawn_locs)
diff --git a/code/modules/ninja/suit/gloves.dm b/code/modules/ninja/suit/gloves.dm
index 62b8cee415..8eaaa40097 100644
--- a/code/modules/ninja/suit/gloves.dm
+++ b/code/modules/ninja/suit/gloves.dm
@@ -63,7 +63,7 @@
if(isnum(.)) //Numerical values of drained handle their feedback here, Alpha values handle it themselves (Research hacking)
if(.)
- to_chat(H, "Gained [.] energy from \the [A]. ")
+ to_chat(H, "Gained [DisplayPower(.)] of energy from [A]. ")
else
to_chat(H, "\The [A] has run dry of power, you must find another source! ")
else
diff --git a/code/modules/power/antimatter/shielding.dm b/code/modules/power/antimatter/shielding.dm
index e6814c5c0a..39353737bb 100644
--- a/code/modules/power/antimatter/shielding.dm
+++ b/code/modules/power/antimatter/shielding.dm
@@ -32,16 +32,24 @@
. = ..()
addtimer(CALLBACK(src, .proc/controllerscan), 10)
+/obj/machinery/am_shielding/proc/overheat()
+ visible_message("[src] melts! ")
+ new /obj/effect/hotspot(loc)
+ qdel(src)
+
+/obj/machinery/am_shielding/proc/collapse()
+ visible_message("[src] collapses back into a container! ")
+ new /obj/item/device/am_shielding_container(drop_location())
+ qdel(src)
/obj/machinery/am_shielding/proc/controllerscan(priorscan = 0)
//Make sure we are the only one here
- if(!istype(src.loc, /turf))
- qdel(src)
- return
+ if(!isturf(loc))
+ collapse()
for(var/obj/machinery/am_shielding/AMS in loc.contents)
if(AMS == src)
continue
- qdel(src)
+ collapse()
return
//Search for shielding first
@@ -59,7 +67,7 @@
if(!priorscan)
addtimer(CALLBACK(src, .proc/controllerscan, 1), 20)
return
- qdel(src)
+ collapse()
/obj/machinery/am_shielding/Destroy()
@@ -67,7 +75,6 @@
control_unit.remove_shielding(src)
if(processing)
shutdown_core()
- visible_message("The [src.name] melts! ")
//Might want to have it leave a mess on the floor but no sprites for now
return ..()
@@ -209,7 +216,7 @@
if(injecting_fuel && control_unit)
control_unit.exploding = 1
if(src)
- qdel(src)
+ overheat()
return
diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm
index c64cb4f4ef..3d87de4e62 100644
--- a/code/modules/power/power.dm
+++ b/code/modules/power/power.dm
@@ -278,7 +278,7 @@
//dist_check - set to only shock mobs within 1 of source (vendors, airlocks, etc.)
//No animations will be performed by this proc.
/proc/electrocute_mob(mob/living/carbon/M, power_source, obj/source, siemens_coeff = 1, dist_check = FALSE)
- if(istype(M.loc, /obj/mecha))
+ if(ismecha(M.loc))
return 0 //feckin mechs are dumb
if(dist_check)
if(!in_range(source,M))
diff --git a/code/modules/power/singularity/containment_field.dm b/code/modules/power/singularity/containment_field.dm
index f819b35d75..f2610f97b0 100644
--- a/code/modules/power/singularity/containment_field.dm
+++ b/code/modules/power/singularity/containment_field.dm
@@ -57,8 +57,8 @@
/obj/machinery/field/containment/Crossed(mob/mover)
if(isliving(mover))
shock(mover)
-
- if(istype(mover, /obj/machinery) || istype(mover, /obj/structure) || istype(mover, /obj/mecha))
+
+ if(istype(mover, /obj/machinery) || isstructure(mover) || ismecha(mover))
bump_field(mover)
/obj/machinery/field/containment/proc/set_master(master1,master2)
@@ -90,13 +90,13 @@
if(isliving(mover))
shock(mover)
return
- if(istype(mover, /obj/machinery) || istype(mover, /obj/structure) || istype(mover, /obj/mecha))
+ if(istype(mover, /obj/machinery) || isstructure(mover) || ismecha(mover))
bump_field(mover)
return
/obj/machinery/field/CanPass(atom/movable/mover, turf/target)
- if(hasShocked || isliving(mover) || istype(mover, /obj/machinery) || istype(mover, /obj/structure) || istype(mover, /obj/mecha))
+ if(hasShocked || isliving(mover) || istype(mover, /obj/machinery) || isstructure(mover) || ismecha(mover))
return FALSE
return ..()
diff --git a/code/modules/power/singularity/particle_accelerator/particle.dm b/code/modules/power/singularity/particle_accelerator/particle.dm
index 4519835c1f..f04c61426b 100644
--- a/code/modules/power/singularity/particle_accelerator/particle.dm
+++ b/code/modules/power/singularity/particle_accelerator/particle.dm
@@ -1,62 +1,65 @@
-/obj/effect/accelerated_particle
- name = "Accelerated Particles"
- desc = "Small things moving very fast."
- icon = 'icons/obj/machines/particle_accelerator.dmi'
- icon_state = "particle"
+/obj/effect/accelerated_particle
+ name = "Accelerated Particles"
+ desc = "Small things moving very fast."
+ icon = 'icons/obj/machines/particle_accelerator.dmi'
+ icon_state = "particle"
anchored = TRUE
density = FALSE
- var/movement_range = 10
- var/energy = 10
- var/speed = 1
-
-/obj/effect/accelerated_particle/weak
- movement_range = 8
- energy = 5
-
-/obj/effect/accelerated_particle/strong
- movement_range = 15
- energy = 15
-
-/obj/effect/accelerated_particle/powerful
- movement_range = 20
- energy = 50
-
-
-/obj/effect/accelerated_particle/New(loc)
- ..()
-
- addtimer(CALLBACK(src, .proc/move), 1)
-
-
+ var/movement_range = 10
+ var/energy = 10
+ var/speed = 1
+
+/obj/effect/accelerated_particle/weak
+ movement_range = 8
+ energy = 5
+
+/obj/effect/accelerated_particle/strong
+ movement_range = 15
+ energy = 15
+
+/obj/effect/accelerated_particle/powerful
+ movement_range = 20
+ energy = 50
+
+
+/obj/effect/accelerated_particle/New(loc)
+ ..()
+
+ addtimer(CALLBACK(src, .proc/move), 1)
+
+
/obj/effect/accelerated_particle/Collide(atom/A)
- if(A)
- if(isliving(A))
- toxmob(A)
- else if(istype(A, /obj/machinery/the_singularitygen))
- var/obj/machinery/the_singularitygen/S = A
- S.energy += energy
- else if(istype(A, /obj/singularity))
- var/obj/singularity/S = A
- S.energy += energy
-
-
-/obj/effect/accelerated_particle/Crossed(atom/A)
- if(isliving(A))
- toxmob(A)
-
-
-/obj/effect/accelerated_particle/ex_act(severity, target)
- qdel(src)
-
-/obj/effect/accelerated_particle/proc/toxmob(mob/living/M)
- M.rad_act(energy*6)
-
-/obj/effect/accelerated_particle/proc/move()
- if(!step(src,dir))
- forceMove(get_step(src,dir))
- movement_range--
- if(movement_range == 0)
- qdel(src)
- else
- sleep(speed)
- move()
+ if(A)
+ if(isliving(A))
+ toxmob(A)
+ else if(istype(A, /obj/machinery/the_singularitygen))
+ var/obj/machinery/the_singularitygen/S = A
+ S.energy += energy
+ else if(istype(A, /obj/singularity))
+ var/obj/singularity/S = A
+ S.energy += energy
+ else if(istype(A, /obj/structure/blob))
+ var/obj/structure/blob/B = A
+ B.take_damage(energy*0.6)
+ movement_range = 0
+
+/obj/effect/accelerated_particle/Crossed(atom/A)
+ if(isliving(A))
+ toxmob(A)
+
+
+/obj/effect/accelerated_particle/ex_act(severity, target)
+ qdel(src)
+
+/obj/effect/accelerated_particle/proc/toxmob(mob/living/M)
+ M.rad_act(energy*6)
+
+/obj/effect/accelerated_particle/proc/move()
+ if(!step(src,dir))
+ forceMove(get_step(src,dir))
+ movement_range--
+ if(movement_range == 0)
+ qdel(src)
+ else
+ sleep(speed)
+ move()
diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm
index eb6b3f0c52..b6f7d20fbc 100644
--- a/code/modules/power/supermatter/supermatter.dm
+++ b/code/modules/power/supermatter/supermatter.dm
@@ -491,6 +491,9 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard)
/obj/machinery/power/supermatter_shard/attack_paw(mob/user)
dust_mob(user, cause = "monkey attack")
+/obj/machinery/power/supermatter_shard/attack_alien(mob/user)
+ dust_mob(user, cause = "alien attack")
+
/obj/machinery/power/supermatter_shard/attack_animal(mob/living/simple_animal/S)
var/murder
if(!S.melee_damage_upper && !S.melee_damage_lower)
diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm
index 6d90a88a33..d8d396d311 100644
--- a/code/modules/power/tesla/energy_ball.dm
+++ b/code/modules/power/tesla/energy_ball.dm
@@ -244,7 +244,7 @@
else if(closest_blob)
continue
- else if(istype(A, /obj/structure))
+ else if(isstructure(A))
var/obj/structure/S = A
var/dist = get_dist(source, A)
if(dist <= zap_range && (dist < closest_dist || !closest_tesla_coil) && !S.being_shocked)
diff --git a/code/modules/projectiles/guns/misc/blastcannon.dm b/code/modules/projectiles/guns/misc/blastcannon.dm
index 603f8843ca..5ee2ecec05 100644
--- a/code/modules/projectiles/guns/misc/blastcannon.dm
+++ b/code/modules/projectiles/guns/misc/blastcannon.dm
@@ -12,21 +12,17 @@
randomspread = FALSE
var/obj/item/device/transfer_valve/bomb
- var/datum/gas_mixture/air1
- var/datum/gas_mixture/air2
/obj/item/gun/blastcannon/New()
if(!pin)
pin = new
- . = ..()
+ return ..()
/obj/item/gun/blastcannon/Destroy()
if(bomb)
qdel(bomb)
bomb = null
- air1 = null
- air2 = null
- . = ..()
+ return ..()
/obj/item/gun/blastcannon/attack_self(mob/user)
if(bomb)
@@ -35,7 +31,7 @@
user.visible_message("[user] detaches the [bomb] from the [src] ")
bomb = null
update_icon()
- . = ..(user)
+ return ..()
/obj/item/gun/blastcannon/update_icon()
if(bomb)
@@ -46,7 +42,6 @@
icon_state = initial(icon_state)
name = initial(name)
desc = initial(desc)
- . = ..()
/obj/item/gun/blastcannon/attackby(obj/O, mob/user)
if(istype(O, /obj/item/device/transfer_valve))
@@ -59,20 +54,17 @@
return FALSE
user.visible_message("[user] attaches the [O] to the [src]! ")
bomb = O
- O.loc = src
+ O.forceMove(src)
update_icon()
return TRUE
- . = ..()
+ return ..()
/obj/item/gun/blastcannon/proc/calculate_bomb()
if(!istype(bomb)||!istype(bomb.tank_one)||!istype(bomb.tank_two))
return 0
- air1 = bomb.tank_one.air_contents
- air2 = bomb.tank_two.air_contents
- var/datum/gas_mixture/temp
- temp.volume = air1.volume + air2.volume
- temp.merge(air1)
- temp.merge(air2)
+ var/datum/gas_mixture/temp = new(60) //directional buff.
+ temp.merge(bomb.tank_one.air_contents.remove_ratio(1))
+ temp.merge(bomb.tank_two.air_contents.remove_ratio(2))
for(var/i in 1 to 6)
temp.react()
var/pressure = temp.return_pressure()
@@ -82,7 +74,7 @@
return (pressure/TANK_FRAGMENT_SCALE)
/obj/item/gun/blastcannon/afterattack(atom/target, mob/user, flag, params)
- if((!bomb) || (target == user) || (target.loc == user) || (!target) || (target.loc == user.loc) || (target.loc in range(user, 2)) || (target in range(user, 2)))
+ if((!bomb) || (!target) || (get_dist(get_turf(target), get_turf(user)) <= 2))
return ..()
var/power = calculate_bomb()
qdel(bomb)
@@ -90,13 +82,17 @@
var/heavy = power * 0.2
var/medium = power * 0.5
var/light = power
- user.visible_message("[user] opens \the [bomb] on \his [src.name] and fires a blast wave at \the [target]! ","You open \the [bomb] on your [src.name] and fire a blast wave at \the [target]! ")
+ user.visible_message("[user] opens \the [bomb] on \his [name] and fires a blast wave at \the [target]! ","You open \the [bomb] on your [name] and fire a blast wave at \the [target]! ")
playsound(user, "explosion", 100, 1)
var/turf/starting = get_turf(user)
+ var/turf/targturf = get_turf(target)
var/area/A = get_area(user)
- var/log_str = "Blast wave fired at [ADMIN_COORDJMP(starting)] ([A.name]) by [user.name]([user.ckey]) with power [heavy]/[medium]/[light]."
+ var/log_str = "Blast wave fired from [ADMIN_COORDJMP(starting)] ([A.name]) at [ADMIN_COORDJMP(targturf)] ([target.name]) by [user.name]([user.ckey]) with power [heavy]/[medium]/[light]."
message_admins(log_str)
log_game(log_str)
+ var/obj/item/projectile/blastwave/BW = new(loc, heavy, medium, light)
+ BW.preparePixelProjectile(target, get_turf(target), user, params, 0)
+ BW.fire()
/obj/item/projectile/blastwave
name = "blast wave"
@@ -109,6 +105,12 @@
var/lightr = 0
range = 150
+/obj/item/projectile/blastwave/Initialize(mapload, _h, _m, _l)
+ heavyr = _h
+ mediumr = _m
+ lightr = _l
+ return ..()
+
/obj/item/projectile/blastwave/Range()
..()
if(heavyr)
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index e18ac0ab5c..937326a60b 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -90,8 +90,6 @@
new impact_effect_type(target_loca, target, src)
return 0
var/mob/living/L = target
- if(L.buckled && ismob(L.buckled))
- L = L.buckled
if(blocked != 100) // not completely blocked
if(damage && L.blood_volume && damage_type == BRUTE)
var/splatter_dir = dir
@@ -144,7 +142,7 @@
ignore_source_check = TRUE
return FALSE
if(firer && !ignore_source_check)
- if(A == firer || (A == firer.loc && istype(A, /obj/mecha))) //cannot shoot yourself or your mech
+ if(A == firer || (A == firer.loc && ismecha(A))) //cannot shoot yourself or your mech
loc = A.loc
return FALSE
@@ -178,6 +176,8 @@
var/mob/living/picked_mob = pick(mobs_list)
if(!prehit(picked_mob))
return FALSE
+ if(ismob(picked_mob.buckled))
+ picked_mob = picked_mob.buckled
picked_mob.bullet_act(src, def_zone)
qdel(src)
return TRUE
@@ -280,7 +280,7 @@
if(can_hit_target(original, permutated))
Collide(original)
Range()
- sleep(config.run_speed * 0.9)
+ sleep(CONFIG_GET(number/run_delay) * 0.9)
//Returns true if the target atom is on our current turf and above the right layer
/obj/item/projectile/proc/can_hit_target(atom/target, var/list/passthrough)
diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm
index 6f4ae50243..8395ef4d83 100644
--- a/code/modules/projectiles/projectile/bullets.dm
+++ b/code/modules/projectiles/projectile/bullets.dm
@@ -10,7 +10,7 @@
/obj/item/projectile/bullet/pellet/Range()
..()
- damage += -0.75
+ damage -= 0.75
if(damage < 0)
qdel(src)
@@ -66,7 +66,7 @@
/obj/item/projectile/bullet/c38
name = ".38 bullet"
damage = 15
- knockdown = 30
+ knockdown = 60
stamina = 50
// 10mm (Stechkin)
diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm
index 8c4f80b772..5665b365a1 100644
--- a/code/modules/projectiles/projectile/magic.dm
+++ b/code/modules/projectiles/projectile/magic.dm
@@ -276,7 +276,9 @@
to_chat(new_mob, "Your form morphs into that of a [randomize]. ")
- to_chat(new_mob, config.policies["polymorph"])
+ var/poly_msg = CONFIG_GET(keyed_string_list/policy)["polymorph"]
+ if(poly_msg)
+ to_chat(new_mob, poly_msg)
qdel(M)
return new_mob
@@ -293,7 +295,7 @@
..()
/atom/proc/animate_atom_living(var/mob/living/owner = null)
- if((isitem(src) || istype(src, /obj/structure)) && !is_type_in_list(src, GLOB.protected_objects))
+ if((isitem(src) || isstructure(src)) && !is_type_in_list(src, GLOB.protected_objects))
if(istype(src, /obj/structure/statue/petrified))
var/obj/structure/statue/petrified/P = src
if(P.petrified_mob)
diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm
index 79a3d51eec..a5ba7c15a4 100644
--- a/code/modules/projectiles/projectile/special.dm
+++ b/code/modules/projectiles/projectile/special.dm
@@ -45,7 +45,7 @@
..()
explosion(target, -1, 1, 3, 1, 0, flame_range = 4)
- if(istype(target, /obj/mecha))
+ if(ismecha(target))
var/obj/mecha/M = target
M.take_damage(anti_armour_damage)
if(issilicon(target))
diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm
index 5d089739d1..946ec70d38 100644
--- a/code/modules/research/designs/autolathe_designs.dm
+++ b/code/modules/research/designs/autolathe_designs.dm
@@ -608,6 +608,14 @@
build_path = /obj/item/device/electropack
category = list("hacked", "Tools")
+/datum/design/shock_collar
+ name = "Shock Collar"
+ id = "shock_collar"
+ build_type = AUTOLATHE
+ materials = list(MAT_METAL = 5000, MAT_GLASS = 2000)
+ build_path = /obj/item/device/electropack/shockcollar
+ category = list("hacked", "Security")
+
/datum/design/large_welding_tool
name = "Industrial Welding Tool"
id = "large_welding_tool"
diff --git a/code/modules/research/message_server.dm b/code/modules/research/message_server.dm
index 650eebba1a..0cef65c07c 100644
--- a/code/modules/research/message_server.dm
+++ b/code/modules/research/message_server.dm
@@ -67,6 +67,7 @@ GLOBAL_LIST_INIT(message_servers, list())
icon = 'icons/obj/machines/research.dmi'
icon_state = "server"
name = "Messaging Server"
+ desc = "A machine that attempts to gather the secret knowledge of the universe."
density = TRUE
anchored = TRUE
use_power = IDLE_POWER_USE
diff --git a/code/modules/ruins/objects_and_mobs/ash_walker_den.dm b/code/modules/ruins/objects_and_mobs/ash_walker_den.dm
index 5e0f43c7a9..1cc5b482f0 100644
--- a/code/modules/ruins/objects_and_mobs/ash_walker_den.dm
+++ b/code/modules/ruins/objects_and_mobs/ash_walker_den.dm
@@ -25,6 +25,9 @@
if(H.stat)
visible_message("Serrated tendrils eagerly pull [H] to [src], tearing the body apart as its blood seeps over the eggs. ")
playsound(get_turf(src),'sound/magic/demon_consume.ogg', 100, 1)
+ for(var/obj/item/W in H)
+ if(!H.dropItemToGround(W))
+ qdel(W)
if(ismegafauna(H))
meat_counter += 20
else
diff --git a/code/modules/security_levels/security_levels.dm b/code/modules/security_levels/security_levels.dm
index 1fa3e89d3a..a145028ad3 100644
--- a/code/modules/security_levels/security_levels.dm
+++ b/code/modules/security_levels/security_levels.dm
@@ -21,7 +21,7 @@ GLOBAL_VAR_INIT(security_level, 0)
if(level >= SEC_LEVEL_GREEN && level <= SEC_LEVEL_DELTA && level != GLOB.security_level)
switch(level)
if(SEC_LEVEL_GREEN)
- minor_announce(config.alert_desc_green, "Attention! Security level lowered to green:")
+ minor_announce(CONFIG_GET(string/alert_green), "Attention! Security level lowered to green:")
if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
if(GLOB.security_level >= SEC_LEVEL_RED)
SSshuttle.emergency.modTimer(4)
@@ -33,11 +33,11 @@ GLOBAL_VAR_INIT(security_level, 0)
FA.update_icon()
if(SEC_LEVEL_BLUE)
if(GLOB.security_level < SEC_LEVEL_BLUE)
- minor_announce(config.alert_desc_blue_upto, "Attention! Security level elevated to blue:",1)
+ minor_announce(CONFIG_GET(string/alert_blue_upto), "Attention! Security level elevated to blue:",1)
if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
SSshuttle.emergency.modTimer(0.5)
else
- minor_announce(config.alert_desc_blue_downto, "Attention! Security level lowered to blue:")
+ minor_announce(CONFIG_GET(string/alert_blue_downto), "Attention! Security level lowered to blue:")
if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
SSshuttle.emergency.modTimer(2)
GLOB.security_level = SEC_LEVEL_BLUE
@@ -47,14 +47,14 @@ GLOBAL_VAR_INIT(security_level, 0)
FA.update_icon()
if(SEC_LEVEL_RED)
if(GLOB.security_level < SEC_LEVEL_RED)
- minor_announce(config.alert_desc_red_upto, "Attention! Code red!",1)
+ minor_announce(CONFIG_GET(string/alert_red_upto), "Attention! Code red!",1)
if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
if(GLOB.security_level == SEC_LEVEL_GREEN)
SSshuttle.emergency.modTimer(0.25)
else
SSshuttle.emergency.modTimer(0.5)
else
- minor_announce(config.alert_desc_red_downto, "Attention! Code red!")
+ minor_announce(CONFIG_GET(string/alert_red_downto), "Attention! Code red!")
GLOB.security_level = SEC_LEVEL_RED
/* - At the time of commit, setting status displays didn't work properly
@@ -68,7 +68,7 @@ GLOBAL_VAR_INIT(security_level, 0)
for(var/obj/machinery/computer/shuttle/pod/pod in GLOB.machines)
pod.admin_controlled = 0
if(SEC_LEVEL_DELTA)
- minor_announce(config.alert_desc_delta, "Attention! Delta security level reached!",1)
+ minor_announce(CONFIG_GET(string/alert_delta), "Attention! Delta security level reached!",1)
if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
if(GLOB.security_level == SEC_LEVEL_GREEN)
SSshuttle.emergency.modTimer(0.25)
diff --git a/code/modules/server_tools/server_tools.dm b/code/modules/server_tools/server_tools.dm
index f16a56b2f9..9cacb4542f 100644
--- a/code/modules/server_tools/server_tools.dm
+++ b/code/modules/server_tools/server_tools.dm
@@ -77,7 +77,8 @@ GLOBAL_PROTECT(reboot_mode)
if(rtod - last_irc_status < IRC_STATUS_THROTTLE)
return
last_irc_status = rtod
- return "[GLOB.round_id ? "Round #[GLOB.round_id]: " : ""][GLOB.clients.len] players on [SSmapping.config.map_name], Mode: [GLOB.master_mode]; Round [SSticker.HasRoundStarted() ? (SSticker.IsRoundInProgress() ? "Active" : "Finishing") : "Starting"] -- [config.server ? config.server : "[world.internet_address]:[world.port]"]"
+ var/config_server = CONFIG_GET(string/server)
+ return "[GLOB.round_id ? "Round #[GLOB.round_id]: " : ""][GLOB.clients.len] players on [SSmapping.config.map_name], Mode: [GLOB.master_mode]; Round [SSticker.HasRoundStarted() ? (SSticker.IsRoundInProgress() ? "Active" : "Finishing") : "Starting"] -- [config_server ? config_server : "[world.internet_address]:[world.port]"]"
if(SERVICE_CMD_ADMIN_MSG)
return IrcPm(params[SERVICE_CMD_PARAM_TARGET], params[SERVICE_CMD_PARAM_MESSAGE], params[SERVICE_CMD_PARAM_SENDER])
diff --git a/code/modules/server_tools/st_commands.dm b/code/modules/server_tools/st_commands.dm
new file mode 100644
index 0000000000..9ec87a595c
--- /dev/null
+++ b/code/modules/server_tools/st_commands.dm
@@ -0,0 +1,76 @@
+/datum/server_tools_command
+ var/name = "" //the string to trigger this command on a chat bot. e.g. TGS3_BOT: do_this_command
+ var/help_text = "" //help text for this command
+ var/required_parameters = 0 //number of parameters required for this command
+ var/admin_only = FALSE //set to TRUE if this command should only be usable by registered chat admins
+
+//override to implement command
+//sender is the display name of who sent the command
+//params is the trimmed string following the command name
+/datum/server_tools_command/proc/Run(sender, params)
+ CRASH("[type] has no implementation for Run()")
+
+/world/proc/ListServiceCustomCommands(warnings_only)
+ if(!warnings_only)
+ . = list()
+ var/list/command_name_types = list()
+ var/list/warned_command_names = warnings_only ? list() : null
+ for(var/I in typesof(/datum/server_tools_command) - /datum/server_tools_command)
+ var/datum/server_tools_command/stc = I
+ var/command_name = initial(stc.name)
+ var/static/list/warned_server_tools_names = list()
+ if(!command_name || findtext(command_name, " ") || findtext(command_name, "'") || findtext(command_name, "\""))
+ if(warnings_only && !warned_command_names[command_name])
+ SERVER_TOOLS_LOG("WARNING: Custom command [command_name] can't be used as it is empty or contains illegal characters!")
+ warned_command_names[command_name] = TRUE
+ continue
+
+ if(command_name_types[command_name])
+ if(warnings_only)
+ SERVER_TOOLS_LOG("WARNING: Custom commands [command_name_types[command_name]] and [stc] have the same name, only [command_name_types[command_name]] will be available!")
+ continue
+ command_name_types[stc] = command_name
+
+ if(!warnings_only)
+ .[command_name] = list(SERVICE_JSON_PARAM_HELPTEXT = initial(stc.help_text), SERVICE_JSON_PARAM_ADMINONLY = initial(stc.admin_only), SERVICE_JSON_PARAM_REQUIREDPARAMETERS = initial(stc.required_parameters))
+
+/world/proc/HandleServiceCustomCommand(command, sender, params)
+ var/static/list/cached_custom_server_tools_commands
+ if(!cached_custom_server_tools_commands)
+ cached_custom_server_tools_commands = list()
+ for(var/I in typesof(/datum/server_tools_command) - /datum/server_tools_command)
+ var/datum/server_tools_command/stc = I
+ cached_custom_server_tools_commands[lowertext(initial(stc.name))] = stc
+
+ var/command_type = cached_custom_server_tools_commands[command]
+ if(!command_type)
+ return FALSE
+ var/datum/server_tools_command/stc = new command_type
+ return stc.Run(sender, params) || TRUE
+
+/*
+The MIT License
+
+Copyright (c) 2011 Dominic Tarr
+
+Permission is hereby granted, free of charge,
+to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to
+deal in the Software without restriction, including
+without limitation the rights to use, copy, modify,
+merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom
+the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
diff --git a/code/modules/server_tools/st_interface.dm b/code/modules/server_tools/st_interface.dm
new file mode 100644
index 0000000000..10b7f920e8
--- /dev/null
+++ b/code/modules/server_tools/st_interface.dm
@@ -0,0 +1,127 @@
+SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(reboot_mode, REBOOT_MODE_NORMAL)
+SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(server_tools_api_compatible, FALSE)
+
+/proc/GetTestMerges()
+ if(RunningService() && fexists(SERVICE_PR_TEST_JSON))
+ . = json_decode(file2text(SERVICE_PR_TEST_JSON))
+ if(.)
+ return
+ return list()
+
+/world/proc/ServiceInit()
+ if(!RunningService(TRUE))
+ return
+ ListServiceCustomCommands(TRUE)
+ ExportService("[SERVICE_REQUEST_API_VERSION] [SERVER_TOOLS_API_VERSION]", TRUE)
+
+/proc/RunningService(skip_compat_check = FALSE)
+ return (skip_compat_check || SERVER_TOOLS_READ_GLOBAL(server_tools_api_compatible)) && world.params[SERVICE_WORLD_PARAM] != null
+
+/proc/ServiceVersion()
+ if(RunningService(TRUE))
+ return world.params[SERVICE_VERSION_PARAM]
+
+/proc/ServiceAPIVersion()
+ return SERVICE_API_VERSION_STRING
+
+/world/proc/ExportService(command, skip_compat_check = FALSE)
+ . = FALSE
+ if(!RunningService(skip_compat_check))
+ return
+ if(skip_compat_check && !fexists(SERVICE_INTERFACE_DLL))
+ CRASH("Service parameter present but no interface DLL detected. This is symptomatic of running a service less than version 3.1! Please upgrade.")
+ call(SERVICE_INTERFACE_DLL, SERVICE_INTERFACE_FUNCTION)(command) //trust no retval
+ return TRUE
+
+/world/proc/ChatBroadcast(message)
+ ExportService("[SERVICE_REQUEST_IRC_BROADCAST] [message]")
+
+/world/proc/AdminBroadcast(message)
+ ExportService("[SERVICE_REQUEST_IRC_ADMIN_CHANNEL_MESSAGE] [message]")
+
+/world/proc/ServiceEndProcess()
+ SERVER_TOOLS_LOG("Sending shutdown request!");
+ sleep(world.tick_lag) //flush the buffers
+ ExportService(SERVICE_REQUEST_KILL_PROCESS)
+
+//called at the exact moment the world is supposed to reboot
+/world/proc/ServiceReboot()
+ switch(SERVER_TOOLS_READ_GLOBAL(reboot_mode))
+ if(REBOOT_MODE_HARD)
+ SERVER_TOOLS_WORLD_ANNOUNCE("Hard reboot triggered, you will automatically reconnect...")
+ ServiceEndProcess()
+ if(REBOOT_MODE_SHUTDOWN)
+ SERVER_TOOLS_WORLD_ANNOUNCE("The server is shutting down...")
+ ServiceEndProcess()
+ else
+ ExportService(SERVICE_REQUEST_WORLD_REBOOT) //just let em know
+
+/world/proc/ServiceCommand(list/params)
+ var/their_sCK = params[SERVICE_CMD_PARAM_KEY]
+ if(!their_sCK || !RunningService(TRUE))
+ return FALSE //continue world/Topic
+
+ var/sCK = world.params[SERVICE_WORLD_PARAM]
+ if(their_sCK != sCK)
+ return "Invalid comms key!";
+
+ var/command = params[SERVICE_CMD_PARAM_COMMAND]
+ if(!command)
+ return "No command!"
+
+ switch(command)
+ if(SERVICE_CMD_API_COMPATIBLE)
+ SERVER_TOOLS_WRITE_GLOBAL(server_tools_api_compatible, TRUE)
+ return "SUCCESS"
+ if(SERVICE_CMD_HARD_REBOOT)
+ if(SERVER_TOOLS_READ_GLOBAL(reboot_mode) != REBOOT_MODE_HARD)
+ SERVER_TOOLS_WRITE_GLOBAL(reboot_mode, REBOOT_MODE_HARD)
+ SERVER_TOOLS_LOG("Hard reboot requested by service")
+ SERVER_TOOLS_NOTIFY_ADMINS("The world will hard reboot at the end of the game. Requested by service.")
+ if(SERVICE_CMD_GRACEFUL_SHUTDOWN)
+ if(SERVER_TOOLS_READ_GLOBAL(reboot_mode) != REBOOT_MODE_SHUTDOWN)
+ SERVER_TOOLS_WRITE_GLOBAL(reboot_mode, REBOOT_MODE_SHUTDOWN)
+ SERVER_TOOLS_LOG("Shutdown requested by service")
+ message_admins("The world will shutdown at the end of the game. Requested by service.")
+ if(SERVICE_CMD_WORLD_ANNOUNCE)
+ var/msg = params["message"]
+ if(!istext(msg) || !msg)
+ return "No message set!"
+ SERVER_TOOLS_WORLD_ANNOUNCE(msg)
+ return "SUCCESS"
+ if(SERVICE_CMD_PLAYER_COUNT)
+ return "[SERVER_TOOLS_CLIENT_COUNT]"
+ if(SERVICE_CMD_LIST_CUSTOM)
+ return json_encode(ListServiceCustomCommands(FALSE))
+ else
+ var/custom_command_result = HandleServiceCustomCommand(lowertext(command), params[SERVICE_CMD_PARAM_SENDER], params[SERVICE_CMD_PARAM_CUSTOM])
+ if(custom_command_result)
+ return istext(custom_command_result) ? custom_command_result : "SUCCESS"
+ return "Unknown command: [command]"
+
+/*
+The MIT License
+
+Copyright (c) 2011 Dominic Tarr
+
+Permission is hereby granted, free of charge,
+to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to
+deal in the Software without restriction, including
+without limitation the rights to use, copy, modify,
+merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom
+the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
diff --git a/code/modules/shuttle/arrivals.dm b/code/modules/shuttle/arrivals.dm
index 16aa279901..b42ee4e0e4 100644
--- a/code/modules/shuttle/arrivals.dm
+++ b/code/modules/shuttle/arrivals.dm
@@ -130,7 +130,7 @@
return FALSE
/obj/docking_port/mobile/arrivals/proc/SendToStation()
- var/dockTime = config.arrivals_shuttle_dock_window
+ var/dockTime = CONFIG_GET(number/arrivals_shuttle_dock_window)
if(mode == SHUTTLE_CALL && timeLeft(1) > dockTime)
if(console)
console.say(damaged ? "Initiating emergency docking for repairs!" : "Now approaching: [station_name()].")
diff --git a/code/modules/shuttle/computer.dm b/code/modules/shuttle/computer.dm
index 8384e978e5..47ceaef99e 100644
--- a/code/modules/shuttle/computer.dm
+++ b/code/modules/shuttle/computer.dm
@@ -1,5 +1,6 @@
/obj/machinery/computer/shuttle
name = "shuttle console"
+ desc = "A shuttle control computer."
icon_screen = "shuttle"
icon_keyboard = "tech_key"
light_color = LIGHT_COLOR_CYAN
diff --git a/code/modules/shuttle/ferry.dm b/code/modules/shuttle/ferry.dm
index 5b27e562f3..07103088d1 100644
--- a/code/modules/shuttle/ferry.dm
+++ b/code/modules/shuttle/ferry.dm
@@ -1,5 +1,6 @@
/obj/machinery/computer/shuttle/ferry
name = "transport ferry console"
+ desc = "A console that controls the transport ferry."
circuit = /obj/item/circuitboard/computer/ferry
shuttleId = "ferry"
possible_destinations = "ferry_home;ferry_away"
diff --git a/code/modules/shuttle/syndicate.dm b/code/modules/shuttle/syndicate.dm
index ac1339d33e..4574e62bd1 100644
--- a/code/modules/shuttle/syndicate.dm
+++ b/code/modules/shuttle/syndicate.dm
@@ -2,6 +2,7 @@
/obj/machinery/computer/shuttle/syndicate
name = "syndicate shuttle terminal"
+ desc = "The terminal used to control the syndicate transport shuttle."
circuit = /obj/item/circuitboard/computer/syndicate_shuttle
icon_screen = "syndishuttle"
icon_keyboard = "syndie_key"
@@ -13,6 +14,7 @@
/obj/machinery/computer/shuttle/syndicate/recall
name = "syndicate shuttle recall terminal"
+ desc = "Use this if your friends left you behind."
possible_destinations = "syndicate_away"
@@ -27,6 +29,7 @@
/obj/machinery/computer/shuttle/syndicate/drop_pod
name = "syndicate assault pod control"
+ desc = "Controls the drop pod's launch system."
icon = 'icons/obj/terminals.dmi'
icon_state = "dorm_available"
light_color = LIGHT_COLOR_BLUE
diff --git a/code/modules/spells/spell_types/godhand.dm b/code/modules/spells/spell_types/godhand.dm
index 455f5ef165..33f947408a 100644
--- a/code/modules/spells/spell_types/godhand.dm
+++ b/code/modules/spells/spell_types/godhand.dm
@@ -49,6 +49,9 @@
/obj/item/melee/touch_attack/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
+ if(!user.can_speak_vocal())
+ to_chat(user, "You can't get the words out! ")
+ return
var/mob/M = target
do_sparks(4, FALSE, M.loc)
M.gib()
@@ -68,6 +71,9 @@
if(user.lying || user.handcuffed)
to_chat(user, "You can't reach out! ")
return
+ if(!user.can_speak_vocal())
+ to_chat(user, "You can't get the words out! ")
+ return
var/mob/living/M = target
M.Stun(40)
M.petrify()
diff --git a/code/modules/spells/spell_types/lichdom.dm b/code/modules/spells/spell_types/lichdom.dm
index c9fc54f7e6..f7e555ab44 100644
--- a/code/modules/spells/spell_types/lichdom.dm
+++ b/code/modules/spells/spell_types/lichdom.dm
@@ -132,7 +132,7 @@
lich.real_name = mind.name
mind.transfer_to(lich)
mind.grab_ghost(force=TRUE)
- lich.hardset_dna(null,null,lich.real_name,null, /datum/species/skeleton)
+ lich.hardset_dna(null,null,lich.real_name,null, new /datum/species/skeleton)
to_chat(lich, "Your bones clatter and shutter as you are pulled back into this world! ")
var/turf/body_turf = get_turf(old_body)
lich.Knockdown(200 + 200*resurrections)
diff --git a/code/modules/spells/spell_types/shadow_walk.dm b/code/modules/spells/spell_types/shadow_walk.dm
index 45ea521098..9f9b4ac223 100644
--- a/code/modules/spells/spell_types/shadow_walk.dm
+++ b/code/modules/spells/spell_types/shadow_walk.dm
@@ -25,8 +25,9 @@
if(light_amount < SHADOW_SPECIES_LIGHT_THRESHOLD)
playsound(get_turf(user), 'sound/magic/ethereal_enter.ogg', 50, 1, -1)
visible_message("[user] melts into the shadows! ")
- user.AdjustStun(-20, 0)
- user.AdjustKnockdown(-20, 0)
+ user.SetStun(0, FALSE)
+ user.SetKnockdown(0, FALSE)
+ user.setStaminaLoss(0, 0)
var/obj/effect/dummy/shadow/S2 = new(get_turf(user.loc))
user.forceMove(S2)
S2.jaunter = user
diff --git a/code/modules/stock_market/computer.dm b/code/modules/stock_market/computer.dm
index 90ad08c4bb..3422145ec3 100644
--- a/code/modules/stock_market/computer.dm
+++ b/code/modules/stock_market/computer.dm
@@ -13,7 +13,7 @@
/obj/machinery/computer/stockexchange/Initialize()
. = ..()
- logged_in = "[station_name()] Cargo Department"
+ logged_in = "SS13 Cargo Department"
/obj/machinery/computer/stockexchange/proc/balance()
if (!logged_in)
@@ -63,7 +63,7 @@ a.updated {
"}
var/dat = "[station_name()] Stock Exchange [css]"
- dat += "Welcome, [logged_in] Credits: [balance()] "
+ dat += "Welcome, [station_name()] Cargo Department Credits: [balance()] "
for (var/datum/stock/S in GLOB.stockExchange.last_read)
var/list/LR = GLOB.stockExchange.last_read[S]
if (!(logged_in in LR))
diff --git a/code/modules/surgery/bodyparts/bodyparts.dm b/code/modules/surgery/bodyparts/bodyparts.dm
index b239e39576..f05a3a7e42 100644
--- a/code/modules/surgery/bodyparts/bodyparts.dm
+++ b/code/modules/surgery/bodyparts/bodyparts.dm
@@ -108,8 +108,9 @@
/obj/item/bodypart/proc/receive_damage(brute, burn, updating_health = 1)
if(owner && (owner.status_flags & GODMODE))
return 0 //godmode
- brute = max(brute * config.damage_multiplier,0)
- burn = max(burn * config.damage_multiplier,0)
+ var/dmg_mlt = CONFIG_GET(number/damage_multiplier)
+ brute = max(brute * dmg_mlt, 0)
+ burn = max(burn * dmg_mlt, 0)
if(status == BODYPART_ROBOTIC) //This makes robolimbs not damageable by chems and makes it stronger
diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm
index 4b939bf4f1..3b83dd8e62 100644
--- a/code/modules/surgery/organs/eyes.dm
+++ b/code/modules/surgery/organs/eyes.dm
@@ -44,9 +44,11 @@
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
actions_types = list(/datum/action/item_action/organ_action/use)
+ sight_flags = SEE_BLACKNESS
var/night_vision = TRUE
/obj/item/organ/eyes/night_vision/ui_action_click()
+ sight_flags = initial(sight_flags)
switch(lighting_alpha)
if (LIGHTING_PLANE_ALPHA_VISIBLE)
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
@@ -56,6 +58,7 @@
lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE
else
lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE
+ sight_flags &= ~SEE_BLACKNESS
owner.update_sight()
/obj/item/organ/eyes/night_vision/alien
diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm
index f5a00d24cb..4fdda7a7bc 100644
--- a/code/modules/surgery/organs/organ_internal.dm
+++ b/code/modules/surgery/organs/organ_internal.dm
@@ -10,6 +10,8 @@
var/slot
// DO NOT add slots with matching names to different zones - it will break internal_organs_slot list!
var/vital = 0
+ //Was this organ implanted/inserted/etc, if true will not be removed during species change.
+ var/external = FALSE
/obj/item/organ/proc/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
diff --git a/code/modules/uplink/uplink_item_cit.dm b/code/modules/uplink/uplink_item_cit.dm
index 3aa1fd8bb1..40c74269eb 100644
--- a/code/modules/uplink/uplink_item_cit.dm
+++ b/code/modules/uplink/uplink_item_cit.dm
@@ -55,7 +55,7 @@
/datum/uplink_item/ammo/pistolzzz
name = "10mm Soporific Magazine"
desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. Loaded with soporific rounds that put the target to sleep. \
- NOTE: Soporific is not instant acting due to the constraints of the round's scale. Will usually require two shots to take effect."
+ NOTE: Soporific is not instant acting due to the constraints of the round's scale. Will usually require three shots to take effect."
item = /obj/item/ammo_box/magazine/m10mm/soporific
cost = 2
diff --git a/config/config.txt b/config/config.txt
index 80a587885b..72f168dcce 100644
--- a/config/config.txt
+++ b/config/config.txt
@@ -1,3 +1,11 @@
+# You can use the @ character at the beginning of a config option to lock it from being edited in-game
+# Example usage:
+# @SERVERNAME tgstation
+# Which sets the SERVERNAME, and disallows admins from being able to change it using View Variables.
+# @LOG_TWITTER 0
+# Which explicitly disables LOG_TWITTER, as well as locking it.
+# There are various options which are hard-locked for security reasons.
+
## Server name: This appears at the top of the screen in-game and in the BYOND hub. Uncomment and replace 'tgstation' with the name of your choice.
# SERVERNAME tgstation
@@ -286,7 +294,7 @@ ANNOUNCE_ADMIN_LOGOUT
## Map rotation
## You should edit maps.txt to match your configuration when you enable this.
-#MAPROTATION
+MAPROTATION
## Map voting
## Allows players to vote for their preffered map
@@ -300,8 +308,11 @@ ALLOW_MAP_VOTING 1
#MAPROTATIONCHANCEDELTA 0.75
## AUTOADMIN
+## The default admin rank
+AUTOADMIN_RANK Game Master
+
## Uncomment to automatically give that admin rank to all players
-#AUTOADMIN Game Admin
+#AUTOADMIN
## GENERATE_MINIMAPS
## Generating minimaps(For crew monitor) is slow and bogs down testing, so its disabled by default and must be enabled by uncommenting this config if you are running a production server.
diff --git a/config/game_options.txt b/config/game_options.txt
index b609f8b582..77e33fa873 100644
--- a/config/game_options.txt
+++ b/config/game_options.txt
@@ -85,7 +85,6 @@ PROBABILITY REVOLUTION 2
PROBABILITY CULT 2
PROBABILITY CHANGELING 2
PROBABILITY WIZARD 4
-PROBABILITY MALFUNCTION 1
PROBABILITY BLOB 2
PROBABILITY RAGINMAGES 2
PROBABILITY MONKEY 0
@@ -115,7 +114,6 @@ CONTINUOUS CULT
CONTINUOUS CLOCKWORK_CULT
CONTINUOUS CHANGELING
CONTINUOUS WIZARD
-CONTINUOUS MALFUNCTION
CONTINUOUS BLOB
CONTINUOUS ABDUCTION
#CONTINUOUS RAGINMAGES
@@ -141,7 +139,6 @@ MIDROUND_ANTAG CULT
MIDROUND_ANTAG CLOCKWORK_CULT
MIDROUND_ANTAG CHANGELING
MIDROUND_ANTAG WIZARD
-MIDROUND_ANTAG MALFUNCTION
MIDROUND_ANTAG BLOB
MIDROUND_ANTAG ABDUCTION
#MIDROUND_ANTAG RAGINMAGES
@@ -486,7 +483,7 @@ LAVALAND_BUDGET 60
Space_Budget 16
## Time in ds from when a player latejoins till the arrival shuttle docks at the station
-## Must be at least 30 to not break parallax I recommended at least 55 to be visually/aurally appropriate
+## Must be at least 30. At least 55 recommended to be visually/aurally appropriate
ARRIVALS_SHUTTLE_DOCK_WINDOW 55
## Uncomment to require the arrivals shuttle to be in flight (if it can fly) before late join players can join
diff --git a/html/changelogs/AutoChangeLog-pr-2922.yml b/html/changelogs/AutoChangeLog-pr-2922.yml
new file mode 100644
index 0000000000..f46c3136a6
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-2922.yml
@@ -0,0 +1,6 @@
+author: "Daniel0Mclovin"
+delete-after: True
+changes:
+ - rscadd: "Podpeople to roundstart"
+ - tweak: "Modified podpeople heatmod from 1.25 to 1.5"
+ - tweak: "plant-b-gone now does roughly 7 damage per tick on podpeople"
diff --git a/html/changelogs/AutoChangeLog-pr-2938.yml b/html/changelogs/AutoChangeLog-pr-2938.yml
new file mode 100644
index 0000000000..36a1129534
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-2938.yml
@@ -0,0 +1,4 @@
+author: "Arianya"
+delete-after: True
+changes:
+ - balance: "Lesser ash drakes no longer drop ash drake hide when butchered."
diff --git a/html/changelogs/AutoChangeLog-pr-2965.yml b/html/changelogs/AutoChangeLog-pr-2965.yml
new file mode 100644
index 0000000000..98ec6c9b83
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-2965.yml
@@ -0,0 +1,4 @@
+author: "CitadelStationBot"
+delete-after: True
+changes:
+ - tweak: "Wizard cannot cast spoken or whispered spells while mute"
diff --git a/html/changelogs/AutoChangeLog-pr-2972.yml b/html/changelogs/AutoChangeLog-pr-2972.yml
new file mode 100644
index 0000000000..9f1e5aa596
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-2972.yml
@@ -0,0 +1,5 @@
+author: "Xhuis"
+delete-after: True
+changes:
+ - rscadd: "Ian has recently communed with unspeakable horrors and may now be warped by their power if Nar-Sie passes near them."
+ - rscadd: "In order to fight back against their ancient foe Ian, Poly has struck a bargain with Ratvar and will be transformed into a machine by their presence."
diff --git a/html/changelogs/AutoChangeLog-pr-2985.yml b/html/changelogs/AutoChangeLog-pr-2985.yml
new file mode 100644
index 0000000000..1a5d0fb559
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-2985.yml
@@ -0,0 +1,4 @@
+author: "CitadelStationBot"
+delete-after: True
+changes:
+ - rscadd: "The syndicate have recently begun sending agents to extract vital research information from Nanotrasen."
diff --git a/html/changelogs/AutoChangeLog-pr-3031.yml b/html/changelogs/AutoChangeLog-pr-3031.yml
new file mode 100644
index 0000000000..1ea08d2f95
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3031.yml
@@ -0,0 +1,4 @@
+author: "Antur"
+delete-after: True
+changes:
+ - bugfix: "Liches will no longer lose their spells when reviving."
diff --git a/html/changelogs/AutoChangeLog-pr-3032.yml b/html/changelogs/AutoChangeLog-pr-3032.yml
new file mode 100644
index 0000000000..e4e69ea61f
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3032.yml
@@ -0,0 +1,4 @@
+author: "Naksu"
+delete-after: True
+changes:
+ - bugfix: "Removed some of the free lag"
diff --git a/html/changelogs/AutoChangeLog-pr-3033.yml b/html/changelogs/AutoChangeLog-pr-3033.yml
new file mode 100644
index 0000000000..bbd8db4286
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3033.yml
@@ -0,0 +1,4 @@
+author: "More Robust Than You"
+delete-after: True
+changes:
+ - bugfix: "Fixes cogscarab sprites not updating"
diff --git a/html/changelogs/AutoChangeLog-pr-3041.yml b/html/changelogs/AutoChangeLog-pr-3041.yml
new file mode 100644
index 0000000000..872bbc4b99
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3041.yml
@@ -0,0 +1,5 @@
+author: "Robustin"
+delete-after: True
+changes:
+ - rscadd: "Blood cultists can now create a unique bastard sword at their forge"
+ - rscdel: "Blood cultists can no longer obtain a hardsuit from the forge"
diff --git a/html/changelogs/AutoChangeLog-pr-3042.yml b/html/changelogs/AutoChangeLog-pr-3042.yml
new file mode 100644
index 0000000000..af3369c4f2
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3042.yml
@@ -0,0 +1,4 @@
+author: "CitadelStationBot"
+delete-after: True
+changes:
+ - rscadd: "You can now see construction/deconstruction hints when examining airlocks."
diff --git a/html/changelogs/AutoChangeLog-pr-3043.yml b/html/changelogs/AutoChangeLog-pr-3043.yml
new file mode 100644
index 0000000000..cf90a7db23
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3043.yml
@@ -0,0 +1,4 @@
+author: "Qbopper"
+delete-after: True
+changes:
+ - tweak: "Moved a locker blocking an airlock in Toxins maintenance."
diff --git a/html/changelogs/AutoChangeLog-pr-3053.yml b/html/changelogs/AutoChangeLog-pr-3053.yml
new file mode 100644
index 0000000000..ca2c48581f
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3053.yml
@@ -0,0 +1,4 @@
+author: "Naksu"
+delete-after: True
+changes:
+ - bugfix: "Updates to station name are now reflected on Cargo's stock exchange computers."
diff --git a/html/changelogs/AutoChangeLog-pr-3056.yml b/html/changelogs/AutoChangeLog-pr-3056.yml
new file mode 100644
index 0000000000..7963eca536
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3056.yml
@@ -0,0 +1,4 @@
+author: "MrDoomBringer"
+delete-after: True
+changes:
+ - rscadd: "Nanotrasen, as part of their new Employee Retention program, has encouraged more station point-makery by adding the \"Cargo Tech of the Shift\"! The award is located in a lockbox in the Quartermaster's locker."
diff --git a/html/changelogs/AutoChangeLog-pr-3059.yml b/html/changelogs/AutoChangeLog-pr-3059.yml
new file mode 100644
index 0000000000..44c983f0cb
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3059.yml
@@ -0,0 +1,5 @@
+author: "CitadelStationBot"
+delete-after: True
+changes:
+ - bugfix: "The rarely utilized secret satchel item persistence system has been fixed and made more lenient."
+ - rscadd: "In case you forgot how it works: if you find or buy secret satchels, put an item in them, and then bury them under tiles on the station you or someone else can find them again in a future round with the item still there! Free satchels can often be found hiding around the station, so get to burying!"
diff --git a/html/changelogs/AutoChangeLog-pr-3063.yml b/html/changelogs/AutoChangeLog-pr-3063.yml
new file mode 100644
index 0000000000..a8c291e06f
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3063.yml
@@ -0,0 +1,5 @@
+author: "XDTM"
+delete-after: True
+changes:
+ - bugfix: "Fixed a bug where Viral Aggressive Metabolism caused viruses to be cured instantly."
+ - bugfix: "Fixed a bug where viruses' symptoms would all instantly activate on infection."
diff --git a/html/changelogs/AutoChangeLog-pr-3071.yml b/html/changelogs/AutoChangeLog-pr-3071.yml
new file mode 100644
index 0000000000..924aea5179
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3071.yml
@@ -0,0 +1,4 @@
+author: "Joan"
+delete-after: True
+changes:
+ - bugfix: "Fixes Vanguard never stunning for more than 2 seconds."
diff --git a/html/changelogs/AutoChangeLog-pr-3085.yml b/html/changelogs/AutoChangeLog-pr-3085.yml
new file mode 100644
index 0000000000..90001fc8b9
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3085.yml
@@ -0,0 +1,4 @@
+author: "Toriate"
+delete-after: True
+changes:
+ - balance: "10mm Soporific bullets now have a threshold of 60 stamina damage, up from 40, and deal 25 with each shot, down from 50"
diff --git a/html/changelogs/AutoChangeLog-pr-3086.yml b/html/changelogs/AutoChangeLog-pr-3086.yml
new file mode 100644
index 0000000000..90798d5475
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3086.yml
@@ -0,0 +1,4 @@
+author: "Toriate"
+delete-after: True
+changes:
+ - spellcheck: "uplink description for soporific magazines now correctly says at least three shots are needed, rather than two"
diff --git a/html/changelogs/AutoChangeLog-pr-3088.yml b/html/changelogs/AutoChangeLog-pr-3088.yml
new file mode 100644
index 0000000000..1f32d861a6
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3088.yml
@@ -0,0 +1,5 @@
+author: "CitadelStationBot"
+delete-after: True
+changes:
+ - rscadd: "Wormhole event wormholes now actually teleport you."
+ - bugfix: "portals now actually teleport on click."
diff --git a/html/changelogs/AutoChangeLog-pr-3089.yml b/html/changelogs/AutoChangeLog-pr-3089.yml
new file mode 100644
index 0000000000..0ee37ab23d
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3089.yml
@@ -0,0 +1,4 @@
+author: "Thefastfoodguy"
+delete-after: True
+changes:
+ - bugfix: "Antimatter shielding that can't find a control unit won't delete itself anymore"
diff --git a/html/changelogs/AutoChangeLog-pr-3092.yml b/html/changelogs/AutoChangeLog-pr-3092.yml
new file mode 100644
index 0000000000..efb4de6d35
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3092.yml
@@ -0,0 +1,4 @@
+author: "Thefastfoodguy"
+delete-after: True
+changes:
+ - bugfix: "Silicons can no longer take brain damage"
diff --git a/html/changelogs/AutoChangeLog-pr-3093.yml b/html/changelogs/AutoChangeLog-pr-3093.yml
new file mode 100644
index 0000000000..bc2a009a41
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3093.yml
@@ -0,0 +1,6 @@
+author: "Shock Collars"
+delete-after: True
+changes:
+ - rscadd: "Added Shock Collars to hacked autolathes."
+ - imageadd: "On character sprites, credit to Toriate"
+ - imageadd: "Object sprite, credit to Toriate"
diff --git a/html/changelogs/AutoChangeLog-pr-3096.yml b/html/changelogs/AutoChangeLog-pr-3096.yml
new file mode 100644
index 0000000000..4031580453
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3096.yml
@@ -0,0 +1,4 @@
+author: "Kor"
+delete-after: True
+changes:
+ - bugfix: "You can now tell when someone is in soft crit by examining them."
diff --git a/html/changelogs/AutoChangeLog-pr-3102.yml b/html/changelogs/AutoChangeLog-pr-3102.yml
new file mode 100644
index 0000000000..bc737b6a13
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3102.yml
@@ -0,0 +1,4 @@
+author: "Naksu"
+delete-after: True
+changes:
+ - bugfix: "Bees now come with reduced amounts of free lag"
diff --git a/html/changelogs/AutoChangeLog-pr-3104.yml b/html/changelogs/AutoChangeLog-pr-3104.yml
new file mode 100644
index 0000000000..e6f9d22374
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3104.yml
@@ -0,0 +1,4 @@
+author: "More Robust Than You"
+delete-after: True
+changes:
+ - balance: "Blobs now take damage from particle accelerators"
diff --git a/html/changelogs/AutoChangeLog-pr-3105.yml b/html/changelogs/AutoChangeLog-pr-3105.yml
new file mode 100644
index 0000000000..b48644c148
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3105.yml
@@ -0,0 +1,4 @@
+author: "CitadelStationBot"
+delete-after: True
+changes:
+ - balance: "The detectives gun has been restored from a system change that nerfed knockdown in general. We need to have a serious discussion about anti revolver hate in this community."
diff --git a/html/changelogs/AutoChangeLog-pr-3108.yml b/html/changelogs/AutoChangeLog-pr-3108.yml
new file mode 100644
index 0000000000..f1e03db19a
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3108.yml
@@ -0,0 +1,4 @@
+author: "XDTM"
+delete-after: True
+changes:
+ - rscadd: "The CMO now has an advanced health analyzer in his closet! It can give more precise readings on the non-standard damage types."
diff --git a/html/changelogs/AutoChangeLog-pr-3110.yml b/html/changelogs/AutoChangeLog-pr-3110.yml
new file mode 100644
index 0000000000..7d06447f99
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3110.yml
@@ -0,0 +1,4 @@
+author: "Kor"
+delete-after: True
+changes:
+ - rscadd: "Nightmares now have mutant hearts and brains, with their own special properties when consumed or implanted in mobs. Experiment!"
diff --git a/html/changelogs/AutoChangeLog-pr-3114.yml b/html/changelogs/AutoChangeLog-pr-3114.yml
new file mode 100644
index 0000000000..abe6380887
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3114.yml
@@ -0,0 +1,4 @@
+author: "Daniel0Mclovin"
+delete-after: True
+changes:
+ - tweak: "Modify health regeneration from 0.05 to 0.75"
diff --git a/html/changelogs/AutoChangeLog-pr-3115.yml b/html/changelogs/AutoChangeLog-pr-3115.yml
new file mode 100644
index 0000000000..c3a194f971
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3115.yml
@@ -0,0 +1,4 @@
+author: "Naksu"
+delete-after: True
+changes:
+ - bugfix: "Gutlunches will now once again look for gibs to eat."
diff --git a/html/changelogs/AutoChangeLog-pr-3127.yml b/html/changelogs/AutoChangeLog-pr-3127.yml
new file mode 100644
index 0000000000..050e9cb4d7
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3127.yml
@@ -0,0 +1,4 @@
+author: "Raeschen"
+delete-after: True
+changes:
+ - rscadd: "FTL Milky Way added to music"
diff --git a/html/changelogs/AutoChangeLog-pr-3133.yml b/html/changelogs/AutoChangeLog-pr-3133.yml
new file mode 100644
index 0000000000..ac49ae1821
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3133.yml
@@ -0,0 +1,4 @@
+author: "CitadelStationBot"
+delete-after: True
+changes:
+ - spellcheck: "Beds, chairs, closets, grilles, lattices, catwalks, tables, racks, floors, plating and bookcases now show hints about constructing/deconstructing them."
diff --git a/html/changelogs/AutoChangeLog-pr-3134.yml b/html/changelogs/AutoChangeLog-pr-3134.yml
new file mode 100644
index 0000000000..5b8bcf21b6
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-3134.yml
@@ -0,0 +1,4 @@
+author: "ShizCalev"
+delete-after: True
+changes:
+ - bugfix: "You now have to unbuckle a player PRIOR to shaking them up off a bed or resin nest."
diff --git a/icons/mob/accessories.dmi b/icons/mob/accessories.dmi
index 3e73083e3e..8e3e48230f 100644
Binary files a/icons/mob/accessories.dmi and b/icons/mob/accessories.dmi differ
diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi
index 038514d22a..b860bd8426 100644
Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ
diff --git a/icons/mob/inhands/64x64_lefthand.dmi b/icons/mob/inhands/64x64_lefthand.dmi
index a9a952733a..1b450ab3e0 100644
Binary files a/icons/mob/inhands/64x64_lefthand.dmi and b/icons/mob/inhands/64x64_lefthand.dmi differ
diff --git a/icons/mob/inhands/64x64_righthand.dmi b/icons/mob/inhands/64x64_righthand.dmi
index bff96a991b..bbeddf9152 100644
Binary files a/icons/mob/inhands/64x64_righthand.dmi and b/icons/mob/inhands/64x64_righthand.dmi differ
diff --git a/icons/mob/neck.dmi b/icons/mob/neck.dmi
index fb43ae85ec..17f9d3ade4 100644
Binary files a/icons/mob/neck.dmi and b/icons/mob/neck.dmi differ
diff --git a/icons/mob/pets.dmi b/icons/mob/pets.dmi
index e852426e62..647781e2b1 100644
Binary files a/icons/mob/pets.dmi and b/icons/mob/pets.dmi differ
diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi
index 13141a4d4e..9ec6c06c9f 100644
Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ
diff --git a/icons/obj/abductor.dmi b/icons/obj/abductor.dmi
index 21ab5cf9f5..64a877c2a1 100644
Binary files a/icons/obj/abductor.dmi and b/icons/obj/abductor.dmi differ
diff --git a/icons/obj/clothing/accessories.dmi b/icons/obj/clothing/accessories.dmi
index c0756a9f73..4c3c0fe5ce 100644
Binary files a/icons/obj/clothing/accessories.dmi and b/icons/obj/clothing/accessories.dmi differ
diff --git a/icons/obj/clothing/neck.dmi b/icons/obj/clothing/neck.dmi
index 40c4aa03bc..c41db68326 100644
Binary files a/icons/obj/clothing/neck.dmi and b/icons/obj/clothing/neck.dmi differ
diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi
index 53930d778c..9d9801f3a2 100644
Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ
diff --git a/icons/obj/custom.dmi b/icons/obj/custom.dmi
index 3b812e445a..c8b96b8469 100644
Binary files a/icons/obj/custom.dmi and b/icons/obj/custom.dmi differ
diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi
index 79f0a207d4..71ce7d6df5 100644
Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ
diff --git a/icons/obj/items_and_weapons.dmi b/icons/obj/items_and_weapons.dmi
index 94c0c03835..b5ac65c2a8 100644
Binary files a/icons/obj/items_and_weapons.dmi and b/icons/obj/items_and_weapons.dmi differ
diff --git a/icons/obj/smooth_structures/catwalk_clockwork.dmi b/icons/obj/smooth_structures/catwalk_clockwork.dmi
index 483fceee9a..ecef1df389 100644
Binary files a/icons/obj/smooth_structures/catwalk_clockwork.dmi and b/icons/obj/smooth_structures/catwalk_clockwork.dmi differ
diff --git a/icons/obj/smooth_structures/catwalk_clockwork_large.dmi b/icons/obj/smooth_structures/catwalk_clockwork_large.dmi
new file mode 100644
index 0000000000..675ebd91f6
Binary files /dev/null and b/icons/obj/smooth_structures/catwalk_clockwork_large.dmi differ
diff --git a/icons/turf/areas.dmi b/icons/turf/areas.dmi
index ae61dc2852..cb5499487d 100644
Binary files a/icons/turf/areas.dmi and b/icons/turf/areas.dmi differ
diff --git a/interface/interface.dm b/interface/interface.dm
index 9ee5309585..a67cc5d290 100644
--- a/interface/interface.dm
+++ b/interface/interface.dm
@@ -3,12 +3,13 @@
set name = "wiki"
set desc = "Type what you want to know about. This will open the wiki in your web browser. Type nothing to go to the main page."
set hidden = 1
- if(config.wikiurl)
+ var/wikiurl = CONFIG_GET(string/wikiurl)
+ if(wikiurl)
if(query)
- var/output = config.wikiurl + "/index.php?title=Special%3ASearch&profile=default&search=" + query
+ var/output = wikiurl + "/index.php?title=Special%3ASearch&profile=default&search=" + query
src << link(output)
else if (query != null)
- src << link(config.wikiurl)
+ src << link(wikiurl)
else
to_chat(src, "The wiki URL is not set in the server configuration. ")
return
@@ -17,10 +18,11 @@
set name = "forum"
set desc = "Visit the forum."
set hidden = 1
- if(config.forumurl)
+ var/forumurl = CONFIG_GET(string/forumurl)
+ if(forumurl)
if(alert("This will open the forum in your browser. Are you sure?",,"Yes","No")=="No")
return
- src << link(config.forumurl)
+ src << link(forumurl)
else
to_chat(src, "The forum URL is not set in the server configuration. ")
return
@@ -29,10 +31,11 @@
set name = "rules"
set desc = "Show Server Rules."
set hidden = 1
- if(config.rulesurl)
+ var/rulesurl = CONFIG_GET(string/rulesurl)
+ if(rulesurl)
if(alert("This will open the rules in your browser. Are you sure?",,"Yes","No")=="No")
return
- src << link(config.rulesurl)
+ src << link(rulesurl)
else
to_chat(src, "The rules URL is not set in the server configuration. ")
return
@@ -41,10 +44,11 @@
set name = "github"
set desc = "Visit Github"
set hidden = 1
- if(config.githuburl)
+ var/githuburl = CONFIG_GET(string/githuburl)
+ if(githuburl)
if(alert("This will open the Github repository in your browser. Are you sure?",,"Yes","No")=="No")
return
- src << link(config.githuburl)
+ src << link(githuburl)
else
to_chat(src, "The Github URL is not set in the server configuration. ")
return
@@ -53,14 +57,17 @@
set name = "report-issue"
set desc = "Report an issue"
set hidden = 1
- if(config.githuburl)
+ var/githuburl = CONFIG_GET(string/githuburl)
+ if(githuburl)
var/message = "This will open the Github issue reporter in your browser. Are you sure?"
if(GLOB.revdata.testmerge.len)
message += " The following experimental changes are active and are probably the cause of any new or sudden issues you may experience. If possible, please try to find a specific thread for your issue instead of posting to the general issue tracker: "
message += GLOB.revdata.GetTestMergeInfo(FALSE)
if(tgalert(src, message, "Report Issue","Yes","No")=="No")
return
- src << link("[config.githuburl]/issues/new")
+ var/static/issue_template = file2text(".github/ISSUE_TEMPLATE.md")
+ var/servername = CONFIG_GET(string/servername)
+ src << link("[githuburl]/issues/new[GLOB.round_id ? "?body=[url_encode("Issue reported from Round ID: [GLOB.round_id][servername ? " ([servername])" : ""]\n\n[issue_template]")]" : ""]")
else
to_chat(src, "The Github URL is not set in the server configuration. ")
return
diff --git a/sound/music/milkyway.ogg b/sound/music/milkyway.ogg
new file mode 100644
index 0000000000..59d9ba63f4
Binary files /dev/null and b/sound/music/milkyway.ogg differ
diff --git a/sound/weapons/fwoosh.wav b/sound/weapons/fwoosh.wav
new file mode 100644
index 0000000000..1723c4e9b8
Binary files /dev/null and b/sound/weapons/fwoosh.wav differ
diff --git a/sound/weapons/parry.ogg b/sound/weapons/parry.ogg
new file mode 100644
index 0000000000..1f86716337
Binary files /dev/null and b/sound/weapons/parry.ogg differ
diff --git a/strings/names/nightmare.txt b/strings/names/nightmare.txt
new file mode 100644
index 0000000000..b8798b734d
--- /dev/null
+++ b/strings/names/nightmare.txt
@@ -0,0 +1,10 @@
+U'ruan
+Y`shej
+Nex
+Hel-uae
+Noaey'gief
+Mii`mahza
+Amerziox
+Gyrg-mylin
+Kanet'pruunance
+Vigistaezian
\ No newline at end of file
diff --git a/strings/round_start_sounds.txt b/strings/round_start_sounds.txt
index 01323a6120..177f612ee1 100644
--- a/strings/round_start_sounds.txt
+++ b/strings/round_start_sounds.txt
@@ -20,3 +20,4 @@ sound/music/oceanman.ogg
sound/music/indeep.ogg
sound/music/goodbyemoonmen.ogg
sound/music/flytothemoon_otomatone.ogg
+sound/music/milkyway.ogg
\ No newline at end of file
diff --git a/tgstation.dme b/tgstation.dme
index c72669901f..1d878fc78b 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -28,11 +28,12 @@
#include "code\__DEFINES\atmospherics.dm"
#include "code\__DEFINES\atom_hud.dm"
#include "code\__DEFINES\callbacks.dm"
-#include "code\__DEFINES\citadel_defines.dm"
#include "code\__DEFINES\cinematics.dm"
+#include "code\__DEFINES\citadel_defines.dm"
#include "code\__DEFINES\clockcult.dm"
#include "code\__DEFINES\combat.dm"
#include "code\__DEFINES\components.dm"
+#include "code\__DEFINES\configuration.dm"
#include "code\__DEFINES\construction.dm"
#include "code\__DEFINES\contracts.dm"
#include "code\__DEFINES\cult.dm"
@@ -112,7 +113,6 @@
#include "code\_globalvars\genetics.dm"
#include "code\_globalvars\logging.dm"
#include "code\_globalvars\misc.dm"
-#include "code\_globalvars\sensitive.dm"
#include "code\_globalvars\lists\flavor_misc.dm"
#include "code\_globalvars\lists\maintenance_loot.dm"
#include "code\_globalvars\lists\mapping.dm"
@@ -189,7 +189,6 @@
#include "code\citadel\organs\womb.dm"
#include "code\citadel\toys\dildos.dm"
#include "code\controllers\admin.dm"
-#include "code\controllers\configuration.dm"
#include "code\controllers\configuration_citadel.dm"
#include "code\controllers\controller.dm"
#include "code\controllers\failsafe.dm"
@@ -197,6 +196,12 @@
#include "code\controllers\hooks.dm"
#include "code\controllers\master.dm"
#include "code\controllers\subsystem.dm"
+#include "code\controllers\configuration\config_entry.dm"
+#include "code\controllers\configuration\configuration.dm"
+#include "code\controllers\configuration\entries\comms.dm"
+#include "code\controllers\configuration\entries\config.dm"
+#include "code\controllers\configuration\entries\dbconfig.dm"
+#include "code\controllers\configuration\entries\game_options.dm"
#include "code\controllers\subsystem\acid.dm"
#include "code\controllers\subsystem\air.dm"
#include "code\controllers\subsystem\assets.dm"
@@ -1033,6 +1038,7 @@
#include "code\game\turfs\simulated\floor.dm"
#include "code\game\turfs\simulated\lava.dm"
#include "code\game\turfs\simulated\minerals.dm"
+#include "code\game\turfs\simulated\reebe_void.dm"
#include "code\game\turfs\simulated\river.dm"
#include "code\game\turfs\simulated\walls.dm"
#include "code\game\turfs\simulated\water.dm"
@@ -1057,6 +1063,7 @@
#include "code\modules\admin\admin_verbs.dm"
#include "code\modules\admin\adminmenu.dm"
#include "code\modules\admin\banjob.dm"
+#include "code\modules\admin\chat_commands.dm"
#include "code\modules\admin\create_mob.dm"
#include "code\modules\admin\create_object.dm"
#include "code\modules\admin\create_poll.dm"
@@ -2133,7 +2140,8 @@
#include "code\modules\ruins\spaceruin_code\TheDerelict.dm"
#include "code\modules\security_levels\keycard_authentication.dm"
#include "code\modules\security_levels\security_levels.dm"
-#include "code\modules\server_tools\server_tools.dm"
+#include "code\modules\server_tools\st_commands.dm"
+#include "code\modules\server_tools\st_interface.dm"
#include "code\modules\shuttle\arrivals.dm"
#include "code\modules\shuttle\assault_pod.dm"
#include "code\modules\shuttle\computer.dm"
@@ -2283,9 +2291,9 @@
#include "code\modules\VR\vr_sleeper.dm"
#include "code\modules\zombie\items.dm"
#include "code\modules\zombie\organs.dm"
-#include "modular_citadel\cit_screenshake.dm"
#include "interface\interface.dm"
#include "interface\menu.dm"
#include "interface\stylesheet.dm"
#include "interface\skin.dmf"
+#include "modular_citadel\cit_screenshake.dm"
// END_INCLUDE
diff --git a/tools/WebhookProcessor/github_webhook_processor.php b/tools/WebhookProcessor/github_webhook_processor.php
index a8b32c7a92..ede37e4428 100644
--- a/tools/WebhookProcessor/github_webhook_processor.php
+++ b/tools/WebhookProcessor/github_webhook_processor.php
@@ -209,7 +209,7 @@ function tag_pr($payload, $opened) {
$tags[] = 'Merge Conflict';
$treetags = array('_maps' => 'Map Edit', 'tools' => 'Tools', 'SQL' => 'SQL');
- $addonlytags = array('icons' => 'Sprites', 'sounds' => 'Sound', 'config' => 'Config Update');
+ $addonlytags = array('icons' => 'Sprites', 'sounds' => 'Sound', 'config' => 'Config Update', 'code/controllers/configuration/entries' => 'Config Update');
foreach($treetags as $tree => $tag)
if(has_tree_been_edited($payload, $tree))
$tags[] = $tag;