diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000..2df370e6ea --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,66 @@ +# This list auto requests reviews from the specified org members +# when a PR that modifies the file in question is opened +# This list is alphabetized by User -> Filename KEEP IT THAT WAY + +# ChangelingRain + +/code/__DEFINES/clockcult.dm @ChangelingRain +/code/datums/antagonists/datum_clockcult.dm @ChangelingRain +/code/game/gamemodes/blob/* @ChangelingRain +/code/game/gamemodes/clock_cult/* @ChangelingRain +/code/game/gamemodes/miniantags/revenant* @ChangelingRain +/code/game/objects/effects/temporary_visuals/* @ChangelingRain +/code/modules/reagents/chemistry/reagents/blob_reagents.dm @ChangelingRain + +# Cyberboss + +/code/__DATASTRUCTURES/globals.dm @Cyberboss +/code/__DEFINES/components.dm @Cyberboss +/code/__DEFINES/server_tools.config.dm @Cyberboss +/code/__DEFINES/server_tools.dm @Cyberboss +/code/controllers/subsystem/atoms.dm @Cyberboss +/code/controllers/subsystem/mapping.dm @Cyberboss +/code/controllers/globals.dm @Cyberboss +/code/datums/helper_datums/getrev.dm @Cyberboss +/code/datums/components/* @Cyberboss +/code/datums/map_config.dm @Cyberboss +/code/datums/forced_movement.dm @Cyberboss +/code/datums/holocall.dm @Cyberboss +/code/modules/admin/verbs/adminhelp.dm @Cyberboss +/code/modules/admin/verbs/adminpm.dm @Cyberboss +/code/modules/server_tools/* @Cyberboss +/code/modules/mapping/* @Cyberboss + +# duncathan + +/code/__DEFINES/atmospherics.dm @duncathan +/code/controllers/subsystem/air.dm @duncathan +/code/modules/atmospherics/* @duncathan + +# Jordie0608 + +/SQL/* @Jordie0608 +/code/controllers/subsystem/dbcore.dm @Jordie0608 +/tools/SQLAlertEmail/* @Jordie0608 + +# MrStonedOne + +/code/__DEFINES/MC.dm @MrStonedOne +/code/__DEFINES/tick.dm @MrStonedOne +/code/controllers/admin.dm @MrStonedOne +/code/controllers/master.dm @MrStonedOne +/code/controllers/failsafe.dm @MrStonedOne +/code/controllers/subsystem.dm @MrStonedOne +/code/controllers/subsystem/air.dm @MrStonedOne +/code/controllers/subsystem/timer.dm @MrStonedOne + +# ninjanomnom + +/code/controllers/subsystem/shuttle.dm @ninjanomnom +/code/modules/shuttle/* @ninjanomnom + +# ShizCalev + +/_maps/* @ShizCalev +/icons/* @ShizCalev +/sound/* @ShizCalev diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 3b1daafc62..10f60767bb 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,3 +1,9 @@ -[Directions]: # (Include the Round ID from the Status panel or retrieve it from https://atlantaned.space/newSS13tools/round.php ! If you believe the issue to be caused by a testmerge [OOC tab -> Show Server Revision], report it in the pull request's comment section instead. Explain your issue in detail, including the steps to reproduce it.) +[Directions]: # (If you discovered this issue from playing tgstation hosted servers + + +INCLUDE THE ROUND ID + + +from the Status panel or retrieve it from https://atlantaned.space/statbus/round.php ! If you believe the issue to be caused by a test merge [OOC tab -> Show Server Revision], report it in the pull request's comment section instead. Explain your issue in detail, including the steps to reproduce it.) [For Admins]: # (Oddities induced by var-edits and other admin tools are not necessarily bugs. Verify that your issues occur under regular circumstances before reporting them.) diff --git a/.gitignore b/.gitignore index 9744499e37..3b85a6ec30 100644 --- a/.gitignore +++ b/.gitignore @@ -192,6 +192,7 @@ Temporary Items #Visual studio stuff *.vscode/* +tools/MapAtmosFixer/MapAtmosFixer/obj/x86/Debug/MapAtmosFixer.csproj.CoreCompileInputs.cache #GitHub Atom .atom-build.json diff --git a/.travis.yml b/.travis.yml index 35fec579bf..07b63ab3aa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,8 @@ language: generic sudo: false +branches: + except: + - ___TGS3TempBranch env: global: - BYOND_MAJOR="511" diff --git a/OLD_LICENSE-GPLv3.txt b/GPLv3.txt similarity index 100% rename from OLD_LICENSE-GPLv3.txt rename to GPLv3.txt diff --git a/README.md b/README.md index 618f805f94..b286239314 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,10 @@ ##Citadel Station 13
Based and maintained from /tg/station.
+[![Build Status](https://travis-ci.org/tgstation/tgstation.png)](https://travis-ci.org/tgstation/tgstation) [![Krihelimeter](https://www.krihelinator.xyz/badge/tgstation/tgstation)](https://www.krihelinator.xyz) +[![Percentage of issues still open](https://isitmaintained.com/badge/open/tgstation/tgstation.svg)](https://isitmaintained.com/project/tgstation/tgstation "Percentage of issues still open") [![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/tgstation/tgstation.svg)](https://isitmaintained.com/project/tgstation/tgstation "Average time to resolve an issue") ![Coverage](https://img.shields.io/badge/coverage---2%25-red.svg) +[![forthebadge](https://forthebadge.com/images/badges/built-with-resentment.svg)](https://forthebadge.com) [![forthebadge](https://forthebadge.com/images/badges/contains-technical-debt.svg)](https://forthebadge.com) [![forinfinityandbyond](https://user-images.githubusercontent.com/5211576/29499758-4efff304-85e6-11e7-8267-62919c3688a9.gif)](https://www.reddit.com/r/SS13/comments/5oplxp/what_is_the_main_problem_with_byond_as_an_engine/dclbu1a) + [![Build Status](https://api.travis-ci.org/Citadel-Station-13/Citadel-Station-13.png)](https://travis-ci.org/Citadel-Station-13/Citadel-Station-13) [![Krihelimeter](http://www.krihelinator.xyz/badge/Citadel-Station-13/Citadel-Station-13)](http://www.krihelinator.xyz) [![Percentage of issues still open](http://isitmaintained.com/badge/open/Citadel-Station-13/Citadel-Station-13.svg)](http://isitmaintained.com/project/Citadel-Station-13/Citadel-Station-13 "Percentage of issues still open") [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/Citadel-Station-13/Citadel-Station-13.svg)](http://isitmaintained.com/project/Citadel-Station-13/Citadel-Station-13 "Average time to resolve an issue") @@ -32,12 +36,12 @@ 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 +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 +compile. This'll take a little while, and if everything's done right you'll get a message like this: ``` @@ -49,17 +53,17 @@ 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 +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, +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 +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 +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 @@ -71,8 +75,8 @@ 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 +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). @@ -106,7 +110,7 @@ https://github.com/tgstation/tgstation-server 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. +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, BoxStation 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. @@ -140,7 +144,7 @@ All code after [commit 333c566b88108de218d882840e61928a9b759d8f on 2014/31/12 at 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 and OLD_LICENSE-GPLv3.txt for more details. +See LICENSE and 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 diff --git a/SQL/feedback_conversion_2017-11-12.py b/SQL/feedback_conversion_2017-11-12.py index b8577460b3..8a60e10b7e 100644 --- a/SQL/feedback_conversion_2017-11-12.py +++ b/SQL/feedback_conversion_2017-11-12.py @@ -5,6 +5,10 @@ #It can be downloaded from command line with pip: #pip install mysqlclient # +#tgstation no longer supports MySQL which has been superseded by MariaDB, a drop-in replacement. +#Before running this script you will need to migrate to MariaDB. +#Migrating is very easy to do, for details on how see: https://mariadb.com/kb/en/library/upgrading-from-mysql-to-mariadb/ +# #You will also have to create a new feedback table for inserting converted data to per the schema: #CREATE TABLE `feedback_new` ( # `id` int(11) unsigned NOT NULL AUTO_INCREMENT, @@ -476,11 +480,25 @@ parser.add_argument("newtable", help="Name of the new table to insert to, can't args = parser.parse_args() db=MySQLdb.connect(host=args.address, user=args.username, passwd=args.password, db=args.database) cursor=db.cursor() +cursor.execute("SELECT @@GLOBAL.version_comment") +db_version = "".join([x for x in cursor.fetchone()]) +database_mysql = False +if 'MySQL' in db_version: + database_mysql = True +elif 'mariadb' not in db_version: + choice = input("Unable to determine database version installed, are you using MySQL? Type Yes or No and press enter...").lower() + if choice == "yes": + database_mysql = True +if database_mysql == True: + print("WARNING Database detected to be MySQL: tgstation no longer supports MySQL which has been superseded by MariaDB, a drop-in replacement.\nBefore running this script you will need to migrate to MariaDB.\nMigrating is very easy to do, for details on how see: https://mariadb.com/kb/en/library/upgrading-from-mysql-to-mariadb/") + input("Press enter to quit...") + quit() current_table = args.curtable new_table = args.newtable -cursor.execute("SELECT max(id) FROM {0}".format(current_table)) +cursor.execute("SELECT max(id), max(round_id) FROM {0}".format(current_table)) query_id = cursor.fetchone() max_id = query_id[0] +max_round_id = query_id[1] start_time = datetime.now() print("Beginning conversion at {0}".format(start_time.strftime("%Y-%m-%d %H:%M:%S"))) try: @@ -493,7 +511,7 @@ try: if not query_row: continue else: - if current_round != query_row[2]: + if current_round != query_row[2] or current_round == max_round_id: multirows_completed.clear() if query_values: query_values = query_values[:-1] @@ -524,8 +542,11 @@ try: print("Conversion completed at {0}".format(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))) print("Script duration: {0}".format(end_time - start_time)) except Exception as e: + cursor.execute("SELECT round_id FROM {0} WHERE id = {1}".format(current_table, current_id-1)) + query_round_id = cursor.fetchone() end_time = datetime.now() print("Error encountered on row ID {0} at {1}".format(current_id, datetime.now().strftime("%Y-%m-%d %H:%M:%S"))) + print("Note SQL insertion errors will be due to data from round ID {0}".format(query_round_id[0])) #since data is inserted when the round id changes on a new row print("Script duration: {0}".format(end_time - start_time)) cursor.execute("TRUNCATE {0} ".format(new_table)) raise e diff --git a/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm b/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm index aeaf849b73..2e066413f7 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm @@ -270,7 +270,7 @@ /turf/open/floor/wood, /area/ruin/powered/beach) "be" = ( -/obj/vehicle/scooter/skateboard{ +/obj/vehicle/ridden/scooter/skateboard{ dir = 4 }, /turf/open/floor/plating/beach/sand, diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_animal_hospital.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_animal_hospital.dmm index af51457db9..cc961656f6 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_animal_hospital.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_animal_hospital.dmm @@ -528,7 +528,7 @@ /turf/open/floor/plasteel/white, /area/ruin/powered/animal_hospital) "bL" = ( -/obj/vehicle/scooter/skateboard{ +/obj/vehicle/ridden/scooter/skateboard{ dir = 4 }, /turf/open/floor/grass{ diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_biodome_winter.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_biodome_winter.dmm index edc6dcffac..593cbdb665 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_biodome_winter.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_biodome_winter.dmm @@ -170,7 +170,7 @@ }, /area/ruin/powered/snow_biodome) "aJ" = ( -/obj/vehicle/atv, +/obj/vehicle/ridden/atv, /turf/open/floor/plating/asteroid/snow{ initial_gas_mix = "o2=22;n2=82;TEMP=180" }, diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_hermit.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_hermit.dmm index 6fd614754d..8d52fc9180 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_hermit.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_hermit.dmm @@ -140,7 +140,7 @@ icon_state = "blood1"; dir = 1 }, -/obj/machinery/door/airlock/survival_pod, +/obj/machinery/door/airlock/survival_pod/glass, /obj/structure/fans/tiny, /turf/open/floor/pod/dark, /area/ruin/powered) diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_survivalpod.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_survivalpod.dmm index d50777c92f..713385d0e4 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_survivalpod.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_survivalpod.dmm @@ -109,7 +109,7 @@ icon_state = "blood1"; dir = 1 }, -/obj/machinery/door/airlock/survival_pod, +/obj/machinery/door/airlock/survival_pod/glass, /turf/open/floor/pod/dark, /area/ruin/powered) "u" = ( diff --git a/_maps/RandomRuins/SpaceRuins/DJstation.dmm b/_maps/RandomRuins/SpaceRuins/DJstation.dmm index 6a859fccdc..f60b3bd4a5 100644 --- a/_maps/RandomRuins/SpaceRuins/DJstation.dmm +++ b/_maps/RandomRuins/SpaceRuins/DJstation.dmm @@ -172,7 +172,7 @@ /turf/open/floor/plasteel/bar, /area/ruin/space/djstation) "aG" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Kitchen" }, /turf/open/floor/plasteel/cafeteria, @@ -193,7 +193,7 @@ /turf/open/floor/plasteel/cafeteria, /area/ruin/space/djstation) "aJ" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Rest Room" }, /turf/open/floor/plasteel/cafeteria, diff --git a/_maps/RandomRuins/SpaceRuins/TheDerelict.dmm b/_maps/RandomRuins/SpaceRuins/TheDerelict.dmm index e5de6294f9..ced41e0d81 100644 --- a/_maps/RandomRuins/SpaceRuins/TheDerelict.dmm +++ b/_maps/RandomRuins/SpaceRuins/TheDerelict.dmm @@ -1030,7 +1030,7 @@ /turf/open/floor/plasteel, /area/ruin/space/derelict/bridge/access) "dp" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /obj/structure/cable{ icon_state = "4-8" }, @@ -2759,7 +2759,7 @@ /turf/open/floor/plasteel/airless/white, /area/ruin/space/derelict/medical) "ja" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Med-Sci"; req_access_txt = "9" }, diff --git a/_maps/RandomRuins/SpaceRuins/abandonedzoo.dmm b/_maps/RandomRuins/SpaceRuins/abandonedzoo.dmm index 05911c954b..da3f343fd7 100644 --- a/_maps/RandomRuins/SpaceRuins/abandonedzoo.dmm +++ b/_maps/RandomRuins/SpaceRuins/abandonedzoo.dmm @@ -622,7 +622,7 @@ /area/ruin/space/has_grav/abandonedzoo) "bA" = ( /obj/structure/table/reinforced, -/obj/machinery/juicer, +/obj/machinery/reagentgrinder, /turf/open/floor/plasteel{ icon_state = "dark" }, diff --git a/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm b/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm index 6c20d55fdf..1da57dc70a 100644 --- a/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm +++ b/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm @@ -950,7 +950,7 @@ /turf/open/floor/plasteel, /area/ruin/space/has_grav/derelictoutpost/cargobay) "cy" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /obj/machinery/door/poddoor{ id = "bigderelictcheckpoint"; name = "checkpoint security doors" @@ -990,7 +990,7 @@ desc = "A thick gelatinous surface covers the floor. Someone get the golashes."; name = "gelatinous floor" }, -/mob/living/simple_animal/hostile/creature{ +/mob/living/simple_animal/hostile/netherworld{ desc = "Awh its so sm-OH GOD WHAT THE FUCK."; health = 25; maxHealth = 25; @@ -1010,7 +1010,7 @@ icon_state = "trails_1"; dir = 10 }, -/mob/living/simple_animal/hostile/creature{ +/mob/living/simple_animal/hostile/netherworld{ desc = "Awh its so sm-OH GOD WHAT THE FUCK."; health = 25; maxHealth = 25; @@ -1378,7 +1378,7 @@ desc = "A thick gelatinous surface covers the floor. Someone get the golashes."; name = "gelatinous floor" }, -/mob/living/simple_animal/hostile/creature{ +/mob/living/simple_animal/hostile/netherworld{ name = "Miss Tiggles" }, /turf/open/floor/plasteel, @@ -1888,7 +1888,7 @@ desc = "A thick gelatinous surface covers the floor. Someone get the golashes."; name = "gelatinous floor" }, -/mob/living/simple_animal/hostile/creature{ +/mob/living/simple_animal/hostile/netherworld{ desc = "Awh its so sm-OH GOD WHAT THE FUCK."; health = 25; maxHealth = 25; diff --git a/_maps/RandomRuins/SpaceRuins/crashedship.dmm b/_maps/RandomRuins/SpaceRuins/crashedship.dmm index 0ed7578efd..2a1fc96a1b 100644 --- a/_maps/RandomRuins/SpaceRuins/crashedship.dmm +++ b/_maps/RandomRuins/SpaceRuins/crashedship.dmm @@ -68,7 +68,7 @@ /turf/open/floor/engine, /area/awaymission/BMPship/Aft) "ap" = ( -/turf/closed/wall/mineral/titanium/overspace, +/turf/closed/wall/mineral/titanium/nodiagonal, /area/awaymission/BMPship/Midship) "aq" = ( /turf/closed/wall/mineral/titanium, @@ -2309,6 +2309,27 @@ }, /turf/open/floor/carpet, /area/awaymission/BMPship/Fore) +"hy" = ( +/turf/closed/wall/mineral/titanium/nodiagonal, +/area/awaymission/BMPship/Fore) +"hz" = ( +/turf/closed/wall/mineral/titanium/nodiagonal, +/area/awaymission/BMPship/Fore) +"hA" = ( +/turf/closed/wall/mineral/titanium/nodiagonal, +/area/awaymission/BMPship/Fore) +"hB" = ( +/turf/closed/wall/mineral/titanium/nodiagonal, +/area/awaymission/BMPship/Fore) +"hC" = ( +/turf/closed/wall/mineral/titanium/nodiagonal, +/area/awaymission/BMPship/Fore) +"hD" = ( +/turf/closed/wall/mineral/titanium/nodiagonal, +/area/awaymission/BMPship/Fore) +"hE" = ( +/turf/closed/wall/mineral/titanium/nodiagonal, +/area/awaymission/BMPship/Fore) (1,1,1) = {" aa @@ -2684,8 +2705,8 @@ aa aa aa aa -cF -aT +aI +hD bV hx ee @@ -2735,7 +2756,7 @@ aa aa aa aI -aH +hC bV bV dH @@ -2785,7 +2806,7 @@ aa aa aa aI -aT +hB bV bV bV @@ -2834,8 +2855,8 @@ aH aQ bl bt -aT -aT +hy +hA bV bV cY @@ -2849,7 +2870,7 @@ bI fv fJ aH -aH +hE aQ gF gR @@ -2987,7 +3008,7 @@ aH aT aT aT -aT +hz bW co cH diff --git a/_maps/RandomRuins/SpaceRuins/deepstorage.dmm b/_maps/RandomRuins/SpaceRuins/deepstorage.dmm index ab39bb14df..9ff1aad4c6 100644 --- a/_maps/RandomRuins/SpaceRuins/deepstorage.dmm +++ b/_maps/RandomRuins/SpaceRuins/deepstorage.dmm @@ -879,7 +879,7 @@ }, /area/ruin/space/has_grav/deepstorage) "bQ" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Hydroponics" }, /turf/open/floor/plasteel/hydrofloor{ @@ -962,7 +962,7 @@ icon_state = "1-2" }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Kitchen" }, /turf/open/floor/plasteel/cafeteria{ @@ -1488,8 +1488,6 @@ /area/ruin/space/has_grav/deepstorage/armory) "db" = ( /obj/structure/table, -/obj/item/device/mass_spectrometer/adv, -/obj/item/device/mass_spectrometer/adv, /obj/item/device/healthanalyzer, /obj/item/device/healthanalyzer, /obj/item/stack/medical/gauze, @@ -1931,7 +1929,7 @@ icon_state = "4-8" }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Dorms" }, /turf/open/floor/plasteel/floorgrime{ diff --git a/_maps/RandomRuins/SpaceRuins/derelict6.dmm b/_maps/RandomRuins/SpaceRuins/derelict6.dmm index 1dfd9b90cd..6b714814af 100644 --- a/_maps/RandomRuins/SpaceRuins/derelict6.dmm +++ b/_maps/RandomRuins/SpaceRuins/derelict6.dmm @@ -197,11 +197,11 @@ /turf/open/floor/plating/airless, /area/ruin/unpowered) "aF" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/plasteel/airless/bar, /area/ruin/unpowered) "aG" = ( -/obj/structure/door_assembly/door_assembly_glass{ +/obj/structure/door_assembly/door_assembly_public{ name = "broken airlock" }, /turf/open/floor/plasteel/airless/bar, diff --git a/_maps/RandomRuins/SpaceRuins/gondolaasteroid.dmm b/_maps/RandomRuins/SpaceRuins/gondolaasteroid.dmm index b7a5910b1e..5b0387bb39 100644 --- a/_maps/RandomRuins/SpaceRuins/gondolaasteroid.dmm +++ b/_maps/RandomRuins/SpaceRuins/gondolaasteroid.dmm @@ -81,7 +81,9 @@ /turf/open/floor/plating/asteroid/airless, /area/ruin/space/has_grav) "u" = ( -/obj/machinery/door/airlock/survival_pod/vertical, +/obj/machinery/door/airlock/survival_pod/glass{ + dir = 4 + }, /turf/open/floor/plating/asteroid/airless, /area/ruin/space/has_grav) diff --git a/_maps/RandomRuins/SpaceRuins/intactemptyship.dmm b/_maps/RandomRuins/SpaceRuins/intactemptyship.dmm index d46e880401..636eb1f614 100644 --- a/_maps/RandomRuins/SpaceRuins/intactemptyship.dmm +++ b/_maps/RandomRuins/SpaceRuins/intactemptyship.dmm @@ -106,7 +106,7 @@ /turf/open/floor/mineral/titanium/purple, /area/ruin/space/has_grav/powered/authorship) "u" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/mineral/titanium/purple, /area/ruin/space/has_grav/powered/authorship) "v" = ( diff --git a/_maps/RandomRuins/SpaceRuins/oldstation.dmm b/_maps/RandomRuins/SpaceRuins/oldstation.dmm index d0c8abc18e..93154afd94 100644 --- a/_maps/RandomRuins/SpaceRuins/oldstation.dmm +++ b/_maps/RandomRuins/SpaceRuins/oldstation.dmm @@ -1468,7 +1468,7 @@ "eo" = ( /obj/machinery/door/firedoor, /obj/effect/decal/cleanable/dirt, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Hydroponics" }, /turf/open/floor/plasteel/floorgrime, @@ -1502,7 +1502,7 @@ /area/ruin/space/has_grav/ancientstation/hydroponics) "es" = ( /obj/effect/decal/cleanable/dirt, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Hydroponics" }, /obj/machinery/door/firedoor/closed, @@ -1561,7 +1561,7 @@ /turf/open/floor/plasteel/white, /area/ruin/space/has_grav/ancientstation/rnd) "eB" = ( -/obj/machinery/r_n_d/destructive_analyzer, +/obj/machinery/rnd/destructive_analyzer, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/white, /area/ruin/space/has_grav/ancientstation/rnd) @@ -1891,12 +1891,12 @@ /turf/open/floor/plasteel/floorgrime, /area/ruin/space/has_grav/ancientstation/deltacorridor) "fu" = ( -/obj/machinery/r_n_d/protolathe, +/obj/machinery/rnd/protolathe, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/white, /area/ruin/space/has_grav/ancientstation/rnd) "fv" = ( -/obj/machinery/r_n_d/circuit_imprinter, +/obj/machinery/rnd/circuit_imprinter, /obj/effect/decal/cleanable/dirt, /obj/item/reagent_containers/dropper, /turf/open/floor/plasteel/white, @@ -3143,14 +3143,14 @@ "ii" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Dining Area" }, /turf/open/floor/plasteel/cafeteria, /area/ruin/space/has_grav/ancientstation/kitchen) "ij" = ( /obj/effect/decal/cleanable/dirt, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Dining Area" }, /obj/machinery/door/firedoor/closed, @@ -3881,7 +3881,7 @@ /area/ruin/space/has_grav/ancientstation) "jU" = ( /obj/effect/decal/cleanable/dirt, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Cryogenics Room" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, diff --git a/_maps/RandomRuins/SpaceRuins/onehalf.dmm b/_maps/RandomRuins/SpaceRuins/onehalf.dmm index f9e61815c4..7b2e8f6751 100644 --- a/_maps/RandomRuins/SpaceRuins/onehalf.dmm +++ b/_maps/RandomRuins/SpaceRuins/onehalf.dmm @@ -511,7 +511,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /obj/structure/cable{ icon_state = "4-8" }, @@ -631,7 +631,7 @@ /turf/open/floor/plasteel/airless, /area/ruin/space/has_grav/onehalf/hallway) "bC" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /obj/structure/disposalpipe/segment{ dir = 4 }, diff --git a/_maps/RandomRuins/SpaceRuins/shuttlerelic.dmm b/_maps/RandomRuins/SpaceRuins/shuttlerelic.dmm index 3cc67daaec..ecadecdd04 100644 --- a/_maps/RandomRuins/SpaceRuins/shuttlerelic.dmm +++ b/_maps/RandomRuins/SpaceRuins/shuttlerelic.dmm @@ -11,7 +11,7 @@ /turf/closed/indestructible/oldshuttle, /area/ruin/powered) "d" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/oldshuttle, /area/ruin/powered) "e" = ( diff --git a/_maps/RandomRuins/SpaceRuins/spacehotel.dmm b/_maps/RandomRuins/SpaceRuins/spacehotel.dmm index f4f1711b41..2eab719806 100644 --- a/_maps/RandomRuins/SpaceRuins/spacehotel.dmm +++ b/_maps/RandomRuins/SpaceRuins/spacehotel.dmm @@ -1242,12 +1242,12 @@ name = "Hotel Guest Room 1" }) "df" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /obj/machinery/door/firedoor, /turf/open/floor/carpet, /area/ruin/space/has_grav/hotel) "dg" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/carpet, @@ -2228,7 +2228,7 @@ /turf/open/floor/carpet, /area/ruin/space/has_grav/hotel) "fW" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -2283,7 +2283,7 @@ /turf/open/floor/carpet, /area/ruin/space/has_grav/hotel) "gf" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /obj/machinery/door/firedoor, /turf/open/floor/carpet, /area/ruin/space/has_grav/hotel/dock) @@ -3023,7 +3023,7 @@ /turf/open/floor/carpet, /area/ruin/space/has_grav/hotel) "il" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /obj/structure/cable{ icon_state = "4-8" }, @@ -3475,7 +3475,7 @@ /turf/closed/wall, /area/ruin/space/has_grav/hotel/pool) "ju" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -3491,7 +3491,7 @@ /turf/open/floor/plating, /area/ruin/space/has_grav/hotel/pool) "jw" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -3893,7 +3893,7 @@ /turf/open/floor/plating, /area/ruin/space/has_grav/hotel/power) "kJ" = ( -/obj/machinery/door/airlock/glass_external, +/obj/machinery/door/airlock/external/glass, /obj/structure/cable/yellow{ icon_state = "1-2" }, diff --git a/_maps/RandomRuins/SpaceRuins/turretedoutpost.dmm b/_maps/RandomRuins/SpaceRuins/turretedoutpost.dmm index 4146ec1df6..f55f7cf0e6 100644 --- a/_maps/RandomRuins/SpaceRuins/turretedoutpost.dmm +++ b/_maps/RandomRuins/SpaceRuins/turretedoutpost.dmm @@ -108,7 +108,7 @@ }, /area/ruin/space/has_grav/turretedoutpost) "aw" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/plasteel, /area/ruin/space/has_grav/turretedoutpost) "ax" = ( @@ -172,7 +172,7 @@ /turf/open/floor/plasteel/vault, /area/ruin/space/has_grav/turretedoutpost) "aI" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/plasteel/dark, /area/ruin/space/has_grav/turretedoutpost) "aJ" = ( diff --git a/_maps/RandomRuins/SpaceRuins/whiteshipruin_box.dmm b/_maps/RandomRuins/SpaceRuins/whiteshipruin_box.dmm index 34ddbb265e..71196719a4 100644 --- a/_maps/RandomRuins/SpaceRuins/whiteshipruin_box.dmm +++ b/_maps/RandomRuins/SpaceRuins/whiteshipruin_box.dmm @@ -69,7 +69,7 @@ /turf/open/floor/mineral/titanium, /area/ruin/space/has_grav/whiteship/box) "ao" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/plating, /area/ruin/space/has_grav/whiteship/box) "ap" = ( @@ -181,7 +181,7 @@ /turf/open/floor/mineral/titanium, /area/ruin/space/has_grav/whiteship/box) "aH" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/mineral/titanium, /area/ruin/space/has_grav/whiteship/box) "aI" = ( diff --git a/_maps/RandomZLevels/Academy.dmm b/_maps/RandomZLevels/Academy.dmm index a724ded444..535cb1377c 100644 --- a/_maps/RandomZLevels/Academy.dmm +++ b/_maps/RandomZLevels/Academy.dmm @@ -1273,12 +1273,12 @@ /turf/open/floor/plating, /area/awaymission/academy) "eA" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /obj/machinery/door/airlock/external, /turf/open/floor/plating, /area/awaymission/academy/classrooms) "eB" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/plating, /area/awaymission/academy/classrooms) "eC" = ( @@ -3738,7 +3738,7 @@ /turf/open/floor/vault, /area/awaymission/academy/academyengine) "ml" = ( -/mob/living/simple_animal/hostile/creature, +/mob/living/simple_animal/hostile/netherworld, /turf/open/floor/vault, /area/awaymission/academy/academyengine) "mm" = ( diff --git a/_maps/RandomZLevels/Cabin.dmm b/_maps/RandomZLevels/Cabin.dmm index dd40e3c024..4cd42ea994 100644 --- a/_maps/RandomZLevels/Cabin.dmm +++ b/_maps/RandomZLevels/Cabin.dmm @@ -825,7 +825,7 @@ /turf/open/floor/plating/snowed/temperatre, /area/awaymission/cabin) "cT" = ( -/obj/vehicle/atv, +/obj/vehicle/ridden/atv, /turf/open/floor/plating/snowed/temperatre, /area/awaymission/cabin) "cU" = ( diff --git a/_maps/RandomZLevels/beach.dmm b/_maps/RandomZLevels/beach.dmm index db2cce8fb7..fb9c5e73c2 100644 --- a/_maps/RandomZLevels/beach.dmm +++ b/_maps/RandomZLevels/beach.dmm @@ -163,7 +163,7 @@ death = 0; desc = "Looks secure."; flavour_text = "You are a bartender for the beach!"; - icon = 'icons/obj/cryogenic2.dmi'; + icon = 'icons/obj/machines/sleeper.dmi'; icon_state = "sleeper"; mob_name = "Jerry Thomas"; name = "bartenders cryosleeper"; diff --git a/_maps/RandomZLevels/centcomAway.dmm b/_maps/RandomZLevels/centcomAway.dmm index a80fa51a30..0c7fd7f713 100644 --- a/_maps/RandomZLevels/centcomAway.dmm +++ b/_maps/RandomZLevels/centcomAway.dmm @@ -1600,7 +1600,7 @@ /turf/open/floor/carpet, /area/awaymission/centcomAway/courtroom) "fU" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Med-Sci"; req_access_txt = "9" }, diff --git a/_maps/RandomZLevels/moonoutpost19.dmm b/_maps/RandomZLevels/moonoutpost19.dmm index 9277b95a79..f6815d7b1d 100644 --- a/_maps/RandomZLevels/moonoutpost19.dmm +++ b/_maps/RandomZLevels/moonoutpost19.dmm @@ -786,7 +786,7 @@ }, /area/awaymission/moonoutpost19/syndicate) "bO" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Break Room" }, /turf/open/floor/plasteel{ @@ -1127,7 +1127,7 @@ }, /area/awaymission/moonoutpost19/syndicate) "cr" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ density = 0; emagged = 1; icon_state = "open"; @@ -5322,7 +5322,7 @@ /area/awaymission/moonoutpost19/arrivals) "km" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Diner" }, /turf/open/floor/plasteel{ diff --git a/_maps/RandomZLevels/research.dmm b/_maps/RandomZLevels/research.dmm index 39ffb0c913..5693bd14ff 100644 --- a/_maps/RandomZLevels/research.dmm +++ b/_maps/RandomZLevels/research.dmm @@ -4347,7 +4347,7 @@ /turf/open/floor/mineral/plasma, /area/space/nearstation) "nc" = ( -/mob/living/simple_animal/hostile/creature, +/mob/living/simple_animal/hostile/netherworld, /turf/open/floor/mineral/plasma, /area/space/nearstation) "nd" = ( diff --git a/_maps/RandomZLevels/snowdin.dmm b/_maps/RandomZLevels/snowdin.dmm index e9f6caa5fb..7fb4fa76f1 100644 --- a/_maps/RandomZLevels/snowdin.dmm +++ b/_maps/RandomZLevels/snowdin.dmm @@ -15,7 +15,7 @@ /area/awaymission/snowdin/post) "ae" = ( /obj/effect/decal/cleanable/oil, -/obj/vehicle/atv, +/obj/vehicle/ridden/atv, /turf/open/floor/plating{ baseturf = /turf/open/floor/plating/asteroid/snow }, @@ -41,7 +41,7 @@ }, /area/awaymission/snowdin/post) "ai" = ( -/obj/vehicle/atv, +/obj/vehicle/ridden/atv, /turf/open/floor/plating{ baseturf = /turf/open/floor/plating/asteroid/snow }, @@ -720,7 +720,7 @@ /turf/open/floor/plating/asteroid/snow, /area/awaymission/snowdin) "bN" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/plasteel/cafeteria{ baseturf = /turf/open/floor/plating/asteroid/snow }, @@ -1493,7 +1493,7 @@ }, /area/awaymission/snowdin/post) "dV" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ req_access_txt = "150" }, /turf/open/floor/plasteel{ @@ -1842,7 +1842,7 @@ /turf/open/floor/plating/asteroid/snow, /area/awaymission/snowdin) "eZ" = ( -/obj/vehicle/atv, +/obj/vehicle/ridden/atv, /turf/open/floor/plating/asteroid/snow{ temperature = 140 }, @@ -2453,7 +2453,7 @@ }, /area/awaymission/snowdin/post) "gJ" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /obj/structure/barricade/wooden, /turf/open/floor/plasteel{ baseturf = /turf/open/floor/plating/asteroid/snow; @@ -2490,7 +2490,7 @@ /turf/open/floor/plating/snowed/colder, /area/awaymission/snowdin/dungeon1) "gP" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/plasteel/cafeteria{ baseturf = /turf/open/floor/plating/asteroid/snow; temperature = 180 @@ -2549,7 +2549,7 @@ }, /area/awaymission/snowdin/post) "gX" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/plasteel{ baseturf = /turf/open/floor/plating/asteroid/snow; wet = 0 @@ -4299,7 +4299,7 @@ }, /area/awaymission/snowdin/sekret) "lE" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/plasteel/cafeteria{ baseturf = /turf/open/floor/plating/asteroid/snow }, diff --git a/_maps/RandomZLevels/undergroundoutpost45.dmm b/_maps/RandomZLevels/undergroundoutpost45.dmm index a3eb4d1afd..a00c460da8 100644 --- a/_maps/RandomZLevels/undergroundoutpost45.dmm +++ b/_maps/RandomZLevels/undergroundoutpost45.dmm @@ -1307,7 +1307,7 @@ /area/awaymission/undergroundoutpost45/central) "da" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Central Access" }, /turf/open/floor/plasteel{ @@ -1784,7 +1784,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Hydroponics"; req_access_txt = "201" }, @@ -1918,7 +1918,7 @@ /area/awaymission/undergroundoutpost45/central) "eo" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Hydroponics"; req_access_txt = "201" }, @@ -2796,7 +2796,7 @@ "ge" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Central Access" }, /turf/open/floor/plasteel{ @@ -3430,7 +3430,7 @@ }, /area/awaymission/undergroundoutpost45/gateway) "hB" = ( -/obj/machinery/r_n_d/destructive_analyzer, +/obj/machinery/rnd/destructive_analyzer, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -3448,7 +3448,7 @@ }, /area/awaymission/undergroundoutpost45/research) "hD" = ( -/obj/machinery/r_n_d/protolathe, +/obj/machinery/rnd/protolathe, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -3545,7 +3545,7 @@ /area/awaymission/undergroundoutpost45/crew_quarters) "hP" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Kitchen"; req_access_txt = "201" }, @@ -3709,7 +3709,6 @@ "ig" = ( /obj/machinery/computer/rdconsole/core{ dir = 4; - id = 3; req_access = null }, /turf/open/floor/plasteel{ @@ -3722,7 +3721,7 @@ }, /area/awaymission/undergroundoutpost45/research) "ii" = ( -/obj/machinery/r_n_d/circuit_imprinter, +/obj/machinery/rnd/circuit_imprinter, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -4349,7 +4348,7 @@ "jt" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Central Access" }, /turf/open/floor/plasteel{ @@ -4358,7 +4357,7 @@ /area/awaymission/undergroundoutpost45/crew_quarters) "ju" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Central Access" }, /turf/open/floor/plasteel{ @@ -4843,7 +4842,7 @@ /area/awaymission/undergroundoutpost45/crew_quarters) "kp" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Diner" }, /turf/open/floor/plasteel{ @@ -5796,7 +5795,7 @@ "lV" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Diner" }, /turf/open/floor/plasteel{ @@ -5810,7 +5809,7 @@ }, /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Diner" }, /turf/open/floor/plasteel{ @@ -6348,7 +6347,7 @@ "mV" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Dormitories" }, /obj/effect/decal/cleanable/dirt, @@ -6359,7 +6358,7 @@ "mW" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Dormitories" }, /turf/open/floor/plasteel{ @@ -6721,7 +6720,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Dormitories" }, /turf/open/floor/plasteel{ @@ -7209,7 +7208,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Dormitories" }, /turf/open/floor/plasteel{ @@ -8602,9 +8601,7 @@ dir = 4; pixel_x = -22 }, -/obj/machinery/r_n_d/server/core{ - id_with_download_string = "3"; - id_with_upload_string = "3"; +/obj/machinery/rnd/server{ req_access = null }, /turf/open/floor/circuit{ diff --git a/_maps/RandomZLevels/wildwest.dmm b/_maps/RandomZLevels/wildwest.dmm index 426e68e015..e24d9dcb85 100644 --- a/_maps/RandomZLevels/wildwest.dmm +++ b/_maps/RandomZLevels/wildwest.dmm @@ -726,7 +726,7 @@ /turf/open/floor/wood, /area/awaymission/wildwest/gov) "cG" = ( -/mob/living/simple_animal/hostile/creature, +/mob/living/simple_animal/hostile/netherworld, /turf/open/floor/plasteel/stage_bleft, /area/awaymission/wildwest/gov) "cH" = ( @@ -761,7 +761,7 @@ /turf/open/floor/wood, /area/awaymission/wildwest/gov) "cN" = ( -/mob/living/simple_animal/hostile/creature, +/mob/living/simple_animal/hostile/netherworld, /turf/open/floor/wood, /area/awaymission/wildwest/gov) "cO" = ( @@ -771,7 +771,7 @@ /turf/open/floor/wood, /area/awaymission/wildwest/gov) "cP" = ( -/mob/living/simple_animal/hostile/creature, +/mob/living/simple_animal/hostile/netherworld, /turf/open/floor/carpet, /area/awaymission/wildwest/gov) "cQ" = ( @@ -1024,7 +1024,7 @@ /area/awaymission/wildwest/gov) "dB" = ( /obj/structure/toilet, -/mob/living/simple_animal/hostile/creature, +/mob/living/simple_animal/hostile/netherworld, /turf/open/floor/plasteel/white, /area/awaymission/wildwest/gov) "dC" = ( @@ -1941,7 +1941,7 @@ /turf/open/floor/wood, /area/awaymission/wildwest/mines) "gn" = ( -/mob/living/simple_animal/hostile/creature, +/mob/living/simple_animal/hostile/netherworld, /turf/open/floor/grass, /area/awaymission/wildwest/gov) "go" = ( diff --git a/_maps/boxstation.dm b/_maps/boxstation.dm index 1b4e642e4e..527299fd4c 100644 --- a/_maps/boxstation.dm +++ b/_maps/boxstation.dm @@ -1 +1 @@ -#define FORCE_MAP "_maps/boxstation.json" \ No newline at end of file +#define FORCE_MAP "_maps/boxstation.json" diff --git a/_maps/deltastation.dm b/_maps/deltastation.dm index 7dfabf7a48..f64b528da6 100644 --- a/_maps/deltastation.dm +++ b/_maps/deltastation.dm @@ -1 +1 @@ -#define FORCE_MAP "_maps/deltastation.json" \ No newline at end of file +#define FORCE_MAP "_maps/deltastation.json" diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index 39fa8179cd..335393adac 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -777,7 +777,7 @@ id = "permacell3"; name = "cell blast door" }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ id_tag = "permabolt3"; name = "Cell 3" }, @@ -788,7 +788,7 @@ id = "permacell2"; name = "cell blast door" }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ id_tag = "permabolt2"; name = "Cell 2" }, @@ -803,7 +803,7 @@ id = "permacell1"; name = "cell blast door" }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ id_tag = "permabolt1"; name = "Cell 1" }, @@ -914,7 +914,7 @@ /turf/open/floor/carpet, /area/crew_quarters/heads/hos) "acv" = ( -/obj/structure/closet/secure_closet/contraband/armory, +/obj/structure/closet/secure_closet/lethalshots, /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) @@ -1040,7 +1040,9 @@ name = "Transfer Room"; req_access_txt = "2" }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 8 + }, /area/security/execution/transfer) "acJ" = ( /obj/structure/cable{ @@ -1248,7 +1250,7 @@ /turf/open/floor/carpet, /area/crew_quarters/heads/hos) "adi" = ( -/obj/machinery/flasher/portable, +/obj/structure/closet/secure_closet/contraband/armory, /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) @@ -4961,9 +4963,13 @@ /turf/closed/wall/r_wall, /area/ai_monitored/security/armory) "alu" = ( -/obj/machinery/nuclearbomb/selfdestruct, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/nuke_storage) +/obj/structure/barricade/wooden, +/obj/structure/grille, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/maintenance/fore) "alv" = ( /obj/structure/cable{ icon_state = "1-2" @@ -5351,7 +5357,7 @@ /turf/open/floor/plating, /area/security/courtroom) "amt" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Courtroom"; req_access_txt = "42" }, @@ -5943,12 +5949,16 @@ /turf/open/floor/plasteel, /area/security/processing) "anQ" = ( +/obj/structure/sign/securearea{ + desc = "A warning sign which reads 'HIGH VOLTAGE'"; + icon_state = "shock"; + name = "HIGH VOLTAGE"; + pixel_y = 32 + }, /obj/machinery/light{ dir = 1 }, -/turf/open/floor/plasteel/red/corner{ - dir = 1 - }, +/turf/open/floor/plasteel, /area/hallway/primary/fore) "anR" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on, @@ -5975,7 +5985,7 @@ id = "seclobby"; name = "security shutters" }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Courtroom" }, /turf/open/floor/plasteel/dark, @@ -8208,7 +8218,7 @@ /area/security/vacantoffice/b) "atZ" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Holodeck Door" }, /turf/open/floor/plasteel, @@ -8409,7 +8419,7 @@ /area/crew_quarters/dorms) "auy" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Holodeck Door" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -9245,7 +9255,7 @@ /area/crew_quarters/fitness) "awz" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Fitness" }, /turf/open/floor/plasteel, @@ -9803,7 +9813,7 @@ icon_state = "4-8" }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Fitness" }, /turf/open/floor/plasteel, @@ -9862,7 +9872,7 @@ /area/crew_quarters/fitness) "axZ" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Holodeck Door" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -10675,9 +10685,9 @@ icon_state = "1-4" }, /obj/machinery/power/apc{ - areastring = "/area/security/checkpoint/auxiliary"; dir = 2; name = "Security Checkpoint APC"; + areastring = "/area/security/checkpoint/auxiliary"; pixel_x = 1; pixel_y = -24 }, @@ -11360,10 +11370,27 @@ /turf/open/floor/wood, /area/maintenance/bar/cafe) "aBT" = ( -/obj/machinery/computer/bank_machine, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/nuke_storage) +/obj/machinery/power/apc{ + areastring = "/area/crew_quarters/theatre/mime"; + dir = 2; + name = "Mime's Office APC"; + pixel_x = 1; + pixel_y = -24 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/chair/wood{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/wood{ + icon_state = "wood-broken6" + }, +/area/maintenance/bar/cafe) "aBU" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -11383,11 +11410,24 @@ /turf/open/floor/circuit, /area/ai_monitored/nuke_storage) "aBW" = ( -/obj/structure/filingcabinet, -/obj/item/folder/documents, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/nuke_storage) +/obj/machinery/power/apc{ + areastring = "/area/crew_quarters/theatre/clown"; + dir = 2; + name = "Clown's Office APC"; + pixel_x = 1; + pixel_y = -24 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/floor/wood{ + icon_state = "wood-broken6" + }, +/area/maintenance/bar/cafe) "aBX" = ( /obj/machinery/gateway{ dir = 10 @@ -12527,24 +12567,13 @@ /turf/open/floor/circuit, /area/ai_monitored/nuke_storage) "aEN" = ( -/obj/structure/closet/crate{ - name = "Gold Crate" +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/bed, +/obj/item/bedsheet/mime, +/turf/open/floor/plasteel/white/side{ + dir = 1 }, -/obj/item/stack/sheet/mineral/gold{ - pixel_x = -1; - pixel_y = 5 - }, -/obj/item/stack/sheet/mineral/gold{ - pixel_y = 2 - }, -/obj/item/stack/sheet/mineral/gold{ - pixel_x = 1; - pixel_y = -2 - }, -/obj/item/storage/belt/champion, -/obj/effect/turf_decal/bot_white/right, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/nuke_storage) +/area/crew_quarters/theatre/mime) "aEO" = ( /obj/structure/cable{ icon_state = "1-2" @@ -12552,32 +12581,10 @@ /turf/open/floor/circuit, /area/ai_monitored/nuke_storage) "aEP" = ( -/obj/item/coin/silver{ - pixel_x = 7; - pixel_y = 12 - }, -/obj/item/coin/silver{ - pixel_x = 12; - pixel_y = 7 - }, -/obj/item/coin/silver{ - pixel_x = 4; - pixel_y = 8 - }, -/obj/item/coin/silver{ - pixel_x = -6; - pixel_y = 5 - }, -/obj/item/coin/silver{ - pixel_x = 5; - pixel_y = -8 - }, -/obj/structure/closet/crate{ - name = "Silver Crate" - }, -/obj/effect/turf_decal/bot_white/left, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/nuke_storage) +/obj/structure/closet/secure_closet/freezer/cream_pie, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/redyellow, +/area/crew_quarters/theatre/clown) "aEQ" = ( /obj/structure/table, /obj/item/paper/pamphlet/gateway, @@ -13061,9 +13068,15 @@ /turf/open/floor/plasteel/vault/corner, /area/ai_monitored/nuke_storage) "aGb" = ( -/obj/effect/turf_decal/bot_white/right, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/nuke_storage) +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/camera{ + c_tag = "Mime's Office"; + dir = 8 + }, +/turf/open/floor/plasteel/white/side{ + dir = 1 + }, +/area/crew_quarters/theatre/mime) "aGc" = ( /obj/structure/cable{ icon_state = "1-8" @@ -13085,16 +13098,17 @@ /turf/open/floor/plasteel/vault/side, /area/ai_monitored/nuke_storage) "aGe" = ( -/obj/structure/safe, -/obj/item/clothing/head/bearpelt, -/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass, -/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass, -/obj/item/gun/ballistic/revolver/russian, -/obj/item/ammo_box/a357, -/obj/item/reagent_containers/food/drinks/bottle/vodka/badminka, -/obj/effect/turf_decal/bot_white/left, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/nuke_storage) +/obj/structure/mirror{ + pixel_x = -28 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/camera{ + c_tag = "Clown's Office"; + c_tag_order = 999; + dir = 4 + }, +/turf/open/floor/plasteel/redyellow, +/area/crew_quarters/theatre/clown) "aGf" = ( /obj/machinery/firealarm{ dir = 4; @@ -13533,8 +13547,7 @@ /turf/open/floor/wood, /area/library) "aHc" = ( -/obj/structure/table/wood, -/obj/item/storage/pill_bottle/dice, +/obj/machinery/vending/games, /turf/open/floor/wood, /area/library) "aHd" = ( @@ -13752,7 +13765,7 @@ /area/ai_monitored/nuke_storage) "aHH" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Dormitory" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -13787,7 +13800,7 @@ dir = 1 }, /turf/closed/wall, -/area/maintenance/starboard/fore) +/area/crew_quarters/bar) "aHN" = ( /obj/structure/table, /obj/item/stack/sheet/metal/fifty, @@ -13807,14 +13820,14 @@ /area/ai_monitored/storage/eva) "aHP" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Central Access" }, /turf/open/floor/plasteel, /area/hallway/primary/central) "aHQ" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Central Access" }, /turf/open/floor/plasteel/blue/corner{ @@ -13823,7 +13836,7 @@ /area/hallway/primary/central) "aHR" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Central Access" }, /turf/open/floor/plasteel/blue/side{ @@ -13844,7 +13857,7 @@ /area/maintenance/starboard/fore) "aHT" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Dormitory" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -13897,7 +13910,9 @@ pixel_x = -22 }, /obj/structure/table/wood, -/obj/item/device/flashlight/lamp/bananalamp, +/obj/item/device/flashlight/lamp/bananalamp{ + pixel_y = 3 + }, /turf/open/floor/plasteel/redblue, /area/crew_quarters/theatre) "aIa" = ( @@ -13945,7 +13960,7 @@ dir = 4 }, /turf/closed/wall, -/area/maintenance/starboard/fore) +/area/crew_quarters/bar) "aIf" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -13972,7 +13987,7 @@ /turf/open/floor/plasteel{ dir = 2 }, -/area/maintenance/starboard/fore) +/area/crew_quarters/bar) "aIh" = ( /obj/machinery/power/apc{ dir = 2; @@ -14360,9 +14375,7 @@ c_tag = "EVA South"; dir = 1 }, -/turf/open/floor/plasteel/dark/side{ - dir = 8 - }, +/turf/open/floor/plasteel, /area/ai_monitored/storage/eva) "aJg" = ( /obj/structure/extinguisher_cabinet{ @@ -14729,7 +14742,7 @@ icon_state = "1-2" }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Primary Tool Storage" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -14737,7 +14750,7 @@ /area/storage/primary) "aKa" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Primary Tool Storage" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -14835,7 +14848,7 @@ /area/hallway/secondary/entry) "aKm" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Garden" }, /turf/open/floor/plasteel, @@ -15829,7 +15842,7 @@ /area/hallway/secondary/entry) "aNc" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Central Access" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -16067,7 +16080,7 @@ /area/crew_quarters/kitchen) "aNN" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Hydroponics"; req_access_txt = "35" }, @@ -16137,7 +16150,7 @@ /turf/open/floor/wood, /area/library) "aNW" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Chapel Office"; req_access_txt = "22" }, @@ -16399,7 +16412,7 @@ /area/hallway/primary/port) "aOB" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Central Access" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -16781,7 +16794,7 @@ /turf/closed/wall, /area/storage/art) "aPH" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Art Storage" }, /turf/open/floor/plasteel, @@ -17281,7 +17294,7 @@ /area/storage/tools) "aRf" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Auxiliary Tool Storage"; req_access_txt = "12" }, @@ -17831,7 +17844,7 @@ /turf/open/floor/plasteel/bar, /area/crew_quarters/bar) "aSI" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Kitchen"; req_access_txt = "28" }, @@ -17888,7 +17901,7 @@ /area/crew_quarters/kitchen) "aSP" = ( /obj/machinery/smartfridge, -/turf/closed/wall, +/turf/open/floor/plating, /area/crew_quarters/kitchen) "aSQ" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ @@ -19059,7 +19072,7 @@ dir = 4 }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Library" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -19100,7 +19113,7 @@ /area/library) "aWe" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Chapel" }, /turf/open/floor/carpet, @@ -19731,7 +19744,7 @@ /area/crew_quarters/locker) "aXy" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Chapel" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -19878,7 +19891,7 @@ /area/hydroponics) "aXT" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Library" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -20371,7 +20384,7 @@ /area/library) "aZe" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Chapel" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -21222,7 +21235,7 @@ /area/crew_quarters/heads/captain) "bbx" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Diner" }, /turf/open/floor/plasteel, @@ -21248,7 +21261,7 @@ /area/hallway/primary/starboard) "bbB" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Hydroponics"; req_access_txt = "35" }, @@ -23501,7 +23514,7 @@ /obj/machinery/light{ dir = 1 }, -/obj/machinery/r_n_d/circuit_imprinter, +/obj/machinery/rnd/circuit_imprinter, /turf/open/floor/plasteel/white, /area/science/robotics/lab) "bhy" = ( @@ -23795,16 +23808,22 @@ /turf/open/floor/wood, /area/bridge/meeting_room) "big" = ( -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, -/area/engine/gravity_generator) +/obj/machinery/light_switch{ + pixel_y = 28 + }, +/turf/open/floor/circuit, +/area/ai_monitored/nuke_storage) "bih" = ( /obj/effect/turf_decal/bot_white/right, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 1 + }, /area/engine/gravity_generator) "bii" = ( /obj/effect/turf_decal/bot_white/left, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 4 + }, /area/engine/gravity_generator) "bij" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -24959,10 +24978,9 @@ /turf/open/floor/plating, /area/maintenance/central) "bkZ" = ( -/obj/machinery/gravity_generator/main/station, -/obj/effect/turf_decal/bot_white, +/obj/machinery/nuclearbomb/selfdestruct, /turf/open/floor/plasteel/dark, -/area/engine/gravity_generator) +/area/ai_monitored/nuke_storage) "bla" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -25296,17 +25314,17 @@ /turf/open/floor/plasteel/white, /area/science/research) "blI" = ( -/obj/machinery/r_n_d/destructive_analyzer, +/obj/machinery/rnd/destructive_analyzer, /obj/effect/turf_decal/stripes/line{ dir = 1 }, /turf/open/floor/plasteel, /area/science/lab) "blJ" = ( -/obj/machinery/r_n_d/protolathe, /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/machinery/rnd/protolathe/department/science, /turf/open/floor/plasteel, /area/science/lab) "blK" = ( @@ -25515,11 +25533,7 @@ /turf/open/floor/plasteel, /area/quartermaster/sorting) "bml" = ( -/obj/machinery/mineral/ore_redemption{ - input_dir = 8; - output_dir = 4 - }, -/obj/machinery/door/firedoor, +/obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plasteel/floorgrime, /area/quartermaster/office) "bmm" = ( @@ -25738,7 +25752,7 @@ /turf/open/floor/plasteel/red/side, /area/security/checkpoint/medical) "bmO" = ( -/obj/structure/closet, +/obj/structure/closet/secure_closet/security/med, /turf/open/floor/plasteel/red/side{ dir = 10 }, @@ -25948,8 +25962,8 @@ /turf/open/floor/plasteel, /area/science/lab) "bno" = ( -/obj/machinery/r_n_d/circuit_imprinter, /obj/item/reagent_containers/glass/beaker/sulphuric, +/obj/machinery/rnd/circuit_imprinter/department/science, /turf/open/floor/plasteel, /area/science/lab) "bnp" = ( @@ -26209,18 +26223,9 @@ /turf/open/floor/plasteel, /area/crew_quarters/heads/hop) "bnT" = ( -/obj/structure/sign/securearea{ - desc = "A warning sign which reads 'HIGH VOLTAGE'"; - icon_state = "shock"; - name = "HIGH VOLTAGE"; - pixel_x = -32 - }, -/obj/structure/cable{ - icon_state = "0-4" - }, -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/engine/gravity_generator) +/obj/effect/turf_decal/bot_white/right, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/nuke_storage) "bnU" = ( /obj/structure/cable{ icon_state = "1-2" @@ -26239,21 +26244,16 @@ }, /area/ai_monitored/nuke_storage) "bnW" = ( -/obj/structure/sign/securearea{ - desc = "A warning sign which reads 'RADIOACTIVE AREA'"; - icon_state = "radiation"; - name = "RADIOACTIVE AREA"; - pixel_x = 32 - }, -/obj/structure/cable{ - icon_state = "0-2" - }, -/obj/structure/cable{ - icon_state = "0-8" - }, -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/engine/gravity_generator) +/obj/structure/safe, +/obj/item/clothing/head/bearpelt, +/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass, +/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass, +/obj/item/gun/ballistic/revolver/russian, +/obj/item/ammo_box/a357, +/obj/item/reagent_containers/food/drinks/bottle/vodka/badminka, +/obj/effect/turf_decal/bot_white/left, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/nuke_storage) "bnX" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/carpet, @@ -28890,6 +28890,9 @@ }, /area/quartermaster/office) "bud" = ( +/obj/effect/turf_decal/loading_area{ + dir = 1 + }, /turf/open/floor/plasteel/brown/corner{ dir = 8 }, @@ -29731,6 +29734,9 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /obj/structure/cable{ icon_state = "1-2" }, @@ -29785,10 +29791,16 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "bwh" = ( +/obj/structure/sign/securearea{ + pixel_y = 32 + }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "bwi" = ( @@ -30889,10 +30901,10 @@ /obj/machinery/light_switch{ pixel_y = -25 }, -/obj/structure/closet, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, +/obj/structure/closet/secure_closet/security/cargo, /turf/open/floor/plasteel/red/side{ dir = 10 }, @@ -30993,6 +31005,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, +/obj/structure/closet/wardrobe/red, /turf/open/floor/plasteel/red/side, /area/security/checkpoint/supply) "byU" = ( @@ -31195,7 +31208,7 @@ /turf/open/floor/circuit/telecomms/server, /area/science/server) "bzu" = ( -/obj/machinery/r_n_d/server/robotics, +/obj/machinery/rnd/server, /turf/open/floor/circuit/telecomms/server, /area/science/server) "bzv" = ( @@ -31253,7 +31266,7 @@ /obj/machinery/airalarm{ pixel_y = 25 }, -/obj/structure/closet, +/obj/structure/closet/secure_closet/security/science, /turf/open/floor/plasteel/red/side{ dir = 9 }, @@ -31309,7 +31322,7 @@ /area/quartermaster/miningdock) "bzG" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Central Access" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -31723,6 +31736,7 @@ /obj/machinery/light{ dir = 8 }, +/obj/structure/closet/wardrobe/red, /turf/open/floor/plasteel/red/side{ dir = 8 }, @@ -31825,7 +31839,7 @@ /turf/open/floor/engine, /area/science/explab) "bAR" = ( -/obj/machinery/r_n_d/experimentor, +/obj/machinery/rnd/experimentor, /turf/open/floor/engine, /area/science/explab) "bAS" = ( @@ -32280,7 +32294,7 @@ /turf/open/floor/circuit/telecomms/server, /area/science/server) "bBT" = ( -/obj/machinery/r_n_d/server/core, +/obj/machinery/rnd/server, /turf/open/floor/circuit/telecomms/server, /area/science/server) "bBU" = ( @@ -32524,7 +32538,7 @@ "bCu" = ( /obj/structure/disposalpipe/segment, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Central Access" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -33081,7 +33095,7 @@ /obj/machinery/camera{ c_tag = "Custodial Closet" }, -/obj/vehicle/janicart, +/obj/vehicle/ridden/janicart, /turf/open/floor/plasteel, /area/janitor) "bDL" = ( @@ -34178,7 +34192,6 @@ pixel_y = -3 }, /obj/item/circuitboard/machine/destructive_analyzer, -/obj/item/circuitboard/machine/protolathe, /obj/structure/cable{ icon_state = "1-2" }, @@ -38542,6 +38555,7 @@ /obj/machinery/light{ dir = 4 }, +/obj/structure/closet/wardrobe/red, /turf/open/floor/plasteel/red/side{ dir = 4 }, @@ -41665,7 +41679,7 @@ departmentType = 5; pixel_y = 30 }, -/obj/structure/closet, +/obj/structure/closet/secure_closet/security/engine, /turf/open/floor/plasteel/red/side{ dir = 1 }, @@ -44126,7 +44140,6 @@ /area/maintenance/aft) "cdM" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/mob/living/simple_animal/mouse, /turf/open/floor/plating, /area/maintenance/aft) "cdN" = ( @@ -47211,6 +47224,7 @@ /area/engine/engineering) "clS" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/obj/machinery/rnd/protolathe/department/security, /turf/open/floor/plasteel/red/side, /area/security/main) "clT" = ( @@ -47258,7 +47272,7 @@ /turf/closed/wall/r_wall, /area/maintenance/disposal/incinerator) "cmf" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ autoclose = 0; frequency = 1449; heat_proof = 1; @@ -47733,7 +47747,7 @@ /turf/closed/wall, /area/construction) "cnC" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ autoclose = 0; frequency = 1449; heat_proof = 1; @@ -48351,6 +48365,9 @@ name = "HIGH VOLTAGE"; pixel_x = -32 }, +/obj/machinery/computer/rdconsole/production{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/engineering) "cps" = ( @@ -48560,12 +48577,12 @@ /turf/open/floor/plasteel, /area/engine/engine_smes) "cpV" = ( -/obj/structure/table, /obj/machinery/camera{ c_tag = "Engineering Storage"; dir = 4; network = list("SS13") }, +/obj/machinery/rnd/protolathe/department/engineering, /turf/open/floor/plasteel, /area/engine/engineering) "cpW" = ( @@ -48779,13 +48796,10 @@ /turf/open/floor/plating, /area/maintenance/port/aft) "cqw" = ( -/obj/structure/table, -/obj/item/stack/sheet/plasteel{ - amount = 10 - }, /obj/machinery/light{ dir = 8 }, +/obj/machinery/rnd/circuit_imprinter, /turf/open/floor/plasteel, /area/engine/engineering) "cqx" = ( @@ -48910,6 +48924,9 @@ /obj/structure/table, /obj/item/stack/sheet/metal/fifty, /obj/item/stack/sheet/metal/fifty, +/obj/item/stack/sheet/plasteel{ + amount = 10 + }, /turf/open/floor/plasteel, /area/engine/engineering) "cqO" = ( @@ -51289,7 +51306,7 @@ /turf/closed/wall/mineral/titanium, /area/shuttle/escape) "cwX" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Cockpit"; req_access_txt = "19" }, @@ -51348,7 +51365,7 @@ /turf/open/floor/mineral/plastitanium/brig, /area/shuttle/escape) "cxf" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Brig"; req_access_txt = "2" }, @@ -51592,7 +51609,7 @@ /turf/open/floor/plating, /area/maintenance/solars/starboard/fore) "cxO" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Infirmary" }, /turf/open/floor/mineral/titanium/blue, @@ -51911,7 +51928,7 @@ /turf/open/floor/plating, /area/shuttle/abandoned) "cyz" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/plating, /area/shuttle/abandoned) "cyA" = ( @@ -52138,7 +52155,7 @@ /turf/open/floor/plating, /area/shuttle/supply) "cza" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/mineral/titanium, /area/shuttle/abandoned) "czb" = ( @@ -56944,7 +56961,6 @@ desc = "A thin layer of dust coating the floor."; name = "dust" }, -/obj/item/device/mass_spectrometer, /turf/open/floor/mineral/titanium, /area/shuttle/abandoned) "Qnn" = ( @@ -57610,44 +57626,125 @@ /turf/open/floor/plasteel/showroomfloor, /area/crew_quarters/kitchen) "QoM" = ( -/obj/structure/grille, -/turf/open/space/basic, -/area/space/nearstation) +/obj/machinery/rnd/protolathe/department/service, +/turf/open/floor/plating, +/area/crew_quarters/kitchen) "QoN" = ( -/obj/structure/grille, -/turf/open/space/basic, -/area/space/nearstation) +/obj/machinery/rnd/protolathe/department/cargo, +/turf/open/floor/plasteel, +/area/quartermaster/storage) "QoO" = ( -/obj/structure/grille, -/turf/open/space/basic, -/area/space/nearstation) +/obj/machinery/mineral/ore_redemption{ + input_dir = 2; + output_dir = 1 + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel, +/area/quartermaster/miningdock) "QoP" = ( -/obj/structure/grille, -/turf/open/space/basic, -/area/space/nearstation) +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/light_switch{ + pixel_y = 28 + }, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/quartermaster/miningdock) "QoQ" = ( -/obj/structure/grille, -/turf/open/space/basic, -/area/space/nearstation) +/obj/machinery/rnd/protolathe/department/medical, +/turf/open/floor/plasteel/white, +/area/medical/sleeper) "QoR" = ( -/obj/structure/grille, -/turf/open/space/basic, -/area/space/nearstation) +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/rnd/protolathe/department/engineering, +/turf/open/floor/plasteel, +/area/engine/engineering) "QoS" = ( -/obj/structure/grille, -/turf/open/space/basic, -/area/space/nearstation) +/obj/machinery/computer/rdconsole/production, +/turf/open/floor/plasteel, +/area/engine/engineering) "QoT" = ( -/obj/structure/grille, -/turf/open/space/basic, -/area/space/nearstation) +/obj/effect/turf_decal/loading_area, +/turf/open/floor/plasteel/showroomfloor, +/area/crew_quarters/kitchen) "QoU" = ( +/obj/structure/closet/crate/freezer/surplus_limbs, +/obj/item/reagent_containers/glass/beaker/synthflesh, +/turf/open/floor/plasteel/white/side{ + dir = 8 + }, +/area/medical/sleeper) +"QoV" = ( +/obj/structure/rack, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 2; + name = "2maintenance loot spawner" + }, +/turf/open/floor/plating, +/area/maintenance/department/medical/morgue) +"QoW" = ( +/obj/machinery/droneDispenser, +/turf/open/floor/plating, +/area/maintenance/department/medical/morgue) +"QoX" = ( +/obj/structure/table, +/obj/item/stack/sheet/metal/fifty, +/obj/item/stack/sheet/glass/fifty, +/turf/open/floor/plating, +/area/maintenance/department/medical/morgue) +"QoY" = ( /obj/structure/grille, +/obj/structure/lattice, /turf/open/space/basic, /area/space/nearstation) -"QoV" = ( +"QoZ" = ( +/obj/structure/grille, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) +"Qpa" = ( +/obj/structure/grille, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) +"Qpb" = ( +/obj/structure/grille, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) +"Qpc" = ( +/obj/structure/grille, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) +"Qpd" = ( +/obj/structure/grille, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) +"Qpe" = ( +/obj/structure/grille, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) +"Qpf" = ( +/obj/structure/grille, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) +"Qpg" = ( +/obj/structure/grille, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) +"Qph" = ( /obj/structure/window/reinforced, -/obj/vehicle/secway, +/obj/vehicle/ridden/secway, /obj/item/key/security, /obj/machinery/door/window/eastleft{ name = "Secway Docking Port" @@ -57655,9 +57752,9 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel/showroomfloor, /area/security/main) -"QoW" = ( +"Qpi" = ( /obj/structure/window/reinforced, -/obj/vehicle/secway, +/obj/vehicle/ridden/secway, /obj/item/key/security, /obj/machinery/door/window/eastleft{ name = "Secway Docking Port" @@ -57665,11 +57762,31 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel/showroomfloor, /area/security/main) -"QoX" = ( +"Qpj" = ( /obj/structure/closet/l3closet/security, /turf/open/floor/plasteel/showroomfloor, /area/security/main) -"QoY" = ( +"Qpk" = ( +/obj/machinery/flasher/portable, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/security/armory) +"Qpl" = ( +/obj/machinery/flasher/portable, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/security/armory) +"Qpm" = ( +/obj/machinery/flasher/portable, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/security/armory) +"Qpn" = ( +/obj/machinery/flasher/portable, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/security/armory) +"Qpo" = ( /obj/structure/table, /obj/item/grenade/barrier{ pixel_x = 4 @@ -57683,14 +57800,14 @@ }, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"QoZ" = ( +"Qpp" = ( /obj/structure/rack, /obj/item/gun/energy/e_gun/dragnet, /obj/item/gun/energy/e_gun/dragnet, /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"Qpa" = ( +"Qpq" = ( /obj/structure/rack, /obj/item/clothing/suit/armor/bulletproof{ pixel_x = -3; @@ -57717,7 +57834,7 @@ /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"Qpb" = ( +"Qpr" = ( /obj/structure/rack, /obj/item/clothing/suit/armor/riot{ pixel_x = -3; @@ -57749,7 +57866,7 @@ /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"Qpc" = ( +"Qps" = ( /obj/structure/window/reinforced, /obj/machinery/door/window/eastleft{ name = "Cyborg Docking Port" @@ -57758,21 +57875,21 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel/showroomfloor, /area/security/main) -"Qpd" = ( +"Qpt" = ( /obj/effect/landmark/secequipment, /obj/effect/turf_decal/bot{ dir = 2 }, /turf/open/floor/plasteel/showroomfloor, /area/security/main) -"Qpe" = ( +"Qpu" = ( /obj/structure/closet/secure_closet/security/sec, /obj/effect/turf_decal/bot{ dir = 2 }, /turf/open/floor/plasteel/showroomfloor, /area/security/main) -"Qpf" = ( +"Qpv" = ( /obj/machinery/camera/motion{ c_tag = "Non-Lethal Armory Motion Sensor"; dir = 4 @@ -57782,14 +57899,14 @@ }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qpg" = ( +"Qpw" = ( /obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qph" = ( +"Qpx" = ( /obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/components/unary/vent_pump/on, /obj/effect/turf_decal/stripes/line{ @@ -57797,21 +57914,21 @@ }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qpi" = ( +"Qpy" = ( /obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qpj" = ( +"Qpz" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 }, /obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qpk" = ( +"QpA" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -57820,14 +57937,14 @@ }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qpl" = ( +"QpB" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qpm" = ( +"QpC" = ( /obj/machinery/door/poddoor/shutters{ id = "lowsecarmory"; name = "Non-Lethal Armoury Shutter" @@ -57841,32 +57958,31 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qpn" = ( +"QpD" = ( /obj/effect/landmark/secequipment, /obj/effect/turf_decal/bot{ dir = 2 }, /turf/open/floor/plasteel/showroomfloor, /area/security/main) -"Qpo" = ( +"QpE" = ( /obj/machinery/suit_storage_unit/security, /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"Qpp" = ( +"QpF" = ( /obj/machinery/suit_storage_unit/security, -/turf/open/floor/plasteel/vault{ - dir = 8 - }, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"Qpq" = ( +"QpG" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 }, /obj/structure/tank_dispenser/oxygen, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"Qpr" = ( +"QpH" = ( /obj/machinery/suit_storage_unit/security, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -57874,16 +57990,15 @@ /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"Qps" = ( +"QpI" = ( /obj/machinery/suit_storage_unit/security, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/vault{ - dir = 8 - }, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"Qpt" = ( +"QpJ" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 }, @@ -57896,14 +58011,14 @@ }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qpu" = ( +"QpK" = ( /obj/effect/turf_decal/stripes/line, /obj/structure/cable{ icon_state = "4-8" }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qpv" = ( +"QpL" = ( /obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable{ @@ -57911,7 +58026,7 @@ }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qpw" = ( +"QpM" = ( /obj/machinery/firealarm{ pixel_y = 24 }, @@ -57920,7 +58035,7 @@ }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qpx" = ( +"QpN" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -57934,7 +58049,7 @@ }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qpy" = ( +"QpO" = ( /obj/machinery/light{ dir = 1 }, @@ -57947,7 +58062,7 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qpz" = ( +"QpP" = ( /obj/effect/turf_decal/stripes/corner{ dir = 8 }, @@ -57965,7 +58080,7 @@ }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"QpA" = ( +"QpQ" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -57974,23 +58089,31 @@ }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"QpB" = ( -/obj/structure/closet/secure_closet/lethalshots, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/security/armory) -"QpC" = ( +"QpR" = ( /obj/structure/table, /obj/item/storage/box/firingpins, /obj/item/storage/box/firingpins, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"QpD" = ( +"QpS" = ( /obj/structure/table, /obj/item/storage/toolbox/drone, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"QpE" = ( +"QpT" = ( +/obj/structure/falsewall, +/obj/effect/turf_decal/delivery/white, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"QpU" = ( +/obj/effect/turf_decal/loading_area/white, +/obj/effect/turf_decal/stripes/white/corner{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/white/corner, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"QpV" = ( /obj/structure/cable{ icon_state = "4-8" }, @@ -58006,27 +58129,132 @@ }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"QpF" = ( +"QpW" = ( +/obj/effect/turf_decal/stripes/white/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/white/corner{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"QpX" = ( +/obj/effect/turf_decal/stripes/white/line{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/white/corner, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"QpY" = ( +/obj/structure/window/reinforced, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/window/reinforced{ + dir = 1; + layer = 2.9 + }, +/obj/structure/closet/secure_closet/brig{ + id = "Secure Cell"; + name = "Secure Cell Locker" + }, +/obj/effect/turf_decal/stripes/white/end{ + dir = 4 + }, +/obj/effect/turf_decal/delivery/white, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"QpZ" = ( +/turf/open/floor/plasteel, +/area/security/execution/transfer) +"Qqa" = ( +/turf/open/floor/plasteel, +/area/security/execution/transfer) +"Qqb" = ( +/turf/open/floor/plasteel, +/area/security/execution/transfer) +"Qqc" = ( +/obj/effect/turf_decal/stripes/white/line{ + dir = 5 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"Qqd" = ( +/obj/effect/turf_decal/stripes/white/line, +/obj/effect/turf_decal/stripes/white/corner{ + dir = 1 + }, +/obj/machinery/door_timer{ + id = "Secure Cell"; + name = "Secure Cell"; + pixel_y = -32 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"Qqe" = ( +/obj/machinery/door/window/brigdoor/security/cell{ + dir = 4; + id = "Secure Cell"; + name = "Secure Cell" + }, +/obj/machinery/door/window/brigdoor/security/cell{ + dir = 8; + id = "Secure Cell"; + name = "Secure Cell" + }, +/obj/effect/turf_decal/stripes/white/corner{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/white/corner{ + dir = 8 + }, +/obj/machinery/light/small, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, +/area/security/execution/transfer) +"Qqf" = ( +/turf/open/floor/plasteel, +/area/security/execution/transfer) +"Qqg" = ( +/obj/structure/bed, +/obj/item/clothing/suit/straight_jacket, +/obj/item/clothing/mask/muzzle, +/turf/open/floor/plasteel, +/area/security/execution/transfer) +"Qqh" = ( +/turf/open/floor/plasteel, +/area/security/execution/transfer) +"Qqi" = ( +/turf/open/floor/plasteel, +/area/security/execution/transfer) +"Qqj" = ( +/turf/open/floor/plasteel, +/area/security/execution/transfer) +"Qqk" = ( +/turf/open/floor/plasteel, +/area/security/execution/transfer) +"Qql" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ icon_state = "0-4" }, /turf/open/floor/plating, /area/security/warden) -"QpG" = ( +"Qqm" = ( /obj/structure/cable{ icon_state = "4-8" }, /obj/structure/table, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"QpH" = ( +"Qqn" = ( /obj/machinery/computer/secure_data{ dir = 1 }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"QpI" = ( +"Qqo" = ( /obj/structure/table, /obj/item/folder/red, /obj/item/pen, @@ -58035,7 +58263,7 @@ /obj/machinery/light, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"QpJ" = ( +"Qqp" = ( /obj/structure/table/reinforced, /obj/machinery/door/window/brigdoor{ dir = 1; @@ -58062,19 +58290,19 @@ }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"QpK" = ( +"Qqq" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 }, /turf/open/floor/plasteel, /area/security/brig) -"QpL" = ( +"Qqr" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 }, /turf/open/floor/plasteel, /area/security/brig) -"QpM" = ( +"Qqs" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, @@ -58082,7 +58310,7 @@ dir = 4 }, /area/security/brig) -"QpN" = ( +"Qqt" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 }, @@ -58090,7 +58318,7 @@ dir = 1 }, /area/security/brig) -"QpO" = ( +"Qqu" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, @@ -58098,7 +58326,7 @@ dir = 1 }, /area/security/brig) -"QpP" = ( +"Qqv" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, @@ -58113,13 +58341,13 @@ dir = 9 }, /area/security/brig) -"QpQ" = ( +"Qqw" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 }, /turf/open/floor/plasteel, /area/security/brig) -"QpR" = ( +"Qqx" = ( /obj/machinery/door_timer{ id = "Cell 2"; name = "Cell 2"; @@ -58129,7 +58357,7 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plasteel/red/corner, /area/security/brig) -"QpS" = ( +"Qqy" = ( /obj/machinery/door_timer{ id = "Cell 3"; name = "Cell 3"; @@ -58140,7 +58368,7 @@ }, /turf/open/floor/plasteel/red/corner, /area/security/brig) -"QpT" = ( +"Qqz" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, @@ -58148,7 +58376,7 @@ dir = 8 }, /area/security/brig) -"QpU" = ( +"QqA" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, @@ -58163,14 +58391,14 @@ dir = 10 }, /area/security/brig) -"QpV" = ( +"QqB" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/machinery/light, /turf/open/floor/plasteel/red/side, /area/security/brig) -"QpW" = ( +"QqC" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ @@ -58181,7 +58409,7 @@ }, /turf/open/floor/plating, /area/security/brig) -"QpX" = ( +"QqD" = ( /obj/machinery/door/window/brigdoor/security/cell{ id = "Cell 3"; name = "Cell 3" @@ -58192,7 +58420,7 @@ }, /turf/open/floor/plasteel/red/side, /area/security/brig) -"QpY" = ( +"QqE" = ( /obj/machinery/door/firedoor, /obj/structure/cable{ icon_state = "4-8" @@ -58207,7 +58435,7 @@ dir = 9 }, /area/security/brig) -"QpZ" = ( +"QqF" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1 }, @@ -58216,25 +58444,25 @@ }, /turf/open/floor/plasteel/floorgrime, /area/security/brig) -"Qqa" = ( +"QqG" = ( /turf/open/floor/plasteel/red/side{ dir = 1 }, /area/hallway/primary/fore) -"Qqb" = ( +"QqH" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, /turf/open/floor/plasteel/floorgrime, /area/security/brig) -"Qqc" = ( +"QqI" = ( /obj/machinery/flasher{ id = "Cell 2"; pixel_x = -28 }, /turf/open/floor/plasteel/floorgrime, /area/security/brig) -"Qqd" = ( +"QqJ" = ( /obj/machinery/flasher{ id = "Cell 3"; pixel_x = -28 @@ -58244,14 +58472,14 @@ }, /turf/open/floor/plasteel/floorgrime, /area/security/brig) -"Qqe" = ( +"QqK" = ( /obj/machinery/flasher{ id = "Cell 4"; pixel_x = -28 }, /turf/open/floor/plasteel/floorgrime, /area/security/brig) -"Qqf" = ( +"QqL" = ( /obj/structure/table/reinforced, /obj/machinery/door/poddoor/shutters/preopen{ id = "briggate"; @@ -58263,44 +58491,44 @@ }, /turf/open/floor/plasteel/dark, /area/security/brig) -"Qqg" = ( +"QqM" = ( /turf/open/floor/plasteel/red/side{ dir = 8 }, /area/hallway/primary/fore) -"Qqh" = ( +"QqN" = ( /turf/open/floor/plasteel/red/side{ dir = 1 }, /area/hallway/primary/fore) -"Qqi" = ( +"QqO" = ( /turf/open/floor/plasteel/red/side{ dir = 1 }, /area/hallway/primary/fore) -"Qqj" = ( +"QqP" = ( /turf/open/floor/plasteel/red/side{ dir = 6 }, /area/hallway/primary/fore) -"Qqk" = ( +"QqQ" = ( /turf/open/floor/plasteel/red/side{ dir = 10 }, /area/hallway/primary/fore) -"Qql" = ( +"QqR" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/red/side{ dir = 4 }, /area/hallway/primary/fore) -"Qqm" = ( +"QqS" = ( /obj/machinery/vending/cigarette, /turf/open/floor/plasteel/red/side{ dir = 4 }, /area/hallway/primary/fore) -"Qqn" = ( +"QqT" = ( /obj/structure/table/reinforced, /obj/machinery/door/poddoor/shutters/preopen{ id = "briggate"; @@ -58317,7 +58545,7 @@ }, /turf/open/floor/plasteel/dark, /area/security/brig) -"Qqo" = ( +"QqU" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/shutters/preopen{ id = "seclobby"; @@ -58328,24 +58556,32 @@ }, /turf/open/floor/plating, /area/security/brig) -"Qqp" = ( +"QqV" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/red/side{ dir = 4 }, /area/hallway/primary/fore) -"Qqq" = ( +"QqW" = ( /obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk, /turf/open/floor/plasteel/red/side{ dir = 4 }, /area/hallway/primary/fore) -"Qqr" = ( +"QqX" = ( /obj/machinery/vending/kink, /turf/open/floor/plating, /area/maintenance/starboard/fore) -"Qqs" = ( +"QqY" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel/red/corner{ + dir = 1 + }, +/area/hallway/primary/fore) +"QqZ" = ( /obj/structure/sign/securearea{ pixel_y = 32 }, @@ -58353,7 +58589,7 @@ dir = 4 }, /area/hallway/primary/fore) -"Qqt" = ( +"Qra" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/glass_security{ cyclelinkeddir = 1; @@ -58365,31 +58601,31 @@ dir = 1 }, /area/hallway/primary/fore) -"Qqu" = ( +"Qrb" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on, /turf/open/floor/plasteel/red/side{ dir = 10 }, /area/hallway/primary/fore) -"Qqv" = ( +"Qrc" = ( /turf/open/floor/plasteel/red/side, /area/hallway/primary/fore) -"Qqw" = ( +"Qrd" = ( /turf/open/floor/plasteel/red/side, /area/hallway/primary/fore) -"Qqx" = ( +"Qre" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/red/side{ dir = 6 }, /area/hallway/primary/fore) -"Qqy" = ( +"Qrf" = ( /obj/structure/disposalpipe/segment, /turf/open/floor/plasteel/red/side{ dir = 4 }, /area/hallway/primary/fore) -"Qqz" = ( +"Qrg" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/glass_security{ cyclelinkeddir = 1; @@ -58399,12 +58635,12 @@ }, /turf/open/floor/plasteel/red/side, /area/hallway/primary/fore) -"QqA" = ( +"Qrh" = ( /turf/open/floor/plasteel/red/side{ dir = 6 }, /area/hallway/primary/fore) -"QqB" = ( +"Qri" = ( /obj/machinery/flasher{ id = "brigentry"; pixel_x = 0; @@ -58416,70 +58652,70 @@ }, /turf/open/floor/plasteel/red/side, /area/hallway/primary/fore) -"QqC" = ( +"Qrj" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/hallway/primary/fore) -"QqD" = ( +"Qrk" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/maintenance/fore/secondary) -"QqE" = ( +"Qrl" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/structure/disposalpipe/segment, /turf/closed/wall, /area/maintenance/fore/secondary) -"QqF" = ( +"Qrm" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/hallway/primary/fore) -"QqG" = ( +"Qrn" = ( /obj/structure/disposalpipe/segment{ dir = 4 }, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /turf/open/floor/plating, /area/maintenance/fore/secondary) -"QqH" = ( +"Qro" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/hallway/primary/fore) -"QqI" = ( +"Qrp" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/hallway/primary/fore) -"QqJ" = ( +"Qrq" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/hallway/primary/fore) -"QqK" = ( +"Qrr" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/hallway/primary/fore) -"QqL" = ( +"Qrs" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/hallway/primary/fore) -"QqM" = ( +"Qrt" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 }, /turf/open/floor/plating, /area/maintenance/fore) -"QqN" = ( +"Qru" = ( /obj/structure/disposalpipe/segment{ dir = 4 }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plasteel, /area/hallway/primary/fore) -"QqO" = ( +"Qrv" = ( /obj/structure/chair/wood{ dir = 4 }, @@ -58487,11 +58723,11 @@ icon_state = "wood-broken6" }, /area/maintenance/bar/cafe) -"QqP" = ( +"Qrw" = ( /obj/structure/table/wood, /turf/open/floor/wood, /area/maintenance/bar/cafe) -"QqQ" = ( +"Qrx" = ( /obj/structure/chair/wood{ dir = 8 }, @@ -58499,42 +58735,42 @@ icon_state = "wood-broken7" }, /area/maintenance/bar/cafe) -"QqR" = ( +"Qry" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/wood, /area/maintenance/bar/cafe) -"QqS" = ( +"Qrz" = ( /obj/structure/table/wood, /turf/open/floor/wood, /area/maintenance/bar/cafe) -"QqT" = ( +"QrA" = ( /turf/open/floor/wood{ icon_state = "wood-broken5" }, /area/maintenance/bar/cafe) -"QqU" = ( +"QrB" = ( /obj/structure/table/wood, /obj/machinery/chem_dispenser/drinks/beer, /turf/open/floor/wood, /area/maintenance/bar/cafe) -"QqV" = ( +"QrC" = ( /turf/open/floor/wood{ icon_state = "wood-broken5" }, /area/maintenance/bar/cafe) -"QqW" = ( +"QrD" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 }, /turf/open/floor/wood, /area/maintenance/bar/cafe) -"QqX" = ( +"QrE" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 }, /turf/open/floor/wood, /area/maintenance/bar/cafe) -"QqY" = ( +"QrF" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, @@ -58543,21 +58779,21 @@ }, /turf/open/floor/wood, /area/maintenance/bar/cafe) -"QqZ" = ( +"QrG" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/open/floor/wood, /area/maintenance/bar/cafe) -"Qra" = ( +"QrH" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/structure/chair/stool/bar, /turf/open/floor/wood{ icon_state = "wood-broken7" }, /area/maintenance/bar/cafe) -"Qrb" = ( +"QrI" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 10 }, @@ -58566,22 +58802,22 @@ icon_state = "wood-broken6" }, /area/maintenance/bar/cafe) -"Qrc" = ( +"QrJ" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/wood, /area/maintenance/bar/cafe) -"Qrd" = ( +"QrK" = ( /obj/structure/table/wood, /obj/machinery/chem_dispenser/drinks, /turf/open/floor/wood, /area/maintenance/bar/cafe) -"Qre" = ( +"QrL" = ( /obj/structure/chair/wood{ dir = 4 }, /turf/open/floor/wood, /area/maintenance/bar/cafe) -"Qrf" = ( +"QrM" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 }, @@ -58591,29 +58827,7 @@ icon_state = "wood-broken" }, /area/maintenance/bar/cafe) -"Qrg" = ( -/obj/machinery/power/apc{ - areastring = "/area/crew_quarters/theatre/mime"; - dir = 2; - name = "Mime's Office APC"; - pixel_x = 1; - pixel_y = -24 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/structure/chair/wood{ - dir = 8 - }, -/obj/structure/cable{ - icon_state = "0-4" - }, -/turf/open/floor/wood{ - icon_state = "wood-broken6" - }, -/area/maintenance/bar/cafe) -"Qrh" = ( +"QrN" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/cable{ icon_state = "2-4" @@ -58623,26 +58837,7 @@ }, /turf/open/floor/wood, /area/maintenance/bar/cafe) -"Qri" = ( -/obj/machinery/power/apc{ - areastring = "/area/crew_quarters/theatre/clown"; - dir = 2; - name = "Clown's Office APC"; - pixel_x = 1; - pixel_y = -24 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "0-8" - }, -/turf/open/floor/wood{ - icon_state = "wood-broken6" - }, -/area/maintenance/bar/cafe) -"Qrj" = ( +"QrO" = ( /obj/machinery/light/small, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 @@ -58651,7 +58846,7 @@ icon_state = "wood-broken" }, /area/maintenance/bar/cafe) -"Qrk" = ( +"QrP" = ( /obj/structure/table/wood, /obj/item/storage/box/drinkingglasses, /obj/machinery/light_switch{ @@ -58659,32 +58854,24 @@ }, /turf/open/floor/wood, /area/maintenance/bar/cafe) -"Qrl" = ( +"QrQ" = ( /turf/closed/wall, /area/crew_quarters/theatre/mime) -"Qrm" = ( +"QrR" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/closed/wall, /area/crew_quarters/theatre/mime) -"Qrn" = ( -/obj/structure/barricade/wooden, -/obj/structure/grille, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/wood, -/area/maintenance/fore) -"Qro" = ( +"QrS" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/closed/wall, /area/crew_quarters/theatre/clown) -"Qrp" = ( +"QrT" = ( /obj/machinery/vending/autodrobe, /turf/open/floor/plasteel/white/side{ dir = 1 }, /area/crew_quarters/theatre/mime) -"Qrq" = ( +"QrU" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/light{ dir = 1 @@ -58693,20 +58880,7 @@ dir = 1 }, /area/crew_quarters/theatre/mime) -"Qrr" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/bed, -/obj/item/bedsheet/mime, -/turf/open/floor/plasteel/white/side{ - dir = 1 - }, -/area/crew_quarters/theatre/mime) -"Qrs" = ( -/obj/structure/closet/secure_closet/freezer/cream_pie, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plasteel/redyellow, -/area/crew_quarters/theatre/clown) -"Qrt" = ( +"QrV" = ( /obj/structure/closet/crate/wooden/toy, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/light{ @@ -58714,11 +58888,11 @@ }, /turf/open/floor/plasteel/redyellow, /area/crew_quarters/theatre/clown) -"Qru" = ( +"QrW" = ( /obj/machinery/vending/autodrobe, /turf/open/floor/plasteel/redyellow, /area/crew_quarters/theatre/clown) -"Qrv" = ( +"QrX" = ( /obj/structure/table, /obj/item/reagent_containers/food/snacks/baguette, /obj/item/toy/dummy, @@ -58729,7 +58903,7 @@ dir = 1 }, /area/crew_quarters/theatre/mime) -"Qrw" = ( +"QrY" = ( /obj/effect/landmark/start/mime, /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 @@ -58738,36 +58912,14 @@ dir = 1 }, /area/crew_quarters/theatre/mime) -"Qrx" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/camera{ - c_tag = "Mime's Office"; - dir = 8 - }, -/turf/open/floor/plasteel/white/side{ - dir = 1 - }, -/area/crew_quarters/theatre/mime) -"Qry" = ( -/obj/structure/mirror{ - pixel_x = -28 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/camera{ - c_tag = "Clown's Office"; - c_tag_order = 999; - dir = 4 - }, -/turf/open/floor/plasteel/redyellow, -/area/crew_quarters/theatre/clown) -"Qrz" = ( +"QrZ" = ( /obj/effect/landmark/start/clown, /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, /turf/open/floor/plasteel/redyellow, /area/crew_quarters/theatre/clown) -"QrA" = ( +"Qsa" = ( /obj/structure/bed, /obj/item/bedsheet/clown, /obj/machinery/airalarm{ @@ -58776,7 +58928,7 @@ }, /turf/open/floor/plasteel/redyellow, /area/crew_quarters/theatre/clown) -"QrB" = ( +"Qsb" = ( /obj/structure/table, /obj/item/lipstick/random{ pixel_x = -2; @@ -58794,30 +58946,30 @@ dir = 1 }, /area/crew_quarters/theatre/mime) -"QrC" = ( +"Qsc" = ( /turf/open/floor/plasteel/white/side{ dir = 1 }, /area/crew_quarters/theatre/mime) -"QrD" = ( +"Qsd" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/white/side{ dir = 1 }, /area/crew_quarters/theatre/mime) -"QrE" = ( +"Qse" = ( /obj/structure/reagent_dispensers/water_cooler, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/redyellow, /area/crew_quarters/theatre/clown) -"QrF" = ( +"Qsf" = ( /turf/open/floor/plasteel/redyellow, /area/crew_quarters/theatre/clown) -"QrG" = ( +"Qsg" = ( /obj/structure/displaycase/clown, /turf/open/floor/plasteel/redyellow, /area/crew_quarters/theatre/clown) -"QrH" = ( +"Qsh" = ( /obj/structure/table, /obj/item/paper_bin{ pixel_x = 1; @@ -58828,7 +58980,7 @@ dir = 1 }, /area/crew_quarters/theatre/mime) -"QrI" = ( +"Qsi" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 }, @@ -58836,7 +58988,7 @@ dir = 1 }, /area/crew_quarters/theatre/mime) -"QrJ" = ( +"Qsj" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 9 }, @@ -58844,7 +58996,7 @@ dir = 1 }, /area/crew_quarters/theatre/mime) -"QrK" = ( +"Qsk" = ( /obj/structure/table, /obj/item/device/flashlight/lamp/bananalamp, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -58858,104 +59010,98 @@ }, /turf/open/floor/plasteel/redyellow, /area/crew_quarters/theatre/clown) -"QrL" = ( +"Qsl" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 }, /turf/open/floor/plasteel/redyellow, /area/crew_quarters/theatre/clown) -"QrM" = ( +"Qsm" = ( /obj/structure/statue/bananium/clown, /turf/open/floor/plasteel/redyellow, /area/crew_quarters/theatre/clown) -"QrN" = ( +"Qsn" = ( /obj/effect/spawner/structure/window, /turf/open/floor/plating, /area/crew_quarters/theatre/clown) -"QrO" = ( +"Qso" = ( /obj/machinery/door/airlock/clown{ name = "Clown's Office"; req_access_txt = "46" }, /turf/open/floor/plasteel/redyellow, /area/crew_quarters/theatre/clown) -"QrP" = ( +"Qsp" = ( /obj/machinery/door/airlock{ name = "Bar Storage"; req_access_txt = "25" }, -/turf/open/floor/wood, +/turf/open/floor/plasteel{ + icon_state = "wood" + }, /area/crew_quarters/bar) -"QrQ" = ( +"Qsq" = ( /obj/structure/reagent_dispensers/beerkeg, /turf/open/floor/wood, /area/crew_quarters/bar) -"QrR" = ( -/obj/machinery/door/airlock/glass{ - name = "Diner" - }, -/obj/machinery/door/firedoor, -/turf/open/floor/plasteel, -/area/crew_quarters/bar) -"QrS" = ( +"Qsr" = ( /obj/machinery/vending/coffee, /turf/open/floor/wood, /area/bridge/meeting_room) -"QrT" = ( +"Qss" = ( /obj/machinery/door/airlock/maintenance{ req_access_txt = "12" }, /turf/open/floor/plating, /area/bridge/meeting_room) -"QrU" = ( +"Qst" = ( /turf/open/floor/plating, /area/maintenance/department/bridge) -"QrV" = ( +"Qsu" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plating, /area/maintenance/department/bridge) -"QrW" = ( +"Qsv" = ( /turf/open/floor/plating, /area/maintenance/department/bridge) -"QrX" = ( +"Qsw" = ( /turf/open/floor/plating, /area/maintenance/department/bridge) -"QrY" = ( +"Qsx" = ( /turf/open/floor/plating, /area/maintenance/department/bridge) -"QrZ" = ( +"Qsy" = ( /turf/open/floor/plating, /area/maintenance/department/bridge) -"Qsa" = ( +"Qsz" = ( /turf/open/floor/plating, /area/maintenance/department/bridge) -"Qsb" = ( +"QsA" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, /area/maintenance/department/bridge) -"Qsc" = ( +"QsB" = ( /turf/open/floor/plating, /area/maintenance/department/bridge) -"Qsd" = ( +"QsC" = ( /obj/machinery/door/airlock/maintenance{ name = "bridge maintenance access"; req_access_txt = "20" }, /turf/open/floor/plating, /area/crew_quarters/heads/captain) -"Qse" = ( +"QsD" = ( /turf/closed/wall/r_wall, /area/maintenance/department/bridge) -"Qsf" = ( +"QsE" = ( /turf/closed/wall/r_wall, /area/maintenance/department/bridge) -"Qsg" = ( -/obj/machinery/light_switch{ - pixel_y = 28 - }, -/turf/open/floor/circuit, +"QsF" = ( +/obj/machinery/computer/bank_machine, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, /area/ai_monitored/nuke_storage) -"Qsh" = ( +"QsG" = ( /obj/machinery/power/apc{ dir = 1; name = "Vault APC"; @@ -58967,38 +59113,90 @@ }, /turf/open/floor/circuit, /area/ai_monitored/nuke_storage) -"Qsi" = ( +"QsH" = ( +/obj/structure/filingcabinet, +/obj/item/folder/documents, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/nuke_storage) +"QsI" = ( +/obj/structure/closet/crate{ + name = "Gold Crate" + }, +/obj/item/stack/sheet/mineral/gold{ + pixel_x = -1; + pixel_y = 5 + }, +/obj/item/stack/sheet/mineral/gold{ + pixel_y = 2 + }, +/obj/item/stack/sheet/mineral/gold{ + pixel_x = 1; + pixel_y = -2 + }, +/obj/item/storage/belt/champion, +/obj/effect/turf_decal/bot_white/right, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/nuke_storage) +"QsJ" = ( /obj/structure/cable{ icon_state = "2-4" }, /turf/open/floor/circuit, /area/ai_monitored/nuke_storage) -"Qsj" = ( +"QsK" = ( /obj/structure/cable{ icon_state = "1-8" }, /turf/open/floor/circuit, /area/ai_monitored/nuke_storage) -"Qsk" = ( +"QsL" = ( +/obj/item/coin/silver{ + pixel_x = 7; + pixel_y = 12 + }, +/obj/item/coin/silver{ + pixel_x = 12; + pixel_y = 7 + }, +/obj/item/coin/silver{ + pixel_x = 4; + pixel_y = 8 + }, +/obj/item/coin/silver{ + pixel_x = -6; + pixel_y = 5 + }, +/obj/item/coin/silver{ + pixel_x = 5; + pixel_y = -8 + }, +/obj/structure/closet/crate{ + name = "Silver Crate" + }, +/obj/effect/turf_decal/bot_white/left, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/nuke_storage) +"QsM" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 5 }, /turf/closed/wall/r_wall, /area/ai_monitored/nuke_storage) -"Qsl" = ( +"QsN" = ( /obj/structure/sign/securearea, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 }, /turf/closed/wall/r_wall, /area/ai_monitored/nuke_storage) -"Qsm" = ( +"QsO" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 9 }, /turf/closed/wall/r_wall, /area/ai_monitored/nuke_storage) -"Qsn" = ( +"QsP" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable{ @@ -59006,10 +59204,10 @@ }, /turf/open/floor/plating, /area/security/checkpoint/tertiary) -"Qso" = ( +"QsQ" = ( /turf/closed/wall/r_wall, /area/security/checkpoint/tertiary) -"Qsp" = ( +"QsR" = ( /obj/machinery/door/firedoor, /obj/structure/cable{ icon_state = "2-4" @@ -59024,7 +59222,7 @@ dir = 5 }, /area/security/checkpoint/tertiary) -"Qsq" = ( +"QsS" = ( /obj/structure/closet/secure_closet/security, /obj/machinery/power/apc{ areastring = "/area/security/checkpoint/tertiary"; @@ -59040,7 +59238,7 @@ dir = 9 }, /area/security/checkpoint/tertiary) -"Qsr" = ( +"QsT" = ( /obj/structure/reagent_dispensers/peppertank{ pixel_y = 30 }, @@ -59051,7 +59249,7 @@ dir = 1 }, /area/security/checkpoint/tertiary) -"Qss" = ( +"QsU" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable{ icon_state = "2-8" @@ -59063,7 +59261,7 @@ dir = 1 }, /area/security/checkpoint/tertiary) -"Qst" = ( +"QsV" = ( /obj/structure/cable{ icon_state = "1-8" }, @@ -59071,13 +59269,13 @@ dir = 1 }, /area/security/checkpoint/tertiary) -"Qsu" = ( +"QsW" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/red/side{ dir = 1 }, /area/security/checkpoint/tertiary) -"Qsv" = ( +"QsX" = ( /obj/machinery/requests_console{ department = "Security"; departmentType = 5; @@ -59087,13 +59285,13 @@ dir = 1 }, /area/security/checkpoint/tertiary) -"Qsw" = ( +"QsY" = ( /obj/machinery/computer/security, /turf/open/floor/plasteel/red/side{ dir = 5 }, /area/security/checkpoint/tertiary) -"Qsx" = ( +"QsZ" = ( /obj/structure/closet/wardrobe/red, /obj/machinery/light{ dir = 8 @@ -59102,10 +59300,10 @@ dir = 8 }, /area/security/checkpoint/tertiary) -"Qsy" = ( +"Qta" = ( /turf/open/floor/plasteel, /area/security/checkpoint/tertiary) -"Qsz" = ( +"Qtb" = ( /obj/machinery/computer/secure_data, /obj/machinery/light{ dir = 4 @@ -59114,7 +59312,7 @@ dir = 4 }, /area/security/checkpoint/tertiary) -"QsA" = ( +"Qtc" = ( /obj/machinery/airalarm{ dir = 4; pixel_x = -22 @@ -59136,7 +59334,7 @@ dir = 10 }, /area/security/checkpoint/tertiary) -"QsB" = ( +"Qtd" = ( /obj/item/paper_bin{ pixel_x = 1; pixel_y = 9 @@ -59145,7 +59343,7 @@ /obj/structure/table, /turf/open/floor/plasteel/red/side, /area/security/checkpoint/tertiary) -"QsC" = ( +"Qte" = ( /obj/item/device/radio/off, /obj/item/crowbar, /obj/item/device/assembly/flash/handheld, @@ -59159,7 +59357,7 @@ dir = 6 }, /area/security/checkpoint/tertiary) -"QsD" = ( +"Qtf" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/shutters/preopen{ id = "vault"; @@ -59173,28 +59371,41 @@ }, /turf/open/floor/plating, /area/security/checkpoint/tertiary) -"QsE" = ( +"Qtg" = ( +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/quartermaster/miningdock) +"Qth" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/hallway/primary/central) +"Qti" = ( /obj/effect/spawner/lootdrop/grille_or_trash, /turf/open/floor/plating{ icon_state = "platingdmg3" }, /area/maintenance/port/aft) -"QsF" = ( +"Qtj" = ( /obj/machinery/door/airlock{ id_tag = "MaintDorm2"; name = "Maintenance Dorm 2" }, /turf/open/floor/wood, /area/maintenance/port/aft) -"QsG" = ( +"Qtk" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/wood, /area/maintenance/port/aft) -"QsH" = ( +"Qtl" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/wood, /area/maintenance/port/aft) -"QsI" = ( +"Qtm" = ( /obj/structure/rack{ dir = 8; layer = 2.9 @@ -59206,11 +59417,11 @@ /obj/effect/decal/cleanable/cobweb, /turf/open/floor/plating, /area/maintenance/port/aft) -"QsJ" = ( +"Qtn" = ( /obj/structure/closet/secure_closet/personal, /turf/open/floor/wood, /area/maintenance/port/aft) -"QsK" = ( +"Qto" = ( /obj/machinery/light/small, /obj/structure/table/wood, /obj/machinery/atmospherics/pipe/simple/general/hidden{ @@ -59218,7 +59429,7 @@ }, /turf/open/floor/wood, /area/maintenance/port/aft) -"QsL" = ( +"Qtp" = ( /obj/structure/bed, /obj/item/bedsheet, /obj/machinery/atmospherics/pipe/simple/general/hidden{ @@ -59226,49 +59437,49 @@ }, /turf/open/floor/wood, /area/maintenance/port/aft) -"QsM" = ( +"Qtq" = ( /turf/closed/wall, /area/maintenance/bar) -"QsN" = ( +"Qtr" = ( /turf/closed/wall, /area/maintenance/bar) -"QsO" = ( +"Qts" = ( /turf/closed/wall, /area/maintenance/bar) -"QsP" = ( +"Qtt" = ( /obj/machinery/door/airlock/maintenance/abandoned{ req_access_txt = "0" }, /turf/open/floor/plating, /area/maintenance/bar) -"QsQ" = ( +"Qtu" = ( /turf/closed/wall, /area/maintenance/bar) -"QsR" = ( +"Qtv" = ( /turf/closed/wall, /area/maintenance/bar) -"QsS" = ( +"Qtw" = ( /turf/closed/wall, /area/maintenance/bar) -"QsT" = ( +"Qtx" = ( /turf/closed/wall, /area/maintenance/bar) -"QsU" = ( +"Qty" = ( /turf/open/floor/wood, /area/maintenance/bar) -"QsV" = ( +"Qtz" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 }, /turf/open/floor/wood, /area/maintenance/bar) -"QsW" = ( +"QtA" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /turf/open/floor/wood, /area/maintenance/bar) -"QsX" = ( +"QtB" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, @@ -59276,7 +59487,7 @@ icon_state = "wood-broken5" }, /area/maintenance/bar) -"QsY" = ( +"QtC" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, @@ -59285,7 +59496,7 @@ }, /turf/open/floor/wood, /area/maintenance/bar) -"QsZ" = ( +"QtD" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, @@ -59297,7 +59508,7 @@ }, /turf/open/floor/plating, /area/maintenance/bar) -"Qta" = ( +"QtE" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, @@ -59306,30 +59517,30 @@ }, /turf/open/floor/plating, /area/maintenance/port/aft) -"Qtb" = ( +"QtF" = ( /turf/closed/wall, /area/maintenance/bar) -"Qtc" = ( +"QtG" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/wood{ icon_state = "wood-broken7" }, /area/maintenance/bar) -"Qtd" = ( +"QtH" = ( /obj/structure/chair/stool/bar, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 6 }, /turf/open/floor/wood, /area/maintenance/bar) -"Qte" = ( +"QtI" = ( /obj/structure/table/wood, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/open/floor/wood, /area/maintenance/bar) -"Qtf" = ( +"QtJ" = ( /obj/structure/table/wood, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -59344,40 +59555,40 @@ icon_state = "wood-broken7" }, /area/maintenance/bar) -"Qtg" = ( +"QtK" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/closed/wall, /area/maintenance/bar) -"Qth" = ( +"QtL" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/closed/wall, /area/maintenance/bar) -"Qti" = ( +"QtM" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/closed/wall, /area/maintenance/bar) -"Qtj" = ( +"QtN" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/closed/wall, /area/maintenance/bar) -"Qtk" = ( +"QtO" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 }, /turf/closed/wall, /area/maintenance/bar) -"Qtl" = ( +"QtP" = ( /turf/closed/wall, /area/maintenance/bar) -"Qtm" = ( +"QtQ" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, @@ -59386,7 +59597,7 @@ }, /turf/open/floor/wood, /area/maintenance/bar) -"Qtn" = ( +"QtR" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, @@ -59394,38 +59605,38 @@ icon_state = "wood-broken6" }, /area/maintenance/bar) -"Qto" = ( +"QtS" = ( /obj/structure/chair/stool/bar, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/wood, /area/maintenance/bar) -"Qtp" = ( +"QtT" = ( /obj/structure/table/wood, /turf/open/floor/wood{ icon_state = "wood-broken5" }, /area/maintenance/bar) -"Qtq" = ( +"QtU" = ( /obj/structure/cable{ icon_state = "1-2" }, /turf/open/floor/wood, /area/maintenance/bar) -"Qtr" = ( +"QtV" = ( /obj/machinery/chem_dispenser/drinks/beer, /obj/structure/table/wood, /turf/open/floor/wood, /area/maintenance/bar) -"Qts" = ( +"QtW" = ( /turf/closed/wall, /area/maintenance/bar) -"Qtt" = ( +"QtX" = ( /obj/item/restraints/handcuffs/fake, /obj/effect/decal/cleanable/blood/old, /obj/effect/spawner/lootdrop/minor/kittyears_or_rabbitears, /turf/open/floor/plating, /area/maintenance/bar) -"Qtu" = ( +"QtY" = ( /obj/item/shard, /obj/item/wirecutters, /obj/item/wallframe/camera, @@ -59433,14 +59644,14 @@ icon_state = "panelscorched" }, /area/maintenance/bar) -"Qtv" = ( +"QtZ" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/maintenance/bar) -"Qtw" = ( +"Qua" = ( /turf/closed/wall, /area/maintenance/bar) -"Qtx" = ( +"Qub" = ( /obj/item/device/radio/intercom{ freerange = 0; frequency = 1459; @@ -59451,22 +59662,22 @@ icon_state = "wood-broken" }, /area/maintenance/bar) -"Qty" = ( +"Quc" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/wood, /area/maintenance/bar) -"Qtz" = ( +"Qud" = ( /obj/structure/chair/stool/bar, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/wood{ icon_state = "wood-broken7" }, /area/maintenance/bar) -"QtA" = ( +"Que" = ( /obj/structure/table/wood, /turf/open/floor/wood, /area/maintenance/bar) -"QtB" = ( +"Quf" = ( /obj/structure/cable{ icon_state = "1-2" }, @@ -59474,15 +59685,15 @@ icon_state = "wood-broken7" }, /area/maintenance/bar) -"QtC" = ( +"Qug" = ( /obj/structure/table/wood, /obj/machinery/chem_dispenser/drinks, /turf/open/floor/wood, /area/maintenance/bar) -"QtD" = ( +"Quh" = ( /turf/closed/wall, /area/maintenance/bar) -"QtE" = ( +"Qui" = ( /obj/effect/spawner/lootdrop/maintenance{ lootcount = 2; name = "2maintenance loot spawner" @@ -59491,7 +59702,7 @@ /obj/item/device/electropack/shockcollar, /turf/open/floor/plating, /area/maintenance/bar) -"QtF" = ( +"Quj" = ( /obj/structure/bed, /obj/item/bedsheet/grey, /obj/effect/decal/cleanable/semen{ @@ -59503,11 +59714,11 @@ icon_state = "platingdmg3" }, /area/maintenance/bar) -"QtG" = ( +"Quk" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/maintenance/bar) -"QtH" = ( +"Qul" = ( /obj/machinery/door/airlock/maintenance/abandoned{ name = "Incinerator Access"; req_access_txt = "12" @@ -59517,30 +59728,30 @@ }, /turf/open/floor/plating, /area/maintenance/bar) -"QtI" = ( +"Qum" = ( /turf/open/floor/wood, /area/maintenance/bar) -"QtJ" = ( +"Qun" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/wood{ icon_state = "wood-broken5" }, /area/maintenance/bar) -"QtK" = ( +"Quo" = ( /obj/structure/chair/stool/bar, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 }, /turf/open/floor/wood, /area/maintenance/bar) -"QtL" = ( +"Qup" = ( /obj/structure/table/wood, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/open/floor/wood, /area/maintenance/bar) -"QtM" = ( +"Quq" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 }, @@ -59549,15 +59760,15 @@ }, /turf/open/floor/wood, /area/maintenance/bar) -"QtN" = ( +"Qur" = ( /obj/structure/table/wood, /obj/item/storage/box/drinkingglasses, /turf/open/floor/wood, /area/maintenance/bar) -"QtO" = ( +"Qus" = ( /turf/closed/wall, /area/maintenance/bar) -"QtP" = ( +"Qut" = ( /obj/item/lighter/greyscale, /obj/effect/decal/cleanable/semen{ desc = "Blech."; @@ -59567,32 +59778,32 @@ icon_state = "panelscorched" }, /area/maintenance/bar) -"QtQ" = ( +"Quu" = ( /obj/effect/spawner/lootdrop/maintenance, /obj/effect/decal/cleanable/blood/old, /obj/item/device/assembly/signaler, /turf/open/floor/plating, /area/maintenance/bar) -"QtR" = ( +"Quv" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/maintenance/bar) -"QtS" = ( +"Quw" = ( /turf/closed/wall, /area/maintenance/bar) -"QtT" = ( +"Qux" = ( /obj/effect/spawner/lootdrop/keg, /turf/open/floor/wood, /area/maintenance/bar) -"QtU" = ( +"Quy" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/wood, /area/maintenance/bar) -"QtV" = ( +"Quz" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/wood, /area/maintenance/bar) -"QtW" = ( +"QuA" = ( /obj/machinery/power/apc{ areastring = "/area/maintenance/bar"; dir = 2; @@ -59605,37 +59816,37 @@ icon_state = "wood-broken7" }, /area/maintenance/bar) -"QtX" = ( +"QuB" = ( /turf/closed/wall, /area/maintenance/bar) -"QtY" = ( +"QuC" = ( /turf/closed/wall, /area/maintenance/bar) -"QtZ" = ( +"QuD" = ( /obj/structure/falsewall, /turf/open/floor/plating, /area/maintenance/bar) -"Qua" = ( +"QuE" = ( /turf/closed/wall, /area/maintenance/bar) -"Qub" = ( +"QuF" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/maintenance/bar) -"Quc" = ( +"QuG" = ( /turf/closed/wall, /area/maintenance/bar) -"Qud" = ( +"QuH" = ( /turf/closed/wall, /area/maintenance/bar) -"Que" = ( +"QuI" = ( /obj/machinery/door/airlock/maintenance/abandoned{ req_access_txt = "0" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/wood, /area/maintenance/bar) -"Quf" = ( +"QuJ" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/airlock/maintenance/abandoned{ req_access_txt = "0" @@ -59644,48 +59855,48 @@ icon_state = "wood-broken" }, /area/maintenance/bar) -"Qug" = ( +"QuK" = ( /obj/structure/sign/poster/official/no_erp, /turf/closed/wall, /area/maintenance/bar) -"Quh" = ( +"QuL" = ( /turf/closed/wall, /area/maintenance/bar) -"Qui" = ( +"QuM" = ( /obj/machinery/vending/clothing, /turf/open/floor/wood, /area/maintenance/bar) -"Quj" = ( +"QuN" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/maintenance/bar) -"Quk" = ( +"QuO" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/wood, /area/maintenance/bar) -"Qul" = ( +"QuP" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/wood, /area/maintenance/bar) -"Qum" = ( +"QuQ" = ( /turf/open/floor/wood{ icon_state = "wood-broken6" }, /area/maintenance/bar) -"Qun" = ( +"QuR" = ( /turf/open/floor/wood{ icon_state = "wood-broken6" }, /area/maintenance/bar) -"Quo" = ( +"QuS" = ( /obj/machinery/vending/autodrobe, /turf/open/floor/wood, /area/maintenance/bar) -"Qup" = ( +"QuT" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/maintenance/bar) -"Quq" = ( +"QuU" = ( /obj/structure/sign/poster/random{ pixel_x = -32 }, @@ -59696,29 +59907,28 @@ icon_state = "wood-broken7" }, /area/maintenance/bar) -"Qur" = ( +"QuV" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/wood, /area/maintenance/bar) -"Qus" = ( +"QuW" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/wood{ icon_state = "wood-broken" }, /area/maintenance/bar) -"Qut" = ( +"QuX" = ( /obj/structure/chair/stool, /turf/open/floor/wood{ icon_state = "wood-broken7" }, /area/maintenance/bar) -"Quu" = ( +"QuY" = ( /turf/open/floor/wood{ icon_state = "wood-broken5" }, /area/maintenance/bar) -"Quv" = ( -/obj/structure/table/wood/bar, +"QuZ" = ( /obj/item/paper_bin{ pixel_x = -3; pixel_y = 7 @@ -59727,40 +59937,41 @@ /obj/machinery/newscaster{ pixel_x = 30 }, +/obj/structure/table/wood, /turf/open/floor/wood, /area/maintenance/bar) -"Quw" = ( +"Qva" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/maintenance/bar) -"Qux" = ( +"Qvb" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, /turf/open/floor/wood, /area/maintenance/bar) -"Quy" = ( +"Qvc" = ( /obj/structure/chair/stool, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 5 }, /turf/open/floor/wood, /area/maintenance/bar) -"Quz" = ( +"Qvd" = ( /obj/structure/table/wood/poker, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/open/floor/wood, /area/maintenance/bar) -"QuA" = ( +"Qve" = ( /obj/structure/table/wood/poker, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/open/floor/wood, /area/maintenance/bar) -"QuB" = ( +"Qvf" = ( /obj/structure/table/wood/poker, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -59768,81 +59979,80 @@ /obj/item/storage/pill_bottle/dice, /turf/open/floor/wood, /area/maintenance/bar) -"QuC" = ( +"Qvg" = ( /obj/structure/chair/stool, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/open/floor/wood, /area/maintenance/bar) -"QuD" = ( +"Qvh" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 }, /turf/open/floor/wood, /area/maintenance/bar) -"QuE" = ( -/obj/structure/table/wood/bar, +"Qvi" = ( /obj/machinery/light{ dir = 4 }, +/obj/structure/table/wood, +/obj/item/reagent_containers/spray/cleaner, /turf/open/floor/wood{ icon_state = "wood-broken6" }, /area/maintenance/bar) -"QuF" = ( +"Qvj" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/maintenance/bar) -"QuG" = ( +"Qvk" = ( /turf/open/floor/wood{ icon_state = "wood-broken5" }, /area/maintenance/bar) -"QuH" = ( +"Qvl" = ( /obj/structure/table/wood/poker, /turf/open/floor/wood, /area/maintenance/bar) -"QuI" = ( +"Qvm" = ( /obj/structure/table/wood/poker, /turf/open/floor/wood, /area/maintenance/bar) -"QuJ" = ( +"Qvn" = ( /obj/structure/table/wood/poker, /obj/item/coin/iron, /turf/open/floor/wood, /area/maintenance/bar) -"QuK" = ( -/obj/structure/table/wood/bar, -/obj/item/reagent_containers/spray/cleaner, -/obj/structure/sign/poster/random{ - pixel_x = 32 +"Qvo" = ( +/obj/machinery/vending/games{ + name = "\improper Good 'Clean' Fun" }, /turf/open/floor/wood, /area/maintenance/bar) -"QuL" = ( +"Qvp" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/maintenance/bar) -"QuM" = ( +"Qvq" = ( /obj/effect/spawner/lootdrop/keg, /turf/open/floor/wood{ icon_state = "wood-broken7" }, /area/maintenance/bar) -"QuN" = ( +"Qvr" = ( /obj/structure/sign/poster/random{ pixel_y = -32 }, /turf/open/floor/wood, /area/maintenance/bar) -"QuO" = ( +"Qvs" = ( /obj/structure/chair/stool, /turf/open/floor/wood{ icon_state = "wood-broken" }, /area/maintenance/bar) -"QuP" = ( +"Qvt" = ( /obj/structure/chair/stool, /obj/item/device/radio/intercom{ name = "Station Intercom (General)"; @@ -59850,7 +60060,7 @@ }, /turf/open/floor/wood, /area/maintenance/bar) -"QuQ" = ( +"Qvu" = ( /obj/structure/sign/poster/random{ pixel_y = -32 }, @@ -59858,35 +60068,35 @@ icon_state = "wood-broken7" }, /area/maintenance/bar) -"QuR" = ( +"Qvv" = ( /obj/machinery/vending/kink, /turf/open/floor/wood, /area/maintenance/bar) -"QuS" = ( +"Qvw" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/maintenance/bar) -"QuT" = ( +"Qvx" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 }, /turf/closed/wall/r_wall, /area/engine/engine_smes) -"QuU" = ( +"Qvy" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable{ icon_state = "1-2" }, /turf/closed/wall/r_wall, /area/engine/engine_smes) -"QuV" = ( +"Qvz" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable{ icon_state = "1-2" }, /turf/closed/wall/r_wall, /area/engine/gravity_generator) -"QuW" = ( +"QvA" = ( /obj/structure/sign/securearea{ desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; @@ -59899,7 +60109,7 @@ }, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"QuX" = ( +"QvB" = ( /obj/machinery/camera{ c_tag = "Gravity Generator Foyer" }, @@ -59915,17 +60125,17 @@ }, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"QuY" = ( +"QvC" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable{ icon_state = "1-2" }, /turf/closed/wall/r_wall, /area/engine/gravity_generator) -"QuZ" = ( +"QvD" = ( /turf/closed/wall, /area/engine/gravity_generator) -"Qva" = ( +"QvE" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 }, @@ -59938,11 +60148,11 @@ }, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"Qvb" = ( +"QvF" = ( /obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"Qvc" = ( +"QvG" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 }, @@ -59954,7 +60164,7 @@ }, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"Qvd" = ( +"QvH" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 }, @@ -59963,42 +60173,42 @@ }, /turf/closed/wall/r_wall, /area/engine/gravity_generator) -"Qve" = ( +"QvI" = ( /obj/structure/grille, /turf/open/floor/plating/airless, /area/engine/engineering) -"Qvf" = ( +"QvJ" = ( /obj/structure/grille, /turf/open/floor/plating/airless, /area/engine/engineering) -"Qvg" = ( +"QvK" = ( /obj/structure/grille, /turf/open/floor/plating/airless, /area/engine/engineering) -"Qvh" = ( +"QvL" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable{ icon_state = "1-2" }, /turf/closed/wall/r_wall, /area/engine/gravity_generator) -"Qvi" = ( +"QvM" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 }, /turf/closed/wall/r_wall, /area/engine/gravity_generator) -"Qvj" = ( +"QvN" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/closed/wall/r_wall, /area/engine/gravity_generator) -"Qvk" = ( +"QvO" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 }, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"Qvl" = ( +"QvP" = ( /obj/item/device/radio/intercom{ broadcasting = 0; listening = 1; @@ -60010,19 +60220,19 @@ }, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"Qvm" = ( +"QvQ" = ( /obj/machinery/power/terminal, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/structure/cable, /turf/closed/wall/r_wall, /area/engine/gravity_generator) -"Qvn" = ( +"QvR" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 10 }, /turf/closed/wall/r_wall, /area/engine/gravity_generator) -"Qvo" = ( +"QvS" = ( /obj/machinery/firealarm{ dir = 8; pixel_x = -24 @@ -60034,11 +60244,11 @@ /obj/item/pen/blue, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"Qvp" = ( +"QvT" = ( /obj/machinery/holopad, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"Qvq" = ( +"QvU" = ( /obj/machinery/power/smes{ charge = 5e+006 }, @@ -60047,7 +60257,7 @@ }, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"Qvr" = ( +"QvV" = ( /obj/machinery/power/apc{ dir = 8; name = "Gravity Generator APC"; @@ -60066,28 +60276,28 @@ }, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"Qvs" = ( +"QvW" = ( /obj/effect/turf_decal/stripes/line, /obj/structure/cable{ icon_state = "4-8" }, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"Qvt" = ( +"QvX" = ( /obj/effect/turf_decal/stripes/line, /obj/structure/cable{ icon_state = "4-8" }, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"Qvu" = ( +"QvY" = ( /obj/effect/turf_decal/stripes/line, /obj/structure/cable{ icon_state = "4-8" }, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"Qvv" = ( +"QvZ" = ( /obj/effect/turf_decal/stripes/line{ dir = 6 }, @@ -60103,7 +60313,7 @@ }, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"Qvw" = ( +"Qwa" = ( /obj/structure/sign/securearea{ desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; @@ -60116,7 +60326,7 @@ }, /turf/open/floor/plating, /area/engine/gravity_generator) -"Qvx" = ( +"Qwb" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ icon_state = "0-8" @@ -60126,7 +60336,7 @@ }, /turf/open/floor/plating, /area/engine/gravity_generator) -"Qvy" = ( +"Qwc" = ( /obj/machinery/door/airlock/glass_engineering{ name = "Gravity Generator"; req_access_txt = "11"; @@ -60137,7 +60347,7 @@ }, /turf/open/floor/plasteel/dark, /area/engine/gravity_generator) -"Qvz" = ( +"Qwd" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ icon_state = "0-8" @@ -60147,7 +60357,7 @@ }, /turf/open/floor/plating, /area/engine/gravity_generator) -"QvA" = ( +"Qwe" = ( /obj/structure/sign/securearea{ desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; @@ -60161,19 +60371,52 @@ /obj/structure/cable, /turf/open/floor/plating, /area/engine/gravity_generator) -"QvB" = ( +"Qwf" = ( +/obj/effect/turf_decal/bot_white/right, +/turf/open/floor/plasteel/dark, +/area/engine/gravity_generator) +"Qwg" = ( +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, +/area/engine/gravity_generator) +"Qwh" = ( +/obj/effect/turf_decal/bot_white/left, +/turf/open/floor/plasteel/dark, +/area/engine/gravity_generator) +"Qwi" = ( +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, +/area/engine/gravity_generator) +"Qwj" = ( +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, +/area/engine/gravity_generator) +"Qwk" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 }, /turf/closed/wall/r_wall, /area/engine/gravity_generator) -"QvC" = ( +"Qwl" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 }, /turf/open/floor/plasteel/dark, /area/engine/gravity_generator) -"QvD" = ( +"Qwm" = ( +/obj/effect/turf_decal/bot_white/left, +/turf/open/floor/plasteel/dark, +/area/engine/gravity_generator) +"Qwn" = ( +/obj/machinery/gravity_generator/main/station, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, +/area/engine/gravity_generator) +"Qwo" = ( +/obj/effect/turf_decal/bot_white/right, +/turf/open/floor/plasteel/dark, +/area/engine/gravity_generator) +"Qwp" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 }, @@ -60184,168 +60427,12 @@ }, /turf/open/floor/plasteel/dark, /area/engine/gravity_generator) -"QvE" = ( +"Qwq" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 9 }, /turf/closed/wall/r_wall, /area/engine/gravity_generator) -"QvF" = ( -/obj/effect/turf_decal/loading_area, -/turf/open/floor/plasteel/showroomfloor, -/area/crew_quarters/kitchen) -"QvG" = ( -/obj/structure/falsewall, -/obj/effect/turf_decal/delivery/white, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"QvH" = ( -/obj/effect/turf_decal/loading_area/white, -/obj/effect/turf_decal/stripes/white/corner{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/white/corner, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"QvI" = ( -/obj/effect/turf_decal/stripes/white/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/white/corner{ - dir = 1 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"QvJ" = ( -/obj/effect/turf_decal/stripes/white/line{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/white/corner, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"QvK" = ( -/obj/structure/window/reinforced, -/obj/structure/window/reinforced{ - dir = 4 - }, -/obj/structure/window/reinforced{ - dir = 1; - layer = 2.9 - }, -/obj/structure/closet/secure_closet/brig{ - id = "Secure Cell"; - name = "Secure Cell Locker" - }, -/obj/effect/turf_decal/stripes/white/end{ - dir = 4 - }, -/obj/effect/turf_decal/delivery/white, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"QvL" = ( -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"QvM" = ( -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"QvN" = ( -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"QvO" = ( -/obj/effect/turf_decal/stripes/white/line{ - dir = 5 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"QvP" = ( -/obj/effect/turf_decal/stripes/white/line, -/obj/effect/turf_decal/stripes/white/corner{ - dir = 1 - }, -/obj/machinery/door_timer{ - id = "Secure Cell"; - name = "Secure Cell"; - pixel_y = -32 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"QvQ" = ( -/obj/machinery/door/window/brigdoor/security/cell{ - dir = 4; - id = "Secure Cell"; - name = "Secure Cell" - }, -/obj/machinery/door/window/brigdoor/security/cell{ - dir = 8; - id = "Secure Cell"; - name = "Secure Cell" - }, -/obj/effect/turf_decal/stripes/white/corner{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/white/corner{ - dir = 8 - }, -/obj/machinery/light/small, -/turf/open/floor/plasteel/dark/side{ - dir = 8 - }, -/area/security/execution/transfer) -"QvR" = ( -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"QvS" = ( -/obj/structure/bed, -/obj/item/clothing/suit/straight_jacket, -/obj/item/clothing/mask/muzzle, -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"QvT" = ( -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"QvU" = ( -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"QvV" = ( -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"QvW" = ( -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"QvX" = ( -/turf/open/floor/plasteel/dark/side{ - dir = 4 - }, -/area/ai_monitored/storage/eva) -"QvY" = ( -/turf/open/floor/plasteel/dark/side{ - dir = 8 - }, -/area/ai_monitored/storage/eva) -"QvZ" = ( -/turf/open/floor/plasteel/dark/side{ - dir = 4 - }, -/area/ai_monitored/storage/eva) -"Qwa" = ( -/turf/open/floor/plasteel/dark/side{ - dir = 8 - }, -/area/ai_monitored/storage/eva) -"Qwb" = ( -/turf/open/floor/plasteel/dark/side{ - dir = 4 - }, -/area/ai_monitored/storage/eva) -"Qwc" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/hallway/primary/central) (1,1,1) = {" aaa @@ -79525,7 +79612,7 @@ bCq bJP bCq bTs -QsJ +Qtn bCq cbj bLv @@ -79781,8 +79868,8 @@ aaa bCq bHE bCq -QsG -QsK +Qtk +Qto bCq cbk bLv @@ -80039,7 +80126,7 @@ bLv bPR bRc bSo -QsL +Qtp bCq bVy bLv @@ -80241,14 +80328,14 @@ aaf avY axo ayB -QqO -QqT -Qre -Qrl -Qrp Qrv -QrB -QrH +QrC +QrL +QrQ +QrT +QrX +Qsb +Qsh aKu aLF aLF @@ -80498,14 +80585,14 @@ aoV avY axo ayB -QqP -QqW -Qrf -Qrm -Qrq Qrw -QrC -QrI +QrD +QrM +QrR +QrU +QrY +Qsc +Qsi aKt aLE bDe @@ -80755,14 +80842,14 @@ aaf avY axo ayB -QqQ -QqX -Qrg -aDs -Qrr Qrx -QrD -QrJ +QrE +aBT +aDs +aEN +aGb +Qsd +Qsj aKu aLE aLE @@ -80782,7 +80869,7 @@ aZF aZF bgy aZE -bjr +QoN bjr ama bmh @@ -80809,7 +80896,7 @@ aaa bCq bPV bCq -QsG +Qtl bTw bCq bVD @@ -81013,14 +81100,14 @@ avZ axo ayC azH -QqY +QrF aBS -Qrl -Qrl -Qrl -Qrl -Qrl -Qrl +aDr +aDr +aDr +aDr +aDr +aDr aLE aLE aOl @@ -81065,9 +81152,9 @@ aoV aoV bCq bPW -QsF +Qtj bSp -QsL +bTv bCq bVC bWx @@ -81266,13 +81353,13 @@ aqR aGh aqR aqR -QqM +Qrt axq ayA -QqR -QqZ -Qrh -Qrn +Qry +QrG +QrN +alu apS apS apS @@ -81321,7 +81408,7 @@ bGi aoV aoV bCq -QsE +Qti bCq bCq bTu @@ -81527,7 +81614,7 @@ avZ axp ayD azI -Qra +QrH aBU aDt aDt @@ -81580,7 +81667,7 @@ aoV bCq bHE bPU -QsI +Qtm bTx bCq bVE @@ -81783,15 +81870,15 @@ aag avY axo ayB -QqP -Qrb -Qri +Qrz +QrI +aBW aDv -Qrs -Qry -QrE -QrK -QrN +aEP +aGe +Qse +Qsk +Qsn aLE aMS aOt @@ -81838,20 +81925,20 @@ bCq bPY cOw bCq -QsM -QsM -QsM -QsM -QsM -QtH -QsM -QsM -QsM -QsM -QsM -QsM -QsM -QsM +Qtq +Qtx +QtF +QtP +Qua +Qul +Quw +QuG +cjn +cjn +cjn +cjn +cjn +cjn bUs bLv aaa @@ -82040,15 +82127,15 @@ aag avY axo ayB -QqT -Qrc -Qrj -Qro -Qrt -Qrz -QrF -QrL +QrA +QrJ QrO +QrS +QrV +QrZ +Qsf +Qsl +Qso aLE aMS aOi @@ -82095,20 +82182,20 @@ bCq bPX bRg bRg -QsM -QsU +Qtr +Qty bVG -Qtm -Qtx -QsU -QtT -QsM -QsU -Quq +QtQ +Qub +Qum +Qux +QuH +bcU +QuU bVG -QsU -QuM -QsM +bcU +Qvq +cjn bUs bLv aaa @@ -82123,16 +82210,16 @@ aaa aaa aaf aaf -QuZ +QvD aaa -Qvi +QvM bij bij bij bij bij bij -QvB +Qwk btG btG aaa @@ -82297,15 +82384,15 @@ aag avY axo ayB -QqU -Qrd -Qrk +QrB +QrK +QrP aDt -Qru -QrA -QrG -QrM -QrN +QrW +Qsa +Qsg +Qsm +aKx aLE aMS aOi @@ -82352,20 +82439,20 @@ bLv bQa bHE bHE -QsM -QsV -Qtc -Qtn -Qty -QtJ -Qty -Que -Qty -Qty -Qux -Quu -QuN -QsM +Qts +Qtz +QtG +QtR +Quc +Qun +Quy +QuI +QuO +QuV +Qvb +Qvk +Qvr +cjn bUs bLv aaf @@ -82377,19 +82464,19 @@ cjJ cjJ cjJ cjJ -QuT +Qvx bij bij crn bij -Qvj -Qvo -Qvr -Qvw +QvN +QvS +QvV +Qwa bkI bgN bgN -QvC +Qwl bgN btG Qoi @@ -82592,7 +82679,7 @@ bjv btv buc bxz -bBa +QoP bwV byy bBa @@ -82609,20 +82696,20 @@ bLv bPZ bHE bHE -QsP -QsW -Qtd -Qto -Qtz -QtK -QtV -Quf -QtV -Qus -Quy +Qtt +QtA +QtH +QtS +Qud +Quo +Quz +QuJ +QuP +QuW +Qvc cCa -QsU -QsM +bcU +cjn bUs bLv aaa @@ -82636,17 +82723,17 @@ cov cpj cpS btG -QuW -Qva +QvA +QvE btG -Qvk +QvO bsc -Qvs -Qvx +QvW +Qwb bgN -bih -big -bii +Qwf +Qwi +Qwm bgN btG aaa @@ -82866,20 +82953,20 @@ bLv bHE bHE bSs -QsM -QsX -Qte -Qtp -QtA -Qte -QsU -Qug -Qum +Qtu +QtB +QtI +QtT +Que +Qup +bcU +QuK +QuQ cCa -Quz -QuH -QuO -QsM +Qvd +Qvl +Qvs +cjn bUs bLv aaa @@ -82894,16 +82981,16 @@ cpl cpU btF bsc -Qvb +QvF btF bsc -Qvp -Qvs -Qvy +QvT +QvX +Qwc bgN -big +Qwg bgN -bkZ +Qwn bgN btG Qoi @@ -83103,10 +83190,10 @@ bnz bpA bbR bkM -bqs +bbR bud -bxy -bvG +QoO +Qtg bAZ bGm bzF @@ -83123,20 +83210,20 @@ bCq bHE bRh bLu -QsM -QsY -Qtf -Qtq -QtB -QtM -QtW -QsM -QsU -Qut -Quz -QuH -QuP -QsM +Qtv +QtC +QtJ +QtU +Quf +Quq +QuA +QuL +bcU +QuX +Qve +Qvm +Qvt +cjn bUs bLv aaf @@ -83150,17 +83237,17 @@ cow cpk cpT btG -QuX -Qvc +QvB +QvG btG -Qvl +QvP bsc -Qvs -Qvx +QvY +Qwd bgN -bii -big -bih +Qwh +Qwj +Qwo bgN btG aaa @@ -83360,7 +83447,7 @@ boS bfm bNK bkN -bml +bfm bwe bwe bwd @@ -83380,20 +83467,20 @@ bCq bOK bCq bCq -QsM -QsZ -Qtg -Qtr -QtC -QtN -QsM -QsM -QsU -cCa +Qtw +QtD +QtK +QtV +Qug +Qur QuB -QuJ +cjn +bcU cCa -QsM +Qvf +Qvn +cCa +cjn bUs bLv aaa @@ -83405,19 +83492,19 @@ cnq cnP coz cpn -QuU -QuV -QuV -Qvd -QuV -Qvm -Qvq -Qvv -QvA +Qvy +Qvz +QvC +QvH +QvL +QvQ +QvU +QvZ +Qwe bmw bgN bgN -QvD +Qwp bgN btG aaa @@ -83557,10 +83644,10 @@ abc aea aeH aft -QvG -QvH -QvI -QvO +QpT +QpU +QpW +Qqc abc Qoi Qoi @@ -83617,7 +83704,7 @@ boR bqs bbR bkM -bNM +bbR bwd bxB bvL @@ -83638,19 +83725,19 @@ bHE bLv aaa bLv -Qta -Qtg -QsM -QsM -QsM -QsM -QsU -QsU -QsU +QtE +QtL +QtW +Quh +Qus QuC +bcU +bcU +bcU +Qvg cCa -QuQ -QsM +Qvu +cjn bUs bLv aaa @@ -83665,16 +83752,16 @@ cpm cjJ aaf aaf -Qve +QvI aaa -Qvn +QvR bgO bgO bgO bgO bgO bgO -QvE +Qwq btG btG Qoi @@ -83816,8 +83903,8 @@ aeJ afw abc abc -QvJ -QvP +QpX +Qqd abc aaf aaf @@ -83895,19 +83982,19 @@ bHE bLv aaf bLv -Qta -Qtg -Qtt -QtE -QtP -QtZ -QsU -Qum -Quu +bUt +QtM +QtX +Qui +Qut QuD -QsU -QsU -QsM +bcU +QuR +QuY +Qvh +bcU +bcU +cjn bUs bLv aaf @@ -83922,7 +84009,7 @@ cjJ cjJ aaa aaa -Qve +QvJ aaf aaa aaa @@ -84073,8 +84160,8 @@ aeI afv agf abc -QvK -QvQ +QpY +Qqe abc aiT aiT @@ -84152,19 +84239,19 @@ bLv bCq aaa bLv -Qta -Qtg -Qtu -QtF -QtQ -QsM -Qui -Quo -Quv +bUt +QtN +QtY +Quj +Quu QuE -QuK -QuR -QsM +QuM +QuS +QuZ +Qvi +Qvo +Qvv +cjn bUs bCq aaa @@ -84179,7 +84266,7 @@ cpo cjJ aaa aaa -Qve +QvK aaf Qoi aaa @@ -84330,9 +84417,9 @@ aeL afy agh abc -QvL -QvR -QvU +QpZ +Qqf +Qqi aiV ajs akb @@ -84410,17 +84497,17 @@ aaa aaa bTB bUv -Qtk -Qtv -Qtv -Qtv -Qtv -Qtv -Qtv -Qtv -Qtv -Qtv -Qtv +QtO +QtZ +Quk +Quv +QuF +QuN +QuT +Qva +Qvj +Qvp +Qvw car bUs bCq @@ -84587,9 +84674,9 @@ aeK afx agg abc -QvM -QvS -QvV +Qqa +Qqg +Qqj aiV ajr aka @@ -84844,9 +84931,9 @@ aeN afA afA afA -QvN -QvT -QvW +Qqb +Qqh +Qqk aiV aju akd @@ -85900,9 +85987,9 @@ aAW aCa aDB aDI -QvX -QvZ -Qwb +azW +azW +azW ayW aLX aJq @@ -86395,7 +86482,7 @@ akj agj agj agj -agj +aiX aiX anQ aov @@ -86908,7 +86995,7 @@ auj akl akO alx -Qqb +QqH amg aiX anw @@ -86928,8 +87015,8 @@ aBq aBr aDE aFc -QvY -Qwa +azW +azW aJf ayW aJr @@ -87420,9 +87507,9 @@ aiF agj ajD akm -QpW +QqC aly -Qqc +QqI amQ aiX anw @@ -87679,7 +87766,7 @@ aja akl akP alx -Qqb +amh ami aiX anw @@ -87717,7 +87804,7 @@ aZP bbh bcc bdd -QrS +Qsr bfr bbX bif @@ -87933,7 +88020,7 @@ agP agP aiz ajg -QpR +Qqx akQ agj agj @@ -87976,7 +88063,7 @@ bbk bbk bbk bfs -QrT +Qss aZM aZM aaf @@ -88171,7 +88258,7 @@ aaa aaa aaf aaf -QoM +QoY aaf aai abi @@ -88193,7 +88280,7 @@ ajb ajF akN alw -Qqd +QqJ amQ aiX anw @@ -88233,19 +88320,19 @@ bce bdf beb aYv -QrU -Qse +Qst +QsD aaf aaf Qoi aaa Qoi aaa -Qso -Qso -Qso -Qso -Qso +QsQ +bsb +bsb +bsb +bsb aXf aJq byU @@ -88428,7 +88515,7 @@ aaf aaf aaf aaf -abY +aaS aaR aaZ aaZ @@ -88444,16 +88531,16 @@ agn agR agn agR -QpF +Qql agn -QpK +Qqq akv -QpX -QpZ +QqD +QqF aww amk aiX -anQ +QqY aov aph aqb @@ -88490,19 +88577,19 @@ aZR bbm bec bfu -QrV +Qsu aBb aBb bmu aBb aBb -Qsk +QsM aaa -Qso -Qsq -Qsx -QsA -Qso +bsb +QsS +QsZ +Qtc +bsb aXf aJq bBi @@ -88685,26 +88772,26 @@ aaa aaa aaa aaf -QoM +QoZ aaf aaZ -adi -Qpf -Qpo +Qpk +Qpv +QpE aaZ cpg -QpB acv -QpC +adi +QpR aaZ aeW -QpE +QpV ahv ahQ -QpG +Qqm aiI ajI -QpS +Qqy akQ agj agj @@ -88747,22 +88834,22 @@ aZR aZR aZR bft -QrU +Qsv aBa -aBT +QsF bmv -aEN -aGb +QsI +bnT bpg aaa -Qso -Qsr +bsb +QsT buP bwm bxH -aXf +byS aJq -Qwc +Qth bCs bCs bCs @@ -88942,29 +89029,29 @@ aaa aaa aaa aaf -QoM +Qpa aaf aaZ -adi -Qpg -Qpo +Qpl +Qpw +QpF aaZ acl cxA acL -QpD +QpS aaZ agp agT ahx ahS aiK -QpJ -QpK +Qqp +Qqr akm akT aly -Qqe +QqK amQ aiX anw @@ -89004,16 +89091,16 @@ bbm bdh bee bfv -QrU +Qsw aBa -Qsg +big aEM aEM aGa bph bqF bsd -Qss +QsU buQ bwn bxI @@ -89199,14 +89286,14 @@ aaa aaa aaa aaf -QoM +Qpb aaf aaZ -adi -Qph -Qpq +Qpm +Qpx +QpG aaZ -Qpw +QpM adk adK cqG @@ -89221,19 +89308,19 @@ ajI akl akS alx -Qqb +amh amp aiX anS aoy -QqC -QqF -QqF -QqF -QqF -QqF -QqF -QqN +Qrj +Qrm +Qro +Qrp +Qrq +Qrr +Qrs +Qru axB anz anz @@ -89261,20 +89348,20 @@ bcf bdg bed bfv -QrU +Qsx aBa aBV -alu -Qsi +bkZ +QsJ bnU aHG bqE -Qsp -Qst -Qsy -QsB -QsD -aNr +QsR +QsV +Qta +Qtd +Qtf +bvW bAf bBp aHP @@ -89456,14 +89543,14 @@ aaa aaa aaa aaf -QoM +Qpc aaf aaZ -adi -Qpg -Qpr +Qpn +Qpy +QpH aaZ -Qpx +QpN acM adQ cwM @@ -89472,16 +89559,16 @@ agr agU ahy ahX -QpH +Qqn aiN -QpM +Qqs akq akQ agj agj agj aiX -Qqs +QqZ aoz apm aqd @@ -89518,16 +89605,16 @@ bbm bdh bef bfv -QrU +Qsy aBa -Qsh +QsG aEO -Qsj +QsK bnV -Qsl -Qsn +QsN +QsP bsf -Qsu +QsW buS bwp bxK @@ -89713,14 +89800,14 @@ aaa aaa aaa aaf -QoM +Qpd aaf aaZ -QoY -Qpj -Qpr +Qpo +Qpz +QpI aaZ -Qpy +QpO coS aet cxA @@ -89731,15 +89818,15 @@ ahz aie agt aiM -QpN +Qqt akp akU alz aml amT aiX -Qqt -Qqz +Qra +Qrg apl aqc aqc @@ -89775,20 +89862,20 @@ aZR aZR aZR bfw -QrU +Qsz aBa -aBW +QsH bjy -aEP -aGe +QsL +bnW bpi aaa -Qso -Qsv +bsb +QsX buR bwo bxJ -aNs +bwb aJq bBr bCv @@ -89970,14 +90057,14 @@ aaa aaa aaa aaf -QoM +Qpe aaf aaZ -QoZ -Qpk -Qpt +Qpp +QpA +QpJ abQ -Qpz +QpP adj arc blT @@ -89986,17 +90073,17 @@ cml agV cxk aig -QpI +Qqo agn -QpO -QpT +Qqu +Qqz akV alB amn amV -Qqn +QqT anB -Qqj +Qrh aod aqf ahT @@ -90032,19 +90119,19 @@ aZR bbm beh bfx -Qsb +QsA aBc aBc bgR aBc aBc -Qsm +QsO aaa -Qso -Qsw -Qsz -QsC -Qso +bsb +QsY +Qtb +Qte +bsb aJq aJq bBu @@ -90227,14 +90314,14 @@ aaa aaa aaa aaf -QoM +Qpf aaf aaZ -Qpa +Qpq ack -Qpu +QpK abN -QpA +QpQ acF acF aes @@ -90245,13 +90332,13 @@ ahB aHp agn agn -QpP -QpU +Qqv +QqA amS alA -Qqf +QqL amm -Qqo +QqU anT anT aod @@ -90289,19 +90376,19 @@ bcg aZU beg aYB -QrU -Qse +QsB +QsE aaf aaf Qoi aaa Qoi aaa -Qso -Qso -Qso -Qso -Qso +bsb +bsb +bsb +bsb +bsb aJq aJq bBt @@ -90484,12 +90571,12 @@ aaa aaa aaa aaf -QoM +Qpg aaf aaZ -Qpb -Qpl -Qpv +Qpr +QpB +QpL aci acm cpA @@ -90506,10 +90593,10 @@ ajJ akr akX alC -Qqg -Qqg -Qqg -Qqg +QqM +amX +amX +amX aoB aod aqe @@ -90546,7 +90633,7 @@ bbp bbp bbp bfz -Qsd +QsC aZV aZV aaf @@ -90745,7 +90832,7 @@ aaZ aaZ aaZ aaZ -Qpm +QpC avB aaZ aaZ @@ -90762,14 +90849,14 @@ ajd ajb ahY akX -Qqa -amo -Qqg -Qqg -Qqu -QqB -QqD QqG +amo +amX +amX +Qrb +Qri +Qrk +Qrn arf apY ate @@ -90999,9 +91086,9 @@ aaa aaa aaa abp -QoV -QoV -Qpc +Qph +Qpi +Qps abO abO acO @@ -91016,14 +91103,14 @@ ahA ahZ adR aiQ -QpK +Qqw akt -QpY +QqE anw -Qqa -Qqj +QqN +QqP anB -Qqv +Qrc aoD aod aqe @@ -91277,10 +91364,10 @@ ajK aks akY anA -Qqa -Qqk +QqO +QqQ amo -Qqv +Qrd aoC aod aqe @@ -91515,11 +91602,11 @@ aaa abp abO abO -Qpd -Qpd -Qpd -Qpd -Qpd +Qpt +QpD +acq +acq +acq abO aew afe @@ -91531,13 +91618,13 @@ aia aiP aiR ajB -QpV +QqB aiX akz alf -Qql -Qql -Qqx +QqR +QqV +Qre aoF apo aqh @@ -91792,11 +91879,11 @@ aku aiX alE amq -Qqm -Qqq -Qqy +QqS +QqW +Qrf aoE -QqE +Qrl aqg aun asf @@ -92028,12 +92115,12 @@ aaa aaa abp aco -QoX -Qpe +Qpj +Qpu abR -Qpe -Qpe -Qpe +abP +abP +abP abl abp abp @@ -93876,7 +93963,7 @@ aCr aCr aJC bYP -QrR +bbx aJC aQg aJC @@ -95191,7 +95278,7 @@ bvh bzS bBc bCJ -buk +QoU cCp bvd bKH @@ -96698,7 +96785,7 @@ aGJ aIe aJC aJC -QrP +Qsp aJC aJC aJC @@ -97983,7 +98070,7 @@ aGL aIg aJH aKR -QrQ +Qsq aMB aJC aRA @@ -98018,7 +98105,7 @@ bvj bCN bEa bFA -bGS +QoQ bIm bJD bKK @@ -98238,7 +98325,7 @@ aaa alP aGL aIe -aJC +aJI aJI aJI aJI @@ -99268,7 +99355,7 @@ aGL avI aJK aKV -QvF +QoT aMl aMF aJI @@ -100046,7 +100133,7 @@ aJI aJI aSP aUh -aJI +QoM aJI aJI aJI @@ -100609,7 +100696,7 @@ bZQ caP cbO ccJ -cdM +bLS bLS cfp cge @@ -100827,7 +100914,7 @@ aYV aYV bfO bfS -biC +biD bkd bfS cTO @@ -101598,8 +101685,8 @@ aYV bez bfP bfS -biD -bke +bfS +bfS bfS cTO bmZ @@ -101855,9 +101942,9 @@ bci beB bfS bfS -bfS -bfS -bfS +QoV +QoW +QoX cTO bmZ bon @@ -102897,7 +102984,7 @@ buU byf bzu bAz -bBT +bzu bDb bEm bEm @@ -103893,7 +103980,7 @@ aFu aHc aIw aJS -cAM +aJS aMJ aNP aOS @@ -106699,7 +106786,7 @@ aaf aaf aaf alP -Qqr +QqX alP anf alP diff --git a/_maps/map_files/CitadelStation/CitadelStation-1.2.2.dmm b/_maps/map_files/CitadelStation/CitadelStation-1.2.2.dmm index 57a019516a..935e2445a2 100644 --- a/_maps/map_files/CitadelStation/CitadelStation-1.2.2.dmm +++ b/_maps/map_files/CitadelStation/CitadelStation-1.2.2.dmm @@ -36799,7 +36799,7 @@ }, /area/hallway/primary/starboard) "bze" = ( -/obj/machinery/r_n_d/destructive_analyzer, +/obj/machinery/rnd/destructive_analyzer, /turf/open/floor/plasteel/purple, /area/toxins/lab) "bzf" = ( @@ -36807,7 +36807,7 @@ /turf/open/floor/plasteel/purple, /area/toxins/lab) "bzg" = ( -/obj/machinery/r_n_d/protolathe, +/obj/machinery/rnd/protolathe, /turf/open/floor/plasteel/purple, /area/toxins/lab) "bzh" = ( @@ -37256,7 +37256,7 @@ /turf/open/floor/plasteel/purple, /area/toxins/lab) "bAi" = ( -/obj/machinery/r_n_d/circuit_imprinter, +/obj/machinery/rnd/circuit_imprinter, /obj/item/reagent_containers/glass/beaker/sulphuric, /turf/open/floor/plasteel/purple, /area/toxins/lab) @@ -41880,7 +41880,7 @@ /turf/open/floor/plasteel/black, /area/ai_monitored/turret_protected/aisat) "bJa" = ( -/obj/machinery/r_n_d/server/robotics, +/obj/machinery/rnd/server, /turf/open/floor/circuit{ name = "Server Base"; initial_gas_mix = "n2=500;TEMP=80" @@ -43179,7 +43179,7 @@ name = "AI Maintenance" }) "bLq" = ( -/obj/machinery/r_n_d/server/core, +/obj/machinery/rnd/server, /turf/open/floor/circuit{ name = "Server Base"; initial_gas_mix = "n2=500;TEMP=80" @@ -47412,7 +47412,7 @@ /turf/open/floor/plasteel, /area/assembly/robotics) "bTL" = ( -/obj/machinery/r_n_d/circuit_imprinter, +/obj/machinery/rnd/circuit_imprinter, /turf/open/floor/plasteel, /area/assembly/robotics) "bTM" = ( diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 0479e1ec28..2852c76257 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -1059,10 +1059,8 @@ desc = "A thin layer of dust coating the floor."; name = "dust" }, -/obj/machinery/door/airlock{ - glass = 1; - name = "Dormitory"; - opacity = 0 +/obj/machinery/door/airlock/glass{ + name = "Dormitory" }, /turf/open/floor/plasteel/neutral, /area/shuttle/abandoned) @@ -1419,10 +1417,8 @@ desc = "A thin layer of dust coating the floor."; name = "dust" }, -/obj/machinery/door/airlock{ - glass = 1; - name = "Crew Quarters"; - opacity = 0 +/obj/machinery/door/airlock/glass{ + name = "Crew Quarters" }, /turf/open/floor/plasteel/neutral/side{ dir = 1 @@ -10106,7 +10102,7 @@ /turf/open/floor/plasteel/neutral, /area/janitor) "avA" = ( -/obj/vehicle/janicart, +/obj/vehicle/ridden/janicart, /obj/machinery/status_display{ pixel_y = 32 }, @@ -10242,7 +10238,7 @@ /area/crew_quarters/toilet/auxiliary) "avM" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Fore Primary Hallway" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -10257,7 +10253,7 @@ /area/hallway/primary/fore) "avN" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Fore Primary Hallway" }, /obj/effect/turf_decal/stripes/line{ @@ -10271,7 +10267,7 @@ "avO" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Fore Primary Hallway" }, /obj/effect/turf_decal/stripes/line{ @@ -13584,10 +13580,13 @@ /turf/open/floor/plasteel, /area/quartermaster/storage) "aDg" = ( -/obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, /turf/open/floor/plasteel, /area/quartermaster/storage) "aDh" = ( @@ -16518,13 +16517,12 @@ /turf/open/floor/wood, /area/hallway/secondary/service) "aIS" = ( -/obj/item/device/radio/intercom{ - name = "Station Intercom"; - pixel_x = -26 - }, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 }, +/obj/effect/turf_decal/loading_area{ + dir = 4 + }, /turf/open/floor/plasteel/neutral/corner{ dir = 1 }, @@ -17253,16 +17251,16 @@ /obj/machinery/newscaster{ pixel_x = -32 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aKz" = ( /obj/structure/chair/stool/bar, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aKA" = ( /obj/structure/chair/stool/bar, /obj/effect/landmark/start/assistant, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aKB" = ( /obj/structure/chair/stool/bar, @@ -17270,7 +17268,7 @@ name = "Station Intercom"; pixel_x = 26 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aKC" = ( /turf/closed/wall, @@ -17467,7 +17465,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Garden" }, /turf/open/floor/plasteel, @@ -17762,6 +17760,7 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 }, +/obj/structure/closet/secure_closet/personal/cabinet, /turf/open/floor/wood, /area/hallway/secondary/service) "aLE" = ( @@ -17788,9 +17787,6 @@ /turf/open/floor/wood, /area/hallway/secondary/service) "aLH" = ( -/obj/structure/extinguisher_cabinet{ - pixel_x = -26 - }, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 }, @@ -17828,10 +17824,10 @@ /obj/structure/extinguisher_cabinet{ pixel_x = -26 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aLL" = ( -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aLM" = ( /obj/machinery/airalarm{ @@ -17841,7 +17837,7 @@ /obj/machinery/light{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aLN" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -18482,15 +18478,15 @@ /area/crew_quarters/bar/atrium) "aNg" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aNh" = ( /obj/structure/chair/stool, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aNi" = ( /obj/effect/landmark/event_spawn, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aNj" = ( /obj/effect/spawner/structure/window/reinforced, @@ -18800,7 +18796,7 @@ /turf/open/floor/engine/vacuum, /area/maintenance/disposal/incinerator) "aNS" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ autoclose = 0; frequency = 1449; heat_proof = 1; @@ -18827,7 +18823,7 @@ /turf/open/floor/engine, /area/maintenance/disposal/incinerator) "aNU" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ autoclose = 0; frequency = 1449; heat_proof = 1; @@ -19177,12 +19173,12 @@ "aOI" = ( /obj/structure/chair/stool, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aOJ" = ( /obj/structure/table/wood, /obj/item/storage/pill_bottle/dice, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aOK" = ( /obj/item/reagent_containers/food/condiment/saltshaker{ @@ -19193,12 +19189,12 @@ pixel_x = -8 }, /obj/structure/table/wood, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aOL" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/drinks/soda_cans/cola, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aOM" = ( /obj/structure/table, @@ -19968,7 +19964,7 @@ dir = 5 }, /obj/structure/chair/stool, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aQs" = ( /obj/structure/table/wood, @@ -19976,7 +19972,7 @@ dir = 4 }, /obj/item/reagent_containers/food/drinks/bottle/orangejuice, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aQt" = ( /obj/structure/table/wood, @@ -19984,7 +19980,7 @@ dir = 4 }, /obj/item/reagent_containers/food/snacks/cheesiehonkers, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aQu" = ( /obj/structure/table/wood, @@ -19992,27 +19988,27 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aQv" = ( /obj/structure/chair/stool, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aQw" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aQx" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Atrium" }, /obj/effect/turf_decal/stripes/line{ @@ -20829,11 +20825,11 @@ /area/crew_quarters/bar/atrium) "aSb" = ( /obj/effect/landmark/lightsout, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aSc" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Atrium" }, /obj/effect/turf_decal/stripes/line{ @@ -21110,7 +21106,7 @@ id = "permacell3"; name = "Cell Shutters" }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ id_tag = "permabolt3"; name = "Cell 3" }, @@ -21128,7 +21124,7 @@ id = "permacell2"; name = "Cell Shutters" }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ id_tag = "permabolt2"; name = "Cell 2" }, @@ -21148,7 +21144,7 @@ id = "permacell1"; name = "Cell Shutters" }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ id_tag = "permabolt1"; name = "Cell 1" }, @@ -21712,37 +21708,37 @@ "aTH" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/drinks/coffee, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aTI" = ( /obj/structure/table/wood, /obj/item/device/paicard, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aTJ" = ( /obj/structure/table/wood, /obj/item/clothing/head/hardhat/cakehat, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aTK" = ( /obj/structure/chair/stool, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 6 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aTL" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aTM" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Atrium" }, /obj/effect/turf_decal/stripes/line{ @@ -22572,27 +22568,27 @@ "aVq" = ( /obj/structure/chair/stool, /obj/effect/landmark/start/assistant, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aVr" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/snacks/chips, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aVs" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/drinks/soda_cans/dr_gibb, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aVt" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/drinks/britcup, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aVu" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/chair/stool, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aVv" = ( /obj/structure/cable/white{ @@ -22746,7 +22742,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/quartermaster/storage) +/area/quartermaster/office) "aVH" = ( /obj/structure/cable/white{ icon_state = "4-8" @@ -23473,13 +23469,13 @@ pixel_x = -26; pixel_y = -26 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aXc" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aXd" = ( /obj/structure/cable/white{ @@ -23603,7 +23599,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/quartermaster/storage) +/area/quartermaster/office) "aXr" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -24236,7 +24232,7 @@ dir = 4; name = "service camera" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aYF" = ( /obj/machinery/firealarm{ @@ -24246,7 +24242,7 @@ /obj/machinery/light{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aYG" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -24311,6 +24307,9 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, +/obj/effect/turf_decal/loading_area{ + dir = 1 + }, /turf/open/floor/plasteel/neutral, /area/quartermaster/office) "aYP" = ( @@ -25201,21 +25200,21 @@ pixel_x = -32 }, /obj/item/twohanded/required/kirbyplants/random, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "baE" = ( /obj/structure/chair/stool/bar, /obj/structure/disposalpipe/segment{ dir = 6 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "baF" = ( /obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk{ dir = 8 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "baG" = ( /obj/structure/extinguisher_cabinet{ @@ -28091,12 +28090,19 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/quartermaster/miningoffice) "bgS" = ( /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, /turf/open/floor/plasteel, /area/quartermaster/miningoffice) "bgT" = ( @@ -29003,6 +29009,7 @@ /obj/machinery/newscaster/security_unit{ pixel_y = 32 }, +/obj/item/twohanded/required/kirbyplants/random, /turf/open/floor/plasteel/red/side{ dir = 1 }, @@ -29011,7 +29018,8 @@ /obj/structure/cable/white{ icon_state = "1-8" }, -/obj/item/twohanded/required/kirbyplants/random, +/obj/effect/turf_decal/stripes/box, +/obj/machinery/rnd/protolathe/department/security, /turf/open/floor/plasteel/red/side{ dir = 1 }, @@ -29592,7 +29600,6 @@ /turf/open/floor/plasteel/neutral, /area/quartermaster/miningoffice) "bjV" = ( -/obj/machinery/photocopier, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/purple/side{ dir = 4 @@ -29919,6 +29926,7 @@ /area/security/main) "bkv" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/effect/turf_decal/loading_area, /turf/open/floor/plasteel/neutral, /area/security/main) "bkw" = ( @@ -30548,9 +30556,7 @@ /area/quartermaster/miningoffice) "blP" = ( /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/loading_area{ - dir = 4 - }, +/obj/machinery/photocopier, /turf/open/floor/plasteel, /area/quartermaster/miningoffice) "blQ" = ( @@ -30564,9 +30570,6 @@ /obj/structure/cable/white{ icon_state = "1-4" }, -/obj/effect/turf_decal/loading_area{ - dir = 8 - }, /turf/open/floor/plasteel, /area/quartermaster/miningoffice) "blS" = ( @@ -31215,7 +31218,7 @@ /area/hallway/secondary/service) "bno" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Service Foyer" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -31260,7 +31263,7 @@ "bns" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Fore Primary Hallway" }, /obj/effect/turf_decal/stripes/line{ @@ -31273,7 +31276,7 @@ /area/hallway/primary/fore) "bnt" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Fore Primary Hallway" }, /obj/structure/cable/white{ @@ -31341,10 +31344,16 @@ /turf/open/floor/plasteel, /area/hallway/primary/fore) "bnz" = ( -/obj/machinery/mineral/ore_redemption, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/table/reinforced, +/obj/machinery/door/firedoor, +/obj/item/folder/yellow, +/obj/item/pen, +/obj/machinery/door/window/southleft{ + dir = 1; + req_access_txt = "48" + }, /obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/quartermaster/miningoffice) "bnA" = ( @@ -33362,7 +33371,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/bot, +/obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/vault{ dir = 5 }, @@ -34454,7 +34463,7 @@ /area/security/main) "btw" = ( /obj/effect/landmark/secequipment, -/obj/effect/turf_decal/bot, +/obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/vault{ dir = 5 }, @@ -34965,7 +34974,13 @@ /turf/open/floor/plasteel, /area/security/execution/transfer) "buA" = ( -/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, /turf/open/floor/plasteel, /area/security/execution/transfer) "buB" = ( @@ -35134,7 +35149,7 @@ /obj/machinery/light/small{ dir = 4 }, -/obj/effect/turf_decal/bot, +/obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/vault{ dir = 5 }, @@ -35766,7 +35781,7 @@ pixel_x = 32 }, /obj/effect/landmark/secequipment, -/obj/effect/turf_decal/bot, +/obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/vault{ dir = 5 }, @@ -41591,7 +41606,6 @@ pixel_x = -3; pixel_y = 3 }, -/obj/item/circuitboard/machine/protolathe, /obj/item/circuitboard/machine/mechfab, /obj/item/circuitboard/machine/circuit_imprinter{ pixel_x = 3; @@ -44827,6 +44841,12 @@ }, /area/hallway/primary/starboard) "bNi" = ( +/obj/structure/sign/securearea{ + desc = "A warning sign which reads 'HIGH VOLTAGE'"; + icon_state = "shock"; + name = "HIGH VOLTAGE"; + pixel_x = 32 + }, /obj/machinery/light{ dir = 4 }, @@ -48542,7 +48562,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Port Primary Hallway" }, /obj/effect/turf_decal/stripes/line{ @@ -48704,7 +48724,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Starboard Primary Hallway" }, /obj/structure/disposalpipe/segment{ @@ -48911,6 +48931,12 @@ /turf/open/floor/plasteel/neutral, /area/hallway/primary/starboard) "bVj" = ( +/obj/structure/sign/securearea{ + desc = "A warning sign which reads 'HIGH VOLTAGE'"; + icon_state = "shock"; + name = "HIGH VOLTAGE"; + pixel_x = 32 + }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 10 }, @@ -48974,7 +49000,7 @@ /turf/open/floor/plating, /area/ai_monitored/security/armory) "bVp" = ( -/obj/vehicle/secway, +/obj/vehicle/ridden/secway, /turf/open/floor/plasteel/vault{ dir = 8 }, @@ -49689,7 +49715,7 @@ /area/hallway/primary/port) "bWK" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Port Primary Hallway" }, /obj/effect/turf_decal/stripes/line{ @@ -49960,7 +49986,7 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Starboard Primary Hallway" }, /obj/effect/turf_decal/stripes/line{ @@ -50915,7 +50941,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Port Primary Hallway" }, /obj/effect/turf_decal/stripes/line{ @@ -51103,7 +51129,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Starboard Primary Hallway" }, /obj/structure/disposalpipe/segment{ @@ -51807,7 +51833,7 @@ /turf/open/floor/plating, /area/library) "caI" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Library Access" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -51816,7 +51842,7 @@ }, /area/library) "caJ" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Library Access" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -54321,12 +54347,12 @@ /turf/open/floor/plasteel, /area/engine/engineering) "cfH" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 6 - }, /obj/effect/turf_decal/stripes/corner{ dir = 1 }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, /turf/open/floor/plasteel, /area/engine/engineering) "cfI" = ( @@ -54880,15 +54906,15 @@ /turf/open/floor/wood, /area/lawoffice) "cgP" = ( -/obj/structure/cable/white{ - icon_state = "1-2" - }, /obj/machinery/newscaster/security_unit{ pixel_x = -32 }, /obj/machinery/computer/secure_data{ dir = 4 }, +/obj/structure/cable/white{ + icon_state = "1-4" + }, /turf/open/floor/plasteel/red/side{ dir = 8 }, @@ -54897,15 +54923,21 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, /turf/open/floor/plasteel/neutral, /area/security/brig) "cgR" = ( -/obj/structure/cable/white{ - icon_state = "1-2" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, /turf/open/floor/plasteel/red/side{ dir = 4 }, @@ -54914,15 +54946,16 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/red/corner{ - dir = 1 +/obj/structure/cable/white{ + icon_state = "4-8" }, +/turf/open/floor/plasteel, /area/security/brig) "cgT" = ( -/obj/structure/cable/white{ - icon_state = "2-4" - }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/obj/structure/cable/white{ + icon_state = "4-8" + }, /turf/open/floor/plasteel, /area/security/brig) "cgU" = ( @@ -55711,9 +55744,6 @@ /turf/open/floor/wood, /area/lawoffice) "ciz" = ( -/obj/structure/cable/white{ - icon_state = "1-4" - }, /obj/structure/table/reinforced, /obj/item/paper_bin, /obj/machinery/light/small{ @@ -55728,9 +55758,6 @@ }, /area/security/brig) "ciA" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, /obj/structure/sign/nanotrasen{ pixel_y = -32 }, @@ -55748,12 +55775,6 @@ /turf/open/floor/plasteel/red/side, /area/security/brig) "ciB" = ( -/obj/structure/cable/white{ - icon_state = "1-4" - }, -/obj/structure/cable/white{ - icon_state = "4-8" - }, /obj/structure/extinguisher_cabinet{ pixel_y = -26 }, @@ -55766,27 +55787,20 @@ }, /area/security/brig) "ciC" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/closed/wall, /area/security/brig) "ciD" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/red/corner, +/turf/open/floor/plasteel/red/side{ + dir = 10 + }, /area/security/brig) "ciE" = ( -/obj/structure/cable/white{ - icon_state = "1-8" - }, /obj/structure/chair{ dir = 1 }, @@ -56145,7 +56159,7 @@ /turf/open/floor/plasteel/grimy, /area/library) "cjv" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Library Access" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -56375,7 +56389,7 @@ /area/security/courtroom) "cjX" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Courtroom"; req_access_txt = "42" }, @@ -56808,7 +56822,7 @@ /turf/open/floor/plasteel/grimy, /area/library) "ckU" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Library Access" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -60289,7 +60303,7 @@ /area/hallway/primary/central) "cso" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Command Hallway" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -61054,7 +61068,7 @@ icon_state = "4-8" }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Command Hallway" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -61761,14 +61775,14 @@ }, /area/maintenance/port) "cvi" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Library Game Room" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/grimy, /area/library) "cvj" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Library Game Room" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -61971,7 +61985,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Starboard Auxiliary Hallway" }, /obj/structure/disposalpipe/segment{ @@ -62629,7 +62643,7 @@ /area/hallway/primary/central) "cwZ" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Starboard Auxiliary Hallway" }, /obj/effect/turf_decal/stripes/line{ @@ -63397,7 +63411,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Starboard Auxiliary Hallway" }, /obj/structure/disposalpipe/segment{ @@ -64376,24 +64390,35 @@ /turf/open/floor/plating, /area/engine/engineering) "cAL" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/start/station_engineer, -/turf/open/floor/plasteel/neutral, +/obj/machinery/rnd/protolathe/department/engineering, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/plasteel/caution{ + dir = 1 + }, /area/engine/engineering) "cAM" = ( -/obj/structure/table/reinforced, -/obj/item/paper_bin, -/obj/item/pen, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, +/obj/effect/landmark/start/station_engineer, +/obj/effect/turf_decal/loading_area, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel/caution{ + dir = 1 + }, /area/engine/engineering) "cAN" = ( -/obj/structure/table/reinforced, -/obj/item/stack/packageWrap, -/obj/item/hand_labeler, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, +/obj/machinery/computer/rdconsole/production{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/turf/open/floor/plasteel/caution{ + dir = 1 + }, /area/engine/engineering) "cAO" = ( /obj/structure/cable/white{ @@ -64521,20 +64546,11 @@ /area/library) "cBc" = ( /obj/structure/table/wood, -/obj/item/storage/pill_bottle/dice, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/carpet, /area/library) "cBd" = ( /obj/structure/table/wood, -/obj/item/toy/cards/deck/cas{ - pixel_x = -5; - pixel_y = 5 - }, -/obj/item/toy/cards/deck/cas/black{ - pixel_x = 5; - pixel_y = 5 - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/carpet, /area/library) @@ -65210,7 +65226,14 @@ /turf/open/floor/plating, /area/engine/engineering) "cCs" = ( -/turf/open/floor/plasteel/yellow/side, +/obj/structure/table/reinforced, +/obj/item/stack/packageWrap, +/obj/item/hand_labeler, +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel/caution, /area/engine/engineering) "cCt" = ( /turf/open/floor/plasteel/yellow/side{ @@ -65990,12 +66013,10 @@ /turf/open/floor/plasteel, /area/engine/engineering) "cEa" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 8 - }, /obj/effect/turf_decal/stripes/corner{ dir = 4 }, +/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, /turf/open/floor/plasteel, /area/engine/engineering) "cEb" = ( @@ -66183,20 +66204,10 @@ /turf/open/floor/plasteel/dark, /area/library) "cEt" = ( -/obj/structure/table/wood, -/obj/item/dice/d20{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/dice/d10{ - pixel_x = -3 - }, -/obj/machinery/computer/security/telescreen/entertainment{ - pixel_y = -32 - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/machinery/vending/games, /turf/open/floor/plasteel/vault{ dir = 5 }, @@ -68752,7 +68763,7 @@ }, /area/crew_quarters/fitness/recreation) "cJA" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Holodeck Access" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -68778,7 +68789,7 @@ /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) "cJC" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Holodeck Access" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -68793,7 +68804,7 @@ /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) "cJD" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Holodeck Access" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -70759,7 +70770,7 @@ "cNv" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Aft Primary Hallway" }, /obj/structure/disposalpipe/segment, @@ -70773,7 +70784,7 @@ /area/hallway/primary/central) "cNw" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Aft Primary Hallway" }, /obj/effect/turf_decal/stripes/line{ @@ -70787,7 +70798,7 @@ "cNx" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Aft Primary Hallway" }, /obj/structure/disposalpipe/segment, @@ -70994,7 +71005,7 @@ /turf/open/floor/plasteel/neutral/corner, /area/crew_quarters/fitness/recreation) "cOb" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Holodeck Access" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -71019,7 +71030,7 @@ /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) "cOd" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Holodeck Access" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -71034,7 +71045,7 @@ /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) "cOe" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Holodeck Access" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -71661,6 +71672,7 @@ dir = 4; name = "medbay camera" }, +/obj/item/twohanded/required/kirbyplants/random, /turf/open/floor/plasteel/neutral/side{ dir = 4 }, @@ -72370,10 +72382,11 @@ /turf/closed/wall, /area/medical/storage) "cRf" = ( -/obj/item/twohanded/required/kirbyplants/random, /obj/machinery/light{ dir = 8 }, +/obj/machinery/rnd/protolathe/department/medical, +/obj/effect/turf_decal/stripes/box, /turf/open/floor/plasteel/neutral/side{ dir = 4 }, @@ -73254,6 +73267,7 @@ /area/medical/storage) "cSV" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/rnd/protolathe/department/medical, /turf/open/floor/plasteel/cmo, /area/medical/storage) "cSW" = ( @@ -77980,20 +77994,20 @@ /turf/open/floor/plasteel/neutral, /area/science/lab) "dcI" = ( -/obj/machinery/r_n_d/destructive_analyzer, +/obj/machinery/rnd/destructive_analyzer, /obj/effect/turf_decal/stripes/line{ dir = 9 }, /turf/open/floor/plasteel, /area/science/lab) "dcJ" = ( +/obj/effect/turf_decal/loading_area, /obj/effect/turf_decal/stripes/line{ dir = 1 }, /turf/open/floor/plasteel, /area/science/lab) "dcK" = ( -/obj/machinery/r_n_d/protolathe, /obj/machinery/ai_status_display{ pixel_x = 32 }, @@ -78003,6 +78017,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 5 }, +/obj/machinery/rnd/protolathe/department/science, /turf/open/floor/plasteel, /area/science/lab) "dcL" = ( @@ -78652,11 +78667,11 @@ /turf/open/floor/plasteel, /area/science/lab) "dej" = ( -/obj/machinery/r_n_d/circuit_imprinter, /obj/item/reagent_containers/glass/beaker/sulphuric, /obj/effect/turf_decal/stripes/line{ dir = 6 }, +/obj/machinery/rnd/circuit_imprinter/department/science, /turf/open/floor/plasteel, /area/science/lab) "dek" = ( @@ -86137,7 +86152,7 @@ }, /area/science/explab) "duA" = ( -/obj/machinery/r_n_d/experimentor, +/obj/machinery/rnd/experimentor, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/vault{ @@ -87546,6 +87561,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, +/obj/structure/chair/office/light, /turf/open/floor/plasteel/neutral, /area/medical/surgery) "dxk" = ( @@ -88885,6 +88901,9 @@ dir = 8; name = "medbay camera" }, +/obj/item/clipboard, +/obj/item/device/healthanalyzer, +/obj/structure/table, /turf/open/floor/plasteel/whiteblue/corner, /area/medical/medbay/central) "dAb" = ( @@ -89442,6 +89461,7 @@ /obj/structure/sign/poster/official/do_not_question{ pixel_y = -32 }, +/obj/item/twohanded/required/kirbyplants/random, /turf/open/floor/plasteel/whitepurple/corner{ dir = 8 }, @@ -89459,11 +89479,11 @@ /turf/open/floor/plasteel/whiteblue/side, /area/medical/medbay/central) "dBg" = ( -/obj/item/twohanded/required/kirbyplants/random, /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/machinery/vending/medical, /turf/open/floor/plasteel/whiteblue/corner, /area/medical/medbay/central) "dBh" = ( @@ -91203,9 +91223,11 @@ /obj/structure/rack, /obj/item/storage/firstaid, /obj/item/storage/firstaid, -/obj/item/device/paicard, /obj/structure/disposalpipe/segment, /obj/effect/turf_decal/bot, +/obj/item/device/healthanalyzer, +/obj/item/device/healthanalyzer, +/obj/item/device/paicard, /turf/open/floor/plasteel, /area/science/robotics/lab) "dEI" = ( @@ -91867,7 +91889,7 @@ /turf/open/floor/plasteel, /area/science/robotics/lab) "dGe" = ( -/obj/machinery/r_n_d/circuit_imprinter, +/obj/machinery/rnd/circuit_imprinter, /obj/item/reagent_containers/glass/beaker/sulphuric, /obj/machinery/airalarm{ dir = 8; @@ -93833,7 +93855,7 @@ /turf/open/floor/plasteel, /area/science/storage) "dKe" = ( -/obj/machinery/r_n_d/server/core, +/obj/machinery/rnd/server, /obj/machinery/atmospherics/pipe/simple/general/hidden{ dir = 5 }, @@ -93846,7 +93868,7 @@ }, /area/science/server) "dKg" = ( -/obj/machinery/r_n_d/server/robotics, +/obj/machinery/rnd/server, /obj/machinery/atmospherics/pipe/simple/general/hidden{ dir = 9 }, @@ -95308,7 +95330,7 @@ /area/crew_quarters/theatre/abandoned) "dNb" = ( /obj/effect/decal/cleanable/dirt, -/obj/machinery/vending/kink, +/obj/item/twohanded/required/kirbyplants/random, /turf/open/floor/wood, /area/crew_quarters/theatre/abandoned) "dNc" = ( @@ -95316,7 +95338,7 @@ dir = 1; pixel_y = -22 }, -/obj/item/twohanded/required/kirbyplants/random, +/obj/machinery/vending/kink, /turf/open/floor/wood{ icon_state = "wood-broken3" }, @@ -95629,7 +95651,7 @@ /area/hallway/primary/aft) "dNP" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Departures Lounge" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -95644,7 +95666,7 @@ /area/hallway/primary/aft) "dNQ" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Departures Lounge" }, /obj/effect/turf_decal/stripes/line{ @@ -95657,7 +95679,7 @@ /area/hallway/primary/aft) "dNR" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Departures Lounge" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -97995,7 +98017,7 @@ /area/hallway/secondary/exit/departure_lounge) "dSQ" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Departures Lounge" }, /obj/structure/disposalpipe/segment, @@ -98009,7 +98031,7 @@ /area/hallway/secondary/exit/departure_lounge) "dSR" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Departures Lounge" }, /obj/effect/turf_decal/stripes/line{ @@ -99665,9 +99687,7 @@ /area/library/abandoned) "dWH" = ( /obj/effect/decal/cleanable/blood/old, -/obj/item/organ/tongue/bone{ - origin_tech = "biotech=0" - }, +/obj/item/organ/tongue/bone, /turf/open/floor/plating, /area/library/abandoned) "dWI" = ( @@ -103713,7 +103733,13 @@ /turf/open/floor/plasteel, /area/security/checkpoint/escape) "eeT" = ( -/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, /turf/open/floor/plasteel, /area/security/checkpoint/escape) "eeU" = ( @@ -104801,13 +104827,216 @@ /turf/open/floor/plasteel/airless/solarpanel, /area/solar/port/aft) "eht" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/wall, +/area/quartermaster/office) +"ehu" = ( +/obj/machinery/rnd/protolathe/department/security, +/turf/open/floor/plasteel/neutral, +/area/security/main) +"ehv" = ( +/turf/open/floor/plasteel/caution, +/area/engine/engineering) +"ehw" = ( +/obj/machinery/rnd/circuit_imprinter, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel/caution, +/area/engine/engineering) +"ehx" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/machinery/rnd/protolathe/department/engineering, +/turf/open/floor/plasteel/neutral, +/area/engine/engineering) +"ehy" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, +/turf/open/floor/plasteel, +/area/hallway/secondary/entry) +"ehz" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, +/turf/open/floor/plasteel, +/area/hallway/secondary/entry) +"ehA" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, +/turf/open/floor/plasteel, +/area/hallway/secondary/entry) +"ehB" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, +/turf/open/floor/plasteel, +/area/hallway/secondary/entry) +"ehC" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, +/turf/open/floor/plasteel, +/area/hallway/secondary/entry) +"ehD" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, +/turf/open/floor/plasteel, +/area/hallway/secondary/entry) +"ehE" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, +/turf/open/floor/plasteel, +/area/hallway/secondary/entry) +"ehF" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, +/turf/open/floor/plasteel, +/area/hallway/secondary/entry) +"ehG" = ( +/obj/item/device/radio/intercom{ + name = "Station Intercom"; + pixel_x = -26 + }, +/obj/machinery/rnd/protolathe/department/service, +/obj/effect/turf_decal/stripes/box, +/turf/open/floor/plasteel/neutral/corner{ + dir = 1 + }, +/area/hallway/secondary/service) +"ehH" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/neutral/corner{ + dir = 1 + }, +/area/hallway/secondary/service) +"ehI" = ( +/obj/structure/extinguisher_cabinet{ + pixel_x = -26 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/table, +/obj/item/clipboard, +/obj/item/stack/packageWrap, +/obj/item/hand_labeler, +/turf/open/floor/plasteel/neutral/corner{ + dir = 1 + }, +/area/hallway/secondary/service) +"ehJ" = ( +/obj/effect/turf_decal/stripes/box, +/obj/machinery/rnd/protolathe/department/cargo, +/turf/open/floor/plasteel/brown, +/area/quartermaster/office) +"ehK" = ( +/obj/machinery/mineral/ore_redemption{ + input_dir = 4; + output_dir = 8 + }, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/stripes/box, +/turf/open/floor/plasteel/neutral, +/area/quartermaster/miningoffice) +"ehL" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/loading_area{ + dir = 4 + }, +/turf/open/floor/plasteel/cmo, +/area/medical/storage) +"ehM" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, +/turf/open/floor/plasteel, +/area/hallway/secondary/exit/departure_lounge) +"ehN" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, +/turf/open/floor/plasteel, +/area/hallway/secondary/exit/departure_lounge) +"ehO" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, +/turf/open/floor/plasteel, +/area/hallway/secondary/exit/departure_lounge) +"ehP" = ( +/obj/machinery/computer/security/telescreen/entertainment{ + pixel_y = -32 + }, +/turf/open/floor/plasteel/dark, +/area/library) +"ehQ" = ( /obj/machinery/vending/kink, /turf/open/floor/plating, /area/maintenance/port/fore) -"ehu" = ( +"ehR" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, /obj/machinery/door/firedoor, /obj/machinery/door/airlock/glass_security{ name = "Security Desk"; @@ -104817,7 +105046,7 @@ dir = 8 }, /area/security/brig) -"ehv" = ( +"ehS" = ( /obj/machinery/vending/kink, /turf/open/floor/plating, /area/crew_quarters/abandoned_gambling_den) @@ -129156,7 +129385,7 @@ dry dta duk dvY -ehv +ehS dmi dfY aad @@ -129383,7 +129612,7 @@ car cxE cjn cAM -cCs +ehv cDY cFQ cHk @@ -129640,7 +129869,7 @@ car cxF cjn cAN -cCs +ehw cDZ cdN cHl @@ -135227,7 +135456,7 @@ alf avr awp axK -eht +ehQ aAb aBk aCv @@ -135552,7 +135781,7 @@ cxW czE cBc cCI -cwq +ehP caG cHA ceb @@ -136738,14 +136967,14 @@ aaa aad aaa aaO -aeb +ehy aaO aaO aaO aaO aaO aaO -aeb +ehy aaO aaa aad @@ -138576,9 +138805,9 @@ aDH aEK aFX aDI -aIR -aKp -aLG +aDI +aKq +aFY aMX aOz aQh @@ -138833,9 +139062,9 @@ aDI aEL aFY aDI -aDI -aKq -aFY +ehG +ehH +ehI aMX aMX aQi @@ -140593,14 +140822,14 @@ aaa aad aaa aaO -aeb +ehy aaO aaO aaO aaO aaO aaO -aeb +ehy aaO aaa aad @@ -142135,14 +142364,14 @@ aaa aad aaa aaO -aeb +ehy aaO aaO aaO aaO aaO aaO -aeb +ehy aaO aaa aad @@ -145115,15 +145344,15 @@ aad aaa aaa dSU -dVl +ehM dSU -dVl +ehM dSU aad aad aad dSU -dVl +ehM eek eeT eek @@ -145219,14 +145448,14 @@ aaa aad aaa aaO -aeb +ehy aaO aaO aaO aaO aaO aaO -aeb +ehy aaO aaa aad @@ -145783,7 +146012,7 @@ aTU aVC aXl aYO -baK +ehJ aYJ bdT bfp @@ -147064,12 +147293,12 @@ aFi aHL aQJ aSh -avW +aTO aVG aXq -avU -baQ -baQ +eht +aTO +aTO baU bfq bgG @@ -148616,7 +148845,7 @@ baU bfw bgG bik -baU +ehK baQ baQ boW @@ -151494,7 +151723,7 @@ cKH cMm cNM cPE -cRg +ehL cRg cRg cWv @@ -153509,7 +153738,7 @@ buA btc aad btc -bAe +buA btb aad aad @@ -154811,7 +155040,7 @@ bZK cbw bgZ bNj -ehu +ehR ciC bgZ clx diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 34757316a1..8ed9acf09f 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -346,7 +346,7 @@ /turf/open/floor/plating, /area/security/prison) "abb" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ id_tag = "permahydro"; name = "Hydroponics Module" }, @@ -1318,7 +1318,7 @@ id = "permacell3"; name = "Cell Shutters" }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ id_tag = "permabolt3"; name = "Cell 3" }, @@ -1333,7 +1333,7 @@ id = "permacell2"; name = "Cell Shutters" }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ id_tag = "permabolt2"; name = "Cell 2" }, @@ -1348,7 +1348,7 @@ id = "permacell1"; name = "Cell Shutters" }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ id_tag = "permabolt1"; name = "Cell 1" }, @@ -3793,7 +3793,7 @@ dir = 9 }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Holodeck Door" }, /turf/open/floor/plasteel, @@ -3803,7 +3803,7 @@ dir = 5 }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Holodeck Door" }, /turf/open/floor/plasteel, @@ -4648,9 +4648,7 @@ /area/engine/gravity_generator) "aka" = ( /obj/effect/turf_decal/bot_white/right, -/turf/open/floor/plasteel/vault{ - dir = 1 - }, +/turf/open/floor/plasteel/dark, /area/engine/gravity_generator) "akb" = ( /obj/structure/sign/securearea{ @@ -4660,15 +4658,11 @@ pixel_y = 32 }, /obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/vault{ - dir = 8 - }, +/turf/open/floor/plasteel/dark, /area/engine/gravity_generator) "akc" = ( /obj/effect/turf_decal/bot_white/left, -/turf/open/floor/plasteel/vault{ - dir = 4 - }, +/turf/open/floor/plasteel/dark, /area/engine/gravity_generator) "akd" = ( /turf/open/space, @@ -5295,7 +5289,7 @@ dir = 10 }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Holodeck Door" }, /turf/open/floor/plasteel, @@ -5305,7 +5299,7 @@ dir = 6 }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Holodeck Door" }, /turf/open/floor/plasteel, @@ -5348,9 +5342,7 @@ /area/engine/gravity_generator) "alt" = ( /obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/vault{ - dir = 8 - }, +/turf/open/floor/plasteel/dark, /area/engine/gravity_generator) "alu" = ( /obj/machinery/light{ @@ -6028,25 +6020,19 @@ dir = 10 }, /obj/effect/turf_decal/bot_white/left, -/turf/open/floor/plasteel/vault{ - dir = 4 - }, +/turf/open/floor/plasteel/dark, /area/engine/gravity_generator) "amK" = ( /obj/machinery/gravity_generator/main/station, /obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/vault{ - dir = 8 - }, +/turf/open/floor/plasteel/dark, /area/engine/gravity_generator) "amL" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 6 }, /obj/effect/turf_decal/bot_white/right, -/turf/open/floor/plasteel/vault{ - dir = 1 - }, +/turf/open/floor/plasteel/dark, /area/engine/gravity_generator) "amM" = ( /obj/machinery/camera{ @@ -7525,6 +7511,9 @@ /obj/structure/reagent_dispensers/peppertank{ pixel_x = -32 }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, /turf/open/floor/plasteel/red/side{ dir = 8 }, @@ -7574,6 +7563,7 @@ dir = 8; network = list("SS13") }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, /turf/open/floor/plasteel/red/side{ dir = 4 }, @@ -8168,7 +8158,7 @@ /area/security/main) "art" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 10 + dir = 9 }, /turf/open/floor/plasteel/red/side{ dir = 4 @@ -8437,7 +8427,7 @@ /turf/open/floor/plating, /area/maintenance/port/fore) "arY" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "space-bridge access" }, /obj/machinery/button/door{ @@ -8479,7 +8469,7 @@ /turf/open/floor/plating, /area/maintenance/port/fore) "asc" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "space-bridge access" }, /obj/machinery/button/door{ @@ -8766,10 +8756,7 @@ /turf/open/floor/plasteel/showroomfloor, /area/security/warden) "asy" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, -/obj/vehicle/secway, +/obj/vehicle/ridden/secway, /obj/item/key/security, /turf/open/floor/plasteel/red/side{ dir = 10 @@ -8821,10 +8808,12 @@ /turf/open/floor/plating, /area/maintenance/starboard/fore) "asC" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/cable/yellow{ icon_state = "2-4" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, /turf/open/floor/plasteel/red/side, /area/security/main) "asD" = ( @@ -8913,9 +8902,7 @@ /turf/open/floor/plasteel/red/side, /area/security/main) "asL" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 1 - }, +/obj/machinery/rnd/protolathe/department/security, /turf/open/floor/plasteel/red/side{ dir = 6 }, @@ -13028,15 +13015,18 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, /turf/open/floor/plasteel/floorgrime, /area/security/brig) "aBh" = ( -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, /turf/open/floor/plasteel/floorgrime, /area/security/brig) "aBi" = ( @@ -13346,7 +13336,11 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 9 }, -/obj/effect/turf_decal/stripes/line, +/obj/machinery/rnd/circuit_imprinter, +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, /turf/open/floor/plasteel, /area/engine/engineering) "aBM" = ( @@ -13354,13 +13348,21 @@ /obj/structure/cable/yellow{ icon_state = "1-8" }, -/obj/effect/turf_decal/stripes/line, +/obj/machinery/rnd/protolathe/department/engineering, +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/engine/engineering) "aBN" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/computer/rdconsole/production{ + dir = 1 + }, +/obj/effect/turf_decal/delivery, /obj/effect/turf_decal/stripes/line{ - dir = 6 + dir = 1 }, /turf/open/floor/plasteel, /area/engine/engineering) @@ -13638,9 +13640,6 @@ /area/security/brig) "aCq" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, /turf/closed/wall, /area/security/brig) "aCr" = ( @@ -14223,12 +14222,12 @@ /area/security/brig) "aDG" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plasteel/dark, -/area/security/brig) -"aDH" = ( /obj/structure/cable/yellow{ icon_state = "1-2" }, +/turf/open/floor/plasteel/dark, +/area/security/brig) +"aDH" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, @@ -14918,18 +14917,15 @@ /turf/open/floor/plasteel/dark, /area/security/brig) "aEX" = ( -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1 }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, /turf/open/floor/plasteel/dark, /area/security/brig) "aEY" = ( -/obj/structure/cable/yellow{ - icon_state = "1-8" - }, /obj/machinery/airalarm{ dir = 8; pixel_x = 24 @@ -15374,7 +15370,7 @@ icon_state = "1-2" }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Vault Storage" }, /turf/open/floor/plasteel/vault{ @@ -17316,7 +17312,7 @@ /area/storage/primary) "aJP" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Primary Tool Storage" }, /turf/open/floor/plasteel/brown{ @@ -17325,7 +17321,7 @@ /area/storage/primary) "aJQ" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Primary Tool Storage" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -19849,7 +19845,7 @@ /area/security/courtroom) "aPC" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Courtroom"; req_access_txt = "42" }, @@ -22009,6 +22005,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/obj/machinery/rnd/protolathe/department/cargo, /turf/open/floor/plasteel, /area/quartermaster/storage) "aUj" = ( @@ -22238,7 +22235,7 @@ "aUC" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Fore Primary Hallway" }, /turf/open/floor/plasteel/red/corner{ @@ -22250,7 +22247,7 @@ icon_state = "1-2" }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Fore Primary Hallway" }, /turf/open/floor/plasteel, @@ -22258,7 +22255,7 @@ "aUE" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Fore Primary Hallway" }, /turf/open/floor/plasteel/red/corner{ @@ -22434,8 +22431,8 @@ /turf/open/floor/plasteel/vault, /area/crew_quarters/dorms) "aUY" = ( -/obj/structure/closet/firecloset, /obj/effect/turf_decal/delivery, +/obj/structure/closet/wardrobe/engineering_yellow, /turf/open/floor/plasteel, /area/engine/engineering) "aUZ" = ( @@ -22813,7 +22810,7 @@ /area/storage/primary) "aVS" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Primary Tool Storage" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -22826,7 +22823,7 @@ /area/storage/primary) "aVT" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Primary Tool Storage" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -22987,7 +22984,7 @@ "aWm" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Crew Quarters Access" }, /obj/structure/cable/yellow{ @@ -22997,7 +22994,7 @@ /area/crew_quarters/locker) "aWn" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Crew Quarters Access" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -23919,7 +23916,6 @@ pixel_y = -3 }, /obj/item/circuitboard/machine/destructive_analyzer, -/obj/item/circuitboard/machine/protolathe, /obj/item/circuitboard/computer/aifixer, /obj/item/circuitboard/computer/teleporter, /obj/item/circuitboard/machine/circuit_imprinter, @@ -24712,7 +24708,7 @@ /area/security/checkpoint/engineering) "aZO" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Library" }, /turf/open/floor/wood, @@ -27689,7 +27685,7 @@ /area/storage/tools) "bfI" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Auxiliary Tool Storage"; req_access_txt = "12" }, @@ -28622,7 +28618,7 @@ dir = 4 }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Starboard Primary Hallway" }, /turf/open/floor/plasteel/yellow/corner{ @@ -29270,7 +29266,7 @@ name = "Station Intercom (General)"; pixel_y = -28 }, -/obj/vehicle/janicart, +/obj/vehicle/ridden/janicart, /obj/item/key/janitor, /turf/open/floor/plating, /area/janitor) @@ -29449,7 +29445,7 @@ icon_state = "4-8" }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Starboard Primary Hallway" }, /obj/structure/disposalpipe/segment{ @@ -30334,7 +30330,7 @@ dir = 4 }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Starboard Primary Hallway" }, /turf/open/floor/plasteel/caution/corner{ @@ -31240,7 +31236,7 @@ /area/storage/art) "bmN" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Art Storage" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -31965,7 +31961,7 @@ dir = 4 }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Port Primary Hallway" }, /turf/open/floor/plasteel/neutral/corner{ @@ -32247,10 +32243,12 @@ /obj/machinery/light_switch{ pixel_x = 27 }, -/obj/machinery/photocopier, /obj/machinery/light/small{ dir = 4 }, +/obj/structure/easel, +/obj/item/canvas/twentythreeXtwentythree, +/obj/item/canvas/twentythreeXtwentythree, /turf/open/floor/plasteel, /area/storage/art) "boP" = ( @@ -33070,7 +33068,7 @@ icon_state = "4-8" }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Port Primary Hallway" }, /turf/open/floor/plasteel, @@ -34305,7 +34303,7 @@ dir = 4 }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Port Primary Hallway" }, /turf/open/floor/plasteel/neutral/corner{ @@ -34990,7 +34988,7 @@ "bug" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Library" }, /turf/open/floor/wood, @@ -34998,7 +34996,7 @@ "buh" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Library" }, /turf/open/floor/wood, @@ -39142,7 +39140,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Command Hallway" }, /turf/open/floor/plasteel/neutral/corner{ @@ -39416,7 +39414,7 @@ dir = 4 }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Command Hallway" }, /obj/structure/disposalpipe/segment{ @@ -39463,7 +39461,7 @@ /area/hallway/primary/central) "bDC" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Bar" }, /turf/open/floor/plasteel, @@ -39863,7 +39861,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Command Hallway" }, /turf/open/floor/plasteel/neutral/corner{ @@ -40243,7 +40241,7 @@ icon_state = "4-8" }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Command Hallway" }, /turf/open/floor/plasteel/neutral/corner{ @@ -40296,7 +40294,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Bar" }, /turf/open/floor/plasteel, @@ -42473,7 +42471,7 @@ }, /obj/effect/turf_decal/bot_white/right, /turf/open/floor/plasteel/vault{ - dir = 1 + dir = 4 }, /area/gateway) "bJZ" = ( @@ -42485,7 +42483,7 @@ }, /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/vault{ - dir = 8 + dir = 4 }, /area/gateway) "bKa" = ( @@ -43195,12 +43193,14 @@ }, /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/vault{ - dir = 8 + dir = 4 }, /area/gateway) "bLE" = ( /obj/machinery/gateway/centerstation, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 4 + }, /area/gateway) "bLF" = ( /obj/machinery/gateway{ @@ -43208,7 +43208,7 @@ }, /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/vault{ - dir = 8 + dir = 4 }, /area/gateway) "bLG" = ( @@ -43904,8 +43904,9 @@ /obj/structure/sign/kiddieplaque/perfect_drone{ pixel_y = 32 }, -/obj/machinery/droneDispenser, -/obj/machinery/door/window/southleft, +/obj/structure/table/wood, +/obj/item/storage/backpack/duffelbag/drone, +/obj/structure/window/reinforced, /turf/open/floor/carpet, /area/bridge/showroom/corporate) "bNc" = ( @@ -44083,7 +44084,7 @@ }, /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/vault{ - dir = 8 + dir = 4 }, /area/gateway) "bNr" = ( @@ -44092,7 +44093,7 @@ }, /obj/effect/turf_decal/bot_white/right, /turf/open/floor/plasteel/vault{ - dir = 1 + dir = 4 }, /area/gateway) "bNs" = ( @@ -44698,20 +44699,26 @@ /turf/open/floor/plating, /area/gateway) "bOK" = ( -/turf/open/floor/plasteel/vault, +/turf/open/floor/plasteel/vault{ + dir = 4 + }, /area/gateway) "bOL" = ( /obj/structure/cable/yellow{ icon_state = "1-2" }, /obj/effect/landmark/event_spawn, -/turf/open/floor/plasteel/vault, +/turf/open/floor/plasteel/vault{ + dir = 4 + }, /area/gateway) "bOM" = ( /obj/machinery/light{ dir = 4 }, -/turf/open/floor/plasteel/vault, +/turf/open/floor/plasteel/vault{ + dir = 4 + }, /area/gateway) "bON" = ( /obj/structure/sign/securearea{ @@ -45183,10 +45190,8 @@ /turf/open/floor/wood, /area/library) "bPU" = ( -/obj/structure/table/wood, -/obj/item/dice/d20, -/obj/item/dice, /obj/effect/decal/cleanable/cobweb/cobweb2, +/obj/machinery/vending/games, /turf/open/floor/wood, /area/library) "bPV" = ( @@ -45417,7 +45422,7 @@ icon_state = "4-8" }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Gateway Chamber" }, /obj/structure/cable/yellow{ @@ -46660,7 +46665,7 @@ /area/hydroponics) "bSW" = ( /obj/machinery/smartfridge, -/turf/closed/wall, +/turf/open/floor/plating, /area/hydroponics) "bSX" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ @@ -46914,25 +46919,12 @@ dir = 1; network = list("SS13") }, -/obj/item/storage/pill_bottle/dice, /obj/structure/table/wood, /turf/open/floor/wood, /area/library) "bTz" = ( /obj/structure/table/wood, /obj/machinery/light, -/obj/item/toy/cards/deck/cas/black{ - pixel_x = -2; - pixel_y = 6 - }, -/obj/item/toy/cards/deck{ - pixel_x = 2; - pixel_y = 7 - }, -/obj/item/toy/cards/deck/cas{ - pixel_x = -1; - pixel_y = 2 - }, /turf/open/floor/wood, /area/library) "bTA" = ( @@ -49141,7 +49133,7 @@ icon_state = "1-2" }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Hydroponics Storage" }, /turf/open/floor/plasteel/hydrofloor, @@ -49555,6 +49547,17 @@ }, /obj/structure/closet/wardrobe/white/medical, /obj/item/clothing/suit/hooded/wintercoat/medical, +/obj/item/storage/belt/medical{ + pixel_y = 2 + }, +/obj/item/storage/belt/medical{ + pixel_y = 2 + }, +/obj/item/storage/belt/medical{ + pixel_y = 2 + }, +/obj/item/clothing/neck/stethoscope, +/obj/item/clothing/neck/stethoscope, /turf/open/floor/plasteel/whiteblue/side{ dir = 1 }, @@ -49677,7 +49680,7 @@ "bZf" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Aft Primary Hallway" }, /turf/open/floor/plasteel/blue/corner{ @@ -49689,7 +49692,7 @@ icon_state = "1-2" }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Aft Primary Hallway" }, /turf/open/floor/plasteel, @@ -49697,7 +49700,7 @@ "bZh" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Aft Primary Hallway" }, /turf/open/floor/plasteel/purple/corner{ @@ -51790,6 +51793,7 @@ /obj/item/clothing/glasses/hud/health, /obj/item/clothing/glasses/hud/health, /obj/item/clothing/glasses/hud/health, +/obj/item/gun/syringe, /turf/open/floor/plasteel/whiteblue/corner{ dir = 8 }, @@ -51812,19 +51816,7 @@ }, /area/medical/storage) "cdv" = ( -/obj/item/storage/belt/medical{ - pixel_y = 2 - }, -/obj/item/storage/belt/medical{ - pixel_y = 2 - }, -/obj/item/storage/belt/medical{ - pixel_y = 2 - }, -/obj/item/clothing/neck/stethoscope, -/obj/item/clothing/neck/stethoscope, -/obj/item/gun/syringe, -/obj/structure/table/glass, +/obj/machinery/rnd/protolathe/department/medical, /turf/open/floor/plasteel/whiteblue/side{ dir = 5 }, @@ -54305,7 +54297,7 @@ }, /area/medical/chemistry) "ciB" = ( -/obj/machinery/r_n_d/destructive_analyzer, +/obj/machinery/rnd/destructive_analyzer, /obj/machinery/airalarm{ dir = 4; pixel_x = -23 @@ -54322,10 +54314,10 @@ /turf/open/floor/plasteel, /area/science/lab) "ciD" = ( -/obj/machinery/r_n_d/protolathe, /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/machinery/rnd/protolathe/department/science, /turf/open/floor/plasteel, /area/science/lab) "ciE" = ( @@ -54486,7 +54478,7 @@ /turf/open/floor/engine, /area/science/explab) "ciU" = ( -/obj/machinery/r_n_d/experimentor, +/obj/machinery/rnd/experimentor, /turf/open/floor/engine, /area/science/explab) "ciV" = ( @@ -54523,7 +54515,7 @@ /turf/closed/wall/r_wall, /area/maintenance/disposal/incinerator) "cja" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ autoclose = 0; frequency = 1449; heat_proof = 1; @@ -54964,11 +54956,9 @@ /turf/open/floor/plasteel, /area/science/lab) "cjZ" = ( -/obj/machinery/r_n_d/circuit_imprinter{ - pixel_y = 4 - }, /obj/item/reagent_containers/glass/beaker/sulphuric, /obj/effect/turf_decal/stripes/line, +/obj/machinery/rnd/circuit_imprinter/department/science, /turf/open/floor/plasteel, /area/science/lab) "cka" = ( @@ -55927,7 +55917,7 @@ /turf/open/space, /area/space/nearstation) "cmd" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ autoclose = 0; frequency = 1449; heat_proof = 1; @@ -66518,7 +66508,7 @@ /obj/machinery/light{ dir = 8 }, -/obj/machinery/r_n_d/circuit_imprinter, +/obj/machinery/rnd/circuit_imprinter, /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/science/robotics/lab) @@ -67174,7 +67164,7 @@ /turf/open/floor/plating, /area/science/server) "cIe" = ( -/obj/machinery/r_n_d/server/robotics, +/obj/machinery/rnd/server, /turf/open/floor/circuit/telecomms/server, /area/science/server) "cIf" = ( @@ -67877,7 +67867,7 @@ "cJE" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Departure Lounge" }, /turf/open/floor/plasteel/neutral/corner{ @@ -67889,7 +67879,7 @@ icon_state = "1-2" }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Departure Lounge" }, /turf/open/floor/plasteel, @@ -67897,7 +67887,7 @@ "cJG" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Departure Lounge" }, /turf/open/floor/plasteel/neutral/corner{ @@ -68059,7 +68049,7 @@ /turf/open/floor/plating, /area/science/server) "cJV" = ( -/obj/machinery/r_n_d/server/core, +/obj/machinery/rnd/server, /turf/open/floor/circuit/telecomms/server, /area/science/server) "cJW" = ( @@ -69218,8 +69208,12 @@ /turf/open/floor/plating, /area/maintenance/aft) "cMl" = ( -/obj/machinery/space_heater, -/obj/effect/landmark/blobstart, +/obj/structure/table, +/obj/item/stack/sheet/glass/fifty{ + pixel_x = 3; + pixel_y = -4 + }, +/obj/item/stack/sheet/metal/fifty, /turf/open/floor/plating, /area/maintenance/aft) "cMm" = ( @@ -69928,7 +69922,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Chapel" }, /turf/open/floor/plasteel/dark, @@ -70209,7 +70203,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Chapel" }, /turf/open/floor/plasteel/dark, @@ -70632,7 +70626,7 @@ /area/chapel/office) "cPl" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Chapel Office"; req_access_txt = "22" }, @@ -71039,7 +71033,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Funeral Parlour" }, /turf/open/floor/plasteel/dark, @@ -74121,7 +74115,6 @@ desc = "A thin layer of dust coating the floor."; name = "dust" }, -/obj/item/device/mass_spectrometer, /turf/open/floor/mineral/titanium, /area/shuttle/abandoned) "cXL" = ( @@ -79939,6 +79932,9 @@ name = "Security Desk"; req_access_txt = "63" }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, /turf/open/floor/plasteel/dark, /area/security/brig) "dBI" = ( @@ -80741,12 +80737,19 @@ /obj/effect/spawner/structure/window/plasma/reinforced, /turf/open/floor/plating, /area/engine/atmos) -"EDx" = ( -/turf/open/space, -/turf/closed/wall/mineral/plastitanium{ - dir = 8; - icon_state = "diagonalWall3" +"EDv" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 }, +/obj/machinery/rnd/protolathe/department/engineering, +/turf/open/floor/plasteel, +/area/engine/engineering) +"EDw" = ( +/obj/machinery/rnd/protolathe/department/service, +/turf/open/floor/plating, +/area/hydroponics) +"EDx" = ( +/turf/closed/wall/mineral/plastitanium, /area/hallway/secondary/entry) "EDy" = ( /turf/closed/wall/mineral/plastitanium{ @@ -80766,6 +80769,42 @@ "EDC" = ( /turf/closed/wall/mineral/plastitanium, /area/engine/break_room) +"EDD" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/chair{ + dir = 4 + }, +/obj/effect/landmark/start/security_officer, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/red/side{ + dir = 8 + }, +/area/security/main) +"EDE" = ( +/obj/structure/closet/firecloset, +/turf/open/floor/plating, +/area/engine/engineering) +"EDF" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/plating, +/area/maintenance/aft) +"EDG" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/effect/landmark/blobstart, +/turf/open/floor/plating, +/area/maintenance/starboard/aft) +"EDH" = ( +/obj/machinery/droneDispenser, +/turf/open/floor/plating, +/area/maintenance/aft) (1,1,1) = {" aaa @@ -90895,7 +90934,7 @@ aaa aaa aaf aaa -EDy +EDx aRA aRA aRA @@ -101207,7 +101246,7 @@ bzE bLk bML bue -bMQ +bzE bRj bSB bPR @@ -110150,7 +110189,7 @@ akM alY cZR cZR -cZR +EDD arm asC atT @@ -110245,6 +110284,7 @@ cIN cJM cCq cgM +EDF cwc cNe cNT @@ -110253,7 +110293,6 @@ ack ack aaf aaf -aaf aaa aaf aaa @@ -110502,11 +110541,11 @@ cFh cFh cKH cLz +EDG cMk bTs bTs bTs -aaf aaa aaa aaa @@ -110760,11 +110799,11 @@ cJN cCq cgN cMl +EDH bTs aaf aaf aaf -aaf aaa aaa aaa @@ -111018,7 +111057,7 @@ cCq cLA bTs bTs -aaa +bTs aaf aaa aaa @@ -111275,7 +111314,7 @@ cKI cQr cQR cRa -cRe +cSd cRe cRe cRe @@ -113326,7 +113365,7 @@ cEu cHe cIe cIY -cJV +cIe cIg cPe dvY @@ -114830,7 +114869,7 @@ bNA bOU bQD bRS -bST +EDw bUi bVu bWO @@ -118873,7 +118912,7 @@ aaa aaa aaf aaa -acP +EDB adl aQf adl @@ -120448,7 +120487,7 @@ axY aJm aKy aMb -aJu +EDE axY aPX aRm diff --git a/_maps/map_files/Mining/Lavaland.dmm b/_maps/map_files/Mining/Lavaland.dmm index 2b542e23bc..bbf998aaba 100644 --- a/_maps/map_files/Mining/Lavaland.dmm +++ b/_maps/map_files/Mining/Lavaland.dmm @@ -196,6 +196,7 @@ /area/mine/laborcamp) "aI" = ( /obj/machinery/door/airlock{ + cyclelinkeddir = 4; name = "Labor Camp External Access" }, /turf/open/floor/plasteel, @@ -286,6 +287,7 @@ /area/lavaland/surface/outdoors/explored) "aY" = ( /obj/machinery/door/airlock/glass_security{ + cyclelinkeddir = 4; name = "Labor Camp Shuttle Security Airlock"; req_access_txt = "2" }, @@ -449,6 +451,7 @@ /area/mine/eva) "bx" = ( /obj/machinery/door/airlock/glass_security{ + cyclelinkeddir = 4; name = "Labor Camp Shuttle Prisoner Airlock"; req_access_txt = "0" }, @@ -659,6 +662,7 @@ /area/mine/eva) "bX" = ( /obj/machinery/door/airlock/external{ + cyclelinkeddir = 4; glass = 1; name = "Mining External Airlock"; opacity = 0; @@ -744,6 +748,7 @@ /area/mine/laborcamp) "cj" = ( /obj/machinery/door/airlock/external{ + cyclelinkeddir = 4; glass = 1; name = "Mining Shuttle Airlock"; opacity = 0; @@ -1757,10 +1762,8 @@ /area/mine/living_quarters) "eR" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/door/airlock{ - glass = 1; - name = "Break Room"; - opacity = 0 +/obj/machinery/door/airlock/glass{ + name = "Break Room" }, /turf/open/floor/plasteel, /area/mine/living_quarters) @@ -3317,6 +3320,49 @@ /obj/effect/mapping_helpers/planet_z, /turf/open/lava/smooth/lava_land_surface, /area/lavaland/surface/outdoors) +"WA" = ( +/obj/machinery/door/airlock{ + cyclelinkeddir = 8; + name = "Labor Camp External Access" + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"WB" = ( +/obj/machinery/door/airlock/glass_security{ + cyclelinkeddir = 8; + name = "Labor Camp Shuttle Security Airlock"; + req_access_txt = "2" + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"WC" = ( +/obj/machinery/door/airlock/glass_security{ + cyclelinkeddir = 8; + name = "Labor Camp Shuttle Prisoner Airlock"; + req_access_txt = "0" + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"WD" = ( +/obj/machinery/door/airlock/external{ + cyclelinkeddir = 8; + glass = 1; + name = "Mining External Airlock"; + opacity = 0; + req_access_txt = "54" + }, +/turf/open/floor/plasteel, +/area/mine/eva) +"WE" = ( +/obj/machinery/door/airlock/external{ + cyclelinkeddir = 8; + glass = 1; + name = "Mining Shuttle Airlock"; + opacity = 0; + req_access_txt = "0" + }, +/turf/open/floor/plasteel, +/area/mine/production) (1,1,1) = {" aa @@ -8415,11 +8461,11 @@ aH az aQ aq -aY +WB aq bi aq -bx +WC aq bZ bZ @@ -11238,7 +11284,7 @@ an an aD aq -aI +WA aq aT aD @@ -17930,7 +17976,7 @@ aj aj br br -cj +WE br br ab @@ -21270,7 +21316,7 @@ aj ab bf bg -bX +WD bg bf ai diff --git a/_maps/map_files/OmegaStation/OmegaStation.dmm b/_maps/map_files/OmegaStation/OmegaStation.dmm index 00a601dba2..ffda1f471d 100644 --- a/_maps/map_files/OmegaStation/OmegaStation.dmm +++ b/_maps/map_files/OmegaStation/OmegaStation.dmm @@ -319,16 +319,15 @@ }, /area/bridge) "aaJ" = ( -/obj/machinery/computer/station_alert, /obj/structure/cable/white{ icon_state = "1-2" }, +/obj/machinery/computer/rdconsole, /turf/open/floor/plasteel/darkyellow/side{ dir = 1 }, /area/bridge) "aaK" = ( -/obj/machinery/computer/atmos_alert, /obj/machinery/requests_console{ announcementConsole = 1; department = "Bridge"; @@ -336,6 +335,7 @@ name = "Bridge RC"; pixel_y = 32 }, +/obj/machinery/modular_computer/console/preset/engineering, /turf/open/floor/plasteel/darkyellow/side{ dir = 1 }, @@ -654,6 +654,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/bridge) "abl" = ( @@ -667,6 +670,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/bridge) "abm" = ( @@ -708,6 +714,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/bridge) "abr" = ( @@ -730,6 +739,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/bridge) "abs" = ( @@ -1267,6 +1279,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "acx" = ( @@ -1289,6 +1304,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "acz" = ( @@ -1342,6 +1360,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/ruin/unpowered{ name = "Asteroid" @@ -1508,6 +1529,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/bridge) "acX" = ( @@ -1607,6 +1631,9 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/bridge) "ade" = ( @@ -2038,6 +2065,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/crew_quarters/heads/hop) "adW" = ( @@ -2265,6 +2295,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/security/detectives_office) "aes" = ( @@ -2313,6 +2346,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/crew_quarters/heads/captain/private) "aex" = ( @@ -2634,6 +2670,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/quartermaster/storage) "aeX" = ( @@ -2666,6 +2705,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/ruin/unpowered{ name = "Asteroid" @@ -2737,6 +2779,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/maintenance/fore) "afj" = ( @@ -2922,6 +2967,9 @@ /obj/structure/cable/white{ icon_state = "4-8" }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/crew_quarters/heads/hop) "afw" = ( @@ -3197,6 +3245,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/maintenance/fore) "afX" = ( @@ -3521,6 +3572,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/quartermaster/storage) "agC" = ( @@ -3744,6 +3798,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/crew_quarters/heads/captain/private) "agV" = ( @@ -4376,6 +4433,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/quartermaster/storage) "aie" = ( @@ -4528,6 +4588,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/security/brig) "ais" = ( @@ -4546,6 +4609,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/security/brig) "ait" = ( @@ -4578,6 +4644,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/security/detectives_office) "aiw" = ( @@ -4602,6 +4671,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/maintenance/fore) "aiy" = ( @@ -4618,6 +4690,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/bridge) "aiz" = ( @@ -4649,6 +4724,10 @@ /obj/structure/cable/white{ icon_state = "1-2" }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel/vault{ dir = 8 }, @@ -4671,6 +4750,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/bridge) "aiD" = ( @@ -4714,6 +4796,9 @@ /obj/structure/cable/white{ icon_state = "1-2" }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/maintenance/starboard/fore) "aiI" = ( @@ -4733,9 +4818,7 @@ }, /area/quartermaster/storage) "aiK" = ( -/obj/item/twohanded/required/kirbyplants{ - icon_state = "plant-22" - }, +/obj/structure/closet/crate/bin, /turf/open/floor/plasteel/brown{ dir = 1 }, @@ -4835,9 +4918,7 @@ /turf/open/floor/plating, /area/security/brig) "aiV" = ( -/obj/structure/table/reinforced, -/obj/item/paper_bin, -/obj/item/pen, +/obj/machinery/rnd/protolathe/department/security, /turf/open/floor/plasteel/red/side{ dir = 8 }, @@ -5052,6 +5133,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "ajo" = ( @@ -5197,6 +5281,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "ajB" = ( @@ -5673,6 +5760,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "akr" = ( @@ -6032,6 +6122,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/security/brig) "akV" = ( @@ -6043,7 +6136,7 @@ /turf/open/floor/plating, /area/security/brig) "akW" = ( -/obj/vehicle/secway, +/obj/vehicle/ridden/secway, /obj/machinery/light{ dir = 8 }, @@ -6132,6 +6225,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "alf" = ( @@ -6155,6 +6251,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/teleporter) "alj" = ( @@ -6170,6 +6269,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/teleporter) "alk" = ( @@ -6302,6 +6404,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/ai_monitored/storage/eva) "alx" = ( @@ -6314,6 +6419,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/ai_monitored/storage/eva) "aly" = ( @@ -6381,7 +6489,6 @@ /turf/open/floor/plasteel/neutral, /area/quartermaster/storage) "alF" = ( -/obj/structure/closet/crate/bin, /obj/machinery/power/apc{ dir = 4; name = "Cargo Bay APC"; @@ -6391,6 +6498,7 @@ /obj/structure/cable/white{ icon_state = "0-8" }, +/obj/machinery/rnd/protolathe/department/cargo, /turf/open/floor/plasteel/brown{ dir = 4 }, @@ -6464,6 +6572,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/security/brig) "alL" = ( @@ -7193,6 +7304,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "anl" = ( @@ -7204,6 +7318,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "anm" = ( @@ -7237,6 +7354,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/quartermaster/storage) "anp" = ( @@ -7459,6 +7579,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "anI" = ( @@ -7470,6 +7593,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "anJ" = ( @@ -7479,6 +7605,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "anK" = ( @@ -7489,6 +7618,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "anL" = ( @@ -7550,7 +7682,7 @@ "anR" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Atrium" }, /obj/structure/cable/white{ @@ -7559,27 +7691,36 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "anS" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Atrium" }, /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "anT" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Atrium" }, /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "anU" = ( @@ -7672,6 +7813,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "aoc" = ( @@ -7893,6 +8037,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/security/brig) "aoy" = ( @@ -7930,6 +8077,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/security/brig) "aoB" = ( @@ -8135,6 +8285,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/maintenance/starboard/central) "aoT" = ( @@ -8235,6 +8388,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "apc" = ( @@ -8315,6 +8471,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/quartermaster/miningdock) "apj" = ( @@ -8358,6 +8517,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/quartermaster/miningdock) "apn" = ( @@ -8381,6 +8543,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel/white, /area/shuttle/mining) "apq" = ( @@ -8424,6 +8589,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel/white, /area/shuttle/mining) "apu" = ( @@ -8470,6 +8638,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/security/brig) "apy" = ( @@ -8536,6 +8707,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/security/brig) "apD" = ( @@ -8576,6 +8750,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/security/brig) "apG" = ( @@ -8723,6 +8900,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/maintenance/port/central) "apT" = ( @@ -8771,6 +8951,7 @@ "apX" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/delivery, +/obj/machinery/rnd/protolathe/department/service, /turf/open/floor/plasteel, /area/crew_quarters/bar/atrium) "apY" = ( @@ -9327,7 +9508,7 @@ "arc" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Atrium" }, /obj/structure/cable/white{ @@ -9336,27 +9517,36 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/crew_quarters/bar/atrium) "ard" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Atrium" }, /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/crew_quarters/bar/atrium) "are" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Atrium" }, /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/crew_quarters/bar/atrium) "arf" = ( @@ -9378,6 +9568,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/maintenance/starboard/central) "arh" = ( @@ -9742,6 +9935,9 @@ /obj/structure/cable/white{ icon_state = "2-4" }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/security/brig) "arH" = ( @@ -9812,6 +10008,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/security/brig) "arM" = ( @@ -9960,6 +10159,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/maintenance/port/central) "arX" = ( @@ -10051,27 +10253,27 @@ /obj/item/twohanded/required/kirbyplants{ icon_state = "plant-21" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "asf" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "asg" = ( -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "ash" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "asi" = ( /obj/item/twohanded/required/kirbyplants{ icon_state = "plant-22" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "asj" = ( /obj/machinery/vending/cola, @@ -10498,6 +10700,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/storage/primary) "asV" = ( @@ -10612,6 +10817,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/maintenance/port/central) "ath" = ( @@ -10691,6 +10899,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "atr" = ( @@ -10874,6 +11085,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/security/brig) "atM" = ( @@ -10911,6 +11125,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/storage/primary) "atP" = ( @@ -11121,16 +11338,16 @@ }, /obj/structure/table/wood, /obj/item/kitchen/fork, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aud" = ( /obj/structure/chair/stool, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aue" = ( /obj/structure/chair/stool/bar, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "auf" = ( /obj/structure/table/reinforced, @@ -11465,6 +11682,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/maintenance/port/fore) "auN" = ( @@ -11635,7 +11855,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "avg" = ( /obj/structure/table/wood, @@ -11643,7 +11863,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "avh" = ( /obj/structure/chair/stool, @@ -11651,20 +11871,20 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "avi" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "avj" = ( /obj/structure/chair/stool/bar, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "avk" = ( /obj/structure/table/reinforced, @@ -11915,6 +12135,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/maintenance/port/fore) "avL" = ( @@ -12190,32 +12413,32 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "awl" = ( /obj/structure/table/wood, /obj/item/storage/bag/tray, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "awm" = ( /obj/structure/chair/stool, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "awn" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "awo" = ( /obj/structure/chair/stool/bar, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "awp" = ( /obj/structure/table/reinforced, @@ -12265,6 +12488,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/crew_quarters/bar/atrium) "awt" = ( @@ -12317,6 +12543,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/maintenance/starboard/central) "awx" = ( @@ -12478,6 +12707,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/maintenance/port/fore) "awN" = ( @@ -12502,6 +12734,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "awP" = ( @@ -12530,7 +12765,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "awU" = ( /obj/structure/chair/stool, @@ -12541,7 +12776,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "awV" = ( /obj/structure/table/wood, @@ -12549,13 +12784,13 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "awW" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "awX" = ( /obj/structure/table/reinforced, @@ -12995,20 +13230,20 @@ /obj/structure/cable/white{ icon_state = "1-4" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "axP" = ( /obj/structure/cable/white{ icon_state = "4-8" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "axQ" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/white{ icon_state = "4-8" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "axR" = ( /obj/structure/cable/white{ @@ -13329,6 +13564,14 @@ pixel_x = 32 }, /obj/item/bedsheet/blue, +/obj/machinery/button/door{ + id = "Dorm3"; + name = "Cabin Bolt Control"; + normaldoorcontrol = 1; + pixel_y = -25; + req_access_txt = "0"; + specialfunctions = 4 + }, /turf/open/floor/plasteel/grimy, /area/crew_quarters/dorms) "ayB" = ( @@ -13340,6 +13583,14 @@ pixel_x = 32 }, /obj/item/bedsheet/red, +/obj/machinery/button/door{ + id = "Dorm4"; + name = "Cabin Bolt Control"; + normaldoorcontrol = 1; + pixel_y = -25; + req_access_txt = "0"; + specialfunctions = 4 + }, /turf/open/floor/carpet, /area/crew_quarters/dorms) "ayD" = ( @@ -13402,24 +13653,24 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "ayK" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "ayL" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "ayM" = ( /obj/machinery/holopad, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "ayN" = ( /obj/item/storage/fancy/cigarettes/cigars{ @@ -13815,11 +14066,15 @@ "azD" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock{ + id_tag = "Dorm3"; name = "Cabin" }, /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "azE" = ( @@ -13881,7 +14136,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "azK" = ( /obj/structure/table/wood, @@ -13889,7 +14144,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "azL" = ( /obj/structure/closet/crate/bin, @@ -13899,7 +14154,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 5 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "azM" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -13963,6 +14218,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "azT" = ( @@ -14039,6 +14297,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/shuttle/escape) "aAd" = ( @@ -14208,6 +14469,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/atmos) "aAv" = ( @@ -14271,7 +14535,7 @@ /area/hallway/primary/central) "aAD" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Lockerroom" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -14280,6 +14544,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "aAE" = ( @@ -14349,6 +14616,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/crew_quarters/theatre) "aAN" = ( @@ -14362,7 +14632,7 @@ /obj/structure/cable/white{ icon_state = "0-4" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aAO" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -14381,7 +14651,7 @@ /obj/structure/cable/white{ icon_state = "1-4" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aAP" = ( /obj/item/reagent_containers/food/condiment/saltshaker{ @@ -14397,7 +14667,7 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aAQ" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ @@ -14406,7 +14676,7 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aAR" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -14415,7 +14685,7 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aAS" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ @@ -14424,7 +14694,7 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aAT" = ( /obj/machinery/door/airlock/maintenance_hatch{ @@ -14440,6 +14710,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/maintenance/starboard/central) "aAU" = ( @@ -14573,6 +14846,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "aBi" = ( @@ -14588,6 +14864,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel/white, /area/shuttle/escape) "aBk" = ( @@ -14854,7 +15133,7 @@ /area/hallway/primary/central) "aBM" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Lockerroom" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -14866,6 +15145,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "aBN" = ( @@ -14987,12 +15269,12 @@ /obj/machinery/light{ dir = 8 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aBZ" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/snacks/cheesiehonkers, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aCa" = ( /obj/machinery/light{ @@ -15001,7 +15283,7 @@ /obj/item/twohanded/required/kirbyplants{ icon_state = "plant-22" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aCb" = ( /obj/machinery/status_display, @@ -15021,6 +15303,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/crew_quarters/kitchen) "aCe" = ( @@ -15112,6 +15397,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "aCm" = ( @@ -15145,6 +15433,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/shuttle/escape) "aCr" = ( @@ -15352,6 +15643,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/engine/atmos) "aCJ" = ( @@ -15481,7 +15775,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 10 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aCV" = ( /obj/structure/table/reinforced, @@ -15600,6 +15894,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "aDj" = ( @@ -15623,7 +15920,13 @@ turf_type = /turf/open/space; width = 30 }, -/turf/open/floor/plating, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel/white, /area/shuttle/escape) "aDk" = ( /obj/effect/turf_decal/delivery, @@ -15689,6 +15992,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/engine/atmos) "aDu" = ( @@ -15794,6 +16100,14 @@ pixel_x = 32 }, /obj/item/bedsheet/brown, +/obj/machinery/button/door{ + id = "Dorm1"; + name = "Cabin Bolt Control"; + normaldoorcontrol = 1; + pixel_y = 25; + req_access_txt = "0"; + specialfunctions = 4 + }, /turf/open/floor/wood, /area/crew_quarters/dorms) "aDI" = ( @@ -15802,6 +16116,14 @@ pixel_x = 32 }, /obj/item/bedsheet/black, +/obj/machinery/button/door{ + id = "Dorm2"; + name = "Cabin Bolt Control"; + normaldoorcontrol = 1; + pixel_y = 25; + req_access_txt = "0"; + specialfunctions = 4 + }, /turf/open/floor/plasteel/grimy, /area/crew_quarters/dorms) "aDJ" = ( @@ -15864,6 +16186,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/crew_quarters/theatre) "aDO" = ( @@ -15880,21 +16205,21 @@ /obj/structure/cable/white{ icon_state = "1-8" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aDP" = ( /obj/effect/landmark/xmastree, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aDQ" = ( /obj/structure/chair/stool/bar, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 5 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aDR" = ( /obj/structure/table/reinforced, @@ -16326,12 +16651,15 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Engineering Foyer" }, /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "aEI" = ( @@ -16356,28 +16684,26 @@ /turf/open/floor/plasteel/neutral/corner, /area/hallway/primary/central) "aEK" = ( -/obj/machinery/vending/clothing, /obj/machinery/firealarm{ dir = 8; pixel_x = -24 }, +/obj/structure/closet/crate/bin, /turf/open/floor/plasteel/vault{ dir = 5 }, /area/crew_quarters/dorms) "aEL" = ( -/obj/item/twohanded/required/kirbyplants{ - icon_state = "plant-21" - }, /obj/machinery/status_display{ pixel_y = -32 }, +/obj/machinery/vending/kink, /turf/open/floor/plasteel/vault{ dir = 5 }, /area/crew_quarters/dorms) "aEM" = ( -/obj/structure/closet/crate/bin, +/obj/machinery/vending/clothing, /turf/open/floor/plasteel/vault{ dir = 5 }, @@ -16500,12 +16826,12 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aEX" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/snacks/chips, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aEY" = ( /obj/structure/table/reinforced, @@ -16598,6 +16924,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/maintenance/starboard/central) "aFg" = ( @@ -16635,7 +16964,7 @@ /area/hallway/primary/central) "aFj" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Departure Lounge" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -16644,6 +16973,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "aFk" = ( @@ -16894,7 +17226,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Engineering Foyer" }, /obj/structure/cable/white{ @@ -16903,6 +17235,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "aFJ" = ( @@ -16964,7 +17299,7 @@ dir = 4; network = list("MINE") }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aFO" = ( /obj/structure/table/wood, @@ -16972,14 +17307,14 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aFP" = ( /obj/structure/chair/stool, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aFQ" = ( /obj/structure/table/reinforced, @@ -17048,12 +17383,15 @@ /area/hallway/primary/central) "aFZ" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Departure Lounge" }, /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "aGa" = ( @@ -17111,6 +17449,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/engine/engineering) "aGi" = ( @@ -17148,6 +17489,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/engine/engineering) "aGl" = ( @@ -17183,6 +17527,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/engine/engineering) "aGo" = ( @@ -17444,7 +17791,7 @@ /obj/structure/cable/white{ icon_state = "2-8" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aGO" = ( /obj/item/reagent_containers/food/condiment/saltshaker{ @@ -17459,7 +17806,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aGP" = ( /obj/structure/chair/stool, @@ -17467,7 +17814,7 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aGQ" = ( /obj/machinery/holopad, @@ -17475,7 +17822,7 @@ name = "Station Intercom"; pixel_x = 28 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aGR" = ( /obj/machinery/vending/dinnerware, @@ -17841,6 +18188,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/engine/engineering) "aHy" = ( @@ -17953,6 +18303,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/maintenance/port/central) "aHG" = ( @@ -18062,6 +18415,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/maintenance/port/central) "aHP" = ( @@ -18083,7 +18439,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aHS" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ @@ -18092,12 +18448,12 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aHT" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/drinks/coffee, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aHU" = ( /obj/item/twohanded/required/kirbyplants{ @@ -18106,7 +18462,7 @@ /obj/structure/sign/poster/random{ pixel_x = 32 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aHV" = ( /obj/machinery/status_display, @@ -18126,6 +18482,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/crew_quarters/kitchen) "aHX" = ( @@ -18462,6 +18821,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/maintenance/port/central) "aID" = ( @@ -18607,7 +18969,7 @@ pixel_x = 32 }, /obj/structure/closet/crate/bin, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aIR" = ( /obj/structure/closet/secure_closet/freezer/meat, @@ -18731,6 +19093,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel/white, /area/shuttle/escape) "aJf" = ( @@ -18964,12 +19329,18 @@ /obj/item/stack/sheet/metal/fifty, /obj/item/stack/sheet/glass/fifty, /obj/item/stack/sheet/glass/fifty, -/obj/item/crowbar, -/obj/item/grenade/chem_grenade/smart_metal_foam, -/obj/item/grenade/chem_grenade/smart_metal_foam, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/item/stack/sheet/rglass{ + amount = 50; + pixel_x = 2; + pixel_y = -2 + }, +/obj/item/stack/sheet/plasteel/fifty, +/obj/item/grenade/chem_grenade/smart_metal_foam, +/obj/item/grenade/chem_grenade/smart_metal_foam, +/obj/item/crowbar, /turf/open/floor/plasteel/yellow/side{ dir = 8 }, @@ -19057,7 +19428,7 @@ /turf/open/floor/plasteel, /area/janitor) "aJJ" = ( -/obj/vehicle/janicart, +/obj/vehicle/ridden/janicart, /obj/effect/decal/cleanable/dirt, /obj/item/storage/bag/trash, /obj/item/key/janitor, @@ -19105,6 +19476,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/maintenance/port/central) "aJN" = ( @@ -19183,7 +19557,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aJX" = ( /obj/machinery/vending/cola, @@ -19317,6 +19691,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/shuttle/escape) "aKn" = ( @@ -19332,6 +19709,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/shuttle/escape) "aKp" = ( @@ -19364,6 +19744,9 @@ /obj/structure/cable{ icon_state = "1-4" }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/gravity_generator) "aKt" = ( @@ -19435,6 +19818,9 @@ dir = 8 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/gravity_generator) "aKy" = ( @@ -19541,6 +19927,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/engineering) "aKI" = ( @@ -19615,9 +20004,6 @@ /turf/open/floor/plasteel/neutral, /area/engine/engineering) "aKO" = ( -/obj/machinery/computer/station_alert{ - dir = 8 - }, /obj/structure/cable/white{ icon_state = "1-8" }, @@ -19627,6 +20013,9 @@ /obj/structure/cable/white{ icon_state = "4-8" }, +/obj/machinery/computer/rdconsole/production{ + dir = 8 + }, /turf/open/floor/plasteel/yellow/side{ dir = 4 }, @@ -19799,7 +20188,7 @@ pixel_x = -32; pixel_y = -32 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aLg" = ( /obj/machinery/vending/snack, @@ -19884,6 +20273,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "aLw" = ( @@ -20186,6 +20578,7 @@ /obj/item/twohanded/required/kirbyplants{ icon_state = "plant-21" }, +/obj/machinery/rnd/circuit_imprinter, /turf/open/floor/plasteel/yellow/side{ dir = 4 }, @@ -20342,7 +20735,7 @@ /obj/machinery/light{ dir = 8 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aMu" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -20352,7 +20745,7 @@ /obj/structure/cable/white{ icon_state = "2-4" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aMv" = ( /obj/effect/decal/cleanable/dirt, @@ -20369,6 +20762,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/maintenance/starboard/central) "aMw" = ( @@ -20519,6 +20915,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/tcommsat/server) "aMM" = ( @@ -20710,13 +21109,6 @@ /turf/open/floor/plasteel, /area/engine/engineering) "aNd" = ( -/obj/structure/table/reinforced, -/obj/item/stack/sheet/plasteel/fifty, -/obj/item/stack/sheet/rglass{ - amount = 50; - pixel_x = 2; - pixel_y = -2 - }, /obj/effect/turf_decal/delivery, /obj/machinery/computer/security/telescreen{ desc = "Used for watching the Engine."; @@ -20725,6 +21117,7 @@ network = list("Engine"); pixel_y = -32 }, +/obj/machinery/rnd/protolathe/department/engineering, /turf/open/floor/plasteel, /area/engine/engineering) "aNe" = ( @@ -20930,7 +21323,7 @@ /area/hydroponics) "aNy" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Atrium" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -20940,17 +21333,23 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/crew_quarters/bar/atrium) "aNz" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Atrium" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/crew_quarters/bar/atrium) "aNA" = ( @@ -21297,6 +21696,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/janitor) "aOg" = ( @@ -21311,6 +21713,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/maintenance/port/central) "aOh" = ( @@ -21327,6 +21732,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/hydroponics) "aOj" = ( @@ -21342,37 +21750,27 @@ /obj/item/twohanded/required/kirbyplants{ icon_state = "plant-21" }, -/turf/open/floor/plasteel/redyellow/side{ - dir = 9 - }, +/turf/open/floor/plasteel/yellowsiding, /area/hallway/primary/central) "aOn" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/redyellow/side{ - dir = 1 - }, +/turf/open/floor/plasteel/stairs/left, /area/hallway/primary/central) "aOo" = ( -/turf/open/floor/plasteel/redyellow/side{ - dir = 1 - }, +/turf/open/floor/plasteel/stairs/medium, /area/hallway/primary/central) "aOp" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/redyellow/side{ - dir = 1 - }, +/turf/open/floor/plasteel/stairs/right, /area/hallway/primary/central) "aOq" = ( /obj/item/twohanded/required/kirbyplants{ icon_state = "plant-22" }, -/turf/open/floor/plasteel/redyellow/side{ - dir = 5 - }, +/turf/open/floor/plasteel/yellowsiding, /area/hallway/primary/central) "aOr" = ( /obj/structure/sign/directions/engineering{ @@ -21408,6 +21806,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/maintenance/starboard/central) "aOv" = ( @@ -21615,6 +22016,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/maintenance/port) "aOO" = ( @@ -21707,6 +22111,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "aOV" = ( @@ -21847,6 +22254,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "aPe" = ( @@ -22369,6 +22779,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "aQd" = ( @@ -22636,6 +23049,9 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel/grimy, /area/tcommsat/server) "aQJ" = ( @@ -22759,18 +23175,21 @@ /area/library) "aQY" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Library Access" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/library) "aQZ" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Library Access" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -22780,6 +23199,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/library) "aRa" = ( @@ -22806,6 +23228,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/medical/morgue) "aRe" = ( @@ -22907,6 +23332,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/science/research) "aRv" = ( @@ -22919,6 +23347,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/science/research) "aRx" = ( @@ -22935,6 +23366,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/maintenance/starboard) "aRy" = ( @@ -22956,6 +23390,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/maintenance/starboard) "aRB" = ( @@ -23151,6 +23588,7 @@ /obj/structure/sign/nosmoking_2{ pixel_y = 32 }, +/obj/machinery/vending/games, /turf/open/floor/plasteel/dark, /area/library) "aRW" = ( @@ -23175,13 +23613,6 @@ /area/library) "aRY" = ( /obj/structure/table/wood, -/obj/item/dice/d20{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/dice/d10{ - pixel_x = -3 - }, /obj/machinery/firealarm{ pixel_y = 24 }, @@ -23330,6 +23761,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "aSu" = ( @@ -23510,6 +23944,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel/vault/telecomms{ dir = 5 }, @@ -23665,21 +24102,12 @@ /area/library) "aTf" = ( /obj/structure/table/wood, -/obj/item/storage/pill_bottle/dice, /turf/open/floor/plasteel/vault{ dir = 5 }, /area/library) "aTg" = ( /obj/structure/table/wood, -/obj/item/toy/cards/deck/cas{ - pixel_x = -5; - pixel_y = 5 - }, -/obj/item/toy/cards/deck/cas/black{ - pixel_x = 5; - pixel_y = 5 - }, /turf/open/floor/plasteel/dark, /area/library) "aTh" = ( @@ -23974,6 +24402,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/science/research) "aTP" = ( @@ -24002,6 +24433,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/maintenance/starboard) "aTR" = ( @@ -24284,7 +24718,7 @@ /turf/open/floor/plasteel/grimy, /area/hallway/primary/central) "aUA" = ( -/obj/machinery/r_n_d/destructive_analyzer, +/obj/machinery/rnd/destructive_analyzer, /obj/effect/turf_decal/stripes/line{ dir = 9 }, @@ -24297,11 +24731,11 @@ /turf/open/floor/plasteel, /area/science/lab) "aUC" = ( -/obj/machinery/r_n_d/protolathe, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/stripes/line{ dir = 5 }, +/obj/machinery/rnd/protolathe/department/science, /turf/open/floor/plasteel, /area/science/lab) "aUD" = ( @@ -24577,6 +25011,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/medical/medbay/zone3) "aVg" = ( @@ -24706,12 +25143,12 @@ /turf/open/floor/plasteel, /area/science/lab) "aVv" = ( -/obj/machinery/r_n_d/circuit_imprinter, /obj/item/reagent_containers/glass/beaker/sulphuric, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/stripes/line{ dir = 6 }, +/obj/machinery/rnd/circuit_imprinter/department/science, /turf/open/floor/plasteel, /area/science/lab) "aVw" = ( @@ -24807,6 +25244,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/maintenance/starboard) "aVH" = ( @@ -25156,7 +25596,7 @@ }, /area/science/research) "aWs" = ( -/obj/machinery/r_n_d/server/core, +/obj/machinery/rnd/server, /obj/machinery/atmospherics/pipe/manifold/general/visible{ dir = 8 }, @@ -25171,7 +25611,7 @@ }, /area/science/research) "aWu" = ( -/obj/machinery/r_n_d/server/robotics, +/obj/machinery/rnd/server, /obj/machinery/atmospherics/pipe/simple/general/hidden{ dir = 9 }, @@ -25319,6 +25759,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/medical/medbay/zone3) "aWM" = ( @@ -25340,6 +25783,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/medical/chemistry) "aWO" = ( @@ -25455,6 +25901,10 @@ name = "Server Access"; req_access_txt = "30" }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel/vault{ dir = 8 }, @@ -25667,6 +26117,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/science/research) "aXy" = ( @@ -25762,6 +26215,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/science/research) "aXG" = ( @@ -25848,6 +26304,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/maintenance/port) "aXO" = ( @@ -25900,6 +26359,12 @@ pixel_y = 24 }, /obj/effect/turf_decal/bot, +/obj/item/storage/box/beakers{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/storage/box/syringes, +/obj/item/gun/syringe, /turf/open/floor/plasteel, /area/medical/medbay/zone3) "aXR" = ( @@ -26040,6 +26505,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/science/research) "aYi" = ( @@ -26201,6 +26669,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/maintenance/starboard) "aYv" = ( @@ -26360,7 +26831,10 @@ req_access_txt = "5" }, /obj/effect/turf_decal/stripes/line{ - dir = 2 + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 }, /turf/open/floor/plasteel, /area/medical/medbay/zone3) @@ -26442,6 +26916,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/medical/medbay/zone3) "aYU" = ( @@ -26507,6 +26984,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/science/robotics/mechbay) "aZe" = ( @@ -26696,6 +27176,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/maintenance/port) "aZB" = ( @@ -26757,7 +27240,10 @@ dir = 4 }, /obj/effect/turf_decal/stripes/line{ - dir = 2 + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 }, /turf/open/floor/plasteel, /area/medical/medbay/zone3) @@ -26874,6 +27360,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/medical/medbay/zone3) "aZQ" = ( @@ -27116,6 +27605,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/maintenance/port) "bao" = ( @@ -27180,13 +27672,6 @@ /turf/open/floor/plasteel, /area/medical/medbay/zone3) "bau" = ( -/obj/structure/table/glass, -/obj/item/storage/box/beakers{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/storage/box/syringes, -/obj/item/gun/syringe, /obj/machinery/light, /obj/structure/noticeboard{ dir = 1; @@ -27196,6 +27681,7 @@ dir = 5 }, /obj/effect/turf_decal/bot, +/obj/machinery/rnd/protolathe/department/medical, /turf/open/floor/plasteel, /area/medical/medbay/zone3) "bav" = ( @@ -27427,6 +27913,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/science/robotics/mechbay) "baS" = ( @@ -27646,6 +28135,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/maintenance/port) "bbp" = ( @@ -27723,6 +28215,9 @@ dir = 8 }, /obj/effect/landmark/event_spawn, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/security/checkpoint) "bby" = ( @@ -27857,6 +28352,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/science/robotics/lab) "bbJ" = ( @@ -27959,6 +28457,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/maintenance/port) "bbV" = ( @@ -27984,6 +28485,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/maintenance/port) "bbX" = ( @@ -28007,6 +28511,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/maintenance/port) "bca" = ( @@ -28112,6 +28619,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/medical/medbay/zone3) "bcl" = ( @@ -28184,6 +28694,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/science/robotics/mechbay) "bct" = ( @@ -28481,6 +28994,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/security/checkpoint) "bde" = ( @@ -28565,6 +29081,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/science/robotics/mechbay) "bdl" = ( @@ -28714,6 +29233,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/maintenance/starboard) "bdB" = ( @@ -28904,6 +29426,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/medical/medbay/zone3) "bdU" = ( @@ -29291,6 +29816,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/maintenance/port) "beE" = ( @@ -29310,6 +29838,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/maintenance/port) "beG" = ( @@ -29380,6 +29911,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/science/research) "beN" = ( @@ -29398,6 +29932,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/science/research) "beO" = ( @@ -29420,6 +29957,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/maintenance/starboard) "beQ" = ( @@ -29591,6 +30131,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/security/checkpoint) "bfg" = ( @@ -29619,6 +30162,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/maintenance/starboard) "bfj" = ( @@ -29837,6 +30383,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/maintenance/port) "bfC" = ( @@ -29889,6 +30438,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/maintenance/port) "bfI" = ( @@ -29982,6 +30534,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/science/xenobiology) "bfR" = ( @@ -30004,6 +30559,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/science/xenobiology) "bfS" = ( @@ -30462,6 +31020,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/maintenance/port) "bgP" = ( @@ -30483,18 +31044,21 @@ /area/hallway/secondary/entry) "bgR" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Arrivals Port" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bgS" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Arrivals Port" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -30504,6 +31068,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bgT" = ( @@ -30520,13 +31087,16 @@ /area/hallway/secondary/entry) "bgW" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Arrivals Port" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bgX" = ( @@ -30792,6 +31362,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/chapel/main) "bhz" = ( @@ -31378,6 +31951,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/chapel/main) "biI" = ( @@ -31422,6 +31998,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/chapel/main) "biN" = ( @@ -31526,6 +32105,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "biV" = ( @@ -31539,6 +32121,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "biW" = ( @@ -31760,7 +32345,12 @@ /obj/machinery/atmospherics/pipe/simple/general/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/end, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/science/xenobiology) "bjw" = ( @@ -32203,6 +32793,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bki" = ( @@ -32218,6 +32811,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bkk" = ( @@ -32583,6 +33179,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "blh" = ( @@ -32618,7 +33217,7 @@ c_tag = "Central Diner 4"; dir = 1 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "blk" = ( /obj/machinery/camera{ @@ -32878,7 +33477,7 @@ /turf/open/floor/plasteel, /area/engine/engineering) "blL" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Departure Lounge" }, /obj/effect/turf_decal/stripes/line{ @@ -32887,6 +33486,9 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "blM" = ( @@ -32926,19 +33528,22 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "blY" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Departure Lounge" }, /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "blZ" = ( /turf/open/floor/plasteel, /area/hallway/secondary/exit) "bmb" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "bmh" = ( @@ -33028,7 +33633,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "bsB" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Departure Lounge" }, /obj/effect/turf_decal/stripes/line{ @@ -33040,6 +33645,9 @@ /obj/structure/cable/white{ icon_state = "4-8" }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "bsC" = ( @@ -33098,7 +33706,7 @@ /area/hallway/secondary/exit) "bsN" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Departure Lounge" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -33110,6 +33718,9 @@ /obj/structure/cable/white{ icon_state = "4-8" }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "bsO" = ( @@ -33187,6 +33798,9 @@ /obj/structure/cable/white{ icon_state = "1-2" }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "bsY" = ( @@ -33204,6 +33818,12 @@ /obj/structure/cable/white{ icon_state = "4-8" }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, /turf/open/floor/plasteel, /area/hallway/secondary/exit) "bta" = ( @@ -33276,6 +33896,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "btl" = ( @@ -33286,6 +33909,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "buy" = ( @@ -33808,7 +34434,7 @@ dir = 4 }, /obj/effect/landmark/event_spawn, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "bxH" = ( /obj/effect/decal/cleanable/dirt, @@ -33837,7 +34463,7 @@ /area/crew_quarters/dorms) "bxL" = ( /obj/effect/landmark/event_spawn, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "bxM" = ( /obj/effect/landmark/event_spawn, @@ -33969,6 +34595,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/maintenance/starboard/fore) "byk" = ( @@ -33991,6 +34620,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/plasteel, /area/maintenance/starboard/fore) "bym" = ( @@ -34048,6 +34680,66 @@ }, /turf/open/space, /area/space/nearstation) +"swt" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/rnd/protolathe/department/service, +/turf/open/floor/plasteel/redyellow, +/area/crew_quarters/bar/atrium) +"swu" = ( +/obj/machinery/rnd/protolathe/department/medical, +/turf/closed/wall, +/area/medical/medbay/zone3) +"swv" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock{ + id_tag = "Dorm4"; + name = "Cabin" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/crew_quarters/dorms) +"sww" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock{ + id_tag = "Dorm1"; + name = "Cabin" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/crew_quarters/dorms) +"swx" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock{ + id_tag = "Dorm2"; + name = "Cabin" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/crew_quarters/dorms) +"swy" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/vending/kink, +/turf/open/floor/plasteel/vault{ + dir = 8 + }, +/area/maintenance/port) (1,1,1) = {" aaa @@ -66568,7 +67260,7 @@ aZp bak bbc bbQ -bcF +swy bdD beu baj @@ -66825,7 +67517,7 @@ aZq bal bbd bbR -bcG +bbR bdE bev baj @@ -71680,7 +72372,7 @@ ayz azD aAH aBQ -azD +sww aDG aEO awQ @@ -72448,10 +73140,10 @@ apI awQ axJ ayB -azD +swv aAH aBS -azD +swx ayz aEQ awQ diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index fab27c788f..7eb9a7ac7a 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -1801,7 +1801,7 @@ id = "permacell2"; name = "cell blast door" }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ id_tag = "permabolt2"; name = "Cell 2" }, @@ -1820,7 +1820,7 @@ id = "permacell1"; name = "cell blast door" }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ id_tag = "permabolt1"; name = "Cell 1" }, @@ -2614,7 +2614,7 @@ /turf/open/floor/plasteel/dark, /area/security/armory) "ail" = ( -/obj/vehicle/secway, +/obj/vehicle/ridden/secway, /turf/open/floor/plasteel/dark, /area/security/armory) "aim" = ( @@ -2647,7 +2647,7 @@ /turf/open/floor/plasteel/showroomfloor, /area/security/main) "air" = ( -/obj/vehicle/secway, +/obj/vehicle/ridden/secway, /obj/item/key/security, /obj/effect/turf_decal/bot, /turf/open/floor/plasteel/showroomfloor, @@ -2864,6 +2864,7 @@ "aiY" = ( /obj/structure/table, /obj/item/device/flashlight/lamp, +/obj/item/storage/box/mousetraps, /turf/open/floor/plating, /area/maintenance/department/security/brig) "aiZ" = ( @@ -3148,7 +3149,7 @@ /turf/open/space, /area/space/nearstation) "ajB" = ( -/obj/item/storage/box/mousetraps, +/obj/machinery/vending/kink, /turf/open/floor/plating, /area/maintenance/department/security/brig) "ajC" = ( @@ -3459,7 +3460,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "space-bridge access" }, /obj/effect/turf_decal/stripes/line{ @@ -3499,7 +3500,7 @@ /turf/open/floor/plating, /area/maintenance/department/crew_quarters/dorms) "akp" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "space-bridge access" }, /obj/structure/cable{ @@ -4988,12 +4989,12 @@ }, /area/security/main) "anP" = ( -/obj/item/twohanded/required/kirbyplants{ - icon_state = "plant-22" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, +/obj/item/twohanded/required/kirbyplants{ + icon_state = "plant-22" + }, /turf/open/floor/plasteel/dark, /area/security/main) "anQ" = ( @@ -5716,7 +5717,6 @@ /turf/open/floor/plating, /area/maintenance/department/security/brig) "apA" = ( -/mob/living/simple_animal/mouse/gray, /turf/open/floor/plating{ icon_state = "platingdmg3" }, @@ -9024,6 +9024,7 @@ dir = 4; pixel_x = 28 }, +/obj/machinery/computer/rdconsole, /turf/open/floor/plasteel/darkblue/side{ dir = 4 }, @@ -9139,7 +9140,7 @@ /area/crew_quarters/fitness/recreation) "axy" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Holodeck Door" }, /turf/open/floor/plasteel, @@ -9482,7 +9483,7 @@ /area/crew_quarters/dorms) "ayt" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Recreation Room" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -9982,7 +9983,7 @@ /area/crew_quarters/dorms) "azB" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Recreation Room" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -12754,7 +12755,7 @@ /area/security/detectives_office) "aGb" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Central Access" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -12762,14 +12763,14 @@ /area/hallway/primary/fore) "aGc" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Central Access" }, /turf/open/floor/plasteel, /area/hallway/primary/fore) "aGd" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Central Access" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -13093,7 +13094,7 @@ /area/storage/primary) "aGY" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Primary Tool Storage" }, /obj/structure/cable{ @@ -13104,7 +13105,7 @@ /area/storage/primary) "aGZ" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Primary Tool Storage" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -13646,7 +13647,7 @@ /area/hallway/primary/central) "aIg" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Dormitory" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -14053,7 +14054,7 @@ /area/hallway/primary/central) "aJf" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Dormitory" }, /obj/structure/cable{ @@ -14527,7 +14528,7 @@ /area/hallway/primary/central) "aKb" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Dormitory" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -14612,7 +14613,6 @@ /turf/open/floor/plating, /area/maintenance/department/cargo) "aKo" = ( -/mob/living/simple_animal/mouse/gray, /turf/open/floor/plating{ burnt = 1; icon_state = "panelscorched" @@ -14646,7 +14646,7 @@ /turf/closed/wall/mineral/titanium, /area/shuttle/escape) "aKv" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Cockpit"; req_access_txt = "19" }, @@ -14740,7 +14740,7 @@ /turf/open/floor/plating, /area/storage/art) "aKL" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Art Storage" }, /obj/structure/cable{ @@ -14759,7 +14759,7 @@ /area/crew_quarters/cafeteria/lunchroom) "aKO" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Lunchroom" }, /obj/structure/cable{ @@ -14905,7 +14905,7 @@ /turf/open/floor/plating, /area/maintenance/disposal) "aLp" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Cargo Hold"; req_access_txt = "0" }, @@ -14918,7 +14918,7 @@ /turf/open/floor/mineral/titanium/blue, /area/shuttle/escape) "aLr" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Brig"; req_access_txt = "2" }, @@ -16673,7 +16673,7 @@ /area/hallway/secondary/exit/departure_lounge) "aPv" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Departure Lounge" }, /turf/open/floor/plasteel, @@ -16843,7 +16843,7 @@ name = "Security Post - Cargo APC"; pixel_x = -24 }, -/obj/structure/closet/wardrobe/red, +/obj/structure/closet/secure_closet/security/cargo, /turf/open/floor/plasteel/red/side{ dir = 10 }, @@ -17062,7 +17062,7 @@ /area/hallway/secondary/exit/departure_lounge) "aQz" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Departure Lounge" }, /obj/structure/disposalpipe/segment{ @@ -17891,7 +17891,7 @@ /turf/open/floor/plating, /area/maintenance/disposal) "aSp" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Infirmary" }, /turf/open/floor/mineral/titanium/blue, @@ -18923,7 +18923,7 @@ /area/hallway/secondary/exit/departure_lounge) "aUJ" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Departure Lounge" }, /obj/structure/cable{ @@ -19486,7 +19486,7 @@ /area/hallway/secondary/exit/departure_lounge) "aVQ" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Departure Lounge" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -19528,7 +19528,7 @@ /area/janitor) "aVV" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Hydroponics"; req_access_txt = "35" }, @@ -21257,9 +21257,7 @@ /area/hydroponics) "aZZ" = ( /obj/machinery/smartfridge, -/turf/open/floor/plasteel/vault{ - dir = 8 - }, +/turf/open/floor/plating, /area/crew_quarters/kitchen) "baa" = ( /obj/structure/disposalpipe/segment, @@ -21626,7 +21624,7 @@ /turf/open/floor/plasteel/neutral/corner, /area/hallway/primary/central) "baX" = ( -/obj/vehicle/janicart, +/obj/vehicle/ridden/janicart, /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -22167,7 +22165,7 @@ /area/crew_quarters/bar) "bcw" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Bar" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -22449,7 +22447,7 @@ /area/hallway/secondary/entry) "bdf" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Central Access" }, /turf/open/floor/plasteel, @@ -22549,7 +22547,7 @@ /area/crew_quarters/bar) "bdy" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Bar" }, /obj/machinery/door/poddoor/shutters/preopen{ @@ -22851,7 +22849,7 @@ /area/hydroponics) "bek" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ cyclelinkeddir = 4; name = "Hydroponics"; req_access_txt = "35" @@ -22898,7 +22896,7 @@ /area/hallway/primary/central) "beo" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ cyclelinkeddir = 8; name = "Kitchen"; req_access_txt = "28" @@ -23215,7 +23213,7 @@ /area/hallway/secondary/entry) "bfe" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Central Access" }, /obj/structure/cable{ @@ -23616,7 +23614,7 @@ /area/crew_quarters/lounge) "bgb" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Lounge" }, /obj/structure/cable{ @@ -23770,7 +23768,7 @@ /area/hallway/primary/central) "bgt" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Bar" }, /turf/open/floor/plasteel, @@ -23778,7 +23776,7 @@ "bgu" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Bar" }, /turf/open/floor/plasteel, @@ -24725,7 +24723,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/mob/living/simple_animal/mouse/gray, /turf/open/floor/plating, /area/maintenance/department/cargo) "biB" = ( @@ -24904,14 +24901,14 @@ "biV" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Medbay" }, /turf/open/floor/plasteel/white/side, /area/medical/medbay/zone3) "biW" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Medbay" }, /turf/open/floor/plasteel/white/side, @@ -24919,7 +24916,7 @@ "biX" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Medbay" }, /turf/open/floor/plasteel/white/side, @@ -25321,18 +25318,18 @@ "bkj" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/plasteel, /area/hallway/primary/central) "bkk" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/plasteel, /area/hallway/primary/central) "bkl" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/plasteel, /area/hallway/primary/central) "bkm" = ( @@ -25674,6 +25671,7 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 }, +/obj/structure/closet/wardrobe/red, /turf/open/floor/plasteel/red/side{ dir = 8 }, @@ -25937,7 +25935,7 @@ }, /area/science/robotics/lab) "blM" = ( -/obj/machinery/r_n_d/server/core, +/obj/machinery/rnd/server, /obj/structure/sign/poster/random{ pixel_y = 32 }, @@ -25954,7 +25952,7 @@ /turf/open/floor/plasteel/dark/telecomms/server/walkway, /area/science/server) "blO" = ( -/obj/machinery/r_n_d/server/robotics, +/obj/machinery/rnd/server, /obj/structure/sign/poster/random{ pixel_y = 32 }, @@ -25969,7 +25967,7 @@ /turf/open/floor/engine, /area/science/explab) "blQ" = ( -/obj/machinery/r_n_d/experimentor, +/obj/machinery/rnd/experimentor, /turf/open/floor/engine, /area/science/explab) "blR" = ( @@ -26223,7 +26221,7 @@ dir = 4; network = list("SS13") }, -/obj/structure/closet/wardrobe/red, +/obj/structure/closet/secure_closet/security/med, /turf/open/floor/plasteel/red/side{ dir = 10 }, @@ -26721,7 +26719,7 @@ /turf/open/floor/plasteel, /area/science/research/lobby) "bnO" = ( -/obj/machinery/r_n_d/circuit_imprinter, +/obj/machinery/rnd/circuit_imprinter, /obj/machinery/light{ dir = 8 }, @@ -27689,7 +27687,7 @@ "bqd" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Research Division" }, /obj/effect/turf_decal/delivery, @@ -27700,7 +27698,7 @@ "bqe" = ( /obj/machinery/door/firedoor, /obj/structure/disposalpipe/segment, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Research Division" }, /obj/effect/turf_decal/delivery, @@ -27708,7 +27706,7 @@ /area/science/research/lobby) "bqf" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Research Division" }, /obj/effect/turf_decal/delivery, @@ -28967,7 +28965,7 @@ "bsH" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Medbay" }, /turf/open/floor/plasteel/whiteblue/corner{ @@ -28978,7 +28976,7 @@ /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Medbay" }, /turf/open/floor/plasteel/whiteblue/corner, @@ -29703,7 +29701,7 @@ /turf/open/floor/plasteel/white, /area/science/lab) "bup" = ( -/obj/machinery/r_n_d/destructive_analyzer, +/obj/machinery/rnd/destructive_analyzer, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/science/lab) @@ -29714,8 +29712,8 @@ /turf/open/floor/plasteel, /area/science/lab) "bur" = ( -/obj/machinery/r_n_d/protolathe, /obj/effect/turf_decal/delivery, +/obj/machinery/rnd/protolathe/department/science, /turf/open/floor/plasteel, /area/science/lab) "bus" = ( @@ -30247,11 +30245,9 @@ /turf/open/floor/plasteel, /area/science/lab) "bvy" = ( -/obj/machinery/r_n_d/circuit_imprinter{ - pixel_y = 4 - }, /obj/item/reagent_containers/glass/beaker/sulphuric, /obj/effect/turf_decal/delivery, +/obj/machinery/rnd/circuit_imprinter/department/science, /turf/open/floor/plasteel, /area/science/lab) "bvz" = ( @@ -30674,7 +30670,7 @@ /area/shuttle/transport) "bwq" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Monastery Transit" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -30682,7 +30678,7 @@ /area/hallway/secondary/entry) "bwr" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Monastery Transit" }, /obj/machinery/atmospherics/pipe/simple/cyan/hidden, @@ -34038,14 +34034,14 @@ }, /area/hallway/primary/aft) "bDB" = ( -/obj/machinery/computer/aifixer{ - dir = 4 - }, /obj/machinery/airalarm{ dir = 4; locked = 0; pixel_x = -23 }, +/obj/machinery/computer/rdconsole{ + dir = 4 + }, /turf/open/floor/plasteel/darkpurple/side{ dir = 8 }, @@ -34091,6 +34087,7 @@ /area/security/checkpoint/science) "bDI" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/structure/closet/wardrobe/red, /turf/open/floor/plasteel/red/side{ dir = 4 }, @@ -34415,15 +34412,10 @@ /turf/open/floor/plasteel/white, /area/medical/virology) "bEv" = ( -/obj/structure/table, -/obj/item/storage/box/beakers{ - pixel_x = 2; - pixel_y = 2 - }, -/obj/item/storage/box/syringes, /obj/structure/extinguisher_cabinet{ pixel_x = -26 }, +/obj/machinery/rnd/protolathe/department/medical, /turf/open/floor/plasteel/whiteblue/side{ dir = 1 }, @@ -34754,7 +34746,6 @@ /turf/open/floor/plasteel/red/side, /area/security/checkpoint/science) "bEY" = ( -/obj/structure/closet/wardrobe/red, /obj/machinery/power/apc{ dir = 4; name = "Science Security APC"; @@ -34764,6 +34755,7 @@ /obj/structure/cable{ icon_state = "0-8" }, +/obj/structure/closet/secure_closet/security/science, /turf/open/floor/plasteel/red/side{ dir = 6 }, @@ -35695,7 +35687,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Research Division" }, /obj/effect/turf_decal/delivery, @@ -36114,6 +36106,11 @@ /area/medical/medbay/central) "bIg" = ( /obj/structure/table, +/obj/item/storage/box/beakers{ + pixel_x = 2; + pixel_y = 2 + }, +/obj/item/storage/box/syringes, /obj/item/storage/belt/medical{ pixel_y = 2 }, @@ -36265,7 +36262,7 @@ dir = 4 }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Research Division" }, /obj/structure/cable{ @@ -36398,7 +36395,7 @@ /turf/closed/wall/r_wall, /area/science/mixing) "bIL" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ autoclose = 0; frequency = 1449; heat_proof = 1; @@ -36730,7 +36727,7 @@ dir = 4 }, /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Research Division" }, /obj/effect/turf_decal/delivery, @@ -37392,7 +37389,7 @@ /turf/open/floor/engine/vacuum, /area/engine/atmos) "bLf" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ autoclose = 0; frequency = 1449; heat_proof = 1; @@ -39457,7 +39454,6 @@ pixel_y = -3 }, /obj/item/circuitboard/machine/destructive_analyzer, -/obj/item/circuitboard/machine/protolathe, /obj/item/circuitboard/computer/aifixer, /obj/item/circuitboard/computer/teleporter, /obj/item/circuitboard/machine/circuit_imprinter, @@ -41884,6 +41880,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/structure/closet/wardrobe/red, /turf/open/floor/plasteel/red/side{ dir = 4 }, @@ -42233,7 +42230,7 @@ /obj/structure/reagent_dispensers/peppertank{ pixel_x = 32 }, -/obj/structure/closet/wardrobe/red, +/obj/structure/closet/secure_closet/security/engine, /turf/open/floor/plasteel/red/side{ dir = 6 }, @@ -43240,6 +43237,7 @@ /obj/structure/cable{ icon_state = "0-8" }, +/obj/structure/closet/wardrobe/engineering_yellow, /turf/open/floor/plasteel, /area/engine/engineering) "bZd" = ( @@ -43901,7 +43899,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ autoclose = 0; frequency = 1449; heat_proof = 1; @@ -43924,7 +43922,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ autoclose = 0; frequency = 1449; heat_proof = 1; @@ -44922,6 +44920,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/obj/structure/reagent_dispensers/fueltank, /turf/open/floor/plasteel/yellow/side, /area/engine/engineering) "cdS" = ( @@ -44974,6 +44973,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/structure/reagent_dispensers/watertank, /turf/open/floor/plasteel/yellow/side, /area/engine/engineering) "cdY" = ( @@ -45001,7 +45001,9 @@ /turf/open/floor/plasteel, /area/engine/engineering) "ceb" = ( -/obj/structure/reagent_dispensers/watertank, +/obj/machinery/computer/rdconsole/production{ + dir = 8 + }, /turf/open/floor/plasteel, /area/engine/engineering) "cec" = ( @@ -46328,7 +46330,7 @@ /turf/closed/wall/mineral/titanium, /area/shuttle/abandoned) "cin" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Shuttle Airlock" }, /turf/open/floor/plasteel/dark, @@ -46714,7 +46716,7 @@ /turf/open/floor/plating/abductor, /area/shuttle/abandoned) "cjB" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Shuttle Airlock" }, /obj/docking_port/mobile{ @@ -47227,7 +47229,7 @@ /turf/open/floor/plasteel/dark, /area/library) "clm" = ( -/obj/structure/closet/crate/bin, +/obj/machinery/vending/kink, /turf/open/floor/plasteel/dark, /area/library) "cln" = ( @@ -50617,11 +50619,6 @@ /area/library) "czr" = ( /obj/structure/table/wood/fancy, -/obj/item/toy/cards/deck/cas/black{ - pixel_x = -2; - pixel_y = 6 - }, -/obj/item/toy/cards/deck/cas, /turf/open/floor/carpet, /area/library) "czs" = ( @@ -51252,12 +51249,25 @@ }, /turf/open/floor/plasteel, /area/quartermaster/storage) -"cCF" = ( -/obj/machinery/atmospherics/components/unary/outlet_injector/on{ - dir = 1 +"cCC" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 }, -/turf/open/floor/plating/airless, -/area/maintenance/department/chapel/monastery) +/obj/machinery/rnd/protolathe/department/cargo, +/turf/open/floor/plasteel, +/area/quartermaster/storage) +"cCD" = ( +/obj/machinery/rnd/protolathe/department/service, +/turf/open/floor/plating, +/area/crew_quarters/kitchen) +"cCE" = ( +/obj/machinery/rnd/protolathe/department/medical, +/turf/open/floor/plasteel/white, +/area/medical/medbay/central) +"cCF" = ( +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel/white, +/area/engine/gravity_generator) "cCG" = ( /obj/machinery/atmospherics/components/unary/outlet_injector/on{ dir = 4 @@ -51265,11 +51275,9 @@ /turf/open/floor/plating/airless, /area/tcommsat/computer) "cCH" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plating/airless, -/area/engine/engineering) +/obj/effect/turf_decal/bot/left, +/turf/open/floor/plasteel/white, +/area/engine/gravity_generator) "cCI" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -51329,6 +51337,38 @@ }, /turf/open/floor/plating/airless, /area/maintenance/department/chapel/monastery) +"cCS" = ( +/obj/machinery/rnd/protolathe/department/security, +/turf/open/floor/plasteel/dark, +/area/security/main) +"cCT" = ( +/obj/machinery/rnd/protolathe/department/cargo, +/turf/open/floor/plasteel, +/area/quartermaster/storage) +"cCU" = ( +/obj/machinery/rnd/circuit_imprinter, +/turf/open/floor/plasteel, +/area/engine/engineering) +"cCV" = ( +/obj/machinery/rnd/protolathe/department/engineering, +/turf/open/floor/plasteel, +/area/engine/engineering) +"cCW" = ( +/obj/machinery/vending/games, +/turf/open/floor/plasteel/dark, +/area/library) +"cCX" = ( +/obj/machinery/vending/kink, +/turf/open/floor/plating, +/area/maintenance/department/crew_quarters/dorms) +"cCY" = ( +/obj/machinery/vending/kink, +/turf/open/floor/plating, +/area/maintenance/department/engine) +"cCZ" = ( +/obj/machinery/vending/kink, +/turf/open/floor/plating, +/area/maintenance/department/engine) (1,1,1) = {" aaa @@ -65668,19 +65708,19 @@ aaa aaa aaa aaa -cgX -cgX -cgX -cgX -cgX aaa aaa aaa aaa -cgX -cgX -cgX -cgX +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -65922,24 +65962,24 @@ aaa aaa aaa aaa -cgX -cgX -cgX -cgX -cfN -cfN -cfN -cgX aaa -cgX -cgX -cgX -cgX +aaa +aaa +aaa cfN cfN -cgX -cgX -cgX +cfN +aaa +aaa +aaa +aaa +aaa +aaa +cfN +cfN +aaa +aaa +aaa aaa aaa aaa @@ -66177,18 +66217,18 @@ aaa aaa aaa aaa -cgX -cgX -cgX +aaa +aaa +aaa cfN cfN cfN cfN cfN cyM -cgX aaa -cgX +aaa +aaa cfN cfN cfN @@ -66196,9 +66236,9 @@ cfN cfN cfN cfN -cgX -cgX -cgX +aaa +aaa +aaa aaa aaa aaa @@ -66427,14 +66467,14 @@ cvX cke cky cld -cCF +cCR +aaa aaa aaa aaa aaa aaa aaa -cgX cfN cfN cfN @@ -66442,10 +66482,10 @@ cfN cfN cfN cfN -cyK -cgX +aht +aaa +aaa aaa -cgX cfN cyM cfN @@ -66455,7 +66495,7 @@ cfN cfN cfN cfN -cgX +aaa aaa aaa aaa @@ -66691,28 +66731,28 @@ aaa aaa aaa aaa -cgX +aaa cfN cfN cfN cyM cfN cyM -cgX -cyK +aaa +aht aaa aaa -cgX -cgX -cyK -cgX +aaa +aaa +aht +aaa cfN cfN cfN cfN cfN cfN -cgX +aaa aaa aaa aaa @@ -66948,28 +66988,28 @@ aaa aaa aaa aaa -cgX +aaa cfN cfN cfN -cyK -cgX -cyK -cgX +aht +aaa +aht +aaa aht aht aht aht aht aht -cgX +aaa cfN cfN cyM cfN cfN cfN -cgX +aaa aaa aaa aaa @@ -67205,11 +67245,11 @@ cfN cfN aaa aaa -cgX -cgX -cgX -cgX -cyK +aaa +aaa +aaa +aaa +aht aaa aht aaa @@ -67219,14 +67259,14 @@ aaa aaa aaa aht -cgX -cgX -cgX -cyK +aaa +aaa +aaa +aht cfN cfN -cgX -cgX +aaa +aaa aaa aaa aaa @@ -67344,7 +67384,7 @@ aaa aiu aiu aiu -apA +aoK aqf ajD aiu @@ -67479,10 +67519,10 @@ cjp cyU aht aht -cyK -cgX -cgX -cgX +aht +aaa +aaa +aaa aaa aaa aaa @@ -67980,13 +68020,13 @@ aaa aaa aaa cjp -ckW +cCW ckH cyZ ckH czl czr -czA +czr czI ckH ckH @@ -68242,7 +68282,7 @@ ckH ckH ckH czl -czs +czr czB czI czV @@ -68255,9 +68295,9 @@ aaa aaa aaa aaa -cgX -cgX -cgX +aaa +aaa +aaa aaa aaa aaa @@ -68511,11 +68551,11 @@ cjp cyU aaa aaa -cgX -cgX +aaa +aaa cfN -cgX -cgX +aaa +aaa aaa aaa aaa @@ -68768,11 +68808,11 @@ cAS cyU aht aht -cyK +aht cyM cfN cfN -cgX +aaa aaa aaa aaa @@ -69025,12 +69065,12 @@ cAT cyU aaa aaa -cgX +aaa cfN cfN cfN -cgX -cgX +aaa +aaa aaa aaa aaa @@ -69281,13 +69321,13 @@ cAK cAU cyU aaa -cgX -cgX +aaa +aaa cfN cfN cfN cfN -cgX +aaa aaa aaa aaa @@ -69538,13 +69578,13 @@ cAa cAV cyU aaa -cgX +aaa cfN cfN cfN cfN cfN -cgX +aaa aaa aaa aaa @@ -69795,13 +69835,13 @@ cAM cjp cyU aaa -cgX +aaa cfN cfN cfN cfN cfN -cgX +aaa aaa aaa aaa @@ -70052,13 +70092,13 @@ cyU cjp aht aht -cyK +aht cyM cfN cfN cfN cfN -cgX +aaa aaa aaa aaa @@ -70308,14 +70348,14 @@ cjp cyU aht aaa -cgX -cgX +aaa +aaa cfN cfN cfN cfN -cgX -cgX +aaa +aaa aaa aaa aaa @@ -70564,8 +70604,8 @@ cyU aaa aaa aht -cgX -cgX +aaa +aaa cfN cfN cfN @@ -70821,13 +70861,13 @@ cyU aht aht aht -cyK +aht cyM cfN cfN cfN cfN -cgX +aaa aaa aaa aaa @@ -71074,17 +71114,17 @@ aaa aht aaa aht -cgX -cgX -cgX -cgX -cgX +aaa +aaa +aaa +aaa +aaa cfN cfN -cgX +aaa cfN cfN -cgX +aaa aaa aaa aaa @@ -71323,25 +71363,25 @@ aaa aht aht aht -cyK -cgX -cgX -cyK -cyK -cyK +aht +aaa aaa aht -cgX +aht +aht +aaa +aht +aaa cfN cfN -cgX -cgX -cgX -cgX -cgX -cgX -cgX -cgX +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -71578,21 +71618,21 @@ aaa aaa aaa aht -cgX -cgX -cyK +aaa +aaa +aht cfN cfN cyM cfN -cyK -cgX -cyK +aht +aaa +aht cfN cfN cfN -cgX -cgX +aaa +aaa aaa aaa aaa @@ -71833,9 +71873,9 @@ cfN aaa aaa aaa -cgX -cyK -cgX +aaa +aht +aaa cfN cyM cfN @@ -71849,7 +71889,7 @@ cfN cfN cfN cfN -cgX +aaa aaa aaa aaa @@ -72089,8 +72129,8 @@ cfN aaa aaa aaa -cgX -cgX +aaa +aaa cyL cfN cfN @@ -72106,7 +72146,7 @@ cfN cfN cfN cfN -cgX +aaa aaa aaa aaa @@ -72346,7 +72386,7 @@ aaa aaa aaa aaa -cgX +aaa cfN cfN cfN @@ -72363,7 +72403,7 @@ cfN cfN cfN cfN -cgX +aaa aaa aaa aaa @@ -72603,7 +72643,7 @@ aaa aaa aaa aaa -cgX +aaa cfN cfN cfN @@ -72611,8 +72651,8 @@ cfN cfN cfN cfN -cgX -cgX +aaa +aaa cfN cfN cfN @@ -72620,7 +72660,7 @@ cfN cfN cfN cfN -cgX +aaa aaa aaa aaa @@ -72860,24 +72900,24 @@ aaa aaa aaa aaa -cgX -cgX -cgX +aaa +aaa +aaa cfN cfN cfN -cgX -cgX -cgX -cgX -cgX -cgX +aaa +aaa +aaa +aaa +aaa +aaa cfN cfN cfN cfN -cgX -cgX +aaa +aaa aaa aaa aaa @@ -73119,21 +73159,21 @@ aaa aaa aaa aaa -cgX -cgX -cgX -cgX -cgX aaa aaa aaa aaa -cgX -cgX -cgX -cgX -cgX -cgX +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -73833,7 +73873,7 @@ bvb bDj bEo bva -bva +cCY bHQ bJg bKl @@ -74089,7 +74129,7 @@ bnv bnv bDi bmf -bsn +bva bva bHS bJh @@ -77103,10 +77143,10 @@ air agP agP agP -akS +cCS alH ams -alH +akS anP agP apg @@ -78988,7 +79028,7 @@ cCF cCH bTn bPB -bDi +cCZ bVC bQj bPA @@ -79499,7 +79539,7 @@ bPB bQp cCH cCF -cCQ +cCP bTp bPB bUI @@ -79717,7 +79757,7 @@ aRN aRN aZZ bbf -aRN +cCD aRN beo aRN @@ -79778,7 +79818,7 @@ bZA cgs cgQ chv -bPm +ahi abI abI abI @@ -81057,7 +81097,7 @@ cam cam cdQ cet -cCH +cCI cfV cfU cgu @@ -81571,18 +81611,18 @@ ccc ccV cdR cet -cCJ +cCI cfV cfU cgv cgV -cgW -cgW -cgX +bBW +bBW +aaa cgV -cgX -cgW -cgW +aaa +bBW +bBW cgV cfV bTE @@ -81832,15 +81872,15 @@ cfa cfa cfa cgv -cgW -cgW -cgW -cgX -chy -cgX -cgW -cgW -cgW +bBW +bBW +bBW +aaa +abI +aaa +bBW +bBW +bBW cfV bTE abI @@ -82089,15 +82129,15 @@ cfb cfu cfa cgv -cgW -cgW -cgX -cgX -chy -cgX -cgX -cgW -cgW +bBW +bBW +aaa +aaa +abI +aaa +aaa +bBW +bBW cfV bTE abI @@ -82346,15 +82386,15 @@ cfc cfv cfa cgv -cgX -cgX -cgX +aaa +aaa +aaa cii cis ciG -cgX -cgX -cgX +aaa +aaa +aaa cfV bTE abI @@ -82604,13 +82644,13 @@ cfw cfW cgw cgV -chy -chy +abI +abI cij cit ciH -chy -chy +abI +abI cgV cfV bTE @@ -82860,15 +82900,15 @@ cfe cfx cfa cgv -cgX -cgX -cgX +aaa +aaa +aaa cik ciu ciI -cgX -cgX -cgX +aaa +aaa +aaa cfV bTE aaa @@ -83117,15 +83157,15 @@ cey cfy cfa cgv -cgW -cgW -cgX -cgX -chy -cgX -cgX -cgW -cgW +bBW +bBW +aaa +aaa +abI +aaa +aaa +bBW +bBW cfV bTE aaa @@ -83374,15 +83414,15 @@ cfa cfa cfa cgv -cgW -cgW -cgX -cgX -chy -cgX -cgX -cgW -cgW +bBW +bBW +aaa +aaa +abI +aaa +aaa +bBW +bBW cfV bTE aaa @@ -83627,18 +83667,18 @@ cch cdc cdX cet -cCK +cCI cfV cfU cgv cgV -cgW -cgX -cgX +bBW +aaa +aaa cgV -cgX -cgW -cgW +aaa +bBW +bBW cgV cfV bTE @@ -83884,7 +83924,7 @@ cam cam cdQ cet -cCL +cCI cfV cfV cgv @@ -84141,7 +84181,7 @@ cci cam cdQ cet -cCM +cCI cfV cfU cgx @@ -84358,10 +84398,10 @@ bjq cqh bjo cCl -cCq -cCs -cCv -cCy +cCl +cCl +cCl +cCl bxa byD bAm @@ -84614,11 +84654,11 @@ blv bkn cqi boP -cCm +cCl brp bsQ buo -cCz +cCl bxb byE bAn @@ -84871,10 +84911,10 @@ blw bkn cqi boQ -cCn +cCl brq cCt -cCw +cCt bvv bxc byF @@ -85128,7 +85168,7 @@ blx bkn bnI boR -cCo +cCl brr bsR bup @@ -85167,7 +85207,7 @@ cah cbq cam cam -cea +cav bXk bXk bXk @@ -85420,10 +85460,10 @@ bXk bTE bZc bZJ -cay -cbr ccl -cam +cbr +cCU +cCV ceb bXk aaa @@ -86156,10 +86196,10 @@ blA bmJ bnL boU -cCp -cCr -cCu -cCx +cCl +cCl +cCl +cCl bqb bxh bqb @@ -86617,8 +86657,8 @@ aaa aaa aht cBU -cBZ -cCb +cBU +cBU apT apT apT @@ -86873,7 +86913,7 @@ aaa aaa aaa aht -cBV +cBU aoA apq apU @@ -87130,7 +87170,7 @@ aaa aaa aaa aht -cBW +cBU aoB apr apV @@ -87138,7 +87178,7 @@ aqR arY atb aug -cCj +cBU awk axn axn @@ -87387,7 +87427,7 @@ aaa aaa aaa aht -cBX +cBU aoC aps apW @@ -87644,11 +87684,11 @@ aaa aaa aaa aht -cBY -cCa -cCc -cCd -cCe +cBU +cBU +cBU +cBU +cBU asa atd aui @@ -87905,11 +87945,11 @@ aaa aaa aaa aaa -cCf -cCg -cCh -cCi -cCk +cBU +cBU +cBU +cBU +cBU awd axi aaa @@ -88661,7 +88701,7 @@ aaa aaa aaa aiU -ajv +cCX aju ajt alQ @@ -90264,7 +90304,7 @@ aNR bix aFi bkx -blO +blM bmU bnT bpc @@ -91546,7 +91586,7 @@ bdI bbI bhr bbI -biA +aTx bjw bkB blS @@ -92564,7 +92604,7 @@ aVB aWA aXy aYB -aTm +cCT baF bbI bcG diff --git a/_maps/map_files/debug/runtimestation.dmm b/_maps/map_files/debug/runtimestation.dmm index 4692a11ef3..0ef75448e6 100644 --- a/_maps/map_files/debug/runtimestation.dmm +++ b/_maps/map_files/debug/runtimestation.dmm @@ -106,10 +106,10 @@ /obj/structure/cable{ icon_state = "0-4" }, -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 9 }, +/turf/open/floor/plasteel, /area/engine/gravity_generator) "at" = ( /obj/machinery/power/apc{ @@ -123,10 +123,10 @@ /obj/structure/cable{ icon_state = "0-2" }, -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 5 }, +/turf/open/floor/plasteel, /area/engine/gravity_generator) "au" = ( /obj/effect/spawner/structure/window/reinforced, @@ -213,19 +213,19 @@ /obj/machinery/light{ dir = 8 }, -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/turf/open/floor/plasteel, /area/engine/gravity_generator) "aH" = ( /obj/structure/cable{ icon_state = "1-2" }, -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/turf/open/floor/plasteel, /area/engine/gravity_generator) "aI" = ( /obj/effect/spawner/structure/window/reinforced, @@ -255,10 +255,10 @@ dir = 4 }, /obj/machinery/portable_atmospherics/canister/nitrous_oxide, -/turf/open/floor/plasteel{ +/obj/effect/turf_decal/bot{ dir = 2 }, -/obj/effect/turf_decal/bot{ +/turf/open/floor/plasteel{ dir = 2 }, /area/engine/atmos) @@ -324,19 +324,19 @@ /obj/structure/cable{ icon_state = "4-8" }, -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/turf/open/floor/plasteel, /area/engine/gravity_generator) "aW" = ( /obj/structure/cable{ icon_state = "1-8" }, -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/turf/open/floor/plasteel, /area/engine/gravity_generator) "aX" = ( /obj/machinery/door/airlock/glass_engineering{ @@ -367,10 +367,10 @@ dir = 4 }, /obj/machinery/portable_atmospherics/canister, -/turf/open/floor/plasteel{ +/obj/effect/turf_decal/bot{ dir = 2 }, -/obj/effect/turf_decal/bot{ +/turf/open/floor/plasteel{ dir = 2 }, /area/engine/atmos) @@ -397,16 +397,16 @@ /turf/open/floor/plating, /area/engine/engineering) "bg" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/turf/open/floor/plasteel, /area/engine/gravity_generator) "bh" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/turf/open/floor/plasteel, /area/engine/gravity_generator) "bi" = ( /obj/machinery/gravity_generator/main/station, @@ -468,17 +468,17 @@ /turf/open/floor/plating, /area/engine/engineering) "bq" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 10 }, +/turf/open/floor/plasteel, /area/engine/gravity_generator) "br" = ( /obj/structure/closet/radiation, -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 6 }, +/turf/open/floor/plasteel, /area/engine/gravity_generator) "bs" = ( /obj/structure/cable{ @@ -836,7 +836,7 @@ /turf/open/floor/plasteel, /area/bridge) "cx" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "cy" = ( @@ -961,7 +961,7 @@ /turf/closed/wall/r_wall, /area/construction) "cQ" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/plasteel, /area/construction) "cR" = ( @@ -982,7 +982,7 @@ /turf/closed/wall/r_wall, /area/storage/primary) "cV" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/plasteel, /area/storage/primary) "cW" = ( @@ -996,25 +996,25 @@ dir = 8; pixel_x = -24 }, -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/corner, +/turf/open/floor/plasteel, /area/construction) "cX" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, /area/construction) "cY" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, /area/construction) "cZ" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/corner{ dir = 1 }, +/turf/open/floor/plasteel, /area/construction) "da" = ( /obj/machinery/airalarm{ @@ -1036,10 +1036,10 @@ /turf/open/floor/plating, /area/storage/primary) "dc" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/turf/open/floor/plasteel, /area/storage/primary) "dd" = ( /turf/open/floor/plasteel{ @@ -1083,10 +1083,10 @@ }, /area/storage/primary) "dk" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/turf/open/floor/plasteel, /area/storage/primary) "dl" = ( /turf/open/floor/plating, @@ -1095,10 +1095,10 @@ /obj/machinery/light{ dir = 8 }, -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/turf/open/floor/plasteel, /area/construction) "dn" = ( /turf/open/floor/plating, @@ -1107,10 +1107,10 @@ /obj/machinery/light{ dir = 4 }, -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/turf/open/floor/plasteel, /area/construction) "dp" = ( /obj/machinery/light{ @@ -1160,50 +1160,50 @@ /turf/open/floor/plating, /area/storage/primary) "dy" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/turf/open/floor/plasteel, /area/construction) "dz" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/turf/open/floor/plasteel, /area/construction) "dA" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 10 }, +/turf/open/floor/plasteel, /area/storage/primary) "dB" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, /area/storage/primary) "dC" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 6 }, +/turf/open/floor/plasteel, /area/storage/primary) "dD" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 9 }, +/turf/open/floor/plasteel, /area/storage/primary) "dE" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/turf/open/floor/plasteel, /area/storage/primary) "dF" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 5 }, +/turf/open/floor/plasteel, /area/storage/primary) "dG" = ( /obj/machinery/door/airlock, @@ -1221,22 +1221,22 @@ /turf/open/floor/plasteel, /area/storage/primary) "dK" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/corner{ dir = 8 }, +/turf/open/floor/plasteel, /area/construction) "dL" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/turf/open/floor/plasteel, /area/construction) "dM" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/corner{ dir = 4 }, +/turf/open/floor/plasteel, /area/construction) "dN" = ( /obj/structure/table, diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index 4a0f5fdb02..27198fe072 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -8108,6 +8108,7 @@ name = "syndicate infiltrator"; port_direction = 1; roundstart_move = "syndicate_away"; + hidden = 1; width = 18 }, /obj/structure/fans/tiny, @@ -9834,7 +9835,7 @@ /area/wizard_station) "zQ" = ( /obj/effect/decal/cleanable/blood/splatter, -/mob/living/simple_animal/hostile/creature{ +/mob/living/simple_animal/hostile/netherworld{ name = "Experiment 35b" }, /turf/open/floor/grass, @@ -11604,7 +11605,7 @@ /turf/open/floor/plasteel, /area/wizard_station) "Ej" = ( -/obj/vehicle/scooter/skateboard{ +/obj/vehicle/ridden/scooter/skateboard{ icon_state = "skateboard"; dir = 4 }, diff --git a/_maps/map_files/generic/City_of_Cogs.dmm b/_maps/map_files/generic/City_of_Cogs.dmm index 68f45f5472..421d03cf9d 100644 --- a/_maps/map_files/generic/City_of_Cogs.dmm +++ b/_maps/map_files/generic/City_of_Cogs.dmm @@ -300,6 +300,10 @@ /obj/item/clockwork/component/vanguard_cogwheel/onyx_prism, /turf/open/indestructible/reebe_void, /area/reebe) +"bj" = ( +/obj/structure/destructible/clockwork/eminence_spire, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) (1,1,1) = {" aa @@ -31739,7 +31743,7 @@ aj aj ai aj -aj +az aj ai aj @@ -31996,7 +32000,7 @@ aj aj ap aj -az +aj aj ap aj @@ -32253,7 +32257,7 @@ aj aj ai aj -aj +bj aj ai aj diff --git a/_maps/metastation.dm b/_maps/metastation.dm index 3d13caf6d2..d64d7a4900 100644 --- a/_maps/metastation.dm +++ b/_maps/metastation.dm @@ -1 +1 @@ -#define FORCE_MAP "_maps/metastation.json" \ No newline at end of file +#define FORCE_MAP "_maps/metastation.json" diff --git a/_maps/omegastation.dm b/_maps/omegastation.dm index ea4a0c155f..3fda7f2454 100644 --- a/_maps/omegastation.dm +++ b/_maps/omegastation.dm @@ -1 +1 @@ -#define FORCE_MAP "_maps/omegastation.json" \ No newline at end of file +#define FORCE_MAP "_maps/omegastation.json" diff --git a/_maps/pubbystation.dm b/_maps/pubbystation.dm index 867d0ddb17..b01ae7ecbb 100644 --- a/_maps/pubbystation.dm +++ b/_maps/pubbystation.dm @@ -1 +1 @@ -#define FORCE_MAP "_maps/pubbystation.json" \ No newline at end of file +#define FORCE_MAP "_maps/pubbystation.json" diff --git a/_maps/runtimestation.dm b/_maps/runtimestation.dm index 612644e5f0..352d4c1afc 100644 --- a/_maps/runtimestation.dm +++ b/_maps/runtimestation.dm @@ -1 +1 @@ -#define FORCE_MAP "_maps/runtimestation.json" \ No newline at end of file +#define FORCE_MAP "_maps/runtimestation.json" diff --git a/_maps/shuttles/emergency_bar.dmm b/_maps/shuttles/emergency_bar.dmm index a117bdbec8..6ba0875a66 100644 --- a/_maps/shuttles/emergency_bar.dmm +++ b/_maps/shuttles/emergency_bar.dmm @@ -131,7 +131,7 @@ /turf/closed/wall/mineral/titanium, /area/shuttle/escape) "az" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Cockpit"; req_access_txt = "19" }, @@ -201,7 +201,7 @@ /turf/open/floor/mineral/plastitanium/brig, /area/shuttle/escape) "aJ" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Brig"; req_access_txt = "2" }, diff --git a/_maps/shuttles/emergency_birdboat.dmm b/_maps/shuttles/emergency_birdboat.dmm index 460211f03c..3b2617bfe1 100644 --- a/_maps/shuttles/emergency_birdboat.dmm +++ b/_maps/shuttles/emergency_birdboat.dmm @@ -141,7 +141,7 @@ /turf/open/floor/mineral/plastitanium/brig, /area/shuttle/escape) "aA" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/plasteel/white, /area/shuttle/escape) "aB" = ( diff --git a/_maps/shuttles/emergency_box.dmm b/_maps/shuttles/emergency_box.dmm index ab0c739939..65cc9803cb 100644 --- a/_maps/shuttles/emergency_box.dmm +++ b/_maps/shuttles/emergency_box.dmm @@ -122,7 +122,7 @@ /turf/closed/wall/mineral/titanium, /area/shuttle/escape) "ay" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Cockpit"; req_access_txt = "19" }, @@ -185,7 +185,7 @@ /turf/open/floor/mineral/plastitanium/brig, /area/shuttle/escape) "aH" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Brig"; req_access_txt = "2" }, @@ -297,7 +297,7 @@ /turf/closed/wall/mineral/titanium, /area/shuttle/escape) "aZ" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Infirmary" }, /turf/open/floor/mineral/titanium/blue, diff --git a/_maps/shuttles/emergency_cere.dmm b/_maps/shuttles/emergency_cere.dmm index bbdbd8a763..2090fbe199 100644 --- a/_maps/shuttles/emergency_cere.dmm +++ b/_maps/shuttles/emergency_cere.dmm @@ -244,7 +244,7 @@ /turf/open/floor/plasteel/darkred, /area/shuttle/escape) "aR" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Cockpit"; req_access_txt = "19" }, @@ -423,7 +423,7 @@ /turf/open/floor/mineral/plastitanium/brig, /area/shuttle/escape) "bq" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Brig"; req_access_txt = "2" }, diff --git a/_maps/shuttles/emergency_clown.dmm b/_maps/shuttles/emergency_clown.dmm index 96bd21e8b7..b0cd4e7113 100644 --- a/_maps/shuttles/emergency_clown.dmm +++ b/_maps/shuttles/emergency_clown.dmm @@ -99,7 +99,7 @@ /turf/open/floor/noslip, /area/shuttle/escape) "as" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Premium Lounge"; req_access_txt = "0" }, @@ -143,7 +143,7 @@ /turf/open/floor/mineral/plastitanium/brig, /area/shuttle/escape) "aA" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Greentext"; req_access_txt = "0" }, @@ -275,7 +275,7 @@ /turf/open/floor/bluespace, /area/shuttle/escape) "aU" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Infirmary" }, /turf/open/floor/bluespace, diff --git a/_maps/shuttles/emergency_discoinferno.dmm b/_maps/shuttles/emergency_discoinferno.dmm new file mode 100644 index 0000000000..ec42f163f1 --- /dev/null +++ b/_maps/shuttles/emergency_discoinferno.dmm @@ -0,0 +1,497 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/template_noop, +/area/template_noop) +"b" = ( +/turf/closed/wall/mineral/plastitanium, +/area/shuttle/escape) +"c" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plasteel/elevatorshaft, +/area/shuttle/escape) +"d" = ( +/obj/structure/table/wood, +/obj/item/device/flashlight/lamp/green, +/turf/open/floor/mineral/gold, +/area/shuttle/escape) +"e" = ( +/obj/structure/chair/comfy/brown{ + dir = 1 + }, +/turf/open/floor/mineral/gold, +/area/shuttle/escape) +"f" = ( +/obj/machinery/computer/emergency_shuttle, +/turf/open/floor/mineral/gold, +/area/shuttle/escape) +"g" = ( +/obj/structure/table/wood, +/obj/item/storage/fancy/cigarettes/cigars/havana, +/obj/item/lighter{ + pixel_x = -4; + pixel_y = 6 + }, +/turf/open/floor/mineral/gold, +/area/shuttle/escape) +"h" = ( +/obj/machinery/computer/atmos_alert{ + dir = 4 + }, +/turf/open/floor/mineral/gold, +/area/shuttle/escape) +"i" = ( +/obj/structure/chair/comfy/brown{ + dir = 8 + }, +/turf/open/floor/mineral/gold, +/area/shuttle/escape) +"j" = ( +/turf/open/floor/mineral/gold, +/area/shuttle/escape) +"k" = ( +/obj/structure/chair/comfy/brown{ + dir = 4 + }, +/turf/open/floor/mineral/gold, +/area/shuttle/escape) +"l" = ( +/obj/machinery/computer/security{ + dir = 8 + }, +/turf/open/floor/mineral/gold, +/area/shuttle/escape) +"m" = ( +/obj/machinery/computer/crew{ + dir = 4 + }, +/turf/open/floor/mineral/gold, +/area/shuttle/escape) +"n" = ( +/obj/structure/table/wood/poker, +/obj/item/storage/box/drinkingglasses, +/obj/item/reagent_containers/food/drinks/bottle/whiskey, +/obj/machinery/light, +/turf/open/floor/mineral/gold, +/area/shuttle/escape) +"o" = ( +/obj/machinery/computer/communications{ + dir = 8 + }, +/turf/open/floor/mineral/gold, +/area/shuttle/escape) +"p" = ( +/obj/machinery/door/airlock/gold{ + req_access_txt = "19" + }, +/turf/open/floor/mineral/gold, +/area/shuttle/escape) +"q" = ( +/obj/structure/statue/plasma/scientist{ + anchored = 1; + oreAmount = 50 + }, +/turf/open/floor/light/colour_cycle, +/area/shuttle/escape) +"r" = ( +/turf/open/floor/mineral/plasma, +/area/shuttle/escape) +"s" = ( +/turf/open/floor/mineral/silver, +/area/shuttle/escape) +"t" = ( +/turf/open/floor/light/colour_cycle, +/area/shuttle/escape) +"u" = ( +/obj/docking_port/mobile/emergency{ + name = "Disco Inferno"; + timid = 1 + }, +/obj/machinery/door/airlock/gold{ + armor = list("melee" = 30, "bullet" = 30, "laser" = 20, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100); + heat_proof = 1; + resistance_flags = 2 + }, +/turf/open/floor/mineral/plasma, +/area/shuttle/escape) +"v" = ( +/obj/machinery/disco{ + anchored = 1; + req_access = null + }, +/turf/open/floor/light/colour_cycle, +/area/shuttle/escape) +"w" = ( +/obj/machinery/door/airlock/gold, +/turf/open/floor/wood, +/area/shuttle/escape) +"x" = ( +/turf/open/floor/wood, +/area/shuttle/escape) +"y" = ( +/turf/open/floor/carpet, +/area/shuttle/escape) +"z" = ( +/obj/structure/chair/comfy/brown{ + dir = 2 + }, +/turf/open/floor/carpet, +/area/shuttle/escape) +"A" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/drinks/bottle/cognac, +/turf/open/floor/wood, +/area/shuttle/escape) +"B" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/drinks/bottle/vodka/badminka, +/turf/open/floor/wood, +/area/shuttle/escape) +"C" = ( +/obj/machinery/computer/slot_machine, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/wood, +/area/shuttle/escape) +"D" = ( +/obj/structure/chair/comfy/brown{ + dir = 8 + }, +/turf/open/floor/wood, +/area/shuttle/escape) +"E" = ( +/obj/structure/chair/comfy/brown{ + dir = 4 + }, +/turf/open/floor/carpet, +/area/shuttle/escape) +"F" = ( +/obj/structure/table/wood/poker, +/obj/item/toy/cards/deck, +/turf/open/floor/carpet, +/area/shuttle/escape) +"G" = ( +/obj/structure/chair/comfy/brown{ + dir = 8 + }, +/turf/open/floor/carpet, +/area/shuttle/escape) +"H" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass, +/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass, +/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass, +/obj/machinery/light{ + dir = 4 + }, +/obj/item/coin/plasma, +/obj/item/coin/plasma, +/turf/open/floor/wood, +/area/shuttle/escape) +"I" = ( +/obj/machinery/computer/slot_machine{ + dir = 3 + }, +/turf/open/floor/wood, +/area/shuttle/escape) +"J" = ( +/obj/structure/chair/comfy/brown{ + dir = 1 + }, +/turf/open/floor/carpet, +/area/shuttle/escape) +"K" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/drinks/bottle/absinthe, +/turf/open/floor/wood, +/area/shuttle/escape) +"L" = ( +/obj/structure/table/wood/fancy, +/obj/item/reagent_containers/food/drinks/bottle/lizardwine, +/turf/open/floor/wood, +/area/shuttle/escape) +"M" = ( +/obj/structure/shuttle/engine/heater, +/obj/structure/window/plasma/reinforced{ + dir = 1 + }, +/turf/open/floor/plating/airless, +/area/shuttle/escape) +"N" = ( +/obj/structure/shuttle/engine/propulsion, +/turf/open/floor/plating/airless, +/area/shuttle/escape) +"O" = ( +/turf/closed/wall/mineral/plastitanium/nodiagonal, +/area/shuttle/escape) +"P" = ( +/turf/closed/wall/mineral/plastitanium/nodiagonal, +/area/shuttle/escape) +"Q" = ( +/turf/closed/wall/mineral/plastitanium/nodiagonal, +/area/shuttle/escape) + +(1,1,1) = {" +a +a +a +a +b +b +b +c +b +u +b +c +c +c +b +O +b +w +b +c +b +a +"} +(2,1,1) = {" +a +b +b +b +O +q +r +r +r +r +j +r +r +r +r +q +c +x +C +I +b +b +"} +(3,1,1) = {" +b +b +h +m +c +r +r +r +r +s +j +s +r +r +r +r +c +x +D +D +M +N +"} +(4,1,1) = {" +c +d +i +i +c +r +r +r +j +j +t +j +j +r +r +r +c +x +x +x +M +N +"} +(5,1,1) = {" +c +e +j +j +c +r +r +s +j +t +t +t +j +s +r +r +c +y +E +y +M +N +"} +(6,1,1) = {" +c +f +j +n +c +r +j +j +t +t +v +t +t +j +j +r +c +z +F +J +M +N +"} +(7,1,1) = {" +c +e +j +j +p +r +r +s +j +t +t +t +j +s +r +r +c +y +G +y +M +N +"} +(8,1,1) = {" +c +g +k +k +c +r +r +r +j +j +t +j +j +r +r +r +c +x +x +x +M +N +"} +(9,1,1) = {" +b +b +l +o +c +r +r +r +r +s +j +s +r +r +r +r +c +A +x +K +M +N +"} +(10,1,1) = {" +a +b +b +b +O +q +r +r +r +r +j +r +r +r +r +q +c +B +H +L +b +b +"} +(11,1,1) = {" +a +a +a +a +b +b +b +c +b +b +b +c +c +c +b +b +b +c +b +c +b +a +"} diff --git a/_maps/shuttles/emergency_goon.dmm b/_maps/shuttles/emergency_goon.dmm index 7a80420f56..25e4e603eb 100644 --- a/_maps/shuttles/emergency_goon.dmm +++ b/_maps/shuttles/emergency_goon.dmm @@ -104,7 +104,7 @@ /turf/open/floor/mineral/titanium, /area/shuttle/escape) "w" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Infirmary" }, /turf/open/floor/mineral/titanium, @@ -157,7 +157,7 @@ /turf/closed/wall/mineral/titanium, /area/shuttle/escape) "E" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Cockpit"; req_access_txt = "19" }, @@ -193,7 +193,7 @@ /turf/open/floor/mineral/plastitanium/brig, /area/shuttle/escape) "K" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Brig"; req_access_txt = "2" }, diff --git a/_maps/shuttles/emergency_pubby.dmm b/_maps/shuttles/emergency_pubby.dmm index be05c317c8..9c84d5883b 100644 --- a/_maps/shuttles/emergency_pubby.dmm +++ b/_maps/shuttles/emergency_pubby.dmm @@ -149,7 +149,7 @@ /turf/closed/wall/mineral/titanium, /area/shuttle/escape) "aB" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Cockpit"; req_access_txt = "19" }, @@ -169,7 +169,7 @@ /turf/open/floor/plating, /area/shuttle/escape) "aE" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Cargo Hold"; req_access_txt = "0" }, @@ -182,7 +182,7 @@ /turf/open/floor/mineral/titanium/blue, /area/shuttle/escape) "aG" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Brig"; req_access_txt = "2" }, @@ -262,7 +262,7 @@ /turf/open/floor/mineral/titanium/blue, /area/shuttle/escape) "aU" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Infirmary" }, /turf/open/floor/mineral/titanium/blue, diff --git a/_maps/shuttles/emergency_raven.dmm b/_maps/shuttles/emergency_raven.dmm index a48f766a08..c8178fd9a2 100644 --- a/_maps/shuttles/emergency_raven.dmm +++ b/_maps/shuttles/emergency_raven.dmm @@ -893,7 +893,7 @@ }, /area/shuttle/escape) "cf" = ( -/obj/machinery/door/airlock/glass_titanium{ +/obj/machinery/door/airlock/titanium/glass{ name = "Shuttle Engine Room" }, /turf/open/floor/plasteel/darkgreen/side{ @@ -901,7 +901,7 @@ }, /area/shuttle/escape) "cg" = ( -/obj/machinery/door/airlock/glass_titanium{ +/obj/machinery/door/airlock/titanium/glass{ name = "Shuttle Engine Room" }, /turf/open/floor/plasteel/darkgreen/side{ diff --git a/_maps/shuttles/emergency_russiafightpit.dmm b/_maps/shuttles/emergency_russiafightpit.dmm index 127c22daab..1adc770925 100644 --- a/_maps/shuttles/emergency_russiafightpit.dmm +++ b/_maps/shuttles/emergency_russiafightpit.dmm @@ -117,7 +117,7 @@ /turf/closed/wall/rust, /area/shuttle/escape) "at" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Glorious Leaders"; req_access_txt = "19" }, diff --git a/_maps/shuttles/emergency_scrapheap.dmm b/_maps/shuttles/emergency_scrapheap.dmm index 53733b1437..c2452c1761 100644 --- a/_maps/shuttles/emergency_scrapheap.dmm +++ b/_maps/shuttles/emergency_scrapheap.dmm @@ -95,7 +95,7 @@ /turf/open/floor/mineral/plastitanium/brig, /area/shuttle/escape) "ar" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Cockpit"; req_access_txt = "19" }, @@ -148,7 +148,7 @@ /area/shuttle/escape) "az" = ( /obj/structure/grille, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Brig"; req_access_txt = "2" }, diff --git a/_maps/shuttles/emergency_wabbajack.dmm b/_maps/shuttles/emergency_wabbajack.dmm index 87e90155e8..9c7fe55f74 100644 --- a/_maps/shuttles/emergency_wabbajack.dmm +++ b/_maps/shuttles/emergency_wabbajack.dmm @@ -139,7 +139,7 @@ /turf/open/floor/mineral/titanium, /area/shuttle/escape) "aB" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Emergency Shuttle Brig"; req_access_txt = "2" }, @@ -255,7 +255,7 @@ /turf/open/floor/mineral/titanium, /area/shuttle/escape) "aU" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/mineral/titanium/blue, /area/shuttle/escape) "aV" = ( diff --git a/_maps/shuttles/whiteship_box.dmm b/_maps/shuttles/whiteship_box.dmm index 8f52b0bf49..f1c6c838b1 100644 --- a/_maps/shuttles/whiteship_box.dmm +++ b/_maps/shuttles/whiteship_box.dmm @@ -110,7 +110,7 @@ /turf/open/floor/mineral/titanium, /area/shuttle/abandoned) "aw" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/plating, /area/shuttle/abandoned) "ax" = ( @@ -220,7 +220,7 @@ /turf/open/floor/mineral/titanium, /area/shuttle/abandoned) "aR" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/mineral/titanium, /area/shuttle/abandoned) "aS" = ( @@ -288,7 +288,7 @@ /turf/open/floor/mineral/titanium, /area/shuttle/abandoned) "be" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/mineral/titanium, /area/shuttle/abandoned) "bf" = ( diff --git a/_maps/shuttles/whiteship_delta.dmm b/_maps/shuttles/whiteship_delta.dmm index 5961fef79f..78dabd2576 100644 --- a/_maps/shuttles/whiteship_delta.dmm +++ b/_maps/shuttles/whiteship_delta.dmm @@ -584,10 +584,8 @@ desc = "A thin layer of dust coating the floor."; name = "dust" }, -/obj/machinery/door/airlock{ - glass = 1; - name = "Dormitory"; - opacity = 0 +/obj/machinery/door/airlock/glass{ + name = "Dormitory" }, /turf/open/floor/plasteel/neutral, /area/shuttle/abandoned) @@ -722,10 +720,8 @@ desc = "A thin layer of dust coating the floor."; name = "dust" }, -/obj/machinery/door/airlock{ - glass = 1; - name = "Crew Quarters"; - opacity = 0 +/obj/machinery/door/airlock/glass{ + name = "Crew Quarters" }, /turf/open/floor/plasteel/neutral/side{ dir = 1 diff --git a/_maps/shuttles/whiteship_meta.dmm b/_maps/shuttles/whiteship_meta.dmm index 4ac62717c0..96f6e7e3b4 100644 --- a/_maps/shuttles/whiteship_meta.dmm +++ b/_maps/shuttles/whiteship_meta.dmm @@ -1134,7 +1134,6 @@ desc = "A thin layer of dust coating the floor."; name = "dust" }, -/obj/item/device/mass_spectrometer, /turf/open/floor/mineral/titanium, /area/shuttle/abandoned) "bW" = ( diff --git a/_maps/shuttles/whiteship_pubby.dmm b/_maps/shuttles/whiteship_pubby.dmm index f76c0bb251..1ea9db3063 100644 --- a/_maps/shuttles/whiteship_pubby.dmm +++ b/_maps/shuttles/whiteship_pubby.dmm @@ -12,7 +12,7 @@ /turf/closed/wall/mineral/titanium, /area/shuttle/abandoned) "d" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Shuttle Airlock" }, /turf/open/floor/plasteel/dark, @@ -81,7 +81,7 @@ /turf/open/floor/plating/abductor, /area/shuttle/abandoned) "o" = ( -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Shuttle Airlock" }, /obj/docking_port/mobile{ diff --git a/_maps/templates/medium_shuttle1.dmm b/_maps/templates/medium_shuttle1.dmm index aea32eb2f4..4b2df43281 100644 --- a/_maps/templates/medium_shuttle1.dmm +++ b/_maps/templates/medium_shuttle1.dmm @@ -49,7 +49,7 @@ name = "Shuttle" }) "h" = ( -/obj/machinery/door/airlock/glass_external, +/obj/machinery/door/airlock/external/glass, /turf/open/floor/plating, /area/ruin/powered{ name = "Shuttle" @@ -65,7 +65,7 @@ name = "Shuttle" }) "k" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/plasteel/dark, /area/ruin/powered{ name = "Shuttle" @@ -89,7 +89,7 @@ name = "Shuttle" }) "o" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/plasteel, /area/ruin/powered{ name = "Shuttle" diff --git a/_maps/templates/medium_shuttle2.dmm b/_maps/templates/medium_shuttle2.dmm index f676819f8a..5039f5174c 100644 --- a/_maps/templates/medium_shuttle2.dmm +++ b/_maps/templates/medium_shuttle2.dmm @@ -75,7 +75,7 @@ name = "Shuttle" }) "l" = ( -/obj/machinery/door/airlock/glass_external, +/obj/machinery/door/airlock/external/glass, /turf/open/floor/plating, /area/ruin/powered{ name = "Shuttle" @@ -86,7 +86,7 @@ name = "Shuttle" }) "n" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/plasteel/dark, /area/ruin/powered{ name = "Shuttle" diff --git a/_maps/templates/medium_shuttle3.dmm b/_maps/templates/medium_shuttle3.dmm index 61842f022b..edc267f44a 100644 --- a/_maps/templates/medium_shuttle3.dmm +++ b/_maps/templates/medium_shuttle3.dmm @@ -62,7 +62,7 @@ name = "Shuttle" }) "j" = ( -/obj/machinery/door/airlock/glass_external, +/obj/machinery/door/airlock/external/glass, /turf/open/floor/plating, /area/ruin/powered{ name = "Shuttle" @@ -100,7 +100,7 @@ name = "Shuttle" }) "p" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/plasteel, /area/ruin/powered{ name = "Shuttle" diff --git a/_maps/templates/medium_shuttle4.dmm b/_maps/templates/medium_shuttle4.dmm index d3af27d0c4..bfb7f5d88e 100644 --- a/_maps/templates/medium_shuttle4.dmm +++ b/_maps/templates/medium_shuttle4.dmm @@ -11,7 +11,7 @@ /turf/closed/indestructible/oldshuttle, /area/ruin/powered) "d" = ( -/obj/machinery/door/airlock/glass, +/obj/machinery/door/airlock/public/glass, /turf/open/floor/oldshuttle, /area/ruin/powered) "e" = ( diff --git a/_maps/templates/pirate_ship.dmm b/_maps/templates/pirate_ship.dmm index a2170c29ee..e9be381c99 100644 --- a/_maps/templates/pirate_ship.dmm +++ b/_maps/templates/pirate_ship.dmm @@ -929,7 +929,7 @@ /area/shuttle/pirate) "cg" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ name = "Bar" }, /turf/open/floor/plasteel, @@ -1740,7 +1740,7 @@ icon_state = "1-2"; pixel_y = 0 }, -/obj/machinery/door/airlock/glass{ +/obj/machinery/door/airlock/public/glass{ heat_proof = 1; id_tag = "pirateturbinebolt"; locked = 1; diff --git a/_maps/templates/shelter_1.dmm b/_maps/templates/shelter_1.dmm index 42e8ec7540..fff5f4c2cd 100644 --- a/_maps/templates/shelter_1.dmm +++ b/_maps/templates/shelter_1.dmm @@ -61,7 +61,7 @@ /area/survivalpod) "n" = ( /obj/structure/fans/tiny, -/obj/machinery/door/airlock/survival_pod, +/obj/machinery/door/airlock/survival_pod/glass, /turf/open/floor/pod, /area/survivalpod) "o" = ( diff --git a/_maps/templates/shelter_2.dmm b/_maps/templates/shelter_2.dmm index e9489df641..69e7369af7 100644 --- a/_maps/templates/shelter_2.dmm +++ b/_maps/templates/shelter_2.dmm @@ -203,7 +203,7 @@ /area/survivalpod) "D" = ( /obj/structure/fans/tiny, -/obj/machinery/door/airlock/survival_pod, +/obj/machinery/door/airlock/survival_pod/glass, /turf/open/floor/pod, /area/survivalpod) "E" = ( diff --git a/cfg/admin.txt b/cfg/admin.txt index d10666df65..a72a659071 100644 --- a/cfg/admin.txt +++ b/cfg/admin.txt @@ -1 +1,124 @@ jayehh role=admin +optimumtact role=admin +newsta role=admin +expletives role=admin +kingofkosmos role=admin +mrstonedone role=admin +microscopics role=admin +gunhog role=admin +korphaeron role=admin +razharas role=admin +lordpidey role=admin +niknakflak role=admin +rolan7 role=admin +quarxink role=admin +adrix89 role=admin +tle role=admin +xsi role=admin +scaredofshadows role=admin +neofite role=admin +trubblebass role=admin +mport2004 role=admin +deuryn role=admin +agouri role=admin +errorage role=admin +superxpdude role=admin +petethegoat role=admin +nodrak role=admin +carnwennan role=admin +ikarrus role=admin +cheridan role=admin +giacomand role=admin +rockdtben role=admin +sieve role=admin +aranclanos role=admin +intigracy role=admin +dumpdavidson role=admin +kazeespada role=admin +malkevin role=admin +incoming role=admin +demas role=admin +fleure role=admin +ricotez role=admin +misterperson role=admin +crimsonvision role=admin +iamgoofball role=admin +zelacks role=admin +androidsfv role=admin +miggles role=admin +jordie0608 role=admin +s0ldi3rkr4s0 role=admin +ergovisavi role=admin +vistapowa role=admin +miauw62 role=admin +rumia29 role=admin +bobylein role=admin +sirbayer role=admin +hornygranny role=admin +yota role=admin +firecage role=admin +donkieyo role=admin +argoneus role=admin +paprka role=admin +cookingboy3 role=admin +limeliz role=admin +steelpoint role=admin +phil235 role=admin +corruptcomputer role=admin +xxnoob role=admin +tkdrg role=admin +cuboos role=admin +thunder12345 role=admin +wjohnston role=admin +mandurrh role=admin +thurgatar role=admin +xerux role=admin +dannno role=admin +lo6a4evskiy role=admin +vekter role=admin +ahammer18 role=admin +account12 role=admin +fayrik role=admin +shadowlight213 role=admin +drovidicorv role=admin +dunc role=admin +mmmiracles role=admin +bear1ake role=admin +coreoverload role=admin +jalleo role=admin +changelingrain role=admin +foxpmccloud role=admin +xhuis role=admin +astralenigma role=admin +tokiko1 role=admin +supersayu role=admin +lzimann role=admin +as334 role=admin +neersighted role=admin +swankcookie role=admin +ressler role=admin +folix role=admin +bawhoppennn role=admin +anturke role=admin +lumipharon role=admin +bgobandit role=admin +coiax role=admin +randommarine role=admin +pkpenguin321 role=admin +technoalchemist role=admin +aloraydrel role=admin +quiltyquilty role=admin +snipedragon role=admin +fjeld role=admin +kevinz000 role=admin +tacolizard role=admin +trustygun role=admin +cyberboss role=admin +pjb3005 role=admin +sweaterkittens role=admin +feemjmeem role=admin +jstheguy role=admin +excessiveuseofcobby role=admin +plizzard role=admin +octareenroon91 role=admin +serpentarium role=admin diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm index a2aa7b1414..5a834b1f87 100644 --- a/code/__DEFINES/DNA.dm +++ b/code/__DEFINES/DNA.dm @@ -24,7 +24,7 @@ #define MUT_MUTE "Mute" #define SMILE "Smile" #define STONER "Stoner" -#define UNINTELLIGABLE "Unintelligable" +#define UNINTELLIGIBLE "Unintelligible" #define SWEDISH "Swedish" #define CHAV "Chav" #define ELVIS "Elvis" @@ -82,7 +82,7 @@ #define DNA_MUTANTTAIL_BLOCK 17 #define DNA_MUTANTWING_BLOCK 18 #define DNA_WINGCOLOR_BLOCK 19 -#define DNA_STRUC_ENZYMES_BLOCKS 19 +#define DNA_STRUC_ENZYMES_BLOCKS 18 #define DNA_UNIQUE_ENZYMES_LEN 32 //Transformation proc stuff @@ -127,15 +127,19 @@ #define TOXINLOVER 24 #define DIGITIGRADE 25 //Uses weird leg sprites. Optional for Lizards, required for ashwalkers. Don't give it to other races unless you make sprites for this (see human_parts_greyscale.dmi) #define NO_UNDERWEAR 26 -#define MUTCOLORS2 27 -#define MUTCOLORS3 28 -#define NOLIVER 29 -#define NOSTOMACH 30 +#define NOLIVER 27 +#define NOSTOMACH 28 +#define NO_DNA_COPY 29 +#define DRINKSBLOOD 30 +#define SPECIES_ORGANIC 31 +#define SPECIES_INORGANIC 32 +#define SPECIES_UNDEAD 33 +#define SPECIES_ROBOTIC 34 //citadel code -#define NOAROUSAL 29 //Stops all arousal effects -#define NOGENITALS 30 //Cannot create, use, or otherwise have genitals -#define NO_DNA_COPY 31 -#define DRINKSBLOOD 32 +#define MUTCOLORS2 35 +#define MUTCOLORS3 36 +#define NOAROUSAL 37 //Stops all arousal effects +#define NOGENITALS 38 //Cannot create, use, or otherwise have genitals #define ORGAN_SLOT_BRAIN "brain" #define ORGAN_SLOT_APPENDIX "appendix" diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm index 833aaa62cb..7622fc0ea7 100644 --- a/code/__DEFINES/admin.dm +++ b/code/__DEFINES/admin.dm @@ -94,19 +94,22 @@ #define BANTYPE_ANY_JOB 9 //used to remove jobbans //Admin Permissions -#define R_BUILDMODE 1 -#define R_ADMIN 2 -#define R_BAN 4 -#define R_FUN 8 -#define R_SERVER 16 -#define R_DEBUG 32 -#define R_POSSESS 64 -#define R_PERMISSIONS 128 -#define R_STEALTH 256 -#define R_POLL 512 -#define R_VAREDIT 1024 -#define R_SOUNDS 2048 -#define R_SPAWN 4096 +#define R_BUILDMODE 0x1 +#define R_ADMIN 0x2 +#define R_BAN 0x4 +#define R_FUN 0x8 +#define R_SERVER 0x10 +#define R_DEBUG 0x20 +#define R_POSSESS 0x40 +#define R_PERMISSIONS 0x80 +#define R_STEALTH 0x100 +#define R_POLL 0x200 +#define R_VAREDIT 0x400 +#define R_SOUNDS 0x800 +#define R_SPAWN 0x1000 +#define R_AUTOLOGIN 0x2000 + +#define R_DEFAULT R_AUTOLOGIN #if DM_VERSION > 512 #error Remove the flag below , its been long enough @@ -142,6 +145,7 @@ #define ADMIN_PUNISHMENT_GIB "Gib" #define ADMIN_PUNISHMENT_BSA "Bluespace Artillery Device" #define ADMIN_PUNISHMENT_FIREBALL "Fireball" +#define ADMIN_PUNISHMENT_ROD "Immovable Rod" #define AHELP_ACTIVE 1 #define AHELP_CLOSED 2 diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index f607c34ae8..1024bb1229 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -1,14 +1,5 @@ -#define FIRE_DAMAGE_MODIFIER 0.0215 //Higher values result in more external fire damage to the skin (default 0.0215) -#define AIR_DAMAGE_MODIFIER 2.025 //More means less damage from hot air scalding lungs, less = more damage. (default 2.025) - -#define MOLES_CELLSTANDARD (ONE_ATMOSPHERE*CELL_VOLUME/(T20C*R_IDEAL_GAS_EQUATION)) //moles in a 2.5 m^3 cell at 101.325 Pa and 20 degC -#define M_CELL_WITH_RATIO (MOLES_CELLSTANDARD * 0.005) -#define O2STANDARD 0.21 -#define N2STANDARD 0.79 -#define MOLES_O2STANDARD (MOLES_CELLSTANDARD*O2STANDARD) // O2 standard value (21%) -#define MOLES_N2STANDARD (MOLES_CELLSTANDARD*N2STANDARD) // N2 standard value (79%) - -//indices of values in gas lists. used by listmos. +//LISTMOS +//indices of values in gas lists. #define MOLES 1 #define ARCHIVE 2 #define GAS_META 3 @@ -19,32 +10,41 @@ #define META_GAS_DANGER 5 #define META_GAS_ID 6 -//stuff you should probably leave well alone! //ATMOS -#define CELL_VOLUME 2500 //liters in a cell -#define BREATH_VOLUME 0.5 //liters in a normal breath -#define BREATH_PERCENTAGE (BREATH_VOLUME/CELL_VOLUME) //Amount of air to take a from a tile -#define HUMAN_NEEDED_OXYGEN (MOLES_CELLSTANDARD*BREATH_PERCENTAGE*0.16) //Amount of air needed before pass out/suffocation commences -#define NORMPIPERATE 30 //pipe-insulation rate divisor -#define HEATPIPERATE 8 //heat-exch pipe insulation -#define FLOWFRAC 0.99 //fraction of gas transfered per process -#define TANK_MELT_TEMPERATURE 1000000 -#define TANK_LEAK_PRESSURE (30.*ONE_ATMOSPHERE) //Tank starts leaking -#define TANK_RUPTURE_PRESSURE (35.*ONE_ATMOSPHERE) //Tank spills all contents into atmosphere -#define TANK_FRAGMENT_PRESSURE (40.*ONE_ATMOSPHERE) //Boom 3x3 base explosion -#define TANK_FRAGMENT_SCALE (6.*ONE_ATMOSPHERE) //+1 for each SCALE kPa aboe threshold -#define MINIMUM_AIR_RATIO_TO_SUSPEND 0.1 //Ratio of air that must move to/from a tile to reset group processing -#define MINIMUM_AIR_RATIO_TO_MOVE 0.001 //Minimum ratio of air that must move to/from a tile -#define MINIMUM_AIR_TO_SUSPEND (MOLES_CELLSTANDARD*MINIMUM_AIR_RATIO_TO_SUSPEND) //Minimum amount of air that has to move before a group processing can be suspended -#define MINIMUM_MOLES_DELTA_TO_MOVE (MOLES_CELLSTANDARD*MINIMUM_AIR_RATIO_TO_MOVE) //Either this must be active -#define EXCITED_GROUP_BREAKDOWN_CYCLES 4 -#define EXCITED_GROUP_DISMANTLE_CYCLES 16 -#define MINIMUM_TEMPERATURE_TO_MOVE (T20C+100) //or this (or both, obviously) -#define MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND 0.012 +//stuff you should probably leave well alone! +#define R_IDEAL_GAS_EQUATION 8.31 //kPa*L/(K*mol) +#define ONE_ATMOSPHERE 101.325 //kPa +#define T0C 273.15 // 0degC +#define T20C 293.15 // 20degC +#define TCMB 2.7 // -270.3degC + +#define MOLES_CELLSTANDARD (ONE_ATMOSPHERE*CELL_VOLUME/(T20C*R_IDEAL_GAS_EQUATION)) //moles in a 2.5 m^3 cell at 101.325 Pa and 20 degC +#define M_CELL_WITH_RATIO (MOLES_CELLSTANDARD * 0.005) //compared against for superconductivity +#define O2STANDARD 0.21 //percentage of oxygen in a normal mixture of air +#define N2STANDARD 0.79 //same but for nitrogen +#define MOLES_O2STANDARD (MOLES_CELLSTANDARD*O2STANDARD) // O2 standard value (21%) +#define MOLES_N2STANDARD (MOLES_CELLSTANDARD*N2STANDARD) // N2 standard value (79%) +#define CELL_VOLUME 2500 //liters in a cell +#define BREATH_VOLUME 0.5 //liters in a normal breath +#define BREATH_PERCENTAGE (BREATH_VOLUME/CELL_VOLUME) //Amount of air to take a from a tile +#define HUMAN_NEEDED_OXYGEN (MOLES_CELLSTANDARD*BREATH_PERCENTAGE*0.16) //Amount of air needed before pass out/suffocation commences + +//EXCITED GROUPS +#define EXCITED_GROUP_BREAKDOWN_CYCLES 4 //number of FULL air controller ticks before an excited group breaks down (averages gas contents across turfs) +#define EXCITED_GROUP_DISMANTLE_CYCLES 16 //number of FULL air controller ticks before an excited group dismantles and removes its turfs from active +#define MINIMUM_AIR_RATIO_TO_SUSPEND 0.1 //Ratio of air that must move to/from a tile to reset group processing +#define MINIMUM_AIR_RATIO_TO_MOVE 0.001 //Minimum ratio of air that must move to/from a tile +#define MINIMUM_AIR_TO_SUSPEND (MOLES_CELLSTANDARD*MINIMUM_AIR_RATIO_TO_SUSPEND) //Minimum amount of air that has to move before a group processing can be suspended +#define MINIMUM_MOLES_DELTA_TO_MOVE (MOLES_CELLSTANDARD*MINIMUM_AIR_RATIO_TO_MOVE) //Either this must be active +#define MINIMUM_TEMPERATURE_TO_MOVE (T20C+100) //or this (or both, obviously) #define MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND 4 //Minimum temperature difference before group processing is suspended #define MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER 0.5 //Minimum temperature difference before the gas temperatures are just set to be equal #define MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION T20C+10 #define MINIMUM_TEMPERATURE_START_SUPERCONDUCTION T20C+200 + +//HEAT TRANSFER COEFFICIENTS +//Must be between 0 and 1. Values closer to 1 equalize temperature faster +//Should not exceed 0.4 else strange heat flow occur #define FLOOR_HEAT_TRANSFER_COEFFICIENT 0.4 #define WALL_HEAT_TRANSFER_COEFFICIENT 0.0 #define DOOR_HEAT_TRANSFER_COEFFICIENT 0.0 @@ -52,20 +52,31 @@ #define OPEN_HEAT_TRANSFER_COEFFICIENT 0.4 #define WINDOW_HEAT_TRANSFER_COEFFICIENT 0.1 //a hack for now #define HEAT_CAPACITY_VACUUM 7000 //a hack to help make vacuums "cold", sacrificing realism for gameplay - //Must be between 0 and 1. Values closer to 1 equalize temperature faster - //Should not exceed 0.4 else strange heat flow occur + +//FIRE #define FIRE_MINIMUM_TEMPERATURE_TO_SPREAD 150+T0C #define FIRE_MINIMUM_TEMPERATURE_TO_EXIST 100+T0C #define FIRE_SPREAD_RADIOSITY_SCALE 0.85 #define FIRE_GROWTH_RATE 40000 //For small fires #define CARBON_LIFEFORM_FIRE_RESISTANCE 200+T0C //Resistance to fire damage #define CARBON_LIFEFORM_FIRE_DAMAGE 4 //Fire damage +#define PLASMA_MINIMUM_BURN_TEMPERATURE 100+T0C + +//GASES #define MIN_TOXIC_GAS_DAMAGE 1 #define MAX_TOXIC_GAS_DAMAGE 10 #define MOLES_GAS_VISIBLE 0.5 //Moles in a standard cell after which gases are visible -#define STOP_REACTIONS 2 -#define PLASMA_MINIMUM_BURN_TEMPERATURE 100+T0C -#define GAS_STIM_MINIMUM 0.002 + +//REACTIONS +//return values for reactions (bitflags) +#define NO_REACTION 0 +#define REACTING 1 +#define STOP_REACTIONS 2 + +//HUMANS +//Hurty numbers +#define FIRE_DAMAGE_MODIFIER 0.0215 //Higher values result in more external fire damage to the skin +#define AIR_DAMAGE_MODIFIER 2.025 //More means less damage from hot air scalding lungs, less = more damage // Pressure limits. #define HAZARD_HIGH_PRESSURE 550 //This determins at what pressure the ultra-high pressure red icon is displayed. (This one is set as a constant) @@ -107,65 +118,71 @@ #define SHOES_MIN_TEMP_PROTECT 2.0 //For gloves #define SHOES_MAX_TEMP_PROTECT 1500 //For gloves - #define PRESSURE_DAMAGE_COEFFICIENT 4 //The amount of pressure damage someone takes is equal to (pressure / HAZARD_HIGH_PRESSURE)*PRESSURE_DAMAGE_COEFFICIENT, with the maximum of MAX_PRESSURE_DAMAGE #define MAX_HIGH_PRESSURE_DAMAGE 4 #define LOW_PRESSURE_DAMAGE 4 //The amount of damage someone takes when in a low pressure area (The pressure threshold is so low that it doesn't make sense to do any calculations, so it just applies this flat value). #define COLD_SLOWDOWN_FACTOR 20 //Humans are slowed by the difference between bodytemp and BODYTEMP_COLD_DAMAGE_LIMIT divided by this -// Atmos pipe limits +//PIPES +//Atmos pipe limits #define MAX_OUTPUT_PRESSURE 4500 // (kPa) What pressure pumps and powered equipment max out at. #define MAX_TRANSFER_RATE 200 // (L/s) Maximum speed powered equipment can work at. -//Atmos machinery pipenet stuff - -// used for device_type vars; used by DEVICE_TYPE_LOOP +//used for device_type vars; used by DEVICE_TYPE_LOOP #define UNARY 1 #define BINARY 2 #define TRINARY 3 #define QUATERNARY 4 -// this is the standard for loop used by all sorts of atmos machinery procs +//TODO: finally remove this bullshit +//this is the standard for loop used by all sorts of atmos machinery procs #define DEVICE_TYPE_LOOP var/I in 1 to device_type -// defines for the various machinery lists -// NODE_I, AIR_I, PARENT_I are used within DEVICE_TYPE_LOOP +//defines for the various machinery lists +//NODE_I, AIR_I, PARENT_I are used within DEVICE_TYPE_LOOP -// nodes list - all atmos machinery +//nodes list - all atmos machinery #define NODE1 nodes[1] #define NODE2 nodes[2] #define NODE3 nodes[3] #define NODE4 nodes[4] #define NODE_I nodes[I] -// airs list - components only +//airs list - components only #define AIR1 airs[1] #define AIR2 airs[2] #define AIR3 airs[3] #define AIR_I airs[I] -// parents list - components only +//parents list - components only #define PARENT1 parents[1] #define PARENT2 parents[2] #define PARENT3 parents[3] #define PARENT_I parents[I] -//Tanks -#define TANK_MAX_RELEASE_PRESSURE (ONE_ATMOSPHERE*3) -#define TANK_MIN_RELEASE_PRESSURE 0 -#define TANK_DEFAULT_RELEASE_PRESSURE 16 - +//TANKS +#define TANK_MELT_TEMPERATURE 1000000 //temperature in kelvins at which a tank will start to melt +#define TANK_LEAK_PRESSURE (30.*ONE_ATMOSPHERE) //Tank starts leaking +#define TANK_RUPTURE_PRESSURE (35.*ONE_ATMOSPHERE) //Tank spills all contents into atmosphere +#define TANK_FRAGMENT_PRESSURE (40.*ONE_ATMOSPHERE) //Boom 3x3 base explosion +#define TANK_FRAGMENT_SCALE (6.*ONE_ATMOSPHERE) //+1 for each SCALE kPa aboe threshold +#define TANK_MAX_RELEASE_PRESSURE (ONE_ATMOSPHERE*3) +#define TANK_MIN_RELEASE_PRESSURE 0 +#define TANK_DEFAULT_RELEASE_PRESSURE 16 +//CANATMOSPASS #define ATMOS_PASS_YES 1 #define ATMOS_PASS_NO 0 #define ATMOS_PASS_PROC -1 //ask CanAtmosPass() #define ATMOS_PASS_DENSITY -2 //just check density #define CANATMOSPASS(A, O) ( A.CanAtmosPass == ATMOS_PASS_PROC ? A.CanAtmosPass(O) : ( A.CanAtmosPass == ATMOS_PASS_DENSITY ? !A.density : A.CanAtmosPass ) ) +//LAVALAND #define LAVALAND_EQUIPMENT_EFFECT_PRESSURE 50 //what pressure you have to be under to increase the effect of equipment meant for lavaland #define LAVALAND_DEFAULT_ATMOS "o2=14;n2=23;TEMP=300" +//MULTIPIPES //IF YOU EVER CHANGE THESE CHANGE SPRITES TO MATCH. #define PIPING_LAYER_MIN 1 #define PIPING_LAYER_MAX 3 @@ -179,11 +196,10 @@ #define PIPING_DEFAULT_LAYER_ONLY 4 //can only exist at PIPING_LAYER_DEFAULT #define PIPING_CARDINAL_AUTONORMALIZE 8 //north/south east/west doesn't matter, auto normalize on build. +//HELPERS #define THERMAL_ENERGY(gas) (gas.temperature * gas.heat_capacity()) #define ADD_GAS(gas_id, out_list)\ var/list/tmp_gaslist = GLOB.gaslist_cache[gas_id]; out_list[gas_id] = tmp_gaslist.Copy(); -//ASSERT_GAS(gas_id, gas_mixture) - used to guarantee that the gas list for this id exists in gas_mixture.gases. -//Must be used before adding to a gas. May be used before reading from a gas. #define ASSERT_GAS(gas_id, gas_mixture) if (!gas_mixture.gases[gas_id]) { ADD_GAS(gas_id, gas_mixture.gases) }; diff --git a/code/__DEFINES/atom_hud.dm b/code/__DEFINES/atom_hud.dm index 3c3350d6ab..dcdf5aa268 100644 --- a/code/__DEFINES/atom_hud.dm +++ b/code/__DEFINES/atom_hud.dm @@ -16,31 +16,39 @@ #define DIAG_BOT_HUD "12"// Bot HUDs #define DIAG_TRACK_HUD "13"// Mech tracking beacon #define DIAG_AIRLOCK_HUD "14"//Airlock shock overlay +#define DIAG_PATH_HUD "15"//Bot path indicators +#define GLAND_HUD "16"//Gland indicators for abductors //for antag huds. these are used at the /mob level -#define ANTAG_HUD "15" +#define ANTAG_HUD "17" + +//by default everything in the hud_list of an atom is an image +//a value in hud_list with one of these will change that behavior +#define HUD_LIST_LIST 1 //data HUD (medhud, sechud) defines //Don't forget to update human/New() if you change these! -#define DATA_HUD_SECURITY_BASIC 1 -#define DATA_HUD_SECURITY_ADVANCED 2 -#define DATA_HUD_MEDICAL_BASIC 3 -#define DATA_HUD_MEDICAL_ADVANCED 4 -#define DATA_HUD_DIAGNOSTIC 5 +#define DATA_HUD_SECURITY_BASIC 1 +#define DATA_HUD_SECURITY_ADVANCED 2 +#define DATA_HUD_MEDICAL_BASIC 3 +#define DATA_HUD_MEDICAL_ADVANCED 4 +#define DATA_HUD_DIAGNOSTIC_BASIC 5 +#define DATA_HUD_DIAGNOSTIC_ADVANCED 6 +#define DATA_HUD_ABDUCTOR 7 //antag HUD defines -#define ANTAG_HUD_CULT 6 -#define ANTAG_HUD_REV 7 -#define ANTAG_HUD_OPS 8 -#define ANTAG_HUD_WIZ 9 -#define ANTAG_HUD_SHADOW 10 -#define ANTAG_HUD_TRAITOR 11 -#define ANTAG_HUD_NINJA 12 -#define ANTAG_HUD_CHANGELING 13 -#define ANTAG_HUD_ABDUCTOR 14 -#define ANTAG_HUD_DEVIL 15 -#define ANTAG_HUD_SINTOUCHED 16 -#define ANTAG_HUD_SOULLESS 17 -#define ANTAG_HUD_CLOCKWORK 18 -#define ANTAG_HUD_BROTHER 19 +#define ANTAG_HUD_CULT 8 +#define ANTAG_HUD_REV 9 +#define ANTAG_HUD_OPS 10 +#define ANTAG_HUD_WIZ 11 +#define ANTAG_HUD_SHADOW 12 +#define ANTAG_HUD_TRAITOR 13 +#define ANTAG_HUD_NINJA 14 +#define ANTAG_HUD_CHANGELING 15 +#define ANTAG_HUD_ABDUCTOR 16 +#define ANTAG_HUD_DEVIL 17 +#define ANTAG_HUD_SINTOUCHED 18 +#define ANTAG_HUD_SOULLESS 19 +#define ANTAG_HUD_CLOCKWORK 20 +#define ANTAG_HUD_BROTHER 21 // Notification action types #define NOTIFY_JUMP "jump" diff --git a/code/__DEFINES/clockcult.dm b/code/__DEFINES/clockcult.dm index fe804c44f9..7451c42cab 100644 --- a/code/__DEFINES/clockcult.dm +++ b/code/__DEFINES/clockcult.dm @@ -1,12 +1,11 @@ -//component id defines -#define BELLIGERENT_EYE "belligerent_eye" -#define VANGUARD_COGWHEEL "vanguard_cogwheel" -#define GEIS_CAPACITOR "geis_capacitor" +//component id defines; sometimes these may not make sense in regards to their use in scripture but important ones are bright +#define BELLIGERENT_EYE "belligerent_eye" //Use this for offensive and damaging scripture! +#define VANGUARD_COGWHEEL "vanguard_cogwheel" //Use this for defensive and healing scripture! +#define GEIS_CAPACITOR "geis_capacitor" //Use this for niche scripture! #define REPLICANT_ALLOY "replicant_alloy" -#define HIEROPHANT_ANSIBLE "hierophant_ansible" +#define HIEROPHANT_ANSIBLE "hierophant_ansible" //Use this for construction-related scripture! GLOBAL_VAR_INIT(clockwork_construction_value, 0) //The total value of all structures built by the clockwork cult -GLOBAL_VAR_INIT(clockwork_caches, 0) //How many clockwork caches exist in the world (not each individual) GLOBAL_VAR_INIT(clockwork_vitality, 0) //How much Vitality is stored, total GLOBAL_VAR_INIT(clockwork_power, 0) //How many watts of power are globally available to the clockwork cult @@ -69,6 +68,9 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us //Objective text define #define CLOCKCULT_OBJECTIVE "Construct the Ark of the Clockwork Justicar and free Ratvar." +//Eminence defines +#define SUPERHEATED_CLOCKWORK_WALL_LIMIT 20 //How many walls can be superheated at once + //misc clockcult stuff #define SIGIL_ACCESS_RANGE 2 //range at which transmission sigils can access power @@ -86,3 +88,5 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us #define MARAUDER_SCRIPTURE_SCALING_TIME 50 //The amount of extra deciseconds tacked on to the marauder scripture recital time per recent marauder #define MARAUDER_SCRIPTURE_SCALING_MAX 300 //The maximum extra time applied to the marauder scripture + +#define ARK_SCREAM_COOLDOWN 600 //This much time has to pass between instances of the Ark taking damage before it will "scream" again diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index ddf3deb4a3..78ade5c650 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -6,9 +6,10 @@ // How multiple components of the exact same type are handled in the same datum -#define COMPONENT_DUPE_HIGHLANDER 0 //old component is deleted (default) -#define COMPONENT_DUPE_ALLOWED 1 //duplicates allowed -#define COMPONENT_DUPE_UNIQUE 2 //new component is deleted +#define COMPONENT_DUPE_HIGHLANDER 0 //old component is deleted (default) +#define COMPONENT_DUPE_ALLOWED 1 //duplicates allowed +#define COMPONENT_DUPE_UNIQUE 2 //new component is deleted +#define COMPONENT_DUPE_UNIQUE_PASSARGS 4 //old component is given the initialization args of the new // All signals. Format: // When the signal is called: (signal arguments) @@ -23,6 +24,7 @@ // /atom signals #define COMSIG_PARENT_ATTACKBY "atom_attackby" //from base of atom/attackby(): (/obj/item, /mob/living, params) + #define COMPONENT_NO_AFTERATTACK 1 //Return this in response if you don't want afterattack to be called #define COMSIG_ATOM_HULK_ATTACK "hulk_attack" //from base of atom/attack_hulk(): (/mob/living/carbon/human) #define COMSIG_PARENT_EXAMINE "atom_examine" //from base of atom/examine(): (/mob) #define COMSIG_ATOM_ENTERED "atom_entered" //from base of atom/Entered(): (/atom/movable, /atom) @@ -53,11 +55,15 @@ #define COMSIG_MOVABLE_CROSSED "movable_crossed" //from base of atom/movable/Crossed(): (/atom/movable) #define COMSIG_MOVABLE_COLLIDE "movable_collide" //from base of atom/movable/Collide(): (/atom) #define COMSIG_MOVABLE_IMPACT "movable_impact" //from base of atom/movable/throw_impact(): (/atom, throwingdatum) +#define COMSIG_MOVABLE_BUCKLE "buckle" //from base of atom/movable/buckle_mob(): (mob, force) +#define COMSIG_MOVABLE_UNBUCKLE "unbuckle" //from base of atom/movable/unbuckle_mob(): (mob, force) // /obj/item signals #define COMSIG_ITEM_ATTACK "item_attack" //from base of obj/item/attack(): (/mob/living/target, /mob/living/user) #define COMSIG_ITEM_ATTACK_SELF "item_attack_self" //from base of obj/item/attack_self(): (/mob) #define COMSIG_ITEM_ATTACK_OBJ "item_attack_obj" //from base of obj/item/attack_obj(): (/obj, /mob) +#define COMSIG_ITEM_EQUIPPED "item_equip" //from base of obj/item/equipped(): (/mob/equipper, slot) +#define COMSIG_ITEM_DROPPED "item_drop" //from base of obj/item/dropped(): (/mob/dropper) // /obj/item/clothing signals #define COMSIG_SHOES_STEP_ACTION "shoes_step_action" //from base of obj/item/clothing/shoes/proc/step_action(): () @@ -72,4 +78,12 @@ // /obj/machinery signals #define COMSIG_MACHINE_PROCESS "machine_process" //from machinery subsystem fire(): () -#define COMSIG_MACHINE_PROCESS_ATMOS "machine_process_atmos" //from air subsystem process_atmos_machinery(): () +#define COMSIG_MACHINE_PROCESS_ATMOS "machine_process_atmos" //from air subsystem process_atmos_machinery(): () + +// /mob/living/carbon/human signals +#define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack" //from mob/living/carbon/human/UnarmedAttack(): (atom/target) +#define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby" //from mob/living/carbon/human/UnarmedAttack(): (mob/living/carbon/human/attacker) +#define COMSIG_HUMAN_DISARM_HIT "human_disarm_hit" //Hit by successful disarm attack (mob/living/carbon/human/attacker,zone_targeted) + +#define CALTROP_BYPASS_SHOES 1 +#define CALTROP_IGNORE_WALKERS 2 diff --git a/code/__DEFINES/configuration.dm b/code/__DEFINES/configuration.dm index 3db0ca24c2..c4ef8e6606 100644 --- a/code/__DEFINES/configuration.dm +++ b/code/__DEFINES/configuration.dm @@ -1,8 +1,6 @@ //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_TWEAK(X) /datum/config_entry/##X #define CONFIG_MAPS_FILE "maps.txt" diff --git a/code/__DEFINES/construction.dm b/code/__DEFINES/construction.dm index ae3f9f6fe9..b3a9a05119 100644 --- a/code/__DEFINES/construction.dm +++ b/code/__DEFINES/construction.dm @@ -23,6 +23,11 @@ #define WINDOW_IN_FRAME 1 #define WINDOW_SCREWED_TO_FRAME 2 +//airlock assembly construction states +#define AIRLOCK_ASSEMBLY_NEEDS_WIRES 0 +#define AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS 1 +#define AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER 2 + //plastic flaps construction states #define PLASTIC_FLAPS_NORMAL 0 #define PLASTIC_FLAPS_DETACHED 1 diff --git a/code/__DEFINES/integrated_electronics.dm b/code/__DEFINES/integrated_electronics.dm index 8e9e1b7cea..77ee69892e 100644 --- a/code/__DEFINES/integrated_electronics.dm +++ b/code/__DEFINES/integrated_electronics.dm @@ -20,6 +20,7 @@ #define IC_FORMAT_BOOLEAN "\" #define IC_FORMAT_REF "\" #define IC_FORMAT_LIST "\" +#define IC_FORMAT_INDEX "\" #define IC_FORMAT_PULSE "\" @@ -33,6 +34,7 @@ #define IC_PINTYPE_BOOLEAN /datum/integrated_io/boolean #define IC_PINTYPE_REF /datum/integrated_io/ref #define IC_PINTYPE_LIST /datum/integrated_io/lists +#define IC_PINTYPE_INDEX /datum/integrated_io/index #define IC_PINTYPE_PULSE_IN /datum/integrated_io/activate #define IC_PINTYPE_PULSE_OUT /datum/integrated_io/activate/out diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 1e5e994636..da25d34880 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -144,6 +144,8 @@ #define iscameramob(A) (istype(A, /mob/camera)) +#define iseminence(A) (istype(A, /mob/camera/eminence)) + //Objects #define isobj(A) istype(A, /obj) //override the byond proc because it returns true on children of /atom/movable that aren't objs @@ -189,3 +191,5 @@ GLOBAL_LIST_INIT(glass_sheet_types, typecacheof(list( /obj/item/stack/sheet/plasmarglass))) #define is_glass_sheet(O) (is_type_in_typecache(O, GLOB.glass_sheet_types)) + +#define isblobmonster(O) (istype(O, /mob/living/simple_animal/hostile/blob)) \ No newline at end of file diff --git a/code/__DEFINES/logging.dm b/code/__DEFINES/logging.dm index f558511954..6d7cf12789 100644 --- a/code/__DEFINES/logging.dm +++ b/code/__DEFINES/logging.dm @@ -10,6 +10,7 @@ #define INVESTIGATE_TELESCI "telesci" #define INVESTIGATE_WIRES "wires" #define INVESTIGATE_PORTAL "portals" +#define INVESTIGATE_RESEARCH "research" #define INVESTIGATE_HALLUCINATIONS "hallucinations" #define INVESTIGATE_RADIATION "radiation" #define INVESTIGATE_EXONET "exonet" diff --git a/code/__DEFINES/maps.dm b/code/__DEFINES/maps.dm index 1320250f89..cdd2739b3c 100644 --- a/code/__DEFINES/maps.dm +++ b/code/__DEFINES/maps.dm @@ -48,4 +48,4 @@ Last space-z level = empty #define ZLEVEL_SPACEMIN 3 #define ZLEVEL_SPACEMAX 13 -#define SPACERUIN_MAP_EDGE_PAD 15 \ No newline at end of file +#define SPACERUIN_MAP_EDGE_PAD 15 diff --git a/code/__DEFINES/math.dm b/code/__DEFINES/math.dm deleted file mode 100644 index 5b3f51b4e3..0000000000 --- a/code/__DEFINES/math.dm +++ /dev/null @@ -1,27 +0,0 @@ -#define PI 3.1415 -#define SPEED_OF_LIGHT 3e8 //not exact but hey! -#define SPEED_OF_LIGHT_SQ 9e+16 -#define INFINITY 1e31 //closer then enough - -//atmos -#define R_IDEAL_GAS_EQUATION 8.31 //kPa*L/(K*mol) -#define ONE_ATMOSPHERE 101.325 //kPa -#define T0C 273.15 // 0degC -#define T20C 293.15 // 20degC -#define TCMB 2.7 // -270.3degC - -#define SHORT_REAL_LIMIT 16777216 - -//"fancy" math for calculating time in ms from tick_usage percentage and the length of ticks -//percent_of_tick_used * (ticklag * 100(to convert to ms)) / 100(percent ratio) -//collapsed to percent_of_tick_used * tick_lag -#define TICK_DELTA_TO_MS(percent_of_tick_used) ((percent_of_tick_used) * world.tick_lag) -#define TICK_USAGE_TO_MS(starting_tickusage) (TICK_DELTA_TO_MS(TICK_USAGE_REAL - starting_tickusage)) - -#define PERCENT(val) (round(val*100, 0.1)) -#define CLAMP01(x) (Clamp(x, 0, 1)) - -//time of day but automatically adjusts to the server going into the next day within the same round. -//for when you need a reliable time number that doesn't depend on byond time. -#define REALTIMEOFDAY (world.timeofday + (MIDNIGHT_ROLLOVER * MIDNIGHT_ROLLOVER_CHECK)) -#define MIDNIGHT_ROLLOVER_CHECK ( GLOB.rollovercheck_last_timeofday != world.timeofday ? update_midnight_rollover() : GLOB.midnight_rollovers ) diff --git a/code/__DEFINES/maths.dm b/code/__DEFINES/maths.dm new file mode 100644 index 0000000000..0ff3ade369 --- /dev/null +++ b/code/__DEFINES/maths.dm @@ -0,0 +1,209 @@ +// Credits to Nickr5 for the useful procs I've taken from his library resource. +// This file is quadruple wrapped for your pleasure +// ( + +#define NUM_E 2.71828183 +#define NUM_SQRT2 1.41421356 + +#define PI 3.1415 +#define SPEED_OF_LIGHT 3e8 //not exact but hey! +#define SPEED_OF_LIGHT_SQ 9e+16 +#define INFINITY 1e31 //closer then enough + +#define SHORT_REAL_LIMIT 16777216 + +//"fancy" math for calculating time in ms from tick_usage percentage and the length of ticks +//percent_of_tick_used * (ticklag * 100(to convert to ms)) / 100(percent ratio) +//collapsed to percent_of_tick_used * tick_lag +#define TICK_DELTA_TO_MS(percent_of_tick_used) ((percent_of_tick_used) * world.tick_lag) +#define TICK_USAGE_TO_MS(starting_tickusage) (TICK_DELTA_TO_MS(TICK_USAGE_REAL - starting_tickusage)) + +#define PERCENT(val) (round((val)*100, 0.1)) +#define CLAMP01(x) (CLAMP(x, 0, 1)) + +//time of day but automatically adjusts to the server going into the next day within the same round. +//for when you need a reliable time number that doesn't depend on byond time. +#define REALTIMEOFDAY (world.timeofday + (MIDNIGHT_ROLLOVER * MIDNIGHT_ROLLOVER_CHECK)) +#define MIDNIGHT_ROLLOVER_CHECK ( GLOB.rollovercheck_last_timeofday != world.timeofday ? update_midnight_rollover() : GLOB.midnight_rollovers ) + +#define SIGN(x) ( (x)!=0 ? (x) / abs(x) : 0 ) + +#define CEILING(x, y) ( -round(-(x) / (y)) * (y) ) + +// round() acts like floor(x, 1) by default but can't handle other values +#define FLOOR(x, y) ( round((x) / (y)) * (y) ) + +#define CLAMP(CLVALUE,CLMIN,CLMAX) ( max( (CLMIN), min((CLVALUE), (CLMAX)) ) ) + +// Similar to clamp but the bottom rolls around to the top and vice versa. min is inclusive, max is exclusive +#define WRAP(val, min, max) ( min == max ? min : (val) - (round(((val) - (min))/((max) - (min))) * ((max) - (min))) ) + +// Real modulus that handles decimals +#define MODULUS(x, y) ( (x) - (y) * round((x) / (y)) ) + +// Tangent +#define TAN(x) (sin(x) / cos(x)) + +// Cotangent +#define COT(x) (1 / TAN(x)) + +// Secant +#define SEC(x) (1 / cos(x)) + +// Cosecant +#define CSC(x) (1 / sin(x)) + +#define ATAN2(x, y) ( !(x) && !(y) ? 0 : (y) >= 0 ? arccos((x) / sqrt((x)*(x) + (y)*(y))) : -arccos((x) / sqrt((x)*(x) + (y)*(y))) ) + +// Greatest Common Divisor - Euclid's algorithm +/proc/Gcd(a, b) + return b ? Gcd(b, (a) % (b)) : a + +// Least Common Multiple +#define Lcm(a, b) (abs(a) / Gcd(a, b) * abs(b)) + +#define INVERSE(x) ( 1/(x) ) + +// Used for calculating the radioactive strength falloff +#define INVERSE_SQUARE(initial_strength,cur_distance,initial_distance) ( (initial_strength)*((initial_distance)**2/(cur_distance)**2) ) + +#define ISABOUTEQUAL(a, b, deviation) (deviation ? abs((a) - (b)) <= deviation : abs((a) - (b)) <= 0.1) + +#define ISEVEN(x) (x % 2 == 0) + +#define ISODD(x) (x % 2 != 0) + +// Returns true if val is from min to max, inclusive. +#define ISINRANGE(val, min, max) (min <= val && val <= max) + +// Same as above, exclusive. +#define ISINRANGE_EX(val, min, max) (min < val && val > max) + +#define ISINTEGER(x) (round(x) == x) + +#define ISMULTIPLE(x, y) ((x) % (y) == 0) + +// Performs a linear interpolation between a and b. +// Note that amount=0 returns a, amount=1 returns b, and +// amount=0.5 returns the mean of a and b. +#define LERP(a, b, amount) (amount ? ((a) + ((b) - (a)) * (amount)) : ((a) + ((b) - (a)) * 0.5) + +// Returns the nth root of x. +#define ROOT(n, x) ((x) ** (1 / (n))) + +// The quadratic formula. Returns a list with the solutions, or an empty list +// if they are imaginary. +/proc/SolveQuadratic(a, b, c) + ASSERT(a) + . = list() + var/d = b*b - 4 * a * c + var/bottom = 2 * a + if(d < 0) + return + var/root = sqrt(d) + . += (-b + root) / bottom + if(!d) + return + . += (-b - root) / bottom + +#define TODEGREES(radians) ((radians) * 57.2957795) + +#define TORADIANS(degrees) ((degrees) * 0.0174532925) + +// Will filter out extra rotations and negative rotations +// E.g: 540 becomes 180. -180 becomes 180. +#define SIMPLIFY_DEGREES(degrees) (MODULUS((degrees), 360)) + +#define GET_ANGLE_OF_INCIDENCE(face, input) (MODULUS((face) - (input), 360)) + +//A logarithm that converts an integer to a number scaled between 0 and 1. +//Currently, this is used for hydroponics-produce sprite transforming, but could be useful for other transform functions. +#define TRANSFORM_USING_VARIABLE(input, max) ( sin((90*(input))/(max))**2 ) + +//converts a uniform distributed random number into a normal distributed one +//since this method produces two random numbers, one is saved for subsequent calls +//(making the cost negligble for every second call) +//This will return +/- decimals, situated about mean with standard deviation stddev +//68% chance that the number is within 1stddev +//95% chance that the number is within 2stddev +//98% chance that the number is within 3stddev...etc +#define ACCURACY 10000 +/proc/gaussian(mean, stddev) + var/static/gaussian_next + var/R1;var/R2;var/working + if(gaussian_next != null) + R1 = gaussian_next + gaussian_next = null + else + do + R1 = rand(-ACCURACY,ACCURACY)/ACCURACY + R2 = rand(-ACCURACY,ACCURACY)/ACCURACY + working = R1*R1 + R2*R2 + while(working >= 1 || working==0) + working = sqrt(-2 * log(working) / working) + R1 *= working + gaussian_next = R2 * working + return (mean + stddev * R1) +#undef ACCURACY + +/proc/mouse_angle_from_client(client/client) + var/list/mouse_control = params2list(client.mouseParams) + if(mouse_control["screen-loc"] && client) + var/list/screen_loc_params = splittext(mouse_control["screen-loc"], ",") + var/list/screen_loc_X = splittext(screen_loc_params[1],":") + var/list/screen_loc_Y = splittext(screen_loc_params[2],":") + var/x = (text2num(screen_loc_X[1]) * 32 + text2num(screen_loc_X[2]) - 32) + var/y = (text2num(screen_loc_Y[1]) * 32 + text2num(screen_loc_Y[2]) - 32) + var/list/screenview = getviewsize(client.view) + var/screenviewX = screenview[1] * world.icon_size + var/screenviewY = screenview[2] * world.icon_size + var/ox = round(screenviewX/2) - client.pixel_x //"origin" x + var/oy = round(screenviewY/2) - client.pixel_y //"origin" y + var/angle = SIMPLIFY_DEGREES(ATAN2(y - oy, x - ox)) + return angle + +/proc/get_turf_in_angle(angle, turf/starting, increments) + var/pixel_x = 0 + var/pixel_y = 0 + for(var/i in 1 to increments) + pixel_x += sin(angle)+16*sin(angle)*2 + pixel_y += cos(angle)+16*cos(angle)*2 + var/new_x = starting.x + var/new_y = starting.y + while(pixel_x > 16) + pixel_x -= 32 + new_x++ + while(pixel_x < -16) + pixel_x += 32 + new_x-- + while(pixel_y > 16) + pixel_y -= 32 + new_y++ + while(pixel_y < -16) + pixel_y += 32 + new_y-- + new_x = CLAMP(new_x, 0, world.maxx) + new_y = CLAMP(new_y, 0, world.maxy) + return locate(new_x, new_y, starting.z) + +// Returns a list where [1] is all x values and [2] is all y values that overlap between the given pair of rectangles +/proc/get_overlap(x1, y1, x2, y2, x3, y3, x4, y4) + var/list/region_x1 = list() + var/list/region_y1 = list() + var/list/region_x2 = list() + var/list/region_y2 = list() + + // These loops create loops filled with x/y values that the boundaries inhabit + // ex: list(5, 6, 7, 8, 9) + for(var/i in min(x1, x2) to max(x1, x2)) + region_x1["[i]"] = TRUE + for(var/i in min(y1, y2) to max(y1, y2)) + region_y1["[i]"] = TRUE + for(var/i in min(x3, x4) to max(x3, x4)) + region_x2["[i]"] = TRUE + for(var/i in min(y3, y4) to max(y3, y4)) + region_y2["[i]"] = TRUE + + return list(region_x1 & region_x2, region_y1 & region_y2) + +// ) \ No newline at end of file diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 7cc2e4537f..b5d07646d7 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -4,6 +4,11 @@ // #define EAST 4 // #define WEST 8 +#define TEXT_NORTH "[NORTH]" +#define TEXT_SOUTH "[SOUTH]" +#define TEXT_EAST "[EAST]" +#define TEXT_WEST "[WEST]" + //These get to go at the top, because they're special //You can use these defines to get the typepath of the currently running proc/verb (yes procs + verbs are objects) /* eg: @@ -479,7 +484,19 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE #define SYRINGE_DRAW 0 #define SYRINGE_INJECT 1 +#define RESEARCH_MATERIAL_RECLAMATION_ID "0" + + //gold slime core spawning #define NO_SPAWN 0 #define HOSTILE_SPAWN 1 #define FRIENDLY_SPAWN 2 + +#define RIDING_OFFSET_ALL "ALL" + +//text files +#define BRAIN_DAMAGE_FILE "traumas.json" + +//Fullscreen overlay resolution in tiles. +#define FULLSCREEN_OVERLAY_RESOLUTION_X 15 +#define FULLSCREEN_OVERLAY_RESOLUTION_Y 15 diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 69596e7a0f..707ef6a9c1 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -51,6 +51,17 @@ #define DEVIL_BODYPART "devil" /*see __DEFINES/inventory.dm for bodypart bitflag defines*/ +//Brain Damage defines +#define BRAIN_DAMAGE_MILD 20 +#define BRAIN_DAMAGE_SEVERE 100 +#define BRAIN_DAMAGE_DEATH 200 + +#define BRAIN_TRAUMA_MILD /datum/brain_trauma/mild +#define BRAIN_TRAUMA_SEVERE /datum/brain_trauma/severe +#define BRAIN_TRAUMA_SPECIAL /datum/brain_trauma/special + +#define BRAIN_DAMAGE_INTEGRITY_MULTIPLIER 0.5 + //Health hud screws for carbon mobs #define SCREWYHUD_NONE 0 #define SCREWYHUD_CRIT 1 diff --git a/code/__DEFINES/networks.dm b/code/__DEFINES/networks.dm index 42fe8a5ded..0aec59db9b 100644 --- a/code/__DEFINES/networks.dm +++ b/code/__DEFINES/networks.dm @@ -1 +1 @@ -#define HID_RESTRICTED_END 101 //the first nonrestricted ID, automatically assigned on connection creation. +#define HID_RESTRICTED_END 101 //the first nonrestricted ID, automatically assigned on connection creation. diff --git a/code/__DEFINES/reagents.dm b/code/__DEFINES/reagents.dm index c85365db90..d9e6225eb7 100644 --- a/code/__DEFINES/reagents.dm +++ b/code/__DEFINES/reagents.dm @@ -1,19 +1,30 @@ -#define SOLID 1 -#define LIQUID 2 -#define GAS 3 +#define SOLID 1 +#define LIQUID 2 +#define GAS 3 -#define INJECTABLE_1 1024 //Makes reagents addable through droppers and syringes -#define DRAWABLE_1 2048 //If a syringe can draw from it -#define OPENCONTAINER_1 4096 //Is an open container for chemistry purposes -#define TRANSPARENT_1 8192 //Used for non-open containers which you still want to be able to see the reagents off. -#define TOUCH 1 //splashing -#define INGEST 2 //ingestion -#define VAPOR 3 //foam, spray, blob attack -#define PATCH 4 //patches -#define INJECT 5 //injection +// container_type defines +#define INJECTABLE 1 // Makes it possible to add reagents through droppers and syringes. +#define DRAWABLE 2 // Makes it possible to remove reagents through syringes. + +#define REFILLABLE 4 // Makes it possible to add reagents through any reagent container. +#define DRAINABLE 8 // Makes it possible to remove reagents through any reagent container. + +#define TRANSPARENT 16 // Used on containers which you want to be able to see the reagents off. +#define AMOUNT_VISIBLE 32 // For non-transparent containers that still have the general amount of reagents in them visible. + +// Is an open container for all intents and purposes. +#define OPENCONTAINER REFILLABLE | DRAINABLE | TRANSPARENT + + +#define TOUCH 1 // splashing +#define INGEST 2 // ingestion +#define VAPOR 3 // foam, spray, blob attack +#define PATCH 4 // patches +#define INJECT 5 // injection + //defines passed through to the on_reagent_change proc -#define DEL_REAGENT 1 //reagent deleted (fully cleared) -#define ADD_REAGENT 2 // reagent added -#define REM_REAGENT 3 // reagent removed (may still exist) +#define DEL_REAGENT 1 // reagent deleted (fully cleared) +#define ADD_REAGENT 2 // reagent added +#define REM_REAGENT 3 // reagent removed (may still exist) diff --git a/code/__DEFINES/research.dm b/code/__DEFINES/research.dm new file mode 100644 index 0000000000..14e6798528 --- /dev/null +++ b/code/__DEFINES/research.dm @@ -0,0 +1,61 @@ + +//RDSCREEN screens +#define RDSCREEN_MENU 0 +#define RDSCREEN_TECHDISK 1 +#define RDSCREEN_DESIGNDISK 20 +#define RDSCREEN_DESIGNDISK_UPLOAD 21 +#define RDSCREEN_DECONSTRUCT 3 +#define RDSCREEN_PROTOLATHE 40 +#define RDSCREEN_PROTOLATHE_MATERIALS 41 +#define RDSCREEN_PROTOLATHE_CHEMICALS 42 +#define RDSCREEN_PROTOLATHE_CATEGORY_VIEW 43 +#define RDSCREEN_PROTOLATHE_SEARCH 44 +#define RDSCREEN_IMPRINTER 50 +#define RDSCREEN_IMPRINTER_MATERIALS 51 +#define RDSCREEN_IMPRINTER_CHEMICALS 52 +#define RDSCREEN_IMPRINTER_CATEGORY_VIEW 53 +#define RDSCREEN_IMPRINTER_SEARCH 54 +#define RDSCREEN_SETTINGS 61 +#define RDSCREEN_DEVICE_LINKING 62 +#define RDSCREEN_TECHWEB 70 +#define RDSCREEN_TECHWEB_NODEVIEW 71 +#define RDSCREEN_TECHWEB_DESIGNVIEW 72 + +#define RDSCREEN_NOBREAK "" + +#define RDSCREEN_TEXT_NO_PROTOLATHE "

No Protolathe Linked!


" +#define RDSCREEN_TEXT_NO_IMPRINTER "

No Circuit Imprinter Linked!


" +#define RDSCREEN_TEXT_NO_DECONSTRUCT "

No Deconstructive Analyzer Linked!


" +#define RDSCREEN_TEXT_NO_TDISK "

No Technology Disk Inserted!


" +#define RDSCREEN_TEXT_NO_DDISK "

No Design Disk Inserted!


" +#define RDSCREEN_TEXT_NO_SNODE "

No Technology Node Selected!


" +#define RDSCREEN_TEXT_NO_SDESIGN "

No Design Selected!


" + +#define RDSCREEN_UI_LATHE_CHECK if(!linked_lathe) { return RDSCREEN_TEXT_NO_PROTOLATHE } +#define RDSCREEN_UI_IMPRINTER_CHECK if(!linked_imprinter) { return RDSCREEN_TEXT_NO_IMPRINTER } +#define RDSCREEN_UI_DECONSTRUCT_CHECK if(!linked_destroy) { return RDSCREEN_TEXT_NO_DECONSTRUCT } +#define RDSCREEN_UI_TDISK_CHECK if(!t_disk) { return RDSCREEN_TEXT_NO_TDISK } +#define RDSCREEN_UI_DDISK_CHECK if(!d_disk) { return RDSCREEN_TEXT_NO_DDISK } +#define RDSCREEN_UI_SNODE_CHECK if(!selected_node) { return RDSCREEN_TEXT_NO_SNODE } +#define RDSCREEN_UI_SDESIGN_CHECK if(!selected_design) { return RDSCREEN_TEXT_NO_SDESIGN } + +#define DEPLATHE_SCREEN_PRIMARY 1 +#define DEPLATHE_SCREEN_SEARCH 2 +#define DEPLATHE_SCREEN_MATERIALS 3 +#define DEPLATHE_SCREEN_CHEMICALS 4 + +#define DEPPRINTER_SCREEN_PRIMARY 1 +#define DEPPRINTER_SCREEN_SEARCH 2 +#define DEPPRINTER_SCREEN_MATERIALS 3 +#define DEPPRINTER_SCREEN_CHEMICALS 4 + +#define DEPARTMENTAL_FLAG_SECURITY 1 +#define DEPARTMENTAL_FLAG_MEDICAL 2 +#define DEPARTMENTAL_FLAG_CARGO 4 +#define DEPARTMENTAL_FLAG_SCIENCE 8 +#define DEPARTMENTAL_FLAG_ENGINEERING 16 +#define DEPARTMENTAL_FLAG_SERVICE 32 +#define DEPARTMENTAL_FLAG_ALL 64 //NO THIS DOESN'T ALLOW YOU TO PRINT EVERYTHING, IT'S FOR ALL DEPARTMENTS! +//#define DEPARTMENTAL_FLAG_MINING 128 + +#define DESIGN_ID_IGNORE "IGNORE_THIS_DESIGN" diff --git a/code/__DEFINES/say.dm b/code/__DEFINES/say.dm index d30eb36132..74a1669686 100644 --- a/code/__DEFINES/say.dm +++ b/code/__DEFINES/say.dm @@ -49,4 +49,10 @@ #define LOGCHAT "chat" #define LOGASAY "adminsay" #define LOGCOMMENT "comment" -#define LOGOOC "ooc" \ No newline at end of file +#define LOGOOC "ooc" + + +#define LINGHIVE_NONE 0 +#define LINGHIVE_OUTSIDER 1 +#define LINGHIVE_LING 2 +#define LINGHIVE_LINK 3 \ No newline at end of file diff --git a/code/__DEFINES/server_tools.config.dm b/code/__DEFINES/server_tools.config.dm new file mode 100644 index 0000000000..7d3c5b8eba --- /dev/null +++ b/code/__DEFINES/server_tools.config.dm @@ -0,0 +1,8 @@ +#define SERVER_TOOLS_EXTERNAL_CONFIGURATION +#define SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(Name, Value) GLOBAL_VAR_INIT(##Name, ##Value); GLOBAL_PROTECT(##Name) +#define SERVER_TOOLS_READ_GLOBAL(Name) GLOB.##Name +#define SERVER_TOOLS_WRITE_GLOBAL(Name, Value) GLOB.##Name = ##Value +#define SERVER_TOOLS_WORLD_ANNOUNCE(message) to_chat(world, "[html_encode(##message)]") +#define SERVER_TOOLS_LOG(message) log_world("SERVICE: [##message]") +#define SERVER_TOOLS_NOTIFY_ADMINS(event) message_admins(##event) +#define SERVER_TOOLS_CLIENT_COUNT GLOB.clients.len diff --git a/code/__DEFINES/server_tools.dm b/code/__DEFINES/server_tools.dm index 9547c381c1..c0fc133ada 100644 --- a/code/__DEFINES/server_tools.dm +++ b/code/__DEFINES/server_tools.dm @@ -1,4 +1,5 @@ -// /tg/station 13 server tools API v3.1.0.2 +// /tg/station 13 server tools API +#define SERVICE_API_VERSION_STRING "3.2.0.1" //CONFIGURATION //use this define if you want to do configuration outside of this file @@ -10,19 +11,19 @@ //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) +#define SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(Name, Value) //Read the value in the global variable `Name` -#define SERVER_TOOLS_READ_GLOBAL(Name) GLOB.##Name +#define SERVER_TOOLS_READ_GLOBAL(Name) //Set the value in the global variable `Name` to `Value` -#define SERVER_TOOLS_WRITE_GLOBAL(Name, Value) GLOB.##Name = ##Value +#define SERVER_TOOLS_WRITE_GLOBAL(Name, Value) //display an announcement `message` from the server to all players -#define SERVER_TOOLS_WORLD_ANNOUNCE(message) to_chat(world, "[html_encode(##message)]") +#define SERVER_TOOLS_WORLD_ANNOUNCE(message) //Write a string `message` to a server log -#define SERVER_TOOLS_LOG(message) log_world("SERVICE: [##message]") +#define SERVER_TOOLS_LOG(message) //Notify current in-game administrators of a string `event` -#define SERVER_TOOLS_NOTIFY_ADMINS(event) message_admins(##event) +#define SERVER_TOOLS_NOTIFY_ADMINS(event) //The current amount of connected clients -#define SERVER_TOOLS_CLIENT_COUNT GLOB.clients.len +#define SERVER_TOOLS_CLIENT_COUNT #endif //Required hooks: @@ -64,16 +65,15 @@ //IMPLEMENTATION -#define SERVICE_API_VERSION_STRING "3.1.0.2" - #define REBOOT_MODE_NORMAL 0 #define REBOOT_MODE_HARD 1 #define REBOOT_MODE_SHUTDOWN 2 #define SERVICE_WORLD_PARAM "server_service" #define SERVICE_VERSION_PARAM "server_service_version" +#define SERVICE_INSTANCE_PARAM "server_instance" #define SERVICE_PR_TEST_JSON "prtestjob.json" -#define SERVICE_INTERFACE_DLL "TGServiceInterface.dll" +#define SERVICE_INTERFACE_DLL "TGDreamDaemonBridge.dll" #define SERVICE_INTERFACE_FUNCTION "DDEntryPoint" #define SERVICE_CMD_HARD_REBOOT "hard_reboot" @@ -98,11 +98,12 @@ #define SERVICE_REQUEST_WORLD_REBOOT "worldreboot" #define SERVICE_REQUEST_API_VERSION "api_ver" +#define SERVICE_RETURN_SUCCESS "SUCCESS" + /* The MIT License -Copyright (c) 2011 Dominic Tarr - +Copyright (c) 2017 Jordan Brown Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/code/__DEFINES/shuttles.dm b/code/__DEFINES/shuttles.dm index 26b166fd8c..b961c9bd44 100644 --- a/code/__DEFINES/shuttles.dm +++ b/code/__DEFINES/shuttles.dm @@ -70,4 +70,8 @@ //Rotation params #define ROTATE_DIR 1 #define ROTATE_SMOOTH 2 -#define ROTATE_OFFSET 4 \ No newline at end of file +#define ROTATE_OFFSET 4 + +#define SHUTTLE_DOCKER_LANDING_CLEAR 1 +#define SHUTTLE_DOCKER_BLOCKED_BY_HIDDEN_PORT 2 +#define SHUTTLE_DOCKER_BLOCKED 3 diff --git a/code/__DEFINES/sound.dm b/code/__DEFINES/sound.dm index 6866c024e2..8b93c8e38f 100644 --- a/code/__DEFINES/sound.dm +++ b/code/__DEFINES/sound.dm @@ -20,7 +20,7 @@ #define SOUND_MINIMUM_PRESSURE 10 -#define FALLOFF_SOUNDS 0.5 +#define FALLOFF_SOUNDS 1 //Ambience types diff --git a/code/__DEFINES/stat.dm b/code/__DEFINES/stat.dm index 5dbe99a9c5..a23f050c13 100644 --- a/code/__DEFINES/stat.dm +++ b/code/__DEFINES/stat.dm @@ -1,31 +1,34 @@ -/* - Used with the various stat variables (mob, machines) -*/ - -//mob/var/stat things -#define CONSCIOUS 0 -#define SOFT_CRIT 1 -#define UNCONSCIOUS 2 -#define DEAD 3 - -//mob disabilities stat - -#define BLIND 1 -#define MUTE 2 -#define DEAF 4 -#define NEARSIGHT 8 -#define FAT 32 -#define HUSK 64 -#define NOCLONE 128 -#define CLUMSY 256 - -// bitflags for machine stat variable -#define BROKEN 1 -#define NOPOWER 2 -#define MAINT 4 // under maintaince -#define EMPED 8 // temporary broken by EMP pulse - -//ai power requirement defines -#define POWER_REQ_NONE 0 -#define POWER_REQ_ALL 1 -#define POWER_REQ_CLOCKCULT 2 +/* + Used with the various stat variables (mob, machines) +*/ + +//mob/var/stat things +#define CONSCIOUS 0 +#define SOFT_CRIT 1 +#define UNCONSCIOUS 2 +#define DEAD 3 + +//mob disabilities stat + +#define BLIND 1 +#define MUTE 2 +#define DEAF 4 +#define NEARSIGHT 8 +#define FAT 32 +#define HUSK 64 +#define NOCLONE 128 +#define CLUMSY 256 +#define DUMB 512 +#define MONKEYLIKE 1024 //sets IsAdvancedToolUser to FALSE +#define PACIFISM 2048 + +// bitflags for machine stat variable +#define BROKEN 1 +#define NOPOWER 2 +#define MAINT 4 // under maintaince +#define EMPED 8 // temporary broken by EMP pulse + +//ai power requirement defines +#define POWER_REQ_NONE 0 +#define POWER_REQ_ALL 1 +#define POWER_REQ_CLOCKCULT 2 diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 7e49a437bb..5a0dded276 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -23,8 +23,8 @@ #define FLIGHTSUIT_PROCESSING_FULL 1 #define INITIALIZATION_INSSATOMS 0 //New should not call Initialize -#define INITIALIZATION_INNEW_MAPLOAD 1 //New should call Initialize(TRUE) -#define INITIALIZATION_INNEW_REGULAR 2 //New should call Initialize(FALSE) +#define INITIALIZATION_INNEW_MAPLOAD 2 //New should call Initialize(TRUE) +#define INITIALIZATION_INNEW_REGULAR 1 //New should call Initialize(FALSE) #define INITIALIZE_HINT_NORMAL 0 //Nothing happens #define INITIALIZE_HINT_LATELOAD 1 //Call LateInitialize @@ -46,15 +46,16 @@ #define INIT_ORDER_DBCORE 18 #define INIT_ORDER_BLACKBOX 17 #define INIT_ORDER_SERVER_MAINT 16 -#define INIT_ORDER_EVENTS 15 -#define INIT_ORDER_JOBS 14 -#define INIT_ORDER_TICKER 13 -#define INIT_ORDER_MAPPING 12 -#define INIT_ORDER_ATOMS 11 -#define INIT_ORDER_NETWORKS 10 -#define INIT_ORDER_LANGUAGE 9 -#define INIT_ORDER_MACHINES 8 -#define INIT_ORDER_CIRCUIT 7 +#define INIT_ORDER_RESEARCH 15 +#define INIT_ORDER_EVENTS 14 +#define INIT_ORDER_JOBS 13 +#define INIT_ORDER_TICKER 12 +#define INIT_ORDER_MAPPING 11 +#define INIT_ORDER_ATOMS 10 +#define INIT_ORDER_NETWORKS 9 +#define INIT_ORDER_LANGUAGE 8 +#define INIT_ORDER_MACHINES 7 +#define INIT_ORDER_CIRCUIT 6 #define INIT_ORDER_TIMER 1 #define INIT_ORDER_DEFAULT 0 #define INIT_ORDER_AIR -1 diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index c8163f980a..91eee45b4d 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -9,6 +9,16 @@ * Misc */ +#define LAZYINITLIST(L) if (!L) L = list() +#define UNSETEMPTY(L) if (L && !L.len) L = null +#define LAZYREMOVE(L, I) if(L) { L -= I; if(!L.len) { L = null; } } +#define LAZYADD(L, I) if(!L) { L = list(); } L += I; +#define LAZYACCESS(L, I) (L ? (isnum(I) ? (I > 0 && I <= L.len ? L[I] : null) : L[I]) : null) +#define LAZYSET(L, K, V) if(!L) { L = list(); } L[K] = V; +#define LAZYLEN(L) length(L) +#define LAZYCLEARLIST(L) if(L) L.Cut() +#define SANITIZE_LIST(L) ( islist(L) ? L : list() ) + //Returns a list in plain english as a string /proc/english_list(list/input, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "" ) var/total = input.len @@ -32,9 +42,9 @@ //Returns list element or null. Should prevent "index out of bounds" error. /proc/listgetindex(list/L, index) - if(istype(L)) - if(isnum(index) && IsInteger(index)) - if(IsInRange(index,1,L.len)) + if(LAZYLEN(L)) + if(isnum(index) && ISINTEGER(index)) + if(ISINRANGE(index,1,L.len)) return L[index] else if(index in L) return L[index] @@ -42,7 +52,7 @@ //Return either pick(list) or null if list is not of type /list or is empty /proc/safepick(list/L) - if(istype(L) && L.len) + if(LAZYLEN(L)) return pick(L) //Checks if the list is empty @@ -53,7 +63,7 @@ //Checks for specific types in a list /proc/is_type_in_list(atom/A, list/L) - if(!L || !L.len || !A) + if(!LAZYLEN(L) || !A) return FALSE for(var/type in L) if(istype(A, type)) @@ -62,7 +72,7 @@ //Checks for specific types in specifically structured (Assoc "type" = TRUE) lists ('typecaches') /proc/is_type_in_typecache(atom/A, list/L) - if(!L || !L.len || !A) + if(!LAZYLEN(L) || !A) return FALSE if(ispath(A)) @@ -72,7 +82,7 @@ //Checks for a string in a list /proc/is_string_in_list(string, list/L) - if(!L || !L.len || !string) + if(!LAZYLEN(L) || !string) return for(var/V in L) if(string == V) @@ -81,7 +91,7 @@ //Removes a string from a list /proc/remove_strings_from_list(string, list/L) - if(!L || !L.len || !string) + if(!LAZYLEN(L) || !string) return for(var/V in L) if(V == string) @@ -486,16 +496,6 @@ //Picks from the list, with some safeties, and returns the "default" arg if it fails #define DEFAULTPICK(L, default) ((islist(L) && length(L)) ? pick(L) : default) -#define LAZYINITLIST(L) if (!L) L = list() -#define UNSETEMPTY(L) if (L && !L.len) L = null -#define LAZYREMOVE(L, I) if(L) { L -= I; if(!L.len) { L = null; } } -#define LAZYADD(L, I) if(!L) { L = list(); } L += I; -#define LAZYACCESS(L, I) (L ? (isnum(I) ? (I > 0 && I <= L.len ? L[I] : null) : L[I]) : null) -#define LAZYSET(L, K, V) if(!L) { L = list(); } L[K] = V; -#define LAZYLEN(L) length(L) -#define LAZYCLEARLIST(L) if(L) L.Cut() -#define SANITIZE_LIST(L) ( islist(L) ? L : list() ) - /* Definining a counter as a series of key -> numeric value entries * All these procs modify in place. diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 57fe0559fa..0e1c1c3979 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -326,25 +326,6 @@ return M return null -// 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_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)) - 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)) - if(!G.client.is_afk(afk_bracket) && (be_special_type in G.client.prefs.be_special)) - if (jobbanType) - if(!(jobban_isbanned(G, jobbanType) || jobban_isbanned(G, "Syndicate"))) - candidates += G.client - else - candidates += G.client - 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) diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index ca35aa7e47..17497e3cc0 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -72,11 +72,6 @@ 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() diff --git a/code/__HELPERS/maths.dm b/code/__HELPERS/maths.dm deleted file mode 100644 index f1c901ab9a..0000000000 --- a/code/__HELPERS/maths.dm +++ /dev/null @@ -1,255 +0,0 @@ -// Credits to Nickr5 for the useful procs I've taken from his library resource. - -GLOBAL_VAR_INIT(E, 2.71828183) -GLOBAL_VAR_INIT(Sqrt2, 1.41421356) - -// List of square roots for the numbers 1-100. -GLOBAL_LIST_INIT(sqrtTable, list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10)) - -/proc/sign(x) - return x!=0?x/abs(x):0 - -/proc/Atan2(x, y) - if(!x && !y) - return 0 - var/a = arccos(x / sqrt(x*x + y*y)) - return y >= 0 ? a : -a - -/proc/Ceiling(x, y=1) - return -round(-x / y) * y - -/proc/Floor(x, y=1) - return round(x / y) * y - -#define Clamp(CLVALUE,CLMIN,CLMAX) ( max( (CLMIN), min((CLVALUE), (CLMAX)) ) ) - -/proc/Modulus(x, y) //Byond's modulus doesn't work with decimals. - return x - y * round(x / y) - -// cotangent -/proc/Cot(x) - return 1 / Tan(x) - -// cosecant -/proc/Csc(x) - return 1 / sin(x) - -/proc/Default(a, b) - return a ? a : b - -// Greatest Common Divisor - Euclid's algorithm -/proc/Gcd(a, b) - return b ? Gcd(b, a % b) : a - -/proc/Inverse(x) - return 1 / x - -#define InverseSquareLaw(initial_strength,cur_distance,initial_distance) (initial_strength*(initial_distance**2/cur_distance**2)) - -/proc/IsAboutEqual(a, b, deviation = 0.1) - return abs(a - b) <= deviation - -/proc/IsEven(x) - return x % 2 == 0 - -// Returns true if val is from min to max, inclusive. -/proc/IsInRange(val, min, max) - return min <= val && val <= max - -/proc/IsInteger(x) - return round(x) == x - -/proc/IsOdd(x) - return !IsEven(x) - -/proc/IsMultiple(x, y) - return x % y == 0 - -// Least Common Multiple -/proc/Lcm(a, b) - return abs(a) / Gcd(a, b) * abs(b) - -// Performs a linear interpolation between a and b. -// Note that amount=0 returns a, amount=1 returns b, and -// amount=0.5 returns the mean of a and b. -/proc/Lerp(a, b, amount = 0.5) - return a + (b - a) * amount - -//Calculates the sum of a list of numbers. -/proc/Sum(var/list/data) - . = 0 - for(var/val in data) - .+= val - -//Calculates the mean of a list of numbers. -/proc/Mean(var/list/data) - . = Sum(data) / (data.len) - - -// Returns the nth root of x. -/proc/Root(n, x) - return x ** (1 / n) - -// secant -/proc/Sec(x) - return 1 / cos(x) - -// The quadratic formula. Returns a list with the solutions, or an empty list -// if they are imaginary. -/proc/SolveQuadratic(a, b, c) - ASSERT(a) - . = list() - var/d = b*b - 4 * a * c - var/bottom = 2 * a - if(d < 0) - return - var/root = sqrt(d) - . += (-b + root) / bottom - if(!d) - return - . += (-b - root) / bottom - -// tangent -/proc/Tan(x) - return sin(x) / cos(x) - -/proc/ToDegrees(radians) - // 180 / Pi - return radians * 57.2957795 - -/proc/ToRadians(degrees) - // Pi / 180 - return degrees * 0.0174532925 - -// Will filter out extra rotations and negative rotations -// E.g: 540 becomes 180. -180 becomes 180. -/proc/SimplifyDegrees(degrees) - degrees = degrees % 360 - if(degrees < 0) - degrees += 360 - return degrees - -// min is inclusive, max is exclusive -/proc/Wrap(val, min, max) - var/d = max - min - var/t = round((val - min) / d) - return val - (t * d) - -#define NORM_ROT(rot) ((((rot % 360) + (rot - round(rot, 1))) >= 0) ? ((rot % 360) + (rot - round(rot, 1))) : (((rot % 360) + (rot - round(rot, 1))) + 360)) - -/proc/get_angle_of_incidence(face_angle, angle_in, auto_normalize = TRUE) - - var/angle_in_s = NORM_ROT(angle_in) - var/face_angle_s = NORM_ROT(face_angle) - var/incidence = face_angle_s - angle_in_s - var/incidence_s = incidence - while(incidence_s < -90) - incidence_s += 180 - while(incidence_s > 90) - incidence_s -= 180 - if(auto_normalize) - return incidence_s - else - return incidence - -//A logarithm that converts an integer to a number scaled between 0 and 1 (can be tweaked to be higher). -//Currently, this is used for hydroponics-produce sprite transforming, but could be useful for other transform functions. -/proc/TransformUsingVariable(input, inputmaximum, scaling_modifier = 0) - - var/inputToDegrees = (input/inputmaximum)*180 //Converting from a 0 -> 100 scale to a 0 -> 180 scale. The 0 -> 180 scale corresponds to degrees - var/size_factor = ((-cos(inputToDegrees) +1) /2) //returns a value from 0 to 1 - - return size_factor + scaling_modifier //scale mod of 0 results in a number from 0 to 1. A scale modifier of +0.5 returns 0.5 to 1.5 - -//converts a uniform distributed random number into a normal distributed one -//since this method produces two random numbers, one is saved for subsequent calls -//(making the cost negligble for every second call) -//This will return +/- decimals, situated about mean with standard deviation stddev -//68% chance that the number is within 1stddev -//95% chance that the number is within 2stddev -//98% chance that the number is within 3stddev...etc -#define ACCURACY 10000 -/proc/gaussian(mean, stddev) - var/static/gaussian_next - var/R1;var/R2;var/working - if(gaussian_next != null) - R1 = gaussian_next - gaussian_next = null - else - do - R1 = rand(-ACCURACY,ACCURACY)/ACCURACY - R2 = rand(-ACCURACY,ACCURACY)/ACCURACY - working = R1*R1 + R2*R2 - while(working >= 1 || working==0) - working = sqrt(-2 * log(working) / working) - R1 *= working - gaussian_next = R2 * working - return (mean + stddev * R1) -#undef ACCURACY - -/proc/mouse_angle_from_client(client/client) - var/list/mouse_control = params2list(client.mouseParams) - if(mouse_control["screen-loc"]) - var/list/screen_loc_params = splittext(mouse_control["screen-loc"], ",") - var/list/screen_loc_X = splittext(screen_loc_params[1],":") - var/list/screen_loc_Y = splittext(screen_loc_params[2],":") - var/x = (text2num(screen_loc_X[1]) * 32 + text2num(screen_loc_X[2]) - 32) - var/y = (text2num(screen_loc_Y[1]) * 32 + text2num(screen_loc_Y[2]) - 32) - var/screenview = (client.view * 2 + 1) * world.icon_size //Refer to http://www.byond.com/docs/ref/info.html#/client/var/view for mad maths - var/ox = round(screenview/2) - client.pixel_x //"origin" x - var/oy = round(screenview/2) - client.pixel_y //"origin" y - var/angle = NORM_ROT(Atan2(y - oy, x - ox)) - return angle - -/proc/get_turf_in_angle(angle, turf/starting, increments) - var/pixel_x = 0 - var/pixel_y = 0 - for(var/i in 1 to increments) - pixel_x += sin(angle)+16*sin(angle)*2 - pixel_y += cos(angle)+16*cos(angle)*2 - var/new_x = starting.x - var/new_y = starting.y - while(pixel_x > 16) - pixel_x -= 32 - new_x++ - while(pixel_x < -16) - pixel_x += 32 - new_x-- - while(pixel_y > 16) - pixel_y -= 32 - new_y++ - while(pixel_y < -16) - pixel_y += 32 - new_y-- - new_x = Clamp(new_x, 0, world.maxx) - new_y = Clamp(new_y, 0, world.maxy) - return locate(new_x, new_y, starting.z) - -/proc/round_down(num) - if(round(num) != num) - return round(num--) - else return num - -//proc/get_overlap() -// Returns a list where [1] is all x values and [2] is all y values that overlap between the given pair of rectangles -/proc/get_overlap(x1, y1, x2, y2, x3, y3, x4, y4) - var/list/region_x1 = list() - var/list/region_y1 = list() - var/list/region_x2 = list() - var/list/region_y2 = list() - - // These loops create loops filled with x/y values that the boundaries inhabit - // ex: list(5, 6, 7, 8, 9) - for(var/i in min(x1, x2) to max(x1, x2)) - region_x1["[i]"] = TRUE - for(var/i in min(y1, y2) to max(y1, y2)) - region_y1["[i]"] = TRUE - for(var/i in min(x3, x4) to max(x3, x4)) - region_x2["[i]"] = TRUE - for(var/i in min(y3, y4) to max(y3, y4)) - region_y2["[i]"] = TRUE - - return list(region_x1 & region_x2, region_y1 & region_y2) \ No newline at end of file diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 4800f35b65..d3b62b67af 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -359,7 +359,7 @@ Proc for attack log creation, because really why not if(!user) return 0 var/atom/Tloc = null - if(target) + if(target && !isturf(target)) Tloc = target.loc var/atom/Uloc = user.loc diff --git a/code/__HELPERS/names.dm b/code/__HELPERS/names.dm index bfcfd23f50..90205168b5 100644 --- a/code/__HELPERS/names.dm +++ b/code/__HELPERS/names.dm @@ -121,9 +121,6 @@ GLOBAL_VAR(command_name) return new_station_name /proc/syndicate_name() - var/static/syndicate_name - if (syndicate_name) - return syndicate_name var/name = "" @@ -146,8 +143,7 @@ GLOBAL_VAR(command_name) else name += pick("-", "*", "") name += pick("Tech", "Sun", "Co", "Tek", "X", "Inc", "Gen", "Star", "Dyne", "Code", "Hive") - - syndicate_name = name + return name diff --git a/code/__HELPERS/radio.dm b/code/__HELPERS/radio.dm index 1706e8658c..39fe55c67c 100644 --- a/code/__HELPERS/radio.dm +++ b/code/__HELPERS/radio.dm @@ -1,14 +1,14 @@ -// Ensure the frequency is within bounds of what it should be sending/recieving at -/proc/sanitize_frequency(frequency, free = FALSE) - . = round(frequency) - if(free) - . = Clamp(frequency, MIN_FREE_FREQ, MAX_FREE_FREQ) - else - . = Clamp(frequency, MIN_FREQ, MAX_FREQ) - if(!(. % 2)) // Ensure the last digit is an odd number - . += 1 - -// Format frequency by moving the decimal. -/proc/format_frequency(frequency) - frequency = text2num(frequency) - return "[round(frequency / 10)].[frequency % 10]" +// Ensure the frequency is within bounds of what it should be sending/recieving at +/proc/sanitize_frequency(frequency, free = FALSE) + . = round(frequency) + if(free) + . = CLAMP(frequency, MIN_FREE_FREQ, MAX_FREE_FREQ) + else + . = CLAMP(frequency, MIN_FREQ, MAX_FREQ) + if(!(. % 2)) // Ensure the last digit is an odd number + . += 1 + +// Format frequency by moving the decimal. +/proc/format_frequency(frequency) + frequency = text2num(frequency) + return "[round(frequency / 10)].[frequency % 10]" diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm new file mode 100644 index 0000000000..f009ff9c00 --- /dev/null +++ b/code/__HELPERS/roundend.dm @@ -0,0 +1,420 @@ +/datum/controller/subsystem/ticker/proc/gather_roundend_feedback() + var/clients = GLOB.player_list.len + var/surviving_humans = 0 + var/surviving_total = 0 + var/ghosts = 0 + var/escaped_humans = 0 + var/escaped_total = 0 + + for(var/mob/M in GLOB.player_list) + if(ishuman(M)) + if(!M.stat) + surviving_humans++ + if(M.z == ZLEVEL_CENTCOM) + escaped_humans++ + if(!M.stat) + surviving_total++ + if(M.z == ZLEVEL_CENTCOM) + escaped_total++ + + if(isobserver(M)) + ghosts++ + + if(clients) + SSblackbox.record_feedback("nested tally", "round_end_stats", clients, list("clients")) + if(ghosts) + SSblackbox.record_feedback("nested tally", "round_end_stats", ghosts, list("ghosts")) + if(surviving_humans) + SSblackbox.record_feedback("nested tally", "round_end_stats", surviving_humans, list("survivors", "human")) + if(surviving_total) + SSblackbox.record_feedback("nested tally", "round_end_stats", surviving_total, list("survivors", "total")) + if(escaped_humans) + SSblackbox.record_feedback("nested tally", "round_end_stats", escaped_humans, list("escapees", "human")) + if(escaped_total) + SSblackbox.record_feedback("nested tally", "round_end_stats", escaped_total, list("escapees", "total")) + + gather_antag_success_rate() + +/datum/controller/subsystem/ticker/proc/gather_antag_success_rate() + var/team_gid = 1 + var/list/team_ids = list() + + for(var/datum/antagonist/A in GLOB.antagonists) + var/list/antag_info = list() + antag_info["key"] = A.owner.key + antag_info["name"] = A.owner.name + antag_info["antagonist_type"] = A.type + antag_info["antagonist_name"] = A.name //For auto and custom roles + antag_info["objectives"] = list() + antag_info["team"] = list() + var/datum/team/T = A.get_team() + if(T) + antag_info["team"]["type"] = T.type + antag_info["team"]["name"] = T.name + if(!team_ids[T]) + team_ids[T] = team_gid++ + antag_info["team"]["id"] = team_ids[T] + + if(!A.owner) + continue + if(A.objectives.len) + for(var/datum/objective/O in A.objectives) + var/result = O.check_completion() ? "SUCCESS" : "FAIL" + antag_info["objectives"] += list(list("objective_type"=O.type,"text"=O.explanation_text,"result"=result)) + SSblackbox.record_feedback("associative", "antagonists", 1, antag_info) + + +/datum/controller/subsystem/ticker/proc/declare_completion() + set waitfor = FALSE + + to_chat(world, "


The round has ended.") + if(LAZYLEN(GLOB.round_end_notifiees)) + send2irc("Notice", "[GLOB.round_end_notifiees.Join(", ")] the round has ended.") + + /*for(var/client/C in GLOB.clients) + if(!C.credits) + C.RollCredits() + C.playtitlemusic(40)*/ + + display_report() + + gather_roundend_feedback() + + CHECK_TICK + + // Add AntagHUD to everyone, see who was really evil the whole time! + for(var/datum/atom_hud/antag/H in GLOB.huds) + for(var/m in GLOB.player_list) + var/mob/M = m + H.add_hud_to(M) + + CHECK_TICK + + //Set news report and mode result + mode.set_round_result() + + send2irc("Server", "Round just ended.") + + if(CONFIG_GET(string/cross_server_address)) + send_news_report() + + CHECK_TICK + + //These need update to actually reflect the real antagonists + //Print a list of antagonists to the server log + var/list/total_antagonists = list() + //Look into all mobs in world, dead or alive + for(var/datum/mind/Mind in minds) + var/temprole = Mind.special_role + if(temprole) //if they are an antagonist of some sort. + if(temprole in total_antagonists) //If the role exists already, add the name to it + total_antagonists[temprole] += ", [Mind.name]([Mind.key])" + else + total_antagonists.Add(temprole) //If the role doesnt exist in the list, create it and add the mob + total_antagonists[temprole] += ": [Mind.name]([Mind.key])" + + CHECK_TICK + + //Now print them all into the log! + log_game("Antagonists at round end were...") + for(var/i in total_antagonists) + log_game("[i]s[total_antagonists[i]].") + + CHECK_TICK + + //Collects persistence features + if(mode.allow_persistence_save) + SSpersistence.CollectData() + + //stop collecting feedback during grifftime + SSblackbox.Seal() + + sleep(50) + ready_for_reboot = TRUE + standard_reboot() + +/datum/controller/subsystem/ticker/proc/standard_reboot() + if(ready_for_reboot) + if(mode.station_was_nuked) + Reboot("Station destroyed by Nuclear Device.", "nuke") + else + Reboot("Round ended.", "proper completion") + else + CRASH("Attempted standard reboot without ticker roundend completion") + +//Common part of the report +/datum/controller/subsystem/ticker/proc/build_roundend_report() + var/list/parts = list() + + //Gamemode specific things. Should be empty most of the time. + parts += mode.special_report() + + CHECK_TICK + + //AI laws + parts += law_report() + + CHECK_TICK + + //Antagonists + parts += antag_report() + + CHECK_TICK + //Medals + parts += medal_report() + //Station Goals + parts += goal_report() + + listclearnulls(parts) + + return parts.Join() + + +/datum/controller/subsystem/ticker/proc/survivor_report() + var/list/parts = list() + var/station_evacuated = EMERGENCY_ESCAPED_OR_ENDGAMED + var/num_survivors = 0 + var/num_escapees = 0 + var/num_shuttle_escapees = 0 + + //Player status report + for(var/i in GLOB.mob_list) + var/mob/Player = i + if(Player.mind && !isnewplayer(Player)) + if(Player.stat != DEAD && !isbrain(Player)) + num_survivors++ + if(station_evacuated) //If the shuttle has already left the station + var/list/area/shuttle_areas + if(SSshuttle && SSshuttle.emergency) + shuttle_areas = SSshuttle.emergency.shuttle_areas + if(Player.onCentCom() || Player.onSyndieBase()) + num_escapees++ + if(shuttle_areas[get_area(Player)]) + num_shuttle_escapees++ + + //Round statistics report + var/datum/station_state/end_state = new /datum/station_state() + end_state.count() + var/station_integrity = min(PERCENT(GLOB.start_state.score(end_state)), 100) + + parts += "[GLOB.TAB]Shift Duration: [DisplayTimeText(world.time - SSticker.round_start_time)]" + parts += "[GLOB.TAB]Station Integrity: [mode.station_was_nuked ? "Destroyed" : "[station_integrity]%"]" + var/total_players = GLOB.joined_player_list.len + if(total_players) + parts+= "[GLOB.TAB]Total Population: [total_players]" + if(station_evacuated) + parts += "
[GLOB.TAB]Evacuation Rate: [num_escapees] ([PERCENT(num_escapees/total_players)]%)" + parts += "[GLOB.TAB](on emergency shuttle): [num_shuttle_escapees] ([PERCENT(num_shuttle_escapees/total_players)]%)" + parts += "[GLOB.TAB]Survival Rate: [num_survivors] ([PERCENT(num_survivors/total_players)]%)" + return parts.Join("
") + +/datum/controller/subsystem/ticker/proc/show_roundend_report(client/C,common_report) + var/list/report_parts = list() + + report_parts += personal_report(C) + report_parts += common_report + + var/datum/browser/roundend_report = new(C, "roundend") + roundend_report.width = 800 + roundend_report.height = 600 + roundend_report.set_content(report_parts.Join()) + roundend_report.stylesheets = list() + roundend_report.add_stylesheet("roundend",'html/browser/roundend.css') + + roundend_report.open(0) + +/datum/controller/subsystem/ticker/proc/personal_report(client/C) + var/list/parts = list() + var/mob/M = C.mob + if(M.mind && !isnewplayer(M)) + if(M.stat != DEAD && !isbrain(M)) + if(EMERGENCY_ESCAPED_OR_ENDGAMED) + if(!M.onCentCom() || !M.onSyndieBase()) + parts += "
" + parts += "You managed to survive, but were marooned on [station_name()]..." + else + parts += "
" + parts += "You managed to survive the events on [station_name()] as [M.real_name]." + else + parts += "
" + parts += "You managed to survive the events on [station_name()] as [M.real_name]." + + else + parts += "
" + parts += "You did not survive the events on [station_name()]..." + else + parts += "
" + parts += "
" + if(GLOB.survivor_report) + parts += GLOB.survivor_report + else + parts += survivor_report() + + parts += "
" + + return parts.Join() + +/datum/controller/subsystem/ticker/proc/display_report() + GLOB.common_report = build_roundend_report() + for(var/client/C in GLOB.clients) + show_roundend_report(C,GLOB.common_report) + give_show_report_button(C) + CHECK_TICK + +/datum/controller/subsystem/ticker/proc/law_report() + var/list/parts = list() + //Silicon laws report + for (var/i in GLOB.ai_list) + var/mob/living/silicon/ai/aiPlayer = i + if(aiPlayer.mind) + parts += "[aiPlayer.name] (Played by: [aiPlayer.mind.key])'s laws [aiPlayer.stat != DEAD ? "at the end of the round" : "when it was deactivated"] were:" + parts += aiPlayer.laws.get_law_list(include_zeroth=TRUE) + + parts += "Total law changes: [aiPlayer.law_change_counter]" + + if (aiPlayer.connected_robots.len) + var/robolist = "[aiPlayer.real_name]'s minions were: " + for(var/mob/living/silicon/robot/robo in aiPlayer.connected_robots) + if(robo.mind) + robolist += "[robo.name][robo.stat?" (Deactivated) (Played by: [robo.mind.key]), ":" (Played by: [robo.mind.key]), "]" + parts += "[robolist]" + + for (var/mob/living/silicon/robot/robo in GLOB.silicon_mobs) + if (!robo.connected_ai && robo.mind) + if (robo.stat != DEAD) + parts += "[robo.name] (Played by: [robo.mind.key]) survived as an AI-less borg! Its laws were:" + else + parts += "[robo.name] (Played by: [robo.mind.key]) was unable to survive the rigors of being a cyborg without an AI. Its laws were:" + + if(robo) //How the hell do we lose robo between here and the world messages directly above this? + parts += robo.laws.get_law_list(include_zeroth=TRUE) + if(parts.len) + return "
[parts.Join("
")]
" + else + return "" + +/datum/controller/subsystem/ticker/proc/goal_report() + var/list/parts = list() + if(mode.station_goals.len) + for(var/V in mode.station_goals) + var/datum/station_goal/G = V + parts += G.get_result() + return "
    [parts.Join()]
" + +/datum/controller/subsystem/ticker/proc/medal_report() + if(GLOB.commendations.len) + var/list/parts = list() + parts += "Medal Commendations:" + for (var/com in GLOB.commendations) + parts += com + return "
[parts.Join("
")]
" + return "" + +/datum/controller/subsystem/ticker/proc/antag_report() + var/list/result = list() + var/list/all_teams = list() + var/list/all_antagonists = list() + + for(var/datum/antagonist/A in GLOB.antagonists) + all_teams |= A.get_team() + all_antagonists += A + + for(var/datum/team/T in all_teams) + result += T.roundend_report() + for(var/datum/antagonist/X in all_antagonists) + if(X.get_team() == T) + all_antagonists -= X + result += " "//newline between teams + + var/currrent_category + var/datum/antagonist/previous_category + + sortTim(all_antagonists, /proc/cmp_antag_category) + + for(var/datum/antagonist/A in all_antagonists) + if(!A.show_in_roundend) + continue + if(A.roundend_category != currrent_category) + if(previous_category) + result += previous_category.roundend_report_footer() + result += "
" + result += "
" + result += A.roundend_report_header() + currrent_category = A.roundend_category + previous_category = A + result += A.roundend_report() + result += "
" + + if(all_antagonists.len) + var/datum/antagonist/last = all_antagonists[all_antagonists.len] + result += last.roundend_report_footer() + result += "
" + + return result.Join() + +/proc/cmp_antag_category(datum/antagonist/A,datum/antagonist/B) + return sorttext(B.roundend_category,A.roundend_category) + + +/datum/controller/subsystem/ticker/proc/give_show_report_button(client/C) + var/datum/action/report/R = new + C.player_details.player_actions += R + R.Grant(C.mob) + to_chat(C,"Show roundend report again") + +/datum/action/report + name = "Show roundend report" + button_icon_state = "vote" + +/datum/action/report/Trigger() + if(owner && GLOB.common_report && SSticker.current_state == GAME_STATE_FINISHED) + SSticker.show_roundend_report(owner.client,GLOB.common_report) + +/datum/action/report/IsAvailable() + return 1 + +/datum/action/report/Topic(href,href_list) + if(usr != owner) + return + if(href_list["report"]) + Trigger() + return + + +/proc/printplayer(datum/mind/ply, fleecheck) + var/text = "[ply.key] was [ply.name] the [ply.assigned_role] and" + if(ply.current) + if(ply.current.stat == DEAD) + text += " died" + else + text += " survived" + if(fleecheck) + var/turf/T = get_turf(ply.current) + if(!T || !(T.z in GLOB.station_z_levels)) + text += " while fleeing the station" + if(ply.current.real_name != ply.name) + text += " as [ply.current.real_name]" + else + text += " had their body destroyed" + return text + +/proc/printplayerlist(list/players,fleecheck) + var/list/parts = list() + + parts += "
    " + for(var/datum/mind/M in players) + parts += "
  • [printplayer(M,fleecheck)]
  • " + parts += "
" + return parts.Join() + + +/proc/printobjectives(datum/mind/ply) + var/list/objective_parts = list() + var/count = 1 + for(var/datum/objective/objective in ply.objectives) + if(objective.check_completion()) + objective_parts += "Objective #[count]: [objective.explanation_text] Success!" + else + objective_parts += "Objective #[count]: [objective.explanation_text] Fail." + count++ + return objective_parts.Join("
") diff --git a/code/__HELPERS/time.dm b/code/__HELPERS/time.dm index 74c565da52..68ab173ecd 100644 --- a/code/__HELPERS/time.dm +++ b/code/__HELPERS/time.dm @@ -60,7 +60,7 @@ GLOBAL_VAR_INIT(rollovercheck_last_timeofday, 0) if(!second) return "0 seconds" if(second >= 60) - minute = round_down(second/60) + minute = FLOOR(second/60, 1) second = round(second - (minute*60), 0.1) second_rounded = TRUE if(second) //check if we still have seconds remaining to format, or if everything went into minute. @@ -91,7 +91,7 @@ GLOBAL_VAR_INIT(rollovercheck_last_timeofday, 0) if(!minute) return "[second]" if(minute >= 60) - hour = round_down(minute/60,1) + hour = FLOOR(minute/60, 1) minute = (minute - (hour*60)) if(minute) //alot simpler from here since you don't have to worry about fractions if(minute != 1) @@ -114,7 +114,7 @@ GLOBAL_VAR_INIT(rollovercheck_last_timeofday, 0) if(!hour) return "[minute][second]" if(hour >= 24) - day = round_down(hour/24,1) + day = FLOOR(hour/24, 1) hour = (hour - (day*24)) if(hour) if(hour != 1) diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index 64ea8de756..2ebe24b85b 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -14,30 +14,23 @@ //breaks when hittin invalid characters thereafter /proc/hex2num(hex) . = 0 - if(istext(hex)) - var/negative = 0 - var/len = length(hex) - for(var/i=1, i<=len, i++) - var/num = text2ascii(hex,i) - switch(num) - if(48 to 57) - num -= 48 //0-9 - if(97 to 102) - num -= 87 //a-f - if(65 to 70) - num -= 55 //A-F - if(45) - negative = 1//- - else - if(num) - break - else - continue - . *= 16 - . += num - if(negative) - . *= -1 - return . + var/place = 1 + for(var/i in length(hex) to 1 step -1) + var/num = text2ascii(hex, i) + switch(num) + if(48 to 57) + num -= 48 //0-9 + if(97 to 102) + num -= 87 //a-f + if(65 to 70) + num -= 55 //A-F + if(45) + return . * -1 // - + else + CRASH("Malformed hex number") + + . += num * place + place *= 16 //Returns the hex value of a decimal number //len == length of returned string @@ -124,7 +117,7 @@ //Converts an angle (degrees) into an ss13 direction /proc/angle2dir(degree) - degree = SimplifyDegrees(degree) + degree = SIMPLIFY_DEGREES(degree) switch(degree) if(0 to 22.5) //north requires two angle ranges return NORTH diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 5e266fdaa2..1fd60c2bd4 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -147,10 +147,10 @@ Turf and target are separate in case you want to teleport some distance from a t var/line[] = list(locate(px,py,M.z)) var/dx=N.x-px //x distance var/dy=N.y-py - var/dxabs=abs(dx)//Absolute value of x distance - var/dyabs=abs(dy) - var/sdx=sign(dx) //Sign of x distance (+ or -) - var/sdy=sign(dy) + var/dxabs = abs(dx)//Absolute value of x distance + var/dyabs = abs(dy) + var/sdx = SIGN(dx) //Sign of x distance (+ or -) + var/sdy = SIGN(dy) var/x=dxabs>>1 //Counters for steps taken, setting to distance/2 var/y=dyabs>>1 //Bit-shifting makes me l33t. It also makes getline() unnessecarrily fast. var/j //Generic integer for counting @@ -353,9 +353,8 @@ Turf and target are separate in case you want to teleport some distance from a t var/M = E/(SPEED_OF_LIGHT_SQ) return M -//Takes the value of energy used/produced/ect. -//Returns a text value of that number in W, kW, MW, or GW. -/proc/DisplayPower(var/powerused) +// Format a power value in W, kW, MW, or GW. +/proc/DisplayPower(powerused) if(powerused < 1000) //Less than a kW return "[powerused] W" else if(powerused < 1000000) //Less than a MW @@ -364,6 +363,21 @@ Turf and target are separate in case you want to teleport some distance from a t return "[round((powerused * 0.000001),0.001)] MW" return "[round((powerused * 0.000000001),0.0001)] GW" +// Format an energy value in J, kJ, MJ, or GJ. 1W = 1J/s. +/proc/DisplayEnergy(units) + // APCs process every (SSmachines.wait * 0.1) seconds, and turn 1 W of + // excess power into GLOB.CELLRATE energy units when charging cells. + // With the current configuration of wait=20 and CELLRATE=0.002, this + // means that one unit is 1 kJ. + units *= SSmachines.wait * 0.1 / GLOB.CELLRATE + if (units < 1000) // Less than a kJ + return "[round(units, 0.1)] J" + else if (units < 1000000) // Less than a MJ + return "[round(units * 0.001, 0.01)] kJ" + else if (units < 1000000000) // Less than a GJ + return "[round(units * 0.000001, 0.001)] MJ" + return "[round(units * 0.000000001, 0.0001)] GJ" + /proc/key_name(whom, include_link = null, include_name = 1) var/mob/M var/client/C @@ -939,8 +953,8 @@ GLOBAL_LIST_INIT(WALLITEMS_INVERSE, typecacheof(list( tY = tY[1] tX = splittext(tX[1], ":") tX = tX[1] - tX = Clamp(origin.x + text2num(tX) - world.view - 1, 1, world.maxx) - tY = Clamp(origin.y + text2num(tY) - world.view - 1, 1, world.maxy) + tX = CLAMP(origin.x + text2num(tX) - world.view - 1, 1, world.maxx) + tY = CLAMP(origin.y + text2num(tY) - world.view - 1, 1, world.maxy) return locate(tX, tY, tZ) /proc/screen_loc2turf(text, turf/origin) @@ -952,8 +966,8 @@ GLOBAL_LIST_INIT(WALLITEMS_INVERSE, typecacheof(list( tX = splittext(tZ[2], "-") tX = text2num(tX[2]) tZ = origin.z - tX = Clamp(origin.x + 7 - tX, 1, world.maxx) - tY = Clamp(origin.y + 7 - tY, 1, world.maxy) + tX = CLAMP(origin.x + 7 - tX, 1, world.maxx) + tY = CLAMP(origin.y + 7 - tY, 1, world.maxy) return locate(tX, tY, tZ) /proc/IsValidSrc(datum/D) @@ -1258,7 +1272,7 @@ proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types()) . = 0 var/i = DS2TICKS(initial_delay) do - . += Ceiling(i*DELTA_CALC) + . += CEILING(i*DELTA_CALC, 1) sleep(i*world.tick_lag*DELTA_CALC) i *= 2 while (TICK_USAGE > min(TICK_LIMIT_TO_RUN, Master.current_ticklimit)) @@ -1493,3 +1507,35 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) else return "\[[url_encode(thing.tag)]\]" return "\ref[input]" + +// Makes a call in the context of a different usr +// Use sparingly +/world/proc/PushUsr(mob/M, datum/callback/CB) + var/temp = usr + usr = M + . = CB.Invoke() + usr = temp + +//Returns a list of all servants of Ratvar and observers. +/proc/servants_and_ghosts() + . = list() + for(var/V in GLOB.player_list) + if(is_servant_of_ratvar(V) || isobserver(V)) + . += V + +//datum may be null, but it does need to be a typed var +#define NAMEOF(datum, X) (list(##datum.##X, #X)[2]) + +#define VARSET_LIST_CALLBACK(target, var_name, var_value) CALLBACK(GLOBAL_PROC, /proc/___callbackvarset, ##target, ##var_name, ##var_value) +//dupe code because dm can't handle 3 level deep macros +#define VARSET_CALLBACK(datum, var, var_value) CALLBACK(GLOBAL_PROC, /proc/___callbackvarset, ##datum, NAMEOF(##datum, ##var), ##var_value) + +/proc/___callbackvarset(list_or_datum, var_name, var_value) + if(length(list_or_datum)) + list_or_datum[var_name] = var_value + return + var/datum/D = list_or_datum + if(IsAdminAdvancedProcCall()) + D.vv_edit_var(var_name, var_value) //same result generally, unless badmemes + else + D.vars[var_name] = var_value diff --git a/code/__HELPERS/view.dm b/code/__HELPERS/view.dm new file mode 100644 index 0000000000..85819a5ef0 --- /dev/null +++ b/code/__HELPERS/view.dm @@ -0,0 +1,12 @@ +/proc/getviewsize(view) + var/viewX + var/viewY + if(isnum(view)) + var/totalviewrange = 1 + 2 * view + viewX = totalviewrange + viewY = totalviewrange + else + var/list/viewrangelist = splittext(view,"x") + viewX = text2num(viewrangelist[1]) + viewY = text2num(viewrangelist[2]) + return list(viewX, viewY) \ No newline at end of file diff --git a/code/_globalvars/configuration.dm b/code/_globalvars/configuration.dm index 391744e34c..8ecf572ea7 100644 --- a/code/_globalvars/configuration.dm +++ b/code/_globalvars/configuration.dm @@ -35,4 +35,3 @@ 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/game_modes.dm b/code/_globalvars/game_modes.dm index 9c3af923f1..3822f7077d 100644 --- a/code/_globalvars/game_modes.dm +++ b/code/_globalvars/game_modes.dm @@ -1,18 +1,12 @@ GLOBAL_VAR_INIT(master_mode, "traitor") //"extended" GLOBAL_VAR_INIT(secret_force_mode, "secret") // if this is anything but "secret", the secret rotation will forceably choose this mode +GLOBAL_VAR(common_report) //Contains commmon part of roundend report +GLOBAL_VAR(survivor_report) //Contains shared surivor report for roundend report (part of personal report) + GLOBAL_VAR_INIT(wavesecret, 0) // meteor mode, delays wave progression, terrible name GLOBAL_DATUM(start_state, /datum/station_state) // Used in round-end report -// Cult, needs to be global so admin cultists are functional -GLOBAL_VAR_INIT(blood_target, null) // Cult Master's target or Construct's Master -GLOBAL_DATUM(blood_target_image, /image) -GLOBAL_VAR_INIT(blood_target_reset_timer, null) -GLOBAL_DATUM(sac_mind, /datum/mind) -GLOBAL_VAR_INIT(sac_image, null) -GLOBAL_VAR_INIT(cult_vote_called, FALSE) -GLOBAL_VAR_INIT(cult_mastered, FALSE) -GLOBAL_VAR_INIT(reckoning_complete, FALSE) -GLOBAL_VAR_INIT(sac_complete, FALSE) -GLOBAL_DATUM(cult_narsie, /obj/singularity/narsie/large/cult) -GLOBAL_LIST_EMPTY(summon_spots) \ No newline at end of file + +//TODO clear this one up too +GLOBAL_DATUM(cult_narsie, /obj/singularity/narsie/large/cult) \ No newline at end of file diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm index a9ffde59e3..89e4481284 100644 --- a/code/_globalvars/lists/mobs.dm +++ b/code/_globalvars/lists/mobs.dm @@ -24,6 +24,7 @@ GLOBAL_LIST_EMPTY(pai_list) GLOBAL_LIST_EMPTY(available_ai_shells) GLOBAL_LIST_INIT(simple_animals, list(list(),list(),list())) // One for each AI_* status define GLOBAL_LIST_EMPTY(spidermobs) //all sentient spider mobs +GLOBAL_LIST_EMPTY(bots_list) GLOBAL_LIST_EMPTY(language_datum_instances) GLOBAL_LIST_EMPTY(all_languages) diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm index 12173b21b7..ad295167cf 100644 --- a/code/_globalvars/lists/objects.dm +++ b/code/_globalvars/lists/objects.dm @@ -4,6 +4,7 @@ GLOBAL_LIST_EMPTY(airlocks) //list of all airlocks GLOBAL_LIST_EMPTY(mechas_list) //list of all mechs. Used by hostile mobs target tracking. GLOBAL_LIST_EMPTY(shuttle_caller_list) //list of all communication consoles and AIs, for automatic shuttle calls when there are none. GLOBAL_LIST_EMPTY(machines) //NOTE: this is a list of ALL machines now. The processing machines list is SSmachine.processing ! +GLOBAL_LIST_EMPTY(navigation_computers) //list of all /obj/machinery/computer/camera_advanced/shuttle_docker GLOBAL_LIST_EMPTY(syndicate_shuttle_boards) //important to keep track of for managing nukeops war declarations. GLOBAL_LIST_EMPTY(navbeacons) //list of all bot nagivation beacons, used for patrolling. GLOBAL_LIST_EMPTY(teleportbeacons) //list of all tracking beacons used by teleporters diff --git a/code/_globalvars/misc.dm b/code/_globalvars/misc.dm index bb86b4cbb0..8b8b817586 100644 --- a/code/_globalvars/misc.dm +++ b/code/_globalvars/misc.dm @@ -16,3 +16,5 @@ GLOBAL_VAR_INIT(CHARGELEVEL, 0.001) // Cap for how fast cells charge, as a perce GLOBAL_LIST_EMPTY(powernets) GLOBAL_VAR_INIT(bsa_unlock, FALSE) //BSA unlocked by head ID swipes + +GLOBAL_LIST_EMPTY(player_details) // ckey -> /datum/player_details \ No newline at end of file diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index c9e97726b3..ce9e1ead82 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -285,7 +285,7 @@ if(!stat && mind && iscarbon(A) && A != src) var/datum/antagonist/changeling/C = mind.has_antag_datum(/datum/antagonist/changeling) if(C && C.chosen_sting) - C.chosen_sting.try_to_sting(src,A) + C.chosen_sting.try_to_sting(src,A) next_click = world.time + 5 return swap_hand() @@ -349,7 +349,7 @@ if(!stat && mind && iscarbon(A) && A != src) var/datum/antagonist/changeling/C = mind.has_antag_datum(/datum/antagonist/changeling) if(C && C.chosen_sting) - C.chosen_sting.try_to_sting(src,A) + C.chosen_sting.try_to_sting(src,A) next_click = world.time + 5 return ..() @@ -433,28 +433,38 @@ else setDir(WEST) +//debug +/obj/screen/proc/scale_to(x1,y1) + if(!y1) + y1 = x1 + var/matrix/M = new + M.Scale(x1,y1) + transform = M + /obj/screen/click_catcher icon = 'icons/mob/screen_gen.dmi' - icon_state = "flash" + icon_state = "catcher" plane = CLICKCATCHER_PLANE mouse_opacity = MOUSE_OPACITY_OPAQUE screen_loc = "CENTER" -/obj/screen/click_catcher/proc/UpdateGreed(view_size_x = 7, view_size_y = 7) - var/icon/newicon = icon('icons/mob/screen_gen.dmi', "flash") - if(view_size_x > 16 || view_size_y > 16) - newicon.Scale((16 * 2 + 1) * world.icon_size,(16 * 2 + 1) * world.icon_size) - icon = newicon - var/tx = view_size_x/16 - var/ty = view_size_y/16 - var/matrix/M = new - M.Scale(tx, ty) - transform = M - screen_loc = "CENTER-16,CENTER-16" - else - screen_loc = "CENTER-[view_size_x],CENTER-[view_size_y]" - newicon.Scale((view_size_x * 2 + 1) * world.icon_size,(view_size_y * 2 + 1) * world.icon_size) - icon = newicon +#define MAX_SAFE_BYOND_ICON_SCALE_TILES (MAX_SAFE_BYOND_ICON_SCALE_PX / world.icon_size) +#define MAX_SAFE_BYOND_ICON_SCALE_PX 33 * 32 //Not using world.icon_size on purpose. + +/obj/screen/click_catcher/proc/UpdateGreed(view_size_x = 15, view_size_y = 15) + var/icon/newicon = icon('icons/mob/screen_gen.dmi', "catcher") + var/ox = min(MAX_SAFE_BYOND_ICON_SCALE_TILES, view_size_x) + var/oy = min(MAX_SAFE_BYOND_ICON_SCALE_TILES, view_size_y) + var/px = view_size_x * world.icon_size + var/py = view_size_y * world.icon_size + var/sx = min(MAX_SAFE_BYOND_ICON_SCALE_PX, px) + var/sy = min(MAX_SAFE_BYOND_ICON_SCALE_PX, py) + newicon.Scale(sx, sy) + icon = newicon + screen_loc = "CENTER-[(ox-1)*0.5],CENTER-[(oy-1)*0.5]" + var/matrix/M = new + M.Scale(px/sx, py/sy) + transform = M /obj/screen/click_catcher/Click(location, control, params) var/list/modifiers = params2list(params) diff --git a/code/_onclick/hud/action_button.dm b/code/_onclick/hud/action_button.dm index d4d2c2d8a5..cd24e68cbb 100644 --- a/code/_onclick/hud/action_button.dm +++ b/code/_onclick/hud/action_button.dm @@ -8,15 +8,22 @@ var/button_icon_state var/appearance_cache + var/id + /obj/screen/movable/action_button/Click(location,control,params) var/list/modifiers = params2list(params) if(modifiers["shift"]) + if(locked) + to_chat(usr, "Action button \"[name]\" is locked, unlock it first.") + return TRUE moved = 0 usr.update_action_buttons() //redraw buttons that are no longer considered "moved" return TRUE if(modifiers["ctrl"]) locked = !locked to_chat(usr, "Action button \"[name]\" [locked ? "" : "un"]locked.") + if(id && usr.client) //try to (un)remember position + usr.client.prefs.action_buttons_screen_locs["[name]_[id]"] = locked ? moved : null return TRUE if(usr.next_click > world.time) return @@ -38,21 +45,30 @@ /obj/screen/movable/action_button/hide_toggle/Click(location,control,params) var/list/modifiers = params2list(params) if(modifiers["shift"]) + if(locked) + to_chat(usr, "Action button \"[name]\" is locked, unlock it first.") + return TRUE moved = FALSE usr.update_action_buttons(TRUE) return TRUE if(modifiers["ctrl"]) locked = !locked to_chat(usr, "Action button \"[name]\" [locked ? "" : "un"]locked.") + if(id && usr.client) //try to (un)remember position + usr.client.prefs.action_buttons_screen_locs["[name]_[id]"] = locked ? moved : null return TRUE if(modifiers["alt"]) for(var/V in usr.actions) var/datum/action/A = V var/obj/screen/movable/action_button/B = A.button B.moved = FALSE + if(B.id && usr.client) + usr.client.prefs.action_buttons_screen_locs["[B.name]_[B.id]"] = null B.locked = usr.client.prefs.buttons_locked locked = usr.client.prefs.buttons_locked moved = FALSE + if(id && usr.client) + usr.client.prefs.action_buttons_screen_locs["[name]_[id]"] = null usr.update_action_buttons(TRUE) to_chat(usr, "Action button positions have been reset.") return TRUE diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index da2fae9882..2ad2eb76f5 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -302,32 +302,41 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." /obj/screen/alert/bloodsense/process() var/atom/blood_target - if(GLOB.blood_target) - if(!get_turf(GLOB.blood_target)) - GLOB.blood_target = null + + var/datum/antagonist/cult/antag = mob_viewer.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + if(!antag) + return + var/datum/objective/sacrifice/sac_objective = locate() in antag.cult_team.objectives + + if(antag.cult_team.blood_target) + if(!get_turf(antag.cult_team.blood_target)) + antag.cult_team.blood_target = null else - blood_target = GLOB.blood_target + blood_target = antag.cult_team.blood_target if(Cviewer && Cviewer.seeking && Cviewer.master) blood_target = Cviewer.master desc = "Your blood sense is leading you to [Cviewer.master]" if(!blood_target) - if(!GLOB.sac_complete) + if(sac_objective && !sac_objective.check_completion()) if(icon_state == "runed_sense0") return animate(src, transform = null, time = 1, loop = 0) angle = 0 cut_overlays() icon_state = "runed_sense0" - desc = "Nar-Sie demands that [GLOB.sac_mind] be sacrificed before the summoning ritual can begin." - add_overlay(GLOB.sac_image) + desc = "Nar-Sie demands that [sac_objective.target] be sacrificed before the summoning ritual can begin." + add_overlay(sac_objective.sac_image) else + var/datum/objective/eldergod/summon_objective = locate() in antag.cult_team.objectives + if(!summon_objective) + return if(icon_state == "runed_sense1") return animate(src, transform = null, time = 1, loop = 0) angle = 0 cut_overlays() icon_state = "runed_sense1" - desc = "The sacrifice is complete, summon Nar-Sie! The summoning can only take place in [english_list(GLOB.summon_spots)]!" + desc = "The sacrifice is complete, summon Nar-Sie! The summoning can only take place in [english_list(summon_objective.summon_spots)]!" add_overlay(narnar) return var/turf/P = get_turf(blood_target) @@ -388,23 +397,17 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." desc = "CHETR
NYY
HAGEHUGF-NAQ-UBABE
RATVAR.
" else var/servants = 0 - var/validservants = 0 - var/list/textlist + var/list/textlist = list() for(var/mob/living/L in GLOB.alive_mob_list) if(is_servant_of_ratvar(L)) servants++ - if(ishuman(L) || issilicon(L)) - validservants++ - if(servants > 1) - if(validservants > 1) - textlist = list("[servants] Servants, [validservants] of which count towards scripture.
") - else - textlist = list("[servants] Servants, [validservants ? "[validservants] of which counts":"none of which count"] towards scripture.
") - else - textlist = list("[servants] Servant, who [validservants ? "counts":"does not count"] towards scripture.
") - for(var/i in SSticker.scripture_states) - if(i != SCRIPTURE_DRIVER) //ignore the always-unlocked stuff - textlist += "[i] Scripture: [SSticker.scripture_states[i] ? "UNLOCKED":"LOCKED"]
" + var/datum/antagonist/clockcult/C = mob_viewer.mind.has_antag_datum(/datum/antagonist/clockcult,TRUE) + if(C && C.clock_team) + textlist += "[C.clock_team.eminence ? "There is an Eminence." : "There is no Eminence! Get one ASAP!"]
" + textlist += "There are currently [servants] servant[servants > 1 ? "s" : ""] of Ratvar.
" + for(var/i in SSticker.scripture_states) + if(i != SCRIPTURE_DRIVER) //ignore the always-unlocked stuff + textlist += "[i] Scripture: [SSticker.scripture_states[i] ? "UNLOCKED":"LOCKED"]
" var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar if(G) var/time_info = G.get_arrival_time(FALSE) diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm index 58f0fb18a2..2047225589 100644 --- a/code/_onclick/hud/fullscreen.dm +++ b/code/_onclick/hud/fullscreen.dm @@ -16,9 +16,9 @@ if (client && screen.should_show_to(src)) client.screen += screen if (screen.screen_loc == "CENTER-7,CENTER-7" && screen.view != client.view) - var/scale = (1 + 2 * client.view) / 15 + var/list/actualview = getviewsize(client.view) screen.view = client.view - screen.transform = matrix(scale, 0, 0, 0, scale, 0) + screen.transform = matrix(actualview[1]/FULLSCREEN_OVERLAY_RESOLUTION_X, 0, 0, 0, actualview[2]/FULLSCREEN_OVERLAY_RESOLUTION_Y, 0) return screen diff --git a/code/_onclick/hud/parallax.dm b/code/_onclick/hud/parallax.dm index a9971895a7..52319b7866 100755 --- a/code/_onclick/hud/parallax.dm +++ b/code/_onclick/hud/parallax.dm @@ -255,11 +255,13 @@ /obj/screen/parallax_layer/proc/update_o(view) if (!view) view = world.view - - var/count = Ceiling(view/(480/world.icon_size))+1 + + var/list/viewscales = getviewsize(view) + var/countx = CEILING((viewscales[1]/2)/(480/world.icon_size), 1)+1 + var/county = CEILING((viewscales[2]/2)/(480/world.icon_size), 1)+1 var/list/new_overlays = new - for(var/x in -count to count) - for(var/y in -count to count) + for(var/x in -countx to countx) + for(var/y in -county to county) if(x == 0 && y == 0) continue var/mutable_appearance/texture_overlay = mutable_appearance(icon, icon_state) diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index f1ec409520..769cdb2244 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -1,277 +1,277 @@ -/obj/screen/robot - icon = 'icons/mob/screen_cyborg.dmi' - -/obj/screen/robot/module - name = "cyborg module" - icon_state = "nomod" - -/obj/screen/robot/Click() - if(isobserver(usr)) - return 1 - -/obj/screen/robot/module/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - if(R.module.type != /obj/item/robot_module) - R.hud_used.toggle_show_robot_modules() - return 1 - R.pick_module() - -/obj/screen/robot/module1 - name = "module1" - icon_state = "inv1" - -/obj/screen/robot/module1/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.toggle_module(1) - -/obj/screen/robot/module2 - name = "module2" - icon_state = "inv2" - -/obj/screen/robot/module2/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.toggle_module(2) - -/obj/screen/robot/module3 - name = "module3" - icon_state = "inv3" - -/obj/screen/robot/module3/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.toggle_module(3) - -/obj/screen/robot/radio - name = "radio" - icon_state = "radio" - -/obj/screen/robot/radio/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.radio.interact(R) - -/obj/screen/robot/store - name = "store" - icon_state = "store" - -/obj/screen/robot/store/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.uneq_active() - -/obj/screen/robot/lamp - name = "headlamp" - icon_state = "lamp0" - -/obj/screen/robot/lamp/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.control_headlamp() - -/obj/screen/robot/thrusters - name = "ion thrusters" - icon_state = "ionpulse0" - -/obj/screen/robot/thrusters/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.toggle_ionpulse() - -/datum/hud/robot - ui_style_icon = 'icons/mob/screen_cyborg.dmi' - -/datum/hud/robot/New(mob/owner, ui_style = 'icons/mob/screen_cyborg.dmi') - ..() - var/mob/living/silicon/robot/mymobR = mymob - var/obj/screen/using - - using = new/obj/screen/language_menu - using.screen_loc = ui_borg_language_menu - static_inventory += using - -//Radio - using = new /obj/screen/robot/radio() - using.screen_loc = ui_borg_radio - static_inventory += using - -//Module select - using = new /obj/screen/robot/module1() - using.screen_loc = ui_inv1 - static_inventory += using - mymobR.inv1 = using - - using = new /obj/screen/robot/module2() - using.screen_loc = ui_inv2 - static_inventory += using - mymobR.inv2 = using - - using = new /obj/screen/robot/module3() - using.screen_loc = ui_inv3 - static_inventory += using - mymobR.inv3 = using - -//End of module select - -//Photography stuff - using = new /obj/screen/ai/image_take() - using.screen_loc = ui_borg_camera - static_inventory += using - - using = new /obj/screen/ai/image_view() - using.screen_loc = ui_borg_album - static_inventory += using - -//Sec/Med HUDs - using = new /obj/screen/ai/sensors() - using.screen_loc = ui_borg_sensor - static_inventory += using - -//Headlamp control - using = new /obj/screen/robot/lamp() - using.screen_loc = ui_borg_lamp - static_inventory += using - mymobR.lamp_button = using - -//Thrusters - using = new /obj/screen/robot/thrusters() - using.screen_loc = ui_borg_thrusters - static_inventory += using - mymobR.thruster_button = using - -//Intent - action_intent = new /obj/screen/act_intent/robot() - action_intent.icon_state = mymob.a_intent - static_inventory += action_intent - -//Health - healths = new /obj/screen/healths/robot() - infodisplay += healths - -//Installed Module - mymobR.hands = new /obj/screen/robot/module() - mymobR.hands.screen_loc = ui_borg_module - static_inventory += mymobR.hands - -//Store - module_store_icon = new /obj/screen/robot/store() - module_store_icon.screen_loc = ui_borg_store - - pull_icon = new /obj/screen/pull() - pull_icon.icon = 'icons/mob/screen_cyborg.dmi' - pull_icon.update_icon(mymob) - pull_icon.screen_loc = ui_borg_pull - hotkeybuttons += pull_icon - - - zone_select = new /obj/screen/zone_sel/robot() - zone_select.update_icon(mymob) - static_inventory += zone_select - - -/datum/hud/proc/toggle_show_robot_modules() - if(!iscyborg(mymob)) - return - - var/mob/living/silicon/robot/R = mymob - - R.shown_robot_modules = !R.shown_robot_modules - update_robot_modules_display() - -/datum/hud/proc/update_robot_modules_display(mob/viewer) - if(!iscyborg(mymob)) - return - - var/mob/living/silicon/robot/R = mymob - - var/mob/screenmob = viewer || R - - if(!R.module) - return - - if(!R.client) - return - - if(R.shown_robot_modules && screenmob.hud_used.hud_shown) - //Modules display is shown - screenmob.client.screen += module_store_icon //"store" icon - - if(!R.module.modules) - to_chat(usr, "Selected module has no modules to select") - return - - if(!R.robot_modules_background) - return - - var/display_rows = Ceiling(length(R.module.get_inactive_modules()) / 8) - R.robot_modules_background.screen_loc = "CENTER-4:16,SOUTH+1:7 to CENTER+3:16,SOUTH+[display_rows]:7" - screenmob.client.screen += R.robot_modules_background - - var/x = -4 //Start at CENTER-4,SOUTH+1 - var/y = 1 - - for(var/atom/movable/A in R.module.get_inactive_modules()) - //Module is not currently active - screenmob.client.screen += A - if(x < 0) - A.screen_loc = "CENTER[x]:16,SOUTH+[y]:7" - else - A.screen_loc = "CENTER+[x]:16,SOUTH+[y]:7" - A.layer = ABOVE_HUD_LAYER - A.plane = ABOVE_HUD_PLANE - - x++ - if(x == 4) - x = -4 - y++ - - else - //Modules display is hidden - screenmob.client.screen -= module_store_icon //"store" icon - - for(var/atom/A in R.module.get_inactive_modules()) - //Module is not currently active - screenmob.client.screen -= A - R.shown_robot_modules = 0 - screenmob.client.screen -= R.robot_modules_background - -/mob/living/silicon/robot/create_mob_hud() - if(client && !hud_used) - hud_used = new /datum/hud/robot(src) - - -/datum/hud/robot/persistent_inventory_update(mob/viewer) - if(!mymob) - return - var/mob/living/silicon/robot/R = mymob - - var/mob/screenmob = viewer || R - - if(screenmob.hud_used) - if(screenmob.hud_used.hud_shown) - for(var/i in 1 to R.held_items.len) - var/obj/item/I = R.held_items[i] - if(I) - switch(i) - if(1) - I.screen_loc = ui_inv1 - if(2) - I.screen_loc = ui_inv2 - if(3) - I.screen_loc = ui_inv3 - else - return - screenmob.client.screen += I - else - for(var/obj/item/I in R.held_items) - screenmob.client.screen -= I +/obj/screen/robot + icon = 'icons/mob/screen_cyborg.dmi' + +/obj/screen/robot/module + name = "cyborg module" + icon_state = "nomod" + +/obj/screen/robot/Click() + if(isobserver(usr)) + return 1 + +/obj/screen/robot/module/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + if(R.module.type != /obj/item/robot_module) + R.hud_used.toggle_show_robot_modules() + return 1 + R.pick_module() + +/obj/screen/robot/module1 + name = "module1" + icon_state = "inv1" + +/obj/screen/robot/module1/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.toggle_module(1) + +/obj/screen/robot/module2 + name = "module2" + icon_state = "inv2" + +/obj/screen/robot/module2/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.toggle_module(2) + +/obj/screen/robot/module3 + name = "module3" + icon_state = "inv3" + +/obj/screen/robot/module3/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.toggle_module(3) + +/obj/screen/robot/radio + name = "radio" + icon_state = "radio" + +/obj/screen/robot/radio/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.radio.interact(R) + +/obj/screen/robot/store + name = "store" + icon_state = "store" + +/obj/screen/robot/store/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.uneq_active() + +/obj/screen/robot/lamp + name = "headlamp" + icon_state = "lamp0" + +/obj/screen/robot/lamp/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.control_headlamp() + +/obj/screen/robot/thrusters + name = "ion thrusters" + icon_state = "ionpulse0" + +/obj/screen/robot/thrusters/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.toggle_ionpulse() + +/datum/hud/robot + ui_style_icon = 'icons/mob/screen_cyborg.dmi' + +/datum/hud/robot/New(mob/owner, ui_style = 'icons/mob/screen_cyborg.dmi') + ..() + var/mob/living/silicon/robot/mymobR = mymob + var/obj/screen/using + + using = new/obj/screen/language_menu + using.screen_loc = ui_borg_language_menu + static_inventory += using + +//Radio + using = new /obj/screen/robot/radio() + using.screen_loc = ui_borg_radio + static_inventory += using + +//Module select + using = new /obj/screen/robot/module1() + using.screen_loc = ui_inv1 + static_inventory += using + mymobR.inv1 = using + + using = new /obj/screen/robot/module2() + using.screen_loc = ui_inv2 + static_inventory += using + mymobR.inv2 = using + + using = new /obj/screen/robot/module3() + using.screen_loc = ui_inv3 + static_inventory += using + mymobR.inv3 = using + +//End of module select + +//Photography stuff + using = new /obj/screen/ai/image_take() + using.screen_loc = ui_borg_camera + static_inventory += using + + using = new /obj/screen/ai/image_view() + using.screen_loc = ui_borg_album + static_inventory += using + +//Sec/Med HUDs + using = new /obj/screen/ai/sensors() + using.screen_loc = ui_borg_sensor + static_inventory += using + +//Headlamp control + using = new /obj/screen/robot/lamp() + using.screen_loc = ui_borg_lamp + static_inventory += using + mymobR.lamp_button = using + +//Thrusters + using = new /obj/screen/robot/thrusters() + using.screen_loc = ui_borg_thrusters + static_inventory += using + mymobR.thruster_button = using + +//Intent + action_intent = new /obj/screen/act_intent/robot() + action_intent.icon_state = mymob.a_intent + static_inventory += action_intent + +//Health + healths = new /obj/screen/healths/robot() + infodisplay += healths + +//Installed Module + mymobR.hands = new /obj/screen/robot/module() + mymobR.hands.screen_loc = ui_borg_module + static_inventory += mymobR.hands + +//Store + module_store_icon = new /obj/screen/robot/store() + module_store_icon.screen_loc = ui_borg_store + + pull_icon = new /obj/screen/pull() + pull_icon.icon = 'icons/mob/screen_cyborg.dmi' + pull_icon.update_icon(mymob) + pull_icon.screen_loc = ui_borg_pull + hotkeybuttons += pull_icon + + + zone_select = new /obj/screen/zone_sel/robot() + zone_select.update_icon(mymob) + static_inventory += zone_select + + +/datum/hud/proc/toggle_show_robot_modules() + if(!iscyborg(mymob)) + return + + var/mob/living/silicon/robot/R = mymob + + R.shown_robot_modules = !R.shown_robot_modules + update_robot_modules_display() + +/datum/hud/proc/update_robot_modules_display(mob/viewer) + if(!iscyborg(mymob)) + return + + var/mob/living/silicon/robot/R = mymob + + var/mob/screenmob = viewer || R + + if(!R.module) + return + + if(!R.client) + return + + if(R.shown_robot_modules && screenmob.hud_used.hud_shown) + //Modules display is shown + screenmob.client.screen += module_store_icon //"store" icon + + if(!R.module.modules) + to_chat(usr, "Selected module has no modules to select") + return + + if(!R.robot_modules_background) + return + + var/display_rows = CEILING(length(R.module.get_inactive_modules()) / 8, 1) + R.robot_modules_background.screen_loc = "CENTER-4:16,SOUTH+1:7 to CENTER+3:16,SOUTH+[display_rows]:7" + screenmob.client.screen += R.robot_modules_background + + var/x = -4 //Start at CENTER-4,SOUTH+1 + var/y = 1 + + for(var/atom/movable/A in R.module.get_inactive_modules()) + //Module is not currently active + screenmob.client.screen += A + if(x < 0) + A.screen_loc = "CENTER[x]:16,SOUTH+[y]:7" + else + A.screen_loc = "CENTER+[x]:16,SOUTH+[y]:7" + A.layer = ABOVE_HUD_LAYER + A.plane = ABOVE_HUD_PLANE + + x++ + if(x == 4) + x = -4 + y++ + + else + //Modules display is hidden + screenmob.client.screen -= module_store_icon //"store" icon + + for(var/atom/A in R.module.get_inactive_modules()) + //Module is not currently active + screenmob.client.screen -= A + R.shown_robot_modules = 0 + screenmob.client.screen -= R.robot_modules_background + +/mob/living/silicon/robot/create_mob_hud() + if(client && !hud_used) + hud_used = new /datum/hud/robot(src) + + +/datum/hud/robot/persistent_inventory_update(mob/viewer) + if(!mymob) + return + var/mob/living/silicon/robot/R = mymob + + var/mob/screenmob = viewer || R + + if(screenmob.hud_used) + if(screenmob.hud_used.hud_shown) + for(var/i in 1 to R.held_items.len) + var/obj/item/I = R.held_items[i] + if(I) + switch(i) + if(1) + I.screen_loc = ui_inv1 + if(2) + I.screen_loc = ui_inv2 + if(3) + I.screen_loc = ui_inv3 + else + return + screenmob.client.screen += I + else + for(var/obj/item/I in R.held_items) + screenmob.client.screen -= I diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index acdccba3df..2dddce8542 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -34,7 +34,9 @@ // No comment /atom/proc/attackby(obj/item/W, mob/user, params) - return SendSignal(COMSIG_PARENT_ATTACKBY, W, user, params) + if(SendSignal(COMSIG_PARENT_ATTACKBY, W, user, params) & COMPONENT_NO_AFTERATTACK) + return TRUE + return FALSE /obj/attackby(obj/item/I, mob/living/user, params) return ..() || (can_be_hit && I.attack_obj(src, user)) @@ -56,6 +58,8 @@ SendSignal(COMSIG_ITEM_ATTACK, M, user) if(flags_1 & NOBLUDGEON_1) return + if(user.disabilities & PACIFISM) + return if(!force) playsound(loc, 'sound/weapons/tap.ogg', get_clamped_volume(), 1, -1) else if(hitsound) @@ -117,9 +121,9 @@ /obj/item/proc/get_clamped_volume() if(w_class) if(force) - return Clamp((force + w_class) * 4, 30, 100)// Add the item's force to its weight class and multiply by 4, then clamp the value between 30 and 100 + return CLAMP((force + w_class) * 4, 30, 100)// Add the item's force to its weight class and multiply by 4, then clamp the value between 30 and 100 else - return Clamp(w_class * 6, 10, 100) // Multiply the item's weight class by 6, then clamp the value between 10 and 100 + return CLAMP(w_class * 6, 10, 100) // Multiply the item's weight class by 6, then clamp the value between 10 and 100 /mob/living/proc/send_item_attack_message(obj/item/I, mob/living/user, hit_area) var/message_verb = "attacked" @@ -133,6 +137,6 @@ var/attack_message = "[src] has been [message_verb][message_hit_area] with [I]." if(user in viewers(src, null)) attack_message = "[user] has [message_verb] [src][message_hit_area] with [I]!" - visible_message("[attack_message]", \ + visible_message("[attack_message]",\ "[attack_message]", null, COMBAT_MESSAGE_RANGE) - return 1 \ No newline at end of file + return 1 diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index 5ca74b8eee..f124e2779b 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -14,7 +14,7 @@ // Otherwise jump else if(A.loc) - loc = get_turf(A) + forceMove(get_turf(A)) update_parallax_contents() /mob/dead/observer/ClickOn(var/atom/A, var/params) diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index c340943a36..d52a7f6fdc 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -25,7 +25,9 @@ if(override) return + SendSignal(COMSIG_HUMAN_MELEE_UNARMED_ATTACK, A) A.attack_hand(src) + SendSignal(COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY, src) /atom/proc/attack_hand(mob/user) return @@ -61,6 +63,7 @@ /atom/proc/attack_animal(mob/user) return + /mob/living/RestrainedClickOn(atom/A) return diff --git a/code/citadel/cit_arousal.dm b/code/citadel/cit_arousal.dm index 0c03ffb399..077824fe9e 100644 --- a/code/citadel/cit_arousal.dm +++ b/code/citadel/cit_arousal.dm @@ -62,14 +62,14 @@ /mob/living/proc/adjustArousalLoss(amount, updating_arousal=1) if(status_flags & GODMODE || !canbearoused) return 0 - arousalloss = Clamp(arousalloss + amount, min_arousal, max_arousal) + arousalloss = CLAMP(arousalloss + amount, min_arousal, max_arousal) if(updating_arousal) updatearousal() /mob/living/proc/setArousalLoss(amount, updating_arousal=1) if(status_flags & GODMODE || !canbearoused) return 0 - arousalloss = Clamp(amount, min_arousal, max_arousal) + arousalloss = CLAMP(amount, min_arousal, max_arousal) if(updating_arousal) updatearousal() diff --git a/code/citadel/cit_genemods.dm b/code/citadel/cit_genemods.dm index 2d6b027db6..5efebf4860 100644 --- a/code/citadel/cit_genemods.dm +++ b/code/citadel/cit_genemods.dm @@ -8,7 +8,6 @@ throw_speed = 3 throw_range = 5 w_class = WEIGHT_CLASS_TINY - origin_tech = "biotech=3" var/applied_region = "chest" var/list/add_mutations = list() var/list/remove_mutations = list() diff --git a/code/citadel/cit_guns.dm b/code/citadel/cit_guns.dm index 1068d490f1..1235fc27af 100644 --- a/code/citadel/cit_guns.dm +++ b/code/citadel/cit_guns.dm @@ -4,7 +4,6 @@ icon = 'icons/obj/guns/cit_guns.dmi' icon_state = "lasernew" item_state = "laser" - origin_tech = "combat=4;magnets=4" force = 10 throwforce = 10 ammo_type = list(/obj/item/ammo_casing/energy/lasergun) @@ -22,7 +21,6 @@ name = "Laser Carbine" desc = "Beefed up version of a standard laser gun." id = "lasercarbine" - req_tech = list("combat" = 5, "magnets" = 5, "powerstorage" = 4) build_type = PROTOLATHE materials = list(MAT_GOLD = 2500, MAT_METAL = 5000, MAT_GLASS = 5000) build_path = /obj/item/gun/energy/laser/carbine/nopin @@ -40,7 +38,6 @@ mag_type = /obj/item/ammo_box/magazine/sniper_rounds fire_delay = 50 burst_size = 1 - origin_tech = "combat=7" can_suppress = 0 w_class = WEIGHT_CLASS_NORMAL actions_types = list() @@ -60,7 +57,6 @@ name = "Syndicate Anti Tank Pistol" desc = "A massively impractical and silly monstrosity of a pistol that fires .50 calliber rounds. The recoil is likely to dislocate a variety of joints without proper bracing." pin = /obj/item/device/firing_pin/implant/pindicate - origin_tech = "combat=7;syndicate=6" /////////////spinfusor stuff//////////////// @@ -115,7 +111,6 @@ select = 0 actions_types = list() casing_ejector = 0 - origin_tech = "combat=6;magnets=6" /obj/item/gun/ballistic/automatic/spinfusor/attackby(obj/item/A, mob/user, params) var/num_loaded = magazine.attackby(A, user, params, 1) @@ -163,7 +158,6 @@ icon_state = "x9" item_state = "arg" slot_flags = 0 - origin_tech = "combat=7;engineering=7" mag_type = /obj/item/ammo_box/magazine/m556 //Uses the m90gl's magazine, just like the NT-ARG fire_sound = 'sound/weapons/gunshot_smg.ogg' can_suppress = 0 @@ -194,7 +188,6 @@ spread = 90 //MAXIMUM XCOM MEMES (actually that'd be 180 spread) w_class = WEIGHT_CLASS_BULKY weapon_weight = WEAPON_HEAVY - origin_tech = "combat=1;magnets=1" /datum/design/foam_x9 name = "Foam Force X9 Rifle" @@ -254,7 +247,6 @@ name = "magpistol magazine (non-lethal disabler)" icon = 'icons/obj/guns/cit_guns.dmi' icon_state = "nlmagmag" - origin_tech = "magnets=5" ammo_type = /obj/item/ammo_casing/caseless/anlmags caliber = "mags" max_ammo = 15 @@ -264,7 +256,6 @@ name = "magpistol magazine (lethal)" icon = 'icons/obj/guns/cit_guns.dmi' icon_state = "smallmagmag" - origin_tech = "combat=5" ammo_type = /obj/item/ammo_casing/caseless/amags //////the gun itself////// @@ -280,7 +271,6 @@ can_suppress = 0 casing_ejector = 0 fire_delay = 2 - origin_tech = "combat=4;magnets=4" /obj/item/gun/ballistic/automatic/pistol/mag/update_icon() ..() @@ -301,7 +291,6 @@ name = "Magpistol" desc = "A weapon which fires ferromagnetic slugs." id = "magpisol" - req_tech = list("combat" = 5, "magnets" = 6, "powerstorage" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 7500, MAT_GLASS = 1000, MAT_URANIUM = 1000, MAT_TITANIUM = 5000, MAT_SILVER = 2000) build_path = /obj/item/gun/ballistic/automatic/pistol/mag/nopin @@ -311,7 +300,6 @@ name = "Magpistol Magazine" desc = "A 7 round magazine for the Magpistol." id = "mag_magpistol" - req_tech = list("combat" = 5, "magnets" = 6, "materials" = 5, "syndicate" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 4000, MAT_SILVER = 500) build_path = /obj/item/ammo_box/magazine/mmag/small/lethal @@ -321,7 +309,6 @@ name = "Magpistol Magazine (Non-Lethal)" desc = "A 7 round non-lethal magazine for the Magpistol." id = "mag_magpistol_nl" - req_tech = list("combat" = 5, "magnets" = 6, "materials" = 5) materials = list(MAT_METAL = 3000, MAT_SILVER = 250, MAT_TITANIUM = 250) build_path = /obj/item/ammo_box/magazine/mmag/small @@ -354,7 +341,6 @@ fire_sound = 'sound/weapons/magpistol.ogg' slot_flags = SLOT_BELT w_class = WEIGHT_CLASS_SMALL - origin_tech = "combat=1;magnets=1" /obj/item/ammo_box/foambox/mag name = "ammo box (Magnetic Foam Darts)" @@ -427,7 +413,6 @@ name = "magrifle magazine (non-lethal disabler)" icon = 'icons/obj/guns/cit_guns.dmi' icon_state = "mediummagmag" - origin_tech = "magnets=6" ammo_type = /obj/item/ammo_casing/caseless/anlmagm caliber = "magm" max_ammo = 27 @@ -437,7 +422,6 @@ name = "magrifle magazine (lethal)" icon = 'icons/obj/guns/cit_guns.dmi' icon_state = "mediummagmag" - origin_tech = "combat=6" ammo_type = /obj/item/ammo_casing/caseless/amagm max_ammo = 21 @@ -450,7 +434,6 @@ icon_state = "magrifle" item_state = "arg" slot_flags = 0 - origin_tech = "combat=6;engineering=6;magnets=6" mag_type = /obj/item/ammo_box/magazine/mmag fire_sound = 'sound/weapons/magrifle.ogg' can_suppress = 0 @@ -470,7 +453,6 @@ name = "Magrifle" desc = "An upscaled Magpistol in rifle form." id = "magrifle" - req_tech = list("combat" = 7, "magnets" = 7, "powerstorage" = 7) build_type = PROTOLATHE materials = list(MAT_METAL = 10000, MAT_GLASS = 2000, MAT_URANIUM = 2000, MAT_TITANIUM = 10000, MAT_SILVER = 4000, MAT_GOLD = 2000) build_path = /obj/item/gun/ballistic/automatic/magrifle/nopin @@ -480,7 +462,6 @@ name = "Magrifle Magazine (Lethal)" desc = "A 15 round magazine for the Magrifle." id = "mag_magrifle" - req_tech = list("combat" = 7, "magnets" = 7, "materials" = 5, "syndicate" = 4) build_type = PROTOLATHE materials = list(MAT_METAL = 8000, MAT_SILVER = 1000) build_path = /obj/item/ammo_box/magazine/mmag/lethal @@ -490,7 +471,6 @@ name = "Magrifle Magazine (Non-Lethal)" desc = "A 15 round non-lethal magazine for the Magrifle." id = "mag_magrifle_nl" - req_tech = list("combat" = 7, "magnets" = 7, "materials" = 5) materials = list(MAT_METAL = 6000, MAT_SILVER = 500, MAT_TITANIUM = 500) build_path = /obj/item/ammo_box/magazine/mmag @@ -512,7 +492,6 @@ needs_permit = FALSE mag_type = /obj/item/ammo_box/magazine/toy/foamag casing_ejector = FALSE - origin_tech = "combat=1;engineering=1;magnets=1" spread = 60 w_class = WEIGHT_CLASS_BULKY weapon_weight = WEAPON_HEAVY @@ -598,7 +577,6 @@ icon_state = "hyperburst" item_state = "arg" slot_flags = 0 - origin_tech = "combat=6;engineering=6;magnets=6;syndicate=6" mag_type = /obj/item/ammo_box/magazine/mhyper fire_sound = 'sound/weapons/magburst.ogg' can_suppress = 0 @@ -646,7 +624,6 @@ charge_delay = 2 recoil = 2 cell_type = /obj/item/stock_parts/cell/toymagburst - origin_tech = "combat=1;magnets=1" /obj/item/stock_parts/cell/toymagburst name = "toy mag burst rifle power supply" @@ -669,7 +646,6 @@ icon = 'icons/obj/guns/cit_guns.dmi' icon_state = "stealthpistol" w_class = WEIGHT_CLASS_SMALL - origin_tech = "combat=3;materials=3;syndicate=4" mag_type = /obj/item/ammo_box/magazine/m10mm can_suppress = 0 fire_sound = 'sound/weapons/gunshot_silenced.ogg' @@ -703,7 +679,6 @@ fire_delay = 0 spread = 60 actions_types = list() - origin_tech = "combat=1;magnets=1" /obj/item/gun/ballistic/automatic/toy/pistol/stealth/update_icon() ..() @@ -805,7 +780,6 @@ obj/item/projectile/bullet/c10mm/soporific name = "flechette magazine (armor piercing)" icon = 'icons/obj/guns/cit_guns.dmi' icon_state = "flechettemag" - origin_tech = "combat=5;syndicate=1" ammo_type = /obj/item/ammo_casing/caseless/flechetteap caliber = "flechette" max_ammo = 40 @@ -826,7 +800,6 @@ obj/item/projectile/bullet/c10mm/soporific w_class = WEIGHT_CLASS_NORMAL slot_flags = 0 /obj/item/device/firing_pin/implant/pindicate - origin_tech = "combat=6;materials=2;syndicate=5" mag_type = /obj/item/ammo_box/magazine/flechette/ fire_sound = 'sound/weapons/gunshot_smg.ogg' can_suppress = 0 @@ -930,7 +903,6 @@ obj/item/projectile/bullet/c10mm/soporific desc = "A toy laser with a classic, retro feel and look. Compatible with existing laser tag systems." ammo_type = list(/obj/item/ammo_casing/energy/laser/raytag) selfcharge = TRUE - origin_tech = "combat=1;magnets=1" /datum/design/toyray name = "RayTag Gun" @@ -1186,7 +1158,6 @@ obj/item/projectile/bullet/c10mm/soporific mag_type = /obj/item/ammo_box/magazine/toy/pistol can_suppress = FALSE actions_types = list(/datum/action/item_action/pick_color) - origin_tech = "combat=1;magnets=1" /datum/design/foam_p37 name = "Foam Force Mk.37F" @@ -1209,7 +1180,6 @@ obj/item/gun/energy/e_gun/cx lefthand_file = 'icons/mob/citadel/guns_lefthand.dmi' righthand_file = 'icons/mob/citadel/guns_righthand.dmi' ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/laser) - origin_tech = "combat=4;magnets=3" flight_x_offset = 15 flight_y_offset = 10 actions_types = list(/datum/action/item_action/pick_color) diff --git a/code/citadel/cit_weapons.dm b/code/citadel/cit_weapons.dm deleted file mode 100644 index c709fe90e9..0000000000 --- a/code/citadel/cit_weapons.dm +++ /dev/null @@ -1,221 +0,0 @@ -/obj/item/toy/sword/cx - name = "\improper DX Non-Euplastic LightSword" - desc = "A deluxe toy replica of an energy sword. Realistic visuals and sounds! Ages 8 and up." - icon = 'icons/obj/cit_weapons.dmi' - icon_state = "cxsword_hilt" - item_state = "cxsword" - lefthand_file = 'icons/mob/citadel/melee_lefthand.dmi' - righthand_file = 'icons/mob/citadel/melee_righthand.dmi' - active = FALSE - w_class = WEIGHT_CLASS_SMALL - attack_verb = list("poked", "jabbed", "hit") - light_color = "#37FFF7" - var/light_brightness = 3 - actions_types = list(/datum/action/item_action/pick_color) - -/obj/item/toy/sword/cx/attack_self(mob/user) - active = !( active ) - - if (active) - to_chat(user, "You activate the holographic blade with a press of a button.") - playsound(user, 'sound/weapons/nebon.ogg', 50, 1) - w_class = WEIGHT_CLASS_BULKY - attack_verb = list("slashed", "stabbed", "ravaged") - set_light(light_brightness) - update_icon() - - else - to_chat(user, "You deactivate the holographic blade with a press of a button.") - playsound(user, 'sound/weapons/neboff.ogg', 50, 1) - w_class = WEIGHT_CLASS_SMALL - attack_verb = list("poked", "jabbed", "hit") - set_light(0) - update_icon() - - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() - - add_fingerprint(user) - -/obj/item/toy/sword/cx/update_icon() - var/mutable_appearance/blade_overlay = mutable_appearance('icons/obj/cit_weapons.dmi', "cxsword_blade") - var/mutable_appearance/gem_overlay = mutable_appearance('icons/obj/cit_weapons.dmi', "cxsword_gem") - - if(light_color) - blade_overlay.color = light_color - gem_overlay.color = light_color - - cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other - - add_overlay(gem_overlay) - - if(active) - add_overlay(blade_overlay) - - if(ismob(loc)) - var/mob/M = loc - M.update_inv_hands() - -/obj/item/toy/sword/cx/ui_action_click(mob/user, var/datum/action/A) - if(istype(A, /datum/action/item_action/pick_color)) - if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes") - var/energy_color_input = input(usr,"Choose Energy Color") as color|null - if(energy_color_input) - light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1) - update_icon() - update_light() - A.UpdateButtonIcon() - - else - ..() - -/obj/item/toy/sword/cx/worn_overlays(isinhands, icon_file) - . = ..() - if(active) - if(isinhands) - var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "cxsword_blade") - blade_inhand.color = light_color - . += blade_inhand - -/obj/item/toy/sword/cx/attackby(obj/item/W, mob/living/user, params) - return //NO MORE MAKING DUAL ESWORDS - -/*///autolathe memes/// I really need to stop doing this and find a proper way of adding in my toys - -/datum/design/toyneb - name = "Non-Euplastic Blade" - id = "toyneb" - build_type = AUTOLATHE - materials = list(MAT_METAL = 10000, MAT_GLASS = 1000) - build_path = /obj/item/toy/sword/cx - category = list("hacked", "Misc") -*/ // There, I stopped doing it - -/datum/crafting_recipe/toyneb - name = "Non-Euplastic Blade" - reqs = list(/obj/item/light/bulb = 1, /obj/item/stack/cable_coil = 1, /obj/item/toy/sword = 1) - result = /obj/item/toy/sword/cx - category = CAT_MISC - -/*///////////////////////////////////////////////////////////////////////// -///////////// The TRUE Energy Sword /////////////////////////// -*////////////////////////////////////////////////////////////////////////// - -/obj/item/melee/transforming/energy/sword/cx - name = "non-eutactic blade" - desc = "The CX Armories Type-69 Non-Eutactic Blade utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable." - icon_state = "cxsword_hilt" - icon = 'icons/obj/cit_weapons.dmi' - item_state = "cxsword" - lefthand_file = 'icons/mob/citadel/melee_lefthand.dmi' - righthand_file = 'icons/mob/citadel/melee_righthand.dmi' - force = 3 - throwforce = 5 - hitsound = "swing_hit" //it starts deactivated - hitsound_on = 'sound/weapons/nebhit.ogg' - attack_verb_off = list("tapped", "poked") - throw_speed = 3 - throw_range = 5 - sharpness = IS_SHARP - embed_chance = 40 - embedded_impact_pain_multiplier = 10 - armour_penetration = 0 - origin_tech = "combat=3;magnets=4" - block_chance = 60 - light_color = "#37FFF7" - actions_types = list(/datum/action/item_action/pick_color) - -/obj/item/melee/transforming/energy/sword/cx/transform_weapon(mob/living/user, supress_message_text) - active = !active //I'd use a ..() here but it'd inherit from the regular esword's proc instead, so SPAGHETTI CODE - if(active) //also I need to rip out the iconstate changing bits - force = force_on - throwforce = throwforce_on - hitsound = hitsound_on - throw_speed = 4 - if(attack_verb_on.len) - attack_verb = attack_verb_on - w_class = w_class_on - START_PROCESSING(SSobj, src) - set_light(brightness_on) - update_icon() - else - force = initial(force) - throwforce = initial(throwforce) - hitsound = initial(hitsound) - throw_speed = initial(throw_speed) - if(attack_verb_off.len) - attack_verb = attack_verb_off - w_class = initial(w_class) - STOP_PROCESSING(SSobj, src) - set_light(0) - update_icon() - transform_messages(user, supress_message_text) - add_fingerprint(user) - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() - return TRUE - -/obj/item/melee/transforming/energy/sword/cx/transform_messages(mob/living/user, supress_message_text) - playsound(user, active ? 'sound/weapons/nebon.ogg' : 'sound/weapons/neboff.ogg', 65, 1) - if(!supress_message_text) - to_chat(user, "[src] [active ? "is now active":"can now be concealed"].") - -/obj/item/melee/transforming/energy/sword/cx/update_icon() - var/mutable_appearance/blade_overlay = mutable_appearance('icons/obj/cit_weapons.dmi', "cxsword_blade") - var/mutable_appearance/gem_overlay = mutable_appearance('icons/obj/cit_weapons.dmi', "cxsword_gem") - - if(light_color) - blade_overlay.color = light_color - gem_overlay.color = light_color - - cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other - - add_overlay(gem_overlay) - - if(active) - add_overlay(blade_overlay) - - if(ismob(loc)) - var/mob/M = loc - M.update_inv_hands() - -/obj/item/melee/transforming/energy/sword/cx/ui_action_click(mob/user, var/datum/action/A) - if(istype(A, /datum/action/item_action/pick_color)) - if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes") - var/energy_color_input = input(usr,"Choose Energy Color") as color|null - if(energy_color_input) - light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1) - update_icon() - update_light() - A.UpdateButtonIcon() - - else - ..() - -/obj/item/melee/transforming/energy/sword/cx/worn_overlays(isinhands, icon_file) - . = ..() - if(active) - if(isinhands) - var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "cxsword_blade") - blade_inhand.color = light_color - . += blade_inhand - -/obj/item/melee/transforming/energy/sword/cx/traitor - name = "\improper Dragon's Tooth Sword" - desc = "The Dragon's Tooth sword is a blackmarket modification of the CX Armouries Type-69 NEB, \ - which utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable. \ - It appears to have a wooden grip and a shaved down guard." - icon_state = "cxsword_hilt_traitor" - armour_penetration = 35 - embed_chance = 75 - block_chance = 50 - origin_tech = "combat=3;magnets=4;syndicate=4" - hitsound_on = 'sound/weapons/blade1.ogg' - light_color = "#37F0FF" - -/obj/item/melee/transforming/energy/sword/cx/traitor/transform_messages(mob/living/user, supress_message_text) - playsound(user, active ? 'sound/weapons/saberon.ogg' : 'sound/weapons/saberoff.ogg', 35, 1) - if(!supress_message_text) - to_chat(user, "[src] [active ? "is now active":"can now be concealed"].") \ No newline at end of file diff --git a/code/citadel/crew_objectives/cit_crewobjectives_science.dm b/code/citadel/crew_objectives/cit_crewobjectives_science.dm index 1fcba91e46..fb260583fd 100644 --- a/code/citadel/crew_objectives/cit_crewobjectives_science.dm +++ b/code/citadel/crew_objectives/cit_crewobjectives_science.dm @@ -38,8 +38,8 @@ explanation_text = "Make sure the research required to produce a [initial(targetdesign.name)] is available on the R&D server by the end of the shift." /datum/objective/crew/research/check_completion() - for(var/obj/machinery/r_n_d/server/S in GLOB.machines) - if(S && S.files && S.files.known_designs) - if(targetdesign in S.files.known_designs) + for(var/obj/machinery/rnd/server/S in GLOB.machines) + if(S && S.stored_research) + if(S.stored_research.researched_designs[initial(targetdesign.id)]) return TRUE return FALSE diff --git a/code/citadel/custom_loadout/custom_items.dm b/code/citadel/custom_loadout/custom_items.dm index 44f672e653..7cda1d9e5a 100644 --- a/code/citadel/custom_loadout/custom_items.dm +++ b/code/citadel/custom_loadout/custom_items.dm @@ -16,8 +16,9 @@ /obj/item/clothing/neck/cloak/inferno name = "Kiara's Cloak" desc = "The design on this seems a little too familiar." - icon = 'icons/obj/clothing/cloaks.dmi' + icon = 'icons/obj/custom.dmi' icon_state = "infcloak" + icon_override = 'icons/mob/custom_w.dmi' item_state = "infcloak" w_class = WEIGHT_CLASS_SMALL body_parts_covered = CHEST|GROIN|LEGS|ARMS @@ -25,7 +26,9 @@ /obj/item/clothing/neck/petcollar/inferno name = "Kiara's Collar" desc = "A soft black collar that seems to stretch to fit whoever wears it." + icon = 'icons/obj/custom.dmi' icon_state = "infcollar" + icon_override = 'icons/mob/custom_w.dmi' item_state = "infcollar" item_color = null tagname = null @@ -43,7 +46,7 @@ /obj/item/lighter/gold name = "\improper Engraved Zippo" desc = "A shiny and relatively expensive zippo lighter. There's a small etched in verse on the bottom that reads, 'No Gods, No Masters, Only Man.'" - icon = 'icons/obj/cigarettes.dmi' + icon = 'icons/obj/custom.dmi' icon_state = "gold_zippo" item_state = "gold_zippo" w_class = WEIGHT_CLASS_TINY @@ -58,15 +61,19 @@ /obj/item/clothing/neck/scarf/zomb //Default white color, same functionality as beanies. name = "A special scarf" + icon = 'icons/obj/custom.dmi' icon_state = "zombscarf" desc = "A fashionable collar" + icon_override = 'icons/mob/custom_w.dmi' 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 = 'icons/obj/custom.dmi' icon_state = "labred" + icon_override = 'icons/mob/custom_w.dmi' item_state = "labred" @@ -86,8 +93,8 @@ /obj/item/clothing/neck/cloak/carrot name = "carrot cloak" desc = "A cloak in the shape and color of a carrot!" - icon = 'icons/obj/clothing/cloaks.dmi' - icon_override = 'icons/mob/citadel/suit.dmi' + icon = 'icons/obj/custom.dmi' + icon_override = 'icons/mob/custom_w.dmi' icon_state = "carrotcloak" item_state = "carrotcloak" w_class = WEIGHT_CLASS_SMALL @@ -96,7 +103,7 @@ /obj/item/toy/plush/tree name = "christmass tree plushie" desc = "A festive plush that squeeks when you squeeze it!" - icon = 'icons/obj/plushes.dmi' + icon = 'icons/obj/custom.dmi' icon_state = "pine_c" item_state = "pine_c" w_class = WEIGHT_CLASS_SMALL @@ -104,13 +111,24 @@ resistance_flags = FLAMMABLE squeak_override = list('sound/misc/server-ready.ogg'= 1) +/obj/item/clothing/neck/cloak/festive + name = "Celebratory Cloak of Morozko" + desc = " It probably will protect from snow, charcoal or elves." + icon = 'icons/obj/custom.dmi' + icon_state = "festive" + item_state = "festive" + icon_override = 'icons/mob/custom_w.dmi' + w_class = WEIGHT_CLASS_SMALL + body_parts_covered = CHEST|GROIN|LEGS|ARMS + /*Zigfie*/ /obj/item/clothing/mask/luchador/zigfie name = "Alboroto Rosa mask" - icon = 'icons/mob/mask.dmi' + icon = 'icons/obj/custom.dmi' icon_state = "lucharzigfie" + icon_override = 'icons/mob/custom_w.dmi' item_state = "lucharzigfie" @@ -149,7 +167,9 @@ /obj/item/clothing/suit/trenchcoat/green name = "Reece's Great Coat" desc = "You would swear this was in your nightmares after eating too many veggies." + icon = 'icons/obj/custom.dmi' icon_state = "hos-g" + icon_override = 'icons/mob/custom_w.dmi' item_state = "hos-g" body_parts_covered = CHEST|GROIN|ARMS|LEGS @@ -160,13 +180,14 @@ 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 /obj/item/clothing/mask/gas/stalker name = "S.T.A.L.K.E.R. mask" desc = "Smells like reactor four." + icon = 'icons/obj/custom.dmi' item_state = "stalker" + icon_override = 'icons/mob/custom_w.dmi' icon_state = "stalker" @@ -176,7 +197,8 @@ desc = "It's a collar..." icon = 'icons/obj/custom.dmi' icon_state = "petcollar-stripe" - item_color = "petcollar-stripe" + icon_override = 'icons/mob/custom_w.dmi' + item_state = "petcollar-stripe" tagname = null @@ -184,17 +206,30 @@ /obj/item/clothing/under/singery/custom name = "bluish performer's outfit" desc = "Just looking at this makes you want to sing." - icon_state = "ssing" - item_state = "ssing" - item_color = "ssing" + icon = 'icons/obj/custom.dmi' + icon_state = "singer" + icon_override = 'icons/mob/custom_w.dmi' + item_state = "singer" + item_color = "singer" fitted = NO_FEMALE_UNIFORM alternate_worn_layer = ABOVE_SHOES_LAYER can_adjust = 0 /obj/item/clothing/shoes/sneakers/pink + icon = 'icons/obj/custom.dmi' icon_state = "pink" + icon_override = 'icons/mob/custom_w.dmi' item_state = "pink" +/*Fractious*/ +/obj/item/clothing/suit/vermillion + name = "vermillion clothing" + desc = "Some clothing." + icon_state = "vermillion" + item_state = "vermillion" + body_parts_covered = CHEST|GROIN|LEGS|ARMS|HANDS + icon = 'icons/obj/custom.dmi' + icon_override = 'icons/mob/custom_w.dmi' diff --git a/code/controllers/configuration/config_entry.dm b/code/controllers/configuration/config_entry.dm index 92dcb9baf0..d2db743d91 100644 --- a/code/controllers/configuration/config_entry.dm +++ b/code/controllers/configuration/config_entry.dm @@ -9,7 +9,7 @@ var/value var/default //read-only, just set value directly - var/resident_file //the file which this belongs to, must be set + var/resident_file //the file which this was loaded from, if any var/modified = FALSE //set to TRUE if the default has been overridden by a config entry var/protection = NONE @@ -18,8 +18,6 @@ var/dupes_allowed = FALSE /datum/config_entry/New() - if(!resident_file) - CRASH("Config entry [type] has no resident_file set") if(type == abstract_type) CRASH("Abstract config entry [type] instatiated!") name = lowertext(type2top(type)) @@ -110,7 +108,7 @@ /datum/config_entry/number/ValidateAndSet(str_val) var/temp = text2num(trim(str_val)) if(!isnull(temp)) - value = Clamp(integer ? round(temp) : temp, min_val, max_val) + value = CLAMP(integer ? round(temp) : temp, min_val, max_val) if(value != temp && !var_edited) log_config("Changing [name] from [temp] to [value]!") return TRUE diff --git a/code/controllers/configuration/configuration.dm b/code/controllers/configuration/configuration.dm index 70be8cfa0c..e5e999f003 100644 --- a/code/controllers/configuration/configuration.dm +++ b/code/controllers/configuration/configuration.dm @@ -20,10 +20,13 @@ GLOBAL_PROTECT(config_dir) /datum/controller/configuration/New() config = src - var/list/config_files = InitEntries() + InitEntries() LoadModes() - for(var/I in config_files) - LoadEntries(I) + if(LoadEntries("config.txt") <= 1) + log_config("No $include directives found in config.txt! Loading legacy game_options/dbconfig/comms files...") + LoadEntries("game_options.txt") + LoadEntries("dbconfig.txt") + LoadEntries("comms.txt") loadmaplist(CONFIG_MAPS_FILE) /datum/controller/configuration/Destroy() @@ -42,8 +45,6 @@ GLOBAL_PROTECT(config_dir) var/list/_entries_by_type = list() entries_by_type = _entries_by_type - . = list() - 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) @@ -57,24 +58,30 @@ GLOBAL_PROTECT(config_dir) continue _entries[esname] = E _entries_by_type[I] = E - .[E.resident_file] = TRUE /datum/controller/configuration/proc/RemoveEntry(datum/config_entry/CE) entries -= CE.name entries_by_type -= CE.type -/datum/controller/configuration/proc/LoadEntries(filename) +/datum/controller/configuration/proc/LoadEntries(filename, list/stack = list()) + var/filename_to_test = world.system_type == MS_WINDOWS ? lowertext(filename) : filename + if(filename_to_test in stack) + log_config("Warning: Config recursion detected ([english_list(stack)]), breaking!") + return + stack = stack + filename_to_test + 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 - - if(copytext(L, 1, 2) == "#") + + var/firstchar = copytext(L, 1, 2) + if(firstchar == "#") continue - var/lockthis = copytext(L, 1, 2) == "@" + var/lockthis = firstchar == "@" if(lockthis) L = copytext(L, 2) @@ -90,15 +97,25 @@ GLOBAL_PROTECT(config_dir) if(!entry) continue + if(entry == "$include") + if(!value) + log_config("Warning: Invalid $include directive: [value]") + else + LoadEntries(value, stack) + ++. + continue + + if(entry == "$include") + if(!value) + log_config("Warning: Invalid $include directive: [value]") + else + LoadEntries(value, stack) + continue var/datum/config_entry/E = _entries[entry] if(!E) log_config("Unknown setting in configuration: '[entry]'") continue - - if(filename != E.resident_file) - log_config("Found [entry] in [filename] when it should have been in [E.resident_file]! Ignoring.") - continue if(lockthis) E.protection |= CONFIG_ENTRY_LOCKED @@ -107,10 +124,14 @@ GLOBAL_PROTECT(config_dir) 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.") + log_config("Duplicate setting for [entry] ([value], [E.resident_file]) detected! Using latest.") + + E.resident_file = filename if(validated) E.modified = TRUE + + ++. /datum/controller/configuration/can_vv_get(var_name) return (var_name != "entries_by_type" || !hiding_entries_by_type) && ..() @@ -168,7 +189,10 @@ GLOBAL_PROTECT(config_dir) mode_names[M.config_tag] = M.name probabilities[M.config_tag] = M.probability mode_reports[M.config_tag] = M.generate_report() - mode_false_report_weight[M.config_tag] = M.false_report_weight + if(M.probability) + mode_false_report_weight[M.config_tag] = M.false_report_weight + else + mode_false_report_weight[M.config_tag] = 1 if(M.votable) votable_modes += M.config_tag qdel(M) diff --git a/code/controllers/configuration/entries/comms.dm b/code/controllers/configuration/entries/comms.dm index bf099f6cb6..56cec985f1 100644 --- a/code/controllers/configuration/entries/comms.dm +++ b/code/controllers/configuration/entries/comms.dm @@ -1,22 +1,20 @@ -#define CURRENT_RESIDENT_FILE "comms.txt" - -CONFIG_DEF(string/comms_key) +/datum/config_entry/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) +/datum/config_entry/keyed_string_list/cross_server 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) +/datum/config_entry/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) +/datum/config_entry/string/medal_hub_address -CONFIG_DEF(string/medal_hub_password) - protection = CONFIG_ENTRY_HIDDEN \ No newline at end of file +/datum/config_entry/string/medal_hub_password + protection = CONFIG_ENTRY_HIDDEN diff --git a/code/controllers/configuration/entries/config.dm b/code/controllers/configuration/entries/config.dm deleted file mode 100644 index d7dc0ff84d..0000000000 --- a/code/controllers/configuration/entries/config.dm +++ /dev/null @@ -1,387 +0,0 @@ -#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/log_manifest) // log crew manifest to seperate file - -CONFIG_DEF(flag/allow_admin_ooccolor) // Allows admins with relevant permissions to have their own ooc colour - -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/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(flag/client_warn_popup) - -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) - -CONFIG_DEF(number/mc_tick_rate/base_mc_tick_rate) - integer = FALSE - value = 1 - -CONFIG_DEF(number/mc_tick_rate/high_pop_mc_tick_rate) - integer = FALSE - value = 1.1 - -CONFIG_DEF(number/mc_tick_rate/high_pop_mc_mode_amount) - value = 65 - -CONFIG_DEF(number/mc_tick_rate/disable_high_pop_mc_mode_amount) - value = 60 - -CONFIG_TWEAK(number/mc_tick_rate) - abstract_type = /datum/config_entry/number/mc_tick_rate - -CONFIG_TWEAK(number/mc_tick_rate/ValidateAndSet(str_val)) - . = ..() - if (.) - Master.UpdateTickRate() - -CONFIG_DEF(flag/resume_after_initializations) - -CONFIG_TWEAK(flag/ValidateAndSet(str_val)) - . = ..() - if(. && Master.current_runlevel) - world.sleep_offline = !value - -CONFIG_DEF(number/rounds_until_hard_restart) - value = -1 - min_val = 0 diff --git a/code/controllers/configuration/entries/dbconfig.dm b/code/controllers/configuration/entries/dbconfig.dm index c46880686a..1ac4d85419 100644 --- a/code/controllers/configuration/entries/dbconfig.dm +++ b/code/controllers/configuration/entries/dbconfig.dm @@ -1,28 +1,26 @@ -#define CURRENT_RESIDENT_FILE "dbconfig.txt" - -CONFIG_DEF(flag/sql_enabled) // for sql switching +/datum/config_entry/flag/sql_enabled // for sql switching protection = CONFIG_ENTRY_LOCKED -CONFIG_DEF(string/address) +/datum/config_entry/string/address value = "localhost" protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN -CONFIG_DEF(number/port) +/datum/config_entry/number/port value = 3306 min_val = 0 max_val = 65535 protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN -CONFIG_DEF(string/feedback_database) +/datum/config_entry/string/feedback_database value = "test" protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN -CONFIG_DEF(string/feedback_login) +/datum/config_entry/string/feedback_login value = "root" protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN -CONFIG_DEF(string/feedback_password) +/datum/config_entry/string/feedback_password protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN -CONFIG_DEF(string/feedback_tableprefix) +/datum/config_entry/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 index 1b58d86db2..2d96e3c64b 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -1,253 +1,255 @@ -#define CURRENT_RESIDENT_FILE "game_options.txt" +/datum/config_entry/number_list/repeated_mode_adjust -CONFIG_DEF(number_list/repeated_mode_adjust) - -CONFIG_DEF(keyed_number_list/probability) +/datum/config_entry/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 /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 /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 // 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 // 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) +/datum/config_entry/keyed_string_list/policy -CONFIG_DEF(number/damage_multiplier) +/datum/config_entry/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. +/datum/config_entry/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. +/datum/config_entry/flag/jobs_have_minimal_access //determines whether jobs use minimal access or expanded access. -CONFIG_DEF(flag/assistants_have_maint_access) +/datum/config_entry/flag/assistants_have_maint_access -CONFIG_DEF(flag/security_has_maint_access) +/datum/config_entry/flag/security_has_maint_access -CONFIG_DEF(flag/everyone_has_maint_access) +/datum/config_entry/flag/everyone_has_maint_access -CONFIG_DEF(flag/sec_start_brig) //makes sec start in brig instead of dept sec posts +/datum/config_entry/flag/sec_start_brig //makes sec start in brig instead of dept sec posts -CONFIG_DEF(flag/force_random_names) +/datum/config_entry/flag/force_random_names -CONFIG_DEF(flag/humans_need_surnames) +/datum/config_entry/flag/humans_need_surnames -CONFIG_DEF(flag/allow_ai) // allow ai job +/datum/config_entry/flag/allow_ai // allow ai job -CONFIG_DEF(flag/disable_secborg) // disallow secborg module to be chosen. +/datum/config_entry/flag/disable_secborg // disallow secborg module to be chosen. -CONFIG_DEF(flag/disable_peaceborg) +/datum/config_entry/flag/disable_peaceborg -CONFIG_DEF(number/traitor_scaling_coeff) //how much does the amount of players get divided by to determine traitors +/datum/config_entry/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 +/datum/config_entry/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 +/datum/config_entry/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 +/datum/config_entry/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 +/datum/config_entry/number/abductor_scaling_coeff //how many players per abductor team value = 15 min_val = 1 -CONFIG_DEF(number/traitor_objectives_amount) +/datum/config_entry/number/traitor_objectives_amount value = 2 min_val = 0 -CONFIG_DEF(number/brother_objectives_amount) +/datum/config_entry/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 +/datum/config_entry/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 +/datum/config_entry/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 +/datum/config_entry/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 +/datum/config_entry/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 +/datum/config_entry/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 +/datum/config_entry/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 +/datum/config_entry/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) +/datum/config_entry/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 +/datum/config_entry/flag/show_game_type_odds //if set this allows players to see the odds of each roundtype on the get revision screen -CONFIG_DEF(keyed_flag_list/roundstart_races) //races you can play as from the get go. +/datum/config_entry/keyed_flag_list/roundstart_races //races you can play as from the get go. -CONFIG_DEF(flag/join_with_mutant_humans) //players can pick mutant bodyparts for humans before joining the game +/datum/config_entry/flag/join_with_mutant_humans //players can pick mutant bodyparts for humans before joining the game -CONFIG_DEF(flag/no_summon_guns) //No +/datum/config_entry/flag/no_summon_guns //No -CONFIG_DEF(flag/no_summon_magic) //Fun +/datum/config_entry/flag/no_summon_magic //Fun -CONFIG_DEF(flag/no_summon_events) //Allowed +/datum/config_entry/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. +/datum/config_entry/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 +/datum/config_entry/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 +/datum/config_entry/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 +/datum/config_entry/flag/arrivals_shuttle_require_safe_latejoin //Require the arrivals shuttle to be operational in order for latejoiners to join -CONFIG_DEF(string/alert_green) +/datum/config_entry/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) +/datum/config_entry/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) +/datum/config_entry/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) +/datum/config_entry/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) +/datum/config_entry/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) +/datum/config_entry/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) +/datum/config_entry/flag/revival_pod_plants -CONFIG_DEF(flag/revival_cloning) +/datum/config_entry/flag/revival_cloning -CONFIG_DEF(number/revival_brain_life) +/datum/config_entry/number/revival_brain_life value = -1 min_val = -1 -CONFIG_DEF(flag/rename_cyborg) +/datum/config_entry/flag/rename_cyborg -CONFIG_DEF(flag/ooc_during_round) +/datum/config_entry/flag/ooc_during_round -CONFIG_DEF(flag/emojis) +/datum/config_entry/flag/emojis -CONFIG_DEF(number/run_delay) //Used for modifying movement speed for mobs. +/datum/config_entry/number/run_delay //Used for modifying movement speed for mobs. var/static/value_cache = 0 -CONFIG_TWEAK(number/run_delay/ValidateAndSet()) +/datum/config_entry/number/run_delay/ValidateAndSet() . = ..() if(.) value_cache = value -CONFIG_DEF(number/walk_delay) +/datum/config_entry/number/walk_delay var/static/value_cache = 0 -CONFIG_TWEAK(number/walk_delay/ValidateAndSet()) +/datum/config_entry/number/walk_delay/ValidateAndSet() . = ..() if(.) value_cache = value -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) +/datum/config_entry/number/human_delay //Mob specific modifiers. NOTE: These will affect different mob types in different ways +/datum/config_entry/number/robot_delay +/datum/config_entry/number/monkey_delay +/datum/config_entry/number/alien_delay +/datum/config_entry/number/slime_delay +/datum/config_entry/number/animal_delay -CONFIG_DEF(number/gateway_delay) //How long the gateway takes before it activates. Default is half an hour. +/datum/config_entry/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) +/datum/config_entry/flag/ghost_interaction -CONFIG_DEF(flag/silent_ai) -CONFIG_DEF(flag/silent_borg) +/datum/config_entry/flag/silent_ai +/datum/config_entry/flag/silent_borg -CONFIG_DEF(flag/sandbox_autoclose) // close the sandbox panel after spawning an item, potentially reducing griff +/datum/config_entry/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. +/datum/config_entry/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) +/datum/config_entry/number/silicon_max_law_amount value = 12 min_val = 0 -CONFIG_DEF(keyed_flag_list/random_laws) +/datum/config_entry/keyed_flag_list/random_laws -CONFIG_DEF(keyed_number_list/law_weight) +/datum/config_entry/keyed_number_list/law_weight splitter = "," -CONFIG_DEF(number/assistant_cap) +/datum/config_entry/number/assistant_cap value = -1 min_val = -1 -CONFIG_DEF(flag/starlight) -CONFIG_DEF(flag/grey_assistants) +/datum/config_entry/flag/starlight +/datum/config_entry/flag/grey_assistants -CONFIG_DEF(number/lavaland_budget) +/datum/config_entry/number/lavaland_budget value = 60 min_val = 0 -CONFIG_DEF(number/space_budget) +/datum/config_entry/number/space_budget value = 16 min_val = 0 -CONFIG_DEF(flag/allow_random_events) // Enables random events mid-round when set +/datum/config_entry/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 +/datum/config_entry/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) +/datum/config_entry/number/events_min_players_mul value = 1 min_val = 0 integer = FALSE -CONFIG_DEF(number/mice_roundstart) +/datum/config_entry/number/mice_roundstart value = 10 min_val = 0 -CONFIG_DEF(number/bombcap) +/datum/config_entry/number/bombcap value = 14 min_val = 4 -CONFIG_DEF(flag/allow_crew_objectives) -CONFIG_DEF(flag/allow_miscreants) -CONFIG_DEF(flag/allow_extended_miscreants) +//Cit changes - Adds config options for crew objectives and miscreants +/datum/config_entry/flag/allow_crew_objectives + +/datum/config_entry/flag/allow_miscreants + +/datum/config_entry/flag/allow_extended_miscreants +//End of Cit changes /datum/config_entry/number/bombcap/ValidateAndSet(str_val) . = ..() @@ -258,9 +260,9 @@ CONFIG_DEF(flag/allow_extended_miscreants) GLOB.MAX_EX_FLASH_RANGE = value GLOB.MAX_EX_FLAME_RANGE = value -CONFIG_DEF(number/emergency_shuttle_autocall_threshold) +/datum/config_entry/number/emergency_shuttle_autocall_threshold min_val = 0 max_val = 1 integer = FALSE -CONFIG_DEF(flag/ic_printing) \ No newline at end of file +/datum/config_entry/flag/ic_printing diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm new file mode 100644 index 0000000000..637e65c46f --- /dev/null +++ b/code/controllers/configuration/entries/general.dm @@ -0,0 +1,388 @@ +/datum/config_entry/flag/autoadmin // if autoadmin is enabled + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/string/autoadmin_rank // the rank for autoadmins + value = "Game Master" + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/string/servername // server name (the name of the game window) + +/datum/config_entry/string/serversqlname // short form server name used for the DB + +/datum/config_entry/string/stationname // station name (the name of the station in-game) + +/datum/config_entry/number/lobby_countdown // In between round countdown. + value = 120 + min_val = 0 + +/datum/config_entry/number/round_end_countdown // Post round murder death kill countdown + value = 25 + min_val = 0 + +/datum/config_entry/flag/hub // if the game appears on the hub or not + +/datum/config_entry/flag/log_ooc // log OOC channel + +/datum/config_entry/flag/log_access // log login/logout + +/datum/config_entry/flag/log_say // log client say + +/datum/config_entry/flag/log_admin // log admin actions + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/log_prayer // log prayers + +/datum/config_entry/flag/log_law // log lawchanges + +/datum/config_entry/flag/log_game // log game events + +/datum/config_entry/flag/log_vote // log voting + +/datum/config_entry/flag/log_whisper // log client whisper + +/datum/config_entry/flag/log_attack // log attack messages + +/datum/config_entry/flag/log_emote // log emotes + +/datum/config_entry/flag/log_adminchat // log admin chat messages + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/log_pda // log pda messages + +/datum/config_entry/flag/log_twitter // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases. + +/datum/config_entry/flag/log_world_topic // log all world.Topic() calls + +/datum/config_entry/flag/log_manifest // log crew manifest to seperate file + +/datum/config_entry/flag/allow_admin_ooccolor // Allows admins with relevant permissions to have their own ooc colour + +/datum/config_entry/flag/allow_vote_restart // allow votes to restart + +/datum/config_entry/flag/allow_vote_mode // allow votes to change mode + +/datum/config_entry/number/vote_delay // minimum time between voting sessions (deciseconds, 10 minute default) + value = 6000 + min_val = 0 + +/datum/config_entry/number/vote_period // length of voting period (deciseconds, default 1 minute) + value = 600 + min_val = 0 + +/datum/config_entry/flag/default_no_vote // vote does not default to nochange/norestart + +/datum/config_entry/flag/no_dead_vote // dead people can't vote + +/datum/config_entry/flag/allow_metadata // Metadata is supported. + +/datum/config_entry/flag/popup_admin_pm // adminPMs to non-admins show in a pop-up 'reply' window when set + +/datum/config_entry/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 + +/datum/config_entry/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 + +/datum/config_entry/flag/allow_holidays + +/datum/config_entry/number/tick_limit_mc_init //SSinitialization throttling + value = TICK_LIMIT_MC_INIT_DEFAULT + min_val = 0 //oranges warned us + integer = FALSE + +/datum/config_entry/flag/admin_legacy_system //Defines whether the server uses the legacy admin system with admins.txt or the SQL system + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/string/hostedby + +/datum/config_entry/flag/norespawn + +/datum/config_entry/flag/guest_jobban + +/datum/config_entry/flag/usewhitelist + +/datum/config_entry/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 + +/datum/config_entry/flag/use_age_restriction_for_jobs //Do jobs use account age restrictions? --requires database + +/datum/config_entry/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. + +/datum/config_entry/flag/use_exp_tracking + +/datum/config_entry/flag/use_exp_restrictions_heads + +/datum/config_entry/number/use_exp_restrictions_heads_hours + value = 0 + min_val = 0 + +/datum/config_entry/flag/use_exp_restrictions_heads_department + +/datum/config_entry/flag/use_exp_restrictions_other + +/datum/config_entry/flag/use_exp_restrictions_admin_bypass + +/datum/config_entry/string/server + +/datum/config_entry/string/banappeals + +/datum/config_entry/string/wikiurl + value = "http://www.tgstation13.org/wiki" + +/datum/config_entry/string/forumurl + value = "http://tgstation13.org/phpBB/index.php" + +/datum/config_entry/string/rulesurl + value = "http://www.tgstation13.org/wiki/Rules" + +/datum/config_entry/string/githuburl + value = "https://www.github.com/tgstation/-tg-station" + +/datum/config_entry/number/githubrepoid + value = null + min_val = 0 + +/datum/config_entry/flag/guest_ban + +/datum/config_entry/number/id_console_jobslot_delay + value = 30 + min_val = 0 + +/datum/config_entry/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 + +/datum/config_entry/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 + +/datum/config_entry/flag/kick_inactive //force disconnect for inactive players + +/datum/config_entry/flag/load_jobs_from_txt + +/datum/config_entry/flag/forbid_singulo_possession + +/datum/config_entry/flag/automute_on //enables automuting/spam prevention + +/datum/config_entry/string/panic_server_name + +/datum/config_entry/string/panic_server_name/ValidateAndSet(str_val) + return str_val != "\[Put the name here\]" && ..() + +/datum/config_entry/string/panic_server_address //Reconnect a player this linked server if this server isn't accepting new players + +/datum/config_entry/string/panic_server_address/ValidateAndSet(str_val) + return str_val != "byond://address:port" && ..() + +/datum/config_entry/string/invoke_youtubedl + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +/datum/config_entry/flag/show_irc_name + +/datum/config_entry/flag/see_own_notes //Can players see their own admin notes + +/datum/config_entry/number/note_fresh_days + value = null + min_val = 0 + integer = FALSE + +/datum/config_entry/number/note_stale_days + value = null + min_val = 0 + integer = FALSE + +/datum/config_entry/flag/maprotation + +/datum/config_entry/number/maprotatechancedelta + value = 0.75 + min_val = 0 + max_val = 1 + integer = FALSE + +/datum/config_entry/number/soft_popcap + value = null + min_val = 0 + +/datum/config_entry/number/hard_popcap + value = null + min_val = 0 + +/datum/config_entry/number/extreme_popcap + value = null + min_val = 0 + +/datum/config_entry/string/soft_popcap_message + value = "Be warned that the server is currently serving a high number of users, consider using alternative game servers." + +/datum/config_entry/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." + +/datum/config_entry/string/extreme_popcap_message + value = "The server is currently serving a high number of users, find alternative servers." + +/datum/config_entry/flag/panic_bunker // prevents people the server hasn't seen before from connecting + +/datum/config_entry/number/notify_new_player_age // how long do we notify admins of a new player + min_val = -1 + +/datum/config_entry/number/notify_new_player_account_age // how long do we notify admins of a new byond account + min_val = 0 + +/datum/config_entry/flag/irc_first_connection_alert // do we notify the irc channel when somebody is connecting for the first time? + +/datum/config_entry/flag/check_randomizer + +/datum/config_entry/string/ipintel_email + +/datum/config_entry/string/ipintel_email/ValidateAndSet(str_val) + return str_val != "ch@nge.me" && ..() + +/datum/config_entry/number/ipintel_rating_bad + value = 1 + integer = FALSE + min_val = 0 + max_val = 1 + +/datum/config_entry/number/ipintel_save_good + value = 12 + min_val = 0 + +/datum/config_entry/number/ipintel_save_bad + value = 1 + min_val = 0 + +/datum/config_entry/string/ipintel_domain + value = "check.getipintel.net" + +/datum/config_entry/flag/aggressive_changelog + +/datum/config_entry/flag/autoconvert_notes //if all connecting player's notes should attempt to be converted to the database + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/allow_webclient + +/datum/config_entry/flag/webclient_only_byond_members + +/datum/config_entry/flag/announce_admin_logout + +/datum/config_entry/flag/announce_admin_login + +/datum/config_entry/flag/allow_map_voting + +/datum/config_entry/flag/generate_minimaps + +/datum/config_entry/number/client_warn_version + value = null + min_val = 500 + max_val = DM_VERSION - 1 + +/datum/config_entry/string/client_warn_message + value = "Your version of byond may have issues or be blocked from accessing this server in the future." + +/datum/config_entry/flag/client_warn_popup + +/datum/config_entry/number/client_error_version + value = null + min_val = 500 + max_val = DM_VERSION - 1 + +/datum/config_entry/string/client_error_message + value = "Your version of byond is too old, may have issues, and is blocked from accessing this server." + +/datum/config_entry/number/minute_topic_limit + value = null + min_val = 0 + +/datum/config_entry/number/second_topic_limit + value = null + min_val = 0 + +/datum/config_entry/number/error_cooldown // The "cooldown" time for each occurrence of a unique error + value = 600 + min_val = 0 + +/datum/config_entry/number/error_limit // How many occurrences before the next will silence them + value = 50 + +/datum/config_entry/number/error_silence_time // How long a unique error will be silenced for + value = 6000 + +/datum/config_entry/number/error_msg_delay // How long to wait between messaging admins about occurrences of a unique error + value = 50 + +/datum/config_entry/flag/irc_announce_new_game + +/datum/config_entry/flag/debug_admin_hrefs + +/datum/config_entry/number/mc_tick_rate/base_mc_tick_rate + integer = FALSE + value = 1 + +/datum/config_entry/number/mc_tick_rate/high_pop_mc_tick_rate + integer = FALSE + value = 1.1 + +/datum/config_entry/number/mc_tick_rate/high_pop_mc_mode_amount + value = 65 + +/datum/config_entry/number/mc_tick_rate/disable_high_pop_mc_mode_amount + value = 60 + +/datum/config_entry/number/mc_tick_rate + abstract_type = /datum/config_entry/number/mc_tick_rate + +/datum/config_entry/number/mc_tick_rate/ValidateAndSet(str_val) + . = ..() + if (.) + Master.UpdateTickRate() + +/datum/config_entry/flag/resume_after_initializations + +/datum/config_entry/flag/resume_after_initializations/ValidateAndSet(str_val) + . = ..() + if(. && Master.current_runlevel) + world.sleep_offline = !value + +/datum/config_entry/number/rounds_until_hard_restart + value = -1 + min_val = 0 + +/datum/config_entry/string/default_view + value = "15x15" diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 568257e10f..b9950da7b9 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -301,7 +301,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new continue //Byond resumed us late. assume it might have to do the same next tick - if (last_run + Ceiling(world.tick_lag * (processing * sleep_delta), world.tick_lag) < world.time) + if (last_run + CEILING(world.tick_lag * (processing * sleep_delta), world.tick_lag) < world.time) sleep_delta += 1 sleep_delta = MC_AVERAGE_FAST(sleep_delta, 1) //decay sleep_delta diff --git a/code/controllers/subsystem.dm b/code/controllers/subsystem.dm index 4937a3499b..8d450e3a8e 100644 --- a/code/controllers/subsystem.dm +++ b/code/controllers/subsystem.dm @@ -8,6 +8,8 @@ var/flags = 0 //see MC.dm in __DEFINES Most flags must be set on world start to take full effect. (You can also restart the mc to force them to process again) + var/initialized = FALSE //set to TRUE after it has been initialized, will obviously never be set if the subsystem doesn't initialize + //set to 0 to prevent fire() calls, mostly for admin use or subsystems that may be resumed later // use the SS_NO_FIRE flag instead for systems that never fire to keep it from even being added to the list var/can_fire = TRUE @@ -156,6 +158,7 @@ //used to initialize the subsystem AFTER the map has loaded /datum/controller/subsystem/Initialize(start_timeofday) + initialized = TRUE var/time = (REALTIMEOFDAY - start_timeofday) / 10 var/msg = "Initialized [name] subsystem within [time] second[time == 1 ? "" : "s"]!" to_chat(world, "[msg]") diff --git a/code/controllers/subsystem/atoms.dm b/code/controllers/subsystem/atoms.dm index aeadfcf94e..c24f4f0a37 100644 --- a/code/controllers/subsystem/atoms.dm +++ b/code/controllers/subsystem/atoms.dm @@ -8,7 +8,6 @@ SUBSYSTEM_DEF(atoms) init_order = INIT_ORDER_ATOMS flags = SS_NO_FIRE - var/initialized = INITIALIZATION_INSSATOMS var/old_initialized var/list/late_loaders diff --git a/code/controllers/subsystem/blackbox.dm b/code/controllers/subsystem/blackbox.dm index 3a0f3cff24..e638de668e 100644 --- a/code/controllers/subsystem/blackbox.dm +++ b/code/controllers/subsystem/blackbox.dm @@ -10,7 +10,8 @@ SUBSYSTEM_DEF(blackbox) var/sealed = FALSE //time to stop tracking stats? var/list/research_levels = list() //list of highest tech levels attained that isn't lost lost by destruction of RD computers var/list/versions = list("time_dilation_current" = 2, - "science_techweb_unlock" = 2) //associative list of any feedback variables that have had their format changed since creation and their current version, remember to update this + "science_techweb_unlock" = 2, + "antagonists" = 3) //associative list of any feedback variables that have had their format changed since creation and their current version, remember to update this /datum/controller/subsystem/blackbox/Initialize() @@ -39,13 +40,20 @@ SUBSYSTEM_DEF(blackbox) sealed = SSblackbox.sealed //no touchie -/datum/controller/subsystem/blackbox/can_vv_get(var_name) +/datum/controller/subsystem/blackbox/vv_get_var(var_name) if(var_name == "feedback") - return FALSE + return debug_variable(var_name, deepCopyList(feedback), 0, src) return ..() /datum/controller/subsystem/blackbox/vv_edit_var(var_name, var_value) - return FALSE + switch(var_name) + if("feedback") + return FALSE + if("sealed") + if(var_value) + return Seal() + return FALSE + return ..() /datum/controller/subsystem/blackbox/Shutdown() sealed = FALSE @@ -76,11 +84,12 @@ SUBSYSTEM_DEF(blackbox) /datum/controller/subsystem/blackbox/proc/Seal() if(sealed) - return + return FALSE if(IsAdminAdvancedProcCall()) message_admins("[key_name_admin(usr)] sealed the blackbox!") log_game("Blackbox sealed[IsAdminAdvancedProcCall() ? " by [key_name(usr)]" : ""].") sealed = TRUE + return TRUE /datum/controller/subsystem/blackbox/proc/log_research(tech, level) if(!(tech in research_levels) || research_levels[tech] < level) @@ -217,7 +226,12 @@ Versioning var/pos = length(FV.json["data"]) + 1 FV.json["data"]["[pos]"] = list() //in 512 "pos" can be replaced with "[FV.json["data"].len+1]" for(var/i in data) - FV.json["data"]["[pos]"]["[i]"] = "[data[i]]" //and here with "[FV.json["data"].len]" + if(islist(data[i])) + FV.json["data"]["[pos]"]["[i]"] = data[i] //and here with "[FV.json["data"].len]" + else + FV.json["data"]["[pos]"]["[i]"] = "[data[i]]" + else + CRASH("Invalid feedback key_type: [key_type]") /datum/controller/subsystem/blackbox/proc/record_feedback_recurse_list(list/L, list/key_list, increment, depth = 1) if(depth == key_list.len) diff --git a/code/controllers/subsystem/disease.dm b/code/controllers/subsystem/disease.dm index 327ba95196..48676bc51e 100644 --- a/code/controllers/subsystem/disease.dm +++ b/code/controllers/subsystem/disease.dm @@ -1,6 +1,6 @@ SUBSYSTEM_DEF(disease) name = "Disease" - flags = SS_NO_FIRE | SS_NO_INIT + flags = SS_NO_FIRE var/list/active_diseases = list() //List of Active disease in all mobs; purely for quick referencing. var/list/diseases @@ -12,6 +12,13 @@ SUBSYSTEM_DEF(disease) if(!diseases) diseases = subtypesof(/datum/disease) +/datum/controller/subsystem/disease/Initialize(timeofday) + var/list/all_common_diseases = diseases - typesof(/datum/disease/advance) + for(var/common_disease_type in all_common_diseases) + var/datum/disease/prototype = new common_disease_type() + archive_diseases[prototype.GetDiseaseID()] = prototype + ..() + /datum/controller/subsystem/disease/stat_entry(msg) ..("P:[active_diseases.len]") diff --git a/code/controllers/subsystem/input.dm b/code/controllers/subsystem/input.dm new file mode 100644 index 0000000000..5dbb642f2e --- /dev/null +++ b/code/controllers/subsystem/input.dm @@ -0,0 +1,12 @@ +SUBSYSTEM_DEF(input) + name = "Input" + wait = 1 //SS_TICKER means this runs every tick + flags = SS_TICKER | SS_NO_INIT + priority = 1000 + runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY + +/datum/controller/subsystem/input/fire() + var/list/clients = GLOB.clients // Let's sing the list cache song + for(var/i in 1 to clients.len) + var/client/C = clients[i] + C.keyLoop() diff --git a/code/controllers/subsystem/lighting.dm b/code/controllers/subsystem/lighting.dm index 8e19b265cf..43565846fb 100644 --- a/code/controllers/subsystem/lighting.dm +++ b/code/controllers/subsystem/lighting.dm @@ -8,8 +8,6 @@ SUBSYSTEM_DEF(lighting) init_order = INIT_ORDER_LIGHTING flags = SS_TICKER - var/initialized = FALSE - /datum/controller/subsystem/lighting/stat_entry() ..("L:[GLOB.lighting_update_lights.len]|C:[GLOB.lighting_update_corners.len]|O:[GLOB.lighting_update_objects.len]") diff --git a/code/controllers/subsystem/mobs.dm b/code/controllers/subsystem/mobs.dm index 1311ca1589..bcdb1af8ed 100644 --- a/code/controllers/subsystem/mobs.dm +++ b/code/controllers/subsystem/mobs.dm @@ -1,14 +1,18 @@ SUBSYSTEM_DEF(mobs) name = "Mobs" priority = 100 - flags = SS_KEEP_TIMING|SS_NO_INIT + flags = SS_KEEP_TIMING runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME var/list/currentrun = list() + var/static/list/clients_by_zlevel[][] /datum/controller/subsystem/mobs/stat_entry() ..("P:[GLOB.mob_living_list.len]") +/datum/controller/subsystem/mobs/Initialize(start_timeofday) + clients_by_zlevel = new /list(world.maxz,0) + return ..() /datum/controller/subsystem/mobs/fire(resumed = 0) var/seconds = wait * 0.1 diff --git a/code/controllers/subsystem/overlays.dm b/code/controllers/subsystem/overlays.dm index c0ccdddb31..d0b2e8c303 100644 --- a/code/controllers/subsystem/overlays.dm +++ b/code/controllers/subsystem/overlays.dm @@ -10,7 +10,6 @@ SUBSYSTEM_DEF(overlays) var/list/stats var/list/overlay_icon_state_caches var/list/overlay_icon_cache - var/initialized = FALSE /datum/controller/subsystem/overlays/PreInit() overlay_icon_state_caches = list() diff --git a/code/controllers/subsystem/processing/circuit.dm b/code/controllers/subsystem/processing/circuit.dm index 461a793a45..a9abacd934 100644 --- a/code/controllers/subsystem/processing/circuit.dm +++ b/code/controllers/subsystem/processing/circuit.dm @@ -44,10 +44,20 @@ PROCESSING_SUBSYSTEM_DEF(circuit) circuit_fabricator_recipe_list["Assemblies"] = list( - /obj/item/device/electronic_assembly, - /obj/item/device/electronic_assembly/medium, - /obj/item/device/electronic_assembly/large, - /obj/item/device/electronic_assembly/drone + /obj/item/device/electronic_assembly/default, + /obj/item/device/electronic_assembly/calc, + /obj/item/device/electronic_assembly/clam, + /obj/item/device/electronic_assembly/simple, + /obj/item/device/electronic_assembly/medium/default, + /obj/item/device/electronic_assembly/medium/box, + /obj/item/device/electronic_assembly/medium/clam, + /obj/item/device/electronic_assembly/medium/medical, + /obj/item/device/electronic_assembly/large/default, + /obj/item/device/electronic_assembly/large/scope, + /obj/item/device/electronic_assembly/large/terminal, + /obj/item/device/electronic_assembly/large/arm, + /obj/item/device/electronic_assembly/drone/default, + /obj/item/device/electronic_assembly/drone/arms ///obj/item/weapon/implant/integrated_circuit ) diff --git a/code/controllers/subsystem/processing/networks.dm b/code/controllers/subsystem/processing/networks.dm index 960a70a59d..69c5fe1b2b 100644 --- a/code/controllers/subsystem/processing/networks.dm +++ b/code/controllers/subsystem/processing/networks.dm @@ -1,36 +1,36 @@ -PROCESSING_SUBSYSTEM_DEF(networks) - name = "Networks" - priority = 80 - wait = 1 - stat_tag = "NET" - flags = SS_KEEP_TIMING - init_order = INIT_ORDER_NETWORKS - var/datum/ntnet/station/station_network - var/assignment_hardware_id = HID_RESTRICTED_END - var/list/networks_by_id = list() //id = network - var/list/interfaces_by_id = list() //hardware id = component interface - -/datum/controller/subsystem/processing/networks/Initialize() - station_network = new - station_network.register_map_supremecy() - . = ..() - -/datum/controller/subsystem/processing/networks/proc/register_network(datum/ntnet/network) - if(!networks_by_id[network.network_id]) - networks_by_id[network.network_id] = network - return TRUE - return FALSE - -/datum/controller/subsystem/processing/networks/proc/unregister_network(datum/ntnet/network) - networks_by_id -= network.network_id - return TRUE - -/datum/controller/subsystem/processing/networks/proc/register_interface(datum/component/ntnet_interface/D) - if(!interfaces_by_id[D.hardware_id]) - interfaces_by_id[D.hardware_id] = D - return TRUE - return FALSE - -/datum/controller/subsystem/processing/networks/proc/unregister_interface(datum/component/ntnet_interface/D) - interfaces_by_id -= D.hardware_id - return TRUE +PROCESSING_SUBSYSTEM_DEF(networks) + name = "Networks" + priority = 80 + wait = 1 + stat_tag = "NET" + flags = SS_KEEP_TIMING + init_order = INIT_ORDER_NETWORKS + var/datum/ntnet/station/station_network + var/assignment_hardware_id = HID_RESTRICTED_END + var/list/networks_by_id = list() //id = network + var/list/interfaces_by_id = list() //hardware id = component interface + +/datum/controller/subsystem/processing/networks/Initialize() + station_network = new + station_network.register_map_supremecy() + . = ..() + +/datum/controller/subsystem/processing/networks/proc/register_network(datum/ntnet/network) + if(!networks_by_id[network.network_id]) + networks_by_id[network.network_id] = network + return TRUE + return FALSE + +/datum/controller/subsystem/processing/networks/proc/unregister_network(datum/ntnet/network) + networks_by_id -= network.network_id + return TRUE + +/datum/controller/subsystem/processing/networks/proc/register_interface(datum/component/ntnet_interface/D) + if(!interfaces_by_id[D.hardware_id]) + interfaces_by_id[D.hardware_id] = D + return TRUE + return FALSE + +/datum/controller/subsystem/processing/networks/proc/unregister_interface(datum/component/ntnet_interface/D) + interfaces_by_id -= D.hardware_id + return TRUE diff --git a/code/controllers/subsystem/radio.dm b/code/controllers/subsystem/radio.dm index de605cb554..43803aa647 100644 --- a/code/controllers/subsystem/radio.dm +++ b/code/controllers/subsystem/radio.dm @@ -3,6 +3,13 @@ SUBSYSTEM_DEF(radio) flags = SS_NO_FIRE|SS_NO_INIT var/list/datum/radio_frequency/frequencies = list() + var/list/saymodes = list() + +/datum/controller/subsystem/radio/PreInit(timeofday) + for(var/_SM in subtypesof(/datum/saymode)) + var/datum/saymode/SM = new _SM() + saymodes[SM.key] = SM + return ..() /datum/controller/subsystem/radio/proc/add_object(obj/device, new_frequency as num, filter = null as text|null) var/f_text = num2text(new_frequency) diff --git a/code/controllers/subsystem/research.dm b/code/controllers/subsystem/research.dm new file mode 100644 index 0000000000..d1bcf31885 --- /dev/null +++ b/code/controllers/subsystem/research.dm @@ -0,0 +1,75 @@ + +SUBSYSTEM_DEF(research) + name = "Research" + flags = SS_KEEP_TIMING + priority = 15 //My powergame is priority. + wait = 10 + init_order = INIT_ORDER_RESEARCH + var/list/invalid_design_ids = list() //associative id = number of times + var/list/invalid_node_ids = list() //associative id = number of times + var/list/invalid_node_boost = list() //associative id = error message + var/list/obj/machinery/rnd/server/servers = list() + var/datum/techweb/science/science_tech + var/datum/techweb/admin/admin_tech + var/list/techweb_nodes = list() //associative id = node datum + var/list/techweb_categories = list() //category name = list(node.id = node) + var/list/techweb_designs = list() //associative id = node datum + var/list/techweb_nodes_starting = list() //associative id = node datum + var/list/techweb_boost_items = list() //associative double-layer path = list(id = point_discount) + var/list/techweb_nodes_hidden = list() //Nodes that should be hidden by default. + var/list/techweb_point_items = list() //path = value + var/list/errored_datums = list() + //---------------------------------------------- + var/single_server_income = 40.7 + var/multiserver_calculation = FALSE + var/last_income = 0 + //^^^^^^^^ ALL OF THESE ARE PER SECOND! ^^^^^^^^ + + //Aiming for 1.5 hours to max R&D + //[88nodes * 5000points/node] / [1.5hr * 90min/hr * 60s/min] + //Around 450000 points max??? + + var/bomb_research_point_scaling = 1800 + +/datum/controller/subsystem/research/Initialize() + initialize_all_techweb_designs() + initialize_all_techweb_nodes() + science_tech = new /datum/techweb/science + admin_tech = new /datum/techweb/admin + autosort_categories() + return ..() + +/datum/controller/subsystem/research/fire() + handle_research_income() + +/datum/controller/subsystem/research/proc/handle_research_income() + var/bitcoins = 0 + if(multiserver_calculation) + var/eff = calculate_server_coefficient() + for(var/obj/machinery/rnd/server/miner in servers) + bitcoins += (miner.mine() * eff) //SLAVE AWAY, SLAVE. + else + for(var/obj/machinery/rnd/server/miner in servers) + if(miner.working) + bitcoins = single_server_income + break //Just need one to work. + var/income_time_difference = world.time - last_income + bitcoins *= income_time_difference / 10 + science_tech.research_points += bitcoins + last_income = world.time + +/datum/controller/subsystem/research/proc/calculate_server_coefficient() //Diminishing returns. + var/amt = servers.len + if(!amt) + return 0 + var/coeff = 100 + coeff = sqrt(coeff / amt) + return coeff + +/datum/controller/subsystem/research/proc/autosort_categories() + for(var/i in techweb_nodes) + var/datum/techweb_node/I = techweb_nodes[i] + if(techweb_categories[I.category]) + techweb_categories[I.category][I.id] = I + else + techweb_categories[I.category] = list(I.id = I) diff --git a/code/controllers/subsystem/server_maint.dm b/code/controllers/subsystem/server_maint.dm index 43585a5896..cb5a86bd75 100644 --- a/code/controllers/subsystem/server_maint.dm +++ b/code/controllers/subsystem/server_maint.dm @@ -55,5 +55,8 @@ SUBSYSTEM_DEF(server_maint) co.ehjax_send(data = "roundrestart") if(server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite C << link("byond://[server]") + if(SERVER_TOOLS_PRESENT) + SSblackbox.record_feedback("text", "server_tools", 1, SERVER_TOOLS_VERSION) + SSblackbox.record_feedback("text", "server_tools_api", 1, SERVER_TOOLS_API_VERSION) #undef PING_BUFFER_TIME diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index 75111a2017..35208d4137 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -44,6 +44,9 @@ SUBSYSTEM_DEF(shuttle) var/list/requestlist = list() var/list/orderhistory = list() + var/list/hidden_shuttle_turfs = list() //all turfs hidden from navigation computers associated with a list containing the image hiding them and the type of the turf they are pretending to be + var/list/hidden_shuttle_turf_images = list() //only the images from the above list + var/datum/round_event/shuttle_loan/shuttle_loan var/shuttle_purchased = FALSE //If the station has purchased a replacement escape shuttle this round @@ -304,6 +307,9 @@ SUBSYSTEM_DEF(shuttle) return 1 /datum/controller/subsystem/shuttle/proc/autoEvac() + if (!SSticker.IsRoundInProgress()) + return + var/callShuttle = 1 for(var/thing in GLOB.shuttle_caller_list) @@ -648,4 +654,40 @@ SUBSYSTEM_DEF(shuttle) var/list/xs = overlap[1] var/list/ys = overlap[2] if(xs.len && ys.len) - .[port] = overlap \ No newline at end of file + .[port] = overlap + +/datum/controller/subsystem/shuttle/proc/update_hidden_docking_ports(list/remove_turfs, list/add_turfs) + var/list/remove_images = list() + var/list/add_images = list() + + if(remove_turfs) + for(var/T in remove_turfs) + var/list/L = hidden_shuttle_turfs[T] + if(L) + remove_images += L[1] + hidden_shuttle_turfs -= remove_turfs + + if(add_turfs) + for(var/V in add_turfs) + var/turf/T = V + var/image/I + if(remove_images.len) + //we can just reuse any images we are about to delete instead of making new ones + I = remove_images[1] + remove_images.Cut(1, 2) + I.loc = T + else + I = image(loc = T) + add_images += I + I.appearance = T.appearance + I.override = TRUE + hidden_shuttle_turfs[T] = list(I, T.type) + + hidden_shuttle_turf_images -= remove_images + hidden_shuttle_turf_images += add_images + + for(var/V in GLOB.navigation_computers) + var/obj/machinery/computer/camera_advanced/shuttle_docker/C = V + C.update_hidden_docking_ports(remove_images, add_images) + + QDEL_LIST(remove_images) diff --git a/code/controllers/subsystem/throwing.dm b/code/controllers/subsystem/throwing.dm index 97d84a0d3b..ec21f3bab2 100644 --- a/code/controllers/subsystem/throwing.dm +++ b/code/controllers/subsystem/throwing.dm @@ -80,7 +80,7 @@ SUBSYSTEM_DEF(throwing) last_move = world.time //calculate how many tiles to move, making up for any missed ticks. - var/tilestomove = Ceiling(min(((((world.time+world.tick_lag) - start_time + delayed_time) * speed) - (dist_travelled ? dist_travelled : -1)), speed*MAX_TICKS_TO_MAKE_UP) * (world.tick_lag * SSthrowing.wait)) + var/tilestomove = CEILING(min(((((world.time+world.tick_lag) - start_time + delayed_time) * speed) - (dist_travelled ? dist_travelled : -1)), speed*MAX_TICKS_TO_MAKE_UP) * (world.tick_lag * SSthrowing.wait), 1) while (tilestomove-- > 0) if ((dist_travelled >= maxrange || AM.loc == target_turf) && AM.has_gravity(AM.loc)) finalize() diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index dfdff1890a..0f06caa20d 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -33,8 +33,8 @@ SUBSYSTEM_DEF(ticker) SCRIPTURE_APPLICATION = FALSE) //list of clockcult scripture states for announcements var/delay_end = 0 //if set true, the round will not restart on it's own - var/admin_delay_notice = "" //a message to display to anyone who tries to restart the world after a delay + var/ready_for_reboot = FALSE //all roundend preparation done with, all that's left is reboot var/triai = 0 //Global holder for Triumvirate var/tipped = 0 //Did we broadcast the tip of the day yet? @@ -398,197 +398,6 @@ SUBSYSTEM_DEF(ticker) var/mob/living/L = I L.notransform = FALSE -/datum/controller/subsystem/ticker/proc/declare_completion() - set waitfor = FALSE - var/station_evacuated = EMERGENCY_ESCAPED_OR_ENDGAMED - var/num_survivors = 0 - var/num_escapees = 0 - var/num_shuttle_escapees = 0 - var/list/successfulCrew = list() - var/list/miscreants = list() - - 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) - if(!C.credits && !nocredits) - C.RollCredits() - C.playtitlemusic(40)*/ - - //Player status report - for(var/i in GLOB.mob_list) - var/mob/Player = i - if(Player.mind && !isnewplayer(Player)) - if(Player.stat != DEAD && !isbrain(Player)) - num_survivors++ - if(station_evacuated) //If the shuttle has already left the station - var/list/area/shuttle_areas - if(SSshuttle && SSshuttle.emergency) - shuttle_areas = SSshuttle.emergency.shuttle_areas - if(!Player.onCentCom() && !Player.onSyndieBase()) - to_chat(Player, "You managed to survive, but were marooned on [station_name()]...") - else - num_escapees++ - to_chat(Player, "You managed to survive the events on [station_name()] as [Player.real_name].") - if(shuttle_areas[get_area(Player)]) - num_shuttle_escapees++ - else - to_chat(Player, "You managed to survive the events on [station_name()] as [Player.real_name].") - else - to_chat(Player, "You did not survive the events on [station_name()]...") - - CHECK_TICK - - //Round statistics report - var/datum/station_state/end_state = new /datum/station_state() - end_state.count() - var/station_integrity = min(PERCENT(GLOB.start_state.score(end_state)), 100) - - to_chat(world, "
[GLOB.TAB]Shift Duration: [DisplayTimeText(world.time - SSticker.round_start_time)]") - to_chat(world, "
[GLOB.TAB]Station Integrity: [mode.station_was_nuked ? "Destroyed" : "[station_integrity]%"]") - if(mode.station_was_nuked) - SSticker.news_report = STATION_DESTROYED_NUKE - var/total_players = GLOB.joined_player_list.len - if(total_players) - to_chat(world, "
[GLOB.TAB]Total Population: [total_players]") - if(station_evacuated) - to_chat(world, "
[GLOB.TAB]Evacuation Rate: [num_escapees] ([PERCENT(num_escapees/total_players)]%)") - to_chat(world, "
[GLOB.TAB](on emergency shuttle): [num_shuttle_escapees] ([PERCENT(num_shuttle_escapees/total_players)]%)") - news_report = STATION_EVACUATED - if(SSshuttle.emergency.is_hijacked()) - news_report = SHUTTLE_HIJACK - to_chat(world, "
[GLOB.TAB]Survival Rate: [num_survivors] ([PERCENT(num_survivors/total_players)]%)") - to_chat(world, "
") - - CHECK_TICK - - //Silicon laws report - for (var/i in GLOB.ai_list) - var/mob/living/silicon/ai/aiPlayer = i - if (aiPlayer.stat != DEAD && aiPlayer.mind) - to_chat(world, "[aiPlayer.name] (Played by: [aiPlayer.mind.key])'s laws at the end of the round were:") - aiPlayer.show_laws(1) - else if (aiPlayer.mind) //if the dead ai has a mind, use its key instead - to_chat(world, "[aiPlayer.name] (Played by: [aiPlayer.mind.key])'s laws when it was deactivated were:") - aiPlayer.show_laws(1) - - to_chat(world, "Total law changes: [aiPlayer.law_change_counter]") - - if (aiPlayer.connected_robots.len) - var/robolist = "[aiPlayer.real_name]'s minions were: " - for(var/mob/living/silicon/robot/robo in aiPlayer.connected_robots) - if(robo.mind) - robolist += "[robo.name][robo.stat?" (Deactivated) (Played by: [robo.mind.key]), ":" (Played by: [robo.mind.key]), "]" - to_chat(world, "[robolist]") - - CHECK_TICK - - for (var/mob/living/silicon/robot/robo in GLOB.silicon_mobs) - if (!robo.connected_ai && robo.mind) - if (robo.stat != DEAD) - to_chat(world, "[robo.name] (Played by: [robo.mind.key]) survived as an AI-less borg! Its laws were:") - else - to_chat(world, "[robo.name] (Played by: [robo.mind.key]) was unable to survive the rigors of being a cyborg without an AI. Its laws were:") - - if(robo) //How the hell do we lose robo between here and the world messages directly above this? - robo.laws.show_laws(world) - - CHECK_TICK - - mode.declare_completion()//To declare normal completion. - - CHECK_TICK - - //calls auto_declare_completion_* for all modes - for(var/handler in typesof(/datum/game_mode/proc)) - if (findtext("[handler]","auto_declare_completion_")) - call(mode, handler)(force_ending) - - CHECK_TICK - - if(CONFIG_GET(string/cross_server_address)) - send_news_report() - - CHECK_TICK - - //Print a list of antagonists to the server log - var/list/total_antagonists = list() - //Look into all mobs in world, dead or alive - for(var/datum/mind/Mind in minds) - var/temprole = Mind.special_role - if(temprole) //if they are an antagonist of some sort. - if(temprole in total_antagonists) //If the role exists already, add the name to it - total_antagonists[temprole] += ", [Mind.name]([Mind.key])" - else - total_antagonists.Add(temprole) //If the role doesnt exist in the list, create it and add the mob - total_antagonists[temprole] += ": [Mind.name]([Mind.key])" - - CHECK_TICK - - //Now print them all into the log! - log_game("Antagonists at round end were...") - for(var/i in total_antagonists) - log_game("[i]s[total_antagonists[i]].") - - CHECK_TICK - - for(var/datum/mind/crewMind in minds) - if(!crewMind.current || !crewMind.objectives.len) - continue - for(var/datum/objective/miscreant/MO in crewMind.objectives) - miscreants += "[crewMind.current.real_name] (Played by: [crewMind.key])
Objective: [MO.explanation_text] (Optional)" - for(var/datum/objective/crew/CO in crewMind.objectives) - if(CO.check_completion()) - to_chat(crewMind.current, "
Your optional objective: [CO.explanation_text] Success!") - successfulCrew += "[crewMind.current.real_name] (Played by: [crewMind.key])
Objective: [CO.explanation_text] Success! (Optional)" - else - to_chat(crewMind.current, "
Your optional objective: [CO.explanation_text] Failed.") - - if (successfulCrew.len) - var/completedObjectives = "The following crew members completed their Crew Objectives:
" - for(var/i in successfulCrew) - completedObjectives += "[i]
" - to_chat(world, "[completedObjectives]
") - else - if(CONFIG_GET(flag/allow_crew_objectives)) - to_chat(world, "Nobody completed their Crew Objectives!
") - - CHECK_TICK - - if (miscreants.len) - var/miscreantObjectives = "The following crew members were miscreants:
" - for(var/i in miscreants) - miscreantObjectives += "[i]
" - to_chat(world, "[miscreantObjectives]
") - - CHECK_TICK - - mode.declare_station_goal_completion() - - CHECK_TICK - //medals, placed far down so that people can actually see the commendations. - if(GLOB.commendations.len) - to_chat(world, "Medal Commendations:") - for (var/com in GLOB.commendations) - to_chat(world, com) - - CHECK_TICK - - //Collects persistence features - if(mode.allow_persistence_save) - SSpersistence.CollectData() - - //stop collecting feedback during grifftime - SSblackbox.Seal() - - sleep(50) - if(mode.station_was_nuked) - Reboot("Station destroyed by Nuclear Device.", "nuke") - else - Reboot("Round ended.", "proper completion") - /datum/controller/subsystem/ticker/proc/send_tip_of_the_round() var/m if(selected_tip) diff --git a/code/controllers/subsystem/timer.dm b/code/controllers/subsystem/timer.dm index eca88d5126..3a2ca82bcd 100644 --- a/code/controllers/subsystem/timer.dm +++ b/code/controllers/subsystem/timer.dm @@ -357,6 +357,9 @@ SUBSYSTEM_DEF(timer) wait = max(wait, 0) + if(wait >= INFINITY) + CRASH("Attempted to create timer with INFINITY delay") + var/hash if (flags & TIMER_UNIQUE) diff --git a/code/controllers/subsystem/traumas.dm b/code/controllers/subsystem/traumas.dm new file mode 100644 index 0000000000..14f15a4b89 --- /dev/null +++ b/code/controllers/subsystem/traumas.dm @@ -0,0 +1,52 @@ +SUBSYSTEM_DEF(traumas) + name = "Traumas" + flags = SS_NO_FIRE + var/list/phobia_types + var/list/phobia_words + var/list/phobia_mobs + var/list/phobia_objs + var/list/phobia_turfs + var/list/phobia_species + +#define PHOBIA_FILE "phobia.json" + +/datum/controller/subsystem/traumas/Initialize() + phobia_types = list("spiders", "space", "security", "clowns", "greytide", "lizards", "skeletons") + + phobia_words = list("spiders" = strings(PHOBIA_FILE, "spiders"), + "space" = strings(PHOBIA_FILE, "space"), + "security" = strings(PHOBIA_FILE, "security"), + "clowns" = strings(PHOBIA_FILE, "clowns"), + "greytide" = strings(PHOBIA_FILE, "greytide"), + "lizards" = strings(PHOBIA_FILE, "lizards"), + "skeletons" = strings(PHOBIA_FILE, "skeletons"), + ) + + phobia_mobs = list("spiders" = typecacheof(list(/mob/living/simple_animal/hostile/poison/giant_spider)), + "security" = typecacheof(list(/mob/living/simple_animal/bot/secbot)), + "lizards" = typecacheof(list(/mob/living/simple_animal/hostile/lizard)) + ) + + phobia_objs = list("spiders" = typecacheof(list(/obj/structure/spider)), + "security" = typecacheof(list(/obj/item/clothing/under/rank/security, /obj/item/clothing/under/rank/warden, + /obj/item/clothing/under/rank/head_of_security, /obj/item/clothing/under/rank/det, + /obj/item/melee/baton, /obj/item/gun/energy/taser, /obj/item/restraints/handcuffs, + /obj/machinery/door/airlock/security)), + "clowns" = typecacheof(list(/obj/item/clothing/under/rank/clown, /obj/item/clothing/shoes/clown_shoes, + /obj/item/clothing/mask/gas/clown_hat, /obj/item/device/instrument/bikehorn, + /obj/item/device/pda/clown, /obj/item/grown/bananapeel)), + "greytide" = typecacheof(list(/obj/item/clothing/under/color/grey, /obj/item/melee/baton/cattleprod, + /obj/item/twohanded/spear, /obj/item/clothing/mask/gas)), + "lizards" = typecacheof(list(/obj/item/toy/plush/lizardplushie, /obj/item/reagent_containers/food/snacks/kebab/tail, + /obj/item/organ/tail/lizard, /obj/item/reagent_containers/food/drinks/bottle/lizardwine)), + "skeletons" = typecacheof(list(/obj/item/organ/tongue/bone, /obj/item/clothing/suit/armor/bone, /obj/item/stack/sheet/bone, + /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton, + /obj/effect/decal/remains/human)) + ) + phobia_turfs = list("space" = typecacheof(list(/turf/open/space, /turf/open/floor/holofloor/space, /turf/open/floor/fakespace))) + + phobia_species = list("lizards" = typecacheof(list(/datum/species/lizard)), + "skeletons" = typecacheof(list(/datum/species/skeleton, /datum/species/plasmaman)) + ) + +#undef PHOBIA_FILE diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 55624a866c..acb873dd5b 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -165,7 +165,7 @@ SUBSYSTEM_DEF(vote) var/admin = FALSE var/ckey = ckey(initiator_key) - if((GLOB.admin_datums[ckey]) || (ckey in GLOB.deadmins)) + if(GLOB.admin_datums[ckey]) admin = TRUE if(next_allowed_time > world.time && !admin) @@ -206,6 +206,7 @@ SUBSYSTEM_DEF(vote) var/datum/action/vote/V = new if(question) V.name = "Vote: [question]" + C.player_details.player_actions += V V.Grant(C.mob) generated_actions += V return 1 @@ -299,6 +300,7 @@ SUBSYSTEM_DEF(vote) for(var/v in generated_actions) var/datum/action/vote/V = v if(!QDELETED(V)) + V.remove_from_client() V.Remove(V.owner) generated_actions = list() @@ -318,7 +320,16 @@ SUBSYSTEM_DEF(vote) /datum/action/vote/Trigger() if(owner) owner.vote() + remove_from_client() Remove(owner) /datum/action/vote/IsAvailable() return 1 + +/datum/action/vote/proc/remove_from_client() + if(owner.client) + owner.client.player_details.player_actions -= src + else if(owner.ckey) + var/datum/player_details/P = GLOB.player_details[owner.ckey] + if(P) + P.player_actions -= src \ No newline at end of file diff --git a/code/controllers/subsystem/weather.dm b/code/controllers/subsystem/weather.dm index 2909d1c70a..dafd9d6fd0 100644 --- a/code/controllers/subsystem/weather.dm +++ b/code/controllers/subsystem/weather.dm @@ -41,5 +41,14 @@ SUBSYSTEM_DEF(weather) if(W.name == weather_name && W.target_z == Z) W.telegraph() +/datum/controller/subsystem/weather/proc/is_weather_affecting_area(area/A, weather_datum_type) + for(var/V in processing) + var/datum/weather/W = V + if(!istype(W, weather_datum_type)) + continue + if(A in W.impacted_areas) + return TRUE + return FALSE + /datum/controller/subsystem/weather/proc/make_z_eligible(zlevel) eligible_zlevels |= zlevel diff --git a/code/datums/action.dm b/code/datums/action.dm index 721d67044d..f941a00a54 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -43,10 +43,27 @@ return Remove(owner) owner = M + + //button id generation + var/counter = 0 + var/bitfield = 0 + for(var/datum/action/A in M.actions) + if(A.name == name && A.button.id) + counter += 1 + bitfield |= A.button.id + bitfield = ~bitfield + var/bitflag = 1 + for(var/i in 1 to (counter + 1)) + if(bitfield & bitflag) + button.id = bitflag + break + bitflag *= 2 + M.actions += src if(M.client) M.client.screen += button - button.locked = M.client.prefs.buttons_locked + button.locked = M.client.prefs.buttons_locked || button.id ? M.client.prefs.action_buttons_screen_locs["[name]_[button.id]"] : FALSE //even if it's not defaultly locked we should remember we locked it before + button.moved = button.id ? M.client.prefs.action_buttons_screen_locs["[name]_[button.id]"] : FALSE M.update_action_buttons() else Remove(owner) @@ -60,6 +77,7 @@ owner = null button.moved = FALSE //so the button appears in its normal position when given to another owner. button.locked = FALSE + button.id = null /datum/action/proc/Trigger() if(!IsAvailable()) diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm index 8d86507271..c12a08a792 100644 --- a/code/datums/ai_laws.dm +++ b/code/datums/ai_laws.dm @@ -373,32 +373,9 @@ ion = list() /datum/ai_laws/proc/show_laws(who) - - if (devillaws && devillaws.len) //Yes, devil laws go in FRONT of zeroth laws, as the devil must still obey it's ban/obligation. - for(var/i in devillaws) - to_chat(who, "666. [i]") - - if (zeroth) - to_chat(who, "0. [zeroth]") - - for (var/index = 1, index <= ion.len, index++) - var/law = ion[index] - var/num = ionnum() - to_chat(who, "[num]. [law]") - - var/number = 1 - for (var/index = 1, index <= inherent.len, index++) - var/law = inherent[index] - - if (length(law) > 0) - to_chat(who, "[number]. [law]") - number++ - - for (var/index = 1, index <= supplied.len, index++) - var/law = supplied[index] - if (length(law) > 0) - to_chat(who, "[number]. [law]") - number++ + var/list/printable_laws = get_law_list(include_zeroth = TRUE) + for(var/law in printable_laws) + to_chat(who,law) /datum/ai_laws/proc/clear_zeroth_law(force) //only removes zeroth from antag ai if force is 1 if(force) diff --git a/code/datums/antagonists/abductor.dm b/code/datums/antagonists/abductor.dm index 8d13c48e7c..a98acf054e 100644 --- a/code/datums/antagonists/abductor.dm +++ b/code/datums/antagonists/abductor.dm @@ -1,7 +1,8 @@ /datum/antagonist/abductor name = "Abductor" + roundend_category = "abductors" job_rank = ROLE_ABDUCTOR - var/datum/objective_team/abductor_team/team + var/datum/team/abductor_team/team var/sub_role var/outfit var/landmark_type @@ -19,7 +20,7 @@ landmark_type = /obj/effect/landmark/abductor/scientist greet_text = "Use your stealth technology and equipment to incapacitate humans for your scientist to retrieve." -/datum/antagonist/abductor/create_team(datum/objective_team/abductor_team/new_team) +/datum/antagonist/abductor/create_team(datum/team/abductor_team/new_team) if(!new_team) return if(!istype(new_team)) @@ -70,3 +71,65 @@ var/mob/living/carbon/human/H = owner.current var/datum/species/abductor/A = H.dna.species A.scientist = TRUE + + +/datum/team/abductor_team + member_name = "abductor" + var/team_number + var/list/datum/mind/abductees = list() + +/datum/team/abductor_team/is_solo() + return FALSE + +/datum/team/abductor_team/proc/add_objective(datum/objective/O) + O.team = src + O.update_explanation_text() + objectives += O + +/datum/team/abductor_team/roundend_report() + var/list/result = list() + + var/won = TRUE + for(var/datum/objective/O in objectives) + if(!O.check_completion()) + won = FALSE + if(won) + result += "[name] team fulfilled its mission!" + else + result += "[name] team failed its mission." + + result += "The abductors of [name] were:" + for(var/datum/mind/abductor_mind in members) + result += printplayer(abductor_mind) + result += printobjectives(abductor_mind) + + return result.Join("
") + + +/datum/antagonist/abductee + name = "Abductee" + roundend_category = "abductees" + +/datum/antagonist/abductee/on_gain() + give_objective() + . = ..() + +/datum/antagonist/abductee/greet() + to_chat(owner, "Your mind snaps!") + to_chat(owner, "You can't remember how you got here...") + owner.announce_objectives() + +/datum/antagonist/abductee/proc/give_objective() + var/mob/living/carbon/human/H = owner.current + if(istype(H)) + H.gain_trauma_type(BRAIN_TRAUMA_MILD) + var/objtype = (prob(75) ? /datum/objective/abductee/random : pick(subtypesof(/datum/objective/abductee/) - /datum/objective/abductee/random)) + var/datum/objective/abductee/O = new objtype() + objectives += O + owner.objectives += objectives + +/datum/antagonist/abductee/apply_innate_effects(mob/living/mob_override) + SSticker.mode.update_abductor_icons_added(mob_override ? mob_override.mind : owner) + +/datum/antagonist/abductee/remove_innate_effects(mob/living/mob_override) + SSticker.mode.update_abductor_icons_removed(mob_override ? mob_override.mind : owner) \ No newline at end of file diff --git a/code/datums/antagonists/antag_datum.dm b/code/datums/antagonists/antag_datum.dm index 0a7b2aa22f..9b5dbb6d75 100644 --- a/code/datums/antagonists/antag_datum.dm +++ b/code/datums/antagonists/antag_datum.dm @@ -2,6 +2,8 @@ GLOBAL_LIST_EMPTY(antagonists) /datum/antagonist var/name = "Antagonist" + var/roundend_category = "other antagonists" //Section of roundend report, datums with same category will be displayed together, also default header for the section + var/show_in_roundend = TRUE //Set to false to hide the antagonists from roundend report var/datum/mind/owner //Mind that owns this datum var/silent = FALSE //Silent will prevent the gain/lose texts to show var/can_coexist_with_others = TRUE //Whether or not the person will be able to have more than one datum @@ -9,6 +11,7 @@ GLOBAL_LIST_EMPTY(antagonists) var/delete_on_mind_deletion = TRUE var/job_rank var/replace_banned = TRUE //Should replace jobbaned player with ghosts if granted. + var/list/objectives = list() /datum/antagonist/New(datum/mind/new_owner) GLOB.antagonists += src @@ -46,7 +49,7 @@ GLOBAL_LIST_EMPTY(antagonists) return //Assign default team and creates one for one of a kind team antagonists -/datum/antagonist/proc/create_team(datum/objective_team/team) +/datum/antagonist/proc/create_team(datum/team/team) return //Proc called when the datum is given to a mind. @@ -81,7 +84,7 @@ GLOBAL_LIST_EMPTY(antagonists) LAZYREMOVE(owner.antag_datums, src) if(!silent && owner.current) farewell() - var/datum/objective_team/team = get_team() + var/datum/team/team = get_team() if(team) team.remove_member(owner) qdel(src) @@ -96,9 +99,62 @@ GLOBAL_LIST_EMPTY(antagonists) /datum/antagonist/proc/get_team() return +//Individual roundend report +/datum/antagonist/proc/roundend_report() + var/list/report = list() + + if(!owner) + CRASH("antagonist datum without owner") + + report += printplayer(owner) + + var/objectives_complete = TRUE + if(owner.objectives.len) + report += printobjectives(owner) + for(var/datum/objective/objective in owner.objectives) + if(!objective.check_completion()) + objectives_complete = FALSE + break + + if(owner.objectives.len == 0 || objectives_complete) + report += "The [name] was successful!" + else + report += "The [name] has failed!" + + return report.Join("
") + +//Displayed at the start of roundend_category section, default to roundend_category header +/datum/antagonist/proc/roundend_report_header() + return "The [roundend_category] were:
" + +//Displayed at the end of roundend_category section +/datum/antagonist/proc/roundend_report_footer() + return + //Should probably be on ticker or job ss ? /proc/get_antagonists(antag_type,specific = FALSE) . = list() for(var/datum/antagonist/A in GLOB.antagonists) if(!specific && istype(A,antag_type) || specific && A.type == antag_type) - . += A.owner \ No newline at end of file + . += A.owner + + + +//This datum will autofill the name with special_role +//Used as placeholder for minor antagonists, please create proper datums for these +/datum/antagonist/auto_custom + +/datum/antagonist/auto_custom/on_gain() + ..() + name = owner.special_role + //Add all objectives not already owned by other datums to this one. + var/list/already_registered_objectives = list() + for(var/datum/antagonist/A in owner.antag_datums) + if(A == src) + continue + else + already_registered_objectives |= A.objectives + objectives = owner.objectives - already_registered_objectives + +//This one is created by admin tools for custom objectives +/datum/antagonist/custom \ No newline at end of file diff --git a/code/datums/antagonists/brother.dm b/code/datums/antagonists/brother.dm index 6458e6da09..b06c75e4fa 100644 --- a/code/datums/antagonists/brother.dm +++ b/code/datums/antagonists/brother.dm @@ -2,12 +2,12 @@ name = "Brother" job_rank = ROLE_BROTHER var/special_role = "blood brother" - var/datum/objective_team/brother_team/team + var/datum/team/brother_team/team /datum/antagonist/brother/New(datum/mind/new_owner) return ..() -/datum/antagonist/brother/create_team(datum/objective_team/brother_team/new_team) +/datum/antagonist/brother/create_team(datum/team/brother_team/new_team) if(!new_team) return if(!istype(new_team)) @@ -55,3 +55,71 @@ /datum/antagonist/brother/proc/finalize_brother() SSticker.mode.update_brother_icons_added(owner) + + +/datum/team/brother_team + name = "brotherhood" + member_name = "blood brother" + var/meeting_area + +/datum/team/brother_team/is_solo() + return FALSE + +/datum/team/brother_team/proc/update_name() + var/list/last_names = list() + for(var/datum/mind/M in members) + var/list/split_name = splittext(M.name," ") + last_names += split_name[split_name.len] + + name = last_names.Join(" & ") + +/datum/team/brother_team/roundend_report() + var/list/parts = list() + + parts += "The blood brothers of [name] were:" + for(var/datum/mind/M in members) + parts += printplayer(M) + var/win = TRUE + var/objective_count = 1 + for(var/datum/objective/objective in objectives) + if(objective.check_completion()) + parts += "Objective #[objective_count]: [objective.explanation_text] Success!" + else + parts += "Objective #[objective_count]: [objective.explanation_text] Fail." + win = FALSE + objective_count++ + if(win) + parts += "The blood brothers were successful!" + else + parts += "The blood brothers have failed!" + + return "
[parts.Join("
")]
" + +/datum/team/brother_team/proc/add_objective(datum/objective/O, needs_target = FALSE) + O.team = src + if(needs_target) + O.find_target() + O.update_explanation_text() + objectives += O + +/datum/team/brother_team/proc/forge_brother_objectives() + objectives = list() + var/is_hijacker = prob(10) + 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) + add_objective(new/datum/objective/hijack) + else if(!locate(/datum/objective/escape) in objectives) + add_objective(new/datum/objective/escape) + +/datum/team/brother_team/proc/forge_single_objective() + if(prob(50)) + if(LAZYLEN(active_ais()) && prob(100/GLOB.joined_player_list.len)) + add_objective(new/datum/objective/destroy, TRUE) + else if(prob(30)) + add_objective(new/datum/objective/maroon, TRUE) + else + add_objective(new/datum/objective/assassinate, TRUE) + else + add_objective(new/datum/objective/steal, TRUE) \ No newline at end of file diff --git a/code/datums/antagonists/changeling.dm b/code/datums/antagonists/changeling.dm index e98bfed782..4f8af2dc8a 100644 --- a/code/datums/antagonists/changeling.dm +++ b/code/datums/antagonists/changeling.dm @@ -4,11 +4,11 @@ /datum/antagonist/changeling name = "Changeling" + roundend_category = "changelings" job_rank = ROLE_CHANGELING var/you_are_greet = TRUE var/give_objectives = TRUE - var/list/objectives = list() var/team_mode = FALSE //Should assign team objectives ? //Changeling Stuff @@ -478,4 +478,35 @@ /datum/antagonist/changeling/xenobio name = "Xenobio Changeling" give_objectives = FALSE + show_in_roundend = FALSE //These are here for admin tracking purposes only you_are_greet = FALSE + +/datum/antagonist/changeling/roundend_report() + var/list/parts = list() + + var/changelingwin = 1 + if(!owner.current) + changelingwin = 0 + + parts += printplayer(owner) + + //Removed sanity if(changeling) because we -want- a runtime to inform us that the changelings list is incorrect and needs to be fixed. + parts += "Changeling ID: [changelingID]." + parts += "Genomes Extracted: [absorbedcount]" + parts += " " + if(objectives.len) + var/count = 1 + for(var/datum/objective/objective in objectives) + if(objective.check_completion()) + parts += "Objective #[count]: [objective.explanation_text] Success!
" + else + parts += "Objective #[count]: [objective.explanation_text] Fail." + changelingwin = 0 + count++ + + if(changelingwin) + parts += "The changeling was successful!" + else + parts += "The changeling has failed." + + return parts.Join("
") \ No newline at end of file diff --git a/code/datums/antagonists/clockcult.dm b/code/datums/antagonists/clockcult.dm index 8cc1c9e9a7..48f9b53425 100644 --- a/code/datums/antagonists/clockcult.dm +++ b/code/datums/antagonists/clockcult.dm @@ -1,8 +1,11 @@ //CLOCKCULT PROOF OF CONCEPT /datum/antagonist/clockcult name = "Clock Cultist" - var/datum/action/innate/hierophant/hierophant_network = new() + roundend_category = "clock cultists" job_rank = ROLE_SERVANT_OF_RATVAR + var/datum/action/innate/hierophant/hierophant_network = new() + var/datum/team/clockcult/clock_team + var/make_team = TRUE //This should be only false for tutorial scarabs /datum/antagonist/clockcult/silent silent = TRUE @@ -11,6 +14,22 @@ qdel(hierophant_network) return ..() +/datum/antagonist/clockcult/get_team() + return clock_team + +/datum/antagonist/clockcult/create_team(datum/team/clockcult/new_team) + if(!new_team && make_team) + //TODO blah blah same as the others, allow multiple + for(var/datum/antagonist/clockcult/H in GLOB.antagonists) + if(H.clock_team) + clock_team = H.clock_team + return + clock_team = new /datum/team/clockcult + return + if(make_team && !istype(new_team)) + stack_trace("Wrong team type passed to [type] initialization.") + clock_team = new_team + /datum/antagonist/clockcult/can_be_owned(datum/mind/new_owner) . = ..() if(.) @@ -156,7 +175,7 @@ SSticker.mode.servants_of_ratvar -= owner SSticker.mode.update_servant_icons_removed(owner) if(!silent) - owner.current.visible_message("[owner] seems to have remembered their true allegiance!", ignored_mob = owner.current) + owner.current.visible_message("[owner] seems to have remembered their true allegiance!", ignored_mob = owner.current) to_chat(owner, "A cold, cold darkness flows through your mind, extinguishing the Justiciar's light and all of your memories as his servant.") owner.current.log_message("Has renounced the cult of Ratvar!", INDIVIDUAL_ATTACK_LOG) owner.wipe_memory() @@ -164,3 +183,35 @@ if(iscyborg(owner.current)) to_chat(owner.current, "Despite your freedom from Ratvar's influence, you are still irreparably damaged and no longer possess certain functions such as AI linking.") . = ..() + + +/datum/team/clockcult + name = "Clockcult" + var/list/objective + var/datum/mind/eminence + +/datum/team/clockcult/proc/check_clockwork_victory() + if(GLOB.clockwork_gateway_activated) + return TRUE + return FALSE + +/datum/team/clockcult/roundend_report() + var/list/parts = list() + + if(check_clockwork_victory()) + parts += "Ratvar's servants defended the Ark until its activation!" + else + parts += "The Ark was destroyed! Ratvar will rust away for all eternity!" + parts += " " + parts += "The servants' objective was: [CLOCKCULT_OBJECTIVE]." + parts += "Construction Value(CV) was: [GLOB.clockwork_construction_value]" + for(var/i in SSticker.scripture_states) + if(i != SCRIPTURE_DRIVER) + parts += "[i] scripture was: [SSticker.scripture_states[i] ? "UN":""]LOCKED" + if(eminence) + parts += "The Eminence was: [printplayer(eminence)]" + if(members.len) + parts += "Ratvar's servants were:" + parts += printplayerlist(members - eminence) + + return "
[parts.Join("
")]
" \ No newline at end of file diff --git a/code/datums/antagonists/cult.dm b/code/datums/antagonists/cult.dm index c26b0f8108..916123ddff 100644 --- a/code/datums/antagonists/cult.dm +++ b/code/datums/antagonists/cult.dm @@ -2,84 +2,103 @@ /datum/antagonist/cult name = "Cultist" + roundend_category = "cultists" var/datum/action/innate/cult/comm/communion = new var/datum/action/innate/cult/mastervote/vote = new job_rank = ROLE_CULTIST var/ignore_implant = FALSE + var/give_equipment = FALSE + + var/datum/team/cult/cult_team + +/datum/antagonist/cult/get_team() + return cult_team + +/datum/antagonist/cult/create_team(datum/team/cult/new_team) + if(!new_team) + //todo remove this and allow admin buttons to create more than one cult + for(var/datum/antagonist/cult/H in GLOB.antagonists) + if(H.cult_team) + cult_team = H.cult_team + return + cult_team = new /datum/team/cult + cult_team.setup_objectives() + return + if(!istype(new_team)) + stack_trace("Wrong team type passed to [type] initialization.") + cult_team = new_team + +/datum/antagonist/cult/proc/add_objectives() + objectives |= cult_team.objectives + owner.objectives |= objectives + +/datum/antagonist/cult/proc/remove_objectives() + owner.objectives -= objectives /datum/antagonist/cult/Destroy() QDEL_NULL(communion) QDEL_NULL(vote) return ..() -/datum/antagonist/cult/proc/add_objectives() - var/list/target_candidates = list() - for(var/mob/living/carbon/human/player in GLOB.player_list) - if(player.mind && !player.mind.has_antag_datum(ANTAG_DATUM_CULT) && !is_convertable_to_cult(player) && (player != owner) && player.stat != DEAD) - target_candidates += player.mind - if(target_candidates.len == 0) - message_admins("Cult Sacrifice: Could not find unconvertable target, checking for convertable target.") - for(var/mob/living/carbon/human/player in GLOB.player_list) - if(player.mind && !player.mind.has_antag_datum(ANTAG_DATUM_CULT) && (player != owner) && player.stat != DEAD) - target_candidates += player.mind - listclearnulls(target_candidates) - if(LAZYLEN(target_candidates)) - GLOB.sac_mind = pick(target_candidates) - if(!GLOB.sac_mind) - message_admins("Cult Sacrifice: ERROR - Null target chosen!") - else - var/datum/job/sacjob = SSjob.GetJob(GLOB.sac_mind.assigned_role) - var/datum/preferences/sacface = GLOB.sac_mind.current.client.prefs - var/icon/reshape = get_flat_human_icon(null, sacjob, sacface) - reshape.Shift(SOUTH, 4) - reshape.Shift(EAST, 1) - reshape.Crop(7,4,26,31) - reshape.Crop(-5,-3,26,30) - GLOB.sac_image = reshape - else - message_admins("Cult Sacrifice: Could not find unconvertable or convertable target. WELP!") - GLOB.sac_complete = TRUE - SSticker.mode.cult_objectives += "sacrifice" - if(!GLOB.summon_spots.len) - while(GLOB.summon_spots.len < SUMMON_POSSIBILITIES) - var/area/summon = pick(GLOB.sortedAreas - GLOB.summon_spots) - if(summon && (summon.z in GLOB.station_z_levels) && summon.valid_territory) - GLOB.summon_spots += summon - SSticker.mode.cult_objectives += "eldergod" - -/datum/antagonist/cult/proc/cult_memorization(datum/mind/cult_mind) - var/mob/living/current = cult_mind.current - for(var/obj_count = 1,obj_count <= SSticker.mode.cult_objectives.len,obj_count++) - var/explanation - switch(SSticker.mode.cult_objectives[obj_count]) - if("sacrifice") - if(GLOB.sac_mind) - explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role] via invoking a Sacrifice rune with them on it and three acolytes around it." - else - explanation = "The veil has already been weakened here, proceed to the final objective." - GLOB.sac_complete = TRUE - if("eldergod") - explanation = "Summon Nar-Sie by invoking the rune 'Summon Nar-Sie'. The summoning can only be accomplished in [english_list(GLOB.summon_spots)] - where the veil is weak enough for the ritual to begin." - if(!silent) - to_chat(current, "Objective #[obj_count]: [explanation]") - cult_mind.memory += "Objective #[obj_count]: [explanation]
" - /datum/antagonist/cult/can_be_owned(datum/mind/new_owner) . = ..() if(. && !ignore_implant) - . = is_convertable_to_cult(new_owner.current) + . = is_convertable_to_cult(new_owner.current,cult_team) + +/datum/antagonist/cult/greet() + to_chat(owner, "You are a member of the cult!") + owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/bloodcult.ogg', 100, FALSE, pressure_affected = FALSE)//subject to change + owner.announce_objectives() /datum/antagonist/cult/on_gain() . = ..() var/mob/living/current = owner.current - if(!LAZYLEN(SSticker.mode.cult_objectives)) - add_objectives() + add_objectives() + if(give_equipment) + equip_cultist() SSticker.mode.cult += owner // Only add after they've been given objectives - cult_memorization(owner) SSticker.mode.update_cult_icons_added(owner) current.log_message("Has been converted to the cult of Nar'Sie!", INDIVIDUAL_ATTACK_LOG) - if(GLOB.blood_target && GLOB.blood_target_image && current.client) - current.client.images += GLOB.blood_target_image + + if(cult_team.blood_target && cult_team.blood_target_image && current.client) + current.client.images += cult_team.blood_target_image + + +/datum/antagonist/cult/proc/equip_cultist(tome=FALSE) + var/mob/living/carbon/H = owner.current + if(!istype(H)) + return + if (owner.assigned_role == "Clown") + to_chat(owner, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.") + H.dna.remove_mutation(CLOWNMUT) + + if(tome) + . += cult_give_item(/obj/item/tome, H) + else + . += cult_give_item(/obj/item/paper/talisman/supply, H) + to_chat(owner, "These will help you start the cult on this station. Use them well, and remember - you are not the only one.") + + +/datum/antagonist/cult/proc/cult_give_item(obj/item/item_path, mob/living/carbon/human/mob) + var/list/slots = list( + "backpack" = slot_in_backpack, + "left pocket" = slot_l_store, + "right pocket" = slot_r_store + ) + + var/T = new item_path(mob) + var/item_name = initial(item_path.name) + var/where = mob.equip_in_one_of_slots(T, slots) + if(!where) + to_chat(mob, "Unfortunately, you weren't able to get a [item_name]. This is very bad and you should adminhelp immediately (press F1).") + return 0 + else + to_chat(mob, "You have a [item_name] in your [where].") + if(where == "backpack") + var/obj/item/storage/B = mob.back + B.orient2hud(mob) + B.show_to(mob) + return 1 /datum/antagonist/cult/apply_innate_effects(mob/living/mob_override) . = ..() @@ -89,7 +108,7 @@ current.faction |= "cult" current.grant_language(/datum/language/narsie) current.verbs += /mob/living/proc/cult_help - if(!GLOB.cult_mastered) + if(!cult_team.cult_mastered) vote.Grant(current) communion.Grant(current) current.throw_alert("bloodsense", /obj/screen/alert/bloodsense) @@ -107,6 +126,7 @@ current.clear_alert("bloodsense") /datum/antagonist/cult/on_removal() + remove_objectives() owner.wipe_memory() SSticker.mode.cult -= owner SSticker.mode.update_cult_icons_removed(owner) @@ -114,8 +134,8 @@ owner.current.visible_message("[owner.current] looks like [owner.current.p_they()] just reverted to their old faith!", ignored_mob = owner.current) to_chat(owner.current, "An unfamiliar white light flashes through your mind, cleansing the taint of the Geometer and all your memories as her servant.") owner.current.log_message("Has renounced the cult of Nar'Sie!", INDIVIDUAL_ATTACK_LOG) - if(GLOB.blood_target && GLOB.blood_target_image && owner.current.client) - owner.current.client.images -= GLOB.blood_target_image + if(cult_team.blood_target && cult_team.blood_target_image && owner.current.client) + owner.current.client.images -= cult_team.blood_target_image . = ..() /datum/antagonist/cult/master @@ -145,7 +165,7 @@ var/mob/living/current = owner.current if(mob_override) current = mob_override - if(!GLOB.reckoning_complete) + if(!cult_team.reckoning_complete) reckoning.Grant(current) bloodmark.Grant(current) throwing.Grant(current) @@ -162,3 +182,118 @@ throwing.Remove(current) current.update_action_buttons_icon() current.remove_status_effect(/datum/status_effect/cult_master) + +/datum/team/cult + name = "Cult" + + var/blood_target + var/image/blood_target_image + var/blood_target_reset_timer + + var/cult_vote_called = FALSE + var/cult_mastered = FALSE + var/reckoning_complete = FALSE + + +/datum/team/cult/proc/setup_objectives() + //SAC OBJECTIVE , todo: move this to objective internals + var/list/target_candidates = list() + var/datum/objective/sacrifice/sac_objective = new + sac_objective.team = src + + for(var/mob/living/carbon/human/player in GLOB.player_list) + if(player.mind && !player.mind.has_antag_datum(ANTAG_DATUM_CULT) && !is_convertable_to_cult(player) && player.stat != DEAD) + target_candidates += player.mind + + if(target_candidates.len == 0) + message_admins("Cult Sacrifice: Could not find unconvertable target, checking for convertable target.") + for(var/mob/living/carbon/human/player in GLOB.player_list) + if(player.mind && !player.mind.has_antag_datum(ANTAG_DATUM_CULT) && player.stat != DEAD) + target_candidates += player.mind + listclearnulls(target_candidates) + if(LAZYLEN(target_candidates)) + sac_objective.target = pick(target_candidates) + sac_objective.update_explanation_text() + + var/datum/job/sacjob = SSjob.GetJob(sac_objective.target.assigned_role) + var/datum/preferences/sacface = sac_objective.target.current.client.prefs + var/icon/reshape = get_flat_human_icon(null, sacjob, sacface) + reshape.Shift(SOUTH, 4) + reshape.Shift(EAST, 1) + reshape.Crop(7,4,26,31) + reshape.Crop(-5,-3,26,30) + sac_objective.sac_image = reshape + + objectives += sac_objective + else + message_admins("Cult Sacrifice: Could not find unconvertable or convertable target. WELP!") + + + //SUMMON OBJECTIVE + + var/datum/objective/eldergod/summon_objective = new() + summon_objective.team = src + objectives += summon_objective + +/datum/objective/sacrifice + var/sacced = FALSE + var/sac_image + +/datum/objective/sacrifice/check_completion() + return sacced || completed + +/datum/objective/sacrifice/update_explanation_text() + if(target && !sacced) + explanation_text = "Sacrifice [target], the [target.assigned_role] via invoking a Sacrifice rune with them on it and three acolytes around it." + else + explanation_text = "The veil has already been weakened here, proceed to the final objective." + +/datum/objective/eldergod + var/summoned = FALSE + var/list/summon_spots = list() + +/datum/objective/eldergod/New() + ..() + var/sanity = 0 + while(summon_spots.len < SUMMON_POSSIBILITIES && sanity < 100) + var/area/summon = pick(GLOB.sortedAreas - summon_spots) + if(summon && (summon.z in GLOB.station_z_levels) && summon.valid_territory) + summon_spots += summon + sanity++ + update_explanation_text() + +/datum/objective/eldergod/update_explanation_text() + explanation_text = "Summon Nar-Sie by invoking the rune 'Summon Nar-Sie'. The summoning can only be accomplished in [english_list(summon_spots)] - where the veil is weak enough for the ritual to begin." + +/datum/objective/eldergod/check_completion() + return summoned || completed + +/datum/team/cult/proc/check_cult_victory() + for(var/datum/objective/O in objectives) + if(!O.check_completion()) + return FALSE + return TRUE + +/datum/team/cult/roundend_report() + var/list/parts = list() + + if(check_cult_victory()) + parts += "The cult has succeeded! Nar-sie has snuffed out another torch in the void!" + else + parts += "The staff managed to stop the cult! Dark words and heresy are no match for Nanotrasen's finest!" + + if(objectives.len) + parts += "The cultists' objectives were:" + var/count = 1 + for(var/datum/objective/objective in objectives) + if(objective.check_completion()) + parts += "Objective #[count]: [objective.explanation_text] Success!" + else + parts += "Objective #[count]: [objective.explanation_text] Fail." + count++ + + if(members.len) + parts += "The cultists were:" + parts += printplayerlist(members) + + return "
[parts.Join("
")]
" \ No newline at end of file diff --git a/code/datums/antagonists/datum_traitor.dm b/code/datums/antagonists/datum_traitor.dm index d386c79c25..3ccdc7ddfb 100644 --- a/code/datums/antagonists/datum_traitor.dm +++ b/code/datums/antagonists/datum_traitor.dm @@ -1,5 +1,6 @@ /datum/antagonist/traitor name = "Traitor" + roundend_category = "traitors" job_rank = ROLE_TRAITOR var/should_specialise = FALSE //do we split into AI and human, set to true on inital assignment only var/ai_datum = ANTAG_DATUM_TRAITOR_AI @@ -8,7 +9,6 @@ var/employer = "The Syndicate" var/give_objectives = TRUE var/should_give_codewords = TRUE - var/list/objectives_given = list() /datum/antagonist/traitor/human var/should_equip = TRUE @@ -52,9 +52,9 @@ if(should_specialise) return ..()//we never did any of this anyway SSticker.mode.traitors -= owner - for(var/O in objectives_given) + for(var/O in objectives) owner.objectives -= O - objectives_given = list() + objectives = list() if(!silent && owner.current) to_chat(owner.current," You are no longer the [special_role]! ") owner.special_role = null @@ -71,11 +71,11 @@ /datum/antagonist/traitor/proc/add_objective(var/datum/objective/O) owner.objectives += O - objectives_given += O + objectives += O /datum/antagonist/traitor/proc/remove_objective(var/datum/objective/O) owner.objectives -= O - objectives_given -= O + objectives -= O /datum/antagonist/traitor/proc/forge_traitor_objectives() return @@ -294,3 +294,53 @@ where = "In your [equipped_slot]" to_chat(mob, "

[where] is a folder containing secret documents that another Syndicate group wants. We have set up a meeting with one of their agents on station to make an exchange. Exercise extreme caution as they cannot be trusted and may be hostile.
") +//TODO Collate +/datum/antagonist/traitor/roundend_report() + var/list/result = list() + + var/traitorwin = TRUE + + result += printplayer(owner) + + var/TC_uses = 0 + var/uplink_true = FALSE + var/purchases = "" + for(var/datum/component/uplink/H in GLOB.uplinks) + if(H && H.owner && H.owner == owner.key) + TC_uses += H.spent_telecrystals + uplink_true = TRUE + purchases += H.purchase_log.generate_render(FALSE) + + var/objectives_text = "" + if(objectives.len)//If the traitor had no objectives, don't need to process this. + var/count = 1 + for(var/datum/objective/objective in objectives) + if(objective.check_completion()) + objectives_text += "
Objective #[count]: [objective.explanation_text] Success!" + else + objectives_text += "
Objective #[count]: [objective.explanation_text] Fail." + traitorwin = FALSE + count++ + + if(uplink_true) + var/uplink_text = "(used [TC_uses] TC) [purchases]" + if(TC_uses==0 && traitorwin) + var/static/icon/badass = icon('icons/badass.dmi', "badass") + uplink_text += "[icon2html(badass, world)]" + result += uplink_text + + result += objectives_text + + var/special_role_text = lowertext(name) + + if(traitorwin) + result += "The [special_role_text] was successful!" + else + result += "The [special_role_text] has failed!" + SEND_SOUND(owner.current, 'sound/ambience/ambifailure.ogg') + + return result.Join("
") + +/datum/antagonist/traitor/roundend_report_footer() + return "
The code phrases were: [GLOB.syndicate_code_phrase]
\ + The code responses were: [GLOB.syndicate_code_response]
" \ No newline at end of file diff --git a/code/datums/antagonists/devil.dm b/code/datums/antagonists/devil.dm index 416a8f3752..97e0d8c18a 100644 --- a/code/datums/antagonists/devil.dm +++ b/code/datums/antagonists/devil.dm @@ -86,6 +86,7 @@ GLOBAL_LIST_INIT(devil_syllable, list("hal", "ve", "odr", "neit", "ci", "quon", GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master", ", the Lord of all things", ", Jr.")) /datum/antagonist/devil name = "Devil" + roundend_category = "devils" job_rank = ROLE_DEVIL //Don't delete upon mind destruction, otherwise soul re-selling will break. delete_on_mind_deletion = FALSE @@ -508,6 +509,35 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master", owner.RemoveSpell(S) .=..() +/datum/antagonist/devil/proc/printdevilinfo() + var/list/parts = list() + parts += "The devil's true name is: [truename]" + parts += "The devil's bans were:" + parts += "[GLOB.TAB][GLOB.lawlorify[LORE][ban]]" + parts += "[GLOB.TAB][GLOB.lawlorify[LORE][bane]]" + parts += "[GLOB.TAB][GLOB.lawlorify[LORE][obligation]]" + parts += "[GLOB.TAB][GLOB.lawlorify[LORE][banish]]" + return parts.Join("
") + +/datum/antagonist/devil/roundend_report() + var/list/parts = list() + parts += printplayer(owner) + parts += printdevilinfo() + parts += printobjectives(owner) + return parts.Join("
") + +/datum/antagonist/devil/roundend_report_footer() + //sintouched go here for now as a hack , TODO proper antag datum for these + var/list/parts = list() + if(SSticker.mode.sintouched.len) + parts += "The sintouched were:" + var/list/sintouchedUnique = uniqueList(SSticker.mode.sintouched) + for(var/S in sintouchedUnique) + var/datum/mind/sintouched_mind = S + parts += printplayer(sintouched_mind) + parts += printobjectives(sintouched_mind) + return parts.Join("
") + //A simple super light weight datum for the codex gigas. /datum/fakeDevil var/truename diff --git a/code/datums/antagonists/ninja.dm b/code/datums/antagonists/ninja.dm index ab4822dd79..8201cd879d 100644 --- a/code/datums/antagonists/ninja.dm +++ b/code/datums/antagonists/ninja.dm @@ -37,19 +37,20 @@ else if(M.assigned_role in GLOB.command_positions) possible_targets[M] = 1 //good-guy - var/list/objectives = list(1,2,3,4) - while(owner.objectives.len < quantity) - switch(pick_n_take(objectives)) + var/list/possible_objectives = list(1,2,3,4) + + while(objectives.len < quantity) + switch(pick_n_take(possible_objectives)) if(1) //research var/datum/objective/download/O = new /datum/objective/download() O.owner = owner O.gen_amount_goal() - owner.objectives += O + objectives += O if(2) //steal var/datum/objective/steal/special/O = new /datum/objective/steal/special() O.owner = owner - owner.objectives += O + objectives += O if(3) //protect/kill if(!possible_targets.len) continue @@ -63,13 +64,13 @@ O.owner = owner O.target = M O.explanation_text = "Slay \the [M.current.real_name], the [M.assigned_role]." - owner.objectives += O + objectives += O else //protect var/datum/objective/protect/O = new /datum/objective/protect() O.owner = owner O.target = M O.explanation_text = "Protect \the [M.current.real_name], the [M.assigned_role], from harm." - owner.objectives += O + objectives += O if(4) //debrain/capture if(!possible_targets.len) continue var/selected = rand(1,possible_targets.len) @@ -82,17 +83,17 @@ O.owner = owner O.target = M O.explanation_text = "Steal the brain of [M.current.real_name]." - owner.objectives += O + objectives += O else //capture var/datum/objective/capture/O = new /datum/objective/capture() O.owner = owner O.gen_amount_goal() - owner.objectives += O + objectives += O else break var/datum/objective/O = new /datum/objective/survive() O.owner = owner - owner.objectives += O + owner.objectives |= objectives /proc/remove_ninja(mob/living/L) diff --git a/code/datums/antagonists/nukeop.dm b/code/datums/antagonists/nukeop.dm new file mode 100644 index 0000000000..8b7fc7826f --- /dev/null +++ b/code/datums/antagonists/nukeop.dm @@ -0,0 +1,322 @@ +#define NUKE_RESULT_FLUKE 0 +#define NUKE_RESULT_NUKE_WIN 1 +#define NUKE_RESULT_CREW_WIN 2 +#define NUKE_RESULT_CREW_WIN_SYNDIES_DEAD 3 +#define NUKE_RESULT_DISK_LOST 4 +#define NUKE_RESULT_DISK_STOLEN 5 +#define NUKE_RESULT_NOSURVIVORS 6 +#define NUKE_RESULT_WRONG_STATION 7 +#define NUKE_RESULT_WRONG_STATION_DEAD 8 + +/datum/antagonist/nukeop + name = "Nuclear Operative" + roundend_category = "syndicate operatives" //just in case + job_rank = ROLE_OPERATIVE + var/datum/team/nuclear/nuke_team + var/always_new_team = FALSE //If not assigned a team by default ops will try to join existing ones, set this to TRUE to always create new team. + var/send_to_spawnpoint = TRUE //Should the user be moved to default spawnpoint. + var/nukeop_outfit = /datum/outfit/syndicate + +/datum/antagonist/nukeop/proc/update_synd_icons_added(mob/living/M) + var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS] + opshud.join_hud(M) + set_antag_hud(M, "synd") + +/datum/antagonist/nukeop/proc/update_synd_icons_removed(mob/living/M) + var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS] + opshud.leave_hud(M) + set_antag_hud(M, null) + +/datum/antagonist/nukeop/apply_innate_effects(mob/living/mob_override) + var/mob/living/M = mob_override || owner.current + update_synd_icons_added(M) + +/datum/antagonist/nukeop/remove_innate_effects(mob/living/mob_override) + var/mob/living/M = mob_override || owner.current + update_synd_icons_removed(M) + +/datum/antagonist/nukeop/proc/equip_op() + if(!ishuman(owner.current)) + return + var/mob/living/carbon/human/H = owner.current + + H.set_species(/datum/species/human) //Plasamen burn up otherwise, and lizards are vulnerable to asimov AIs + + H.equipOutfit(nukeop_outfit) + return TRUE + +/datum/antagonist/nukeop/greet() + owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/ops.ogg',100,0) + to_chat(owner, "You are a [nuke_team ? nuke_team.syndicate_name : "syndicate"] agent!") + owner.announce_objectives() + return + +/datum/antagonist/nukeop/on_gain() + give_alias() + forge_objectives() + . = ..() + equip_op() + memorize_code() + if(send_to_spawnpoint) + move_to_spawnpoint() + +/datum/antagonist/nukeop/get_team() + return nuke_team + +/datum/antagonist/nukeop/proc/assign_nuke() + if(nuke_team && !nuke_team.tracked_nuke) + nuke_team.memorized_code = random_nukecode() + var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list + if(nuke) + nuke_team.tracked_nuke = nuke + if(nuke.r_code == "ADMIN") + nuke.r_code = nuke_team.memorized_code + else //Already set by admins/something else? + nuke_team.memorized_code = nuke.r_code + else + stack_trace("Syndicate nuke not found during nuke team creation.") + nuke_team.memorized_code = null + +/datum/antagonist/nukeop/proc/give_alias() + if(nuke_team && nuke_team.syndicate_name) + var/number = 1 + number = nuke_team.members.Find(owner) + owner.current.real_name = "[nuke_team.syndicate_name] Operative #[number]" + +/datum/antagonist/nukeop/proc/memorize_code() + if(nuke_team && nuke_team.tracked_nuke && nuke_team.memorized_code) + owner.store_memory("[nuke_team.tracked_nuke] Code: [nuke_team.memorized_code]", 0, 0) + to_chat(owner, "The nuclear authorization code is: [nuke_team.memorized_code]") + else + to_chat(owner, "Unfortunately the syndicate was unable to provide you with nuclear authorization code.") + +/datum/antagonist/nukeop/proc/forge_objectives() + if(nuke_team) + owner.objectives |= nuke_team.objectives + +/datum/antagonist/nukeop/proc/move_to_spawnpoint() + var/team_number = 1 + if(nuke_team) + team_number = nuke_team.members.Find(owner) + owner.current.forceMove(GLOB.nukeop_start[((team_number - 1) % GLOB.nukeop_start.len) + 1]) + +/datum/antagonist/nukeop/leader/move_to_spawnpoint() + owner.current.forceMove(pick(GLOB.nukeop_leader_start)) + +/datum/antagonist/nukeop/create_team(datum/team/nuclear/new_team) + if(!new_team) + if(!always_new_team) + for(var/datum/antagonist/nukeop/N in GLOB.antagonists) + if(N.nuke_team) + nuke_team = N.nuke_team + return + nuke_team = new /datum/team/nuclear + nuke_team.update_objectives() + assign_nuke() //This is bit ugly + return + if(!istype(new_team)) + stack_trace("Wrong team type passed to [type] initialization.") + nuke_team = new_team + +/datum/antagonist/nukeop/leader + name = "Nuclear Operative Leader" + nukeop_outfit = /datum/outfit/syndicate/leader + always_new_team = TRUE + var/title + +/datum/antagonist/nukeop/leader/memorize_code() + ..() + if(nuke_team && nuke_team.memorized_code) + var/obj/item/paper/P = new + P.info = "The nuclear authorization code is: [nuke_team.memorized_code]" + P.name = "nuclear bomb code" + var/mob/living/carbon/human/H = owner.current + if(!istype(H)) + P.forceMove(get_turf(H)) + else + H.put_in_hands(P, TRUE) + H.update_icons() + +/datum/antagonist/nukeop/leader/give_alias() + title = pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord") + if(nuke_team && nuke_team.syndicate_name) + owner.current.real_name = "[nuke_team.syndicate_name] [title]" + else + owner.current.real_name = "Syndicate [title]" + +/datum/antagonist/nukeop/leader/greet() + owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/ops.ogg',100,0) + to_chat(owner, "You are the Syndicate [title] for this mission. You are responsible for the distribution of telecrystals and your ID is the only one who can open the launch bay doors.") + to_chat(owner, "If you feel you are not up to this task, give your ID to another operative.") + to_chat(owner, "In your hand you will find a special item capable of triggering a greater challenge for your team. Examine it carefully and consult with your fellow operatives before activating it.") + owner.announce_objectives() + addtimer(CALLBACK(src, .proc/nuketeam_name_assign), 1) + + +/datum/antagonist/nukeop/leader/proc/nuketeam_name_assign() + if(!nuke_team) + return + nuke_team.rename_team(ask_name()) + +/datum/team/nuclear/proc/rename_team(new_name) + syndicate_name = new_name + name = "[syndicate_name] Team" + for(var/I in members) + var/datum/mind/synd_mind = I + var/mob/living/carbon/human/H = synd_mind.current + if(!istype(H)) + continue + var/chosen_name = H.dna.species.random_name(H.gender,0,syndicate_name) + H.fully_replace_character_name(H.real_name,chosen_name) + +/datum/antagonist/nukeop/leader/proc/ask_name() + var/randomname = pick(GLOB.last_names) + var/newname = stripped_input(owner.current,"You are the nuke operative [title]. Please choose a last name for your family.", "Name change",randomname) + if (!newname) + newname = randomname + else + newname = reject_bad_name(newname) + if(!newname) + newname = randomname + + return capitalize(newname) + +/datum/antagonist/nukeop/lone + name = "Lone Operative" + always_new_team = TRUE + send_to_spawnpoint = FALSE //Handled by event + nukeop_outfit = /datum/outfit/syndicate/full + +/datum/antagonist/nukeop/lone/assign_nuke() + if(nuke_team && !nuke_team.tracked_nuke) + nuke_team.memorized_code = random_nukecode() + var/obj/machinery/nuclearbomb/selfdestruct/nuke = locate() in GLOB.nuke_list + if(nuke) + nuke_team.tracked_nuke = nuke + if(nuke.r_code == "ADMIN") + nuke.r_code = nuke_team.memorized_code + else //Already set by admins/something else? + nuke_team.memorized_code = nuke.r_code + else + stack_trace("Station self destruct ot found during lone op team creation.") + nuke_team.memorized_code = null + +/datum/team/nuclear + var/syndicate_name + var/obj/machinery/nuclearbomb/tracked_nuke + var/core_objective = /datum/objective/nuclear + var/memorized_code + +/datum/team/nuclear/New() + ..() + syndicate_name = syndicate_name() + +/datum/team/nuclear/proc/update_objectives() + if(core_objective) + var/datum/objective/O = new core_objective + O.team = src + objectives += O + +/datum/team/nuclear/proc/disk_rescued() + for(var/obj/item/disk/nuclear/D in GLOB.poi_list) + if(!D.onCentCom()) + return FALSE + return TRUE + +/datum/team/nuclear/proc/operatives_dead() + for(var/I in members) + var/datum/mind/operative_mind = I + if(ishuman(operative_mind.current) && (operative_mind.current.stat != DEAD)) + return FALSE + return TRUE + +/datum/team/nuclear/proc/syndies_escaped() + var/obj/docking_port/mobile/S = SSshuttle.getShuttle("syndicate") + return (S && (S.z == ZLEVEL_CENTCOM || S.z == ZLEVEL_TRANSIT)) + +/datum/team/nuclear/proc/get_result() + var/evacuation = SSshuttle.emergency.mode == SHUTTLE_ENDGAME + var/disk_rescued = disk_rescued() + var/syndies_didnt_escape = !syndies_escaped() + var/station_was_nuked = SSticker.mode.station_was_nuked + var/nuke_off_station = SSticker.mode.nuke_off_station + + if(nuke_off_station == NUKE_SYNDICATE_BASE) + return NUKE_RESULT_FLUKE + else if(!disk_rescued && station_was_nuked && !syndies_didnt_escape) + return NUKE_RESULT_NUKE_WIN + else if (!disk_rescued && station_was_nuked && syndies_didnt_escape) + return NUKE_RESULT_NOSURVIVORS + else if (!disk_rescued && !station_was_nuked && nuke_off_station && !syndies_didnt_escape) + return NUKE_RESULT_WRONG_STATION + else if (!disk_rescued && !station_was_nuked && nuke_off_station && syndies_didnt_escape) + return NUKE_RESULT_WRONG_STATION_DEAD + else if ((disk_rescued || evacuation) && operatives_dead()) + return NUKE_RESULT_CREW_WIN_SYNDIES_DEAD + else if (disk_rescued) + return NUKE_RESULT_CREW_WIN + else if (!disk_rescued && operatives_dead()) + return NUKE_RESULT_DISK_LOST + else if (!disk_rescued && evacuation) + return NUKE_RESULT_DISK_STOLEN + else + return //Undefined result + +/datum/team/nuclear/roundend_report() + var/list/parts = list() + parts += "[syndicate_name] Operatives:" + + switch(get_result()) + if(NUKE_RESULT_FLUKE) + parts += "Humiliating Syndicate Defeat" + parts += "The crew of [station_name()] gave [syndicate_name] operatives back their bomb! The syndicate base was destroyed! Next time, don't lose the nuke!" + if(NUKE_RESULT_NUKE_WIN) + parts += "Syndicate Major Victory!" + parts += "[syndicate_name] operatives have destroyed [station_name()]!" + if(NUKE_RESULT_NOSURVIVORS) + parts += "Total Annihilation" + parts += "[syndicate_name] operatives destroyed [station_name()] but did not leave the area in time and got caught in the explosion. Next time, don't lose the disk!" + if(NUKE_RESULT_WRONG_STATION) + parts += "Crew Minor Victory" + parts += "[syndicate_name] operatives secured the authentication disk but blew up something that wasn't [station_name()]. Next time, don't do that!" + if(NUKE_RESULT_WRONG_STATION_DEAD) + parts += "[syndicate_name] operatives have earned Darwin Award!" + parts += "[syndicate_name] operatives blew up something that wasn't [station_name()] and got caught in the explosion. Next time, don't do that!" + if(NUKE_RESULT_CREW_WIN_SYNDIES_DEAD) + parts += "Crew Major Victory!" + parts += "The Research Staff has saved the disk and killed the [syndicate_name] Operatives" + if(NUKE_RESULT_CREW_WIN) + parts += "Crew Major Victory" + parts += "The Research Staff has saved the disk and stopped the [syndicate_name] Operatives!" + if(NUKE_RESULT_DISK_LOST) + parts += "Neutral Victory!" + parts += "The Research Staff failed to secure the authentication disk but did manage to kill most of the [syndicate_name] Operatives!" + if(NUKE_RESULT_DISK_STOLEN) + parts += "Syndicate Minor Victory!" + parts += "[syndicate_name] operatives survived the assault but did not achieve the destruction of [station_name()]. Next time, don't lose the disk!" + else + parts += "Neutral Victory" + parts += "Mission aborted!" + + var/text = "
The syndicate operatives were:" + var/purchases = "" + var/TC_uses = 0 + for(var/I in members) + var/datum/mind/syndicate = I + for(var/U in GLOB.uplinks) + var/datum/component/uplink/H = U + if(H.owner == syndicate.key) + TC_uses += H.purchase_log.total_spent + if(H.purchase_log) + purchases += H.purchase_log.generate_render(show_key = FALSE) + else + stack_trace("WARNING: Nuke Op uplink with no purchase_log Owner: [H.owner]") + text += printplayerlist(members) + text += "
" + text += "(Syndicates used [TC_uses] TC) [purchases]" + if(TC_uses == 0 && SSticker.mode.station_was_nuked && !operatives_dead()) + text += "[icon2html('icons/badass.dmi', world, "badass")]" + + parts += text + + return "
[parts.Join("
")]
" diff --git a/code/datums/antagonists/pirate.dm b/code/datums/antagonists/pirate.dm index ad32e09151..9bf20a4bf5 100644 --- a/code/datums/antagonists/pirate.dm +++ b/code/datums/antagonists/pirate.dm @@ -1,7 +1,8 @@ /datum/antagonist/pirate name = "Space Pirate" job_rank = ROLE_TRAITOR - var/datum/objective_team/pirate/crew + roundend_category = "space pirates" + var/datum/team/pirate/crew /datum/antagonist/pirate/greet() to_chat(owner, "You are a Space Pirate!") @@ -11,15 +12,16 @@ /datum/antagonist/pirate/get_team() return crew -/datum/antagonist/pirate/create_team(datum/objective_team/pirate/new_team) +/datum/antagonist/pirate/create_team(datum/team/pirate/new_team) if(!new_team) for(var/datum/antagonist/pirate/P in GLOB.antagonists) if(P.crew) - new_team = P.crew + crew = P.crew + return if(!new_team) - crew = new /datum/objective_team/pirate + crew = new /datum/team/pirate crew.forge_objectives() - return + return if(!istype(new_team)) stack_trace("Wrong team type passed to [type] initialization.") crew = new_team @@ -34,11 +36,10 @@ owner.objectives -= crew.objectives . = ..() -/datum/objective_team/pirate +/datum/team/pirate name = "Pirate crew" - var/list/objectives = list() -/datum/objective_team/pirate/proc/forge_objectives() +/datum/team/pirate/proc/forge_objectives() var/datum/objective/loot/getbooty = new() getbooty.team = src getbooty.storage_area = locate(/area/shuttle/pirate/vault) in GLOB.sortedAreas @@ -84,11 +85,11 @@ GLOBAL_LIST_INIT(pirate_loot_cache, typecacheof(list( loot_table[lootname] = count else loot_table[lootname] += count - var/text = "" + var/list/loot_texts = list() for(var/key in loot_table) var/amount = loot_table[key] - text += "[amount] [key][amount > 1 ? "s":""], " - return text + loot_texts += "[amount] [key][amount > 1 ? "s":""]" + return loot_texts.Join(", ") /datum/objective/loot/proc/get_loot_value() if(!storage_area) @@ -104,32 +105,25 @@ GLOBAL_LIST_INIT(pirate_loot_cache, typecacheof(list( /datum/objective/loot/check_completion() return ..() || get_loot_value() >= target_value +/datum/team/pirate/roundend_report() + var/list/parts = list() -//These need removal ASAP as everything is converted to datum antags. -/datum/game_mode/proc/auto_declare_completion_pirates() - var/list/datum/mind/pirates = get_antagonists(/datum/antagonist/pirate) - var/datum/objective_team/pirate/crew - var/text = "" - if(pirates.len) - text += "
Space Pirates were:" - for(var/datum/mind/M in pirates) - text += printplayer(M) - if(!crew) - var/datum/antagonist/pirate/P = M.has_antag_datum(/datum/antagonist/pirate) - crew = P.crew - if(crew) - text += "
Loot stolen: " - var/datum/objective/loot/L = locate() in crew.objectives - text += L.loot_listing() - text += "
Total loot value : [L.get_loot_value()]/[L.target_value] credits" + parts += "Space Pirates were:" - var/all_dead = TRUE - for(var/datum/mind/M in crew.members) - if(considered_alive(M)) - all_dead = FALSE - break - if(L.check_completion() && !all_dead) - text += "
The pirate crew was successful!" - else - text += "
The pirate crew has failed." - to_chat(world, text) \ No newline at end of file + var/all_dead = TRUE + for(var/datum/mind/M in members) + if(considered_alive(M)) + all_dead = FALSE + parts += printplayerlist(members) + + parts += "Loot stolen: " + var/datum/objective/loot/L = locate() in objectives + parts += L.loot_listing() + parts += "Total loot value : [L.get_loot_value()]/[L.target_value] credits" + + if(L.check_completion() && !all_dead) + parts += "The pirate crew was successful!" + else + parts += "The pirate crew has failed." + + return "
[parts.Join("
")]
" \ No newline at end of file diff --git a/code/datums/antagonists/revolution.dm b/code/datums/antagonists/revolution.dm index fc501a55a7..3209b9221c 100644 --- a/code/datums/antagonists/revolution.dm +++ b/code/datums/antagonists/revolution.dm @@ -3,9 +3,10 @@ /datum/antagonist/rev name = "Revolutionary" + roundend_category = "revolutionaries" // if by some miracle revolutionaries without revolution happen job_rank = ROLE_REV var/hud_type = "rev" - var/datum/objective_team/revolution/rev_team + var/datum/team/revolution/rev_team /datum/antagonist/rev/can_be_owned(datum/mind/new_owner) . = ..() @@ -39,17 +40,17 @@ . = ..() /datum/antagonist/rev/greet() - to_chat(owner, " You are now a revolutionary! Help your cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them kill the heads to win the revolution!") + to_chat(owner, "You are now a revolutionary! Help your cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them kill the heads to win the revolution!") owner.announce_objectives() -/datum/antagonist/rev/create_team(datum/objective_team/revolution/new_team) +/datum/antagonist/rev/create_team(datum/team/revolution/new_team) if(!new_team) //For now only one revolution at a time for(var/datum/antagonist/rev/head/H in GLOB.antagonists) if(H.rev_team) rev_team = H.rev_team return - rev_team = new /datum/objective_team/revolution + rev_team = new /datum/team/revolution rev_team.update_objectives() rev_team.update_heads() return @@ -77,7 +78,7 @@ old_owner.add_antag_datum(new_revhead,old_team) new_revhead.silent = FALSE to_chat(old_owner, "You have proved your devotion to revolution! You are a head revolutionary now!") - + /datum/antagonist/rev/head name = "Head Revolutionary" @@ -131,14 +132,14 @@ old_owner.add_antag_datum(new_rev,old_team) new_rev.silent = FALSE to_chat(old_owner, "Revolution has been disappointed of your leader traits! You are a regular revolutionary now!") - + /datum/antagonist/rev/farewell() if(ishuman(owner.current)) - owner.current.visible_message("[owner.current] looks like they just remembered their real allegiance!", \ - "You are no longer a brainwashed revolutionary! Your memory is hazy from the time you were a rebel...the only thing you remember is the name of the one who brainwashed you...") + owner.current.visible_message("[owner.current] looks like they just remembered their real allegiance!", ignored_mob = owner.current) + to_chat(owner, "You are no longer a brainwashed revolutionary! Your memory is hazy from the time you were a rebel...the only thing you remember is the name of the one who brainwashed you...") else if(issilicon(owner.current)) - owner.current.visible_message("The frame beeps contentedly, purging the hostile memory engram from the MMI before initalizing it.", \ - "The frame's firmware detects and deletes your neural reprogramming! You remember nothing but the name of the one who flashed you.") + owner.current.visible_message("The frame beeps contentedly, purging the hostile memory engram from the MMI before initalizing it.", ignored_mob = owner.current) + to_chat(owner, "The frame's firmware detects and deletes your neural reprogramming! You remember nothing but the name of the one who flashed you.") /datum/antagonist/rev/proc/remove_revolutionary(borged, deconverter) log_attack("[owner.current] (Key: [key_name(owner.current)]) has been deconverted from the revolution by [deconverter] (Key: [key_name(deconverter)])!") @@ -163,7 +164,7 @@ if(remove_clumsy && owner.assigned_role == "Clown") to_chat(owner, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.") H.dna.remove_mutation(CLOWNMUT) - + if(give_flash) var/obj/item/device/assembly/flash/T = new(H) var/list/slots = list ( @@ -176,18 +177,17 @@ to_chat(H, "The Syndicate were unfortunately unable to get you a flash.") else to_chat(H, "The flash in your [where] will help you to persuade the crew to join your cause.") - + if(give_hud) var/obj/item/organ/cyberimp/eyes/hud/security/syndicate/S = new(H) S.Insert(H, special = FALSE, drop_if_replaced = FALSE) to_chat(H, "Your eyes have been implanted with a cybernetic security HUD which will help you keep track of who is mindshield-implanted, and therefore unable to be recruited.") -/datum/objective_team/revolution +/datum/team/revolution name = "Revolution" - var/list/objectives = list() var/max_headrevs = 3 -/datum/objective_team/revolution/proc/update_objectives(initial = FALSE) +/datum/team/revolution/proc/update_objectives(initial = FALSE) var/untracked_heads = SSjob.get_all_heads() for(var/datum/objective/mutiny/O in objectives) untracked_heads -= O.target @@ -199,16 +199,16 @@ objectives += new_target for(var/datum/mind/M in members) M.objectives |= objectives - + addtimer(CALLBACK(src,.proc/update_objectives),HEAD_UPDATE_PERIOD,TIMER_UNIQUE) -/datum/objective_team/revolution/proc/head_revolutionaries() +/datum/team/revolution/proc/head_revolutionaries() . = list() for(var/datum/mind/M in members) if(M.has_antag_datum(/datum/antagonist/rev/head)) . += M -/datum/objective_team/revolution/proc/update_heads() +/datum/team/revolution/proc/update_heads() if(SSticker.HasRoundStarted()) var/list/datum/mind/head_revolutionaries = head_revolutionaries() var/list/datum/mind/heads = SSjob.get_all_heads() @@ -227,3 +227,56 @@ rev.promote() addtimer(CALLBACK(src,.proc/update_heads),HEAD_UPDATE_PERIOD,TIMER_UNIQUE) + + +/datum/team/revolution/roundend_report() + if(!members.len) + return + + var/list/result = list() + + result += "
" + + var/num_revs = 0 + var/num_survivors = 0 + for(var/mob/living/carbon/survivor in GLOB.alive_mob_list) + if(survivor.ckey) + num_survivors++ + if(survivor.mind) + if(is_revolutionary(survivor)) + num_revs++ + if(num_survivors) + result += "Command's Approval Rating: [100 - round((num_revs/num_survivors)*100, 0.1)]%
" + + + var/list/targets = list() + var/list/datum/mind/headrevs = get_antagonists(/datum/antagonist/rev/head) + var/list/datum/mind/revs = get_antagonists(/datum/antagonist/rev,TRUE) + if(headrevs.len) + var/list/headrev_part = list() + headrev_part += "The head revolutionaries were:" + headrev_part += printplayerlist(headrevs,TRUE) + result += headrev_part.Join("
") + + if(revs.len) + var/list/rev_part = list() + rev_part += "The revolutionaries were:" + rev_part += printplayerlist(revs,TRUE) + result += rev_part.Join("
") + + var/list/heads = SSjob.get_all_heads() + if(heads.len) + var/head_text = "The heads of staff were:" + head_text += "
    " + for(var/datum/mind/head in heads) + var/target = (head in targets) + head_text += "
  • " + if(target) + head_text += "Target" + head_text += "[printplayer(head, 1)]
  • " + head_text += "

" + result += head_text + + result += "
" + + return result.Join() \ No newline at end of file diff --git a/code/datums/antagonists/wizard.dm b/code/datums/antagonists/wizard.dm index 740e7e156e..e856a6642f 100644 --- a/code/datums/antagonists/wizard.dm +++ b/code/datums/antagonists/wizard.dm @@ -5,13 +5,13 @@ /datum/antagonist/wizard name = "Space Wizard" + roundend_category = "wizards/witches" job_rank = ROLE_WIZARD var/give_objectives = TRUE var/strip = TRUE //strip before equipping var/allow_rename = TRUE var/hud_version = "wizard" - var/datum/objective_team/wizard/wiz_team //Only created if wizard summons apprentices - var/list/objectives = list() //this should be base datum antag proc and list, todo make lazy + var/datum/team/wizard/wiz_team //Only created if wizard summons apprentices var/move_to_lair = TRUE var/outfit_type = /datum/outfit/wizard var/wiz_age = WIZARD_AGE_MIN /* Wizards by nature cannot be too young. */ @@ -33,7 +33,7 @@ /datum/antagonist/wizard/proc/unregister() SSticker.mode.wizards -= src -/datum/antagonist/wizard/create_team(datum/objective_team/wizard/new_team) +/datum/antagonist/wizard/create_team(datum/team/wizard/new_team) if(!new_team) return if(!istype(new_team)) @@ -43,12 +43,14 @@ /datum/antagonist/wizard/get_team() return wiz_team -/datum/objective_team/wizard +/datum/team/wizard name = "wizard team" + var/datum/antagonist/wizard/master_wizard /datum/antagonist/wizard/proc/create_wiz_team() wiz_team = new(owner) wiz_team.name = "[owner.current.real_name] team" + wiz_team.master_wizard = src update_wiz_icons_added(owner.current) /datum/antagonist/wizard/proc/send_to_lair() @@ -71,7 +73,7 @@ var/datum/objective/escape/escape_objective = new escape_objective.owner = owner objectives += escape_objective - + if(31 to 60) var/datum/objective/steal/steal_objective = new steal_objective.owner = owner @@ -103,8 +105,8 @@ if (!(locate(/datum/objective/hijack) in owner.objectives)) var/datum/objective/hijack/hijack_objective = new hijack_objective.owner = owner - objectives += hijack_objective - + objectives += hijack_objective + for(var/datum/objective/O in objectives) owner.objectives += O @@ -128,7 +130,7 @@ if(H.age < wiz_age) H.age = wiz_age H.equipOutfit(outfit_type) - + /datum/antagonist/wizard/greet() to_chat(owner, "You are the Space Wizard!") to_chat(owner, "The Space Wizards Federation has given you the following tasks:") @@ -204,11 +206,11 @@ owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/forcewall(null)) H.put_in_hands(new /obj/item/gun/magic/staff/healing(H)) to_chat(owner, "Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned livesaving survival spells. You are able to cast charge and forcewall.") - if(APPRENTICE_HEALING) + if(APPRENTICE_ROBELESS) owner.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/knock(null)) owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/mind_transfer(null)) to_chat(owner, "Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned stealthy, robeless spells. You are able to cast knock and mindswap.") - + /datum/antagonist/wizard/apprentice/create_objectives() var/datum/objective/protect/new_objective = new /datum/objective/protect new_objective.owner = owner @@ -221,6 +223,7 @@ /datum/antagonist/wizard/apprentice/imposter name = "Wizard Imposter" allow_rename = FALSE + move_to_lair = FALSE /datum/antagonist/wizard/apprentice/imposter/greet() to_chat(owner, "You are an imposter! Trick and confuse the crew to misdirect malice from your handsome original!") @@ -266,7 +269,7 @@ /datum/antagonist/wizard/academy/equip_wizard() . = ..() - + owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt) owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile) owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball) @@ -274,7 +277,7 @@ var/mob/living/M = owner.current if(!istype(M)) return - + var/obj/item/implant/exile/Implant = new/obj/item/implant/exile(M) Implant.implant(M) @@ -282,4 +285,46 @@ var/datum/objective/new_objective = new("Protect Wizard Academy from the intruders") new_objective.owner = owner owner.objectives += new_objective - objectives += new_objective \ No newline at end of file + objectives += new_objective + +//Solo wizard report +/datum/antagonist/wizard/roundend_report() + var/list/parts = list() + + parts += printplayer(owner) + + var/count = 1 + var/wizardwin = 1 + for(var/datum/objective/objective in objectives) + if(objective.check_completion()) + parts += "Objective #[count]: [objective.explanation_text] Success!" + else + parts += "Objective #[count]: [objective.explanation_text] Fail." + wizardwin = 0 + count++ + + if(wizardwin) + parts += "The wizard was successful!" + else + parts += "The wizard has failed!" + + if(owner.spell_list.len>0) + parts += "[owner.name] used the following spells: " + var/list/spell_names = list() + for(var/obj/effect/proc_holder/spell/S in owner.spell_list) + spell_names += S.name + parts += spell_names.Join(", ") + + return parts.Join("
") + +//Wizard with apprentices report +/datum/team/wizard/roundend_report() + var/list/parts = list() + + parts += "Wizards/witches of [master_wizard.owner.name] team were:" + parts += master_wizard.roundend_report() + parts += " " + parts += "[master_wizard.owner.name] apprentices were:" + parts += printplayerlist(members - master_wizard.owner) + + return "
[parts.Join("
")]
" \ No newline at end of file diff --git a/code/datums/beam.dm b/code/datums/beam.dm index 252a305af2..dc68de933a 100644 --- a/code/datums/beam.dm +++ b/code/datums/beam.dm @@ -29,7 +29,8 @@ icon = beam_icon icon_state = beam_icon_state beam_type = btype - addtimer(CALLBACK(src,.proc/End), time) + if(time < INFINITY) + addtimer(CALLBACK(src,.proc/End), time) /datum/beam/proc/Start() Draw() @@ -127,11 +128,11 @@ //Position the effect so the beam is one continous line var/a if(abs(Pixel_x)>32) - a = Pixel_x > 0 ? round(Pixel_x/32) : Ceiling(Pixel_x/32) + a = Pixel_x > 0 ? round(Pixel_x/32) : CEILING(Pixel_x/32, 1) X.x += a Pixel_x %= 32 if(abs(Pixel_y)>32) - a = Pixel_y > 0 ? round(Pixel_y/32) : Ceiling(Pixel_y/32) + a = Pixel_y > 0 ? round(Pixel_y/32) : CEILING(Pixel_y/32, 1) X.y += a Pixel_y %= 32 diff --git a/code/datums/brain_damage/brain_trauma.dm b/code/datums/brain_damage/brain_trauma.dm new file mode 100644 index 0000000000..53b0fbe056 --- /dev/null +++ b/code/datums/brain_damage/brain_trauma.dm @@ -0,0 +1,49 @@ +//Brain Traumas are the new actual brain damage. Brain damage itself acts as a way to acquire traumas: every time brain damage is dealt, there's a chance of receiving a trauma. +//This chance gets higher the higher the mob's brainloss is. Removing traumas is a separate thing from removing brain damage: you can get restored to full brain operativity, +//but keep the quirks, until repaired by mannitol (for mild/special ones) or brain surgery (for severe ones). +/datum/brain_trauma + var/name = "Brain Trauma" + var/desc = "A trauma caused by brain damage, which causes issues to the patient." + var/scan_desc = "a generic brain trauma" //description when detected by a health scanner + var/mob/living/carbon/owner //the poor bastard + var/obj/item/organ/brain/brain //the poor bastard's brain + var/gain_text = "You feel traumatized." + var/lose_text = "You no longer feel traumatized." + var/can_gain = TRUE //can this be gained through random traumas? + var/permanent = FALSE //can this be cured? + +/datum/brain_trauma/New(obj/item/organ/brain/B, _permanent) + brain = B + owner = B.owner + permanent = _permanent + if(owner) + on_gain() + +/datum/brain_trauma/Destroy() + brain.traumas -= src + if(owner) + on_lose() + brain = null + owner = null + return ..() + +//Called on life ticks +/datum/brain_trauma/proc/on_life() + return + +//Called when given to a mob +/datum/brain_trauma/proc/on_gain() + to_chat(owner, gain_text) + +//Called when removed from a mob +/datum/brain_trauma/proc/on_lose(silent) + if(!silent) + to_chat(owner, lose_text) + +//Called when hearing a spoken message +/datum/brain_trauma/proc/on_hear(message, speaker, message_language, raw_message, radio_freq) + return message + +//Called when speaking +/datum/brain_trauma/proc/on_say(message) + return message diff --git a/code/datums/brain_damage/imaginary_friend.dm b/code/datums/brain_damage/imaginary_friend.dm new file mode 100644 index 0000000000..ea01a87506 --- /dev/null +++ b/code/datums/brain_damage/imaginary_friend.dm @@ -0,0 +1,157 @@ +/datum/brain_trauma/special/imaginary_friend + name = "Imaginary Friend" + desc = "Patient can see and hear an imaginary person." + scan_desc = "partial schizophrenia" + gain_text = "You feel in good company, for some reason." + lose_text = "You feel lonely again." + var/mob/camera/imaginary_friend/friend + var/friend_initialized = FALSE + +/datum/brain_trauma/special/imaginary_friend/on_gain() + ..() + make_friend() + get_ghost() + +/datum/brain_trauma/special/imaginary_friend/on_life() + if(get_dist(owner, friend) > 9) + friend.yank() + if(!friend) + qdel(src) + return + if(!friend.client && friend_initialized) + addtimer(CALLBACK(src, .proc/reroll_friend), 600) + +/datum/brain_trauma/special/imaginary_friend/on_lose() + ..() + QDEL_NULL(friend) + +//If the friend goes afk, make a brand new friend. Plenty of fish in the sea of imagination. +/datum/brain_trauma/special/imaginary_friend/proc/reroll_friend() + if(friend.client) //reconnected + return + friend_initialized = FALSE + QDEL_NULL(friend) + make_friend() + get_ghost() + +/datum/brain_trauma/special/imaginary_friend/proc/make_friend() + friend = new(get_turf(src), src) + +/datum/brain_trauma/special/imaginary_friend/proc/get_ghost() + set waitfor = FALSE + var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner]'s imaginary friend?", ROLE_PAI, null, null, 75, friend) + if(LAZYLEN(candidates)) + var/client/C = pick(candidates) + friend.key = C.key + friend_initialized = TRUE + else + qdel(src) + +/mob/camera/imaginary_friend + name = "imaginary friend" + real_name = "imaginary friend" + move_on_shuttle = TRUE + desc = "A wonderful yet fake friend." + see_in_dark = 0 + lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE + sight = NONE + see_invisible = SEE_INVISIBLE_LIVING + var/icon/human_image + var/image/current_image + var/mob/living/carbon/owner + var/datum/brain_trauma/special/imaginary_friend/trauma + +/mob/camera/imaginary_friend/Login() + ..() + to_chat(src, "You are the imaginary friend of [owner]!") + to_chat(src, "You are absolutely loyal to your friend, no matter what.") + to_chat(src, "You cannot directly influence the world around you, but you can see what [owner] cannot.") + +/mob/camera/imaginary_friend/Initialize(mapload, _trauma) + . = ..() + var/gender = pick(MALE, FEMALE) + real_name = random_unique_name(gender) + name = real_name + trauma = _trauma + owner = trauma.owner + human_image = get_flat_human_icon(null, pick(SSjob.occupations)) + Show() + +/mob/camera/imaginary_friend/proc/Show() + if(!client) //nobody home + return + + //Remove old image from owner and friend + if(owner.client) + owner.client.images.Remove(current_image) + + client.images.Remove(current_image) + + //Generate image from the static icon and the current dir + current_image = image(human_image, src, , MOB_LAYER, dir=src.dir) + current_image.override = TRUE + current_image.name = name + + //Add new image to owner and friend + if(owner.client) + owner.client.images |= current_image + + client.images |= current_image + +/mob/camera/imaginary_friend/Destroy() + if(owner.client) + owner.client.images.Remove(human_image) + if(client) + client.images.Remove(human_image) + return ..() + +/mob/camera/imaginary_friend/proc/yank() + if(!client) //don't bother if the friend is braindead + return + forceMove(get_turf(owner)) + Show() + +/mob/camera/imaginary_friend/say(message) + if (!message) + return + + if (src.client) + if(client.prefs.muted & MUTE_IC) + to_chat(src, "You cannot send IC messages (muted).") + return + if (src.client.handle_spam_prevention(message,MUTE_IC)) + return + + friend_talk(message) + +/mob/camera/imaginary_friend/proc/friend_talk(message) + message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) + + if(!message) + return + + log_talk(src,"[key_name(src)] : [message]",LOGSAY) + + var/rendered = "[name] [say_quote(message)]" + var/dead_rendered = "[name] (Imaginary friend of [owner]) [say_quote(message)]" + + to_chat(owner, "[rendered]") + to_chat(src, "[rendered]") + + for(var/mob/M in GLOB.dead_mob_list) + var/link = FOLLOW_LINK(M, owner) + to_chat(M, "[link] [dead_rendered]") + +/mob/camera/imaginary_friend/emote(act,m_type=1,message = null) + return + +/mob/camera/imaginary_friend/forceMove(atom/destination) + dir = get_dir(get_turf(src), destination) + loc = destination + if(get_dist(src, owner) > 9) + yank() + return + Show() + +/mob/camera/imaginary_friend/movement_delay() + return 2 diff --git a/code/datums/brain_damage/mild.dm b/code/datums/brain_damage/mild.dm new file mode 100644 index 0000000000..7c2ba20a62 --- /dev/null +++ b/code/datums/brain_damage/mild.dm @@ -0,0 +1,214 @@ +//Mild traumas are the most common; they are generally minor annoyances. +//They can be cured with mannitol and patience, although brain surgery still works. +//Most of the old brain damage effects have been transferred to the dumbness trauma. + +/datum/brain_trauma/mild + +/datum/brain_trauma/mild/hallucinations + name = "Hallucinations" + desc = "Patient suffers constant hallucinations." + scan_desc = "schizophrenia" + gain_text = "You feel your grip on reality slipping..." + lose_text = "You feel more grounded." + +/datum/brain_trauma/mild/hallucinations/on_life() + owner.hallucination = min(owner.hallucination + 10, 50) + ..() + +/datum/brain_trauma/mild/hallucinations/on_lose() + owner.hallucination = 0 + ..() + +/datum/brain_trauma/mild/stuttering + name = "Stuttering" + desc = "Patient can't speak properly." + scan_desc = "reduced mouth coordination" + gain_text = "Speaking clearly is getting harder." + lose_text = "You feel in control of your speech." + +/datum/brain_trauma/mild/stuttering/on_life() + owner.stuttering = min(owner.stuttering + 5, 25) + ..() + +/datum/brain_trauma/mild/stuttering/on_lose() + owner.stuttering = 0 + ..() + +/datum/brain_trauma/mild/dumbness + name = "Dumbness" + desc = "Patient has reduced brain activity, making them less intelligent." + scan_desc = "reduced brain activity" + gain_text = "You feel dumber." + lose_text = "You feel smart again." + +/datum/brain_trauma/mild/dumbness/on_gain() + owner.disabilities |= DUMB + ..() + +/datum/brain_trauma/mild/dumbness/on_life() + owner.derpspeech = min(owner.derpspeech + 5, 25) + if(prob(3)) + owner.emote("drool") + else if(owner.stat == CONSCIOUS && prob(3)) + owner.say(pick_list_replacements(BRAIN_DAMAGE_FILE, "brain_damage")) + ..() + +/datum/brain_trauma/mild/dumbness/on_lose() + owner.disabilities &= ~DUMB + owner.derpspeech = 0 + ..() + +/datum/brain_trauma/mild/speech_impediment + name = "Speech Impediment" + desc = "Patient is unable to form coherent sentences." + scan_desc = "communication disorder" + gain_text = "" //mutation will handle the text + lose_text = "" + +/datum/brain_trauma/mild/speech_impediment/on_gain() + owner.dna.add_mutation(UNINTELLIGIBLE) + ..() + +//no fiddling with genetics to get out of this one +/datum/brain_trauma/mild/speech_impediment/on_life() + if(!(GLOB.mutations_list[UNINTELLIGIBLE] in owner.dna.mutations)) + on_gain() + ..() + +/datum/brain_trauma/mild/speech_impediment/on_lose() + owner.dna.remove_mutation(UNINTELLIGIBLE) + ..() + +/datum/brain_trauma/mild/concussion + name = "Concussion" + desc = "Patient's brain is concussed." + scan_desc = "a concussion" + gain_text = "Your head hurts!" + lose_text = "The pressure inside your head starts fading." + +/datum/brain_trauma/mild/concussion/on_life() + if(prob(5)) + switch(rand(1,11)) + if(1) + owner.vomit() + if(2,3) + owner.dizziness += 10 + if(4,5) + owner.confused += 10 + owner.blur_eyes(10) + if(6 to 9) + owner.slurring += 30 + if(10) + to_chat(owner, "You forget for a moment what you were doing.") + owner.Stun(20) + if(11) + to_chat(owner, "You faint.") + owner.Unconscious(80) + + ..() + +/datum/brain_trauma/mild/healthy + name = "Anosognosia" + desc = "Patient always feels healthy, regardless of their condition." + scan_desc = "self-awareness deficit" + gain_text = "You feel great!" + lose_text = "You no longer feel perfectly healthy." + +/datum/brain_trauma/mild/healthy/on_gain() + owner.set_screwyhud(SCREWYHUD_HEALTHY) + ..() + +/datum/brain_trauma/mild/healthy/on_life() + owner.set_screwyhud(SCREWYHUD_HEALTHY) //just in case of hallucinations + owner.adjustStaminaLoss(-5) //no pain, no fatigue + ..() + +/datum/brain_trauma/mild/healthy/on_lose() + owner.set_screwyhud(SCREWYHUD_NONE) + ..() + +/datum/brain_trauma/mild/muscle_weakness + name = "Muscle Weakness" + desc = "Patient experiences occasional bouts of muscle weakness." + scan_desc = "weak motor nerve signal" + gain_text = "Your muscles feel oddly faint." + lose_text = "You feel in control of your muscles again." + +/datum/brain_trauma/mild/muscle_weakness/on_life() + var/fall_chance = 1 + if(owner.m_intent == MOVE_INTENT_RUN) + fall_chance += 2 + if(prob(fall_chance) && !owner.lying && !owner.buckled) + to_chat(owner, "Your leg gives out!") + owner.Knockdown(35) + + else if(owner.get_active_held_item()) + var/drop_chance = 1 + var/obj/item/I = owner.get_active_held_item() + drop_chance += I.w_class + if(prob(drop_chance) && owner.dropItemToGround(I)) + to_chat(owner, "You drop [I]!") + + else if(prob(3)) + to_chat(owner, "You feel a sudden weakness in your muscles!") + owner.adjustStaminaLoss(50) + ..() + +/datum/brain_trauma/mild/muscle_spasms + name = "Muscle Spasms" + desc = "Patient has occasional muscle spasms, causing them to move unintentionally." + scan_desc = "nervous fits" + gain_text = "Your muscles feel oddly faint." + lose_text = "You feel in control of your muscles again." + +/datum/brain_trauma/mild/muscle_spasms/on_life() + if(prob(7)) + switch(rand(1,5)) + if(1) + if(owner.canmove && !isspaceturf(owner.loc)) + to_chat(owner, "Your leg spasms!") + step(owner, pick(GLOB.cardinals)) + if(2) + if(owner.incapacitated()) + return + var/obj/item/I = owner.get_active_held_item() + if(I) + to_chat(owner, "Your fingers spasm!") + log_attack("[key_name(owner)] used [I] due to a Muscle Spasm.") + I.attack_self(owner) + if(3) + var/prev_intent = owner.a_intent + owner.a_intent = INTENT_HARM + + var/range = 1 + if(istype(owner.get_active_held_item(), /obj/item/gun)) //get targets to shoot at + range = 7 + + var/list/mob/living/targets = list() + for(var/mob/M in oview(owner, range)) + if(isliving(M)) + targets += M + if(LAZYLEN(targets)) + to_chat(owner, "Your arm spasms!") + log_attack("[key_name(owner)] attacked someone due to a Muscle Spasm.") //the following attack will log itself + owner.ClickOn(pick(targets)) + owner.a_intent = prev_intent + if(4) + var/prev_intent = owner.a_intent + owner.a_intent = INTENT_HARM + to_chat(owner, "Your arm spasms!") + log_attack("[key_name(owner)] attacked himself to a Muscle Spasm.") + owner.ClickOn(owner) + owner.a_intent = prev_intent + if(5) + if(owner.incapacitated()) + return + var/obj/item/I = owner.get_active_held_item() + var/list/turf/targets = list() + for(var/turf/T in oview(owner, 3)) + targets += T + if(LAZYLEN(targets) && I) + to_chat(owner, "Your arm spasms!") + log_attack("[key_name(owner)] threw [I] due to a Muscle Spasm.") + owner.throw_item(pick(targets)) + ..() \ No newline at end of file diff --git a/code/datums/brain_damage/phobia.dm b/code/datums/brain_damage/phobia.dm new file mode 100644 index 0000000000..313b693436 --- /dev/null +++ b/code/datums/brain_damage/phobia.dm @@ -0,0 +1,115 @@ +/datum/brain_trauma/mild/phobia + name = "Phobia" + desc = "Patient is unreasonably afraid of something." + scan_desc = "phobia" + gain_text = "" + lose_text = "" + var/phobia_type + var/next_check = 0 + var/next_scare = 0 + var/list/trigger_words + //instead of cycling every atom, only cycle the relevant types + var/list/trigger_mobs + var/list/trigger_objs //also checked in mob equipment + var/list/trigger_turfs + var/list/trigger_species + +/datum/brain_trauma/mild/phobia/New(mob/living/carbon/C, _permanent, specific_type) + phobia_type = specific_type + if(!phobia_type) + phobia_type = pick(SStraumas.phobia_types) + + gain_text = "You start finding [phobia_type] very unnerving..." + lose_text = "You no longer feel afraid of [phobia_type]." + scan_desc += " of [phobia_type]" + trigger_words = SStraumas.phobia_words[phobia_type] + trigger_mobs = SStraumas.phobia_mobs[phobia_type] + trigger_objs = SStraumas.phobia_objs[phobia_type] + trigger_turfs = SStraumas.phobia_turfs[phobia_type] + trigger_species = SStraumas.phobia_species[phobia_type] + ..() + +/datum/brain_trauma/mild/phobia/on_life() + ..() + if(owner.eye_blind) + return + if(world.time > next_check && world.time > next_scare) + next_check = world.time + 50 + var/list/seen_atoms = view(7, owner) + + if(LAZYLEN(trigger_objs)) + for(var/obj/O in seen_atoms) + if(is_type_in_typecache(O, trigger_objs)) + freak_out(O) + return + + if(LAZYLEN(trigger_turfs)) + for(var/turf/T in seen_atoms) + if(is_type_in_typecache(T, trigger_turfs)) + freak_out(T) + return + + if(LAZYLEN(trigger_mobs) || LAZYLEN(trigger_objs)) + for(var/mob/M in seen_atoms) + if(is_type_in_typecache(M, trigger_mobs)) + freak_out(M) + return + + else if(ishuman(M)) //check their equipment for trigger items + var/mob/living/carbon/human/H = M + + if(LAZYLEN(trigger_species) && H.dna && H.dna.species && is_type_in_typecache(H.dna.species, trigger_species)) + freak_out(H) + + for(var/X in H.get_all_slots() | H.held_items) + var/obj/I = X + if(!QDELETED(I) && is_type_in_typecache(I, trigger_objs)) + freak_out(I) + return + +/datum/brain_trauma/mild/phobia/on_hear(message, speaker, message_language, raw_message, radio_freq) + if(owner.disabilities & DEAF || world.time < next_scare) //words can't trigger you if you can't hear them *taps head* + return message + for(var/word in trigger_words) + if(findtext(message, word)) + addtimer(CALLBACK(src, .proc/freak_out, null, word), 10) //to react AFTER the chat message + break + return message + +/datum/brain_trauma/mild/phobia/on_say(message) + for(var/word in trigger_words) + if(findtext(message, word)) + to_chat(owner, "You can't bring yourself to say the word \"[word]\"!") + return "" + return message + +/datum/brain_trauma/mild/phobia/proc/freak_out(atom/reason, trigger_word) + next_scare = world.time + 120 + var/message = pick("spooks you to the bone", "shakes you up", "terrifies you", "sends you into a panic", "sends chills down your spine") + if(reason) + to_chat(owner, "Seeing [reason] [message]!") + else if(trigger_word) + to_chat(owner, "Hearing \"[trigger_word]\" [message]!") + else + to_chat(owner, "Something [message]!") + var/reaction = rand(1,4) + switch(reaction) + if(1) + to_chat(owner, "You are paralyzed with fear!") + owner.Stun(70) + owner.Jitter(8) + if(2) + owner.emote("scream") + owner.Jitter(5) + owner.say("AAAAH!!") + if(reason) + owner.pointed(reason) + if(3) + to_chat(owner, "You shut your eyes in terror!") + owner.Jitter(5) + owner.blind_eyes(10) + if(4) + owner.dizziness += 10 + owner.confused += 10 + owner.Jitter(10) + owner.stuttering += 10 \ No newline at end of file diff --git a/code/datums/brain_damage/severe.dm b/code/datums/brain_damage/severe.dm new file mode 100644 index 0000000000..ceda917713 --- /dev/null +++ b/code/datums/brain_damage/severe.dm @@ -0,0 +1,217 @@ +//Severe traumas, when your brain gets abused way too much. +//These range from very annoying to completely debilitating. +//They cannot be cured with chemicals, and require brain surgery to solve. + +/datum/brain_trauma/severe + +/datum/brain_trauma/severe/mute + name = "Mutism" + desc = "Patient is completely unable to speak." + scan_desc = "extensive damage to the brain's speech center" + gain_text = "You forget how to speak!" + lose_text = "You suddenly remember how to speak." + +/datum/brain_trauma/severe/mute/on_gain() + owner.disabilities |= MUTE + ..() + +//no fiddling with genetics to get out of this one +/datum/brain_trauma/severe/mute/on_life() + if(!(owner.disabilities & MUTE)) + on_gain() + ..() + +/datum/brain_trauma/severe/mute/on_lose() + owner.disabilities &= ~MUTE + ..() + +/datum/brain_trauma/severe/aphasia + name = "Aphasia" + desc = "Patient is unable to speak or understand any language." + scan_desc = "extensive damage to the brain's language center" + gain_text = "You have trouble forming words in your head..." + lose_text = "You suddenly remember how languages work." + var/datum/language_holder/prev_language + var/datum/language_holder/mob_language + +/datum/brain_trauma/severe/aphasia/on_gain() + mob_language = owner.get_language_holder() + prev_language = mob_language.copy() + mob_language.remove_all_languages() + mob_language.grant_language(/datum/language/aphasia) + ..() + +/datum/brain_trauma/severe/aphasia/on_lose() + mob_language.remove_language(/datum/language/aphasia) + mob_language.copy_known_languages_from(prev_language) //this will also preserve languages learned during the trauma + QDEL_NULL(prev_language) + mob_language = null + ..() + +/datum/brain_trauma/severe/blindness + name = "Cerebral Blindness" + desc = "Patient's brain is no longer connected to its eyes." + scan_desc = "extensive damage to the brain's occipital lobe" + gain_text = "You can't see!" + lose_text = "Your vision returns." + +/datum/brain_trauma/severe/blindness/on_gain() + owner.become_blind() + ..() + +//no fiddling with genetics to get out of this one +/datum/brain_trauma/severe/blindness/on_life() + if(!(owner.disabilities & BLIND)) + on_gain() + ..() + +/datum/brain_trauma/severe/blindness/on_lose() + owner.cure_blind() + ..() + +/datum/brain_trauma/severe/paralysis + name = "Paralysis" + desc = "Patient's brain can no longer control its motor functions." + scan_desc = "cerebral paralysis" + gain_text = "You can't feel your body anymore!" + lose_text = "You can feel your limbs again!" + +/datum/brain_trauma/severe/paralysis/on_life() + owner.Knockdown(200, ignore_canknockdown = TRUE) + ..() + +/datum/brain_trauma/severe/paralysis/on_lose() + owner.SetKnockdown(0) + ..() + +/datum/brain_trauma/severe/narcolepsy + name = "Narcolepsy" + desc = "Patient may involuntarily fall asleep during normal activities." + scan_desc = "traumatic narcolepsy" + gain_text = "You have a constant feeling of drowsiness..." + lose_text = "You feel awake and aware again." + +/datum/brain_trauma/severe/narcolepsy/on_life() + ..() + if(owner.IsSleeping()) + return + var/sleep_chance = 1 + if(owner.m_intent == MOVE_INTENT_RUN) + sleep_chance += 2 + if(owner.drowsyness) + sleep_chance += 3 + if(prob(sleep_chance)) + to_chat(owner, "You fall asleep.") + owner.Sleeping(60) + else if(!owner.drowsyness && prob(sleep_chance * 2)) + to_chat(owner, "You feel tired...") + owner.drowsyness += 10 + +/datum/brain_trauma/severe/monophobia + name = "Monophobia" + desc = "Patient feels sick and distressed when not around other people, leading to potentially lethal levels of stress." + scan_desc = "severe monophobia" + gain_text = "" + lose_text = "You feel like you could be safe on your own." + var/stress = 0 + +/datum/brain_trauma/severe/monophobia/on_gain() + ..() + if(check_alone()) + to_chat(owner, "You feel really lonely...") + else + to_chat(owner, "You feel safe, as long as you have people around you.") + +/datum/brain_trauma/severe/monophobia/on_life() + ..() + if(check_alone()) + stress = min(stress + 0.5, 100) + if(stress > 10 && (prob(5))) + stress_reaction() + else + stress -= 4 + +/datum/brain_trauma/severe/monophobia/proc/check_alone() + if(owner.disabilities & BLIND) + return TRUE + for(var/mob/M in oview(owner, 7)) + if(!isliving(M)) //ghosts ain't people + continue + if((istype(M, /mob/living/simple_animal/pet)) || M.ckey) + return FALSE + return TRUE + +/datum/brain_trauma/severe/monophobia/proc/stress_reaction() + if(owner.stat != CONSCIOUS) + return + + var/high_stress = (stress > 60) //things get psychosomatic from here on + switch(rand(1,6)) + if(1) + if(!high_stress) + to_chat(owner, "You feel sick...") + else + to_chat(owner, "You feel really sick at the thought of being alone!") + addtimer(CALLBACK(owner, /mob/living/carbon.proc/vomit, high_stress), 50) //blood vomit if high stress + if(2) + if(!high_stress) + to_chat(owner, "You can't stop shaking...") + owner.dizziness += 20 + owner.confused += 20 + owner.Jitter(20) + else + to_chat(owner, "You feel weak and scared! If only you weren't alone...") + owner.dizziness += 20 + owner.confused += 20 + owner.Jitter(20) + owner.adjustStaminaLoss(50) + + if(3, 4) + if(!high_stress) + to_chat(owner, "You feel really lonely...") + else + to_chat(owner, "You're going mad with loneliness!") + owner.hallucination += 20 + + if(5) + if(!high_stress) + to_chat(owner, "Your heart skips a beat.") + owner.adjustOxyLoss(8) + else + if(prob(15) && ishuman(owner)) + var/mob/living/carbon/human/H = owner + H.set_heartattack(TRUE) + to_chat(H, "You feel a stabbing pain in your heart!") + else + to_chat(owner, "You feel your heart lurching in your chest...") + owner.adjustOxyLoss(8) + +/datum/brain_trauma/severe/discoordination + name = "Discoordination" + desc = "Patient is unable to use complex tools or machinery." + scan_desc = "extreme discoordination" + gain_text = "You can barely control your hands!" + lose_text = "You feel in control of your hands again." + +/datum/brain_trauma/severe/discoordination/on_gain() + owner.disabilities |= MONKEYLIKE + ..() + +/datum/brain_trauma/severe/discoordination/on_lose() + owner.disabilities &= ~MONKEYLIKE + ..() + +/datum/brain_trauma/severe/pacifism + name = "Traumatic Non-Violence" + desc = "Patient is extremely unwilling to harm others in violent ways." + scan_desc = "pacific syndrome" + gain_text = "You feel oddly peaceful." + lose_text = "You no longer feel compelled to not harm." + +/datum/brain_trauma/severe/pacifism/on_gain() + owner.disabilities |= PACIFISM + ..() + +/datum/brain_trauma/severe/pacifism/on_lose() + owner.disabilities &= ~PACIFISM + ..() \ No newline at end of file diff --git a/code/datums/brain_damage/special.dm b/code/datums/brain_damage/special.dm new file mode 100644 index 0000000000..db0ca60801 --- /dev/null +++ b/code/datums/brain_damage/special.dm @@ -0,0 +1,132 @@ +//Brain traumas that are rare and/or somewhat beneficial; +//they are the easiest to cure, which means that if you want +//to keep them, you can't cure your other traumas +/datum/brain_trauma/special + +/datum/brain_trauma/special/godwoken + name = "Godwoken Syndrome" + desc = "Patient occasionally and uncontrollably channels an eldritch god when speaking." + scan_desc = "god delusion" + gain_text = "You feel a higher power inside your mind..." + lose_text = "The divine presence leaves your head, no longer interested." + +/datum/brain_trauma/special/godwoken/on_life() + ..() + if(prob(4)) + if(prob(33) && (owner.IsStun() || owner.IsKnockdown() || owner.IsUnconscious())) + speak("unstun", TRUE) + else if(prob(60) && owner.health <= HEALTH_THRESHOLD_CRIT) + speak("heal", TRUE) + else if(prob(30) && owner.a_intent == INTENT_HARM) + speak("aggressive") + else + speak("neutral", prob(25)) + +/datum/brain_trauma/special/godwoken/proc/speak(type, include_owner = FALSE) + var/message + switch(type) + if("unstun") + message = pick_list_replacements(BRAIN_DAMAGE_FILE, "god_unstun") + if("heal") + message = pick_list_replacements(BRAIN_DAMAGE_FILE, "god_heal") + if("neutral") + message = pick_list_replacements(BRAIN_DAMAGE_FILE, "god_neutral") + if("aggressive") + message = pick_list_replacements(BRAIN_DAMAGE_FILE, "god_aggressive") + else + message = pick_list_replacements(BRAIN_DAMAGE_FILE, "god_neutral") + + playsound(get_turf(owner), 'sound/magic/clockwork/invoke_general.ogg', 200, 1, 5) + voice_of_god(message, owner, list("colossus","yell"), 2.5, include_owner, FALSE) + +/datum/brain_trauma/special/bluespace_prophet + name = "Bluespace Prophecy" + desc = "Patient can sense the bob and weave of bluespace around them, showing them passageways no one else can see." + scan_desc = "bluespace attunement" + gain_text = "You feel the bluespace pulsing around you..." + lose_text = "The faint pulsing of bluespace fades into silence." + var/next_portal = 0 + +/datum/brain_trauma/special/bluespace_prophet/on_life() + if(world.time > next_portal) + next_portal = world.time + 100 + var/list/turf/possible_turfs = list() + for(var/turf/T in range(owner, 8)) + if(!T.density) + var/clear = TRUE + for(var/obj/O in T) + if(O.density) + clear = FALSE + break + if(clear) + possible_turfs += T + + if(!LAZYLEN(possible_turfs)) + return + + var/turf/first_turf = pick(possible_turfs) + if(!first_turf) + return + + possible_turfs -= (possible_turfs & range(first_turf, 3)) + + var/turf/second_turf = pick(possible_turfs) + if(!second_turf) + return + + var/obj/effect/hallucination/simple/bluespace_stream/first = new(first_turf, owner) + var/obj/effect/hallucination/simple/bluespace_stream/second = new(second_turf, owner) + + first.linked_to = second + second.linked_to = first + first.seer = owner + second.seer = owner + +/obj/effect/hallucination/simple/bluespace_stream + name = "bluespace stream" + desc = "You see a hidden pathway through bluespace..." + image_icon = 'icons/effects/effects.dmi' + image_state = "bluestream" + image_layer = ABOVE_MOB_LAYER + var/obj/effect/hallucination/simple/bluespace_stream/linked_to + var/mob/living/carbon/seer + +/obj/effect/hallucination/simple/bluespace_stream/Initialize() + . = ..() + QDEL_IN(src, 300) + +/obj/effect/hallucination/simple/bluespace_stream/attack_hand(mob/user) + if(user != seer || !linked_to) + return + var/slip_in_message = pick("slides sideways in an odd way, and disappears", "jumps into an unseen dimension",\ + "sticks one leg straight out, wiggles [user.p_their()] foot, and is suddenly gone", "stops, then blinks out of reality", \ + "is pulled into an invisible vortex, vanishing from sight") + var/slip_out_message = pick("silently fades in", "leaps out of thin air","appears", "walks out of an invisible doorway",\ + "slides out of a fold in spacetime") + to_chat(user, "You try to align with the bluespace stream...") + if(do_after(user, 20, target = src)) + new /obj/effect/temp_visual/bluespace_fissure(get_turf(src)) + new /obj/effect/temp_visual/bluespace_fissure(get_turf(linked_to)) + user.forceMove(get_turf(linked_to)) + user.visible_message("[user] [slip_in_message].", ignored_mob = user) + user.visible_message("[user] [slip_out_message].", "...and find your way to the other side.") + +/datum/brain_trauma/special/psychotic_brawling + name = "Violent Psychosis" + desc = "Patient fights in unpredictable ways, ranging from helping his target to hitting them with brutal strength." + scan_desc = "violent psychosis" + gain_text = "You feel unhinged..." + lose_text = "You feel more balanced." + var/datum/martial_art/psychotic_brawling/psychotic_brawling + +/datum/brain_trauma/special/psychotic_brawling/on_gain() + ..() + psychotic_brawling = new(null) + if(!psychotic_brawling.teach(owner, TRUE)) + to_chat(owner, "But your martial knowledge keeps you grounded.") + qdel(src) + +/datum/brain_trauma/special/psychotic_brawling/on_lose() + ..() + psychotic_brawling.remove(owner) + QDEL_NULL(psychotic_brawling) \ No newline at end of file diff --git a/code/datums/brain_damage/split_personality.dm b/code/datums/brain_damage/split_personality.dm new file mode 100644 index 0000000000..deed1c8406 --- /dev/null +++ b/code/datums/brain_damage/split_personality.dm @@ -0,0 +1,221 @@ +#define OWNER 0 +#define STRANGER 1 + +/datum/brain_trauma/severe/split_personality + name = "Split Personality" + desc = "Patient's brain is split into two personalities, which randomly switch control of the body." + scan_desc = "complete lobe separation" + gain_text = "You feel like your mind was split in two." + lose_text = "You feel alone again." + var/current_controller = OWNER + var/initialized = FALSE //to prevent personalities deleting themselves while we wait for ghosts + var/mob/living/split_personality/stranger_backseat //there's two so they can swap without overwriting + var/mob/living/split_personality/owner_backseat + +/datum/brain_trauma/severe/split_personality/on_gain() + ..() + make_backseats() + get_ghost() + +/datum/brain_trauma/severe/split_personality/proc/make_backseats() + stranger_backseat = new(owner, src) + owner_backseat = new(owner, src) + +/datum/brain_trauma/severe/split_personality/proc/get_ghost() + set waitfor = FALSE + var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner]'s split personality?", ROLE_PAI, null, null, 75, stranger_backseat) + if(LAZYLEN(candidates)) + var/client/C = pick(candidates) + stranger_backseat.key = C.key + log_game("[key_name(stranger_backseat)] became [key_name(owner)]'s split personality.") + message_admins("[key_name_admin(stranger_backseat)] became [key_name_admin(owner)]'s split personality.") + else + qdel(src) + +/datum/brain_trauma/severe/split_personality/on_life() + if(owner.stat == DEAD) + if(current_controller != OWNER) + switch_personalities() + qdel(src) + else if(prob(3)) + switch_personalities() + ..() + +/datum/brain_trauma/severe/split_personality/on_lose() + if(current_controller != OWNER) //it would be funny to cure a guy only to be left with the other personality, but it seems too cruel + switch_personalities() + QDEL_NULL(stranger_backseat) + QDEL_NULL(owner_backseat) + ..() + +/datum/brain_trauma/severe/split_personality/proc/switch_personalities() + if(QDELETED(owner) || owner.stat == DEAD || QDELETED(stranger_backseat) || QDELETED(owner_backseat)) + return + + var/mob/living/split_personality/current_backseat + var/mob/living/split_personality/free_backseat + if(current_controller == OWNER) + current_backseat = stranger_backseat + free_backseat = owner_backseat + else + current_backseat = owner_backseat + free_backseat = stranger_backseat + + log_game("[key_name(current_backseat)] assumed control of [key_name(owner)] due to [src]. (Original owner: [current_controller == OWNER ? owner.ckey : current_backseat.ckey])") + to_chat(owner, "You feel your control being taken away... your other personality is in charge now!") + to_chat(current_backseat, "You manage to take control of your body!") + + //Body to backseat + + var/h2b_id = owner.computer_id + var/h2b_ip= owner.lastKnownIP + owner.computer_id = null + owner.lastKnownIP = null + + free_backseat.ckey = owner.ckey + + free_backseat.name = owner.name + + if(owner.mind) + free_backseat.mind = owner.mind + + if(!free_backseat.computer_id) + free_backseat.computer_id = h2b_id + + if(!free_backseat.lastKnownIP) + free_backseat.lastKnownIP = h2b_ip + + //Backseat to body + + var/s2h_id = current_backseat.computer_id + var/s2h_ip= current_backseat.lastKnownIP + current_backseat.computer_id = null + current_backseat.lastKnownIP = null + + owner.ckey = current_backseat.ckey + owner.mind = current_backseat.mind + + if(!owner.computer_id) + owner.computer_id = s2h_id + + if(!owner.lastKnownIP) + owner.lastKnownIP = s2h_ip + + current_controller = !current_controller + + +/mob/living/split_personality + name = "split personality" + real_name = "unknown conscience" + var/mob/living/carbon/body + var/datum/brain_trauma/severe/split_personality/trauma + +/mob/living/split_personality/Initialize(mapload, _trauma) + if(iscarbon(loc)) + body = loc + name = body.real_name + real_name = body.real_name + trauma = _trauma + return ..() + +/mob/living/split_personality/Life() + if(QDELETED(body)) + qdel(src) //in case trauma deletion doesn't already do it + + if((body.stat == DEAD && trauma.owner_backseat == src)) + trauma.switch_personalities() + qdel(trauma) + + //if one of the two ghosts, the other one stays permanently + if(!body.client && trauma.initialized) + trauma.switch_personalities() + qdel(trauma) + + ..() + +/mob/living/split_personality/Login() + ..() + to_chat(src, "As a split personality, you cannot do anything but observe. However, you will eventually gain control of your body, switching places with the current personality.") + to_chat(src, "Do not commit suicide or put the body in a deadly position. Behave like you care about it as much as the owner.") + +/mob/living/split_personality/say(message) + to_chat(src, "You cannot speak, your other self is controlling your body!") + return FALSE + +/mob/living/split_personality/emote(message) + return + +///////////////BRAINWASHING//////////////////// + +/datum/brain_trauma/severe/split_personality/brainwashing + name = "Split Personality" + desc = "Patient's brain is split into two personalities, which randomly switch control of the body." + scan_desc = "complete lobe separation" + gain_text = "" + lose_text = "You are free of your brainwashing." + can_gain = FALSE + var/codeword + var/objective + +/datum/brain_trauma/severe/split_personality/brainwashing/New(obj/item/organ/brain/B, _permanent, _codeword, _objective) + ..() + if(_codeword) + codeword = _codeword + else + codeword = pick(strings("ion_laws.json", "ionabstract")\ + | strings("ion_laws.json", "ionobjects")\ + | strings("ion_laws.json", "ionadjectives")\ + | strings("ion_laws.json", "ionthreats")\ + | strings("ion_laws.json", "ionfood")\ + | strings("ion_laws.json", "iondrinks")) + +/datum/brain_trauma/severe/split_personality/brainwashing/on_gain() + ..() + var/mob/living/split_personality/traitor/traitor_backseat = stranger_backseat + traitor_backseat.codeword = codeword + traitor_backseat.objective = objective + +/datum/brain_trauma/severe/split_personality/brainwashing/make_backseats() + stranger_backseat = new /mob/living/split_personality/traitor(owner, src, codeword, objective) + owner_backseat = new(owner, src) + +/datum/brain_trauma/severe/split_personality/brainwashing/get_ghost() + set waitfor = FALSE + var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner]'s brainwashed mind?", null, null, null, 75, stranger_backseat) + if(LAZYLEN(candidates)) + var/client/C = pick(candidates) + stranger_backseat.key = C.key + else + qdel(src) + +/datum/brain_trauma/severe/split_personality/brainwashing/on_life() + return //no random switching + +/datum/brain_trauma/severe/split_personality/brainwashing/on_hear(message, speaker, message_language, raw_message, radio_freq) + if(owner.disabilities & DEAF || owner == speaker) + return message + if(findtext(message, codeword)) + message = replacetext(message, codeword, "[codeword]") + addtimer(CALLBACK(src, /datum/brain_trauma/severe/split_personality.proc/switch_personalities), 10) + return message + +/datum/brain_trauma/severe/split_personality/brainwashing/on_say(message) + if(findtext(message, codeword)) + return "" //oh hey did you want to tell people about the secret word to bring you back? + return message + +/mob/living/split_personality/traitor + name = "split personality" + real_name = "unknown conscience" + var/objective + var/codeword + +/mob/living/split_personality/traitor/Login() + ..() + to_chat(src, "As a brainwashed personality, you cannot do anything yet but observe. However, you may gain control of your body if you hear the special codeword, switching places with the current personality.") + to_chat(src, "Your activation codeword is: [codeword]") + if(objective) + to_chat(src, "Your master left you an objective: [objective]. Follow it at all costs when in control.") + +#undef OWNER +#undef STRANGER diff --git a/code/datums/callback.dm b/code/datums/callback.dm index 88d9427301..5566137189 100644 --- a/code/datums/callback.dm +++ b/code/datums/callback.dm @@ -48,6 +48,7 @@ var/datum/object = GLOBAL_PROC var/delegate var/list/arguments + var/datum/weakref/user /datum/callback/New(thingtocall, proctocall, ...) if (thingtocall) @@ -55,6 +56,8 @@ delegate = proctocall if (length(args) > 2) arguments = args.Copy(3) + if(usr) + user = WEAKREF(usr) /world/proc/ImmediateInvokeAsync(thingtocall, proctocall, ...) set waitfor = FALSE @@ -70,8 +73,16 @@ call(thingtocall, proctocall)(arglist(calling_arguments)) /datum/callback/proc/Invoke(...) + if(!usr) + var/datum/weakref/W = user + if(W) + var/mob/M = W.resolve() + if(M) + return world.PushUsr(M, src) + if (!object) return + var/list/calling_arguments = arguments if (length(args)) if (length(arguments)) @@ -87,8 +98,17 @@ //copy and pasted because fuck proc overhead /datum/callback/proc/InvokeAsync(...) set waitfor = FALSE + + if(!usr) + var/datum/weakref/W = user + if(W) + var/mob/M = W.resolve() + if(M) + return world.PushUsr(M, src) + if (!object) return + var/list/calling_arguments = arguments if (length(args)) if (length(arguments)) diff --git a/code/datums/components/README.md b/code/datums/components/README.md index 11cbf1858d..026b387e27 100644 --- a/code/datums/components/README.md +++ b/code/datums/components/README.md @@ -34,12 +34,13 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo * Lazy associated list of type -> component/list of components. 1. `/datum/component/var/enabled` (protected, boolean) * If the component is enabled. If not, it will not react to signals - * `TRUE` by default + * `FALSE` by default, set to `TRUE` when a signal is registered 1. `/datum/component/var/dupe_mode` (protected, enum) * How duplicate component types are handled when added to the datum. * `COMPONENT_DUPE_HIGHLANDER` (default): Old component will be deleted, new component will first have `/datum/component/proc/InheritComponent(datum/component/old, FALSE)` on it * `COMPONENT_DUPE_ALLOWED`: The components will be treated as separate, `GetComponent()` will return the first added * `COMPONENT_DUPE_UNIQUE`: New component will be deleted, old component will first have `/datum/component/proc/InheritComponent(datum/component/new, TRUE)` on it + * `COMPONENT_DUPE_UNIQUE_PASSARGS`: New component will never exist and instead its initialization arguments will be passed on to the old component. 1. `/datum/component/var/dupe_type` (protected, type) * Definition of a duplicate component type * `null` means exact match on `type` (default) @@ -66,6 +67,7 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo * All components a datum owns are deleted with the datum * Returns the component that was created. Or the old component in a dupe situation where `COMPONENT_DUPE_UNIQUE` was set * If this tries to add an component to an incompatible type, the component will be deleted and the result will be `null`. This is very unperformant, try not to do it + * Properly handles duplicate situations based on the `dupe_mode` var 1. `/datum/proc/LoadComponent(component_type(type), ...) -> datum/component` (public, final) * Equivalent to calling `GetComponent(component_type)` where, if the result would be `null`, returns `AddComponent(component_type, ...)` instead 1. `/datum/proc/ComponentActivated(datum/component/C)` (abstract, async) @@ -78,6 +80,7 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo 1. `/datum/proc/SendSignal(signal, ...)` (public, final) * Call to send a signal to the components of the target datum * Extra arguments are to be specified in the signal definition + * Returns a bitflag with signal specific information assembled from all activated components 1. `/datum/component/New(datum/parent, ...)` (private, final) * Runs internal setup for the component * Extra arguments are passed to `Initialize()` @@ -103,9 +106,8 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo * Allows the component to react to ownership transfers 1. `/datum/component/proc/_RemoveFromParent()` (private, final) * Clears `parent` and removes the component from it's component list -1. `/datum/component/proc/_CheckDupesAndJoinParent` (private, final) +1. `/datum/component/proc/_JoinParent` (private, final) * Tries to add the component to it's `parent`s `datum_components` list - * Properly handles duplicate situations based on the `dupe_mode` var 1. `/datum/component/proc/RegisterSignal(signal(string/list of strings), proc_ref(type), override(boolean))` (protected, final) (Consider removing for performance gainz) * If signal is a list it will be as if RegisterSignal was called for each of the entries with the same following arguments * Makes a component listen for the specified `signal` on it's `parent` datum. diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm index 4fb71acf84..fcd4651459 100644 --- a/code/datums/components/_component.dm +++ b/code/datums/components/_component.dm @@ -1,64 +1,26 @@ /datum/component - var/enabled = TRUE + var/enabled = FALSE var/dupe_mode = COMPONENT_DUPE_HIGHLANDER var/dupe_type var/list/signal_procs var/datum/parent /datum/component/New(datum/P, ...) - if(type == /datum/component) - qdel(src) - CRASH("[type] instantiated!") - - //check for common mishaps - if(!isnum(dupe_mode)) - qdel(src) - CRASH("[type]: Invalid dupe_mode!") - if(dupe_type && !ispath(dupe_type)) - qdel(src) - CRASH("[type]: Invalid dupe_type!") - parent = P - var/list/arguments = args.Copy() - arguments.Cut(1, 2) + var/list/arguments = args.Copy(2) if(Initialize(arglist(arguments)) == COMPONENT_INCOMPATIBLE) qdel(src, TRUE, TRUE) return - - _CheckDupesAndJoinParent(P) -/datum/component/proc/_CheckDupesAndJoinParent() + _JoinParent(P) + +/datum/component/proc/_JoinParent() var/datum/P = parent - var/dm = dupe_mode - - var/datum/component/old - if(dm != COMPONENT_DUPE_ALLOWED) - var/dt = dupe_type - if(!dt) - old = P.GetExactComponent(type) - else - old = P.GetComponent(dt) - if(old) - //One or the other has to die - switch(dm) - if(COMPONENT_DUPE_UNIQUE) - old.InheritComponent(src, TRUE) - qdel(src, TRUE, TRUE) - return - if(COMPONENT_DUPE_HIGHLANDER) - InheritComponent(old, FALSE) - qdel(old, FALSE, TRUE) - - //provided we didn't eat someone - if(!old) - //let the others know - P.SendSignal(COMSIG_COMPONENT_ADDED, src) - //lazy init the parent's dc list var/list/dc = P.datum_components if(!dc) P.datum_components = dc = list() - + //set up the typecache var/our_type = type for(var/I in _GetInverseTypeList(our_type)) @@ -122,7 +84,7 @@ if(!procs) procs = list() signal_procs = procs - + var/list/sig_types = islist(sig_type_or_types) ? sig_type_or_types : list(sig_type_or_types) for(var/sig_type in sig_types) if(!override) @@ -133,6 +95,8 @@ if(!istype(proc_or_callback, /datum/callback)) //if it wasnt a callback before, it is now proc_or_callback = CALLBACK(src, proc_or_callback) procs[sig_type] = proc_or_callback + + enabled = TRUE /datum/component/proc/InheritComponent(datum/component/C, i_am_original) return @@ -140,10 +104,6 @@ /datum/component/proc/OnTransfer(datum/new_parent) return -/datum/component/proc/AfterComponentActivated() - set waitfor = FALSE - return - /datum/component/proc/_GetInverseTypeList(our_type = type) #if DM_VERSION >= 513 #warning 512 is definitely stable now, remove the old code @@ -164,40 +124,26 @@ /datum/proc/SendSignal(sigtype, ...) var/list/comps = datum_components if(!comps) - return FALSE - var/list/arguments = args.Copy() - arguments.Cut(1, 2) + return NONE + var/list/arguments = args.Copy(2) var/target = comps[/datum/component] if(!length(target)) var/datum/component/C = target if(!C.enabled) - return FALSE - var/list/sps = C.signal_procs - var/datum/callback/CB = LAZYACCESS(sps, sigtype) + return NONE + var/datum/callback/CB = C.signal_procs[sigtype] if(!CB) - return FALSE - . = CB.InvokeAsync(arglist(arguments)) - if(.) - ComponentActivated(C) - C.AfterComponentActivated() - else - . = FALSE - for(var/I in target) - var/datum/component/C = I - if(!C.enabled) - continue - var/list/sps = C.signal_procs - var/datum/callback/CB = LAZYACCESS(sps, sigtype) - if(!CB) - continue - if(CB.InvokeAsync(arglist(arguments))) - ComponentActivated(C) - C.AfterComponentActivated() - . = TRUE - -/datum/proc/ComponentActivated(datum/component/C) - set waitfor = FALSE - return + return NONE + return CB.InvokeAsync(arglist(arguments)) + . = NONE + for(var/I in target) + var/datum/component/C = I + if(!C.enabled) + continue + var/datum/callback/CB = C.signal_procs[sigtype] + if(!CB) + continue + . |= CB.InvokeAsync(arglist(arguments)) /datum/proc/GetComponent(c_type) var/list/dc = datum_components @@ -228,10 +174,59 @@ return list(.) /datum/proc/AddComponent(new_type, ...) - var/nt = new_type + var/datum/component/nt = new_type + var/dm = initial(nt.dupe_mode) + var/dt = initial(nt.dupe_type) + + var/datum/component/old_comp + var/datum/component/new_comp + + if(ispath(nt)) + if(nt == /datum/component) + CRASH("[nt] attempted instantiation!") + if(!isnum(dm)) + CRASH("[nt]: Invalid dupe_mode ([dm])!") + if(dt && !ispath(dt)) + CRASH("[nt]: Invalid dupe_type ([dt])!") + else + new_comp = nt + args[1] = src - var/datum/component/C = new nt(arglist(args)) - return QDELING(C) ? GetExactComponent(new_type) : C + + if(dm != COMPONENT_DUPE_ALLOWED) + if(!dt) + old_comp = GetExactComponent(nt) + else + old_comp = GetComponent(dt) + if(old_comp) + switch(dm) + if(COMPONENT_DUPE_UNIQUE) + if(!new_comp) + new_comp = new nt(arglist(args)) + if(!QDELETED(new_comp)) + old_comp.InheritComponent(new_comp, TRUE) + qdel(new_comp) + if(COMPONENT_DUPE_HIGHLANDER) + if(!new_comp) + new_comp = new nt(arglist(args)) + if(!QDELETED(new_comp)) + new_comp.InheritComponent(old_comp, FALSE) + qdel(old_comp) + if(COMPONENT_DUPE_UNIQUE_PASSARGS) + if(!new_comp) + var/list/arguments = args.Copy(2) + old_comp.InheritComponent(null, TRUE, arguments) + else + old_comp.InheritComponent(new_comp, TRUE) + else if(!new_comp) + new_comp = new nt(arglist(args)) // There's a valid dupe mode but there's no old component, act like normal + else if(!new_comp) + new_comp = new nt(arglist(args)) // Dupes are allowed, act like normal + + if(!old_comp && !QDELETED(new_comp)) // Nothing related to duplicate components happened and the new component is healthy + SendSignal(COMSIG_COMPONENT_ADDED, new_comp) + return new_comp + return old_comp /datum/proc/LoadComponent(component_type, ...) . = GetComponent(component_type) @@ -251,7 +246,8 @@ C._RemoveFromParent() helicopter.SendSignal(COMSIG_COMPONENT_REMOVING, C) C.parent = src - C._CheckDupesAndJoinParent() + if(C == AddComponent(C)) + C._JoinParent() /datum/proc/TransferComponents(datum/target) var/list/dc = datum_components @@ -263,3 +259,6 @@ target.TakeComponent(I) else target.TakeComponent(comps) + +/datum/component/ui_host() + return parent diff --git a/code/datums/components/archaeology.dm b/code/datums/components/archaeology.dm index ac4e3c107c..30bf107ad0 100644 --- a/code/datums/components/archaeology.dm +++ b/code/datums/components/archaeology.dm @@ -3,10 +3,12 @@ var/list/archdrops var/prob2drop var/dug + var/datum/callback/callback -/datum/component/archaeology/Initialize(_prob2drop, list/_archdrops = list()) - prob2drop = Clamp(_prob2drop, 0, 100) +/datum/component/archaeology/Initialize(_prob2drop, list/_archdrops = list(), datum/callback/_callback) + prob2drop = CLAMP(_prob2drop, 0, 100) archdrops = _archdrops + callback = _callback RegisterSignal(COMSIG_PARENT_ATTACKBY,.proc/Dig) RegisterSignal(COMSIG_ATOM_EX_ACT, .proc/BombDig) RegisterSignal(COMSIG_ATOM_SING_PULL, .proc/SingDig) @@ -20,27 +22,26 @@ /datum/component/archaeology/proc/Dig(obj/item/W, mob/living/user) if(dug) to_chat(user, "Looks like someone has dug here already.") - return FALSE - else - var/digging_speed - if (istype(W, /obj/item/shovel)) - var/obj/item/shovel/S = W - digging_speed = S.digspeed - else if (istype(W, /obj/item/pickaxe)) - var/obj/item/pickaxe/P = W - digging_speed = P.digspeed + return + + var/digging_speed + if (istype(W, /obj/item/shovel)) + var/obj/item/shovel/S = W + digging_speed = S.digspeed + else if (istype(W, /obj/item/pickaxe)) + var/obj/item/pickaxe/P = W + digging_speed = P.digspeed + + if (digging_speed && isturf(user.loc)) + to_chat(user, "You start digging...") + playsound(parent, 'sound/effects/shovel_dig.ogg', 50, 1) - if (digging_speed && isturf(user.loc)) - to_chat(user, "You start digging...") - playsound(parent, 'sound/effects/shovel_dig.ogg', 50, 1) - - if(do_after(user, digging_speed, target = parent)) - to_chat(user, "You dig a hole.") - gets_dug() - dug = TRUE - SSblackbox.record_feedback("tally", "pick_used_mining", 1, W.type) - return TRUE - return FALSE + if(do_after(user, digging_speed, target = parent)) + to_chat(user, "You dig a hole.") + gets_dug() + dug = TRUE + SSblackbox.record_feedback("tally", "pick_used_mining", 1, W.type) + return COMPONENT_NO_AFTERATTACK /datum/component/archaeology/proc/gets_dug() if(dug) @@ -68,6 +69,8 @@ if(OT.slowdown) //Things like snow slow you down until you dig them. OT.slowdown = 0 dug = TRUE + if(callback) + callback.Invoke() /datum/component/archaeology/proc/SingDig(S, current_size) switch(current_size) diff --git a/code/datums/components/caltrop.dm b/code/datums/components/caltrop.dm new file mode 100644 index 0000000000..5b8adf0175 --- /dev/null +++ b/code/datums/components/caltrop.dm @@ -0,0 +1,60 @@ +/datum/component/caltrop + var/min_damage + var/max_damage + var/probability + var/flags + + var/cooldown = 0 + +/datum/component/caltrop/Initialize(_min_damage = 0, _max_damage = 0, _probability = 100, _flags = NONE) + min_damage = _min_damage + max_damage = max(_min_damage, _max_damage) + probability = _probability + flags = _flags + + RegisterSignal(list(COMSIG_MOVABLE_CROSSED), .proc/Crossed) + +/datum/component/caltrop/proc/Crossed(atom/movable/AM) + var/atom/A = parent + if(!A.has_gravity()) + return + + if(!prob(probability)) + return + + if(ishuman(AM)) + var/mob/living/carbon/human/H = AM + if(PIERCEIMMUNE in H.dna.species.species_traits) + return + + if((flags & CALTROP_IGNORE_WALKERS) && H.m_intent == MOVE_INTENT_WALK) + return + + var/picked_def_zone = pick("l_leg", "r_leg") + var/obj/item/bodypart/O = H.get_bodypart(picked_def_zone) + if(!istype(O)) + return + if(O.status == BODYPART_ROBOTIC) + return + + var/feetCover = (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)) || (H.w_uniform && (H.w_uniform.body_parts_covered & FEET)) + + if(!(flags & CALTROP_BYPASS_SHOES) && (H.shoes || feetCover)) + return + + if((H.movement_type & FLYING) || H.buckled) + return + + var/damage = rand(min_damage, max_damage) + H.apply_damage(damage, BRUTE, picked_def_zone) + + if(cooldown < world.time - 10) //cooldown to avoid message spam. + if(!H.incapacitated(ignore_restraints = TRUE)) + H.visible_message("[H] steps on [A].", \ + "You step on [A]!") + else + H.visible_message("[H] slides on [A]!", \ + "You slide on [A]!") + + cooldown = world.time + H.Knockdown(60) diff --git a/code/datums/components/decal.dm b/code/datums/components/decal.dm index a28213b0b5..a79de32898 100644 --- a/code/datums/components/decal.dm +++ b/code/datums/components/decal.dm @@ -48,8 +48,7 @@ if(old_dir == new_dir) return remove() - var/rotation = SimplifyDegrees(dir2angle(new_dir)-dir2angle(old_dir)) - pic.dir = turn(pic.dir, rotation) + pic.dir = turn(pic.dir, dir2angle(old_dir) - dir2angle(new_dir)) apply() /datum/component/decal/proc/clean_react(strength) @@ -57,4 +56,4 @@ qdel(src) /datum/component/decal/proc/examine(mob/user) - to_chat(user, description) \ No newline at end of file + to_chat(user, description) diff --git a/code/datums/components/infective.dm b/code/datums/components/infective.dm index cedede6b04..521d9ece2c 100644 --- a/code/datums/components/infective.dm +++ b/code/datums/components/infective.dm @@ -9,5 +9,4 @@ var/mob/living/carbon/victim = AM if(istype(victim)) for(var/datum/disease/D in diseases) - victim.ContactContractDisease(D, "feet") - return TRUE \ No newline at end of file + victim.ContactContractDisease(D, "feet") \ No newline at end of file diff --git a/code/datums/components/jousting.dm b/code/datums/components/jousting.dm new file mode 100644 index 0000000000..68621e60ec --- /dev/null +++ b/code/datums/components/jousting.dm @@ -0,0 +1,81 @@ +/datum/component/jousting + var/current_direction = NONE + var/max_tile_charge = 5 + var/min_tile_charge = 2 //tiles before this code gets into effect. + var/current_tile_charge = 0 + var/movement_reset_tolerance = 2 //deciseconds + var/unmounted_damage_boost_per_tile = 0 + var/unmounted_knockdown_chance_per_tile = 0 + var/unmounted_knockdown_time = 0 + var/mounted_damage_boost_per_tile = 2 + var/mounted_knockdown_chance_per_tile = 20 + var/mounted_knockdown_time = 20 + var/requires_mob_riding = TRUE //whether this only works if the attacker is riding a mob, rather than anything they can buckle to. + var/requires_mount = TRUE //kinda defeats the point of jousting if you're not mounted but whatever. + var/mob/current_holder + var/datum/component/redirect/listener + var/current_timerid + +/datum/component/jousting/Initialize() + if(!isitem(parent)) + . = COMPONENT_INCOMPATIBLE + stack_trace("Warning: Jousting component incorrectly applied to invalid parent type [parent.type]") + RegisterSignal(COMSIG_ITEM_EQUIPPED, .proc/on_equip) + RegisterSignal(COMSIG_ITEM_DROPPED, .proc/on_drop) + RegisterSignal(COMSIG_ITEM_ATTACK, .proc/on_attack) + +/datum/component/jousting/Destroy() + QDEL_NULL(listener) + return ..() + +/datum/component/jousting/proc/on_equip(mob/user, slot) + QDEL_NULL(listener) + current_holder = user + listener = new(user, COMSIG_MOVABLE_MOVED, CALLBACK(src, .proc/mob_move)) + +/datum/component/jousting/proc/on_drop(mob/user) + QDEL_NULL(listener) + current_holder = null + current_direction = NONE + current_tile_charge = 0 + +/datum/component/jousting/proc/on_attack(mob/living/target, mob/user) + if(user != current_holder) + return + var/current = current_tile_charge + var/obj/item/I = parent + var/target_buckled = target.buckled ? TRUE : FALSE //we don't need the reference of what they're buckled to, just whether they are. + if((requires_mount && ((requires_mob_riding && !ismob(user.buckled)) || (!user.buckled))) || !current_direction || (current_tile_charge < min_tile_charge)) + return + var/turf/target_turf = get_step(user, current_direction) + if(target in range(1, target_turf)) + var/knockdown_chance = (target_buckled? mounted_knockdown_chance_per_tile : unmounted_knockdown_chance_per_tile) * current + var/knockdown_time = (target_buckled? mounted_knockdown_time : unmounted_knockdown_time) + var/damage = (target_buckled? mounted_damage_boost_per_tile : unmounted_damage_boost_per_tile) * current + var/sharp = I.is_sharp() + var/msg + if(damage) + msg += "[user] [sharp? "impales" : "slams into"] [target] [sharp? "on" : "with"] their [parent]" + target.apply_damage(damage, BRUTE, user.zone_selected, 0) + if(prob(knockdown_chance)) + msg += " and knocks [target] [target_buckled? "off of [target.buckled]" : "down"]" + if(target_buckled) + target.buckled.unbuckle_mob(target) + target.Knockdown(knockdown_time) + if(length(msg)) + user.visible_message("[msg]!") + +/datum/component/jousting/proc/mob_move(newloc, dir) + if(!current_holder || (requires_mount && ((requires_mob_riding && !ismob(current_holder.buckled)) || (!current_holder.buckled)))) + return + if(dir != current_direction) + current_tile_charge = 0 + current_direction = dir + if(current_tile_charge < max_tile_charge) + current_tile_charge++ + if(current_timerid) + deltimer(current_timerid) + current_timerid = addtimer(CALLBACK(src, .proc/reset_charge), movement_reset_tolerance, TIMER_STOPPABLE) + +/datum/component/jousting/proc/reset_charge() + current_tile_charge = 0 diff --git a/code/datums/components/knockoff.dm b/code/datums/components/knockoff.dm new file mode 100644 index 0000000000..35d1e5423e --- /dev/null +++ b/code/datums/components/knockoff.dm @@ -0,0 +1,53 @@ +//Items with these will have a chance to get knocked off when disarming +/datum/component/knockoff + var/knockoff_chance = 100 //Chance to knockoff + var/list/target_zones //Aiming for these zones will cause the knockoff, null means all zones allowed + var/list/slots_knockoffable //Can be only knocked off from these slots, null means all slots allowed + var/datum/component/redirect/disarm_redirect + +/datum/component/knockoff/Initialize(knockoff_chance,zone_override,slots_knockoffable) + if(!isitem(parent)) + . = COMPONENT_INCOMPATIBLE + CRASH("Knockoff component misuse") + RegisterSignal(COMSIG_ITEM_EQUIPPED,.proc/OnEquipped) + RegisterSignal(COMSIG_ITEM_DROPPED,.proc/OnDropped) + + src.knockoff_chance = knockoff_chance + + if(zone_override) + target_zones = zone_override + + if(slots_knockoffable) + src.slots_knockoffable = slots_knockoffable + +/datum/component/knockoff/proc/Knockoff(mob/living/attacker,zone) + var/obj/item/I = parent + var/mob/living/carbon/human/wearer = I.loc + if(!istype(wearer)) + return + if(target_zones && !(zone in target_zones)) + return + if(!prob(knockoff_chance)) + return + if(!wearer.dropItemToGround(I)) + return + + wearer.visible_message("[attacker] knocks off [wearer]'s [I.name]!","[attacker] knocks off your [I.name]!") + +/datum/component/knockoff/proc/OnEquipped(mob/living/carbon/human/H,slot) + if(!istype(H)) + return + if(slots_knockoffable && !(slot in slots_knockoffable)) + if(disarm_redirect) + QDEL_NULL(disarm_redirect) + return + if(!disarm_redirect) + disarm_redirect = H.AddComponent(/datum/component/redirect,list(COMSIG_HUMAN_DISARM_HIT),CALLBACK(src,.proc/Knockoff)) + +/datum/component/knockoff/proc/OnDropped(mob/living/M) + if(disarm_redirect) + QDEL_NULL(disarm_redirect) + +/datum/component/knockoff/Destroy() + QDEL_NULL(disarm_redirect) + . = ..() \ No newline at end of file diff --git a/code/datums/components/material_container.dm b/code/datums/components/material_container.dm index c6acb7d78d..d8b3b058dd 100644 --- a/code/datums/components/material_container.dm +++ b/code/datums/components/material_container.dm @@ -16,20 +16,19 @@ var/list/materials 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/precise_insertion = FALSE var/datum/callback/precondition + var/datum/callback/after_insert -/datum/component/material_container/Initialize(list/mat_list, max_amt = 0, _show_on_examine = FALSE, list/allowed_types, datum/callback/_precondition) +/datum/component/material_container/Initialize(list/mat_list, max_amt = 0, _show_on_examine = FALSE, list/allowed_types, datum/callback/_precondition, datum/callback/_after_insert) materials = list() max_amount = max(0, max_amt) show_on_examine = _show_on_examine if(allowed_types) allowed_typecache = typecacheof(allowed_types) precondition = _precondition + after_insert = _after_insert RegisterSignal(COMSIG_PARENT_ATTACKBY, .proc/OnAttackBy) RegisterSignal(COMSIG_PARENT_EXAMINE, .proc/OnExamine) @@ -53,14 +52,13 @@ /datum/component/material_container/proc/OnAttackBy(obj/item/I, mob/living/user) var/list/tc = allowed_typecache if(user.a_intent == INTENT_HARM) - return FALSE + return if((I.flags_2 & (HOLOGRAM_2 | NO_MAT_REDEMPTION_2)) || (tc && !is_type_in_typecache(I, tc))) to_chat(user, "[parent] won't accept [I]!") - return FALSE - . = TRUE - last_insert_success = FALSE + return + . = COMPONENT_NO_AFTERATTACK var/datum/callback/pc = precondition - if(pc && !pc.Invoke()) + if(pc && !pc.Invoke(user)) return var/material_amount = get_item_material_amount(I) if(!material_amount) @@ -69,11 +67,13 @@ if(!has_space(material_amount)) to_chat(user, "[parent] is full. Please remove metal or glass from [parent] in order to insert more.") return - INVOKE_ASYNC(src, .proc/user_insert, I, user) + user_insert(I, user) /datum/component/material_container/proc/user_insert(obj/item/I, mob/living/user) + set waitfor = FALSE var/requested_amount - if(istype(I, /obj/item/stack) && precise_insertion) + var/Itype = I.type + if(ispath(Itype, /obj/item/stack) && precise_insertion) var/atom/current_parent = parent requested_amount = input(user, "How much do you want to insert?", "Inserting sheets") as num|null if(isnull(requested_amount) || (requested_amount <= 0)) @@ -85,7 +85,6 @@ return var/inserted = insert_item(I, stack_amt = requested_amount) if(inserted) - last_insert_success = TRUE if(istype(I, /obj/item/stack)) to_chat(user, "You insert [inserted] sheet[inserted>1 ? "s" : ""] into [parent].") if(!QDELETED(I)) @@ -93,6 +92,8 @@ else to_chat(user, "You insert a material total of [inserted] into [parent].") qdel(I) + if(after_insert) + after_insert.Invoke(Itype, last_inserted_id, inserted) else user.put_in_active_hand(I) @@ -132,9 +133,7 @@ return FALSE last_inserted_id = insert_materials(S,amt) - last_inserted_type = S.type S.use(amt) - last_amount_inserted = amt return amt /datum/component/material_container/proc/insert_item(obj/item/I, multiplier = 1, stack_amt) @@ -148,8 +147,6 @@ return FALSE 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 diff --git a/code/datums/components/ntnet_interface.dm b/code/datums/components/ntnet_interface.dm index 14705691bb..3016e53c08 100644 --- a/code/datums/components/ntnet_interface.dm +++ b/code/datums/components/ntnet_interface.dm @@ -1,59 +1,59 @@ -//Thing meant for allowing datums and objects to access a NTnet network datum. -/datum/proc/ntnet_recieve(datum/netdata/data) - return - -/datum/proc/ntnet_send(datum/netdata/data, netid) - GET_COMPONENT(NIC, /datum/component/ntnet_interface) - if(!NIC) - return FALSE - return NIC.__network_send(data, netid) - -/datum/component/ntnet_interface - var/hardware_id //text - var/network_name = "" //text - var/list/networks_connected_by_id = list() //id = datum/ntnet - -/datum/component/ntnet_interface/Initialize(force_ID, force_name = "NTNet Device", autoconnect_station_network = TRUE) //Don't force ID unless you know what you're doing! - if(!force_ID) - hardware_id = "[SSnetworks.assignment_hardware_id++]" - else - hardware_id = force_ID - network_name = force_name - SSnetworks.register_interface(src) - if(autoconnect_station_network) - register_connection(SSnetworks.station_network) - -/datum/component/ntnet_interface/Destroy() - unregister_all_connections() - SSnetworks.unregister_interface(src) - return ..() - -/datum/component/ntnet_interface/proc/__network_recieve(datum/netdata/data) //Do not directly proccall! - parent.SendSignal(COMSIG_COMPONENT_NTNET_RECIEVE, data) - parent.ntnet_recieve(data) - -/datum/component/ntnet_interface/proc/__network_send(datum/netdata/data, netid) //Do not directly proccall! - if(netid) - if(networks_connected_by_id[netid]) - var/datum/ntnet/net = networks_connected_by_id[netid] - return net.process_data_transmit(src, data) - return FALSE - for(var/i in networks_connected_by_id) - var/datum/ntnet/net = networks_connected_by_id[i] - net.process_data_transmit(src, data) - return TRUE - -/datum/component/ntnet_interface/proc/register_connection(datum/ntnet/net) - if(net.interface_connect(src)) - networks_connected_by_id[net.network_id] = net - return TRUE - -/datum/component/ntnet_interface/proc/unregister_all_connections() - for(var/i in networks_connected_by_id) - unregister_connection(networks_connected_by_id[i]) - return TRUE - -/datum/component/ntnet_interface/proc/unregister_connection(datum/ntnet/net) - net.interface_disconnect(src) - networks_connected_by_id -= net.network_id - return TRUE +//Thing meant for allowing datums and objects to access a NTnet network datum. +/datum/proc/ntnet_recieve(datum/netdata/data) + return + +/datum/proc/ntnet_send(datum/netdata/data, netid) + GET_COMPONENT(NIC, /datum/component/ntnet_interface) + if(!NIC) + return FALSE + return NIC.__network_send(data, netid) + +/datum/component/ntnet_interface + var/hardware_id //text + var/network_name = "" //text + var/list/networks_connected_by_id = list() //id = datum/ntnet + +/datum/component/ntnet_interface/Initialize(force_ID, force_name = "NTNet Device", autoconnect_station_network = TRUE) //Don't force ID unless you know what you're doing! + if(!force_ID) + hardware_id = "[SSnetworks.assignment_hardware_id++]" + else + hardware_id = force_ID + network_name = force_name + SSnetworks.register_interface(src) + if(autoconnect_station_network) + register_connection(SSnetworks.station_network) + +/datum/component/ntnet_interface/Destroy() + unregister_all_connections() + SSnetworks.unregister_interface(src) + return ..() + +/datum/component/ntnet_interface/proc/__network_recieve(datum/netdata/data) //Do not directly proccall! + parent.SendSignal(COMSIG_COMPONENT_NTNET_RECIEVE, data) + parent.ntnet_recieve(data) + +/datum/component/ntnet_interface/proc/__network_send(datum/netdata/data, netid) //Do not directly proccall! + if(netid) + if(networks_connected_by_id[netid]) + var/datum/ntnet/net = networks_connected_by_id[netid] + return net.process_data_transmit(src, data) + return FALSE + for(var/i in networks_connected_by_id) + var/datum/ntnet/net = networks_connected_by_id[i] + net.process_data_transmit(src, data) + return TRUE + +/datum/component/ntnet_interface/proc/register_connection(datum/ntnet/net) + if(net.interface_connect(src)) + networks_connected_by_id[net.network_id] = net + return TRUE + +/datum/component/ntnet_interface/proc/unregister_all_connections() + for(var/i in networks_connected_by_id) + unregister_connection(networks_connected_by_id[i]) + return TRUE + +/datum/component/ntnet_interface/proc/unregister_connection(datum/ntnet/net) + net.interface_disconnect(src) + networks_connected_by_id -= net.network_id + return TRUE diff --git a/code/datums/components/paintable.dm b/code/datums/components/paintable.dm index 2ea94334d0..01e81d27c0 100644 --- a/code/datums/components/paintable.dm +++ b/code/datums/components/paintable.dm @@ -14,8 +14,8 @@ /datum/component/spraycan_paintable/proc/Repaint(obj/item/toy/crayon/spraycan/spraycan, mob/living/user) if(!istype(spraycan) || user.a_intent == INTENT_HARM) - return FALSE - . = TRUE + return + . = COMPONENT_NO_AFTERATTACK if(spraycan.is_capped) to_chat(user, "Take the cap off first!") return diff --git a/code/datums/components/radioactive.dm b/code/datums/components/radioactive.dm index c149fd8492..fc0456ad10 100644 --- a/code/datums/components/radioactive.dm +++ b/code/datums/components/radioactive.dm @@ -4,7 +4,7 @@ #define RAD_AMOUNT_EXTREME 1000 /datum/component/radioactive - dupe_mode = COMPONENT_DUPE_UNIQUE + dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS var/source @@ -47,13 +47,16 @@ if(strength <= RAD_BACKGROUND_RADIATION) return PROCESS_KILL -/datum/component/radioactive/InheritComponent(datum/component/C, i_am_original) +/datum/component/radioactive/InheritComponent(datum/component/C, i_am_original, list/arguments) if(!i_am_original) return if(!hl3_release_date) // Permanently radioactive things don't get to grow stronger return - var/datum/component/radioactive/other = C - strength = max(strength, other.strength) + if(C) + var/datum/component/radioactive/other = C + strength = max(strength, other.strength) + else + strength = max(strength, arguments[1]) /datum/component/radioactive/proc/rad_examine(mob/user, atom/thing) var/atom/master = parent diff --git a/code/datums/components/riding.dm b/code/datums/components/riding.dm new file mode 100644 index 0000000000..e21db3e094 --- /dev/null +++ b/code/datums/components/riding.dm @@ -0,0 +1,326 @@ +/datum/component/riding + var/next_vehicle_move = 0 //used for move delays + var/vehicle_move_delay = 2 //tick delay between movements, lower = faster, higher = slower + var/keytype + + var/slowed = FALSE + var/slowvalue = 1 + + var/list/riding_offsets = list() //position_of_user = list(dir = list(px, py)), or RIDING_OFFSET_ALL for a generic one. + var/list/directional_vehicle_layers = list() //["[DIRECTION]"] = layer. Don't set it for a direction for default, set a direction to null for no change. + var/list/directional_vehicle_offsets = list() //same as above but instead of layer you have a list(px, py) + var/list/allowed_turf_typecache + var/list/forbid_turf_typecache //allow typecache for only certain turfs, forbid to allow all but those. allow only certain turfs will take precedence. + var/allow_one_away_from_valid_turf = TRUE //allow moving one tile away from a valid turf but not more. + var/override_allow_spacemove = FALSE + var/drive_verb = "drive" + var/ride_check_rider_incapacitated = FALSE + var/ride_check_rider_restrained = FALSE + var/ride_check_ridden_incapacitated = FALSE + +/datum/component/riding/Initialize() + if(!ismovableatom(parent)) + . = COMPONENT_INCOMPATIBLE + CRASH("RIDING COMPONENT ASSIGNED TO NON ATOM MOVABLE!") + RegisterSignal(COMSIG_MOVABLE_BUCKLE, .proc/vehicle_mob_buckle) + RegisterSignal(COMSIG_MOVABLE_UNBUCKLE, .proc/vehicle_mob_unbuckle) + RegisterSignal(COMSIG_MOVABLE_MOVED, .proc/vehicle_moved) + +/datum/component/riding/proc/vehicle_mob_unbuckle(mob/living/M, force = FALSE) + restore_position(M) + unequip_buckle_inhands(M) + +/datum/component/riding/proc/vehicle_mob_buckle(mob/living/M, force = FALSE) + handle_vehicle_offsets() + +/datum/component/riding/proc/handle_vehicle_layer() + var/atom/movable/AM = parent + var/static/list/defaults = list(TEXT_NORTH = OBJ_LAYER, TEXT_SOUTH = ABOVE_MOB_LAYER, TEXT_EAST = ABOVE_MOB_LAYER, TEXT_WEST = ABOVE_MOB_LAYER) + . = defaults["[AM.dir]"] + if(directional_vehicle_layers["[AM.dir]"]) + . = directional_vehicle_layers["[AM.dir]"] + if(isnull(.)) //you can set it to null to not change it. + . = AM.layer + AM.layer = . + +/datum/component/riding/proc/set_vehicle_dir_layer(dir, layer) + directional_vehicle_layers["[dir]"] = layer + +/datum/component/riding/proc/vehicle_moved() + var/atom/movable/AM = parent + for(var/i in AM.buckled_mobs) + ride_check(i) + handle_vehicle_offsets() + handle_vehicle_layer() + +/datum/component/riding/proc/ride_check(mob/living/M) + var/atom/movable/AM = parent + var/mob/AMM = AM + if((ride_check_rider_restrained && M.restrained(TRUE)) || (ride_check_rider_incapacitated && M.incapacitated(FALSE, TRUE)) || (ride_check_ridden_incapacitated && istype(AMM) && AMM.incapacitated(FALSE, TRUE))) + AM.visible_message("[M] falls off of [AM]!") + AM.unbuckle_mob(M) + return TRUE + +/datum/component/riding/proc/force_dismount(mob/living/M) + var/atom/movable/AM = parent + AM.unbuckle_mob(M) + +/datum/component/riding/proc/handle_vehicle_offsets() + var/atom/movable/AM = parent + var/AM_dir = "[AM.dir]" + var/passindex = 0 + if(AM.has_buckled_mobs()) + for(var/m in AM.buckled_mobs) + passindex++ + var/mob/living/buckled_mob = m + var/list/offsets = get_offsets(passindex) + var/rider_dir = get_rider_dir(passindex) + buckled_mob.setDir(rider_dir) + dir_loop: + for(var/offsetdir in offsets) + if(offsetdir == AM_dir) + var/list/diroffsets = offsets[offsetdir] + buckled_mob.pixel_x = diroffsets[1] + if(diroffsets.len >= 2) + buckled_mob.pixel_y = diroffsets[2] + if(diroffsets.len == 3) + buckled_mob.layer = diroffsets[3] + break dir_loop + var/list/static/default_vehicle_pixel_offsets = list(TEXT_NORTH = list(0, 0), TEXT_SOUTH = list(0, 0), TEXT_EAST = list(0, 0), TEXT_WEST = list(0, 0)) + var/px = default_vehicle_pixel_offsets[AM_dir] + var/py = default_vehicle_pixel_offsets[AM_dir] + if(directional_vehicle_offsets[AM_dir]) + if(isnull(directional_vehicle_offsets[AM_dir])) + px = AM.pixel_x + py = AM.pixel_y + else + px = directional_vehicle_offsets[AM_dir][1] + py = directional_vehicle_offsets[AM_dir][2] + AM.pixel_x = px + AM.pixel_y = py + +/datum/component/riding/proc/set_vehicle_dir_offsets(dir, x, y) + directional_vehicle_offsets["[dir]"] = list(x, y) + +//Override this to set your vehicle's various pixel offsets +/datum/component/riding/proc/get_offsets(pass_index) // list(dir = x, y, layer) + . = list(TEXT_NORTH = list(0, 0), TEXT_SOUTH = list(0, 0), TEXT_EAST = list(0, 0), TEXT_WEST = list(0, 0)) + if(riding_offsets["[pass_index]"]) + . = riding_offsets["[pass_index]"] + else if(riding_offsets["[RIDING_OFFSET_ALL]"]) + . = riding_offsets["[RIDING_OFFSET_ALL]"] + +/datum/component/riding/proc/set_riding_offsets(index, list/offsets) + if(!islist(offsets)) + return FALSE + riding_offsets["[index]"] = offsets + +//Override this to set the passengers/riders dir based on which passenger they are. +//ie: rider facing the vehicle's dir, but passenger 2 facing backwards, etc. +/datum/component/riding/proc/get_rider_dir(pass_index) + var/atom/movable/AM = parent + return AM.dir + +//KEYS +/datum/component/riding/proc/keycheck(mob/user) + return !keytype || user.is_holding_item_of_type(keytype) + +//BUCKLE HOOKS +/datum/component/riding/proc/restore_position(mob/living/buckled_mob) + if(buckled_mob) + buckled_mob.pixel_x = 0 + buckled_mob.pixel_y = 0 + if(buckled_mob.client) + buckled_mob.client.change_view(CONFIG_GET(string/default_view)) + +//MOVEMENT +/datum/component/riding/proc/turf_check(turf/next, turf/current) + if(allowed_turf_typecache && !allowed_turf_typecache[next.type]) + return (allow_one_away_from_valid_turf && allowed_turf_typecache[current.type]) + else if(forbid_turf_typecache && forbid_turf_typecache[next.type]) + return (allow_one_away_from_valid_turf && !forbid_turf_typecache[current.type]) + return TRUE + +/datum/component/riding/proc/handle_ride(mob/user, direction) + var/atom/movable/AM = parent + if(user.incapacitated()) + Unbuckle(user) + return + + if(world.time < next_vehicle_move) + return + next_vehicle_move = world.time + vehicle_move_delay + + if(keycheck(user)) + var/turf/next = get_step(AM, direction) + var/turf/current = get_turf(AM) + if(!istype(next) || !istype(current)) + return //not happening. + if(!turf_check(next, current)) + to_chat(user, "Your \the [AM] can not go onto [next]!") + return + if(!Process_Spacemove(direction) || !isturf(AM.loc)) + return + step(AM, direction) + + handle_vehicle_layer() + handle_vehicle_offsets() + else + to_chat(user, "You'll need the keys in one of your hands to [drive_verb] [AM].") + +/datum/component/riding/proc/Unbuckle(atom/movable/M) + addtimer(CALLBACK(parent, /atom/movable/.proc/unbuckle_mob, M), 0, TIMER_UNIQUE) + +/datum/component/riding/proc/Process_Spacemove(direction) + var/atom/movable/AM = parent + return override_allow_spacemove || AM.has_gravity() + +/datum/component/riding/proc/account_limbs(mob/living/M) + if(M.get_num_legs() < 2 && !slowed) + vehicle_move_delay = vehicle_move_delay + slowvalue + slowed = TRUE + else if(slowed) + vehicle_move_delay = vehicle_move_delay - slowvalue + slowed = FALSE + +///////Yes, I said humans. No, this won't end well...////////// +/datum/component/riding/human + +/datum/component/riding/human/Initialize() + . = ..() + RegisterSignal(COMSIG_HUMAN_MELEE_UNARMED_ATTACK, .proc/on_host_unarmed_melee) + +/datum/component/riding/human/proc/on_host_unarmed_melee(atom/target) + var/mob/living/carbon/human/AM = parent + if(AM.a_intent == INTENT_DISARM && (target in AM.buckled_mobs)) + force_dismount(target) + +/datum/component/riding/human/handle_vehicle_layer() + var/atom/movable/AM = parent + if(AM.buckled_mobs && AM.buckled_mobs.len) + if(AM.dir == SOUTH) + AM.layer = ABOVE_MOB_LAYER + else + AM.layer = OBJ_LAYER + else + AM.layer = MOB_LAYER + +/datum/component/riding/human/force_dismount(mob/living/user) + var/atom/movable/AM = parent + AM.unbuckle_mob(user) + user.Knockdown(60) + user.visible_message("[AM] pushes [user] off of them!") + +/datum/component/riding/cyborg + +/datum/component/riding/cyborg/ride_check(mob/user) + var/atom/movable/AM = parent + if(user.incapacitated()) + var/kick = TRUE + if(iscyborg(AM)) + var/mob/living/silicon/robot/R = AM + if(R.module && R.module.ride_allow_incapacitated) + kick = FALSE + if(kick) + to_chat(user, "You fall off of [AM]!") + Unbuckle(user) + return + if(iscarbon(user)) + var/mob/living/carbon/carbonuser = user + if(!carbonuser.get_num_arms()) + Unbuckle(user) + to_chat(user, "You can't grab onto [AM] with no hands!") + return + +/datum/component/riding/cyborg/handle_vehicle_layer() + var/atom/movable/AM = parent + if(AM.buckled_mobs && AM.buckled_mobs.len) + if(AM.dir == SOUTH) + AM.layer = ABOVE_MOB_LAYER + else + AM.layer = OBJ_LAYER + else + AM.layer = MOB_LAYER + +/datum/component/riding/cyborg/get_offsets(pass_index) // list(dir = x, y, layer) + return list(TEXT_NORTH = list(0, 4), TEXT_SOUTH = list(0, 4), TEXT_EAST = list(-6, 3), TEXT_WEST = list( 6, 3)) + +/datum/component/riding/cyborg/handle_vehicle_offsets() + var/atom/movable/AM = parent + if(AM.has_buckled_mobs()) + for(var/mob/living/M in AM.buckled_mobs) + M.setDir(AM.dir) + if(iscyborg(AM)) + var/mob/living/silicon/robot/R = AM + if(istype(R.module)) + M.pixel_x = R.module.ride_offset_x[dir2text(AM.dir)] + M.pixel_y = R.module.ride_offset_y[dir2text(AM.dir)] + else + ..() + +/datum/component/riding/cyborg/force_dismount(mob/living/M) + var/atom/movable/AM = parent + AM.unbuckle_mob(M) + var/turf/target = get_edge_target_turf(AM, AM.dir) + var/turf/targetm = get_step(get_turf(AM), AM.dir) + M.Move(targetm) + M.visible_message("[M] is thrown clear of [AM]!") + M.throw_at(target, 14, 5, AM) + M.Knockdown(60) + +/datum/component/riding/proc/equip_buckle_inhands(mob/living/carbon/human/user, amount_required = 1) + var/atom/movable/AM = parent + var/amount_equipped = 0 + for(var/amount_needed = amount_required, amount_needed > 0, amount_needed--) + var/obj/item/riding_offhand/inhand = new /obj/item/riding_offhand(user) + inhand.rider = user + inhand.parent = AM + if(user.put_in_hands(inhand, TRUE)) + amount_equipped++ + else + break + if(amount_equipped >= amount_required) + return TRUE + else + unequip_buckle_inhands(user) + return FALSE + +/datum/component/riding/proc/unequip_buckle_inhands(mob/living/carbon/user) + var/atom/movable/AM = parent + for(var/obj/item/riding_offhand/O in user.contents) + if(O.parent != AM) + CRASH("RIDING OFFHAND ON WRONG MOB") + continue + if(O.selfdeleting) + continue + else + qdel(O) + return TRUE + +/obj/item/riding_offhand + name = "offhand" + icon = 'icons/obj/items_and_weapons.dmi' + icon_state = "offhand" + w_class = WEIGHT_CLASS_HUGE + flags_1 = ABSTRACT_1 | DROPDEL_1 | NOBLUDGEON_1 + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF + var/mob/living/carbon/rider + var/mob/living/parent + var/selfdeleting = FALSE + +/obj/item/riding_offhand/dropped() + selfdeleting = TRUE + . = ..() + +/obj/item/riding_offhand/equipped() + if(loc != rider) + selfdeleting = TRUE + qdel(src) + . = ..() + +/obj/item/riding_offhand/Destroy() + var/atom/movable/AM = parent + if(selfdeleting) + if(rider in AM.buckled_mobs) + AM.unbuckle_mob(rider) + . = ..() diff --git a/code/datums/components/slippery.dm b/code/datums/components/slippery.dm index 573bb81d11..24cb22020d 100644 --- a/code/datums/components/slippery.dm +++ b/code/datums/components/slippery.dm @@ -1,18 +1,15 @@ /datum/component/slippery var/intensity var/lube_flags - var/mob/slip_victim + var/datum/callback/callback -/datum/component/slippery/Initialize(_intensity, _lube_flags = NONE) +/datum/component/slippery/Initialize(_intensity, _lube_flags = NONE, datum/callback/_callback) intensity = max(_intensity, 0) lube_flags = _lube_flags + callback = _callback RegisterSignal(list(COMSIG_MOVABLE_CROSSED, COMSIG_ATOM_ENTERED), .proc/Slip) /datum/component/slippery/proc/Slip(atom/movable/AM) var/mob/victim = AM - if(istype(victim) && !victim.is_flying() && victim.slip(intensity, parent, lube_flags)) - slip_victim = victim - return TRUE - -/datum/component/slippery/AfterComponentActivated() - slip_victim = null + if(istype(victim) && !victim.is_flying() && victim.slip(intensity, parent, lube_flags) && callback) + callback.Invoke(victim) diff --git a/code/datums/components/spooky.dm b/code/datums/components/spooky.dm index 966baf7c4a..3f3b0341ee 100644 --- a/code/datums/components/spooky.dm +++ b/code/datums/components/spooky.dm @@ -19,7 +19,7 @@ if(ishuman(C)) var/mob/living/carbon/human/H = C if(istype(H.dna.species, /datum/species/skeleton)) - return ..() //undeads are unaffected by the spook-pocalypse. + return //undeads are unaffected by the spook-pocalypse. if(istype(H.dna.species, /datum/species/zombie)) H.adjustStaminaLoss(25) H.Knockdown(15) //zombies can't resist the doot diff --git a/code/datums/components/thermite.dm b/code/datums/components/thermite.dm index f76178213d..11611cadfb 100644 --- a/code/datums/components/thermite.dm +++ b/code/datums/components/thermite.dm @@ -1,5 +1,5 @@ /datum/component/thermite - dupe_mode = COMPONENT_DUPE_UNIQUE + dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS var/amount var/overlay @@ -46,10 +46,13 @@ master.cut_overlay(overlay) return ..() -/datum/component/thermite/InheritComponent(datum/component/thermite/newC, i_am_original) +/datum/component/thermite/InheritComponent(datum/component/thermite/newC, i_am_original, list/arguments) if(!i_am_original) return - amount += newC.amount + if(newC) + amount += newC.amount + else + amount += arguments[1] /datum/component/thermite/proc/thermite_melt(mob/user) var/turf/master = parent diff --git a/code/datums/dash_weapon.dm b/code/datums/dash_weapon.dm index 1637655d18..03badb2069 100644 --- a/code/datums/dash_weapon.dm +++ b/code/datums/dash_weapon.dm @@ -43,7 +43,7 @@ addtimer(CALLBACK(src, .proc/charge), charge_rate) /datum/action/innate/dash/proc/charge() - current_charges = Clamp(current_charges + 1, 0, max_charges) + current_charges = CLAMP(current_charges + 1, 0, max_charges) holder.update_action_buttons_icon() if(recharge_sound) playsound(dashing_item, recharge_sound, 50, 1) diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index c609e63f0f..1df8d60d39 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -104,15 +104,7 @@ else atomsnowflake += "[D]" - var/formatted_type = "[type]" - if(length(formatted_type) > 25) - var/middle_point = length(formatted_type) / 2 - var/splitpoint = findtext(formatted_type,"/",middle_point) - if(splitpoint) - formatted_type = "[copytext(formatted_type,1,splitpoint)]
[copytext(formatted_type,splitpoint)]" - else - formatted_type = "Type too long" //No suitable splitpoint (/) found. - + var/formatted_type = replacetext("[type]", "/", "/") var/marked if(holder && holder.marked_datum && holder.marked_datum == D) marked = "
Marked Object" @@ -748,6 +740,28 @@ src.give_disease(M) href_list["datumrefresh"] = href_list["give_spell"] + else if(href_list["ninja"]) + if(!check_rights(R_FUN)) + return + + var/mob/living/carbon/human/M = locate(href_list["ninja"]) in GLOB.carbon_list + if(!istype(M)) + to_chat(usr, "This can only be used on instances of type /mob") + return + + if(tgalert(usr, "Are you sure you want to make [M] into a ninja?", "Confirmation", "Yes", "No") == "No") + return + + if(!M.mind) + M.mind_initialize() + + var/datum/antagonist/ninja/hiyah = M.mind.has_antag_datum(/datum/antagonist/ninja) + if(!hiyah) + hiyah = add_ninja(M) + if(hiyah) + hiyah.equip_space_ninja() + href_list["datumrefresh"] = href_list["ninja"] + else if(href_list["gib"]) if(!check_rights(R_FUN)) return @@ -940,6 +954,42 @@ manipulate_organs(C) href_list["datumrefresh"] = href_list["editorgans"] + else if(href_list["givetrauma"]) + if(!check_rights(0)) + return + + var/mob/living/carbon/C = locate(href_list["givetrauma"]) in GLOB.mob_list + if(!istype(C)) + to_chat(usr, "This can only be done to instances of type /mob/living/carbon") + return + + var/list/traumas = subtypesof(/datum/brain_trauma) + var/result = input(usr, "Choose the brain trauma to apply","Traumatize") as null|anything in traumas + var/permanent = alert("Do you want to make the trauma unhealable?", "Permanently Traumatize", "Yes", "No") + if(!usr) + return + if(QDELETED(C)) + to_chat(usr, "Mob doesn't exist anymore") + return + + if(result) + C.gain_trauma(result, permanent) + + href_list["datumrefresh"] = href_list["givetrauma"] + + else if(href_list["curetraumas"]) + if(!check_rights(0)) + return + + var/mob/living/carbon/C = locate(href_list["curetraumas"]) in GLOB.mob_list + if(!istype(C)) + to_chat(usr, "This can only be done to instances of type /mob/living/carbon") + return + + C.cure_all_traumas(TRUE, TRUE) + + href_list["datumrefresh"] = href_list["curetraumas"] + else if(href_list["hallucinate"]) if(!check_rights(0)) return diff --git a/code/datums/diseases/_MobProcs.dm b/code/datums/diseases/_MobProcs.dm index f13239a113..7c08a3908f 100644 --- a/code/datums/diseases/_MobProcs.dm +++ b/code/datums/diseases/_MobProcs.dm @@ -143,14 +143,25 @@ //Proc to use when you 100% want to infect someone, as long as they aren't immune /mob/proc/ForceContractDisease(datum/disease/D) if(!CanContractDisease(D)) - return 0 + return FALSE AddDisease(D) /mob/living/carbon/human/CanContractDisease(datum/disease/D) - if(dna && (VIRUSIMMUNE in dna.species.species_traits) && !D.bypasses_immunity) - return 0 + + if(dna) + if((VIRUSIMMUNE in dna.species.species_traits) && !D.bypasses_immunity) + return FALSE + + var/can_infect = FALSE + for(var/host_type in D.infectable_hosts) + if(host_type in dna.species.species_traits) + can_infect = TRUE + break + if(!can_infect) + return FALSE + for(var/thing in D.required_organs) if(!((locate(thing) in bodyparts) || (locate(thing) in internal_organs))) - return 0 + return FALSE return ..() \ No newline at end of file diff --git a/code/datums/diseases/_disease.dm b/code/datums/diseases/_disease.dm index 69da2ab96d..951edece23 100644 --- a/code/datums/diseases/_disease.dm +++ b/code/datums/diseases/_disease.dm @@ -30,6 +30,8 @@ var/list/required_organs = list() var/needs_all_cures = TRUE var/list/strain_data = list() //dna_spread special bullshit + var/list/infectable_hosts = list(SPECIES_ORGANIC) //if the disease can spread on organics, synthetics, or undead + var/process_dead = FALSE //if this ticks while the host is dead /datum/disease/Destroy() affected_mob = null @@ -101,8 +103,9 @@ /datum/disease/proc/cure(add_resistance = TRUE) if(affected_mob) if(disease_flags & CAN_RESIST) - if(add_resistance && !(type in affected_mob.resistances)) - affected_mob.resistances += type + var/id = GetDiseaseID() + if(add_resistance && !(id in affected_mob.resistances)) + affected_mob.resistances += id remove_virus() qdel(src) @@ -119,7 +122,7 @@ /datum/disease/proc/GetDiseaseID() - return type + return "[type]" //don't use this proc directly. this should only ever be called by cure() /datum/disease/proc/remove_virus() diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm index bbe98ff18d..60f90d61ad 100644 --- a/code/datums/diseases/advance/advance.dm +++ b/code/datums/diseases/advance/advance.dm @@ -95,15 +95,6 @@ return 0 return 1 -// To add special resistances. -/datum/disease/advance/cure(resistance=1) - if(affected_mob) - var/id = "[GetDiseaseID()]" - if(resistance && !(id in affected_mob.resistances)) - affected_mob.resistances[id] = id - remove_virus() - qdel(src) //delete the datum to stop it processing - // Returns the advance disease with a different reference memory. /datum/disease/advance/Copy(process = 0) return new /datum/disease/advance(process, src, 1) @@ -194,10 +185,10 @@ if(properties["stealth"] >= 2) visibility_flags = HIDDEN_SCANNER - SetSpread(Clamp(2 ** (properties["transmittable"] - symptoms.len), VIRUS_SPREAD_BLOOD, VIRUS_SPREAD_AIRBORNE)) + SetSpread(CLAMP(2 ** (properties["transmittable"] - symptoms.len), VIRUS_SPREAD_BLOOD, VIRUS_SPREAD_AIRBORNE)) - permeability_mod = max(Ceiling(0.4 * properties["transmittable"]), 1) - cure_chance = 15 - Clamp(properties["resistance"], -5, 5) // can be between 10 and 20 + permeability_mod = max(CEILING(0.4 * properties["transmittable"], 1), 1) + cure_chance = 15 - CLAMP(properties["resistance"], -5, 5) // can be between 10 and 20 stage_prob = max(properties["stage_rate"], 2) SetSeverity(properties["severity"]) GenerateCure(properties) @@ -252,7 +243,7 @@ // Will generate a random cure, the less resistance the symptoms have, the harder the cure. /datum/disease/advance/proc/GenerateCure() if(properties && properties.len) - var/res = Clamp(properties["resistance"] - (symptoms.len / 2), 1, advance_cures.len) + var/res = CLAMP(properties["resistance"] - (symptoms.len / 2), 1, advance_cures.len) cures = list(advance_cures[res]) // Get the cure name from the cure_id diff --git a/code/datums/diseases/advance/symptoms/confusion.dm b/code/datums/diseases/advance/symptoms/confusion.dm index 04418610e5..209c7b0bf6 100644 --- a/code/datums/diseases/advance/symptoms/confusion.dm +++ b/code/datums/diseases/advance/symptoms/confusion.dm @@ -54,8 +54,8 @@ Bonus else to_chat(M, "You can't think straight!") M.confused = min(100 * power, M.confused + 8) - if(brain_damage && M.getBrainLoss()<=80) - M.adjustBrainLoss(5 * power) + if(brain_damage) + M.adjustBrainLoss(3 * power, 80) M.updatehealth() return diff --git a/code/datums/diseases/advance/symptoms/heal.dm b/code/datums/diseases/advance/symptoms/heal.dm index 4fba54121f..104a4c00c2 100644 --- a/code/datums/diseases/advance/symptoms/heal.dm +++ b/code/datums/diseases/advance/symptoms/heal.dm @@ -9,20 +9,15 @@ base_message_chance = 20 //here used for the overlays symptom_delay_min = 1 symptom_delay_max = 1 - var/hide_healing = FALSE + var/passive_message = "" //random message to infected but not actively healing people threshold_desc = "Stage Speed 6: Doubles healing speed.
\ - Stage Speed 11: Triples healing speed.
\ Stealth 4: Healing will no longer be visible to onlookers." /datum/symptom/heal/Start(datum/disease/advance/A) if(!..()) return - if(A.properties["stealth"] >= 4) //invisible healing - hide_healing = TRUE if(A.properties["stage_rate"] >= 6) //stronger healing power = 2 - if(A.properties["stage_rate"] >= 11) //even stronger healing - power = 3 /datum/symptom/heal/Activate(datum/disease/advance/A) if(!..()) @@ -31,299 +26,439 @@ var/mob/living/M = A.affected_mob switch(A.stage) if(4, 5) - Heal(M, A) + var/effectiveness = CanHeal(A) + if(!effectiveness) + if(passive_message && prob(2) && passive_message_condition(M)) + to_chat(M, passive_message) + return + else + Heal(M, A, effectiveness) return -/datum/symptom/heal/proc/Heal(mob/living/M, datum/disease/advance/A) - return 1 +/datum/symptom/heal/proc/CanHeal(datum/disease/advance/A) + return power -/* -////////////////////////////////////// +/datum/symptom/heal/proc/Heal(mob/living/M, datum/disease/advance/A, actual_power) + return TRUE -Toxin Filter +/datum/symptom/heal/proc/passive_message_condition(mob/living/M) + return TRUE - Little bit hidden. - Lowers resistance tremendously. - Decreases stage speed tremendously. - Decreases transmittablity temrendously. - Fatal Level. - -Bonus - Heals toxins in the affected mob's blood stream. - -////////////////////////////////////// -*/ /datum/symptom/heal/toxin - name = "Toxic Filter" - desc = "The virus synthesizes regenerative chemicals in the bloodstream, repairing damage caused by toxins." + name = "Starlight Condensation" + desc = "The virus reacts to direct starlight, producing regenerative chemicals that can cure toxin damage." stealth = 1 - resistance = -4 - stage_speed = -4 - transmittable = -4 + resistance = -3 + stage_speed = -3 + transmittable = -3 level = 6 + passive_message = "You miss the feeling of starlight on your skin." + var/nearspace_penalty = 0.3 + threshold_desc = "Stage Speed 6: Increases healing speed.
\ + Transmission 6: Removes penalty for only being close to space." -/datum/symptom/heal/toxin/Heal(mob/living/M, datum/disease/advance/A) - var/heal_amt = 1 * power - if(M.toxloss > 0 && prob(base_message_chance) && !hide_healing) - new /obj/effect/temp_visual/heal(get_turf(M), "#66FF99") +/datum/symptom/heal/toxin/Start(datum/disease/advance/A) + if(!..()) + return + if(A.properties["transmission"] >= 6) + nearspace_penalty = 1 + if(A.properties["stage_rate"] >= 6) + power = 2 + +/datum/symptom/heal/toxin/CanHeal(datum/disease/advance/A) + var/mob/living/M = A.affected_mob + if(istype(get_turf(M), /turf/open/space)) + return power + else + for(var/turf/T in view(M, 2)) + if(istype(T, /turf/open/space)) + return power * nearspace_penalty + +/datum/symptom/heal/toxin/Heal(mob/living/M, datum/disease/advance/A, actual_power) + var/heal_amt = actual_power + if(M.getToxLoss() && prob(5)) + to_chat(M, "Your skin tingles as the starlight purges toxins from your bloodstream.") M.adjustToxLoss(-heal_amt) return 1 -/* -////////////////////////////////////// +/datum/symptom/heal/toxin/passive_message_condition(mob/living/M) + if(M.getToxLoss()) + return TRUE + return FALSE -Apoptosis - - Lowers resistance. - Decreases stage speed. - Decreases transmittablity. - -Bonus - Heals toxins in the affected mob's blood stream faster. - -////////////////////////////////////// -*/ - -/datum/symptom/heal/toxin/plus - - name = "Apoptoxin filter" +/datum/symptom/heal/chem + name = "Toxolysis" stealth = 0 resistance = -2 stage_speed = -2 transmittable = -2 - level = 8 - desc = "The virus stimulates production of special stem cells in the bloodstream, causing rapid reparation of any damage caused by toxins." + level = 7 + var/food_conversion = FALSE + desc = "The virus rapidly breaks down any foreign chemicals in the bloodstream." + threshold_desc = "Resistance 7: Increases chem removal speed.
\ + Stage Speed 6: Consumed chemicals nourish the host." -/datum/symptom/heal/toxin/plus/Heal(mob/living/M, datum/disease/advance/A) - var/heal_amt = 2 * power - if(M.toxloss > 0 && prob(base_message_chance) && !hide_healing) - new /obj/effect/temp_visual/heal(get_turf(M), "#00FF00") - M.adjustToxLoss(-heal_amt) +/datum/symptom/heal/chem/Start(datum/disease/advance/A) + if(!..()) + return + if(A.properties["stage_rate"] >= 6) + food_conversion = TRUE + if(A.properties["resistance"] >= 7) + power = 2 + +/datum/symptom/heal/chem/Heal(mob/living/M, datum/disease/advance/A, actual_power) + for(var/datum/reagent/R in M.reagents.reagent_list) //Not just toxins! + M.reagents.remove_reagent(R.id, actual_power) + if(food_conversion) + M.nutrition += 0.3 + if(prob(2)) + to_chat(M, "You feel a mild warmth as your blood purifies itself.") return 1 -/* -////////////////////////////////////// -Regeneration - Little bit hidden. - Lowers resistance tremendously. - Decreases stage speed tremendously. - Decreases transmittablity temrendously. - Fatal Level. +/datum/symptom/heal/metabolism + name = "Metabolic Boost" + stealth = -1 + resistance = -2 + stage_speed = 2 + transmittable = 1 + level = 7 + var/triple_metabolism = FALSE + var/reduced_hunger = FALSE + desc = "The virus causes the host's metabolism to accelerate rapidly, making them process chemicals twice as fast,\ + but also causing increased hunger." + threshold_desc = "Stealth 3: Reduces hunger rate.
\ + Stage Speed 10: Chemical metabolization is tripled instead of doubled." -Bonus - Heals brute damage slowly over time. +/datum/symptom/heal/metabolism/Start(datum/disease/advance/A) + if(!..()) + return + if(A.properties["stage_rate"] >= 10) + triple_metabolism = TRUE + if(A.properties["stealth"] >= 3) + reduced_hunger = TRUE -////////////////////////////////////// -*/ +/datum/symptom/heal/metabolism/Heal(mob/living/carbon/C, datum/disease/advance/A, actual_power) + if(!istype(C)) + return + C.reagents.metabolize(C, can_overdose=TRUE) //this works even without a liver; it's intentional since the virus is metabolizing by itself + if(triple_metabolism) + C.reagents.metabolize(C, can_overdose=TRUE) + C.overeatduration = max(C.overeatduration - 2, 0) + var/lost_nutrition = 9 - (reduced_hunger * 5) + C.nutrition = max(C.nutrition - (lost_nutrition * HUNGER_FACTOR), 0) //Hunger depletes at 10x the normal speed + if(prob(2)) + to_chat(C, "You feel an odd gurgle in your stomach, as if it was working much faster than normal.") + return 1 /datum/symptom/heal/brute - - name = "Regeneration" - desc = "The virus stimulates the regenerative process in the host, causing faster wound healing." + name = "Cellular Molding" + desc = "The virus is able to shift cells around when in conditions of high heat, repairing existing physical damage." stealth = 1 - resistance = -4 - stage_speed = -4 - transmittable = -4 + resistance = -3 + stage_speed = -3 + transmittable = -3 level = 6 + passive_message = "You feel the flesh pulsing under your skin for a moment, but it's too cold to move." + threshold_desc = "Stage Speed 8: Doubles healing speed." -/datum/symptom/heal/brute/Heal(mob/living/carbon/M, datum/disease/advance/A) - var/heal_amt = 2 * power +/datum/symptom/heal/brute/Start(datum/disease/advance/A) + if(!..()) + return + if(A.properties["stage_rate"] >= 8) + power = 2 + +/datum/symptom/heal/brute/CanHeal(datum/disease/advance/A) + var/mob/living/M = A.affected_mob + switch(M.bodytemperature) + if(0 to 340) + return FALSE + if(340 to BODYTEMP_HEAT_DAMAGE_LIMIT) + . = 0.3 * power + if(BODYTEMP_HEAT_DAMAGE_LIMIT to 400) + . = 0.75 * power + if(400 to 460) + . = power + else + . = 1.5 * power + + if(M.on_fire) + . *= 2 + +/datum/symptom/heal/brute/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power) + var/heal_amt = 2 * actual_power var/list/parts = M.get_damaged_bodyparts(1,0) //brute only if(!parts.len) return + if(prob(5)) + to_chat(M, "You feel your flesh moving beneath your heated skin, mending your wounds.") + for(var/obj/item/bodypart/L in parts) if(L.heal_damage(heal_amt/parts.len, 0)) M.update_damage_overlays() - - if(prob(base_message_chance) && !hide_healing) - new /obj/effect/temp_visual/heal(get_turf(M), "#FF3333") - return 1 +/datum/symptom/heal/brute/passive_message_condition(mob/living/M) + if(M.getBruteLoss()) + return TRUE + return FALSE -/* -////////////////////////////////////// - -Flesh Mending - - No resistance change. - Decreases stage speed. - Decreases transmittablity. - Fatal Level. - -Bonus - Heals brute damage over time. Turns cloneloss into burn damage. - -////////////////////////////////////// -*/ - -/datum/symptom/heal/brute/plus - - name = "Flesh Mending" - desc = "The virus rapidly mutates into body cells, effectively allowing it to quickly fix the host's wounds." +/datum/symptom/heal/coma + name = "Regenerative Coma" + desc = "The virus causes the host to fall into a death-like coma when severely damaged, then rapidly fixes the damage." stealth = 0 resistance = 0 stage_speed = -2 transmittable = -2 level = 8 + passive_message = "The pain from your wounds makes you feel oddly sleepy..." + var/deathgasp = FALSE + var/active_coma = FALSE //to prevent multiple coma procs + threshold_desc = "Stealth 2: Host appears to die when falling into a coma.
\ + Stage Speed 7: Increases healing speed." -/datum/symptom/heal/brute/plus/Heal(mob/living/carbon/M, datum/disease/advance/A) - var/heal_amt = 4 * power +/datum/symptom/heal/coma/Start(datum/disease/advance/A) + if(!..()) + return + if(A.properties["stage_rate"] >= 7) + power = 1.5 + if(A.properties["stealth"] >= 2) + deathgasp = TRUE - var/list/parts = M.get_damaged_bodyparts(1,0) //brute only +/datum/symptom/heal/coma/CanHeal(datum/disease/advance/A) + var/mob/living/M = A.affected_mob + if(M.status_flags & FAKEDEATH) + return power + else if(M.IsUnconscious() || M.stat == UNCONSCIOUS) + return power * 0.9 + else if(M.stat == SOFT_CRIT) + return power * 0.5 + else if(M.IsSleeping()) + return power * 0.25 + else if(M.getBruteLoss() + M.getFireLoss() >= 70 && !active_coma) + to_chat(M, "You feel yourself slip into a regenerative coma...") + active_coma = TRUE + addtimer(CALLBACK(src, .proc/coma, M), 60) - if(M.getCloneLoss() > 0) - M.adjustCloneLoss(-1) - M.take_bodypart_damage(0, 1) //Deals BURN damage, which is not cured by this symptom - if(!hide_healing) - new /obj/effect/temp_visual/heal(get_turf(M), "#33FFCC") +/datum/symptom/heal/coma/proc/coma(mob/living/M) + if(deathgasp) + M.emote("deathgasp") + M.status_flags |= FAKEDEATH + M.update_stat() + M.update_canmove() + addtimer(CALLBACK(src, .proc/uncoma, M), 300) + +/datum/symptom/heal/coma/proc/uncoma(mob/living/M) + if(!active_coma) + return + active_coma = FALSE + M.status_flags &= ~FAKEDEATH + M.update_stat() + M.update_canmove() + +/datum/symptom/heal/coma/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power) + var/heal_amt = 4 * actual_power + + var/list/parts = M.get_damaged_bodyparts(1,1) if(!parts.len) return for(var/obj/item/bodypart/L in parts) - if(L.heal_damage(heal_amt/parts.len, 0)) + if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len)) M.update_damage_overlays() - if(prob(base_message_chance) && !hide_healing) - new /obj/effect/temp_visual/heal(get_turf(M), "#CC1100") + if(active_coma && M.getBruteLoss() + M.getFireLoss() == 0) + uncoma(M) return 1 -/* -////////////////////////////////////// - -Tissue Regrowth - - Little bit hidden. - Lowers resistance tremendously. - Decreases stage speed tremendously. - Decreases transmittablity temrendously. - Fatal Level. - -Bonus - Heals burn damage slowly over time. - -////////////////////////////////////// -*/ +/datum/symptom/heal/coma/passive_message_condition(mob/living/M) + if((M.getBruteLoss() + M.getFireLoss()) > 30) + return TRUE + return FALSE /datum/symptom/heal/burn - - name = "Tissue Regrowth" - desc = "The virus recycles dead and burnt tissues, speeding up the healing of damage caused by burns." + name = "Tissue Hydration" + desc = "The virus uses excess water inside and outside the body to repair burned tisue cells." stealth = 1 - resistance = -4 - stage_speed = -4 - transmittable = -4 + resistance = -3 + stage_speed = -3 + transmittable = -3 level = 6 + passive_message = "Your burned skin feels oddly dry..." + var/absorption_coeff = 1 + threshold_desc = "Resistance 5: Water is consumed at a much slower rate.
\ + Stage Speed 7: Increases healing speed." -/datum/symptom/heal/burn/Heal(mob/living/carbon/M, datum/disease/advance/A) - var/heal_amt = 2 * power +/datum/symptom/heal/burn/Start(datum/disease/advance/A) + if(!..()) + return + if(A.properties["stage_rate"] >= 7) + power = 2 + if(A.properties["stealth"] >= 2) + absorption_coeff = 0.25 + +/datum/symptom/heal/burn/CanHeal(datum/disease/advance/A) + . = 0 + var/mob/living/M = A.affected_mob + if(M.fire_stacks < 0) + M.fire_stacks = min(M.fire_stacks + 1 * absorption_coeff, 0) + . += power + if(M.reagents.has_reagent("holywater")) + M.reagents.remove_reagent("holywater", 0.5 * absorption_coeff) + . += power * 0.75 + else if(M.reagents.has_reagent("water")) + M.reagents.remove_reagent("water", 0.5 * absorption_coeff) + . += power * 0.5 + +/datum/symptom/heal/burn/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power) + var/heal_amt = 2 * actual_power var/list/parts = M.get_damaged_bodyparts(0,1) //burn only if(!parts.len) return + if(prob(5)) + to_chat(M, "You feel yourself absorbing the water around you to soothe your burned skin.") + for(var/obj/item/bodypart/L in parts) if(L.heal_damage(0, heal_amt/parts.len)) M.update_damage_overlays() - if(prob(base_message_chance) && !hide_healing) - new /obj/effect/temp_visual/heal(get_turf(M), "#FF9933") return 1 +/datum/symptom/heal/burn/passive_message_condition(mob/living/M) + if(M.getFireLoss()) + return TRUE + return FALSE -/* -////////////////////////////////////// - -Heat Resistance //Needs a better name - - No resistance change. - Decreases stage speed. - Decreases transmittablity. - Fatal Level. - -Bonus - Heals burn damage over time, and helps stabilize body temperature. - -////////////////////////////////////// -*/ - -/datum/symptom/heal/burn/plus - - name = "Temperature Adaptation" - desc = "The virus quickly balances body heat, while also replacing tissues damaged by external sources." +/datum/symptom/heal/plasma + name = "Plasma Fixation" + desc = "The virus draws plasma from the atmosphere and from inside the body to stabilize body temperature and heal burns." stealth = 0 resistance = 0 stage_speed = -2 transmittable = -2 level = 8 + passive_message = "You feel an odd attraction to plasma." + var/temp_rate = 1 + threshold_desc = "Transmission 6: Increases temperature adjustment rate.
\ + Stage Speed 7: Increases healing speed." -/datum/symptom/heal/burn/plus/Heal(mob/living/carbon/M, datum/disease/advance/A) - var/heal_amt = 4 * power +/datum/symptom/heal/plasma/Start(datum/disease/advance/A) + if(!..()) + return + if(A.properties["stage_rate"] >= 7) + power = 2 + if(A.properties["trasmission"] >= 6) + temp_rate = 4 + +/datum/symptom/heal/plasma/CanHeal(datum/disease/advance/A) + var/mob/living/M = A.affected_mob + var/datum/gas_mixture/environment + var/list/gases + + . = 0 + + if(M.loc) + environment = M.loc.return_air() + if(environment) + gases = environment.gases + if(gases["plasma"] && gases["plasma"][MOLES] > gases["plasma"][GAS_META][META_GAS_MOLES_VISIBLE]) //if there's enough plasma in the air to see + . += power * 0.5 + if(M.reagents.has_reagent("plasma")) + . += power * 0.75 + +/datum/symptom/heal/plasma/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power) + var/heal_amt = 4 * actual_power var/list/parts = M.get_damaged_bodyparts(0,1) //burn only + if(prob(5)) + to_chat(M, "You feel yourself absorbing plasma inside and around you...") + if(M.bodytemperature > 310) - M.bodytemperature = max(310, M.bodytemperature - (10 * heal_amt * TEMPERATURE_DAMAGE_COEFFICIENT)) + M.bodytemperature = max(310, M.bodytemperature - (20 * temp_rate * TEMPERATURE_DAMAGE_COEFFICIENT)) + if(prob(5)) + to_chat(M, "You feel less hot.") else if(M.bodytemperature < 311) - M.bodytemperature = min(310, M.bodytemperature + (10 * heal_amt * TEMPERATURE_DAMAGE_COEFFICIENT)) + M.bodytemperature = min(310, M.bodytemperature + (20 * temp_rate * TEMPERATURE_DAMAGE_COEFFICIENT)) + if(prob(5)) + to_chat(M, "You feel warmer.") if(!parts.len) return + if(prob(5)) + to_chat(M, "The pain from your burns fades rapidly.") for(var/obj/item/bodypart/L in parts) if(L.heal_damage(0, heal_amt/parts.len)) M.update_damage_overlays() - - if(prob(base_message_chance) && !hide_healing) - new /obj/effect/temp_visual/heal(get_turf(M), "#CC6600") return 1 -/* -////////////////////////////////////// - DNA Restoration - - Not well hidden. - Lowers resistance minorly. - Does not affect stage speed. - Decreases transmittablity greatly. - Very high level. - -Bonus - Heals brain damage, treats radiation, cleans SE of non-power mutations. - -////////////////////////////////////// -*/ - -/datum/symptom/heal/dna - - name = "Deoxyribonucleic Acid Restoration" - desc = "The virus repairs the host's genome, purging negative mutations." +/datum/symptom/heal/radiation + name = "Radioactive Resonance" + desc = "The virus uses radiation to fix damage through dna mutations." stealth = -1 - resistance = -1 + resistance = -2 stage_speed = 0 transmittable = -3 - level = 5 - symptom_delay_min = 3 - symptom_delay_max = 8 - threshold_desc = "Stage Speed 6: Additionally heals brain damage.
\ - Stage Speed 11: Increases brain damage healing." + level = 6 + symptom_delay_min = 1 + symptom_delay_max = 1 + passive_message = "Your skin glows faintly for a moment." + var/cellular_damage = FALSE + threshold_desc = "Transmission 6: Additionally heals cellular damage.
\ + Resistance 7: Increases healing speed." -/datum/symptom/heal/dna/Heal(mob/living/carbon/M, datum/disease/advance/A) - var/amt_healed = 2 * (power - 1) - M.adjustBrainLoss(-amt_healed) - //Non-power mutations, excluding race, so the virus does not force monkey -> human transformations. - var/list/unclean_mutations = (GLOB.not_good_mutations|GLOB.bad_mutations) - GLOB.mutations_list[RACEMUT] - M.dna.remove_mutation_group(unclean_mutations) - M.radiation = max(M.radiation - (2 * amt_healed), 0) +/datum/symptom/heal/radiation/Start(datum/disease/advance/A) + if(!..()) + return + if(A.properties["resistance"] >= 7) + power = 2 + if(A.properties["trasmission"] >= 6) + cellular_damage = TRUE + +/datum/symptom/heal/radiation/CanHeal(datum/disease/advance/A) + var/mob/living/M = A.affected_mob + switch(M.radiation) + if(0) + return FALSE + if(1 to RAD_MOB_SAFE) + return 0.25 + if(RAD_MOB_SAFE to RAD_BURN_THRESHOLD) + return 0.5 + if(RAD_BURN_THRESHOLD to RAD_MOB_MUTATE) + return 0.75 + if(RAD_MOB_MUTATE to RAD_MOB_KNOCKDOWN) + return 1 + else + return 1.5 + +/datum/symptom/heal/radiation/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power) + var/heal_amt = actual_power + + if(cellular_damage) + M.adjustCloneLoss(-heal_amt * 0.5) + + var/list/parts = M.get_damaged_bodyparts(1,1) + + if(!parts.len) + return + + if(prob(4)) + to_chat(M, "Your skin glows faintly, and you feel your wounds mending themselves.") + + for(var/obj/item/bodypart/L in parts) + if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len)) + M.update_damage_overlays() return 1 diff --git a/code/datums/diseases/advance/symptoms/sensory.dm b/code/datums/diseases/advance/symptoms/sensory.dm index df6bda1729..746844f7cb 100644 --- a/code/datums/diseases/advance/symptoms/sensory.dm +++ b/code/datums/diseases/advance/symptoms/sensory.dm @@ -27,7 +27,9 @@ Bonus symptom_delay_max = 10 var/purge_alcohol = FALSE var/brain_heal = FALSE + var/trauma_heal = FALSE threshold_desc = "Resistance 6: Heals brain damage.
\ + Resistance 9: Heals brain traumas.
\ Transmission 8: Purges alcohol in the bloodstream." /datum/symptom/mind_restoration/Start(datum/disease/advance/A) @@ -35,6 +37,8 @@ Bonus return if(A.properties["resistance"] >= 6) //heal brain damage brain_heal = TRUE + if(A.properties["resistance"] >= 9) //heal brain traumas + trauma_heal = TRUE if(A.properties["transmittable"] >= 8) //purge alcohol purge_alcohol = TRUE @@ -66,3 +70,9 @@ Bonus if(brain_heal && A.stage >= 5) M.adjustBrainLoss(-3) + if(trauma_heal && iscarbon(M)) + var/mob/living/carbon/C = M + if(prob(30) && C.has_trauma_type(BRAIN_TRAUMA_SPECIAL)) + C.cure_trauma_type(BRAIN_TRAUMA_SPECIAL) + if(prob(10) && C.has_trauma_type(BRAIN_TRAUMA_MILD)) + C.cure_trauma_type(BRAIN_TRAUMA_MILD) diff --git a/code/datums/diseases/advance/symptoms/species.dm b/code/datums/diseases/advance/symptoms/species.dm new file mode 100644 index 0000000000..837252c1e6 --- /dev/null +++ b/code/datums/diseases/advance/symptoms/species.dm @@ -0,0 +1,30 @@ +/datum/symptom/undead_adaptation + name = "Necrotic Metabolism" + desc = "The virus is able to thrive and act even within dead hosts." + stealth = 2 + resistance = -2 + stage_speed = 1 + transmittable = 0 + level = 5 + severity = 0 + +/datum/symptom/undead_adaptation/Start(datum/disease/advance/A) + if(!..()) + return + A.process_dead = TRUE + A.infectable_hosts |= SPECIES_UNDEAD + +/datum/symptom/inorganic_adaptation + name = "Inorganic Biology" + desc = "The virus can survive and replicate even in an inorganic environment, increasing its resistance and infection rate." + stealth = -1 + resistance = 4 + stage_speed = -2 + transmittable = 3 + level = 5 + severity = 0 + +/datum/symptom/inorganic_adaptation/Start(datum/disease/advance/A) + if(!..()) + return + A.infectable_hosts |= SPECIES_INORGANIC \ No newline at end of file diff --git a/code/datums/diseases/advance/symptoms/weight.dm b/code/datums/diseases/advance/symptoms/weight.dm index f8f4343649..7052e90bf7 100644 --- a/code/datums/diseases/advance/symptoms/weight.dm +++ b/code/datums/diseases/advance/symptoms/weight.dm @@ -1,56 +1,6 @@ /* ////////////////////////////////////// -Weight Gain - - Very Very Noticable. - Decreases resistance. - Decreases stage speed. - Reduced transmittable. - Intense Level. - -Bonus - Increases the weight gain of the mob, - forcing it to eventually turn fat. -////////////////////////////////////// -*/ - -/datum/symptom/weight_gain - - name = "Weight Gain" - desc = "The virus mutates the host's metabolism, making it gain weight much faster than normal." - stealth = -3 - resistance = -3 - stage_speed = -2 - transmittable = -2 - level = 4 - severity = 3 - base_message_chance = 100 - symptom_delay_min = 15 - symptom_delay_max = 45 - threshold_desc = "Stealth 4: The symptom is less noticeable." - -/datum/symptom/weight_gain/Start(datum/disease/advance/A) - if(!..()) - return - if(A.properties["stealth"] >= 4) //warn less often - base_message_chance = 25 - -/datum/symptom/weight_gain/Activate(datum/disease/advance/A) - if(!..()) - return - var/mob/living/M = A.affected_mob - switch(A.stage) - if(1, 2, 3, 4) - if(prob(base_message_chance)) - to_chat(M, "[pick("You feel blubbery.", "Your stomach hurts.")]") - else - M.overeatduration = min(M.overeatduration + 100, 600) - M.nutrition = min(M.nutrition + 100, NUTRITION_LEVEL_FULL) - -/* -////////////////////////////////////// - Weight Loss Very Very Noticable. @@ -70,8 +20,8 @@ Bonus name = "Weight Loss" desc = "The virus mutates the host's metabolism, making it almost unable to gain nutrition from food." - stealth = -3 - resistance = -2 + stealth = -2 + resistance = 2 stage_speed = -2 transmittable = -2 level = 3 @@ -99,43 +49,3 @@ Bonus to_chat(M, "[pick("So hungry...", "You'd kill someone for a bite of food...", "Hunger cramps seize you...")]") M.overeatduration = max(M.overeatduration - 100, 0) M.nutrition = max(M.nutrition - 100, 0) - -/* -////////////////////////////////////// - -Weight Even - - Very Noticable. - Decreases resistance. - Decreases stage speed. - Reduced transmittable. - High level. - -Bonus - Causes the weight of the mob to - be even, meaning eating isn't - required anymore. - -////////////////////////////////////// -*/ - -/datum/symptom/weight_even - - name = "Weight Even" - desc = "The virus alters the host's metabolism, making it far more efficient then normal, and synthesizing nutrients from normally unedible sources." - stealth = -3 - resistance = -2 - stage_speed = -2 - transmittable = -2 - level = 4 - symptom_delay_min = 5 - symptom_delay_max = 5 - -/datum/symptom/weight_even/Activate(datum/disease/advance/A) - if(!..()) - return - var/mob/living/M = A.affected_mob - switch(A.stage) - if(4, 5) - M.overeatduration = 0 - M.nutrition = NUTRITION_LEVEL_WELL_FED + 50 diff --git a/code/datums/diseases/beesease.dm b/code/datums/diseases/beesease.dm index f02c3b90ee..80ec0abe6b 100644 --- a/code/datums/diseases/beesease.dm +++ b/code/datums/diseases/beesease.dm @@ -10,6 +10,7 @@ viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) desc = "If left untreated subject will regurgitate bees." severity = VIRUS_SEVERITY_MEDIUM + infectable_hosts = list(SPECIES_ORGANIC, SPECIES_UNDEAD) //bees nesting in corpses /datum/disease/beesease/stage_act() ..() diff --git a/code/datums/diseases/brainrot.dm b/code/datums/diseases/brainrot.dm index 576518b955..49f8afcaff 100644 --- a/code/datums/diseases/brainrot.dm +++ b/code/datums/diseases/brainrot.dm @@ -24,15 +24,15 @@ if(prob(2)) to_chat(affected_mob, "You don't feel like yourself.") if(prob(5)) - affected_mob.adjustBrainLoss(1) + affected_mob.adjustBrainLoss(1, 170) affected_mob.updatehealth() if(3) if(prob(2)) affected_mob.emote("stare") if(prob(2)) affected_mob.emote("drool") - if(prob(10) && affected_mob.getBrainLoss()<=98)//shouldn't retard you to death now - affected_mob.adjustBrainLoss(2) + if(prob(10)) + affected_mob.adjustBrainLoss(2, 170) affected_mob.updatehealth() if(prob(2)) to_chat(affected_mob, "Your try to remember something important...but can't.") @@ -42,8 +42,8 @@ affected_mob.emote("stare") if(prob(2)) affected_mob.emote("drool") - if(prob(15) && affected_mob.getBrainLoss()<=98) //shouldn't retard you to death now - affected_mob.adjustBrainLoss(3) + if(prob(15)) + affected_mob.adjustBrainLoss(3, 170) affected_mob.updatehealth() if(prob(2)) to_chat(affected_mob, "Strange buzzing fills your head, removing all thoughts.") diff --git a/code/datums/diseases/magnitis.dm b/code/datums/diseases/magnitis.dm index e82c24ba59..4430eee19d 100644 --- a/code/datums/diseases/magnitis.dm +++ b/code/datums/diseases/magnitis.dm @@ -10,6 +10,8 @@ permeability_mod = 0.75 desc = "This disease disrupts the magnetic field of your body, making it act as if a powerful magnet. Injections of iron help stabilize the field." severity = VIRUS_SEVERITY_MEDIUM + infectable_hosts = list(SPECIES_ORGANIC, SPECIES_ROBOTIC) + process_dead = TRUE /datum/disease/magnitis/stage_act() ..() diff --git a/code/datums/diseases/parrotpossession.dm b/code/datums/diseases/parrotpossession.dm index 42d5daa797..284c3bd7f2 100644 --- a/code/datums/diseases/parrotpossession.dm +++ b/code/datums/diseases/parrotpossession.dm @@ -11,6 +11,8 @@ viable_mobtypes = list(/mob/living/carbon/human) desc = "Subject is possesed by the vengeful spirit of a parrot. Call the priest." severity = VIRUS_SEVERITY_MEDIUM + infectable_hosts = list(SPECIES_ORGANIC, SPECIES_UNDEAD, SPECIES_INORGANIC, SPECIES_ROBOTIC) + bypasses_immunity = TRUE //2spook var/mob/living/simple_animal/parrot/Poly/ghost/parrot /datum/disease/parrot_possession/stage_act() diff --git a/code/datums/diseases/rhumba_beat.dm b/code/datums/diseases/rhumba_beat.dm index 855f1f44f0..8217364fb5 100644 --- a/code/datums/diseases/rhumba_beat.dm +++ b/code/datums/diseases/rhumba_beat.dm @@ -9,6 +9,7 @@ viable_mobtypes = list(/mob/living/carbon/human) permeability_mod = 1 severity = VIRUS_SEVERITY_BIOHAZARD + process_dead = TRUE /datum/disease/rhumba_beat/stage_act() ..() diff --git a/code/datums/diseases/transformation.dm b/code/datums/diseases/transformation.dm index 0ff47f854d..60622f61cb 100644 --- a/code/datums/diseases/transformation.dm +++ b/code/datums/diseases/transformation.dm @@ -127,7 +127,7 @@ stage4 = list("Your skin feels very loose.", "You can feel... something...inside you.") stage5 = list("Your skin feels as if it's about to burst off!") new_form = /mob/living/silicon/robot - + infectable_hosts = list(SPECIES_ORGANIC, SPECIES_UNDEAD, SPECIES_ROBOTIC) /datum/disease/transformation/robot/stage_act() ..() @@ -240,3 +240,4 @@ stage4 = list("You're ravenous.") stage5 = list("You have become a morph.") new_form = /mob/living/simple_animal/hostile/morph + infectable_hosts = list(SPECIES_ORGANIC, SPECIES_INORGANIC, SPECIES_UNDEAD) //magic! diff --git a/code/datums/explosion.dm b/code/datums/explosion.dm index 51844567cc..73b76a9155 100644 --- a/code/datums/explosion.dm +++ b/code/datums/explosion.dm @@ -85,9 +85,16 @@ GLOBAL_LIST_EMPTY(explosions) var/max_range = max(devastation_range, heavy_impact_range, light_impact_range, flame_range) + var/area/epi_area = get_area(epicenter) if(adminlog) - message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area: [get_area(epicenter)] [ADMIN_COORDJMP(epicenter)]") + message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area: [epi_area] [ADMIN_COORDJMP(epicenter)]") log_game("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z])") + + var/x0 = epicenter.x + var/y0 = epicenter.y + var/z0 = epicenter.z + + SSblackbox.record_feedback("associative", "explosion", 1, list("dev" = devastation_range, "heavy" = heavy_impact_range, "light" = light_impact_range, "flash" = flash_range, "flame" = flame_range, "orig_dev" = orig_dev_range, "orig_heavy" = orig_heavy_range, "orig_light" = orig_light_range, "x" = x0, "y" = y0, "z" = z0, "area" = epi_area.type)) // Play sounds; we want sounds to be different depending on distance so we will manually do it ourselves. // Stereo users will also hear the direction of the explosion! @@ -99,10 +106,6 @@ GLOBAL_LIST_EMPTY(explosions) far_dist += heavy_impact_range * 5 far_dist += devastation_range * 20 - var/x0 = epicenter.x - var/y0 = epicenter.y - var/z0 = epicenter.z - if(!silent) var/frequency = get_rand_frequency() var/sound/explosion_sound = sound(get_sfx("explosion")) @@ -118,7 +121,7 @@ GLOBAL_LIST_EMPTY(explosions) M.playsound_local(epicenter, null, 100, 1, frequency, falloff = 5, S = explosion_sound) // You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station. else if(dist <= far_dist) - var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist + var/far_volume = CLAMP(far_dist, 30, 50) // Volume is based on explosion size and dist far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion M.playsound_local(epicenter, null, far_volume, 1, frequency, falloff = 5, S = far_explosion_sound) EX_PREPROCESS_CHECK_TICK diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm index 5d04d1c7c0..c030bd4c2a 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -119,6 +119,9 @@ playSpecials(destturf,effectout,soundout) if(ismegafauna(teleatom)) message_admins("[teleatom] [ADMIN_FLW(teleatom)] has teleported from [ADMIN_COORDJMP(curturf)] to [ADMIN_COORDJMP(destturf)].") + if(ismob(teleatom)) + var/mob/M = teleatom + M.cancel_camera() return 1 /datum/teleport/proc/teleport() diff --git a/code/datums/holocall.dm b/code/datums/holocall.dm index abad0dba1d..75abc87080 100644 --- a/code/datums/holocall.dm +++ b/code/datums/holocall.dm @@ -1,5 +1,14 @@ #define HOLOPAD_MAX_DIAL_TIME 200 +#define HOLORECORD_DELAY "delay" +#define HOLORECORD_SAY "say" +#define HOLORECORD_SOUND "sound" +#define HOLORECORD_LANGUAGE "lang" +#define HOLORECORD_PRESET "preset" +#define HOLORECORD_RENAME "rename" + +#define HOLORECORD_MAX_LENGTH 200 + /mob/camera/aiEye/remote/holo/setLoc() . = ..() var/obj/machinery/holopad/H = origin @@ -184,3 +193,122 @@ /datum/action/innate/end_holocall/Activate() hcall.Disconnect(hcall.calling_holopad) + + +//RECORDS +/datum/holorecord + var/caller_name = "Unknown" //Caller name + var/image/caller_image + var/list/entries = list() + var/language = /datum/language/common //Initial language, can be changed by HOLORECORD_LANGUAGE entries + +/obj/item/disk/holodisk + name = "holorecord disk" + desc = "Stores recorder holocalls." + icon_state = "holodisk" + var/datum/holorecord/record + //Preset variables + var/preset_image_type + var/preset_record_text + +/obj/item/disk/holodisk/Initialize(mapload) + . = ..() + if(preset_record_text) + build_record() + +/obj/item/disk/holodisk/Destroy() + QDEL_NULL(record) + return ..() + +/obj/item/disk/holodisk/proc/build_record() + record = new + var/list/lines = splittext(preset_record_text,"\n") + for(var/line in lines) + var/prepared_line = trim(line) + if(!length(prepared_line)) + continue + var/splitpoint = findtext(prepared_line," ") + if(!splitpoint) + continue + var/command = copytext(prepared_line,1,splitpoint) + var/value = copytext(prepared_line,splitpoint+1) + switch(command) + if("DELAY") + var/delay_value = text2num(value) + if(!delay_value) + continue + record.entries += list(list(HOLORECORD_DELAY,delay_value)) + if("NAME") + if(!record.caller_name) + record.caller_name = value + else + record.entries += list(list(HOLORECORD_RENAME,value)) + if("SAY") + record.entries += list(list(HOLORECORD_SAY,value)) + if("SOUND") + record.entries += list(list(HOLORECORD_SOUND,value)) + if("LANGUAGE") + var/lang_type = text2path(value) + if(ispath(lang_type,/datum/language)) + record.entries += list(list(HOLORECORD_LANGUAGE,lang_type)) + if("PRESET") + var/preset_type = text2path(value) + if(ispath(preset_type,/datum/preset_holoimage)) + record.entries += list(list(HOLORECORD_PRESET,preset_type)) + if(!preset_image_type) + record.caller_image = image('icons/mob/animal.dmi',"old") + else + var/datum/preset_holoimage/H = new preset_image_type + record.caller_image = H.build_image() + +//These build caller image from outfit and some additional data, for use by mappers for ruin holorecords +/datum/preset_holoimage + var/nonhuman_mobtype //Fill this if you just want something nonhuman + var/outfit_type + var/species_type = /datum/species/human + +/datum/preset_holoimage/proc/build_image() + if(nonhuman_mobtype) + var/mob/living/L = nonhuman_mobtype + . = image(initial(L.icon),initial(L.icon_state)) + else + var/mob/living/carbon/human/dummy/mannequin = generate_or_wait_for_human_dummy("HOLODISK_PRESET") + if(species_type) + mannequin.set_species(species_type) + if(outfit_type) + mannequin.equipOutfit(outfit_type,TRUE) + mannequin.setDir(SOUTH) + COMPILE_OVERLAYS(mannequin) + . = getFlatIcon(mannequin) + unset_busy_human_dummy("HOLODISK_PRESET") + +/obj/item/disk/holodisk/example + preset_image_type = /datum/preset_holoimage/clown + preset_record_text = {" + NAME Clown + DELAY 10 + SAY Why did the chaplain cross the maint ? + DELAY 20 + SAY He wanted to get to the other side! + SOUND clownstep + DELAY 30 + LANGUAGE /datum/language/narsie + SAY Helped him get there! + DELAY 10 + SAY ALSO IM SECRETLY A GORILLA + DELAY 10 + PRESET /datum/preset_holoimage/gorilla + NAME Gorilla + LANGUAGE /datum/language/common + SAY OOGA + DELAY 20"} + +/datum/preset_holoimage/engineer + outfit_type = /datum/outfit/job/engineer/gloved/rig + +/datum/preset_holoimage/gorilla + nonhuman_mobtype = /mob/living/simple_animal/hostile/gorilla + +/datum/preset_holoimage/clown + outfit_type = /datum/outfit/job/clown + diff --git a/code/datums/hud.dm b/code/datums/hud.dm index be2b5c620c..fc6c09be14 100644 --- a/code/datums/hud.dm +++ b/code/datums/hud.dm @@ -1,12 +1,16 @@ /* HUD DATUMS */ +GLOBAL_LIST_EMPTY(all_huds) + //GLOBAL HUD LIST GLOBAL_LIST_INIT(huds, list( DATA_HUD_SECURITY_BASIC = new/datum/atom_hud/data/human/security/basic(), DATA_HUD_SECURITY_ADVANCED = new/datum/atom_hud/data/human/security/advanced(), DATA_HUD_MEDICAL_BASIC = new/datum/atom_hud/data/human/medical/basic(), DATA_HUD_MEDICAL_ADVANCED = new/datum/atom_hud/data/human/medical/advanced(), - DATA_HUD_DIAGNOSTIC = new/datum/atom_hud/data/diagnostic(), + DATA_HUD_DIAGNOSTIC_BASIC = new/datum/atom_hud/data/diagnostic/basic(), + DATA_HUD_DIAGNOSTIC_ADVANCED = new/datum/atom_hud/data/diagnostic/advanced(), + DATA_HUD_ABDUCTOR = new/datum/atom_hud/abductor(), ANTAG_HUD_CULT = new/datum/atom_hud/antag(), ANTAG_HUD_REV = new/datum/atom_hud/antag(), ANTAG_HUD_OPS = new/datum/atom_hud/antag(), @@ -28,6 +32,17 @@ GLOBAL_LIST_INIT(huds, list( var/list/mob/hudusers = list() //list with all mobs who can see the hud var/list/hud_icons = list() //these will be the indexes for the atom's hud_list +/datum/atom_hud/New() + GLOB.all_huds += src + +/datum/atom_hud/Destroy() + for(var/v in hudusers) + remove_hud_from(v) + for(var/v in hudatoms) + remove_from_hud(v) + GLOB.all_huds -= src + return ..() + /datum/atom_hud/proc/remove_hud_from(mob/M) if(!M || !hudusers[M]) return @@ -77,7 +92,7 @@ GLOBAL_LIST_INIT(huds, list( //MOB PROCS /mob/proc/reload_huds() - for(var/datum/atom_hud/hud in (GLOB.huds|GLOB.active_alternate_appearances)) + for(var/datum/atom_hud/hud in GLOB.all_huds) if(hud && hud.hudusers[src]) for(var/atom/A in hud.hudatoms) hud.add_to_single_hud(src, A) diff --git a/code/datums/looping_sounds/machinery_sounds.dm b/code/datums/looping_sounds/machinery_sounds.dm index 4e93daba0d..b84133faf7 100644 --- a/code/datums/looping_sounds/machinery_sounds.dm +++ b/code/datums/looping_sounds/machinery_sounds.dm @@ -4,13 +4,13 @@ mid_sounds = list('sound/machines/shower/shower_mid1.ogg'=1,'sound/machines/shower/shower_mid2.ogg'=1,'sound/machines/shower/shower_mid3.ogg'=1) mid_length = 10 end_sound = 'sound/machines/shower/shower_end.ogg' - volume = 25 + volume = 20 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /datum/looping_sound/supermatter mid_sounds = list('sound/machines/sm/supermatter1.ogg'=1,'sound/machines/sm/supermatter2.ogg'=1,'sound/machines/sm/supermatter3.ogg'=1) - mid_length = 6 + mid_length = 10 volume = 1 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -32,7 +32,7 @@ mid_sounds = list('sound/machines/fryer/deep_fryer_1.ogg' = 1, 'sound/machines/fryer/deep_fryer_2.ogg' = 1) mid_length = 2 end_sound = 'sound/machines/fryer/deep_fryer_emerge.ogg' - volume = 25 + volume = 15 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/code/datums/martial/cqc.dm b/code/datums/martial/cqc.dm index 8974c388b1..b4b49dc81b 100644 --- a/code/datums/martial/cqc.dm +++ b/code/datums/martial/cqc.dm @@ -58,7 +58,7 @@ "[A] kicks your head, knocking you out!") playsound(get_turf(A), 'sound/weapons/genhit1.ogg', 50, 1, -1) D.SetSleeping(300) - D.adjustBrainLoss(25) + D.adjustBrainLoss(15, 150) return 1 /datum/martial_art/cqc/proc/Pressure(mob/living/carbon/human/A, mob/living/carbon/human/D) diff --git a/code/datums/martial/krav_maga.dm b/code/datums/martial/krav_maga.dm index 5c78a0c321..82497adf45 100644 --- a/code/datums/martial/krav_maga.dm +++ b/code/datums/martial/krav_maga.dm @@ -101,7 +101,7 @@ "[A] slams your chest! You can't breathe!") playsound(get_turf(A), 'sound/effects/hit_punch.ogg', 50, 1, -1) if(D.losebreath <= 10) - D.losebreath = Clamp(D.losebreath + 5, 0, 10) + D.losebreath = CLAMP(D.losebreath + 5, 0, 10) D.adjustOxyLoss(10) add_logs(A, D, "quickchoked") return 1 @@ -112,7 +112,7 @@ playsound(get_turf(A), 'sound/effects/hit_punch.ogg', 50, 1, -1) D.apply_damage(5, BRUTE) if(D.silent <= 10) - D.silent = Clamp(D.silent + 10, 0, 10) + D.silent = CLAMP(D.silent + 10, 0, 10) add_logs(A, D, "neck chopped") return 1 diff --git a/code/datums/martial/psychotic_brawl.dm b/code/datums/martial/psychotic_brawl.dm new file mode 100644 index 0000000000..28f8e9502c --- /dev/null +++ b/code/datums/martial/psychotic_brawl.dm @@ -0,0 +1,66 @@ +/datum/martial_art/psychotic_brawling + name = "Psychotic Brawling" + +/datum/martial_art/psychotic_brawling/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + return psycho_attack(A,D) + +/datum/martial_art/psychotic_brawling/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + return psycho_attack(A,D) + +/datum/martial_art/psychotic_brawling/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + return psycho_attack(A,D) + +/datum/martial_art/psychotic_brawling/proc/psycho_attack(mob/living/carbon/human/A, mob/living/carbon/human/D) + var/atk_verb + switch(rand(1,8)) + if(1) + D.help_shake_act(A) + atk_verb = "helped" + if(2) + A.emote("cry") + A.Stun(20) + atk_verb = "cried looking at" + if(3) + if(A.grab_state >= GRAB_AGGRESSIVE) + D.grabbedby(A, 1) + else + A.start_pulling(D, 1) + if(A.pulling) + D.drop_all_held_items() + D.stop_pulling() + if(A.a_intent == INTENT_GRAB) + add_logs(A, D, "grabbed", addition="aggressively") + D.visible_message("[A] violently grabs [D]!", \ + "[A] violently grabs you!") + A.grab_state = GRAB_AGGRESSIVE //Instant aggressive grab + else + add_logs(A, D, "grabbed", addition="passively") + A.grab_state = GRAB_PASSIVE + if(4) + A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) + atk_verb = "headbutts" + D.visible_message("[A] [atk_verb] [D]!", \ + "[A] [atk_verb] you!") + playsound(get_turf(D), 'sound/weapons/punch1.ogg', 40, 1, -1) + D.apply_damage(rand(5,10), BRUTE, "head") + A.apply_damage(rand(5,10), BRUTE, "head") + if(!istype(D.head,/obj/item/clothing/head/helmet/) && !istype(D.head,/obj/item/clothing/head/hardhat)) + D.adjustBrainLoss(5) + A.Stun(rand(10,45)) + D.Stun(rand(5,30)) + if(5,6) + A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) + atk_verb = pick("punches", "kicks", "hits", "slams into") + D.visible_message("[A] [atk_verb] [D] with inhuman strength, sending [D.p_them()] flying backwards!", \ + "[A] [atk_verb] you with inhuman strength, sending you flying backwards!") + D.apply_damage(rand(15,30), BRUTE) + playsound(get_turf(D), 'sound/effects/meteorimpact.ogg', 25, 1, -1) + var/throwtarget = get_edge_target_turf(A, get_dir(A, get_step_away(D, A))) + D.throw_at(throwtarget, 4, 2, A)//So stuff gets tossed around at the same time. + D.Knockdown(60) + if(7,8) + basic_hit(A,D) + + if(atk_verb) + add_logs(A, D, "[atk_verb] (Psychotic Brawling)") + return 1 \ No newline at end of file diff --git a/code/datums/martial/sleeping_carp.dm b/code/datums/martial/sleeping_carp.dm index ed46910148..f3a1f53dd2 100644 --- a/code/datums/martial/sleeping_carp.dm +++ b/code/datums/martial/sleeping_carp.dm @@ -240,7 +240,7 @@ H.visible_message("[user] delivers a heavy hit to [H]'s head, knocking them out cold!", \ "[user] knocks you unconscious!") H.SetSleeping(600) - H.adjustBrainLoss(25) + H.adjustBrainLoss(15, 150) else return ..() diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 04b3ee31b7..231ce66f28 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -149,7 +149,7 @@ return LAZYADD(antag_datums, A) A.create_team(team) - var/datum/objective_team/antag_team = A.get_team() + var/datum/team/antag_team = A.get_team() if(antag_team) antag_team.add_member(src) A.on_gain() @@ -185,12 +185,6 @@ objectives, uplinks, powers etc are all handled. */ -/datum/mind/proc/remove_objectives() - if(objectives.len) - for(var/datum/objective/O in objectives) - objectives -= O - qdel(O) - /datum/mind/proc/remove_changeling() var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling) if(C) @@ -207,13 +201,12 @@ remove_antag_datum(ANTAG_DATUM_BROTHER) SSticker.mode.update_brother_icons_removed(src) + /datum/mind/proc/remove_nukeop() - if(src in SSticker.mode.syndicates) - SSticker.mode.syndicates -= src - SSticker.mode.update_synd_icons_removed(src) - special_role = null - remove_objectives() - remove_antag_equip() + var/datum/antagonist/nukeop/nuke = has_antag_datum(/datum/antagonist/nukeop,TRUE) + if(nuke) + remove_antag_datum(nuke.type) + special_role = null /datum/mind/proc/remove_wizard() remove_antag_datum(/datum/antagonist/wizard) @@ -223,7 +216,6 @@ if(src in SSticker.mode.cult) SSticker.mode.remove_cultist(src, 0, 0) special_role = null - remove_objectives() remove_antag_equip() /datum/mind/proc/remove_rev() @@ -299,9 +291,7 @@ to_chat(traitor_mob, "Unfortunately, [employer] wasn't able to get you an Uplink.") . = 0 else - var/obj/item/device/uplink/U = new(uplink_loc) - U.owner = "[traitor_mob.key]" - uplink_loc.hidden_uplink = U + uplink_loc.AddComponent(/datum/component/uplink, traitor_mob.key) if(uplink_loc == R) R.traitor_frequency = sanitize_frequency(rand(MIN_FREQ, MAX_FREQ)) @@ -331,14 +321,19 @@ SSticker.mode.add_cultist(src) else if(is_revolutionary(creator)) - var/datum/antagonist/rev/converter = creator.mind.has_antag_datum(/datum/antagonist/rev) + var/datum/antagonist/rev/converter = creator.mind.has_antag_datum(/datum/antagonist/rev,TRUE) converter.add_revolutionary(src,FALSE) else if(is_servant_of_ratvar(creator)) add_servant_of_ratvar(current) else if(is_nuclear_operative(creator)) - make_Nuke(null, null, 0, FALSE) + var/datum/antagonist/nukeop/converter = creator.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE) + var/datum/antagonist/nukeop/N = new(src) + N.send_to_spawnpoint = FALSE + N.nukeop_outfit = null + add_antag_datum(N,converter.nuke_team) + enslaved_to = creator @@ -495,7 +490,8 @@ if (SSticker.mode.config_tag=="nuclear") text = uppertext(text) text = "[text]: " - if (src in SSticker.mode.syndicates) + var/datum/antagonist/nukeop/N = has_antag_datum(/datum/antagonist/nukeop,TRUE) + if(N) text += "OPERATIVE | nanotrasen" text += "
To shuttle, undress, dress up." var/code @@ -715,9 +711,9 @@ out += sections[i]+"
" - if(((src in SSticker.mode.traitors) || (src in SSticker.mode.syndicates)) && ishuman(current)) + if(((src in SSticker.mode.traitors) || is_nuclear_operative(current)) && ishuman(current)) text = "Uplink: give" - var/obj/item/device/uplink/U = find_syndicate_uplink() + var/datum/component/uplink/U = find_syndicate_uplink() if(U) text += " | take" if (check_rights(R_FUN, 0)) @@ -771,17 +767,44 @@ var/objective_pos var/def_value + + + var/datum/antagonist/target_antag + if (href_list["obj_edit"]) objective = locate(href_list["obj_edit"]) if (!objective) return - objective_pos = objectives.Find(objective) + + for(var/datum/antagonist/A in antag_datums) + if(objective in A.objectives) + target_antag = A + objective_pos = A.objectives.Find(objective) + break + + if(!target_antag) //Shouldn't happen + stack_trace("objective without antagonist found") + objective_pos = objectives.Find(objective) //Text strings are easy to manipulate. Revised for simplicity. var/temp_obj_type = "[objective.type]"//Convert path into a text string. def_value = copytext(temp_obj_type, 19)//Convert last part of path into an objective keyword. if(!def_value)//If it's a custom objective, it will be an empty string. def_value = "custom" + else + switch(antag_datums.len) + if(0) + target_antag = add_antag_datum(/datum/antagonist/custom) + if(1) + target_antag = antag_datums[1] + else + var/datum/antagonist/target = input("Which antagonist gets the objective:", "Antagonist", def_value) as null|anything in antag_datums + "(new custom antag)" + if (QDELETED(target)) + return + else if(target == "(new custom antag)") + target_antag = add_antag_datum(/datum/antagonist/custom) + else + target_antag = target var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "late-assassinate", "maroon", "debrain", "protect", "destroy", "prevent", "hijack", "escape", "survive", "martyr", "steal", "download", "nuclear", "capture", "absorb", "custom") if (!new_obj_type) @@ -903,11 +926,15 @@ return if (objective) + if(target_antag) + target_antag.objectives -= objective objectives -= objective - objectives.Insert(objective_pos, new_objective) + target_antag.objectives.Insert(objective_pos, new_objective) message_admins("[key_name_admin(usr)] edited [current]'s objective to [new_objective.explanation_text]") log_admin("[key_name(usr)] edited [current]'s objective to [new_objective.explanation_text]") else + if(target_antag) + target_antag.objectives += new_objective objectives += new_objective message_admins("[key_name_admin(usr)] added a new objective for [current]: [new_objective.explanation_text]") log_admin("[key_name(usr)] added a new objective for [current]: [new_objective.explanation_text]") @@ -916,6 +943,11 @@ var/datum/objective/objective = locate(href_list["obj_delete"]) if(!istype(objective)) return + + for(var/datum/antagonist/A in antag_datums) + if(objective in A.objectives) + A.objectives -= objective + break objectives -= objective message_admins("[key_name_admin(usr)] removed an objective for [current]: [objective.explanation_text]") log_admin("[key_name(usr)] removed an objective for [current]: [objective.explanation_text]") @@ -998,11 +1030,13 @@ message_admins("[key_name_admin(usr)] has cult'ed [current].") log_admin("[key_name(usr)] has cult'ed [current].") if("tome") - if (!SSticker.mode.equip_cultist(current,1)) + var/datum/antagonist/cult/C = has_antag_datum(/datum/antagonist/cult,TRUE) + if (C.equip_cultist(current,1)) to_chat(usr, "Spawning tome failed!") if("amulet") - if (!SSticker.mode.equip_cultist(current)) + var/datum/antagonist/cult/C = has_antag_datum(/datum/antagonist/cult,TRUE) + if (C.equip_cultist(current)) to_chat(usr, "Spawning amulet failed!") else if(href_list["clockcult"]) @@ -1073,36 +1107,14 @@ message_admins("[key_name_admin(usr)] has de-nuke op'ed [current].") log_admin("[key_name(usr)] has de-nuke op'ed [current].") if("nuclear") - if(!(src in SSticker.mode.syndicates)) - SSticker.mode.syndicates += src - SSticker.mode.update_synd_icons_added(src) - if (SSticker.mode.syndicates.len==1) - SSticker.mode.prepare_syndicate_leader(src) - else - current.real_name = "[syndicate_name()] Operative #[SSticker.mode.syndicates.len-1]" + if(!has_antag_datum(/datum/antagonist/nukeop,TRUE)) + add_antag_datum(/datum/antagonist/nukeop) special_role = "Syndicate" assigned_role = "Syndicate" - to_chat(current, "You are a [syndicate_name()] agent!") - SSticker.mode.forge_syndicate_objectives(src) - SSticker.mode.greet_syndicate(src) message_admins("[key_name_admin(usr)] has nuke op'ed [current].") log_admin("[key_name(usr)] has nuke op'ed [current].") if("lair") current.forceMove(pick(GLOB.nukeop_start)) - if("dressup") - var/mob/living/carbon/human/H = current - qdel(H.belt) - qdel(H.back) - qdel(H.ears) - qdel(H.gloves) - qdel(H.head) - qdel(H.shoes) - qdel(H.wear_id) - qdel(H.wear_suit) - qdel(H.w_uniform) - - if (!SSticker.mode.equip_syndicate(current)) - to_chat(usr, "Equipping a syndicate failed!") if("tellcode") var/code for (var/obj/machinery/nuclearbomb/bombue in GLOB.machines) @@ -1306,7 +1318,7 @@ log_admin("[key_name(usr)] removed [current]'s uplink.") if("crystals") if(check_rights(R_FUN, 0)) - var/obj/item/device/uplink/U = find_syndicate_uplink() + var/datum/component/uplink/U = find_syndicate_uplink() if(U) var/crystals = input("Amount of telecrystals for [key]","Syndicate uplink", U.telecrystals) as null | num if(!isnull(crystals)) @@ -1335,15 +1347,14 @@ /datum/mind/proc/find_syndicate_uplink() var/list/L = current.GetAllContents() - for (var/obj/item/I in L) - if (I.hidden_uplink) - return I.hidden_uplink - return null + for (var/i in L) + var/atom/movable/I = i + . = I.GetComponent(/datum/component/uplink) + if(.) + break /datum/mind/proc/take_uplink() - var/obj/item/device/uplink/H = find_syndicate_uplink() - if(H) - qdel(H) + qdel(find_syndicate_uplink()) /datum/mind/proc/make_Traitor() if(!(has_antag_datum(ANTAG_DATUM_TRAITOR))) @@ -1351,50 +1362,6 @@ T.should_specialise = TRUE add_antag_datum(T) - -/datum/mind/proc/make_Nuke(turf/spawnloc, nuke_code, leader=0, telecrystals = TRUE) - if(!(src in SSticker.mode.syndicates)) - SSticker.mode.syndicates += src - SSticker.mode.update_synd_icons_added(src) - assigned_role = "Syndicate" - special_role = "Syndicate" - SSticker.mode.forge_syndicate_objectives(src) - SSticker.mode.greet_syndicate(src) - current.faction |= "syndicate" - - if(spawnloc) - current.forceMove(spawnloc) - - if(ishuman(current)) - var/mob/living/carbon/human/H = current - qdel(H.belt) - qdel(H.back) - qdel(H.ears) - qdel(H.gloves) - qdel(H.head) - qdel(H.shoes) - qdel(H.wear_id) - qdel(H.wear_suit) - qdel(H.w_uniform) - - SSticker.mode.equip_syndicate(current, telecrystals) - - if (nuke_code) - store_memory("Syndicate Nuclear Bomb Code: [nuke_code]", 0, 0) - to_chat(current, "The nuclear authorization code is: [nuke_code]") - else - var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list - if(nuke) - store_memory("Syndicate Nuclear Bomb Code: [nuke.r_code]", 0, 0) - to_chat(current, "The nuclear authorization code is: nuke.r_code") - else - to_chat(current, "You were not provided with a nuclear code. Trying asking your team leader or contacting syndicate command.
") - - if (leader) - SSticker.mode.prepare_syndicate_leader(src,nuke_code) - else - current.real_name = "[syndicate_name()] Operative #[SSticker.mode.syndicates.len-1]" - /datum/mind/proc/make_Changling() var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling) if(!C) @@ -1410,16 +1377,11 @@ /datum/mind/proc/make_Cultist() - if(!(src in SSticker.mode.cult)) - SSticker.mode.add_cultist(src,FALSE) + if(!has_antag_datum(/datum/antagonist/cult,TRUE)) + SSticker.mode.add_cultist(src,FALSE,equip=TRUE) special_role = "Cultist" to_chat(current, "You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy your world is, you see that it should be open to the knowledge of Nar-Sie.") to_chat(current, "Assist your new bretheren in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back.") - var/datum/antagonist/cult/C - C.cult_memorization(src) - var/mob/living/carbon/human/H = current - if (!SSticker.mode.equip_cultist(current)) - to_chat(H, "Spawning an amulet from your Master failed.") /datum/mind/proc/make_Rev() var/datum/antagonist/rev/head/head = new(src) diff --git a/code/datums/mutations.dm b/code/datums/mutations.dm index c19dc2c180..170c0a2a7f 100644 --- a/code/datums/mutations.dm +++ b/code/datums/mutations.dm @@ -113,543 +113,6 @@ GLOBAL_LIST_EMPTY(mutations_list) /datum/mutation/human/proc/get_spans() return list() -/datum/mutation/human/hulk - - name = "Hulk" - quality = POSITIVE - get_chance = 15 - lowest_value = 256 * 12 - text_gain_indication = "Your muscles hurt!" - species_allowed = list("fly") //no skeleton/lizard hulk - health_req = 25 - -/datum/mutation/human/hulk/on_acquiring(mob/living/carbon/human/owner) - if(..()) - return - var/status = CANSTUN | CANKNOCKDOWN | CANUNCONSCIOUS | CANPUSH - owner.status_flags &= ~status - owner.update_body_parts() - -/datum/mutation/human/hulk/on_attack_hand(mob/living/carbon/human/owner, atom/target, proximity) - if(proximity) //no telekinetic hulk attack - return target.attack_hulk(owner) - -/datum/mutation/human/hulk/on_life(mob/living/carbon/human/owner) - if(owner.health < 0) - on_losing(owner) - to_chat(owner, "You suddenly feel very weak.") - -/datum/mutation/human/hulk/on_losing(mob/living/carbon/human/owner) - if(..()) - return - owner.status_flags |= CANSTUN | CANKNOCKDOWN | CANUNCONSCIOUS | CANPUSH - owner.update_body_parts() - -/datum/mutation/human/hulk/say_mod(message) - if(message) - message = "[uppertext(replacetext(message, ".", "!"))]!!" - return message - -/datum/mutation/human/telekinesis - - name = "Telekinesis" - quality = POSITIVE - get_chance = 20 - lowest_value = 256 * 12 - text_gain_indication = "You feel smarter!" - limb_req = "head" - -/datum/mutation/human/telekinesis/New() - ..() - visual_indicators |= mutable_appearance('icons/effects/genetics.dmi', "telekinesishead", -MUTATIONS_LAYER) - -/datum/mutation/human/telekinesis/get_visual_indicator(mob/living/carbon/human/owner) - return visual_indicators[1] - -/datum/mutation/human/telekinesis/on_ranged_attack(mob/living/carbon/human/owner, atom/target) - target.attack_tk(owner) - -/datum/mutation/human/cold_resistance - - name = "Cold Resistance" - quality = POSITIVE - get_chance = 25 - lowest_value = 256 * 12 - text_gain_indication = "Your body feels warm!" - time_coeff = 5 - -/datum/mutation/human/cold_resistance/New() - ..() - visual_indicators |= mutable_appearance('icons/effects/genetics.dmi', "fire", -MUTATIONS_LAYER) - -/datum/mutation/human/cold_resistance/get_visual_indicator(mob/living/carbon/human/owner) - return visual_indicators[1] - -/datum/mutation/human/cold_resistance/on_life(mob/living/carbon/human/owner) - if(owner.getFireLoss()) - if(prob(1)) - owner.heal_bodypart_damage(0,1) //Is this really needed? - -/datum/mutation/human/x_ray - - name = "X Ray Vision" - quality = POSITIVE - get_chance = 25 - lowest_value = 256 * 12 - text_gain_indication = "The walls suddenly disappear!" - time_coeff = 2 - -/datum/mutation/human/x_ray/on_acquiring(mob/living/carbon/human/owner) - if(..()) - return - - owner.update_sight() - -/datum/mutation/human/x_ray/on_losing(mob/living/carbon/human/owner) - if(..()) - return - owner.update_sight() - -/datum/mutation/human/nearsight - - name = "Near Sightness" - quality = MINOR_NEGATIVE - text_gain_indication = "You can't see very well." - -/datum/mutation/human/nearsight/on_acquiring(mob/living/carbon/human/owner) - if(..()) - return - owner.become_nearsighted() - -/datum/mutation/human/nearsight/on_losing(mob/living/carbon/human/owner) - if(..()) - return - owner.cure_nearsighted() - -/datum/mutation/human/epilepsy - - name = "Epilepsy" - quality = NEGATIVE - text_gain_indication = "You get a headache." - -/datum/mutation/human/epilepsy/on_life(mob/living/carbon/human/owner) - if(prob(1) && owner.stat == CONSCIOUS) - owner.visible_message("[owner] starts having a seizure!", "You have a seizure!") - owner.Unconscious(200) - owner.Jitter(1000) - addtimer(CALLBACK(src, .proc/jitter_less, owner), 90) - -/datum/mutation/human/epilepsy/proc/jitter_less(mob/living/carbon/human/owner) - if(owner) - owner.jitteriness = 10 - -/datum/mutation/human/bad_dna - name = "Unstable DNA" - quality = NEGATIVE - text_gain_indication = "You feel strange." - -/datum/mutation/human/bad_dna/on_acquiring(mob/living/carbon/human/owner) - to_chat(owner, text_gain_indication) - var/mob/new_mob - if(prob(95)) - if(prob(50)) - new_mob = owner.randmutb() - else - new_mob = owner.randmuti() - else - new_mob = owner.randmutg() - if(new_mob && ismob(new_mob)) - owner = new_mob - . = owner - on_losing(owner) - -/datum/mutation/human/cough - name = "Cough" - quality = MINOR_NEGATIVE - text_gain_indication = "You start coughing." - -/datum/mutation/human/cough/on_life(mob/living/carbon/human/owner) - if(prob(5) && owner.stat == CONSCIOUS) - owner.drop_all_held_items() - owner.emote("cough") - -/datum/mutation/human/dwarfism - name = "Dwarfism" - quality = POSITIVE - get_chance = 15 - lowest_value = 256 * 12 - -/datum/mutation/human/dwarfism/on_acquiring(mob/living/carbon/human/owner) - if(..()) - return - owner.resize = 0.8 - owner.update_transform() - owner.pass_flags |= PASSTABLE - owner.visible_message("[owner] suddenly shrinks!", "Everything around you seems to grow..") - -/datum/mutation/human/dwarfism/on_losing(mob/living/carbon/human/owner) - if(..()) - return - owner.resize = 1.25 - owner.update_transform() - owner.pass_flags &= ~PASSTABLE - owner.visible_message("[owner] suddenly grows!", "Everything around you seems to shrink..") - -/datum/mutation/human/clumsy - - name = "Clumsiness" - quality = MINOR_NEGATIVE - text_gain_indication = "You feel lightheaded." - -/datum/mutation/human/clumsy/on_acquiring(mob/living/carbon/human/owner) - if(..()) - return - owner.disabilities |= CLUMSY - -/datum/mutation/human/clumsy/on_losing(mob/living/carbon/human/owner) - if(..()) - return - owner.disabilities &= ~CLUMSY - -/datum/mutation/human/tourettes - name = "Tourettes Syndrome" - quality = NEGATIVE - text_gain_indication = "You twitch." - -/datum/mutation/human/tourettes/on_life(mob/living/carbon/human/owner) - if(prob(10) && owner.stat == CONSCIOUS) - owner.Stun(200) - switch(rand(1, 3)) - if(1) - owner.emote("twitch") - if(2 to 3) - owner.say("[prob(50) ? ";" : ""][pick("SHIT", "PISS", "FUCK", "CUNT", "COCKSUCKER", "MOTHERFUCKER", "TITS")]") - var/x_offset_old = owner.pixel_x - var/y_offset_old = owner.pixel_y - var/x_offset = owner.pixel_x + rand(-2,2) - var/y_offset = owner.pixel_y + rand(-1,1) - animate(owner, pixel_x = x_offset, pixel_y = y_offset, time = 1) - animate(owner, pixel_x = x_offset_old, pixel_y = y_offset_old, time = 1) - -/datum/mutation/human/nervousness - name = "Nervousness" - quality = MINOR_NEGATIVE - text_gain_indication = "You feel nervous." - -/datum/mutation/human/nervousness/on_life(mob/living/carbon/human/owner) - if(prob(10)) - owner.stuttering = max(10, owner.stuttering) - -/datum/mutation/human/deaf - name = "Deafness" - quality = NEGATIVE - text_gain_indication = "You can't seem to hear anything." - -/datum/mutation/human/deaf/on_acquiring(mob/living/carbon/human/owner) - if(..()) - return - owner.disabilities |= DEAF - -/datum/mutation/human/deaf/on_losing(mob/living/carbon/human/owner) - if(..()) - return - owner.disabilities &= ~DEAF - -/datum/mutation/human/blind - name = "Blindness" - quality = NEGATIVE - text_gain_indication = "You can't seem to see anything." - -/datum/mutation/human/blind/on_acquiring(mob/living/carbon/human/owner) - if(..()) - return - owner.become_blind() - -/datum/mutation/human/blind/on_losing(mob/living/carbon/human/owner) - if(..()) - return - owner.cure_blind() - - -/datum/mutation/human/race - name = "Monkified" - quality = NEGATIVE - time_coeff = 2 - -/datum/mutation/human/race/on_acquiring(mob/living/carbon/human/owner) - if(owner.has_brain_worms()) - to_chat(owner, "You feel something strongly clinging to your humanity!") - return - if(..()) - return - . = owner.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE) - -/datum/mutation/human/race/on_losing(mob/living/carbon/monkey/owner) - if(owner && istype(owner) && owner.stat != DEAD && (owner.dna.mutations.Remove(src))) - . = owner.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE) - -/datum/mutation/human/chameleon - name = "Chameleon" - quality = POSITIVE - get_chance = 20 - lowest_value = 256 * 12 - text_gain_indication = "You feel one with your surroundings." - text_lose_indication = "You feel oddly exposed." - time_coeff = 5 - -/datum/mutation/human/chameleon/on_acquiring(mob/living/carbon/human/owner) - if(..()) - return - owner.alpha = CHAMELEON_MUTATION_DEFAULT_TRANSPARENCY - -/datum/mutation/human/chameleon/on_life(mob/living/carbon/human/owner) - owner.alpha = max(0, owner.alpha - 25) - -/datum/mutation/human/chameleon/on_move(mob/living/carbon/human/owner) - owner.alpha = CHAMELEON_MUTATION_DEFAULT_TRANSPARENCY - -/datum/mutation/human/chameleon/on_attack_hand(mob/living/carbon/human/owner, atom/target, proximity) - if(proximity) //stops tk from breaking chameleon - owner.alpha = CHAMELEON_MUTATION_DEFAULT_TRANSPARENCY - return - -/datum/mutation/human/chameleon/on_losing(mob/living/carbon/human/owner) - if(..()) - return - owner.alpha = 255 - -/datum/mutation/human/wacky - name = "Wacky" - quality = MINOR_NEGATIVE - text_gain_indication = "You feel an off sensation in your voicebox." - text_lose_indication = "The off sensation passes." - -/datum/mutation/human/wacky/get_spans() - return list(SPAN_SANS) - -/datum/mutation/human/mute - name = "Mute" - quality = NEGATIVE - text_gain_indication = "You feel unable to express yourself at all." - text_lose_indication = "You feel able to speak freely again." - -/datum/mutation/human/mute/on_acquiring(mob/living/carbon/human/owner) - if(..()) - return - owner.disabilities |= MUTE - -/datum/mutation/human/mute/on_losing(mob/living/carbon/human/owner) - if(..()) - return - owner.disabilities &= ~MUTE - -/datum/mutation/human/smile - name = "Smile" - quality = MINOR_NEGATIVE - dna_block = NON_SCANNABLE - text_gain_indication = "You feel so happy. Nothing can be wrong with anything. :)" - text_lose_indication = "Everything is terrible again. :(" - -/datum/mutation/human/smile/say_mod(message) - if(message) - message = " [message] " - //Time for a friendly game of SS13 - message = replacetext(message," stupid "," smart ") - message = replacetext(message," retard "," genius ") - message = replacetext(message," unrobust "," robust ") - message = replacetext(message," dumb "," smart ") - message = replacetext(message," awful "," great ") - message = replacetext(message," gay ",pick(" nice "," ok "," alright ")) - message = replacetext(message," horrible "," fun ") - message = replacetext(message," terrible "," terribly fun ") - message = replacetext(message," terrifying "," wonderful ") - message = replacetext(message," gross "," cool ") - message = replacetext(message," disgusting "," amazing ") - message = replacetext(message," loser "," winner ") - message = replacetext(message," useless "," useful ") - message = replacetext(message," oh god "," cheese and crackers ") - message = replacetext(message," jesus "," gee wiz ") - message = replacetext(message," weak "," strong ") - message = replacetext(message," kill "," hug ") - message = replacetext(message," murder "," tease ") - message = replacetext(message," ugly "," beautiful ") - message = replacetext(message," douchbag "," nice guy ") - message = replacetext(message," whore "," lady ") - message = replacetext(message," nerd "," smart guy ") - message = replacetext(message," moron "," fun person ") - message = replacetext(message," IT'S LOOSE "," EVERYTHING IS FINE ") - message = replacetext(message," sex "," hug fight ") - message = replacetext(message," idiot "," genius ") - message = replacetext(message," fat "," thin ") - message = replacetext(message," beer "," water with ice ") - message = replacetext(message," drink "," water ") - message = replacetext(message," feminist "," empowered woman ") - message = replacetext(message," i hate you "," you're mean ") - message = replacetext(message," nigger "," african american ") - message = replacetext(message," jew "," jewish ") - message = replacetext(message," shit "," shiz ") - message = replacetext(message," crap "," poo ") - message = replacetext(message," slut "," tease ") - message = replacetext(message," ass "," butt ") - message = replacetext(message," damn "," dang ") - message = replacetext(message," fuck "," ") - message = replacetext(message," penis "," privates ") - message = replacetext(message," cunt "," privates ") - message = replacetext(message," dick "," jerk ") - message = replacetext(message," vagina "," privates ") - return trim(message) - -/datum/mutation/human/unintelligable - name = "Unintelligable" - quality = NEGATIVE - text_gain_indication = "You can't seem to form any coherent thoughts!" - text_lose_indication = "Your mind feels more clear." - -/datum/mutation/human/unintelligable/say_mod(message) - if(message) - var/prefix=copytext(message,1,2) - if(prefix == ";") - message = copytext(message,2) - else if(prefix in list(":","#")) - prefix += copytext(message,2,3) - message = copytext(message,3) - else - prefix="" - - var/list/words = splittext(message," ") - var/list/rearranged = list() - for(var/i=1;i<=words.len;i++) - var/cword = pick(words) - words.Remove(cword) - var/suffix = copytext(cword,length(cword)-1,length(cword)) - while(length(cword)>0 && suffix in list(".",",",";","!",":","?")) - cword = copytext(cword,1 ,length(cword)-1) - suffix = copytext(cword,length(cword)-1,length(cword) ) - if(length(cword)) - rearranged += cword - message = "[prefix][uppertext(jointext(rearranged," "))]!!" - return message - -/datum/mutation/human/swedish - name = "Swedish" - quality = MINOR_NEGATIVE - dna_block = NON_SCANNABLE - text_gain_indication = "You feel Swedish, however that works." - text_lose_indication = "The feeling of Swedishness passes." - -/datum/mutation/human/swedish/say_mod(message) - if(message) - message = replacetext(message,"w","v") - message = replacetext(message,"j","y") - message = replacetext(message,"a",pick("�","�","�","a")) - message = replacetext(message,"bo","bjo") - message = replacetext(message,"o",pick("�","�","o")) - if(prob(30)) - message += " Bork[pick("",", bork",", bork, bork")]!" - return message - -/datum/mutation/human/chav - name = "Chav" - quality = MINOR_NEGATIVE - dna_block = NON_SCANNABLE - text_gain_indication = "Ye feel like a reet prat like, innit?" - text_lose_indication = "You no longer feel like being rude and sassy." - -/datum/mutation/human/chav/say_mod(message) - if(message) - message = " [message] " - message = replacetext(message," looking at "," gawpin' at ") - message = replacetext(message," great "," bangin' ") - message = replacetext(message," man "," mate ") - message = replacetext(message," friend ",pick(" mate "," bruv "," bledrin ")) - message = replacetext(message," what "," wot ") - message = replacetext(message," drink "," wet ") - message = replacetext(message," get "," giz ") - message = replacetext(message," what "," wot ") - message = replacetext(message," no thanks "," wuddent fukken do one ") - message = replacetext(message," i don't know "," wot mate ") - message = replacetext(message," no "," naw ") - message = replacetext(message," robust "," chin ") - message = replacetext(message," hi "," how what how ") - message = replacetext(message," hello "," sup bruv ") - message = replacetext(message," kill "," bang ") - message = replacetext(message," murder "," bang ") - message = replacetext(message," windows "," windies ") - message = replacetext(message," window "," windy ") - message = replacetext(message," break "," do ") - message = replacetext(message," your "," yer ") - message = replacetext(message," security "," coppers ") - return trim(message) - -/datum/mutation/human/elvis - name = "Elvis" - quality = MINOR_NEGATIVE - dna_block = NON_SCANNABLE - text_gain_indication = "You feel pretty good, honeydoll." - text_lose_indication = "You feel a little less conversation would be great." - -/datum/mutation/human/elvis/on_life(mob/living/carbon/human/owner) - switch(pick(1,2)) - if(1) - if(prob(15)) - var/list/dancetypes = list("swinging", "fancy", "stylish", "20'th century", "jivin'", "rock and roller", "cool", "salacious", "bashing", "smashing") - var/dancemoves = pick(dancetypes) - owner.visible_message("[owner] busts out some [dancemoves] moves!") - if(2) - if(prob(15)) - owner.visible_message("[owner] [pick("jiggles their hips", "rotates their hips", "gyrates their hips", "taps their foot", "dances to an imaginary song", "jiggles their legs", "snaps their fingers")]!") - -/datum/mutation/human/elvis/say_mod(message) - if(message) - message = " [message] " - message = replacetext(message," i'm not "," I aint ") - message = replacetext(message," girl ",pick(" honey "," baby "," baby doll ")) - message = replacetext(message," man ",pick(" son "," buddy "," brother"," pal "," friendo ")) - message = replacetext(message," out of "," outta ") - message = replacetext(message," thank you "," thank you, thank you very much ") - message = replacetext(message," what are you "," whatcha ") - message = replacetext(message," yes ",pick(" sure", "yea ")) - message = replacetext(message," faggot "," square ") - message = replacetext(message," muh valids "," getting my kicks ") - return trim(message) - -/datum/mutation/human/stoner - name = "Stoner" - quality = NEGATIVE - dna_block = NON_SCANNABLE - text_gain_indication = "You feel...totally chill, man!" - text_lose_indication = "You feel like you have a better sense of time." - -/datum/mutation/human/stoner/on_acquiring(mob/living/carbon/human/owner) - ..() - owner.grant_language(/datum/language/beachbum) - owner.remove_language(/datum/language/common) - -/datum/mutation/human/stoner/on_losing(mob/living/carbon/human/owner) - ..() - owner.grant_language(/datum/language/common) - owner.remove_language(/datum/language/beachbum) - -/datum/mutation/human/laser_eyes - name = "Laser Eyes" - quality = POSITIVE - dna_block = NON_SCANNABLE - text_gain_indication = "You feel pressure building up behind your eyes." - layer_used = FRONT_MUTATIONS_LAYER - limb_req = "head" - -/datum/mutation/human/laser_eyes/New() - ..() - visual_indicators |= mutable_appearance('icons/effects/genetics.dmi', "lasereyes", -FRONT_MUTATIONS_LAYER) - -/datum/mutation/human/laser_eyes/get_visual_indicator(mob/living/carbon/human/owner) - return visual_indicators[1] - -/datum/mutation/human/laser_eyes/on_ranged_attack(mob/living/carbon/human/owner, atom/target, mouseparams) - if(owner.a_intent == INTENT_HARM) - owner.LaserEyes(target, mouseparams) - - /mob/living/carbon/proc/update_mutations_overlay() return diff --git a/code/datums/mutations/body.dm b/code/datums/mutations/body.dm new file mode 100644 index 0000000000..23b91add58 --- /dev/null +++ b/code/datums/mutations/body.dm @@ -0,0 +1,148 @@ +//These mutations change your overall "form" somehow, like size + +//Epilepsy gives a very small chance to have a seizure every life tick, knocking you unconscious. +/datum/mutation/human/epilepsy + name = "Epilepsy" + quality = NEGATIVE + text_gain_indication = "You get a headache." + +/datum/mutation/human/epilepsy/on_life(mob/living/carbon/human/owner) + if(prob(1) && owner.stat == CONSCIOUS) + owner.visible_message("[owner] starts having a seizure!", "You have a seizure!") + owner.Unconscious(200) + owner.Jitter(1000) + addtimer(CALLBACK(src, .proc/jitter_less, owner), 90) + +/datum/mutation/human/epilepsy/proc/jitter_less(mob/living/carbon/human/owner) + if(owner) + owner.jitteriness = 10 + + +//Unstable DNA induces random mutations! +/datum/mutation/human/bad_dna + name = "Unstable DNA" + quality = NEGATIVE + text_gain_indication = "You feel strange." + +/datum/mutation/human/bad_dna/on_acquiring(mob/living/carbon/human/owner) + to_chat(owner, text_gain_indication) + var/mob/new_mob + if(prob(95)) + if(prob(50)) + new_mob = owner.randmutb() + else + new_mob = owner.randmuti() + else + new_mob = owner.randmutg() + if(new_mob && ismob(new_mob)) + owner = new_mob + . = owner + on_losing(owner) + + +//Cough gives you a chronic cough that causes you to drop items. +/datum/mutation/human/cough + name = "Cough" + quality = MINOR_NEGATIVE + text_gain_indication = "You start coughing." + +/datum/mutation/human/cough/on_life(mob/living/carbon/human/owner) + if(prob(5) && owner.stat == CONSCIOUS) + owner.drop_all_held_items() + owner.emote("cough") + + +//Dwarfism shrinks your body and lets you pass tables. +/datum/mutation/human/dwarfism + name = "Dwarfism" + quality = POSITIVE + get_chance = 15 + lowest_value = 256 * 12 + +/datum/mutation/human/dwarfism/on_acquiring(mob/living/carbon/human/owner) + if(..()) + return + owner.resize = 0.8 + owner.update_transform() + owner.pass_flags |= PASSTABLE + owner.visible_message("[owner] suddenly shrinks!", "Everything around you seems to grow..") + +/datum/mutation/human/dwarfism/on_losing(mob/living/carbon/human/owner) + if(..()) + return + owner.resize = 1.25 + owner.update_transform() + owner.pass_flags &= ~PASSTABLE + owner.visible_message("[owner] suddenly grows!", "Everything around you seems to shrink..") + + +//Clumsiness has a very large amount of small drawbacks depending on item. +/datum/mutation/human/clumsy + name = "Clumsiness" + quality = MINOR_NEGATIVE + text_gain_indication = "You feel lightheaded." + +/datum/mutation/human/clumsy/on_acquiring(mob/living/carbon/human/owner) + if(..()) + return + owner.disabilities |= CLUMSY + +/datum/mutation/human/clumsy/on_losing(mob/living/carbon/human/owner) + if(..()) + return + owner.disabilities &= ~CLUMSY + + +//Tourettes causes you to randomly stand in place and shout. +/datum/mutation/human/tourettes + name = "Tourettes Syndrome" + quality = NEGATIVE + text_gain_indication = "You twitch." + +/datum/mutation/human/tourettes/on_life(mob/living/carbon/human/owner) + if(prob(10) && owner.stat == CONSCIOUS) + owner.Stun(200) + switch(rand(1, 3)) + if(1) + owner.emote("twitch") + if(2 to 3) + owner.say("[prob(50) ? ";" : ""][pick("SHIT", "PISS", "FUCK", "CUNT", "COCKSUCKER", "MOTHERFUCKER", "TITS")]") + var/x_offset_old = owner.pixel_x + var/y_offset_old = owner.pixel_y + var/x_offset = owner.pixel_x + rand(-2,2) + var/y_offset = owner.pixel_y + rand(-1,1) + animate(owner, pixel_x = x_offset, pixel_y = y_offset, time = 1) + animate(owner, pixel_x = x_offset_old, pixel_y = y_offset_old, time = 1) + + +//Deafness makes you deaf. +/datum/mutation/human/deaf + name = "Deafness" + quality = NEGATIVE + text_gain_indication = "You can't seem to hear anything." + +/datum/mutation/human/deaf/on_acquiring(mob/living/carbon/human/owner) + if(..()) + return + owner.disabilities |= DEAF + +/datum/mutation/human/deaf/on_losing(mob/living/carbon/human/owner) + if(..()) + return + owner.disabilities &= ~DEAF + + +//Monified turns you into a monkey. +/datum/mutation/human/race + name = "Monkified" + quality = NEGATIVE + time_coeff = 2 + +/datum/mutation/human/race/on_acquiring(mob/living/carbon/human/owner) + if(..()) + return + . = owner.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE) + +/datum/mutation/human/race/on_losing(mob/living/carbon/monkey/owner) + if(owner && istype(owner) && owner.stat != DEAD && (owner.dna.mutations.Remove(src))) + . = owner.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE) diff --git a/code/datums/mutations/chameleon.dm b/code/datums/mutations/chameleon.dm new file mode 100644 index 0000000000..da10510970 --- /dev/null +++ b/code/datums/mutations/chameleon.dm @@ -0,0 +1,30 @@ +//Chameleon causes the owner to slowly become transparent when not moving. +/datum/mutation/human/chameleon + name = "Chameleon" + quality = POSITIVE + get_chance = 20 + lowest_value = 256 * 12 + text_gain_indication = "You feel one with your surroundings." + text_lose_indication = "You feel oddly exposed." + time_coeff = 5 + +/datum/mutation/human/chameleon/on_acquiring(mob/living/carbon/human/owner) + if(..()) + return + owner.alpha = CHAMELEON_MUTATION_DEFAULT_TRANSPARENCY + +/datum/mutation/human/chameleon/on_life(mob/living/carbon/human/owner) + owner.alpha = max(0, owner.alpha - 25) + +/datum/mutation/human/chameleon/on_move(mob/living/carbon/human/owner) + owner.alpha = CHAMELEON_MUTATION_DEFAULT_TRANSPARENCY + +/datum/mutation/human/chameleon/on_attack_hand(mob/living/carbon/human/owner, atom/target, proximity) + if(proximity) //stops tk from breaking chameleon + owner.alpha = CHAMELEON_MUTATION_DEFAULT_TRANSPARENCY + return + +/datum/mutation/human/chameleon/on_losing(mob/living/carbon/human/owner) + if(..()) + return + owner.alpha = 255 diff --git a/code/datums/mutations/cold_resistance.dm b/code/datums/mutations/cold_resistance.dm new file mode 100644 index 0000000000..6281514e71 --- /dev/null +++ b/code/datums/mutations/cold_resistance.dm @@ -0,0 +1,20 @@ +//Cold Resistance gives your entire body an orange halo, and makes you immune to the effects of vacuum and cold. +/datum/mutation/human/cold_resistance + name = "Cold Resistance" + quality = POSITIVE + get_chance = 25 + lowest_value = 256 * 12 + text_gain_indication = "Your body feels warm!" + time_coeff = 5 + +/datum/mutation/human/cold_resistance/New() + ..() + visual_indicators |= mutable_appearance('icons/effects/genetics.dmi', "fire", -MUTATIONS_LAYER) + +/datum/mutation/human/cold_resistance/get_visual_indicator(mob/living/carbon/human/owner) + return visual_indicators[1] + +/datum/mutation/human/cold_resistance/on_life(mob/living/carbon/human/owner) + if(owner.getFireLoss()) + if(prob(1)) + owner.heal_bodypart_damage(0,1) //Is this really needed? diff --git a/code/datums/mutations/hulk.dm b/code/datums/mutations/hulk.dm new file mode 100644 index 0000000000..666c910557 --- /dev/null +++ b/code/datums/mutations/hulk.dm @@ -0,0 +1,36 @@ +//Hulk turns your skin green, and allows you to punch through walls. +/datum/mutation/human/hulk + name = "Hulk" + quality = POSITIVE + get_chance = 15 + lowest_value = 256 * 12 + text_gain_indication = "Your muscles hurt!" + species_allowed = list("fly") //no skeleton/lizard hulk + health_req = 25 + +/datum/mutation/human/hulk/on_acquiring(mob/living/carbon/human/owner) + if(..()) + return + var/status = CANSTUN | CANKNOCKDOWN | CANUNCONSCIOUS | CANPUSH + owner.status_flags &= ~status + owner.update_body_parts() + +/datum/mutation/human/hulk/on_attack_hand(mob/living/carbon/human/owner, atom/target, proximity) + if(proximity) //no telekinetic hulk attack + return target.attack_hulk(owner) + +/datum/mutation/human/hulk/on_life(mob/living/carbon/human/owner) + if(owner.health < 0) + on_losing(owner) + to_chat(owner, "You suddenly feel very weak.") + +/datum/mutation/human/hulk/on_losing(mob/living/carbon/human/owner) + if(..()) + return + owner.status_flags |= CANSTUN | CANKNOCKDOWN | CANUNCONSCIOUS | CANPUSH + owner.update_body_parts() + +/datum/mutation/human/hulk/say_mod(message) + if(message) + message = "[uppertext(replacetext(message, ".", "!"))]!!" + return message diff --git a/code/datums/mutations/sight.dm b/code/datums/mutations/sight.dm new file mode 100644 index 0000000000..dee26166dd --- /dev/null +++ b/code/datums/mutations/sight.dm @@ -0,0 +1,74 @@ +//Nearsightedness restricts your vision by several tiles. +/datum/mutation/human/nearsight + name = "Near Sightness" + quality = MINOR_NEGATIVE + text_gain_indication = "You can't see very well." + +/datum/mutation/human/nearsight/on_acquiring(mob/living/carbon/human/owner) + if(..()) + return + owner.become_nearsighted() + +/datum/mutation/human/nearsight/on_losing(mob/living/carbon/human/owner) + if(..()) + return + owner.cure_nearsighted() + + +//Blind makes you blind. Who knew? +/datum/mutation/human/blind + name = "Blindness" + quality = NEGATIVE + text_gain_indication = "You can't seem to see anything." + +/datum/mutation/human/blind/on_acquiring(mob/living/carbon/human/owner) + if(..()) + return + owner.become_blind() + +/datum/mutation/human/blind/on_losing(mob/living/carbon/human/owner) + if(..()) + return + owner.cure_blind() + + +//X-Ray Vision lets you see through walls. +/datum/mutation/human/x_ray + name = "X Ray Vision" + quality = POSITIVE + get_chance = 25 + lowest_value = 256 * 12 + text_gain_indication = "The walls suddenly disappear!" + time_coeff = 2 + +/datum/mutation/human/x_ray/on_acquiring(mob/living/carbon/human/owner) + if(..()) + return + + owner.update_sight() + +/datum/mutation/human/x_ray/on_losing(mob/living/carbon/human/owner) + if(..()) + return + owner.update_sight() + + +//Laser Eyes lets you shoot lasers from your eyes! +/datum/mutation/human/laser_eyes + name = "Laser Eyes" + quality = POSITIVE + dna_block = NON_SCANNABLE + text_gain_indication = "You feel pressure building up behind your eyes." + layer_used = FRONT_MUTATIONS_LAYER + limb_req = "head" + +/datum/mutation/human/laser_eyes/New() + ..() + visual_indicators |= mutable_appearance('icons/effects/genetics.dmi', "lasereyes", -FRONT_MUTATIONS_LAYER) + +/datum/mutation/human/laser_eyes/get_visual_indicator(mob/living/carbon/human/owner) + return visual_indicators[1] + +/datum/mutation/human/laser_eyes/on_ranged_attack(mob/living/carbon/human/owner, atom/target, mouseparams) + if(owner.a_intent == INTENT_HARM) + owner.LaserEyes(target, mouseparams) diff --git a/code/datums/mutations/speech.dm b/code/datums/mutations/speech.dm new file mode 100644 index 0000000000..3b4b38bbcc --- /dev/null +++ b/code/datums/mutations/speech.dm @@ -0,0 +1,232 @@ +//These are all minor mutations that affect your speech somehow. +//Individual ones aren't commented since their functions should be evident at a glance + +/datum/mutation/human/nervousness + name = "Nervousness" + quality = MINOR_NEGATIVE + text_gain_indication = "You feel nervous." + +/datum/mutation/human/nervousness/on_life(mob/living/carbon/human/owner) + if(prob(10)) + owner.stuttering = max(10, owner.stuttering) + + +/datum/mutation/human/wacky + name = "Wacky" + quality = MINOR_NEGATIVE + text_gain_indication = "You feel an off sensation in your voicebox." + text_lose_indication = "The off sensation passes." + +/datum/mutation/human/wacky/get_spans() + return list(SPAN_SANS) + + +/datum/mutation/human/mute + name = "Mute" + quality = NEGATIVE + text_gain_indication = "You feel unable to express yourself at all." + text_lose_indication = "You feel able to speak freely again." + +/datum/mutation/human/mute/on_acquiring(mob/living/carbon/human/owner) + if(..()) + return + owner.disabilities |= MUTE + +/datum/mutation/human/mute/on_losing(mob/living/carbon/human/owner) + if(..()) + return + owner.disabilities &= ~MUTE + + +/datum/mutation/human/smile + name = "Smile" + quality = MINOR_NEGATIVE + dna_block = NON_SCANNABLE + text_gain_indication = "You feel so happy. Nothing can be wrong with anything. :)" + text_lose_indication = "Everything is terrible again. :(" + +/datum/mutation/human/smile/say_mod(message) + if(message) + message = " [message] " + //Time for a friendly game of SS13 + message = replacetext(message," stupid "," smart ") + message = replacetext(message," retard "," genius ") + message = replacetext(message," unrobust "," robust ") + message = replacetext(message," dumb "," smart ") + message = replacetext(message," awful "," great ") + message = replacetext(message," gay ",pick(" nice "," ok "," alright ")) + message = replacetext(message," horrible "," fun ") + message = replacetext(message," terrible "," terribly fun ") + message = replacetext(message," terrifying "," wonderful ") + message = replacetext(message," gross "," cool ") + message = replacetext(message," disgusting "," amazing ") + message = replacetext(message," loser "," winner ") + message = replacetext(message," useless "," useful ") + message = replacetext(message," oh god "," cheese and crackers ") + message = replacetext(message," jesus "," gee wiz ") + message = replacetext(message," weak "," strong ") + message = replacetext(message," kill "," hug ") + message = replacetext(message," murder "," tease ") + message = replacetext(message," ugly "," beautiful ") + message = replacetext(message," douchbag "," nice guy ") + message = replacetext(message," whore "," lady ") + message = replacetext(message," nerd "," smart guy ") + message = replacetext(message," moron "," fun person ") + message = replacetext(message," IT'S LOOSE "," EVERYTHING IS FINE ") + message = replacetext(message," sex "," hug fight ") + message = replacetext(message," idiot "," genius ") + message = replacetext(message," fat "," thin ") + message = replacetext(message," beer "," water with ice ") + message = replacetext(message," drink "," water ") + message = replacetext(message," feminist "," empowered woman ") + message = replacetext(message," i hate you "," you're mean ") + message = replacetext(message," nigger "," african american ") + message = replacetext(message," jew "," jewish ") + message = replacetext(message," shit "," shiz ") + message = replacetext(message," crap "," poo ") + message = replacetext(message," slut "," tease ") + message = replacetext(message," ass "," butt ") + message = replacetext(message," damn "," dang ") + message = replacetext(message," fuck "," ") + message = replacetext(message," penis "," privates ") + message = replacetext(message," cunt "," privates ") + message = replacetext(message," dick "," jerk ") + message = replacetext(message," vagina "," privates ") + return trim(message) + + +/datum/mutation/human/unintelligible + name = "Unintelligible" + quality = NEGATIVE + dna_block = NON_SCANNABLE + text_gain_indication = "You can't seem to form any coherent thoughts!" + text_lose_indication = "Your mind feels more clear." + +/datum/mutation/human/unintelligible/say_mod(message) + if(message) + var/prefix=copytext(message,1,2) + if(prefix == ";") + message = copytext(message,2) + else if(prefix in list(":","#")) + prefix += copytext(message,2,3) + message = copytext(message,3) + else + prefix="" + + var/list/words = splittext(message," ") + var/list/rearranged = list() + for(var/i=1;i<=words.len;i++) + var/cword = pick(words) + words.Remove(cword) + var/suffix = copytext(cword,length(cword)-1,length(cword)) + while(length(cword)>0 && suffix in list(".",",",";","!",":","?")) + cword = copytext(cword,1 ,length(cword)-1) + suffix = copytext(cword,length(cword)-1,length(cword) ) + if(length(cword)) + rearranged += cword + message ="[prefix][jointext(rearranged," ")]" + return message + + +/datum/mutation/human/swedish + name = "Swedish" + quality = MINOR_NEGATIVE + dna_block = NON_SCANNABLE + text_gain_indication = "You feel Swedish, however that works." + text_lose_indication = "The feeling of Swedishness passes." + +/datum/mutation/human/swedish/say_mod(message) + if(message) + message = replacetext(message,"w","v") + message = replacetext(message,"j","y") + message = replacetext(message,"a",pick("�","�","�","a")) + message = replacetext(message,"bo","bjo") + message = replacetext(message,"o",pick("�","�","o")) + if(prob(30)) + message += " Bork[pick("",", bork",", bork, bork")]!" + return message + + +/datum/mutation/human/chav + name = "Chav" + quality = MINOR_NEGATIVE + dna_block = NON_SCANNABLE + text_gain_indication = "Ye feel like a reet prat like, innit?" + text_lose_indication = "You no longer feel like being rude and sassy." + +/datum/mutation/human/chav/say_mod(message) + if(message) + message = " [message] " + message = replacetext(message," looking at "," gawpin' at ") + message = replacetext(message," great "," bangin' ") + message = replacetext(message," man "," mate ") + message = replacetext(message," friend ",pick(" mate "," bruv "," bledrin ")) + message = replacetext(message," what "," wot ") + message = replacetext(message," drink "," wet ") + message = replacetext(message," get "," giz ") + message = replacetext(message," what "," wot ") + message = replacetext(message," no thanks "," wuddent fukken do one ") + message = replacetext(message," i don't know "," wot mate ") + message = replacetext(message," no "," naw ") + message = replacetext(message," robust "," chin ") + message = replacetext(message," hi "," how what how ") + message = replacetext(message," hello "," sup bruv ") + message = replacetext(message," kill "," bang ") + message = replacetext(message," murder "," bang ") + message = replacetext(message," windows "," windies ") + message = replacetext(message," window "," windy ") + message = replacetext(message," break "," do ") + message = replacetext(message," your "," yer ") + message = replacetext(message," security "," coppers ") + return trim(message) + + +/datum/mutation/human/elvis + name = "Elvis" + quality = MINOR_NEGATIVE + dna_block = NON_SCANNABLE + text_gain_indication = "You feel pretty good, honeydoll." + text_lose_indication = "You feel a little less conversation would be great." + +/datum/mutation/human/elvis/on_life(mob/living/carbon/human/owner) + switch(pick(1,2)) + if(1) + if(prob(15)) + var/list/dancetypes = list("swinging", "fancy", "stylish", "20'th century", "jivin'", "rock and roller", "cool", "salacious", "bashing", "smashing") + var/dancemoves = pick(dancetypes) + owner.visible_message("[owner] busts out some [dancemoves] moves!") + if(2) + if(prob(15)) + owner.visible_message("[owner] [pick("jiggles their hips", "rotates their hips", "gyrates their hips", "taps their foot", "dances to an imaginary song", "jiggles their legs", "snaps their fingers")]!") + +/datum/mutation/human/elvis/say_mod(message) + if(message) + message = " [message] " + message = replacetext(message," i'm not "," I aint ") + message = replacetext(message," girl ",pick(" honey "," baby "," baby doll ")) + message = replacetext(message," man ",pick(" son "," buddy "," brother"," pal "," friendo ")) + message = replacetext(message," out of "," outta ") + message = replacetext(message," thank you "," thank you, thank you very much ") + message = replacetext(message," what are you "," whatcha ") + message = replacetext(message," yes ",pick(" sure", "yea ")) + message = replacetext(message," faggot "," square ") + message = replacetext(message," muh valids "," getting my kicks ") + return trim(message) + + +/datum/mutation/human/stoner + name = "Stoner" + quality = NEGATIVE + dna_block = NON_SCANNABLE + text_gain_indication = "You feel...totally chill, man!" + text_lose_indication = "You feel like you have a better sense of time." + +/datum/mutation/human/stoner/on_acquiring(mob/living/carbon/human/owner) + ..() + owner.grant_language(/datum/language/beachbum) + owner.remove_language(/datum/language/common) + +/datum/mutation/human/stoner/on_losing(mob/living/carbon/human/owner) + ..() + owner.grant_language(/datum/language/common) + owner.remove_language(/datum/language/beachbum) diff --git a/code/datums/mutations/telekinesis.dm b/code/datums/mutations/telekinesis.dm new file mode 100644 index 0000000000..3aa562ee74 --- /dev/null +++ b/code/datums/mutations/telekinesis.dm @@ -0,0 +1,18 @@ +//Telekinesis lets you interact with objects from range, and gives you a light blue halo around your head. +/datum/mutation/human/telekinesis + name = "Telekinesis" + quality = POSITIVE + get_chance = 20 + lowest_value = 256 * 12 + text_gain_indication = "You feel smarter!" + limb_req = "head" + +/datum/mutation/human/telekinesis/New() + ..() + visual_indicators |= mutable_appearance('icons/effects/genetics.dmi', "telekinesishead", -MUTATIONS_LAYER) + +/datum/mutation/human/telekinesis/get_visual_indicator(mob/living/carbon/human/owner) + return visual_indicators[1] + +/datum/mutation/human/telekinesis/on_ranged_attack(mob/living/carbon/human/owner, atom/target) + target.attack_tk(owner) diff --git a/code/datums/progressbar.dm b/code/datums/progressbar.dm index f9883cfe50..3599c60f89 100644 --- a/code/datums/progressbar.dm +++ b/code/datums/progressbar.dm @@ -38,7 +38,7 @@ if (user.client) user.client.images += bar - progress = Clamp(progress, 0, goal) + progress = CLAMP(progress, 0, goal) bar.icon_state = "prog_bar_[round(((progress / goal) * 100), 5)]" if (!shown) user.client.images += bar diff --git a/code/datums/radiation_wave.dm b/code/datums/radiation_wave.dm index f065ccfeab..68d8ebc31f 100644 --- a/code/datums/radiation_wave.dm +++ b/code/datums/radiation_wave.dm @@ -34,7 +34,7 @@ var/strength if(steps>1) - strength = InverseSquareLaw(intensity, max(range_modifier*steps, 1), 1) + strength = INVERSE_SQUARE(intensity, max(range_modifier*steps, 1), 1) else strength = intensity @@ -42,7 +42,7 @@ qdel(src) return - radiate(atoms, Floor(strength)) + radiate(atoms, FLOOR(strength, 1)) check_obstructions(atoms) // reduce our overall strength if there are radiation insulators diff --git a/code/datums/riding.dm b/code/datums/riding.dm deleted file mode 100644 index 7cd12ae6c8..0000000000 --- a/code/datums/riding.dm +++ /dev/null @@ -1,442 +0,0 @@ -/datum/riding - var/next_vehicle_move = 0 //used for move delays - var/vehicle_move_delay = 2 //tick delay between movements, lower = faster, higher = slower - var/keytype = null - var/atom/movable/ridden = null - - var/slowed = FALSE - var/slowvalue = 1 - -/datum/riding/New(atom/movable/_ridden) - ridden = _ridden - -/datum/riding/Destroy() - ridden = null - return ..() - -/datum/riding/proc/handle_vehicle_layer() - if(ridden.dir != NORTH) - ridden.layer = ABOVE_MOB_LAYER - else - ridden.layer = OBJ_LAYER - -/datum/riding/proc/on_vehicle_move() - for(var/mob/living/M in ridden.buckled_mobs) - ride_check(M) - handle_vehicle_offsets() - handle_vehicle_layer() - -/datum/riding/proc/ride_check(mob/living/M) - return TRUE - -/datum/riding/proc/force_dismount(mob/living/M) - ridden.unbuckle_mob(M) - -/datum/riding/proc/handle_vehicle_offsets() - var/ridden_dir = "[ridden.dir]" - var/passindex = 0 - if(ridden.has_buckled_mobs()) - for(var/m in ridden.buckled_mobs) - passindex++ - var/mob/living/buckled_mob = m - var/list/offsets = get_offsets(passindex) - var/rider_dir = get_rider_dir(passindex) - buckled_mob.setDir(rider_dir) - dir_loop: - for(var/offsetdir in offsets) - if(offsetdir == ridden_dir) - var/list/diroffsets = offsets[offsetdir] - buckled_mob.pixel_x = diroffsets[1] - if(diroffsets.len >= 2) - buckled_mob.pixel_y = diroffsets[2] - if(diroffsets.len == 3) - buckled_mob.layer = diroffsets[3] - break dir_loop - - -//Override this to set your vehicle's various pixel offsets -/datum/riding/proc/get_offsets(pass_index) // list(dir = x, y, layer) - return list("[NORTH]" = list(0, 0), "[SOUTH]" = list(0, 0), "[EAST]" = list(0, 0), "[WEST]" = list(0, 0)) - -//Override this to set the passengers/riders dir based on which passenger they are. -//ie: rider facing the vehicle's dir, but passenger 2 facing backwards, etc. -/datum/riding/proc/get_rider_dir(pass_index) - return ridden.dir - -//KEYS -/datum/riding/proc/keycheck(mob/user) - if(keytype) - if(user.is_holding_item_of_type(keytype)) - return TRUE - else - return TRUE - return FALSE - -//BUCKLE HOOKS -/datum/riding/proc/restore_position(mob/living/buckled_mob) - if(istype(buckled_mob)) - buckled_mob.pixel_x = 0 - buckled_mob.pixel_y = 0 - if(buckled_mob.client) - buckled_mob.client.change_view(world.view) - -//MOVEMENT -/datum/riding/proc/handle_ride(mob/user, direction) - if(user.incapacitated()) - Unbuckle(user) - return - - if(world.time < next_vehicle_move) - return - next_vehicle_move = world.time + vehicle_move_delay - if(keycheck(user)) - if(!Process_Spacemove(direction) || !isturf(ridden.loc)) - return - step(ridden, direction) - - handle_vehicle_layer() - handle_vehicle_offsets() - else - to_chat(user, "You'll need the keys in one of your hands to drive \the [ridden.name].") - -/datum/riding/proc/Unbuckle(atom/movable/M) - addtimer(CALLBACK(ridden, /atom/movable/.proc/unbuckle_mob, M), 0, TIMER_UNIQUE) - -/datum/riding/proc/Process_Spacemove(direction) - if(ridden.has_gravity()) - return 1 - - return 0 - -/datum/riding/space/Process_Spacemove(direction) - return 1 - - -//atv -/datum/riding/atv - keytype = /obj/item/key - vehicle_move_delay = 1 - -/datum/riding/atv/get_offsets(pass_index) // list(dir = x, y, layer) - return list("[NORTH]" = list(0, 4), "[SOUTH]" = list(0, 4), "[EAST]" = list(0, 4), "[WEST]" = list( 0, 4)) - - -/datum/riding/atv/handle_vehicle_layer() - if(ridden.dir == SOUTH) - ridden.layer = ABOVE_MOB_LAYER - else - ridden.layer = OBJ_LAYER - -/datum/riding/atv/turret - var/obj/machinery/porta_turret/syndicate/vehicle_turret/turret = null - -/datum/riding/atv/turret/handle_vehicle_layer() - if(ridden.dir == SOUTH) - ridden.layer = ABOVE_MOB_LAYER - else - ridden.layer = OBJ_LAYER - - if(turret) - if(ridden.dir == NORTH) - turret.layer = ABOVE_MOB_LAYER - else - turret.layer = OBJ_LAYER - - -/datum/riding/atv/turret/handle_vehicle_offsets() - ..() - if(turret) - turret.forceMove(get_turf(ridden)) - switch(ridden.dir) - if(NORTH) - turret.pixel_x = 0 - turret.pixel_y = 4 - if(EAST) - turret.pixel_x = -12 - turret.pixel_y = 4 - if(SOUTH) - turret.pixel_x = 0 - turret.pixel_y = 4 - if(WEST) - turret.pixel_x = 12 - turret.pixel_y = 4 - - -//pimpin ride -/datum/riding/janicart - keytype = /obj/item/key/janitor - - -/datum/riding/janicart/get_offsets(pass_index) // list(dir = x, y, layer) - return list("[NORTH]" = list(0, 4), "[SOUTH]" = list(0, 7), "[EAST]" = list(-12, 7), "[WEST]" = list( 12, 7)) - -//scooter -/datum/riding/scooter/handle_vehicle_layer() - if(ridden.dir == SOUTH) - ridden.layer = ABOVE_MOB_LAYER - else - ridden.layer = OBJ_LAYER - -/datum/riding/scooter/get_offsets(pass_index) // list(dir = x, y, layer) - return list("[NORTH]" = list(0), "[SOUTH]" = list(-2), "[EAST]" = list(0), "[WEST]" = list( 2)) - -/datum/riding/scooter/handle_vehicle_offsets() - ..() - if(ridden.has_buckled_mobs()) - for(var/m in ridden.buckled_mobs) - var/mob/living/buckled_mob = m - if(buckled_mob.get_num_legs() > 0) - buckled_mob.pixel_y = 5 - else - buckled_mob.pixel_y = -4 - -/datum/riding/proc/account_limbs(mob/living/M) - if(M.get_num_legs() < 2 && !slowed) - vehicle_move_delay = vehicle_move_delay + slowvalue - slowed = TRUE - else if(slowed) - vehicle_move_delay = vehicle_move_delay - slowvalue - slowed = FALSE - -/datum/riding/scooter/skateboard - vehicle_move_delay = 0//fast - - -//secway -/datum/riding/secway - keytype = /obj/item/key/security - -/datum/riding/secway/get_offsets(pass_index) // list(dir = x, y, layer) - return list("[NORTH]" = list(0, 4), "[SOUTH]" = list(0, 4), "[EAST]" = list(0, 4), "[WEST]" = list( 0, 4)) - -//i want to ride my -/datum/riding/bicycle - keytype = null - vehicle_move_delay = 0 - -/datum/riding/bicycle/get_offsets(pass_index) // list(dir = x, y, layer) - return list("[NORTH]" = list(0, 4), "[SOUTH]" = list(0, 4), "[EAST]" = list(0, 4), "[WEST]" = list( 0, 4)) - -//speedbike -/datum/riding/space/speedbike - keytype = null - vehicle_move_delay = 0 - -/datum/riding/space/speedbike/handle_vehicle_layer() - switch(ridden.dir) - if(NORTH,SOUTH) - ridden.pixel_x = -16 - ridden.pixel_y = -16 - if(EAST,WEST) - ridden.pixel_x = -18 - ridden.pixel_y = 0 - -/datum/riding/space/speedbike/get_offsets(pass_index) // list(dir = x, y, layer) - return list("[NORTH]" = list(0, -8), "[SOUTH]" = list(0, 4), "[EAST]" = list(-10, 5), "[WEST]" = list( 10, 5)) - -//SPEEDUWAGON - -/datum/riding/space/speedwagon - vehicle_move_delay = 0 - -/datum/riding/space/speedwagon/handle_vehicle_layer() - ridden.layer = BELOW_MOB_LAYER - -/datum/riding/space/speedwagon/get_offsets(pass_index) // list(dir = x, y, layer) - switch(pass_index) - if(1) - return list("[NORTH]" = list(-10, -4), "[SOUTH]" = list(16, 3), "[EAST]" = list(-4, 30), "[WEST]" = list(4, -3)) - if(2) - return list("[NORTH]" = list(19, -5, 4), "[SOUTH]" = list(-13, 3, 4), "[EAST]" = list(-4, -3, 4.1), "[WEST]" = list(4, 28, 3.9)) - if(3) - return list("[NORTH]" = list(-10, -18, 4.2), "[SOUTH]" = list(16, 25, 3.9), "[EAST]" = list(-22, 30), "[WEST]" = list(22, -3, 4.1)) - if(4) - return list("[NORTH]" = list(19, -18, 4.2), "[SOUTH]" = list(-13, 25, 3.9), "[EAST]" = list(-22, 3, 3.9), "[WEST]" = list(22, 28)) - -///////////////BOATS//////////// -/datum/riding/boat - keytype = /obj/item/oar - -/datum/riding/boat/handle_ride(mob/user, direction) - var/turf/next = get_step(ridden, direction) - var/turf/current = get_turf(ridden) - - if(islava(next) || islava(current)) //We can move from land to lava, or lava to land, but not from land to land - ..() - else - to_chat(user, "Boats don't go on land!") - return 0 - -/datum/riding/boat/dragon - keytype = null - vehicle_move_delay = 1 - -/datum/riding/boat/dragon/get_offsets(pass_index) // list(dir = x, y, layer) - return list("[NORTH]" = list(1, 2), "[SOUTH]" = list(1, 2), "[EAST]" = list(1, 2), "[WEST]" = list( 1, 2)) - -///////////////ANIMALS//////////// -//general animals -/datum/riding/animal - keytype = null - -/datum/riding/animal/handle_ride(mob/user, direction) - if(user.incapacitated()) - Unbuckle(user) - return - - if(world.time < next_vehicle_move) - return - - next_vehicle_move = world.time + vehicle_move_delay - if(keycheck(user)) - if(!isturf(ridden.loc)) - return - step(ridden, direction) - - handle_vehicle_layer() - handle_vehicle_offsets() - else - to_chat(user, "You'll need something to guide the [ridden.name].") - -///////Humans. Yes, I said humans. No, this won't end well...////////// -/datum/riding/human - keytype = null - -/datum/riding/human/ride_check(mob/living/M) - var/mob/living/carbon/human/H = ridden //IF this runtimes I'm blaming the admins. - if(M.incapacitated(FALSE, TRUE) || H.incapacitated(FALSE, TRUE)) - M.visible_message("[M] falls off [ridden]!") - Unbuckle(M) - return FALSE - if(M.restrained(TRUE)) - M.visible_message("[M] can't hang onto [ridden] with their hands cuffed!") //Honestly this should put the ridden mob in a chokehold. - Unbuckle(M) - return FALSE - if(H.pulling == M) - H.stop_pulling() - -/datum/riding/human/get_offsets(pass_index) // list(dir = x, y, layer) - return list("[NORTH]" = list(0, 6), "[SOUTH]" = list(0, 6), "[EAST]" = list(-6, 4), "[WEST]" = list( 6, 4)) - - -/datum/riding/human/handle_vehicle_layer() - if(ridden.buckled_mobs && ridden.buckled_mobs.len) - if(ridden.dir == SOUTH) - ridden.layer = ABOVE_MOB_LAYER - else - ridden.layer = OBJ_LAYER - else - ridden.layer = MOB_LAYER - -/datum/riding/human/force_dismount(mob/living/user) - ridden.unbuckle_mob(user) - user.Knockdown(60) - user.visible_message("[ridden] pushes [user] off of them!") - -/datum/riding/cyborg - keytype = null - -/datum/riding/cyborg/ride_check(mob/user) - if(user.incapacitated()) - var/kick = TRUE - if(iscyborg(ridden)) - var/mob/living/silicon/robot/R = ridden - if(R.module && R.module.ride_allow_incapacitated) - kick = FALSE - if(kick) - to_chat(user, "You fall off of [ridden]!") - Unbuckle(user) - return - if(iscarbon(user)) - var/mob/living/carbon/carbonuser = user - if(!carbonuser.get_num_arms()) - Unbuckle(user) - to_chat(user, "You can't grab onto [ridden] with no hands!") - return - -/datum/riding/cyborg/handle_vehicle_layer() - if(ridden.buckled_mobs && ridden.buckled_mobs.len) - if(ridden.dir == SOUTH) - ridden.layer = ABOVE_MOB_LAYER - else - ridden.layer = OBJ_LAYER - else - ridden.layer = MOB_LAYER - -/datum/riding/cyborg/get_offsets(pass_index) // list(dir = x, y, layer) - return list("[NORTH]" = list(0, 4), "[SOUTH]" = list(0, 4), "[EAST]" = list(-6, 3), "[WEST]" = list( 6, 3)) - -/datum/riding/cyborg/handle_vehicle_offsets() - if(ridden.has_buckled_mobs()) - for(var/mob/living/M in ridden.buckled_mobs) - M.setDir(ridden.dir) - if(iscyborg(ridden)) - var/mob/living/silicon/robot/R = ridden - if(istype(R.module)) - M.pixel_x = R.module.ride_offset_x[dir2text(ridden.dir)] - M.pixel_y = R.module.ride_offset_y[dir2text(ridden.dir)] - else - ..() - -/datum/riding/cyborg/force_dismount(mob/living/M) - ridden.unbuckle_mob(M) - var/turf/target = get_edge_target_turf(ridden, ridden.dir) - var/turf/targetm = get_step(get_turf(ridden), ridden.dir) - M.Move(targetm) - M.visible_message("[M] is thrown clear of [ridden]!") - M.throw_at(target, 14, 5, ridden) - M.Knockdown(60) - -/datum/riding/proc/equip_buckle_inhands(mob/living/carbon/human/user, amount_required = 1) - var/amount_equipped = 0 - for(var/amount_needed = amount_required, amount_needed > 0, amount_needed--) - var/obj/item/riding_offhand/inhand = new /obj/item/riding_offhand(user) - inhand.rider = user - inhand.ridden = ridden - if(user.put_in_hands(inhand, TRUE)) - amount_equipped++ - else - break - if(amount_equipped >= amount_required) - return TRUE - else - unequip_buckle_inhands(user) - return FALSE - -/datum/riding/proc/unequip_buckle_inhands(mob/living/carbon/user) - for(var/obj/item/riding_offhand/O in user.contents) - if(O.ridden != ridden) - CRASH("RIDING OFFHAND ON WRONG MOB") - continue - if(O.selfdeleting) - continue - else - qdel(O) - return TRUE - -/obj/item/riding_offhand - name = "offhand" - icon = 'icons/obj/items_and_weapons.dmi' - icon_state = "offhand" - w_class = WEIGHT_CLASS_HUGE - flags_1 = ABSTRACT_1 | DROPDEL_1 | NOBLUDGEON_1 - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF - var/mob/living/carbon/rider - var/mob/living/ridden - var/selfdeleting = FALSE - -/obj/item/riding_offhand/dropped() - selfdeleting = TRUE - . = ..() - -/obj/item/riding_offhand/equipped() - if(loc != rider) - selfdeleting = TRUE - qdel(src) - . = ..() - -/obj/item/riding_offhand/Destroy() - if(selfdeleting) - if(rider in ridden.buckled_mobs) - ridden.unbuckle_mob(rider) - . = ..() diff --git a/code/datums/saymode.dm b/code/datums/saymode.dm new file mode 100644 index 0000000000..e372d5c0b2 --- /dev/null +++ b/code/datums/saymode.dm @@ -0,0 +1,112 @@ +/datum/saymode + var/key + var/mode + +//Return FALSE if you have handled the message. Otherwise, return TRUE and saycode will continue doing saycode things. +//user = whoever said the message +//message = the message +//language = the language. +/datum/saymode/proc/handle_message(mob/living/user, message, datum/language/language) + return TRUE + + +/datum/saymode/changeling + key = "g" + mode = MODE_CHANGELING + +/datum/saymode/changeling/handle_message(mob/living/user, message, datum/language/language) + switch(user.lingcheck()) + if(LINGHIVE_LINK) + var/msg = "[user.mind]: [message]" + for(var/_M in GLOB.mob_list) + var/mob/M = _M + if(M in GLOB.dead_mob_list) + var/link = FOLLOW_LINK(M, user) + to_chat(M, "[link] [msg]") + else + switch(M.lingcheck()) + if(LINGHIVE_LINK, LINGHIVE_LING) + to_chat(M, msg) + if(LINGHIVE_OUTSIDER) + if(prob(40)) + to_chat(M, "We can faintly sense an outsider trying to communicate through the hivemind...") + if(LINGHIVE_LING) + var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) + var/msg = "[changeling.changelingID]: [message]" + log_talk(src,"[changeling.changelingID]/[user.key] : [message]",LOGSAY) + for(var/_M in GLOB.mob_list) + var/mob/M = _M + if(M in GLOB.dead_mob_list) + var/link = FOLLOW_LINK(M, user) + to_chat(M, "[link] [msg]") + else + switch(M.lingcheck()) + if(LINGHIVE_LINK) + to_chat(M, msg) + if(LINGHIVE_LING) + to_chat(M, msg) + if(LINGHIVE_OUTSIDER) + if(prob(40)) + to_chat(M, "We can faintly sense another of our kind trying to communicate through the hivemind...") + if(LINGHIVE_OUTSIDER) + to_chat(user, "Our senses have not evolved enough to be able to communicate this way...") + return FALSE + + +/datum/saymode/xeno + key = "a" + mode = MODE_ALIEN + +/datum/saymode/xeno/handle_message(mob/living/user, message, datum/language/language) + if(user.hivecheck()) + user.alien_talk(message) + return FALSE + + +/datum/saymode/vocalcords + key = "x" + mode = MODE_VOCALCORDS + +/datum/saymode/vocalcords/handle_message(mob/living/user, message, datum/language/language) + if(iscarbon(user)) + var/mob/living/carbon/C = user + var/obj/item/organ/vocal_cords/V = C.getorganslot(ORGAN_SLOT_VOICE) + if(V && V.can_speak_with()) + V.handle_speech(message) //message + V.speak_with(message) //action + return FALSE + + +/datum/saymode/binary //everything that uses .b (silicons, drones, blobbernauts/spores, swarmers) + key = "b" + mode = MODE_BINARY + +/datum/saymode/binary/handle_message(mob/living/user, message, datum/language/language) + if(isswarmer(user)) + var/mob/living/simple_animal/hostile/swarmer/S = user + S.swarmer_chat(message) + return FALSE + if(isblobmonster(user)) + var/mob/living/simple_animal/hostile/blob/B = user + B.blob_chat(message) + return FALSE + if(isdrone(user)) + var/mob/living/simple_animal/drone/D = user + D.drone_chat(message) + return FALSE + if(user.binarycheck()) + user.robot_talk(message) + return FALSE + return FALSE + + +/datum/saymode/holopad + key = "h" + mode = MODE_HOLOPAD + +/datum/saymode/holopad/handle_message(mob/living/user, message, datum/language/language) + if(isAI(user)) + var/mob/living/silicon/ai/AI = user + AI.holopad_talk(message, language) + return FALSE + return TRUE diff --git a/code/datums/shuttles.dm b/code/datums/shuttles.dm index 1ec392a5b2..1a0c19f5ab 100644 --- a/code/datums/shuttles.dm +++ b/code/datums/shuttles.dm @@ -94,7 +94,13 @@ admin_notes = "Due to the limited space for non paying crew, this shuttle may cause a riot." credit_cost = 10000 - +/datum/map_template/shuttle/emergency/discoinferno + suffix = "discoinferno" + name = "Disco Inferno" + description = "The glorious results of centuries of plasma research done by Nanotrasen employees. This is the reason why you are here. Get on and dance like you're on fire, burn baby burn!" + admin_notes = "Flaming hot." + credit_cost = 10000 + /datum/map_template/shuttle/emergency/arena suffix = "arena" name = "The Arena" diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm index 20d218f767..ec4b81acbe 100644 --- a/code/datums/status_effects/buffs.dm +++ b/code/datums/status_effects/buffs.dm @@ -60,8 +60,8 @@ if(istype(L)) //this is probably more safety than actually needed var/vanguard = L.stun_absorption["vanguard"] desc = initial(desc) - desc += "
[Floor(vanguard["stuns_absorbed"] * 0.1)] seconds of stuns held back.\ - [GLOB.ratvar_awakens ? "":"
[Floor(min(vanguard["stuns_absorbed"] * 0.025, 20))] seconds of stun will affect you."]" + desc += "
[FLOOR(vanguard["stuns_absorbed"] * 0.1, 1)] seconds of stuns held back.\ + [GLOB.ratvar_awakens ? "":"
[FLOOR(min(vanguard["stuns_absorbed"] * 0.025, 20), 1)] seconds of stun will affect you."]" ..() /datum/status_effect/vanguard_shield/Destroy() @@ -87,7 +87,7 @@ var/vanguard = owner.stun_absorption["vanguard"] var/stuns_blocked = 0 if(vanguard) - stuns_blocked = Floor(min(vanguard["stuns_absorbed"] * 0.25, 400)) + stuns_blocked = FLOOR(min(vanguard["stuns_absorbed"] * 0.25, 400), 1) 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..." diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index 2ea1469481..cc64cc2eb8 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -230,7 +230,7 @@ if(prob(severity * 0.15)) to_chat(owner, "\"[text2ratvar(pick(mania_messages))]\"") owner.playsound_local(get_turf(motor), hum, severity, 1) - owner.adjust_drugginess(Clamp(max(severity * 0.075, 1), 0, max(0, 50 - owner.druggy))) //7.5% of severity per second, minimum 1 + owner.adjust_drugginess(CLAMP(max(severity * 0.075, 1), 0, max(0, 50 - owner.druggy))) //7.5% of severity per second, minimum 1 if(owner.hallucination < 50) owner.hallucination = min(owner.hallucination + max(severity * 0.075, 1), 50) //7.5% of severity per second, minimum 1 if(owner.dizziness < 50) @@ -310,7 +310,7 @@ var/icon/I = icon(owner.icon, owner.icon_state, owner.dir) var/icon_height = I.Height() bleed_overlay.pixel_x = -owner.pixel_x - bleed_overlay.pixel_y = Floor(icon_height * 0.25) + bleed_overlay.pixel_y = FLOOR(icon_height * 0.25, 1) bleed_overlay.transform = matrix() * (icon_height/world.icon_size) //scale the bleed overlay's size based on the target's icon size bleed_underlay.pixel_x = -owner.pixel_x bleed_underlay.transform = matrix() * (icon_height/world.icon_size) * 3 diff --git a/code/datums/weather/weather_types/floor_is_lava.dm b/code/datums/weather/weather_types/floor_is_lava.dm index 52f82abec9..cf9fa0da86 100644 --- a/code/datums/weather/weather_types/floor_is_lava.dm +++ b/code/datums/weather/weather_types/floor_is_lava.dm @@ -20,10 +20,11 @@ overlay_layer = ABOVE_OPEN_TURF_LAYER //Covers floors only immunity_type = "lava" + /datum/weather/floor_is_lava/weather_act(mob/living/L) - for(var/obj/structure/O in L.loc) - if(O.density) + for(var/obj/structure/O in L.loc) + if(O.density || (L in O.buckled_mobs && istype(O, /obj/structure/bed))) return if(L.loc.density) return diff --git a/code/datums/wires/particle_accelerator.dm b/code/datums/wires/particle_accelerator.dm index d38147f1ec..4bf49dd814 100644 --- a/code/datums/wires/particle_accelerator.dm +++ b/code/datums/wires/particle_accelerator.dm @@ -42,4 +42,7 @@ if(WIRE_LIMIT) C.strength_upper_limit = (mend ? 2 : 3) if(C.strength_upper_limit < C.strength) - C.remove_strength() \ No newline at end of file + C.remove_strength() + +/datum/wires/particle_accelerator/control_box/emp_pulse() // to prevent singulo from pulsing wires + return \ No newline at end of file diff --git a/code/datums/wires/r_n_d.dm b/code/datums/wires/r_n_d.dm index 0308788d25..b8e78f55e0 100644 --- a/code/datums/wires/r_n_d.dm +++ b/code/datums/wires/r_n_d.dm @@ -1,8 +1,8 @@ -/datum/wires/r_n_d - holder_type = /obj/machinery/r_n_d +/datum/wires/rnd + holder_type = /obj/machinery/rnd randomize = TRUE -/datum/wires/r_n_d/New(atom/holder) +/datum/wires/rnd/New(atom/holder) wires = list( WIRE_HACK, WIRE_DISABLE, WIRE_SHOCK @@ -10,22 +10,22 @@ add_duds(5) ..() -/datum/wires/r_n_d/interactable(mob/user) - var/obj/machinery/r_n_d/R = holder +/datum/wires/rnd/interactable(mob/user) + var/obj/machinery/rnd/R = holder if(R.panel_open) return TRUE -/datum/wires/r_n_d/get_status() - var/obj/machinery/r_n_d/R = holder +/datum/wires/rnd/get_status() + var/obj/machinery/rnd/R = holder var/list/status = list() status += "The red light is [R.disabled ? "off" : "on"]." status += "The green light is [R.shocked ? "off" : "on"]." status += "The blue light is [R.hacked ? "off" : "on"]." return status -/datum/wires/r_n_d/on_pulse(wire) +/datum/wires/rnd/on_pulse(wire) set waitfor = FALSE - var/obj/machinery/r_n_d/R = holder + var/obj/machinery/rnd/R = holder switch(wire) if(WIRE_HACK) R.hacked = !R.hacked @@ -37,8 +37,8 @@ if(R) R.shocked = FALSE -/datum/wires/r_n_d/on_cut(wire, mend) - var/obj/machinery/r_n_d/R = holder +/datum/wires/rnd/on_cut(wire, mend) + var/obj/machinery/rnd/R = holder switch(wire) if(WIRE_HACK) R.hacked = !mend diff --git a/code/game/alternate_appearance.dm b/code/game/alternate_appearance.dm index 9b74020488..901a8610a6 100644 --- a/code/game/alternate_appearance.dm +++ b/code/game/alternate_appearance.dm @@ -20,7 +20,6 @@ GLOBAL_LIST_EMPTY(active_alternate_appearances) var/list/arguments = args.Copy(2) new type(arglist(arguments)) - /datum/atom_hud/alternate_appearance var/appearance_key @@ -30,10 +29,6 @@ GLOBAL_LIST_EMPTY(active_alternate_appearances) appearance_key = key /datum/atom_hud/alternate_appearance/Destroy() - for(var/v in hudusers) - remove_hud_from(v) - for(var/v in hudatoms) - remove_from_hud(v) GLOB.active_alternate_appearances -= src return ..() diff --git a/code/game/area/Space_Station_13_areas.dm b/code/game/area/Space_Station_13_areas.dm index c3296175fb..c5e3d25375 100644 --- a/code/game/area/Space_Station_13_areas.dm +++ b/code/game/area/Space_Station_13_areas.dm @@ -171,6 +171,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/maintenance/department/science/xenobiology name = "Xenobiology Maintenance" icon_state = "xenomaint" + xenobiology_compatible = TRUE //Maintenance - Generic diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 17f75fc336..28209558d7 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -61,6 +61,7 @@ var/list/cameras var/list/firealarms var/firedoors_last_closed_on = 0 + var/xenobiology_compatible = FALSE //Can the Xenobio management console transverse this area by default? /*Adding a wizard area teleport list because motherfucking lag -- Urist*/ /*I am far too lazy to make it a proper list of areas so I'll just make it run the usual telepot routine at the start of the game*/ diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 5f074e44f3..211f9dea59 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -37,7 +37,7 @@ GLOB._preloader.load(src) var/do_initialize = SSatoms.initialized - if(do_initialize > INITIALIZATION_INSSATOMS) + if(do_initialize != INITIALIZATION_INSSATOMS) args[1] = do_initialize == INITIALIZATION_INNEW_MAPLOAD if(SSatoms.InitAtom(src, args)) //we were deleted @@ -57,9 +57,7 @@ //Note: the following functions don't call the base for optimization and must copypasta: // /turf/Initialize // /turf/open/space/Initialize -// /mob/dead/new_player/Initialize -//Do also note that this proc always runs in New for /mob/dead /atom/proc/Initialize(mapload, ...) if(initialized) stack_trace("Warning: [src]([type]) initialized multiple times!") @@ -196,27 +194,22 @@ set waitfor = FALSE return -// Convenience proc to see if a container is open for chemistry handling -// returns true if open -// false if closed +// Convenience procs to see if a container is open for chemistry handling /atom/proc/is_open_container() - return container_type & OPENCONTAINER_1 - -/atom/proc/is_transparent() - return container_type & TRANSPARENT_1 + return is_refillable() && is_drainable() /atom/proc/is_injectable(allowmobs = TRUE) - if(isliving(src) && allowmobs) - var/mob/living/L = src - return L.can_inject() - if(container_type & OPENCONTAINER_1) - return TRUE - return container_type & INJECTABLE_1 + return reagents && (container_type & (INJECTABLE | REFILLABLE)) /atom/proc/is_drawable(allowmobs = TRUE) - if(is_injectable(allowmobs)) //Everything that can be injected can also be drawn from, but not vice versa - return TRUE - return container_type & DRAWABLE_1 + return reagents && (container_type & (DRAWABLE | DRAINABLE)) + +/atom/proc/is_refillable() + return reagents && (container_type & REFILLABLE) + +/atom/proc/is_drainable() + return reagents && (container_type & DRAINABLE) + /atom/proc/AllowDrop() return FALSE @@ -258,19 +251,26 @@ if(desc) to_chat(user, desc) - if(reagents && (is_open_container() || is_transparent())) //is_open_container() isn't really the right proc for this, but w/e - to_chat(user, "It contains:") - if(reagents.reagent_list.len) - if(user.can_see_reagents()) //Show each individual reagent - for(var/datum/reagent/R in reagents.reagent_list) - to_chat(user, "[R.volume] units of [R.name]") - else //Otherwise, just show the total volume - var/total_volume = 0 - for(var/datum/reagent/R in reagents.reagent_list) - total_volume += R.volume - to_chat(user, "[total_volume] units of various reagents") - else - to_chat(user, "Nothing.") + if(reagents) + if(container_type & TRANSPARENT) + to_chat(user, "It contains:") + if(reagents.reagent_list.len) + if(user.can_see_reagents()) //Show each individual reagent + for(var/datum/reagent/R in reagents.reagent_list) + to_chat(user, "[R.volume] units of [R.name]") + else //Otherwise, just show the total volume + var/total_volume = 0 + for(var/datum/reagent/R in reagents.reagent_list) + total_volume += R.volume + to_chat(user, "[total_volume] units of various reagents") + else + to_chat(user, "Nothing.") + else if(container_type & AMOUNT_VISIBLE) + if(reagents.total_volume) + to_chat(user, "It has [reagents.total_volume] unit\s left.") + else + to_chat(user, "It's empty.") + SendSignal(COMSIG_PARENT_EXAMINE, user) /atom/proc/relaymove(mob/user) @@ -421,22 +421,6 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons) /atom/proc/wash_cream() return 1 -/atom/proc/get_global_map_pos() - if(!islist(GLOB.global_map) || isemptylist(GLOB.global_map)) - return - var/cur_x = null - var/cur_y = null - var/list/y_arr = null - for(cur_x=1,cur_x<=GLOB.global_map.len,cur_x++) - y_arr = GLOB.global_map[cur_x] - cur_y = y_arr.Find(src.z) - if(cur_y) - break - if(cur_x && cur_y) - return list("x"=cur_x,"y"=cur_y) - else - return 0 - /atom/proc/isinspace() if(isspaceturf(get_turf(src))) return 1 @@ -634,4 +618,4 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons) return /atom/proc/wirecutter_act(mob/user, obj/item/tool) - return \ No newline at end of file + return diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 9d3b208acc..ddb768488a 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -26,6 +26,7 @@ appearance_flags = TILE_BOUND|PIXEL_SCALE var/datum/forced_movement/force_moving = null //handled soley by forced_movement.dm var/floating = FALSE + var/movement_type = GROUND //Incase you have multiple types, you automatically use the most useful one. IE: Skating on ice, flippers on water, flying over chasm/space, etc. /atom/movable/vv_edit_var(var_name, var_value) var/static/list/banned_edits = list("step_x", "step_y", "step_size") @@ -199,7 +200,7 @@ loc.handle_atom_del(src) for(var/atom/movable/AM in contents) qdel(AM) - loc = null + moveToNullspace() invisibility = INVISIBILITY_ABSTRACT if(pulledby) pulledby.stop_pulling() @@ -253,6 +254,12 @@ loc = destination if(!same_loc) + var/turf/oldturf = get_turf(oldloc) + var/turf/destturf = get_turf(destination) + var/old_z = (oldturf ? oldturf.z : null) + var/dest_z = (destturf ? destturf.z : null) + if (old_z != dest_z) + onTransitZ(old_z, dest_z) destination.Entered(src, oldloc) if(destarea && old_area != destarea) destarea.Entered(src, oldloc) @@ -267,30 +274,18 @@ //If no destination, move the atom into nullspace (don't do this unless you know what you're doing) else . = TRUE - var/atom/oldloc = loc - var/area/old_area = get_area(oldloc) - oldloc.Exited(src, null) - if(old_area) - old_area.Exited(src, null) + if (loc) + var/atom/oldloc = loc + var/area/old_area = get_area(oldloc) + oldloc.Exited(src, null) + if(old_area) + old_area.Exited(src, null) loc = null -/mob/living/forceMove(atom/destination) - stop_pulling() - if(buckled) - buckled.unbuckle_mob(src, force = TRUE) - if(has_buckled_mobs()) - unbuckle_all_mobs(force = TRUE) - . = ..() - if(.) - if(client) - reset_perspective(destination) - update_canmove() //if the mob was asleep inside a container and then got forceMoved out we need to make them fall. - -/mob/living/brain/forceMove(atom/destination) - if(container) - return container.forceMove(destination) - else //something went very wrong. - CRASH("Brainmob without container.") +/atom/movable/proc/onTransitZ(old_z,new_z) + for (var/item in src) // Notify contents of Z-transition. This can be overridden IF we know the items contents do not care. + var/atom/movable/AM = item + AM.onTransitZ(old_z,new_z) //Called whenever an object moves and by mobs when they attempt to move themselves through space //And when an object or action applies a force on src, see newtonian_move() below @@ -419,7 +414,7 @@ for(var/m in buckled_mobs) var/mob/living/buckled_mob = m if(!buckled_mob.Move(newloc, direct)) - loc = buckled_mob.loc + forceMove(buckled_mob.loc) last_move = buckled_mob.last_move inertia_dir = last_move buckled_mob.inertia_dir = last_move @@ -521,6 +516,7 @@ . = ..() . -= "Jump to" .["Follow"] = "?_src_=holder;[HrefToken()];adminplayerobservefollow=[REF(src)]" + .["Get"] = "?_src_=holder;[HrefToken()];admingetmovable=[REF(src)]" /atom/movable/proc/ex_check(ex_id) if(!ex_id) diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index 10ff185fd6..74ac93c023 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -50,8 +50,19 @@ hud_icons = list(ID_HUD, IMPTRACK_HUD, IMPLOYAL_HUD, IMPCHEM_HUD, WANTED_HUD) /datum/atom_hud/data/diagnostic + +/datum/atom_hud/data/diagnostic/basic hud_icons = list (DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD) +/datum/atom_hud/data/diagnostic/advanced + hud_icons = list (DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD, DIAG_PATH_HUD) + +/datum/atom_hud/data/bot_path + hud_icons = list(DIAG_PATH_HUD) + +/datum/atom_hud/abductor + hud_icons = list(GLAND_HUD) + /* MED/SEC/DIAG HUD HOOKS */ /* diff --git a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm index 2a1a196b0e..d8ba1f5fa1 100644 --- a/code/game/gamemodes/antag_spawner.dm +++ b/code/game/gamemodes/antag_spawner.dm @@ -4,7 +4,7 @@ w_class = WEIGHT_CLASS_TINY var/used = 0 -/obj/item/antag_spawner/proc/spawn_antag(client/C, turf/T, type = "") +/obj/item/antag_spawner/proc/spawn_antag(client/C, turf/T, kind = "", datum/mind/user) return /obj/item/antag_spawner/proc/equip_antag(mob/target) @@ -67,18 +67,16 @@ else to_chat(H, "Unable to reach your apprentice! You can either attack the spellbook with the contract to refund your points, or wait and try again later.") -/obj/item/antag_spawner/contract/spawn_antag(client/C, turf/T, school,datum/mind/user) +/obj/item/antag_spawner/contract/spawn_antag(client/C, turf/T, kind ,datum/mind/user) new /obj/effect/particle_effect/smoke(T) var/mob/living/carbon/human/M = new/mob/living/carbon/human(T) C.prefs.copy_to(M) M.key = C.key var/datum/mind/app_mind = M.mind - - - + var/datum/antagonist/wizard/apprentice/app = new(app_mind) app.master = user - app.school = school + app.school = kind var/datum/antagonist/wizard/master_wizard = user.has_antag_datum(/datum/antagonist/wizard) if(master_wizard) @@ -107,7 +105,7 @@ if(used) to_chat(user, "[src] is out of power!") return FALSE - if(!(user.mind in SSticker.mode.syndicates)) + if(!user.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE)) to_chat(user, "AUTHENTICATION FAILURE. ACCESS DENIED.") return FALSE if(user.z != ZLEVEL_CENTCOM) @@ -133,19 +131,19 @@ else to_chat(user, "Unable to connect to Syndicate command. Please wait and try again later or use the teleporter on your uplink to get your points refunded.") -/obj/item/antag_spawner/nuke_ops/spawn_antag(client/C, turf/T) +/obj/item/antag_spawner/nuke_ops/spawn_antag(client/C, turf/T, kind, datum/mind/user) var/mob/living/carbon/human/M = new/mob/living/carbon/human(T) C.prefs.copy_to(M) M.key = C.key - var/code = "BOMB-NOT-FOUND" - var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list - if(nuke) - code = nuke.r_code - M.mind.make_Nuke(null, code, 0, FALSE) - var/newname = M.dna.species.random_name(M.gender,0,SSticker.mode.nukeops_lastname) - M.mind.name = newname - M.real_name = newname - M.name = newname + + var/datum/antagonist/nukeop/new_op = new(M.mind) + new_op.send_to_spawnpoint = FALSE + new_op.nukeop_outfit = /datum/outfit/syndicate/no_crystals + + var/datum/antagonist/nukeop/creator_op = user.has_antag_datum(/datum/antagonist/nukeop,TRUE) + if(creator_op) + M.mind.add_antag_datum(new_op,creator_op.nuke_team) + M.mind.special_role = "Nuclear Operative" //////SYNDICATE BORG /obj/item/antag_spawner/nuke_ops/borg_tele @@ -162,8 +160,12 @@ name = "syndicate medical teleporter" borg_to_spawn = "Medical" -/obj/item/antag_spawner/nuke_ops/borg_tele/spawn_antag(client/C, turf/T) +/obj/item/antag_spawner/nuke_ops/borg_tele/spawn_antag(client/C, turf/T, kind, datum/mind/user) var/mob/living/silicon/robot/R + var/datum/antagonist/nukeop/creator_op = user.has_antag_datum(/datum/antagonist/nukeop,TRUE) + if(!creator_op) + return + switch(borg_to_spawn) if("Medical") R = new /mob/living/silicon/robot/modules/syndicate/medical(T) @@ -174,8 +176,8 @@ if(prob(50)) brainfirstname = pick(GLOB.first_names_female) var/brainopslastname = pick(GLOB.last_names) - if(SSticker.mode.nukeops_lastname) //the brain inside the syndiborg has the same last name as the other ops. - brainopslastname = SSticker.mode.nukeops_lastname + if(creator_op.nuke_team.syndicate_name) //the brain inside the syndiborg has the same last name as the other ops. + brainopslastname = creator_op.nuke_team.syndicate_name var/brainopsname = "[brainfirstname] [brainopslastname]" R.mmi.name = "Man-Machine Interface: [brainopsname]" @@ -185,7 +187,11 @@ R.real_name = R.name R.key = C.key - R.mind.make_Nuke(null, nuke_code = null,leader=0, telecrystals = TRUE) + + var/datum/antagonist/nukeop/new_borg = new(R.mind) + new_borg.send_to_spawnpoint = FALSE + R.mind.add_antag_datum(new_borg,creator_op.nuke_team) + R.mind.special_role = "Syndicate Cyborg" ///////////SLAUGHTER DEMON @@ -222,8 +228,7 @@ to_chat(user, "You can't seem to work up the nerve to shatter the bottle. Perhaps you should try again later.") -/obj/item/antag_spawner/slaughter_demon/spawn_antag(client/C, turf/T, type = "") - +/obj/item/antag_spawner/slaughter_demon/spawn_antag(client/C, turf/T, kind = "", datum/mind/user) var/obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(T) var/mob/living/simple_animal/slaughter/S = new demon_type(holder) S.holder = holder @@ -242,6 +247,7 @@ new_objective2.owner = S.mind new_objective2.explanation_text = "[objective_verb] everyone[usr ? " else while you're at it":""]." S.mind.objectives += new_objective2 + S.mind.add_antag_datum(/datum/antagonist/auto_custom) to_chat(S, S.playstyle_string) to_chat(S, "You are currently not currently in the same plane of existence as the station. \ Ctrl+Click a blood pool to manifest.") diff --git a/code/game/gamemodes/antag_team.dm b/code/game/gamemodes/antag_team.dm new file mode 100644 index 0000000000..372ee26dfa --- /dev/null +++ b/code/game/gamemodes/antag_team.dm @@ -0,0 +1,34 @@ +//A barebones antagonist team. +/datum/team + var/list/datum/mind/members = list() + var/name = "team" + var/member_name = "member" + var/list/objectives = list() //common objectives, these won't be added or removed automatically, subtypes handle this, this is here for bookkeeping purposes. + +/datum/team/New(starting_members) + . = ..() + if(starting_members) + if(islist(starting_members)) + for(var/datum/mind/M in starting_members) + add_member(M) + else + add_member(starting_members) + +/datum/team/proc/is_solo() + return members.len == 1 + +/datum/team/proc/add_member(datum/mind/new_member) + members |= new_member + +/datum/team/proc/remove_member(datum/mind/member) + members -= member + +//Display members/victory/failure/objectives for the team +/datum/team/proc/roundend_report() + var/list/report = list() + + report += "[name]:" + report += "The [member_name]s were:" + report += printplayerlist(members) + + return report.Join("
") \ No newline at end of file diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm index 5572bbd9d8..9e4bf51d41 100644 --- a/code/game/gamemodes/blob/blobs/blob_mobs.dm +++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm @@ -42,7 +42,7 @@ /mob/living/simple_animal/hostile/blob/fire_act(exposed_temperature, exposed_volume) ..() if(exposed_temperature) - adjustFireLoss(Clamp(0.01 * exposed_temperature, 1, 5)) + adjustFireLoss(CLAMP(0.01 * exposed_temperature, 1, 5)) else adjustFireLoss(5) @@ -56,13 +56,6 @@ return 1 return ..() -/mob/living/simple_animal/hostile/blob/handle_inherent_channels(message, message_mode) - if(message_mode == MODE_BINARY) - blob_chat(message) - return 1 - else - ..() - /mob/living/simple_animal/hostile/blob/proc/blob_chat(msg) var/spanned_message = say_quote(msg, get_spans()) var/rendered = "\[Blob Telepathy\] [real_name] [spanned_message]" diff --git a/code/game/gamemodes/blob/overmind.dm b/code/game/gamemodes/blob/overmind.dm index 4f26563da1..878b747ea9 100644 --- a/code/game/gamemodes/blob/overmind.dm +++ b/code/game/gamemodes/blob/overmind.dm @@ -153,7 +153,7 @@ GLOBAL_LIST_EMPTY(blob_nodes) B.hud_used.blobpwrdisplay.maptext = "
[round(blob_core.obj_integrity)]
" /mob/camera/blob/proc/add_points(points) - blob_points = Clamp(blob_points + points, 0, max_blob_points) + blob_points = CLAMP(blob_points + points, 0, max_blob_points) hud_used.blobpwrdisplay.maptext = "
[round(blob_points)]
" /mob/camera/blob/say(message) @@ -215,12 +215,12 @@ GLOBAL_LIST_EMPTY(blob_nodes) if(placed) var/obj/structure/blob/B = locate() in range("3x3", NewLoc) if(B) - loc = NewLoc + forceMove(NewLoc) else return 0 else var/area/A = get_area(NewLoc) if(isspaceturf(NewLoc) || istype(A, /area/shuttle)) //if unplaced, can't go on shuttles or space tiles return 0 - loc = NewLoc + forceMove(NewLoc) return 1 diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm index aa1a3e7046..2ef047506f 100644 --- a/code/game/gamemodes/blob/powers.dm +++ b/code/game/gamemodes/blob/powers.dm @@ -42,7 +42,7 @@ return 0 else if(placement_override == 1) var/turf/T = pick(GLOB.blobstart) - loc = T //got overrided? you're somewhere random, motherfucker + forceMove(T) //got overrided? you're somewhere random, motherfucker if(placed && blob_core) blob_core.forceMove(loc) else @@ -74,7 +74,7 @@ var/node_name = input(src, "Choose a node to jump to.", "Node Jump") in nodes var/obj/structure/blob/node/chosen_node = nodes[node_name] if(chosen_node) - loc = chosen_node.loc + forceMove(chosen_node.loc) /mob/camera/blob/proc/createSpecial(price, blobType, nearEquals, needsNode, turf/T) if(!T) diff --git a/code/game/gamemodes/brother/traitor_bro.dm b/code/game/gamemodes/brother/traitor_bro.dm index c1af1601ce..609f5bb6ab 100644 --- a/code/game/gamemodes/brother/traitor_bro.dm +++ b/code/game/gamemodes/brother/traitor_bro.dm @@ -1,44 +1,6 @@ -/datum/objective_team/brother_team - name = "brotherhood" - member_name = "blood brother" - var/list/objectives = list() - var/meeting_area - -/datum/objective_team/brother_team/is_solo() - return FALSE - -/datum/objective_team/brother_team/proc/add_objective(datum/objective/O, needs_target = FALSE) - O.team = src - if(needs_target) - O.find_target() - O.update_explanation_text() - objectives += O - -/datum/objective_team/brother_team/proc/forge_brother_objectives() - objectives = list() - var/is_hijacker = prob(10) - 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) - add_objective(new/datum/objective/hijack) - else if(!locate(/datum/objective/escape) in objectives) - add_objective(new/datum/objective/escape) - -/datum/objective_team/brother_team/proc/forge_single_objective() - if(prob(50)) - if(LAZYLEN(active_ais()) && prob(100/GLOB.joined_player_list.len)) - add_objective(new/datum/objective/destroy, TRUE) - else if(prob(30)) - add_objective(new/datum/objective/maroon, TRUE) - else - add_objective(new/datum/objective/assassinate, TRUE) - else - add_objective(new/datum/objective/steal, TRUE) - /datum/game_mode var/list/datum/mind/brothers = list() - var/list/datum/objective_team/brother_team/brother_teams = list() + var/list/datum/team/brother_team/brother_teams = list() /datum/game_mode/traitor/bros name = "traitor+brothers" @@ -51,9 +13,10 @@ Blood Brothers: Accomplish your objectives.\n\ Crew: Do not let the traitors or brothers succeed!" - var/list/datum/objective_team/brother_team/pre_brother_teams = list() + var/list/datum/team/brother_team/pre_brother_teams = list() var/const/team_amount = 2 //hard limit on brother teams if scaling is turned off var/const/min_team_size = 2 + traitors_required = FALSE //Only teams are possible var/meeting_areas = list("The Bar", "Dorms", "Escape Dock", "Arrivals", "Holodeck", "Primary Tool Storage", "Recreation Area", "Chapel", "Library") @@ -73,7 +36,7 @@ for(var/j = 1 to num_teams) if(possible_brothers.len < min_team_size || antag_candidates.len <= required_enemies) break - var/datum/objective_team/brother_team/team = new + var/datum/team/brother_team/team = new var/team_size = prob(10) ? min(3, possible_brothers.len) : 2 for(var/k = 1 to team_size) var/datum/mind/bro = pick(possible_brothers) @@ -86,50 +49,19 @@ return ..() /datum/game_mode/traitor/bros/post_setup() - for(var/datum/objective_team/brother_team/team in pre_brother_teams) + for(var/datum/team/brother_team/team in pre_brother_teams) team.meeting_area = pick(meeting_areas) meeting_areas -= team.meeting_area team.forge_brother_objectives() for(var/datum/mind/M in team.members) M.add_antag_datum(ANTAG_DATUM_BROTHER, team) + team.update_name() brother_teams += pre_brother_teams return ..() /datum/game_mode/traitor/bros/generate_report() return "It's Syndicate recruiting season. Be alert for potential Syndicate infiltrators, but also watch out for disgruntled employees trying to defect. Unlike Nanotrasen, the Syndicate prides itself in teamwork and will only recruit pairs that share a brotherly trust." -/datum/game_mode/proc/auto_declare_completion_brother() - if(!LAZYLEN(brother_teams)) - return - var/text = "
The blood brothers were:" - var/teamnumber = 1 - for(var/datum/objective_team/brother_team/team in brother_teams) - if(!team.members.len) - continue - text += "
Team #[teamnumber++]" - for(var/datum/mind/M in team.members) - text += printplayer(M) - var/win = TRUE - var/objective_count = 1 - for(var/datum/objective/objective in team.objectives) - if(objective.check_completion()) - text += "
Objective #[objective_count]: [objective.explanation_text] Success! [istype(objective, /datum/objective/crew) ? "(Optional)" : ""]" - SSblackbox.record_feedback("nested tally", "traitor_objective", 1, list("[objective.type]", "SUCCESS")) - else - text += "
Objective #[objective_count]: [objective.explanation_text] Fail. [istype(objective, /datum/objective/crew) ? "(Optional)" : ""]" - SSblackbox.record_feedback("nested tally", "traitor_objective", 1, list("[objective.type]", "FAIL")) - if(!(istype(objective, /datum/objective/crew))) - win = FALSE - objective_count++ - if(win) - text += "
The blood brothers were successful!" - SSblackbox.record_feedback("tally", "brother_success", 1, "SUCCESS") - else - text += "
The blood brothers have failed!" - SSblackbox.record_feedback("tally", "brother_success", 1, "FAIL") - text += "
" - to_chat(world, text) - /datum/game_mode/proc/update_brother_icons_added(datum/mind/brother_mind) var/datum/atom_hud/antag/brotherhud = GLOB.huds[ANTAG_HUD_BROTHER] brotherhud.join_hud(brother_mind.current) diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index a70f392d4f..ad76d41d47 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -94,47 +94,6 @@ GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our th of the Thing being sent to a station in this sector is highly likely. It may be in the guise of any crew member. Trust nobody - suspect everybody. Do not announce this to the crew, \ as paranoia may spread and inhibit workplace efficiency." -/datum/game_mode/proc/auto_declare_completion_changeling() - var/list/changelings = get_antagonists(/datum/antagonist/changeling,TRUE) //Only real lings get a mention - if(changelings.len) - var/text = "
The changelings were:" - for(var/datum/mind/changeling in changelings) - var/datum/antagonist/changeling/ling = changeling.has_antag_datum(/datum/antagonist/changeling) - var/changelingwin = 1 - if(!changeling.current) - changelingwin = 0 - - text += printplayer(changeling) - - //Removed sanity if(changeling) because we -want- a runtime to inform us that the changelings list is incorrect and needs to be fixed. - text += "
Changeling ID: [ling.changelingID]." - text += "
Genomes Extracted: [ling.absorbedcount]" - - if(changeling.objectives.len) - var/count = 1 - for(var/datum/objective/objective in changeling.objectives) - if(objective.check_completion()) - text += "
Objective #[count]: [objective.explanation_text] Success! [istype(objective, /datum/objective/crew) ? "(Optional)" : ""]" - SSblackbox.record_feedback("nested tally", "changeling_objective", 1, list("[objective.type]", "SUCCESS")) - else - text += "
Objective #[count]: [objective.explanation_text] Fail. [istype(objective, /datum/objective/crew) ? "(Optional)" : ""]" - SSblackbox.record_feedback("nested tally", "changeling_objective", 1, list("[objective.type]", "FAIL")) - if(!(istype(objective, /datum/objective/crew))) - changelingwin = 0 - count++ - - if(changelingwin) - text += "
The changeling was successful!" - SSblackbox.record_feedback("tally", "changeling_success", 1, "SUCCESS") - else - text += "
The changeling has failed." - SSblackbox.record_feedback("tally", "changeling_success", 1, "FAIL") - text += "
" - - to_chat(world, text) - - return 1 - /proc/changeling_transform(mob/living/carbon/human/user, datum/changelingprofile/chosen_prof) var/datum/dna/chosen_dna = chosen_prof.dna user.real_name = chosen_prof.name diff --git a/code/game/gamemodes/changeling/powers/absorb.dm b/code/game/gamemodes/changeling/powers/absorb.dm index 4584dc5a67..56003d91eb 100644 --- a/code/game/gamemodes/changeling/powers/absorb.dm +++ b/code/game/gamemodes/changeling/powers/absorb.dm @@ -58,6 +58,8 @@ user.nutrition = min((user.nutrition + target.nutrition), NUTRITION_LEVEL_WELL_FED) if(target.mind)//if the victim has got a mind + // Absorb a lizard, speak Draconic. + user.copy_known_languages_from(target) target.mind.show_memory(user, 0) //I can read your mind, kekeke. Output all their notes. diff --git a/code/game/gamemodes/changeling/powers/linglink.dm b/code/game/gamemodes/changeling/powers/linglink.dm index d6ceb4edd0..cd7c944137 100644 --- a/code/game/gamemodes/changeling/powers/linglink.dm +++ b/code/game/gamemodes/changeling/powers/linglink.dm @@ -50,7 +50,7 @@ to_chat(target, "A migraine throbs behind your eyes, you hear yourself screaming - but your mouth has not opened!") for(var/mi in GLOB.mob_list) var/mob/M = mi - if(M.lingcheck() == 2) + if(M.lingcheck() == LINGHIVE_LING) to_chat(M, "We can sense a foreign presence in the hivemind...") target.mind.linglink = 1 target.say(":g AAAAARRRRGGGGGHHHHH!!") diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm index 63900d0f89..e4f75ea563 100644 --- a/code/game/gamemodes/clock_cult/clock_cult.dm +++ b/code/game/gamemodes/clock_cult/clock_cult.dm @@ -44,10 +44,10 @@ Credit where due: // PROCS // /////////// -/proc/is_servant_of_ratvar(mob/living/M) +/proc/is_servant_of_ratvar(mob/M) return istype(M) && M.mind && M.mind.has_antag_datum(ANTAG_DATUM_CLOCKCULT) -/proc/is_eligible_servant(mob/living/M) +/proc/is_eligible_servant(mob/M) if(!istype(M)) return FALSE if(M.mind) @@ -61,19 +61,22 @@ Credit where due: return FALSE if(iscultist(M) || isconstruct(M) || M.isloyal() || ispAI(M)) return FALSE - if(ishuman(M) || isbrain(M) || isguardian(M) || issilicon(M) || isclockmob(M) || istype(M, /mob/living/simple_animal/drone/cogscarab)) + if(ishuman(M) || isbrain(M) || isguardian(M) || issilicon(M) || isclockmob(M) || istype(M, /mob/living/simple_animal/drone/cogscarab) || istype(M, /mob/camera/eminence)) return TRUE return FALSE -/proc/add_servant_of_ratvar(mob/living/L, silent = FALSE) +/proc/add_servant_of_ratvar(mob/L, silent = FALSE, create_team = TRUE) if(!L || !L.mind) return var/update_type = ANTAG_DATUM_CLOCKCULT if(silent) update_type = ANTAG_DATUM_CLOCKCULT_SILENT - . = L.mind.add_antag_datum(update_type) + var/datum/antagonist/clockcult/C = new update_type(L.mind) + C.make_team = create_team + C.show_in_roundend = create_team //tutorial scarabs begone + . = L.mind.add_antag_datum(C) -/proc/remove_servant_of_ratvar(mob/living/L, silent = FALSE) +/proc/remove_servant_of_ratvar(mob/L, silent = FALSE) if(!L || !L.mind) return var/datum/antagonist/clockcult/clock_datum = L.mind.has_antag_datum(ANTAG_DATUM_CLOCKCULT) @@ -110,6 +113,8 @@ Credit where due: var/roundstart_player_count var/ark_time //In minutes, how long the Ark waits before activation; this is equal to 30 + (number of players / 5) (max 40 mins.) + var/datum/team/clockcult/main_clockcult + /datum/game_mode/clockwork_cult/pre_setup() if(CONFIG_GET(flag/protect_roles_from_antagonist)) restricted_jobs += protected_jobs @@ -176,7 +181,7 @@ Credit where due: if(!S.forceMove(get_turf(L))) qdel(S) if(S && !QDELETED(S)) - to_chat(L, "There is a paper in your backpack! Read it!") + to_chat(L, "There is a paper in your backpack! It'll tell you if anything's changed, as well as what to expect.") to_chat(L, "[slot] is a clockwork slab, a multipurpose tool used to construct machines and invoke ancient words of power. If this is your first time \ as a servant, you can find a concise tutorial in the Recollection category of its interface.") to_chat(L, "If you want more information, you can find a wiki link here! https://tgstation13.org/wiki/Clockwork_Cult") @@ -184,51 +189,29 @@ Credit where due: return FALSE /datum/game_mode/clockwork_cult/check_finished() - var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar - if(G && !GLOB.ratvar_awakens) // Doesn't end until the Ark is destroyed or completed + if(GLOB.ark_of_the_clockwork_justiciar && !GLOB.ratvar_awakens) // Doesn't end until the Ark is destroyed or completed return FALSE - . = ..() + return ..() /datum/game_mode/clockwork_cult/proc/check_clockwork_victory() + return main_clockcult.check_clockwork_victory() + +/datum/game_mode/clock_cult/set_round_result() + ..() if(GLOB.clockwork_gateway_activated) SSticker.news_report = CLOCK_SUMMON - return TRUE + SSticker.mode_result = "win - servants completed their objective (summon ratvar)" else SSticker.news_report = CULT_FAILURE - return FALSE - -/datum/game_mode/clockwork_cult/declare_completion() - ..() - return //Doesn't end until the round does + SSticker.mode_result = "loss - servants failed their objective (summon ratvar)" /datum/game_mode/clockwork_cult/generate_report() - return "We have lost contact with multiple stations in your sector. They have gone dark and do not respond to all transmissions, although they appear intact and the crew's life \ - signs remain uninterrupted. Those that have managed to send a transmission or have had some of their crew escape tell tales of a machine cult creating sapient automatons and seeking \ - to brainwash the crew to summon their god, Ratvar. If evidence of this cult is dicovered aboard your station, extreme caution and extreme vigilance must be taken going forward, and \ - all resources should be devoted to stopping this cult. Note that holy water seems to weaken and eventually return the minds of cultists that ingest it, and mindshield implants will \ - prevent conversion altogether." - -/datum/game_mode/proc/auto_declare_completion_clockwork_cult() - var/text = "" - if(istype(SSticker.mode, /datum/game_mode/clockwork_cult)) //Possibly hacky? - var/datum/game_mode/clockwork_cult/C = SSticker.mode - if(C.check_clockwork_victory()) - text += "Ratvar's servants defended the Ark until its activation!" - SSticker.mode_result = "win - servants completed their objective (summon ratvar)" - else - text += "The Ark was destroyed! Ratvar will rust away for all eternity!" - SSticker.mode_result = "loss - servants failed their objective (summon ratvar)" - text += "
The servants' objective was: [CLOCKCULT_OBJECTIVE]." - text += "
Ratvar's servants had [GLOB.clockwork_caches] Tinkerer's Caches." - text += "
Construction Value(CV) was: [GLOB.clockwork_construction_value]" - for(var/i in SSticker.scripture_states) - if(i != SCRIPTURE_DRIVER) - text += "
[i] scripture was: [SSticker.scripture_states[i] ? "UN":""]LOCKED" - if(servants_of_ratvar.len) - text += "
Ratvar's servants were:" - for(var/datum/mind/M in servants_of_ratvar) - text += printplayer(M) - to_chat(world, text) + return "Bluespace monitors near your sector have detected a continuous stream of patterned fluctuations since the station was completed. It is most probable that a powerful entity \ + from a very far distance away is using to the station as a vector to cross that distance through bluespace. The theoretical power required for this would be monumental, and if \ + the entity is hostile, it would need to rely on a single central power source - disrupting or destroying that power source would be the best way to prevent said entity from causing \ + harm to company personnel or property.

Keep a sharp on any crew that appear to be oddly-dressed or using what appear to be magical powers, as these crew may be defectors \ + working for this entity and utilizing highly-advanced technology to cross the great distance at will. If they should turn out to be a credible threat, the task falls on you and \ + your crew to dispatch it in a timely manner." /datum/game_mode/proc/update_servant_icons_added(datum/mind/M) var/datum/atom_hud/antag/A = GLOB.huds[ANTAG_HUD_CLOCKWORK] @@ -246,14 +229,14 @@ Credit where due: /datum/outfit/servant_of_ratvar name = "Servant of Ratvar" uniform = /obj/item/clothing/under/chameleon/ratvar - shoes = /obj/item/clothing/shoes/workboots + shoes = /obj/item/clothing/shoes/sneakers/black back = /obj/item/storage/backpack ears = /obj/item/device/radio/headset gloves = /obj/item/clothing/gloves/color/yellow belt = /obj/item/storage/belt/utility/servant backpack_contents = list(/obj/item/storage/box/engineer = 1, \ /obj/item/clockwork/replica_fabricator = 1, /obj/item/stack/tile/brass/fifty = 1, /obj/item/paper/servant_primer = 1) - id = /obj/item/card/id + id = /obj/item/device/pda var/plasmaman //We use this to determine if we should activate internals in post_equip() /datum/outfit/servant_of_ratvar/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE) @@ -265,7 +248,8 @@ Credit where due: plasmaman = TRUE /datum/outfit/servant_of_ratvar/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - var/obj/item/card/id/W = H.wear_id + var/obj/item/card/id/W = new(H) + var/obj/item/device/pda/PDA = H.wear_id W.assignment = "Assistant" W.access += ACCESS_MAINT_TUNNELS W.registered_name = H.real_name @@ -273,8 +257,15 @@ Credit where due: if(plasmaman && !visualsOnly) //If we need to breathe from the plasma tank, we should probably start doing that H.internal = H.get_item_for_held_index(2) H.update_internals_hud_icon(1) + PDA.owner = H.real_name + PDA.ownjob = "Assistant" + PDA.update_label() + PDA.id_check(H, W) H.sec_hud_set_ID() + +//This paper serves as a quick run-down to the cult as well as a changelog to refer to. +//Check strings/clockwork_cult_changelog.txt for the changelog, and update it when you can! /obj/item/paper/servant_primer name = "The Ark And You: A Primer On Servitude" color = "#DAAA18" @@ -304,14 +295,19 @@ Credit where due:
\

Things that have changed:

\
    \ -
  • Scripture no longer requires components, and instead uses power.
  • \ -
  • Added a 5-minute grace period for the crew to prepare for the assault when the Ark activates.
  • \ -
  • Script and Application scriptures can now be unlocked with enough power.
  • \ -
  • Added the Hateful Manacles scripture, which handcuffs targets!
  • \ + CLOCKCULTCHANGELOG\
\
\ Good luck!" +/obj/item/paper/servant_primer/Initialize() + . = ..() + var/changelog = world.file2list("strings/clockwork_cult_changelog.txt") + var/changelog_contents = "" + for(var/entry in changelog) + changelog_contents += "
  • [entry]
  • " + info = replacetext(info, "CLOCKCULTCHANGELOG", changelog_contents) + /obj/item/paper/servant_primer/examine(mob/user) if(!is_servant_of_ratvar(user) && !isobserver(user)) to_chat(user, "You can't understand any of the words on [src].") diff --git a/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm b/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm index 3091d6071a..29655a0ac9 100644 --- a/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm +++ b/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm @@ -207,7 +207,7 @@ to_chat(cyborg, "You start to charge from the [sigil_name]...") if(!do_after(cyborg, 50, target = src, extra_checks = CALLBACK(src, .proc/cyborg_checks, cyborg, TRUE))) return - var/giving_power = min(Floor(cyborg.cell.maxcharge - cyborg.cell.charge, MIN_CLOCKCULT_POWER), get_clockwork_power()) //give the borg either all our power or their missing power floored to MIN_CLOCKCULT_POWER + var/giving_power = min(FLOOR(cyborg.cell.maxcharge - cyborg.cell.charge, MIN_CLOCKCULT_POWER), get_clockwork_power()) //give the borg either all our power or their missing power floored to MIN_CLOCKCULT_POWER if(adjust_clockwork_power(-giving_power)) cyborg.visible_message("[cyborg] glows a brilliant orange!") var/previous_color = cyborg.color @@ -275,7 +275,6 @@ /obj/effect/clockwork/sigil/vitality/sigil_effects(mob/living/L) if((is_servant_of_ratvar(L) && L.suiciding) || sigil_active) return - visible_message("[src] begins to glow bright blue!") animate(src, alpha = 255, time = 10, flags = ANIMATION_END_NOW) //we may have a previous animation going. finish it first, then do this one without delay. sleep(10) //as long as they're still on the sigil and are either not a servant or they're a servant AND it has remaining vitality @@ -310,7 +309,7 @@ else if(L.stat == DEAD) var/revival_cost = revive_cost - if(GLOB.ratvar_awakens) + if(GLOB.ratvar_awakens || L.suiciding) // No cost if Ratvar is summoned or if you're reviving a convert who suicided revival_cost = 0 var/mob/dead/observer/ghost = L.get_ghost(TRUE) if(GLOB.clockwork_vitality >= revival_cost && (ghost || (L.mind && L.mind.active))) @@ -323,6 +322,20 @@ L.visible_message("[L] suddenly gets back up, [L.p_their()] body dripping blue ichor!", "\"[text2ratvar("You will be okay, child.")]\"") GLOB.clockwork_vitality -= revival_cost break + if(!L.client || L.client.is_afk()) + set waitfor = FALSE + var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a [L.name], an inactive clock cultist?", "[name]", null, "Clock Cultist", 50, L) + var/mob/dead/observer/theghost = null + if(candidates.len) + to_chat(L, "Your physical form has been taken over by another soul due to your inactivity! Ahelp if you wish to regain your form!") + message_admins("[key_name_admin(theghost)] has taken control of ([key_name_admin(L)]) to replace an inactive clock cultist.") + L.ghostize(0) + L.key = theghost.key + var/obj/effect/temp_visual/ratvar/sigil/vitality/V = new /obj/effect/temp_visual/ratvar/sigil/vitality(get_turf(src)) + animate(V, alpha = 0, transform = matrix()*2, time = 8) + playsound(L, 'sound/magic/staff_healing.ogg', 50, 1) + L.visible_message("[L]'s eyes suddenly open wide, gleaming with renewed vigor for the cause!", "\"[text2ratvar("Awaken!")]\"") + break var/vitality_for_cycle = 3 if(!GLOB.ratvar_awakens) if(L.stat == CONSCIOUS) @@ -341,5 +354,4 @@ if(sigil_active) animation_number = initial(animation_number) sigil_active = FALSE - visible_message("[src] slowly stops glowing!") animate(src, alpha = initial(alpha), time = 10, flags = ANIMATION_END_NOW) diff --git a/code/game/gamemodes/clock_cult/clock_helpers/fabrication_helpers.dm b/code/game/gamemodes/clock_cult/clock_helpers/fabrication_helpers.dm index a5af47ff05..74f7119193 100644 --- a/code/game/gamemodes/clock_cult/clock_helpers/fabrication_helpers.dm +++ b/code/game/gamemodes/clock_cult/clock_helpers/fabrication_helpers.dm @@ -90,7 +90,7 @@ if(amount_temp < 2) to_chat(user, "You need at least 2 floor tiles to convert into power.") return TRUE - if(IsOdd(amount_temp)) + if(ISODD(amount_temp)) amount_temp-- no_delete = TRUE use(amount_temp) @@ -239,7 +239,7 @@ if(!do_after(user, repair_values["healing_for_cycle"] * fabricator.speed_multiplier, target = src, \ extra_checks = CALLBACK(fabricator, /obj/item/clockwork/replica_fabricator.proc/fabricator_repair_checks, repair_values, src, user, TRUE))) break - obj_integrity = Clamp(obj_integrity + repair_values["healing_for_cycle"], 0, max_integrity) + obj_integrity = CLAMP(obj_integrity + repair_values["healing_for_cycle"], 0, max_integrity) adjust_clockwork_power(-repair_values["power_required"]) playsound(src, 'sound/machines/click.ogg', 50, 1) diff --git a/code/game/gamemodes/clock_cult/clock_helpers/power_helpers.dm b/code/game/gamemodes/clock_cult/clock_helpers/power_helpers.dm index 1935eb3e0b..c2479460c7 100644 --- a/code/game/gamemodes/clock_cult/clock_helpers/power_helpers.dm +++ b/code/game/gamemodes/clock_cult/clock_helpers/power_helpers.dm @@ -10,12 +10,15 @@ for(var/obj/effect/clockwork/sigil/transmission/T in GLOB.all_clockwork_objects) T.update_icon() var/power_overwhelming = GLOB.clockwork_power + var/unlock_message if(power_overwhelming >= SCRIPT_UNLOCK_THRESHOLD && !GLOB.script_scripture_unlocked) GLOB.script_scripture_unlocked = TRUE - hierophant_message("The Ark swells as a key power threshold is reached. Script scriptures are now available.") + unlock_message = "The Ark swells as a key power threshold is reached. Script scriptures are now available." if(power_overwhelming >= APPLICATION_UNLOCK_THRESHOLD && !GLOB.application_scripture_unlocked) GLOB.application_scripture_unlocked = TRUE - hierophant_message("The Ark surges as a key power threshold is reached. Application scriptures are now available.") + unlock_message = "The Ark surges as a key power threshold is reached. Application scriptures are now available." + if(GLOB.servants_active) + hierophant_message(unlock_message) return TRUE /proc/can_access_clockwork_power(atom/movable/access_point, amount) //Returns true if the access point has access to clockwork power (and optionally, a number of watts for it) diff --git a/code/game/gamemodes/clock_cult/clock_helpers/scripture_checks.dm b/code/game/gamemodes/clock_cult/clock_helpers/scripture_checks.dm index c6f3f0f7f3..bfa27cefdb 100644 --- a/code/game/gamemodes/clock_cult/clock_helpers/scripture_checks.dm +++ b/code/game/gamemodes/clock_cult/clock_helpers/scripture_checks.dm @@ -11,6 +11,8 @@ //reports to servants when scripture is locked or unlocked /proc/scripture_unlock_alert(list/previous_states) + if(!GLOB.servants_active) + return . = scripture_unlock_check() for(var/i in .) if(.[i] != previous_states[i]) @@ -43,7 +45,9 @@ //changes construction value /proc/change_construction_value(amount) - GLOB.clockwork_construction_value += amount + if(!SSticker.current_state != GAME_STATE_PLAYING) //This is primarily so that structures added pre-roundstart don't contribute to construction value + return + GLOB.clockwork_construction_value = max(0, GLOB.clockwork_construction_value + amount) /proc/can_recite_scripture(mob/living/L, can_potentially) return (is_servant_of_ratvar(L) && (can_potentially || (L.stat == CONSCIOUS && L.can_speak_vocal())) && (GLOB.ratvar_awakens || (ishuman(L) || issilicon(L)))) diff --git a/code/game/gamemodes/clock_cult/clock_helpers/slab_abilities.dm b/code/game/gamemodes/clock_cult/clock_helpers/slab_abilities.dm index 4ca8f7f35b..3cef31a706 100644 --- a/code/game/gamemodes/clock_cult/clock_helpers/slab_abilities.dm +++ b/code/game/gamemodes/clock_cult/clock_helpers/slab_abilities.dm @@ -65,8 +65,8 @@ /obj/item/restraints/handcuffs/clockwork name = "replicant manacles" - desc = "Cold, heavy manacles made out of some strange black metal." - origin_tech = "materials=2;magnets=5" + desc = "Heavy manacles made out of freezing-cold metal. It looks like brass, but feels much more solid." + icon_state = "brass_manacles" flags_1 = DROPDEL_1 /obj/item/restraints/handcuffs/clockwork/dropped(mob/user) diff --git a/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm b/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm index 70aeaa6520..0111567122 100644 --- a/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm +++ b/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm @@ -1,23 +1,31 @@ /obj/item/clockwork/slab //Clockwork slab: The most important tool in Ratvar's arsenal. Allows scripture recital, tutorials, and generates components. name = "clockwork slab" desc = "A strange metal tablet. A clock in the center turns around and around." - clockwork_desc = "A link between you and the Celestial Derelict. It contains information, recites scripture, and is your most vital tool as a Servant." + clockwork_desc = "A link between you and the Celestial Derelict. It contains information, recites scripture, and is your most vital tool as a Servant.
    \ + It can be used to link traps and triggers by attacking them with the slab. Keep in mind that traps linked with one another will activate in tandem!" + icon_state = "dread_ipad" lefthand_file = 'icons/mob/inhands/antag/clockwork_lefthand.dmi' righthand_file = 'icons/mob/inhands/antag/clockwork_righthand.dmi' var/inhand_overlay //If applicable, this overlay will be applied to the slab's inhand + slot_flags = SLOT_BELT w_class = WEIGHT_CLASS_SMALL + var/busy //If the slab is currently being used by something var/no_cost = FALSE //If the slab is admin-only and needs no components and has no scripture locks var/speed_multiplier = 1 //multiples how fast this slab recites scripture var/selected_scripture = SCRIPTURE_DRIVER - var/recollecting = FALSE //if we're looking at fancy recollection var/obj/effect/proc_holder/slab/slab_ability //the slab's current bound ability, for certain scripture + + var/recollecting = FALSE //if we're looking at fancy recollection + var/recollection_category = "Default" + var/list/quickbound = list(/datum/clockwork_scripture/abscond, \ /datum/clockwork_scripture/ranged_ability/kindle, /datum/clockwork_scripture/ranged_ability/hateful_manacles) //quickbound scripture, accessed by index var/maximum_quickbound = 5 //how many quickbound scriptures we can have - var/recollection_category = "Default" + + var/obj/structure/destructible/clockwork/trap/linking //If we're linking traps together, which ones we're doing /obj/item/clockwork/slab/internal //an internal motor for mobs running scripture name = "scripture motor" @@ -34,8 +42,7 @@ add_servant_of_ratvar(user) /obj/item/clockwork/slab/cyborg //three scriptures, plus a spear and fabricator - clockwork_desc = "A divine link to the Celestial Derelict, allowing for limited recital of scripture.\n\ - Hitting a slab, a Servant with a slab, or a cache will transfer this slab's components into the target, the target's slab, or the global cache, respectively." + clockwork_desc = "A divine link to the Celestial Derelict, allowing for limited recital of scripture." quickbound = list(/datum/clockwork_scripture/ranged_ability/judicial_marker, /datum/clockwork_scripture/ranged_ability/linked_vanguard, \ /datum/clockwork_scripture/create_object/stargazer) maximum_quickbound = 6 //we usually have one or two unique scriptures, so if ratvar is up let us bind one more @@ -46,7 +53,7 @@ /obj/item/clockwork/slab/cyborg/medical //five scriptures, plus a spear quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/ranged_ability/linked_vanguard, /datum/clockwork_scripture/ranged_ability/sentinels_compromise, \ - /datum/clockwork_scripture/create_object/vitality_matrix, /datum/clockwork_scripture/channeled/mending_mantra) + /datum/clockwork_scripture/create_object/vitality_matrix) /obj/item/clockwork/slab/cyborg/security //twoscriptures, plus a spear quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/ranged_ability/hateful_manacles, /datum/clockwork_scripture/ranged_ability/judicial_marker) @@ -153,6 +160,11 @@ return 0 access_display(user) +/obj/item/clockwork/slab/AltClick(mob/living/user) + if(is_servant_of_ratvar(user) && linking) + linking = null + to_chat(user, "Object link canceled.") + /obj/item/clockwork/slab/proc/access_display(mob/living/user) if(!is_servant_of_ratvar(user)) return FALSE @@ -410,7 +422,10 @@ data["tier_info"] = "Unlock these optional scriptures by converting another servant or if [DisplayPower(APPLICATION_UNLOCK_THRESHOLD)] of power is reached.." data["selected"] = selected_scripture - + data["scripturecolors"] = "Scriptures in yellow are related to construction and building.
    \ + Scriptures in red are related to attacking and offense.
    \ + Scriptures in blue are related to healing and defense.
    \ + Scriptures in purple are niche but still important!" generate_all_scripture() data["scripture"] = list() diff --git a/code/game/gamemodes/clock_cult/clock_items/construct_chassis.dm b/code/game/gamemodes/clock_cult/clock_items/construct_chassis.dm index acf6e43974..1b2b867aa5 100644 --- a/code/game/gamemodes/clock_cult/clock_items/construct_chassis.dm +++ b/code/game/gamemodes/clock_cult/clock_items/construct_chassis.dm @@ -91,7 +91,8 @@ /obj/item/clockwork/construct_chassis/cogscarab/pre_spawn() if(infinite_resources) - construct_type = /mob/living/simple_animal/drone/cogscarab/ratvar //During rounds where they can't interact with the station, let them experiment with builds + //During rounds where they can't interact with the station, let them experiment with builds + construct_type = /mob/living/simple_animal/drone/cogscarab/ratvar /obj/item/clockwork/construct_chassis/cogscarab/post_spawn(mob/living/construct) if(infinite_resources) //Allow them to build stuff and recite scripture diff --git a/code/game/gamemodes/clock_cult/clock_items/judicial_visor.dm b/code/game/gamemodes/clock_cult/clock_items/judicial_visor.dm index 4f6485310b..d6b2ddce0d 100644 --- a/code/game/gamemodes/clock_cult/clock_items/judicial_visor.dm +++ b/code/game/gamemodes/clock_cult/clock_items/judicial_visor.dm @@ -184,7 +184,7 @@ sleep(13) name = "judicial explosion" var/targetsjudged = 0 - playsound(src, 'sound/effects/explosionfar.ogg', 100, 1, 1, 1) + playsound(src, 'sound/effects/explosion_distant.ogg', 100, 1, 1, 1) set_light(0) for(var/mob/living/L in range(1, src)) if(is_servant_of_ratvar(L)) diff --git a/code/game/gamemodes/clock_cult/clock_mobs/_eminence.dm b/code/game/gamemodes/clock_cult/clock_mobs/_eminence.dm new file mode 100644 index 0000000000..8416e4651d --- /dev/null +++ b/code/game/gamemodes/clock_cult/clock_mobs/_eminence.dm @@ -0,0 +1,262 @@ +//The Eminence is a unique mob that functions like the leader of the cult. It's incorporeal but can interact with the world in several ways. +/mob/camera/eminence + name = "\the Emininence" + real_name = "\the Eminence" + desc = "The leader-elect of the servants of Ratvar." + icon = 'icons/effects/clockwork_effects.dmi' + icon_state = "eminence" + mouse_opacity = MOUSE_OPACITY_OPAQUE + move_on_shuttle = TRUE + see_in_dark = 8 + invisibility = INVISIBILITY_OBSERVER + layer = FLY_LAYER + faction = list("ratvar") + lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + var/static/superheated_walls = 0 + +/mob/camera/eminence/CanPass(atom/movable/mover, turf/target) + return TRUE + +/mob/camera/eminence/Move(NewLoc, direct) + var/OldLoc = loc + if(NewLoc && !istype(NewLoc, /turf/open/indestructible/reebe_void)) + forceMove(get_turf(NewLoc)) + Moved(OldLoc, direct) + if(GLOB.ratvar_awakens) + for(var/turf/T in range(5, src)) + if(prob(166 - (get_dist(src, T) * 33))) + T.ratvar_act() //Causes moving to leave a swath of proselytized area behind the Eminence + +/mob/camera/eminence/Login() + ..() + var/datum/antagonist/clockcult/C = mind.has_antag_datum(/datum/antagonist/clockcult,TRUE) + if(!C) + add_servant_of_ratvar(src, TRUE) + C = mind.has_antag_datum(/datum/antagonist/clockcult,TRUE) + if(C && C.clock_team) + if(C.clock_team.eminence) + remove_servant_of_ratvar(src,TRUE) + qdel(src) + else + C.clock_team.eminence = src + to_chat(src, "You have been selected as the Eminence!") + to_chat(src, "As the Eminence, you lead the servants. Anything you say will be heard by the entire cult.") + to_chat(src, "Though you can move through walls, you're also incorporeal, and largely can't interact with the world except for a few ways.") + to_chat(src, "Additionally, unless the herald's beacon is activated, you can't understand any speech while away from Reebe.") + eminence_help() + for(var/V in actions) + var/datum/action/A = V + A.Remove(src) //So we get rid of duplicate actions; this also removes Hierophant network, since our say() goes across it anyway + var/datum/action/innate/eminence/E + for(var/V in subtypesof(/datum/action/innate/eminence)) + E = new V + E.Grant(src) + +/mob/camera/eminence/say(message) + message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) + if(!message) + return + log_talk(src, "[key_name(src)] : [message]", LOGSAY) + if(GLOB.ratvar_awakens) + visible_message("You feel light slam into your mind and form words: \"[capitalize(message)]\"") + playsound(src, 'sound/machines/clockcult/ark_scream.ogg', 50, FALSE) + hierophant_message("The Eminence: \"[message]\"") + +/mob/camera/eminence/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode) + if(z == ZLEVEL_CITYOFCOGS || is_servant_of_ratvar(speaker) || GLOB.ratvar_approaches || GLOB.ratvar_awakens) //Away from Reebe, the Eminence can't hear anything + to_chat(src, message) + return + to_chat(src, "[speaker] says something, but you can't understand any of it...") + +/mob/camera/eminence/ClickOn(atom/A, params) + var/list/modifiers = params2list(params) + if(modifiers["shift"]) + A.examine(src) + return + if(modifiers["alt"] && istype(A, /turf/closed/wall/clockwork)) + superheat_wall(A) + return + if(modifiers["middle"] || modifiers["ctrl"]) + issue_command(A) + return + if(GLOB.ark_of_the_clockwork_justiciar == A) + var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar + if(G.recalling) + return + if(!G.recalls_remaining) + to_chat(src, "The Ark can no longer recall!") + return + if(alert(src, "Initiate mass recall?", "Mass Recall", "Yes", "No") != "Yes" || QDELETED(src) || QDELETED(G) || !G.obj_integrity) + return + G.initiate_mass_recall() //wHOOPS LOOKS LIKE A HULK GOT THROUGH + else if(istype(A, /obj/structure/destructible/clockwork/trap/trigger)) + var/obj/structure/destructible/clockwork/trap/trigger/T = A + T.visible_message("[T] clunks as it's activated remotely.") + to_chat(src, "You activate [T].") + T.activate() + +/mob/camera/eminence/ratvar_act() + name = "\improper Radiance" + real_name = "\improper Radiance" + desc = "The light, forgotten." + transform = matrix() * 2 + invisibility = SEE_INVISIBLE_MINIMUM + +/mob/camera/eminence/proc/issue_command(atom/movable/A) + var/list/commands + var/atom/movable/command_location + if(A == src) + commands = list("Defend the Ark!", "Advance!", "Retreat!", "Generate Power", "Build Defenses (Bottom-Up)", "Build Defenses (Top-Down)") + else + command_location = A + commands = list("Rally Here", "Regroup Here", "Avoid This Area", "Reinforce This Area") + if(istype(A, /obj/structure/destructible/clockwork/powered)) + var/obj/structure/destructible/clockwork/powered/P = A + if(!can_access_clockwork_power(P)) + commands += "Power This Structure" + if(P.obj_integrity < P.max_integrity) + commands += "Repair This Structure" + var/roma_invicta = input(src, "Choose a command to issue to your cult!", "Issue Commands") as null|anything in commands + if(!roma_invicta) + return + var/command_text = "" + var/marker_icon + switch(roma_invicta) + if("Rally Here") + command_text = "The Eminence orders an offensive rally at [command_location] to the GETDIR!" + marker_icon = "eminence_rally" + if("Regroup Here") + command_text = "The Eminence orders a regroup to [command_location] to the GETDIR!" + marker_icon = "eminence_rally" + if("Avoid This Area") + command_text = "The Eminence has designated the area to your GETDIR as dangerous and to be avoided!" + marker_icon = "eminence_avoid" + if("Reinforce This Area") + command_text = "The Eminence orders the defense and fortification of the area to your GETDIR!" + marker_icon = "eminence_reinforce" + if("Power This Structure") + command_text = "[command_location] to your GETDIR has no power! Turn it on and make sure there's a sigil of transmission nearby!" + marker_icon = "eminence_unlimited_power" + if("Repair This Structure") + command_text = "The Eminence orders that [command_location] to your GETDIR should be repaired ASAP!" + marker_icon = "eminence_repair" + if("Defend the Ark!") + command_text = "The Eminence orders immediate defense of the Ark!" + if("Advance!") + command_text = "The Eminence commands you push forward!" + if("Retreat!") + command_text = "The Eminence has sounded the retreat! Fall back!" + if("Generate Power") + command_text = "The Eminence orders more power! Build power generations on the station!" + if("Build Defenses (Bottom-Up)") + command_text = "The Eminence orders that defenses should be built starting from the bottom of Reebe!" + if("Build Defenses (Top-Down)") + command_text = "The Eminence orders that defenses should be built starting from the top of Reebe!" + if(marker_icon) + new/obj/effect/temp_visual/ratvar/command_point(get_turf(A), marker_icon) + for(var/mob/M in servants_and_ghosts()) + to_chat(M, "[replacetext(command_text, "GETDIR", dir2text(get_dir(M, command_location)))]") + M.playsound_local(M, 'sound/machines/clockcult/eminence_command.ogg', 75, FALSE, pressure_affected = FALSE) + else + hierophant_message("[command_text]") + for(var/mob/M in servants_and_ghosts()) + M.playsound_local(M, 'sound/machines/clockcult/eminence_command.ogg', 75, FALSE, pressure_affected = FALSE) + +/mob/camera/eminence/proc/superheat_wall(turf/closed/wall/clockwork/wall) + if(!istype(wall)) + return + if(superheated_walls >= SUPERHEATED_CLOCKWORK_WALL_LIMIT && !wall.heated) + to_chat(src, "You're exerting all of your power superheating this many walls already! Cool some down first!") + return + wall.turn_up_the_heat() + if(wall.heated) + superheated_walls++ + to_chat(src, "You superheat [wall]. Superheated walls: [superheated_walls]/[SUPERHEATED_CLOCKWORK_WALL_LIMIT]") + else + superheated_walls-- + to_chat(src, "You cool [wall]. Superheated walls: [superheated_walls]/[SUPERHEATED_CLOCKWORK_WALL_LIMIT]") + +/mob/camera/eminence/proc/eminence_help() + to_chat(src, "You can make use of certain shortcuts to perform different actions:") + to_chat(src, "Alt-Click a clockwork wall to superheat or cool it down. \ + Superheated walls can't be destroyed by hulks or mechs and are much slower to deconstruct, and are marked by a bright red glow. \ + This lasts indefinitely, but only [SUPERHEATED_CLOCKWORK_WALL_LIMIT] clockwork walls can be superheated at once.") + to_chat(src, "Interact with the Ark to initiate an emergency recall that teleports all servants directly to its location after a short delay. \ + This can only be used a single time, or twice if the herald's beacon was activated,") + to_chat(src, "Middle or Ctrl-Click anywhere to allow you to issue a variety of contextual commands to your cult. Different objects allow for different \ + commands. Doing this on yourself will provide commands that tell the entire cult a goal.") + + +//Eminence actions below this point +/datum/action/innate/eminence + name = "Eminence Action" + desc = "You shouldn't see this. File a bug report!" + icon_icon = 'icons/mob/actions/actions_clockcult.dmi' + background_icon_state = "bg_clock" + buttontooltipstyle = "clockcult" + +/datum/action/innate/eminence/IsAvailable() + if(!iseminence(owner)) + qdel(src) + return + return ..() + +//Lists available powers +/datum/action/innate/eminence/power_list + name = "Eminence Powers" + desc = "Forgot what you can do? This refreshes you on your powers as Eminence." + button_icon_state = "eminence_rally" + +/datum/action/innate/eminence/power_list/Activate() + var/mob/camera/eminence/E = owner + E.eminence_help() + +//Returns to the Ark +/datum/action/innate/eminence/ark_jump + name = "Return to Ark" + desc = "Warps you to the Ark." + button_icon_state = "Abscond" + +/datum/action/innate/eminence/ark_jump/Activate() + var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar + if(G) + owner.forceMove(get_turf(G)) + owner.playsound_local(owner, 'sound/magic/magic_missile.ogg', 50, TRUE) + flash_color(owner, flash_color = "#AF0AAF", flash_time = 25) + else + to_chat(owner, "There is no Ark!") + +//Warps to the Station +/datum/action/innate/eminence/station_jump + name = "Warp to Station" + desc = "Warps to Space Station 13. You cannot hear anything while there!" + button_icon_state = "warp_down" + +/datum/action/innate/eminence/station_jump/Activate() + if(owner.z == ZLEVEL_CITYOFCOGS) + owner.forceMove(get_turf(pick(GLOB.generic_event_spawns))) + owner.playsound_local(owner, 'sound/magic/magic_missile.ogg', 50, TRUE) + flash_color(owner, flash_color = "#AF0AAF", flash_time = 25) + else + to_chat(owner, "You're already on the station!") + +//A quick-use button for recalling the servants to the Ark +/datum/action/innate/eminence/mass_recall + name = "Mass Recall" + desc = "Initiates a mass recall, warping all servants to the Ark after a short delay. This can only be used once." + button_icon_state = "Spatial Gateway" + +/datum/action/innate/eminence/mass_recall/IsAvailable() + . = ..() + if(.) + var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar + if(G) + return G.recalls_remaining && !G.recalling + return FALSE + +/datum/action/innate/eminence/mass_recall/Activate() + var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar + if(G && !G.recalling && G.recalls_remaining) + if(alert(owner, "Initiate mass recall?", "Mass Recall", "Yes", "No") != "Yes" || QDELETED(owner) || QDELETED(G) || !G.obj_integrity) + return + G.initiate_mass_recall() diff --git a/code/game/gamemodes/clock_cult/clock_mobs/clockwork_marauder.dm b/code/game/gamemodes/clock_cult/clock_mobs/clockwork_marauder.dm index a1c3d211fb..562814dfeb 100644 --- a/code/game/gamemodes/clock_cult/clock_mobs/clockwork_marauder.dm +++ b/code/game/gamemodes/clock_cult/clock_mobs/clockwork_marauder.dm @@ -1,13 +1,13 @@ #define MARAUDER_SLOWDOWN_PERCENTAGE 0.40 //Below this percentage of health, marauders will become slower -#define MARAUDER_SHIELD_REGEN_TIME 100 //In deciseconds, how long it takes for shields to regenerate after breaking +#define MARAUDER_SHIELD_REGEN_TIME 200 //In deciseconds, how long it takes for shields to regenerate after breaking //Clockwork marauder: A well-rounded frontline construct. Only one can exist for every two human servants. /mob/living/simple_animal/hostile/clockwork/marauder name = "clockwork marauder" desc = "The stalwart apparition of a soldier, blazing with crimson flames. It's armed with a gladius and shield." icon_state = "clockwork_marauder" - health = 150 - maxHealth = 150 + health = 120 + maxHealth = 120 force_threshold = 8 speed = 0 obj_damage = 40 @@ -39,10 +39,11 @@ speed = initial(speed) + 1 //Yes, this slows them down else speed = initial(speed) - if(shield_health != max_shield_health && world.time >= shield_health_regen) - to_chat(src, "Your shield has recovered. [max_shield_health] blocks remaining!") + if(shield_health < max_shield_health && world.time >= shield_health_regen) + shield_health_regen = world.time + MARAUDER_SHIELD_REGEN_TIME + to_chat(src, "Your shield has recovered, [shield_health] blocks remaining!") playsound_local(src, "shatter", 75, TRUE, frequency = -1) - shield_health = max_shield_health + shield_health++ /mob/living/simple_animal/hostile/clockwork/marauder/update_values() if(GLOB.ratvar_awakens) //Massive attack damage bonuses and health increase, because Ratvar diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm index bcb9d1d1df..da1f5965bd 100644 --- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm +++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm @@ -3,6 +3,70 @@ ////////////////// +//Sigil of Transmission: Creates a sigil of transmission that can drain and store power for clockwork structures. +/datum/clockwork_scripture/create_object/sigil_of_transmission + descname = "Powers Nearby Structures - Important!" + name = "Sigil of Transmission" + desc = "Places a sigil that can drain and will store energy to power clockwork structures." + invocations = list("Divinity...", "...power our creations!") + channel_time = 70 + power_cost = 200 + whispered = TRUE + object_path = /obj/effect/clockwork/sigil/transmission + creator_message = "A sigil silently appears below you. It will automatically power clockwork structures near it and will drain power when activated." + usage_tip = "Cyborgs can charge from this sigil by remaining over it for 5 seconds." + tier = SCRIPTURE_APPLICATION + one_per_tile = TRUE + primary_component = HIEROPHANT_ANSIBLE + sort_priority = 1 + quickbind = TRUE + quickbind_desc = "Creates a Sigil of Transmission, which can drain and will store power for clockwork structures." + + +//Mania Motor: Creates a malevolent transmitter that will broadcast the whispers of Sevtug into the minds of nearby nonservants, causing a variety of mental effects at a power cost. +/datum/clockwork_scripture/create_object/mania_motor + descname = "Powered Structure, Area Denial" + name = "Mania Motor" + desc = "Creates a mania motor which causes minor damage and a variety of negative mental effects in nearby non-Servant humans, potentially up to and including conversion." + invocations = list("May this transmitter...", "...break the will of all who oppose us!") + channel_time = 80 + power_cost = 750 + object_path = /obj/structure/destructible/clockwork/powered/mania_motor + creator_message = "You form a mania motor, which causes minor damage and negative mental effects in non-Servants." + observer_message = "A two-pronged machine rises from the ground!" + invokers_required = 2 + multiple_invokers_used = TRUE + usage_tip = "It will also cure hallucinations and brain damage in nearby Servants." + tier = SCRIPTURE_APPLICATION + one_per_tile = TRUE + primary_component = HIEROPHANT_ANSIBLE + sort_priority = 2 + quickbind = TRUE + quickbind_desc = "Creates a Mania Motor, which causes minor damage and negative mental effects in non-Servants." + + +//Clockwork Obelisk: Creates a powerful obelisk that can be used to broadcast messages or open a gateway to any servant or clockwork obelisk at a power cost. +/datum/clockwork_scripture/create_object/clockwork_obelisk + descname = "Powered Structure, Teleportation Hub" + name = "Clockwork Obelisk" + desc = "Creates a clockwork obelisk that can broadcast messages over the Hierophant Network or open a Spatial Gateway to any living Servant or clockwork obelisk." + invocations = list("May this obelisk...", "...take us to all places!") + channel_time = 80 + power_cost = 300 + object_path = /obj/structure/destructible/clockwork/powered/clockwork_obelisk + creator_message = "You form a clockwork obelisk which can broadcast messages or produce Spatial Gateways." + observer_message = "A brass obelisk appears hanging in midair!" + invokers_required = 2 + multiple_invokers_used = TRUE + usage_tip = "Producing a gateway has a high power cost. Gateways to or between clockwork obelisks receive double duration and uses." + tier = SCRIPTURE_APPLICATION + one_per_tile = TRUE + primary_component = HIEROPHANT_ANSIBLE + sort_priority = 3 + quickbind = TRUE + quickbind_desc = "Creates a Clockwork Obelisk, which can send messages or open Spatial Gateways with power." + + //Clockwork Marauder: Creates a construct shell for a clockwork marauder, a well-rounded frontline fighter. /datum/clockwork_scripture/create_object/construct/clockwork_marauder descname = "Well-Rounded Combat Construct" @@ -16,7 +80,7 @@ tier = SCRIPTURE_APPLICATION one_per_tile = TRUE primary_component = BELLIGERENT_EYE - sort_priority = 1 + sort_priority = 4 quickbind = TRUE quickbind_desc = "Creates a clockwork marauder, used for frontline combat." object_path = /obj/item/clockwork/construct_chassis/clockwork_marauder @@ -33,7 +97,7 @@ if(ishuman(M.current)) human_servants++ construct_limit = human_servants / 4 //1 per 4 human servants, and a maximum of 3 marauders - construct_limit = Clamp(construct_limit, 1, 3) + construct_limit = CLAMP(construct_limit, 1, 3) /datum/clockwork_scripture/create_object/construct/clockwork_marauder/pre_recital() channel_time = initial(channel_time) @@ -59,67 +123,3 @@ time_since_last_marauder = world.time //So that it can't be spammed to make the marauder exclusion plummet; this emulates "ticking" recent_marauders = max(0, recent_marauders - marauders_to_exclude) scaled_recital_time = min(recent_marauders * MARAUDER_SCRIPTURE_SCALING_TIME, MARAUDER_SCRIPTURE_SCALING_MAX) - - -//Mania Motor: Creates a malevolent transmitter that will broadcast the whispers of Sevtug into the minds of nearby nonservants, causing a variety of mental effects at a power cost. -/datum/clockwork_scripture/create_object/mania_motor - descname = "Powered Structure, Area Denial" - name = "Mania Motor" - desc = "Creates a mania motor which causes minor damage and a variety of negative mental effects in nearby non-Servant humans, potentially up to and including conversion." - invocations = list("May this transmitter...", "...break the will of all who oppose us!") - channel_time = 80 - power_cost = 750 - object_path = /obj/structure/destructible/clockwork/powered/mania_motor - creator_message = "You form a mania motor, which causes minor damage and negative mental effects in non-Servants." - observer_message = "A two-pronged machine rises from the ground!" - invokers_required = 2 - multiple_invokers_used = TRUE - usage_tip = "It will also cure hallucinations and brain damage in nearby Servants." - tier = SCRIPTURE_APPLICATION - one_per_tile = TRUE - primary_component = GEIS_CAPACITOR - sort_priority = 2 - quickbind = TRUE - quickbind_desc = "Creates a Mania Motor, which causes minor damage and negative mental effects in non-Servants." - - -//Sigil of Transmission: Creates a sigil of transmission that can drain and store power for clockwork structures. -/datum/clockwork_scripture/create_object/sigil_of_transmission - descname = "Structure Power Generator & Battery" - name = "Sigil of Transmission" - desc = "Places a sigil that can drain and will store energy to power clockwork structures." - invocations = list("Divinity...", "...power our creations!") - channel_time = 70 - power_cost = 200 - whispered = TRUE - object_path = /obj/effect/clockwork/sigil/transmission - creator_message = "A sigil silently appears below you. It will automatically power clockwork structures near it and will drain power when activated." - usage_tip = "Cyborgs can charge from this sigil by remaining over it for 5 seconds." - tier = SCRIPTURE_APPLICATION - one_per_tile = TRUE - primary_component = HIEROPHANT_ANSIBLE - sort_priority = 3 - quickbind = TRUE - quickbind_desc = "Creates a Sigil of Transmission, which can drain and will store power for clockwork structures." - - -//Clockwork Obelisk: Creates a powerful obelisk that can be used to broadcast messages or open a gateway to any servant or clockwork obelisk at a power cost. -/datum/clockwork_scripture/create_object/clockwork_obelisk - descname = "Powered Structure, Teleportation Hub" - name = "Clockwork Obelisk" - desc = "Creates a clockwork obelisk that can broadcast messages over the Hierophant Network or open a Spatial Gateway to any living Servant or clockwork obelisk." - invocations = list("May this obelisk...", "...take us to all places!") - channel_time = 80 - power_cost = 300 - object_path = /obj/structure/destructible/clockwork/powered/clockwork_obelisk - creator_message = "You form a clockwork obelisk which can broadcast messages or produce Spatial Gateways." - observer_message = "A brass obelisk appears hanging in midair!" - invokers_required = 2 - multiple_invokers_used = TRUE - usage_tip = "Producing a gateway has a high power cost. Gateways to or between clockwork obelisks receive double duration and uses." - tier = SCRIPTURE_APPLICATION - one_per_tile = TRUE - primary_component = HIEROPHANT_ANSIBLE - sort_priority = 4 - quickbind = TRUE - quickbind_desc = "Creates a Clockwork Obelisk, which can send messages or open Spatial Gateways with power." diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm index 93d203aba0..8275e4d20e 100644 --- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm +++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm @@ -2,27 +2,52 @@ // DRIVERS // ///////////// -//Hateful Manacles: Applies restraints from melee over several seconds. The restraints function like handcuffs and break on removal. -/datum/clockwork_scripture/ranged_ability/hateful_manacles - descname = "Handcuffs" - name = "Hateful Manacles" - desc = "Forms replicant manacles around a target's wrists that function like handcuffs." - invocations = list("Shackle the heretic!", "Break them in body and spirit!") - channel_time = 15 - power_cost = 25 - whispered = TRUE - usage_tip = "The manacles are about as strong as zipties, and break when removed." + +//Stargazer: Creates a stargazer, a cheap power generator that utilizes starlight. +/datum/clockwork_scripture/create_object/stargazer + descname = "Generates Power From Starlight - Important!" + name = "Stargazer" + desc = "Forms a weak structure that generates power every second while within three tiles of starlight." + invocations = list("Capture their inferior light for us!") + channel_time = 50 + power_cost = 50 + object_path = /obj/structure/destructible/clockwork/stargazer + creator_message = "You form a stargazer, which will generate power near starlight." + observer_message = "A large lantern-shaped machine forms!" + usage_tip = "For obvious reasons, make sure to place this near a window or somewhere else that can see space!" tier = SCRIPTURE_DRIVER - primary_component = BELLIGERENT_EYE + one_per_tile = TRUE + primary_component = HIEROPHANT_ANSIBLE sort_priority = 1 - ranged_type = /obj/effect/proc_holder/slab/hateful_manacles - slab_overlay = "hateful_manacles" - ranged_message = "You charge the clockwork slab with divine energy.\n\ - Left-click a target within melee range to shackle!\n\ - Click your slab to cancel." - timeout_time = 200 quickbind = TRUE - quickbind_desc = "Applies handcuffs to a struck target." + quickbind_desc = "Creates a stargazer, which generates power when near starlight." + +/datum/clockwork_scripture/create_object/stargazer/check_special_requirements() + var/area/A = get_area(invoker) + if(A.outdoors || A.map_name == "Space" || !A.blob_allowed) + to_chat(invoker, "Stargazers can't be built off-station.") + return + return ..() + + +//Integration Cog: Creates an integration cog that can be inserted into APCs to passively siphon power. +/datum/clockwork_scripture/create_object/integration_cog + descname = "APC Power Siphoner" + name = "Integration Cog" + desc = "Fabricates an integration cog, which can be used on an open APC to replace its innards and passively siphon its power." + invocations = list("Take that which sustains them!") + channel_time = 10 + power_cost = 10 + whispered = TRUE + object_path = /obj/item/clockwork/integration_cog + creator_message = "You form an integration cog, which can be inserted into an open APC to passively siphon power." + usage_tip = "Tampering isn't visible unless the APC is opened." + tier = SCRIPTURE_DRIVER + space_allowed = TRUE + primary_component = HIEROPHANT_ANSIBLE + sort_priority = 2 + quickbind = TRUE + quickbind_desc = "Creates an integration cog, which can be used to siphon power from an open APC." //Sigil of Transgression: Creates a sigil of transgression, which briefly stuns and applies Belligerent to the first non-servant to cross it. @@ -39,12 +64,78 @@ usage_tip = "The sigil does not silence its victim, and is generally used to soften potential converts or would-be invaders." tier = SCRIPTURE_DRIVER one_per_tile = TRUE - primary_component = BELLIGERENT_EYE - sort_priority = 2 + primary_component = HIEROPHANT_ANSIBLE + sort_priority = 3 quickbind = TRUE quickbind_desc = "Creates a Sigil of Transgression, which will briefly stun and slow the next non-Servant to cross it." +//Sigil of Submission: Creates a sigil of submission, which converts one heretic above it after a delay. +/datum/clockwork_scripture/create_object/sigil_of_submission + descname = "Trap, Conversion" + name = "Sigil of Submission" + desc = "Places a luminous sigil that will convert any non-Servants that remain on it for 8 seconds." + invocations = list("Divinity, enlighten...", "...those who trespass here!") + channel_time = 60 + power_cost = 125 + whispered = TRUE + object_path = /obj/effect/clockwork/sigil/submission + creator_message = "A luminous sigil appears below you. Any non-Servants to cross it will be converted after 8 seconds if they do not move." + usage_tip = "This is the primary conversion method, though it will not penetrate mindshield implants." + tier = SCRIPTURE_DRIVER + one_per_tile = TRUE + primary_component = HIEROPHANT_ANSIBLE + sort_priority = 4 + quickbind = TRUE + quickbind_desc = "Creates a Sigil of Submission, which will convert non-Servants that remain on it." + + +//Kindle: Charges the slab with blazing energy. It can be released to stun and silence a target. +/datum/clockwork_scripture/ranged_ability/kindle + descname = "Short-Range Single-Target Stun" + name = "Kindle" + desc = "Charges your slab with divine energy, allowing you to overwhelm a target with Ratvar's light." + invocations = list("Divinity, show them your light!") + whispered = TRUE + channel_time = 30 + power_cost = 125 + usage_tip = "The light can be used from up to two tiles away. Damage taken will GREATLY REDUCE the stun's duration." + tier = SCRIPTURE_DRIVER + primary_component = BELLIGERENT_EYE + sort_priority = 5 + slab_overlay = "volt" + ranged_type = /obj/effect/proc_holder/slab/kindle + ranged_message = "You charge the clockwork slab with divine energy.\n\ + Left-click a target within melee range to stun!\n\ + Click your slab to cancel." + timeout_time = 150 + quickbind = TRUE + quickbind_desc = "Stuns and mutes a target from a short range." + + +//Hateful Manacles: Applies restraints from melee over several seconds. The restraints function like handcuffs and break on removal. +/datum/clockwork_scripture/ranged_ability/hateful_manacles + descname = "Handcuffs" + name = "Hateful Manacles" + desc = "Forms replicant manacles around a target's wrists that function like handcuffs." + invocations = list("Shackle the heretic!", "Break them in body and spirit!") + channel_time = 15 + power_cost = 25 + whispered = TRUE + usage_tip = "The manacles are about as strong as zipties, and break when removed." + tier = SCRIPTURE_DRIVER + primary_component = BELLIGERENT_EYE + sort_priority = 6 + ranged_type = /obj/effect/proc_holder/slab/hateful_manacles + slab_overlay = "hateful_manacles" + ranged_message = "You charge the clockwork slab with divine energy.\n\ + Left-click a target within melee range to shackle!\n\ + Click your slab to cancel." + timeout_time = 200 + quickbind = TRUE + quickbind_desc = "Applies handcuffs to a struck target." + + //Vanguard: Provides twenty seconds of stun immunity. At the end of the twenty seconds, 25% of all stuns absorbed are applied to the invoker. /datum/clockwork_scripture/vanguard descname = "Self Stun Immunity" @@ -57,7 +148,7 @@ usage_tip = "You cannot reactivate Vanguard while still shielded by it." tier = SCRIPTURE_DRIVER primary_component = VANGUARD_COGWHEEL - sort_priority = 3 + sort_priority = 7 quickbind = TRUE quickbind_desc = "Allows you to temporarily absorb stuns. All stuns absorbed will affect you when disabled." @@ -89,7 +180,7 @@ usage_tip = "The Compromise is very fast to invoke, and will remove holy water from the target Servant." tier = SCRIPTURE_DRIVER primary_component = VANGUARD_COGWHEEL - sort_priority = 4 + sort_priority = 8 quickbind = TRUE quickbind_desc = "Allows you to convert a Servant's brute, burn, and oxygen damage to half toxin damage.
    Click your slab to disable." slab_overlay = "compromise" @@ -101,7 +192,7 @@ //Abscond: Used to return to Reebe. /datum/clockwork_scripture/abscond - descname = "Return to Reebe" + descname = "Return to Reebe - Important!" name = "Abscond" desc = "Yanks you through space, returning you to home base." invocations = list("As we bid farewell, and return to the stars...", "...we shall find our way home.") @@ -113,7 +204,7 @@ usage_tip = "This can't be used while on Reebe, for obvious reasons." tier = SCRIPTURE_DRIVER primary_component = GEIS_CAPACITOR - sort_priority = 5 + sort_priority = 9 quickbind = TRUE quickbind_desc = "Returns you to Reebe." @@ -153,52 +244,9 @@ animate(invoker.client, color = initial(invoker.client.color), time = 10) -//Kindle: Charges the slab with blazing energy. It can be released to stun and silence a target. -/datum/clockwork_scripture/ranged_ability/kindle - descname = "Short-Range Single-Target Stun" - name = "Kindle" - desc = "Charges your slab with divine energy, allowing you to overwhelm a target with Ratvar's light." - invocations = list("Divinity, show them your light!") - whispered = TRUE - channel_time = 30 - power_cost = 125 - usage_tip = "The light can be used from up to two tiles away. Damage taken will GREATLY REDUCE the stun's duration." - tier = SCRIPTURE_DRIVER - primary_component = GEIS_CAPACITOR - sort_priority = 6 - slab_overlay = "volt" - ranged_type = /obj/effect/proc_holder/slab/kindle - ranged_message = "You charge the clockwork slab with divine energy.\n\ - Left-click a target within melee range to stun!\n\ - Click your slab to cancel." - timeout_time = 150 - quickbind = TRUE - quickbind_desc = "Stuns and mutes a target from a short range." - - -//Sigil of Submission: Creates a sigil of submission, which converts one heretic above it after a delay. -/datum/clockwork_scripture/create_object/sigil_of_submission - descname = "Trap, Conversion" - name = "Sigil of Submission" - desc = "Places a luminous sigil that will convert any non-Servants that remain on it for 8 seconds." - invocations = list("Divinity, enlighten...", "...those who trespass here!") - channel_time = 60 - power_cost = 125 - whispered = TRUE - object_path = /obj/effect/clockwork/sigil/submission - creator_message = "A luminous sigil appears below you. Any non-Servants to cross it will be converted after 8 seconds if they do not move." - usage_tip = "This is the primary conversion method, though it will not penetrate mindshield implants." - tier = SCRIPTURE_DRIVER - one_per_tile = TRUE - primary_component = GEIS_CAPACITOR - sort_priority = 6 - quickbind = TRUE - quickbind_desc = "Creates a Sigil of Submission, which will convert non-Servants that remain on it." - - //Replicant: Creates a new clockwork slab. /datum/clockwork_scripture/create_object/replicant - descname = "New Clockwork Slab" + descname = "New Clockwork Slab - Important!" name = "Replicant" desc = "Creates a new clockwork slab." invocations = list("Metal, become greater!") @@ -210,59 +258,12 @@ usage_tip = "This is inefficient as a way to produce components, as the slab produced must be held by someone with no other slabs to produce components." tier = SCRIPTURE_DRIVER space_allowed = TRUE - primary_component = REPLICANT_ALLOY - sort_priority = 7 + primary_component = GEIS_CAPACITOR + sort_priority = 10 quickbind = TRUE quickbind_desc = "Creates a new Clockwork Slab." -//Stargazer: Creates a stargazer, a cheap power generator that utilizes starlight. -/datum/clockwork_scripture/create_object/stargazer - descname = "Necessary Structure, Generates Power From Starlight" - name = "Stargazer" - desc = "Forms a weak structure that generates power every second while within three tiles of starlight." - invocations = list("Capture their inferior light for us!") - channel_time = 50 - power_cost = 50 - object_path = /obj/structure/destructible/clockwork/stargazer - creator_message = "You form a stargazer, which will generate power near starlight." - observer_message = "A large lantern-shaped machine forms!" - usage_tip = "For obvious reasons, make sure to place this near a window or somewhere else that can see space!" - tier = SCRIPTURE_DRIVER - one_per_tile = TRUE - primary_component = REPLICANT_ALLOY - sort_priority = 8 - quickbind = TRUE - quickbind_desc = "Creates a stargazer, which generates power when near starlight." - -/datum/clockwork_scripture/create_object/stargazer/check_special_requirements() - var/area/A = get_area(invoker) - if(A.outdoors || A.map_name == "Space" || !A.blob_allowed) - to_chat(invoker, "Stargazers can't be built off-station.") - return - return ..() - - -//Integration Cog: Creates an integration cog that can be inserted into APCs to passively siphon power. -/datum/clockwork_scripture/create_object/integration_cog - descname = "APC Power Siphoner" - name = "Integration Cog" - desc = "Fabricates an integration cog, which can be used on an open APC to replace its innards and passively siphon its power." - invocations = list("Take that which sustains them!") - channel_time = 10 - power_cost = 10 - whispered = TRUE - object_path = /obj/item/clockwork/integration_cog - creator_message = "You form an integration cog, which can be inserted into an open APC to passively siphon power." - usage_tip = "Tampering isn't visible unless the APC is opened." - tier = SCRIPTURE_DRIVER - space_allowed = TRUE - primary_component = HIEROPHANT_ANSIBLE - sort_priority = 9 - quickbind = TRUE - quickbind_desc = "Creates an integration cog, which can be used to siphon power from an open APC." - - //Wraith Spectacles: Creates a pair of wraith spectacles, which grant xray vision but damage vision slowly. /datum/clockwork_scripture/create_object/wraith_spectacles descname = "Limited Xray Vision Glasses" @@ -277,7 +278,7 @@ usage_tip = "\"True sight\" means that you are able to see through walls and in darkness." tier = SCRIPTURE_DRIVER space_allowed = TRUE - primary_component = HIEROPHANT_ANSIBLE - sort_priority = 10 + primary_component = GEIS_CAPACITOR + sort_priority = 11 quickbind = TRUE quickbind_desc = "Creates a pair of Wraith Spectacles, which grant true sight but cause gradual vision loss." diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm index a172f4ca41..09cfeb99d3 100644 --- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm +++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm @@ -2,6 +2,27 @@ // SCRIPTS // ///////////// + +//Replica Fabricator: Creates a replica fabricator, used to convert objects and repair clockwork structures. +/datum/clockwork_scripture/create_object/replica_fabricator + descname = "Creates Brass and Converts Objects - Important!" + name = "Replica Fabricator" + desc = "Forms a device that, when used on certain objects, replaces them with their Ratvarian equivalents. It requires power to function." + invocations = list("With this device...", "...his presence shall be made known.") + channel_time = 20 + power_cost = 250 + whispered = TRUE + object_path = /obj/item/clockwork/replica_fabricator + creator_message = "You form a replica fabricator." + usage_tip = "Clockwork Walls cause nearby Tinkerer's Caches to generate components passively, making this a vital tool. Clockwork Floors heal toxin damage in Servants standing on them." + tier = SCRIPTURE_SCRIPT + space_allowed = TRUE + primary_component = HIEROPHANT_ANSIBLE + sort_priority = 1 + quickbind = TRUE + quickbind_desc = "Creates a Replica Fabricator, which can convert various objects to Ratvarian variants." + + //Ocular Warden: Creates an ocular warden, which defends a small area near it. /datum/clockwork_scripture/create_object/ocular_warden descname = "Structure, Turret" @@ -17,8 +38,8 @@ tier = SCRIPTURE_SCRIPT one_per_tile = TRUE space_allowed = TRUE - primary_component = BELLIGERENT_EYE - sort_priority = 1 + primary_component = HIEROPHANT_ANSIBLE + sort_priority = 2 quickbind = TRUE quickbind_desc = "Creates an Ocular Warden, which will automatically attack nearby unrestrained non-Servants that can see it." @@ -29,26 +50,6 @@ return ..() -//Judicial Visor: Creates a judicial visor, which can smite an area. -/datum/clockwork_scripture/create_object/judicial_visor - descname = "Delayed Area Knockdown Glasses" - name = "Judicial Visor" - desc = "Creates a visor that can smite an area, applying Belligerent and briefly stunning. The smote area will explode after 3 seconds." - invocations = list("Grant me the flames of Engine!") - channel_time = 10 - power_cost = 400 - whispered = TRUE - object_path = /obj/item/clothing/glasses/judicial_visor - creator_message = "You form a judicial visor, which is capable of smiting a small area." - usage_tip = "The visor has a thirty-second cooldown once used." - tier = SCRIPTURE_SCRIPT - space_allowed = TRUE - primary_component = BELLIGERENT_EYE - sort_priority = 2 - quickbind = TRUE - quickbind_desc = "Creates a Judicial Visor, which can smite an area, applying Belligerent and briefly stunning." - - //Vitality Matrix: Creates a sigil which will drain health from nonservants and can use that health to heal or even revive servants. /datum/clockwork_scripture/create_object/vitality_matrix descname = "Trap, Damage to Healing" @@ -64,147 +65,35 @@ usage_tip = "The sigil will be consumed upon reviving a Servant." tier = SCRIPTURE_SCRIPT one_per_tile = TRUE - primary_component = VANGUARD_COGWHEEL + primary_component = HIEROPHANT_ANSIBLE sort_priority = 3 quickbind = TRUE quickbind_desc = "Creates a Vitality Matrix, which drains non-Servants on it to heal Servants that cross it." -//Mending Mantra: Channeled for up to ten times over twenty seconds to repair structures and heal allies -/datum/clockwork_scripture/channeled/mending_mantra - descname = "Channeled, Area Healing and Repair" - name = "Mending Mantra" - desc = "Repairs nearby structures and constructs. Servants wearing clockwork armor will also be healed. Channeled every two seconds for a maximum of twenty seconds." - chant_invocations = list("Mend our dents!", "Heal our scratches!", "Repair our gears!") - chant_amount = 10 - chant_interval = 20 - power_cost = 1000 - usage_tip = "This is a very effective way to rapidly reinforce a base after an attack." - tier = SCRIPTURE_SCRIPT - primary_component = VANGUARD_COGWHEEL - sort_priority = 4 - quickbind = TRUE - quickbind_desc = "Repairs nearby structures and constructs. Servants wearing clockwork armor will also be healed.
    Maximum 10 chants." - var/heal_attempts = 4 - var/heal_amount = 2.5 - var/static/list/damage_heal_order = list(BRUTE, BURN, OXY) - var/static/list/heal_finish_messages = list("There, all mended!", "Try not to get too damaged.", "No more dents and scratches for you!", "Champions never die.", "All patched up.", \ - "Ah, child, it's okay now.", "Pain is temporary.", "What you do for the Justiciar is eternal.", "Bear this for me.", "Be strong, child.", "Please, be careful!", \ - "If you die, you will be remembered.") - var/static/list/heal_target_typecache = typecacheof(list( - /obj/structure/destructible/clockwork, - /obj/machinery/door/airlock/clockwork, - /obj/machinery/door/window/clockwork, - /obj/structure/window/reinforced/clockwork, - /obj/structure/table/reinforced/brass)) - var/static/list/ratvarian_armor_typecache = typecacheof(list( - /obj/item/clothing/suit/armor/clockwork, - /obj/item/clothing/head/helmet/clockwork, - /obj/item/clothing/gloves/clockwork, - /obj/item/clothing/shoes/clockwork)) - -/datum/clockwork_scripture/channeled/mending_mantra/chant_effects(chant_number) - var/turf/T - for(var/atom/movable/M in range(7, invoker)) - if(isliving(M)) - if(isclockmob(M) || istype(M, /mob/living/simple_animal/drone/cogscarab)) - var/mob/living/simple_animal/S = M - if(S.health == S.maxHealth || S.stat == DEAD) - continue - T = get_turf(M) - for(var/i in 1 to heal_attempts) - if(S.health < S.maxHealth) - S.adjustHealth(-heal_amount) - new /obj/effect/temp_visual/heal(T, "#1E8CE1") - if(i == heal_attempts && S.health >= S.maxHealth) //we finished healing on the last tick, give them the message - to_chat(S, "\"[text2ratvar(pick(heal_finish_messages))]\"") - break - else - to_chat(S, "\"[text2ratvar(pick(heal_finish_messages))]\"") - break - else if(issilicon(M)) - var/mob/living/silicon/S = M - if(S.health == S.maxHealth || S.stat == DEAD || !is_servant_of_ratvar(S)) - continue - T = get_turf(M) - for(var/i in 1 to heal_attempts) - if(S.health < S.maxHealth) - S.heal_ordered_damage(heal_amount, damage_heal_order) - new /obj/effect/temp_visual/heal(T, "#1E8CE1") - if(i == heal_attempts && S.health >= S.maxHealth) - to_chat(S, "\"[text2ratvar(pick(heal_finish_messages))]\"") - break - else - to_chat(S, "\"[text2ratvar(pick(heal_finish_messages))]\"") - break - else if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(H.health == H.maxHealth || H.stat == DEAD || !is_servant_of_ratvar(H)) - continue - T = get_turf(M) - var/heal_ticks = 0 //one heal tick for each piece of ratvarian armor worn - var/obj/item/I = H.get_item_by_slot(slot_wear_suit) - if(is_type_in_typecache(I, ratvarian_armor_typecache)) - heal_ticks++ - I = H.get_item_by_slot(slot_head) - if(is_type_in_typecache(I, ratvarian_armor_typecache)) - heal_ticks++ - I = H.get_item_by_slot(slot_gloves) - if(is_type_in_typecache(I, ratvarian_armor_typecache)) - heal_ticks++ - I = H.get_item_by_slot(slot_shoes) - if(is_type_in_typecache(I, ratvarian_armor_typecache)) - heal_ticks++ - if(heal_ticks) - for(var/i in 1 to heal_ticks) - if(H.health < H.maxHealth) - H.heal_ordered_damage(heal_amount, damage_heal_order) - new /obj/effect/temp_visual/heal(T, "#1E8CE1") - if(i == heal_ticks && H.health >= H.maxHealth) - to_chat(H, "\"[text2ratvar(pick(heal_finish_messages))]\"") - break - else - to_chat(H, "\"[text2ratvar(pick(heal_finish_messages))]\"") - break - else if(is_type_in_typecache(M, heal_target_typecache)) - var/obj/structure/destructible/clockwork/C = M - if(C.obj_integrity == C.max_integrity || (istype(C) && !C.can_be_repaired)) - continue - T = get_turf(M) - for(var/i in 1 to heal_attempts) - if(C.obj_integrity < C.max_integrity) - C.obj_integrity = min(C.obj_integrity + 5, C.max_integrity) - C.update_icon() - new /obj/effect/temp_visual/heal(T, "#1E8CE1") - else - break - new /obj/effect/temp_visual/ratvar/mending_mantra(get_turf(invoker)) - return TRUE - - -//Replica Fabricator: Creates a replica fabricator, used to convert objects and repair clockwork structures. -/datum/clockwork_scripture/create_object/replica_fabricator - descname = "Replaces Objects with Ratvarian Versions" - name = "Replica Fabricator" - desc = "Forms a device that, when used on certain objects, replaces them with their Ratvarian equivalents. It requires power to function." - invocations = list("With this device...", "...his presence shall be made known.") - channel_time = 20 - power_cost = 250 +//Judicial Visor: Creates a judicial visor, which can smite an area. +/datum/clockwork_scripture/create_object/judicial_visor + descname = "Delayed Area Knockdown Glasses" + name = "Judicial Visor" + desc = "Creates a visor that can smite an area, applying Belligerent and briefly stunning. The smote area will explode after 3 seconds." + invocations = list("Grant me the flames of Engine!") + channel_time = 10 + power_cost = 400 whispered = TRUE - object_path = /obj/item/clockwork/replica_fabricator - creator_message = "You form a replica fabricator." - usage_tip = "Clockwork Walls cause nearby Tinkerer's Caches to generate components passively, making this a vital tool. Clockwork Floors heal toxin damage in Servants standing on them." + object_path = /obj/item/clothing/glasses/judicial_visor + creator_message = "You form a judicial visor, which is capable of smiting a small area." + usage_tip = "The visor has a thirty-second cooldown once used." tier = SCRIPTURE_SCRIPT space_allowed = TRUE - primary_component = REPLICANT_ALLOY - sort_priority = 5 + primary_component = BELLIGERENT_EYE + sort_priority = 4 quickbind = TRUE - quickbind_desc = "Creates a Replica Fabricator, which can convert various objects to Ratvarian variants." + quickbind_desc = "Creates a Judicial Visor, which can smite an area, applying Belligerent and briefly stunning." //Clockwork Arnaments: Grants the invoker the ability to call forth a Ratvarian spear and clockwork armor. /datum/clockwork_scripture/clockwork_arnaments - descname = "Summonable Armor and Weapons" + descname = "Summonable Armor and Weapons - Important!" name = "Clockwork Arnaments" desc = "Allows the invoker to summon clockwork armor and a Ratvarian spear at will. The spear's attacks will generate Vitality, used for healing." invocations = list("Grant me arnaments...", "...from the forge of Armorer!") @@ -213,8 +102,8 @@ whispered = TRUE usage_tip = "Throwing the spear at a mob will do massive damage and knock them down, but break the spear. You will need to wait for 30 seconds before resummoning it." tier = SCRIPTURE_SCRIPT - primary_component = REPLICANT_ALLOY - sort_priority = 6 + primary_component = VANGUARD_COGWHEEL + sort_priority = 5 quickbind = TRUE quickbind_desc = "Permanently binds clockwork armor and a Ratvarian spear to you." @@ -312,8 +201,8 @@ multiple_invokers_optional = TRUE usage_tip = "This gateway is strictly one-way and will only allow things through the invoker's portal." tier = SCRIPTURE_SCRIPT - primary_component = HIEROPHANT_ANSIBLE - sort_priority = 9 + primary_component = GEIS_CAPACITOR + sort_priority = 6 quickbind = TRUE quickbind_desc = "Allows you to create a one-way Spatial Gateway to a living Servant or Clockwork Obelisk." diff --git a/code/game/gamemodes/clock_cult/clock_structures/_trap_object.dm b/code/game/gamemodes/clock_cult/clock_structures/_trap_object.dm new file mode 100644 index 0000000000..63c0182f7f --- /dev/null +++ b/code/game/gamemodes/clock_cult/clock_structures/_trap_object.dm @@ -0,0 +1,86 @@ +//No, not that kind. +/obj/structure/destructible/clockwork/trap + name = "base clockwork trap" + desc = "You shouldn't see this. File a bug report!" + clockwork_desc = "A trap that shouldn't exist, and you should report this as a bug." + var/list/wired_to + +/obj/structure/destructible/clockwork/trap/Initialize() + . = ..() + wired_to = list() + +/obj/structure/destructible/clockwork/trap/Destroy() + for(var/V in wired_to) + var/obj/structure/destructible/clockwork/trap/T = V + T.wired_to -= src + return ..() + +/obj/structure/destructible/clockwork/trap/examine(mob/user) + ..() + if(is_servant_of_ratvar(user) || isobserver(user)) + to_chat(user, "It's wired to:") + if(!wired_to.len) + to_chat(user, "Nothing.") + else + for(var/V in wired_to) + var/obj/O = V + var/distance = get_dist(src, O) + to_chat(user, "[O] ([distance == 0 ? "same tile" : "[distance] tiles [dir2text(get_dir(src, O))]"])") + +/obj/structure/destructible/clockwork/trap/wrench_act(mob/living/user, obj/item/wrench) + if(!is_servant_of_ratvar(user)) + return ..() + to_chat(user, "You break down the delicate components of [src] into brass.") + playsound(src, wrench.usesound, 50, TRUE) + new/obj/item/stack/tile/brass(get_turf(src)) + qdel(src) + return TRUE + +/obj/structure/destructible/clockwork/trap/attackby(obj/item/I, mob/living/user, params) + if(istype(I, /obj/item/clockwork/slab) && is_servant_of_ratvar(user)) + var/obj/item/clockwork/slab/F = I + if(!F.linking) + to_chat(user, "Beginning link. Alt-click the slab to cancel, or use it on another trap object to link the two.") + F.linking = src + else + if(F.linking in wired_to) + to_chat(user, "These two objects are already connected!") + return + if(F.linking.z != z) + to_chat(user, "You'd need a much tougher slab to link two objects in different sectors.") + return + to_chat(user, "You link [F.linking] with [src].") + wired_to += F.linking + F.linking.wired_to += src + F.linking = null + return + ..() + +/obj/structure/destructible/clockwork/trap/wirecutter_act(mob/living/user, obj/item/wirecutters) + if(!is_servant_of_ratvar(user)) + return + if(!wired_to.len) + to_chat(user, "[src] has no connections!") + return + to_chat(user, "You sever all connections to [src].") + playsound(src, wirecutters.usesound, 50, TRUE) + for(var/V in wired_to) + var/obj/structure/destructible/clockwork/trap/T = V + T.wired_to -= src + wired_to -= T + return TRUE + +/obj/structure/destructible/clockwork/trap/proc/activate() + +//These objects send signals to normal traps to activate +/obj/structure/destructible/clockwork/trap/trigger + name = "base trap trigger" + max_integrity = 5 + break_message = "The trigger breaks apart!" + density = FALSE + +/obj/structure/destructible/clockwork/trap/trigger/activate() + for(var/obj/structure/destructible/clockwork/trap/T in wired_to) + if(istype(T, /obj/structure/destructible/clockwork/trap/trigger)) //Triggers don't go off multiple times + continue + T.activate() diff --git a/code/game/gamemodes/clock_cult/clock_structures/ark_of_the_clockwork_justicar.dm b/code/game/gamemodes/clock_cult/clock_structures/ark_of_the_clockwork_justicar.dm index 0f13ac66ac..63fea1eeb6 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/ark_of_the_clockwork_justicar.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/ark_of_the_clockwork_justicar.dm @@ -26,6 +26,9 @@ var/fourth_sound_played = FALSE var/obj/effect/clockwork/overlay/gateway_glow/glow var/obj/effect/countdown/clockworkgate/countdown + var/last_scream = 0 + var/recalls_remaining = 1 + var/recalling /obj/structure/destructible/clockwork/massive/celestial_gateway/Initialize() . = ..() @@ -34,7 +37,21 @@ GLOB.ark_of_the_clockwork_justiciar = src START_PROCESSING(SSprocessing, src) -/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/final_countdown(ark_time) +/obj/structure/destructible/clockwork/massive/celestial_gateway/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir) + . = ..() + if(.) + flick("clockwork_gateway_damaged", glow) + playsound(src, 'sound/machines/clockcult/ark_damage.ogg', 75, FALSE) + if(last_scream < world.time) + audible_message("An unearthly screaming sound resonates throughout Reebe!") + for(var/V in GLOB.player_list) + var/mob/M = V + if(M.z == z || is_servant_of_ratvar(M) || isobserver(M)) + M.playsound_local(M, 'sound/machines/clockcult/ark_scream.ogg', 100, FALSE, pressure_affected = FALSE) + hierophant_message("The Ark is taking damage!") + last_scream = world.time + ARK_SCREAM_COOLDOWN + +/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/final_countdown(ark_time) //WE'RE LEAVING TOGETHEEEEEEEEER if(!ark_time) ark_time = 30 //minutes initial_activation_delay = ark_time * 60 @@ -58,13 +75,17 @@ active = TRUE priority_announce("Massive [Gibberish("bluespace", 100)] anomaly detected on all frequencies. All crew are directed to \ @!$, [text2ratvar("PURGE ALL UNTRUTHS")] <&. the anomalies and destroy their source to prevent further damage to corporate property. This is \ - not a drill.[grace_period ? " Estimated time of appearance: [grace_period] seconds. Use this time to prepare." : ""]", \ + not a drill.[grace_period ? " Estimated time of appearance: [grace_period] seconds. Use this time to prepare for an attack on [station_name()]." : ""]", \ "Central Command Higher Dimensional Affairs", 'sound/magic/clockwork/ark_activation.ogg') set_security_level("delta") for(var/V in SSticker.mode.servants_of_ratvar) var/datum/mind/M = V if(ishuman(M.current)) M.current.add_overlay(mutable_appearance('icons/effects/genetics.dmi', "servitude", -MUTATIONS_LAYER)) + for(var/V in GLOB.brass_recipes) + var/datum/stack_recipe/R = V + if(R.title == "wall gear") + R.time *= 2 //Building walls becomes slower when the Ark activates /obj/structure/destructible/clockwork/massive/celestial_gateway/proc/open_portal(turf/T) new/obj/effect/clockwork/city_of_cogs_rift(T) @@ -83,6 +104,25 @@ seconds_until_activation = 0 SSshuttle.registerHostileEnvironment(src) +/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/initiate_mass_recall() + recalling = TRUE + sound_to_playing_players('sound/machines/clockcult/ark_recall.ogg', 75, FALSE) + hierophant_message("The Eminence has initiated a mass recall! You are being transported to the Ark!") + addtimer(CALLBACK(src, .proc/mass_recall), 100) + +/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/mass_recall() + for(var/V in SSticker.mode.servants_of_ratvar) + var/datum/mind/M = V + if(!M.current.stat) + M.current.forceMove(get_turf(src)) + M.current.overlay_fullscreen("flash", /obj/screen/fullscreen/flash) + M.current.clear_fullscreen("flash", 5) + playsound(src, 'sound/magic/clockwork/invoke_general.ogg', 50, FALSE) + recalls_remaining-- + recalling = FALSE + transform = matrix() * 2 + animate(src, transform = matrix() * 0.5, time = 30, flags = ANIMATION_END_NOW) + /obj/structure/destructible/clockwork/massive/celestial_gateway/Destroy() STOP_PROCESSING(SSprocessing, src) SSshuttle.clearHostileEnvironment(src) @@ -117,6 +157,9 @@ countdown.stop() visible_message("[src] begins to pulse uncontrollably... you might want to run!") sound_to_playing_players(volume = 50, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/clockcult_gateway_disrupted.ogg')) + for(var/mob/M in GLOB.player_list) + if(M.z == z || is_servant_of_ratvar(M)) + M.playsound_local(M, 'sound/machines/clockcult/ark_deathrattle.ogg', 100, FALSE, pressure_affected = FALSE) make_glow() glow.icon_state = "clockwork_gateway_disrupted" resistance_flags |= INDESTRUCTIBLE diff --git a/code/game/gamemodes/clock_cult/clock_structures/eminence_spire.dm b/code/game/gamemodes/clock_cult/clock_structures/eminence_spire.dm new file mode 100644 index 0000000000..495bfaeaa8 --- /dev/null +++ b/code/game/gamemodes/clock_cult/clock_structures/eminence_spire.dm @@ -0,0 +1,132 @@ +//Used to nominate oneself or ghosts for the role of Eminence. +/obj/structure/destructible/clockwork/eminence_spire + name = "eminence spire" + desc = "A hulking machine made of powerful alloy, with three small obelisks and a huge plate in the center." + clockwork_desc = "This spire is used to become the Eminence, who functions as an invisible leader of the cult. Activate it to nominate yourself or propose that the Eminence should be \ + selected from available ghosts. Once an Eminence is selected, they can't normally be changed." + icon_state = "tinkerers_daemon" + break_message = "The spire screeches with crackling power and collapses into scrap!" + max_integrity = 400 + var/mob/eminence_nominee + var/selection_timer //Timer ID; this is canceled if the vote is canceled + var/kingmaking + +/obj/structure/destructible/clockwork/eminence_spire/attack_hand(mob/living/user) + if(!is_servant_of_ratvar(user)) + to_chat(user, "You can tell how powerful [src] is; you know better than to touch it.") + return + if(kingmaking) + return + + var/datum/antagonist/clockcult/C = user.mind.has_antag_datum(/datum/antagonist/clockcult) + if(!C || !C.clock_team) + return + if(C.clock_team.eminence) + to_chat(user, "There's already an Eminence!") + return + if(!GLOB.servants_active) + to_chat(user, "The Ark isn't active!") + return + if(eminence_nominee) //This could be one large proc, but is split into three for ease of reading + if(eminence_nominee == user) + cancelation(user) + else + objection(user) + else + nomination(user) + +/obj/structure/destructible/clockwork/eminence_spire/attack_ghost(mob/user) + if(!IsAdminGhost(user)) + return + + var/datum/antagonist/clockcult/random_cultist = locate() in GLOB.antagonists //if theres no cultists new team without eminence will be created anyway. + if(random_cultist && random_cultist.clock_team && random_cultist.clock_team.eminence) + to_chat(user, "There's already an Eminence - too late!") + return + if(!GLOB.servants_active) + to_chat(user, "The Ark must be active first!") + return + if(alert(user, "Become the Eminence using admin?", "Become Eminence", "Yes", "No") != "Yes") + return + message_admins("Admin [key_name_admin(user)] directly became the Eminence of the cult!") + log_admin("Admin [key_name(user)] made themselves the Eminence.") + var/mob/camera/eminence/eminence = new(get_turf(src)) + eminence.key = user.key + hierophant_message("Ratvar has directly assigned the Eminence!") + for(var/mob/M in servants_and_ghosts()) + M.playsound_local(M, 'sound/machines/clockcult/eminence_selected.ogg', 50, FALSE) + +/obj/structure/destructible/clockwork/eminence_spire/proc/nomination(mob/living/nominee) //A user is nominating themselves or ghosts to become Eminence + var/nomination_choice = alert(nominee, "Who would you like to nominate?", "Eminence Nomination", "Nominate Yourself", "Nominate Ghosts", "Cancel") + if(!is_servant_of_ratvar(nominee) || !nominee.canUseTopic(src) || eminence_nominee) + return + switch(nomination_choice) + if("Cancel") + return + if("Nominate Yourself") + eminence_nominee = nominee + hierophant_message("[nominee] nominates themselves as the Eminence! You may object by interacting with the eminence spire. The vote will otherwise pass in 30 seconds.") + if("Nominate Ghosts") + eminence_nominee = "ghosts" + hierophant_message("[nominee] proposes selecting an Eminence from ghosts! You may object by interacting with the eminence spire. The vote will otherwise pass in 30 seconds.") + for(var/mob/M in servants_and_ghosts()) + M.playsound_local(M, 'sound/machines/clockcult/ocularwarden-target.ogg', 50, FALSE) + selection_timer = addtimer(CALLBACK(src, .proc/kingmaker), 300, TIMER_STOPPABLE) + +/obj/structure/destructible/clockwork/eminence_spire/proc/objection(mob/living/wright) + if(alert(wright, "Object to the selection of [eminence_nominee] as Eminence?", "Objection!", "Object", "Cancel") == "Cancel" || !is_servant_of_ratvar(wright) || !wright.canUseTopic(src) || !eminence_nominee) + return + hierophant_message("[wright] objects to the nomination of [eminence_nominee]! The eminence spire has been reset.") + for(var/mob/M in servants_and_ghosts()) + M.playsound_local(M, 'sound/machines/clockcult/integration_cog_install.ogg', 50, FALSE) + eminence_nominee = null + deltimer(selection_timer) + +/obj/structure/destructible/clockwork/eminence_spire/proc/cancelation(mob/living/cold_feet) + if(alert(cold_feet, "Cancel your nomination?", "Cancel Nomination", "Withdraw Nomination", "Cancel") == "Cancel" || !is_servant_of_ratvar(cold_feet) || !cold_feet.canUseTopic(src) || !eminence_nominee) + return + hierophant_message("[eminence_nominee] has withdrawn their nomination! The eminence spire has been reset.") + for(var/mob/M in servants_and_ghosts()) + M.playsound_local(M, 'sound/machines/clockcult/integration_cog_install.ogg', 50, FALSE) + eminence_nominee = null + deltimer(selection_timer) + +/obj/structure/destructible/clockwork/eminence_spire/proc/kingmaker() + if(!eminence_nominee) + return + if(ismob(eminence_nominee)) + if(!eminence_nominee.client || !eminence_nominee.mind) + hierophant_message("[eminence_nominee] somehow lost their sentience! The eminence spire has been reset.") + for(var/mob/M in servants_and_ghosts()) + M.playsound_local(M, 'sound/machines/clockcult/integration_cog_install.ogg', 50, FALSE) + eminence_nominee = null + return + playsound(eminence_nominee, 'sound/machines/clockcult/ark_damage.ogg', 50, FALSE) + eminence_nominee.visible_message("A blast of white-hot light flows into [eminence_nominee], vaporizing them in an instant!", \ + "allthelightintheuniverseflowing.into.YOU") + for(var/obj/item/I in eminence_nominee) + eminence_nominee.dropItemToGround(I) + var/mob/camera/eminence/eminence = new(get_turf(src)) + eminence_nominee.mind.transfer_to(eminence) + eminence_nominee.dust() + hierophant_message("[eminence_nominee] has ascended into the Eminence!") + else if(eminence_nominee == "ghosts") + kingmaking = TRUE + hierophant_message("The eminence spire is now selecting a ghost to be the Eminence...") + var/list/candidates = pollGhostCandidates("Would you like to play as the servants' Eminence?", "Servant of Ratvar", null, ROLE_SERVANT_OF_RATVAR, poll_time = 100) + kingmaking = FALSE + if(!candidates.len) + for(var/mob/M in servants_and_ghosts()) + M.playsound_local(M, 'sound/machines/clockcult/integration_cog_install.ogg', 50, FALSE) + hierophant_message("No ghosts accepted the offer! The eminence spire has been reset.") + eminence_nominee = null + return + visible_message("A blast of white-hot light spirals from [src] in waves!") + playsound(src, 'sound/machines/clockcult/ark_damage.ogg', 50, FALSE) + var/mob/camera/eminence/eminence = new(get_turf(src)) + eminence_nominee = pick(candidates) + eminence.key = eminence_nominee.key + hierophant_message("A ghost has ascended into the Eminence!") + for(var/mob/M in servants_and_ghosts()) + M.playsound_local(M, 'sound/machines/clockcult/eminence_selected.ogg', 50, FALSE) + eminence_nominee = null diff --git a/code/game/gamemodes/clock_cult/clock_structures/heralds_beacon.dm b/code/game/gamemodes/clock_cult/clock_structures/heralds_beacon.dm index 9f18ff1669..2be948d7ca 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/heralds_beacon.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/heralds_beacon.dm @@ -106,3 +106,4 @@ H.set_species(/datum/species/golem/clockwork/no_scrap) var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar G.grace_period = FALSE //no grace period if we've declared war + G.recalls_remaining++ diff --git a/code/game/gamemodes/clock_cult/clock_structures/mania_motor.dm b/code/game/gamemodes/clock_cult/clock_structures/mania_motor.dm index b95d9cc0db..447b077d87 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/mania_motor.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/mania_motor.dm @@ -60,4 +60,4 @@ break if(!M) M = H.apply_status_effect(STATUS_EFFECT_MANIAMOTOR, src) - M.severity = Clamp(M.severity + ((11 - get_dist(src, H)) * efficiency * efficiency), 0, MAX_MANIA_SEVERITY) + M.severity = CLAMP(M.severity + ((11 - get_dist(src, H)) * efficiency * efficiency), 0, MAX_MANIA_SEVERITY) diff --git a/code/game/gamemodes/clock_cult/clock_structures/taunting_trail.dm b/code/game/gamemodes/clock_cult/clock_structures/taunting_trail.dm index 9d4667ee9f..e417cbbc32 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/taunting_trail.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/taunting_trail.dm @@ -57,5 +57,5 @@ L.confused = min(L.confused + 15, 50) L.dizziness = min(L.dizziness + 15, 50) if(L.confused >= 25) - L.Knockdown(Floor(L.confused * 0.8)) + L.Knockdown(FLOOR(L.confused * 0.8, 1)) take_damage(max_integrity) diff --git a/code/game/gamemodes/clock_cult/clock_structures/trap_triggers/lever.dm b/code/game/gamemodes/clock_cult/clock_structures/trap_triggers/lever.dm new file mode 100644 index 0000000000..4d11cc5f39 --- /dev/null +++ b/code/game/gamemodes/clock_cult/clock_structures/trap_triggers/lever.dm @@ -0,0 +1,14 @@ +//Lever: Do I really need to explain this? +/obj/structure/destructible/clockwork/trap/trigger/lever + name = "lever" + desc = "A fancy lever made of wood and capped with brass." + clockwork_desc = "A fancy lever.that activates when pulled." + max_integrity = 75 + icon_state = "lever" + +/obj/structure/destructible/clockwork/trap/trigger/lever/attack_hand(mob/living/user) + user.visible_message("[user] pulls [src]!", "You pull [src]. It clicks, then lifts back upwards.") + if(wired_to.len) + audible_message("You hear gears clanking.") + playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE) + activate() diff --git a/code/game/gamemodes/clock_cult/clock_structures/trap_triggers/pressure_sensor.dm b/code/game/gamemodes/clock_cult/clock_structures/trap_triggers/pressure_sensor.dm new file mode 100644 index 0000000000..f6a7b8e347 --- /dev/null +++ b/code/game/gamemodes/clock_cult/clock_structures/trap_triggers/pressure_sensor.dm @@ -0,0 +1,26 @@ +//Pressure sensor: Activates when stepped on. +/obj/structure/destructible/clockwork/trap/trigger/pressure_sensor + name = "pressure sensor" + desc = "A thin plate of brass, barely visible but clearly distinct." + clockwork_desc = "A trigger that will activate when a non-servant runs across it." + max_integrity = 25 + icon_state = "pressure_sensor" + alpha = 80 + layer = LOW_ITEM_LAYER + +/obj/structure/destructible/clockwork/trap/trigger/Initialize() + . = ..() + for(var/obj/structure/destructible/clockwork/trap/T in get_turf(src)) + if(!istype(T, /obj/structure/destructible/clockwork/trap/trigger)) + wired_to += T + T.wired_to += src + to_chat(usr, "[src] automatically links with [T] beneath it.") + +/obj/structure/destructible/clockwork/trap/trigger/pressure_sensor/Crossed(atom/movable/AM) + if(isliving(AM) && !is_servant_of_ratvar(AM)) + var/mob/living/L = AM + if(L.stat || L.m_intent == MOVE_INTENT_WALK || L.lying) + return + audible_message("*click*") + playsound(src, 'sound/items/screwdriver2.ogg', 50, TRUE) + activate() diff --git a/code/game/gamemodes/clock_cult/clock_structures/trap_triggers/repeater.dm b/code/game/gamemodes/clock_cult/clock_structures/trap_triggers/repeater.dm new file mode 100644 index 0000000000..68e8cc00e8 --- /dev/null +++ b/code/game/gamemodes/clock_cult/clock_structures/trap_triggers/repeater.dm @@ -0,0 +1,27 @@ +//Repeater: Activates every second. +/obj/structure/destructible/clockwork/trap/trigger/repeater + name = "repeater" + desc = "A small black prism with a gem in the center." + clockwork_desc = "A repeater that will send an activation signal every second." + max_integrity = 15 //Fragile! + icon_state = "repeater" + +/obj/structure/destructible/clockwork/trap/trigger/repeater/attack_hand(mob/living/user) + if(!is_servant_of_ratvar(user)) + return + if(!isprocessing) + START_PROCESSING(SSprocessing, src) + to_chat(user, "You activate [src].") + icon_state = "[icon_state]_on" + else + STOP_PROCESSING(SSprocessing, src) + to_chat(user, "You halt [src]'s ticking.") + icon_state = initial(icon_state) + +/obj/structure/destructible/clockwork/trap/trigger/repeater/process() + activate() + playsound(src, 'sound/items/screwdriver2.ogg', 25, FALSE) + +/obj/structure/destructible/clockwork/trap/trigger/repeater/Destroy() + STOP_PROCESSING(SSprocessing, src) + return ..() diff --git a/code/game/gamemodes/clock_cult/clock_structures/traps/brass_skewer.dm b/code/game/gamemodes/clock_cult/clock_structures/traps/brass_skewer.dm new file mode 100644 index 0000000000..d79ca88ecb --- /dev/null +++ b/code/game/gamemodes/clock_cult/clock_structures/traps/brass_skewer.dm @@ -0,0 +1,106 @@ +//Non-servants standing over this will get spikes through the feet, immobilizing them until they're freed. +/obj/structure/destructible/clockwork/trap/brass_skewer + name = "brass skewer" + desc = "A deadly brass spike, cleverly concealed in the floor. You think you should be safe if you disarm whatever's meant to set it off." + clockwork_desc = "A barbaric but undeniably effective weapon: a spear through the chest. It immobilizes anyone unlucky enough to step on it and keeps them in place until they get help.." + icon_state = "brass_skewer" + break_message = "The skewer snaps in two!" + max_integrity = 40 + density = FALSE + can_buckle = TRUE + buckle_prevents_pull = TRUE + buckle_lying = FALSE + var/wiggle_wiggle + var/mutable_appearance/impale_overlay //This is applied to any mob impaled so that they visibly have the skewer coming through their chest + +/obj/structure/destructible/clockwork/trap/brass_skewer/Initialize() + . = ..() + START_PROCESSING(SSfastprocess, src) + +/obj/structure/destructible/clockwork/trap/brass_skewer/Destroy() + STOP_PROCESSING(SSfastprocess, src) + if(buckled_mobs && buckled_mobs.len) + var/mob/living/L = buckled_mobs[1] + L.Knockdown(100) + L.visible_message("[L] is maimed as the skewer shatters while still in their body!") + L.adjustBruteLoss(15) + unbuckle_mob(L) + return ..() + +/obj/structure/destructible/clockwork/trap/brass_skewer/process() + if(density) + if(buckled_mobs.len) + var/mob/living/spitroast = buckled_mobs[1] + spitroast.adjustBruteLoss(0.1) + +/obj/structure/destructible/clockwork/trap/attackby(obj/item/I, mob/living/user, params) + if(user in buckled_mobs) + to_chat(user, "You can't reach!") + return + ..() + +/obj/structure/destructible/clockwork/trap/brass_skewer/bullet_act(obj/item/projectile/P) + if(buckled_mobs.len) + var/mob/living/L = buckled_mobs[1] + return L.bullet_act(P) + return ..() + +/obj/structure/destructible/clockwork/trap/brass_skewer/activate() + if(density) + return + var/mob/living/carbon/squirrel = locate() in get_turf(src) + if(squirrel) + squirrel.visible_message("A massive brass spike erupts from the ground, impaling [squirrel]!", \ + "A massive brass spike rams through your chest, hoisting you into the air!") + squirrel.emote("scream") + playsound(squirrel, 'sound/effects/splat.ogg', 50, TRUE) + playsound(squirrel, 'sound/misc/desceration-03.ogg', 50, TRUE) + squirrel.apply_damage(20, BRUTE, "chest") + mouse_opacity = MOUSE_OPACITY_OPAQUE //So players can interact with the tile it's on to pull them off + buckle_mob(squirrel, TRUE) + else + visible_message("A massive brass spike erupts from the ground!") + playsound(src, 'sound/machines/clockcult/brass_skewer.ogg', 75, FALSE) + icon_state = "[initial(icon_state)]_extended" + density = TRUE //Skewers are one-use only + desc = "A vicious brass spike protruding from the ground like a stala[pick("gm", "ct")]ite. It makes you sick to look at." //is stalagmite the ground one? or the ceiling one? who can ever remember? + +/obj/structure/destructible/clockwork/trap/brass_skewer/user_buckle_mob() + return + +/obj/structure/destructible/clockwork/trap/brass_skewer/post_buckle_mob(mob/living/L) + if(L in buckled_mobs) + L.pixel_y = 3 + impale_overlay = mutable_appearance('icons/obj/clockwork_objects.dmi', "brass_skewer_pokeybit", ABOVE_MOB_LAYER) + add_overlay(impale_overlay) + else + L.pixel_y = initial(L.pixel_y) + L.cut_overlay(impale_overlay) + +/obj/structure/destructible/clockwork/trap/brass_skewer/user_unbuckle_mob(mob/living/skewee, mob/living/user) + if(user == skewee) + if(wiggle_wiggle) + return + user.visible_message("[user] starts wriggling off of [src]!", \ + "You start agonizingly working your way off of [src]...") + wiggle_wiggle = TRUE + if(!do_after(user, 300, target = user)) + user.visible_message("[user] slides back down [src]!") + user.emote("scream") + user.apply_damage(10, BRUTE, "chest") + playsound(user, 'sound/misc/desceration-03.ogg', 50, TRUE) + wiggle_wiggle = FALSE + return + wiggle_wiggle = FALSE + else + user.visible_message("You start tenderly lifting [user] off of [src]...", \ + "You start tenderly lifting [user] off of [src]...") + if(!do_after(user, 60, target = skewee)) + skewee.visible_message("[skewee] painfully slides back down [src].") + skewee.emote("moan") + return + skewee.visible_message("[skewee] comes free of [src] with a squelching pop!", \ + "You come free of [src]!") + skewee.Knockdown(30) + playsound(skewee, 'sound/misc/desceration-03.ogg', 50, TRUE) + unbuckle_mob(skewee) diff --git a/code/game/gamemodes/clock_cult/clock_structures/traps/steam_vent.dm b/code/game/gamemodes/clock_cult/clock_structures/traps/steam_vent.dm new file mode 100644 index 0000000000..6aede1592e --- /dev/null +++ b/code/game/gamemodes/clock_cult/clock_structures/traps/steam_vent.dm @@ -0,0 +1,23 @@ +//This doesn't function like a "trap" in of itself, but obscures vision when active. +/obj/structure/destructible/clockwork/trap/steam_vent + name = "steam vent" + desc = "Some wired slats embedded in the floor. They feel warm to the touch." + icon_state = "steam_vent_0" + clockwork_desc = "When active, these vents will billow out clouds of excess steam from Reebe, obscuring vision." + break_message = "The vent snaps and collapses!" + max_integrity = 100 + density = FALSE + +/obj/structure/destructible/clockwork/trap/steam_vent/activate() + opacity = !opacity + icon_state = "steam_vent_[opacity]" + if(opacity) + playsound(src, 'sound/machines/clockcult/steam_whoosh.ogg', 50, TRUE) + + else + playsound(src, 'sound/machines/clockcult/integration_cog_install.ogg', 50, TRUE) + +/obj/structure/destructible/clockwork/trap/steam_vent/Crossed(atom/movable/AM) + if(isliving(AM) && opacity) + var/mob/living/L = AM + L.adjust_fire_stacks(-1) //It's wet! diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index f20dd25802..697a5c8eba 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -2,24 +2,23 @@ /datum/game_mode var/list/datum/mind/cult = list() - var/list/cult_objectives = list() - var/eldergod = 1 //for the summon god objective /proc/iscultist(mob/living/M) return istype(M) && M.mind && M.mind.has_antag_datum(ANTAG_DATUM_CULT) -/proc/is_sacrifice_target(datum/mind/mind) - if(mind == GLOB.sac_mind) - return TRUE +/datum/team/cult/proc/is_sacrifice_target(datum/mind/mind) + for(var/datum/objective/sacrifice/sac_objective in objectives) + if(mind == sac_objective.target) + return TRUE return FALSE -/proc/is_convertable_to_cult(mob/living/M) +/proc/is_convertable_to_cult(mob/living/M,datum/team/cult/specific_cult) if(!istype(M)) return FALSE if(M.mind) if(ishuman(M) && (M.mind.assigned_role in list("Captain", "Chaplain"))) return FALSE - if(is_sacrifice_target(M.mind)) + if(specific_cult && specific_cult.is_sacrifice_target(M.mind)) return FALSE if(M.mind.enslaved_to && !iscultist(M.mind.enslaved_to)) return FALSE @@ -55,10 +54,10 @@ var/list/cultists_to_cult = list() //the cultists we'll convert + var/datum/team/cult/main_cult + /datum/game_mode/cult/pre_setup() - cult_objectives += "sacrifice" - if(CONFIG_GET(flag/protect_roles_from_antagonist)) restricted_jobs += protected_jobs @@ -86,82 +85,19 @@ /datum/game_mode/cult/post_setup() - if("sacrifice" in cult_objectives) - var/list/possible_targets = get_unconvertables() - if(!possible_targets.len) - message_admins("Cult Sacrifice: Could not find unconvertable target, checking for convertable target.") - for(var/mob/living/carbon/human/player in GLOB.player_list) - if(player.mind && !(player.mind in cultists_to_cult)) - possible_targets += player.mind - if(possible_targets.len > 0) - GLOB.sac_mind = pick(possible_targets) - if(!GLOB.sac_mind) - message_admins("Cult Sacrifice: ERROR - Null target chosen!") - else - var/datum/job/sacjob = SSjob.GetJob(GLOB.sac_mind.assigned_role) - var/datum/preferences/sacface = GLOB.sac_mind.current.client.prefs - var/icon/reshape = get_flat_human_icon(null, sacjob, sacface) - reshape.Shift(SOUTH, 4) - reshape.Shift(EAST, 1) - reshape.Crop(7,4,26,31) - reshape.Crop(-5,-3,26,30) - GLOB.sac_image = reshape - else - message_admins("Cult Sacrifice: Could not find unconvertable or convertable target. WELP!") - if(!GLOB.summon_spots.len) - while(GLOB.summon_spots.len < SUMMON_POSSIBILITIES) - var/area/summon = pick(GLOB.sortedAreas - GLOB.summon_spots) - if((summon.z in GLOB.station_z_levels) && summon.valid_territory) - GLOB.summon_spots += summon - cult_objectives += "eldergod" - for(var/datum/mind/cult_mind in cultists_to_cult) - equip_cultist(cult_mind.current) - update_cult_icons_added(cult_mind) - to_chat(cult_mind.current, "You are a member of the cult!") - cult_mind.current.playsound_local(get_turf(cult_mind.current), 'sound/ambience/antag/bloodcult.ogg', 100, FALSE, pressure_affected = FALSE)//subject to change - add_cultist(cult_mind, 0) + add_cultist(cult_mind, 0, equip=TRUE) ..() -/datum/game_mode/proc/equip_cultist(mob/living/carbon/human/mob,tome = 0) - if(!istype(mob)) - return - if (mob.mind) - if (mob.mind.assigned_role == "Clown") - to_chat(mob, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.") - mob.dna.remove_mutation(CLOWNMUT) - if(tome) - . += cult_give_item(/obj/item/tome, mob) - else - . += cult_give_item(/obj/item/paper/talisman/supply, mob) - to_chat(mob, "These will help you start the cult on this station. Use them well, and remember - you are not the only one.
    ") - -/datum/game_mode/proc/cult_give_item(obj/item/item_path, mob/living/carbon/human/mob) - var/list/slots = list( - "backpack" = slot_in_backpack, - "left pocket" = slot_l_store, - "right pocket" = slot_r_store - ) - - var/T = new item_path(mob) - var/item_name = initial(item_path.name) - var/where = mob.equip_in_one_of_slots(T, slots) - if(!where) - to_chat(mob, "Unfortunately, you weren't able to get a [item_name]. This is very bad and you should adminhelp immediately (press F1).") - return 0 - else - to_chat(mob, "You have a [item_name] in your [where].") - if(where == "backpack") - var/obj/item/storage/B = mob.back - B.orient2hud(mob) - B.show_to(mob) - return 1 - -/datum/game_mode/proc/add_cultist(datum/mind/cult_mind, stun) //BASE +/datum/game_mode/proc/add_cultist(datum/mind/cult_mind, stun , equip = FALSE) //BASE if (!istype(cult_mind)) return 0 - if(cult_mind.add_antag_datum(ANTAG_DATUM_CULT)) + + var/datum/antagonist/cult/new_cultist = new(cult_mind) + new_cultist.give_equipment = equip + + if(cult_mind.add_antag_datum(new_cultist)) if(stun) cult_mind.current.Unconscious(100) return 1 @@ -187,25 +123,19 @@ culthud.leave_hud(cult_mind.current) set_antag_hud(cult_mind.current, null) -/datum/game_mode/cult/proc/get_unconvertables() - var/list/ucs = list() - for(var/mob/living/carbon/human/player in GLOB.player_list) - if(player.mind && !is_convertable_to_cult(player) && !(player.mind in cultists_to_cult)) - ucs += player.mind - return ucs - /datum/game_mode/cult/proc/check_cult_victory() - var/cult_fail = 0 - if(cult_objectives.Find("survive")) - cult_fail += check_survive() //the proc returns 1 if there are not enough cultists on the shuttle, 0 otherwise - if(cult_objectives.Find("eldergod")) - cult_fail += eldergod //1 by default, 0 if the elder god has been summoned at least once - if(cult_objectives.Find("sacrifice")) - if(GLOB.sac_mind && !GLOB.sac_complete) //if the target has been GLOB.sacrificed, ignore this step. otherwise, add 1 to cult_fail - cult_fail++ - return cult_fail //if any objectives aren't met, failure + return main_cult.check_cult_victory() +/datum/game_mode/cult/set_round_result() + ..() + if(check_cult_victory()) + SSticker.mode_result = "win - cult win" + SSticker.news_report = CULT_SUMMON + else + SSticker.mode_result = "loss - staff stopped the cult" + SSticker.news_report = CULT_FAILURE + /datum/game_mode/cult/proc/check_survive() var/acolytes_survived = 0 for(var/datum/mind/cult_mind in cult) @@ -218,57 +148,6 @@ return 1 -/datum/game_mode/cult/declare_completion() - - if(!check_cult_victory()) - SSticker.mode_result = "win - cult win" - to_chat(world, "The cult has succeeded! Nar-sie has snuffed out another torch in the void!") - else - SSticker.mode_result = "loss - staff stopped the cult" - to_chat(world, "The staff managed to stop the cult! Dark words and heresy are no match for Nanotrasen's finest!") - - var/text = "" - - if(cult_objectives.len) - text += "
    The cultists' objectives were:" - for(var/obj_count=1, obj_count <= cult_objectives.len, obj_count++) - var/explanation - switch(cult_objectives[obj_count]) - if("survive") - if(!check_survive()) - explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. ([acolytes_survived] escaped) Success!" - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_survive", "SUCCESS")) - SSticker.news_report = CULT_ESCAPE - else - explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. ([acolytes_survived] escaped) Fail." - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_survive", "FAIL")) - SSticker.news_report = CULT_FAILURE - if("sacrifice") - if(GLOB.sac_complete) - explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role]. Success!" - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_sacrifice", "SUCCESS")) - else - explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role]. Fail." - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_sacrifice", "FAIL")) - if("eldergod") - if(!eldergod) - explanation = "Summon Nar-Sie. The summoning can only be accomplished in [english_list(GLOB.summon_spots)].Success!" - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_narsie", "SUCCESS")) - SSticker.news_report = CULT_SUMMON - else - explanation = "Summon Nar-Sie. The summoning can only be accomplished in [english_list(GLOB.summon_spots)]Fail." - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_narsie", "FAIL")) - SSticker.news_report = CULT_FAILURE - - text += "
    Objective #[obj_count]: [explanation]" - if(cult.len) - text += "
    The cultists were:" - for(var/datum/mind/M in cult) - text += printplayer(M) - to_chat(world, text) - ..() - return 1 - /datum/game_mode/cult/generate_report() return "Some stations in your sector have reported evidence of blood sacrifice and strange magic. Ties to the Wizards' Federation have been proven not to exist, and many employees \ have disappeared; even Central Command employees light-years away have felt strange presences and at times hysterical compulsions. Interrogations point towards this being the work of \ @@ -276,41 +155,4 @@ devoted to stopping this cult. Note that holy water seems to weaken and eventually return the minds of cultists that ingest it, and mindshield implants will prevent conversion \ altogether." -/datum/game_mode/proc/datum_cult_completion() - var/text = "" - var/cult_fail = 0 - cult_fail += eldergod - if(!GLOB.sac_complete) - cult_fail++ - if(!cult_fail) - SSticker.mode_result = "win - cult win" - to_chat(world, "The cult has succeeded! Nar-sie has snuffed out another torch in the void!") - else - SSticker.mode_result = "loss - staff stopped the cult" - to_chat(world, "The staff managed to stop the cult! Dark words and heresy are no match for Nanotrasen's finest!") - if(cult_objectives.len) - text += "
    The cultists' objectives were:" - for(var/obj_count in 1 to 2) - var/explanation - switch(cult_objectives[obj_count]) - if("sacrifice") - if(GLOB.sac_mind) - if(GLOB.sac_complete) - explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role]. Success!" - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_sacrifice", "SUCCESS")) - else - explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role]. Fail." - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_sacrifice", "FAIL")) - if("eldergod") - if(!eldergod) - explanation = "Summon Nar-Sie. Success!" - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_narsie", "SUCCESS")) - SSticker.news_report = CULT_SUMMON - else - explanation = "Summon Nar-Sie. Fail." - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_narsie", "FAIL")) - SSticker.news_report = CULT_FAILURE - text += "
    Objective #[obj_count]: [explanation]" - to_chat(world, text) - #undef CULT_SCALING_COEFFICIENT diff --git a/code/game/gamemodes/cult/cult_comms.dm b/code/game/gamemodes/cult/cult_comms.dm index 530b6ebb20..b809f2419c 100644 --- a/code/game/gamemodes/cult/cult_comms.dm +++ b/code/game/gamemodes/cult/cult_comms.dm @@ -30,7 +30,7 @@ user.whisper("O bidai nabora se[pick("'","`")]sma!", language = /datum/language/common) user.whisper(html_decode(message)) var/title = "Acolyte" - var/span = "cultitalic" + var/span = "cult italic" if(user.mind && user.mind.has_antag_datum(ANTAG_DATUM_CULT_MASTER)) span = "cultlarge" if(ishuman(user)) @@ -88,19 +88,21 @@ button_icon_state = "cultvote" /datum/action/innate/cult/mastervote/IsAvailable() - if(GLOB.cult_vote_called || !ishuman(owner)) + var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + if(!C || C.cult_team.cult_vote_called || !ishuman(owner)) return FALSE return ..() /datum/action/innate/cult/mastervote/Activate() - pollCultists(owner) + var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + pollCultists(owner,C.cult_team) -/proc/pollCultists(var/mob/living/Nominee) //Cult Master Poll +/proc/pollCultists(var/mob/living/Nominee,datum/team/cult/team) //Cult Master Poll if(world.time < CULT_POLL_WAIT) to_chat(Nominee, "It would be premature to select a leader while everyone is still settling in, try again in [DisplayTimeText(CULT_POLL_WAIT-world.time)].") return - GLOB.cult_vote_called = TRUE //somebody's trying to be a master, make sure we don't let anyone else try - for(var/datum/mind/B in SSticker.mode.cult) + team.cult_vote_called = TRUE //somebody's trying to be a master, make sure we don't let anyone else try + for(var/datum/mind/B in team.members) if(B.current) B.current.update_action_buttons_icon() if(!B.current.incapacitated()) @@ -108,39 +110,39 @@ to_chat(B.current, "Acolyte [Nominee] has asserted that they are worthy of leading the cult. A vote will be called shortly.") sleep(100) var/list/asked_cultists = list() - for(var/datum/mind/B in SSticker.mode.cult) + for(var/datum/mind/B in team.members) if(B.current && B.current != Nominee && !B.current.incapacitated()) SEND_SOUND(B.current, 'sound/magic/exit_blood.ogg') asked_cultists += B.current var/list/yes_voters = pollCandidates("[Nominee] seeks to lead your cult, do you support [Nominee.p_them()]?", poll_time = 300, group = asked_cultists) if(QDELETED(Nominee) || Nominee.incapacitated()) - GLOB.cult_vote_called = FALSE - for(var/datum/mind/B in SSticker.mode.cult) + team.cult_vote_called = FALSE + for(var/datum/mind/B in team.members) if(B.current) B.current.update_action_buttons_icon() if(!B.current.incapacitated()) to_chat(B.current,"[Nominee] has died in the process of attempting to win the cult's support!") return FALSE if(!Nominee.mind) - GLOB.cult_vote_called = FALSE - for(var/datum/mind/B in SSticker.mode.cult) + team.cult_vote_called = FALSE + for(var/datum/mind/B in team.members) if(B.current) B.current.update_action_buttons_icon() if(!B.current.incapacitated()) to_chat(B.current,"[Nominee] has gone catatonic in the process of attempting to win the cult's support!") return FALSE if(LAZYLEN(yes_voters) <= LAZYLEN(asked_cultists) * 0.5) - GLOB.cult_vote_called = FALSE - for(var/datum/mind/B in SSticker.mode.cult) + team.cult_vote_called = FALSE + for(var/datum/mind/B in team.members) if(B.current) B.current.update_action_buttons_icon() if(!B.current.incapacitated()) to_chat(B.current, "[Nominee] could not win the cult's support and shall continue to serve as an acolyte.") return FALSE - GLOB.cult_mastered = TRUE + team.cult_mastered = TRUE SSticker.mode.remove_cultist(Nominee.mind, TRUE) Nominee.mind.add_antag_datum(ANTAG_DATUM_CULT_MASTER) - for(var/datum/mind/B in SSticker.mode.cult) + for(var/datum/mind/B in team.members) if(B.current) for(var/datum/action/innate/cult/mastervote/vote in B.current.actions) vote.Remove(B.current) @@ -159,6 +161,9 @@ button_icon_state = "sintouch" /datum/action/innate/cult/master/finalreck/Activate() + var/datum/antagonist/cult/antag = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + if(!antag) + return for(var/i in 1 to 4) chant(i) var/list/destinations = list() @@ -169,7 +174,7 @@ to_chat(owner, "You need more space to summon the cult!") return if(do_after(owner, 30, target = owner)) - for(var/datum/mind/B in SSticker.mode.cult) + for(var/datum/mind/B in antag.cult_team.members) if(B.current && B.current.stat != DEAD) var/turf/mobloc = get_turf(B.current) switch(i) @@ -194,7 +199,7 @@ addtimer(CALLBACK(B.current, /mob/.proc/reckon, final), 10) else return - GLOB.reckoning_complete = TRUE + antag.cult_team.reckoning_complete = TRUE Remove(owner) /mob/proc/reckon(turf/final) @@ -269,34 +274,37 @@ var/turf/T = get_turf(ranged_ability_user) if(!isturf(T)) return FALSE + + var/datum/antagonist/cult/C = caller.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + if(target in view(7, get_turf(ranged_ability_user))) - GLOB.blood_target = target + C.cult_team.blood_target = target var/area/A = get_area(target) attached_action.cooldown = world.time + attached_action.base_cooldown addtimer(CALLBACK(attached_action.owner, /mob.proc/update_action_buttons_icon), attached_action.base_cooldown) - GLOB.blood_target_image = image('icons/effects/cult_target.dmi', target, "glow", ABOVE_MOB_LAYER) - GLOB.blood_target_image.appearance_flags = RESET_COLOR - GLOB.blood_target_image.pixel_x = -target.pixel_x - GLOB.blood_target_image.pixel_y = -target.pixel_y + C.cult_team.blood_target_image = image('icons/effects/cult_target.dmi', target, "glow", ABOVE_MOB_LAYER) + C.cult_team.blood_target_image.appearance_flags = RESET_COLOR + C.cult_team.blood_target_image.pixel_x = -target.pixel_x + C.cult_team.blood_target_image.pixel_y = -target.pixel_y for(var/datum/mind/B in SSticker.mode.cult) if(B.current && B.current.stat != DEAD && B.current.client) - to_chat(B.current, "Master [ranged_ability_user] has marked [GLOB.blood_target] in the [A.name] as the cult's top priority, get there immediately!") + to_chat(B.current, "Master [ranged_ability_user] has marked [C.cult_team.blood_target] in the [A.name] as the cult's top priority, get there immediately!") SEND_SOUND(B.current, sound(pick('sound/hallucinations/over_here2.ogg','sound/hallucinations/over_here3.ogg'),0,1,75)) - B.current.client.images += GLOB.blood_target_image + B.current.client.images += C.cult_team.blood_target_image attached_action.owner.update_action_buttons_icon() remove_ranged_ability("The marking rite is complete! It will last for 90 seconds.") - GLOB.blood_target_reset_timer = addtimer(CALLBACK(GLOBAL_PROC, .proc/reset_blood_target), 900, TIMER_STOPPABLE) + C.cult_team.blood_target_reset_timer = addtimer(CALLBACK(GLOBAL_PROC, .proc/reset_blood_target,C.cult_team), 900, TIMER_STOPPABLE) return TRUE return FALSE -/proc/reset_blood_target() - for(var/datum/mind/B in SSticker.mode.cult) +/proc/reset_blood_target(datum/team/cult/team) + for(var/datum/mind/B in team.members) if(B.current && B.current.stat != DEAD && B.current.client) - if(GLOB.blood_target) + if(team.blood_target) to_chat(B.current,"The blood mark has expired!") - B.current.client.images -= GLOB.blood_target_image - QDEL_NULL(GLOB.blood_target_image) - GLOB.blood_target = null + B.current.client.images -= team.blood_target_image + QDEL_NULL(team.blood_target_image) + team.blood_target = null diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index 2adaa57a2f..f0934b524f 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -179,6 +179,13 @@ This file contains the arcane tome files. var/list/shields = list() var/area/A = get_area(src) + var/datum/antagonist/cult/user_antag = user.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + if(!user_antag) + return + + var/datum/objective/eldergod/summon_objective = locate() in user_antag.cult_team.objectives + var/datum/objective/sacrifice/sac_objective = locate() in user_antag.cult_team.objectives + if(!check_rune_turf(Turf, user)) return entered_rune_name = input(user, "Choose a rite to scribe.", "Sigils of Power") as null|anything in GLOB.rune_types @@ -196,18 +203,20 @@ This file contains the arcane tome files. A = get_area(src) if(!src || QDELETED(src) || !Adjacent(user) || user.incapacitated() || !check_rune_turf(Turf, user)) return + + //AAAAAAAAAAAAAAAH, i'm rewriting enough for now so TODO: remove this shit if(ispath(rune_to_scribe, /obj/effect/rune/narsie)) - if(!("eldergod" in SSticker.mode.cult_objectives)) + if(!summon_objective) to_chat(user, "Nar-Sie does not wish to be summoned!") return - if(!GLOB.sac_complete) + if(sac_objective && !sac_objective.check_completion()) to_chat(user, "The sacrifice is not complete. The portal would lack the power to open if you tried!") return - if(!SSticker.mode.eldergod) + if(summon_objective.check_completion()) to_chat(user, "\"I am already here. There is no need to try to summon me now.\"") return - if(!(A in GLOB.summon_spots)) - to_chat(user, "The Geometer can only be summoned where the veil is weak - in [english_list(GLOB.summon_spots)]!") + if(!(A in summon_objective.summon_spots)) + to_chat(user, "The Geometer can only be summoned where the veil is weak - in [english_list(summon_objective.summon_spots)]!") return var/confirm_final = alert(user, "This is the FINAL step to summon Nar-Sie; it is a long, painful ritual and the crew will be alerted to your presence", "Are you prepared for the final battle?", "My life for Nar-Sie!", "No") if(confirm_final == "No") @@ -215,8 +224,8 @@ This file contains the arcane tome files. return Turf = get_turf(user) A = get_area(src) - if(!(A in GLOB.summon_spots)) // Check again to make sure they didn't move - to_chat(user, "The Geometer can only be summoned where the veil is weak - in [english_list(GLOB.summon_spots)]!") + if(!(A in summon_objective.summon_spots)) // Check again to make sure they didn't move + to_chat(user, "The Geometer can only be summoned where the veil is weak - in [english_list(summon_objective.summon_spots)]!") return priority_announce("Figments from an eldritch god are being summoned by [user] into [A.map_name] from an unknown dimension. Disrupt the ritual at all costs!","Central Command Higher Dimensional Affairs", 'sound/ai/spanomalies.ogg') for(var/B in spiral_range_turfs(1, user, 1)) diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index be1c2ccaff..ff85499029 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -349,7 +349,11 @@ structure_check() searches for nearby cultist structures required for the invoca color = RUNE_COLOR_DARKRED var/mob/living/L = pick(myriad_targets) var/is_clock = is_servant_of_ratvar(L) - var/is_convertable = is_convertable_to_cult(L) + + var/mob/living/F = invokers[1] + var/datum/antagonist/cult/C = F.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + + var/is_convertable = is_convertable_to_cult(L,C.cult_team) if(L.stat != DEAD && (is_clock || is_convertable)) invocation = "Mah'weyh pleggh at e'ntrath!" ..() @@ -397,17 +401,27 @@ structure_check() searches for nearby cultist structures required for the invoca return 1 /obj/effect/rune/convert/proc/do_sacrifice(mob/living/sacrificial, list/invokers) + var/mob/living/first_invoker = invokers[1] + if(!first_invoker) + return FALSE + var/datum/antagonist/cult/C = first_invoker.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + if(!C) + return + + var/big_sac = FALSE - if((((ishuman(sacrificial) || iscyborg(sacrificial)) && sacrificial.stat != DEAD) || is_sacrifice_target(sacrificial.mind)) && invokers.len < 3) + if((((ishuman(sacrificial) || iscyborg(sacrificial)) && sacrificial.stat != DEAD) || C.cult_team.is_sacrifice_target(sacrificial.mind)) && invokers.len < 3) for(var/M in invokers) to_chat(M, "[sacrificial] is too greatly linked to the world! You need three acolytes!") log_game("Offer rune failed - not enough acolytes and target is living or sac target") return FALSE if(sacrificial.mind) GLOB.sacrificed += sacrificial.mind - if(is_sacrifice_target(sacrificial.mind)) - GLOB.sac_complete = TRUE - big_sac = TRUE + for(var/datum/objective/sacrifice/sac_objective in C.cult_team.objectives) + if(sac_objective.target == sacrificial.mind) + sac_objective.sacced = TRUE + sac_objective.update_explanation_text() + big_sac = TRUE else GLOB.sacrificed += sacrificial @@ -481,7 +495,6 @@ structure_check() searches for nearby cultist structures required for the invoca sleep(40) if(src) color = RUNE_COLOR_RED - SSticker.mode.eldergod = FALSE new /obj/singularity/narsie/large/cult(T) //Causes Nar-Sie to spawn even if the rune has been removed /obj/effect/rune/narsie/attackby(obj/I, mob/user, params) //Since the narsie rune takes a long time to make, add logging to removal. diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm index 71955e4881..e3792b6be4 100644 --- a/code/game/gamemodes/cult/talisman.dm +++ b/code/game/gamemodes/cult/talisman.dm @@ -338,7 +338,6 @@ name = "cult shackles" desc = "Shackles that bind the wrists with sinister magic." trashtype = /obj/item/restraints/handcuffs/energy/used - origin_tech = "materials=2;magnets=5" flags_1 = DROPDEL_1 /obj/item/restraints/handcuffs/energy/cult/used/dropped(mob/user) diff --git a/code/game/gamemodes/devil/game_mode.dm b/code/game/gamemodes/devil/game_mode.dm index 722c1f525e..44f3368feb 100644 --- a/code/game/gamemodes/devil/game_mode.dm +++ b/code/game/gamemodes/devil/game_mode.dm @@ -3,32 +3,6 @@ var/list/datum/mind/devils = list() var/devil_ascended = 0 // Number of arch devils on station -/datum/game_mode/proc/auto_declare_completion_sintouched() - var/text = "" - if(sintouched.len) - text += "
    The sintouched were:" - var/list/sintouchedUnique = uniqueList(sintouched) - for(var/S in sintouchedUnique) - var/datum/mind/sintouched_mind = S - text += printplayer(sintouched_mind) - text += printobjectives(sintouched_mind) - text += "
    " - text += "
    " - to_chat(world, text) - -/datum/game_mode/proc/auto_declare_completion_devils() - /var/text = "" - if(devils.len) - text += "
    The devils were:" - for(var/D in devils) - var/datum/mind/devil = D - text += printplayer(devil) - text += printdevilinfo(devil) - text += printobjectives(devil) - text += "
    " - text += "
    " - to_chat(world, text) - /datum/game_mode/proc/add_devil_objectives(datum/mind/devil_mind, quantity) var/list/validtypes = list(/datum/objective/devil/soulquantity, /datum/objective/devil/soulquality, /datum/objective/devil/sintouch, /datum/objective/devil/buy_target) for(var/i = 1 to quantity) @@ -41,18 +15,6 @@ else objective.find_target() -/datum/game_mode/proc/printdevilinfo(mob/living/ply) - var/datum/antagonist/devil/devilinfo = is_devil(ply) - if(!devilinfo) - return "Target is not a devil." - var/text = "
    The devil's true name is: [devilinfo.truename]
    " - text += "The devil's bans were:
    " - text += " [GLOB.lawlorify[LORE][devilinfo.ban]]
    " - text += " [GLOB.lawlorify[LORE][devilinfo.bane]]
    " - text += " [GLOB.lawlorify[LORE][devilinfo.obligation]]
    " - text += " [GLOB.lawlorify[LORE][devilinfo.banish]]

    " - return text - /datum/game_mode/proc/update_devil_icons_added(datum/mind/devil_mind) var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_DEVIL] hud.join_hud(devil_mind.current) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 803e73b9e0..a0e5a9f147 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -19,6 +19,7 @@ var/probability = 0 var/false_report_weight = 0 //How often will this show up incorrectly in a centcom report? var/station_was_nuked = 0 //see nuclearbomb.dm and malfunction.dm + var/nuke_off_station = 0 //Used for tracking where the nuke hit var/round_ends_with_antag_death = 0 //flags the "one verse the station" antags as such var/list/datum/mind/antag_candidates = list() // List of possible starting antags goes here var/list/restricted_jobs = list() // Jobs it doesn't make sense to be. I.E chaplain or AI cultist @@ -73,7 +74,6 @@ /datum/game_mode/proc/pre_setup() return 1 - ///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) @@ -241,55 +241,9 @@ return 0 -/datum/game_mode/proc/declare_completion() - var/clients = 0 - var/surviving_humans = 0 - var/surviving_total = 0 - var/ghosts = 0 - var/escaped_humans = 0 - var/escaped_total = 0 - - for(var/mob/M in GLOB.player_list) - if(M.client) - clients++ - if(ishuman(M)) - if(!M.stat) - surviving_humans++ - if(M.z == ZLEVEL_CENTCOM) - escaped_humans++ - if(!M.stat) - surviving_total++ - if(M.z == ZLEVEL_CENTCOM) - escaped_total++ - - - if(isobserver(M)) - ghosts++ - - if(clients) - SSblackbox.record_feedback("nested tally", "round_end_stats", clients, list("clients")) - if(ghosts) - SSblackbox.record_feedback("nested tally", "round_end_stats", ghosts, list("ghosts")) - if(surviving_humans) - SSblackbox.record_feedback("nested tally", "round_end_stats", surviving_humans, list("survivors", "human")) - if(surviving_total) - SSblackbox.record_feedback("nested tally", "round_end_stats", surviving_total, list("survivors", "total")) - if(escaped_humans) - SSblackbox.record_feedback("nested tally", "round_end_stats", escaped_humans, list("escapees", "human")) - if(escaped_total) - SSblackbox.record_feedback("nested tally", "round_end_stats", escaped_total, list("escapees", "total")) - - send2irc("Server", "Round just ended.") - if(cult.len && !istype(SSticker.mode, /datum/game_mode/cult)) - datum_cult_completion() - - return 0 - - /datum/game_mode/proc/check_win() //universal trigger to be called at mob death, nuke explosion, etc. To be called from everywhere. return 0 - /datum/game_mode/proc/send_intercept() var/intercepttext = "Central Command Status Summary
    " intercepttext += "Central Command has intercepted and partially decoded a Syndicate transmission with vital information regarding their movements. The following report outlines the most \ @@ -451,34 +405,6 @@ for (var/C in GLOB.admins) to_chat(C, msg) -/datum/game_mode/proc/printplayer(datum/mind/ply, fleecheck) - var/text = "
    [ply.key] was [ply.name] the [ply.assigned_role] and" - if(ply.current) - if(ply.current.stat == DEAD) - text += " died" - else - text += " survived" - if(fleecheck) - var/turf/T = get_turf(ply.current) - if(!T || !(T.z in GLOB.station_z_levels)) - text += " while fleeing the station" - if(ply.current.real_name != ply.name) - text += " as [ply.current.real_name]" - else - text += " had their body destroyed" - return text - -/datum/game_mode/proc/printobjectives(datum/mind/ply) - var/text = "" - var/count = 1 - for(var/datum/objective/objective in ply.objectives) - if(objective.check_completion()) - text += "
    Objective #[count]: [objective.explanation_text] Success!" - else - text += "
    Objective #[count]: [objective.explanation_text] Fail." - count++ - return text - //If the configuration option is set to require players to be logged as old enough to play certain jobs, then this proc checks that they are, otherwise it just returns 1 /datum/game_mode/proc/age_check(client/C) if(get_remaining_days(C) == 0) @@ -518,15 +444,25 @@ station_goals += new picked -/datum/game_mode/proc/declare_station_goal_completion() - for(var/V in station_goals) - var/datum/station_goal/G = V - G.print_result() - /datum/game_mode/proc/generate_report() //Generates a small text blurb for the gamemode in centcom report return "Gamemode report for [name] not set. Contact a coder." //By default nuke just ends the round /datum/game_mode/proc/OnNukeExplosion(off_station) + nuke_off_station = off_station if(off_station < 2) station_was_nuked = TRUE //Will end the round on next check. + +//Additional report section in roundend report +/datum/game_mode/proc/special_report() + return + +//Set result and news report here +/datum/game_mode/proc/set_round_result() + SSticker.mode_result = "undefined" + if(station_was_nuked) + SSticker.news_report = STATION_DESTROYED_NUKE + if(EMERGENCY_ESCAPED_OR_ENDGAMED) + SSticker.news_report = STATION_EVACUATED + if(SSshuttle.emergency.is_hijacked()) + SSticker.news_report = SHUTTLE_HIJACK \ No newline at end of file diff --git a/code/game/gamemodes/gang/gang_pen.dm b/code/game/gamemodes/gang/gang_pen.dm index 5df405fa4d..c410d7d7da 100644 --- a/code/game/gamemodes/gang/gang_pen.dm +++ b/code/game/gamemodes/gang/gang_pen.dm @@ -2,7 +2,6 @@ * Gang Boss Pens */ /obj/item/pen/gang - origin_tech = "materials=2;syndicate=3" var/cooldown var/last_used = 0 var/charges = 1 diff --git a/code/game/gamemodes/gang/recaller.dm b/code/game/gamemodes/gang/recaller.dm index 120e3a6345..f578ac3d3d 100644 --- a/code/game/gamemodes/gang/recaller.dm +++ b/code/game/gamemodes/gang/recaller.dm @@ -11,7 +11,6 @@ throw_speed = 3 throw_range = 7 flags_1 = CONDUCT_1 - origin_tech = "programming=5;bluespace=2;syndicate=5" var/datum/gang/gang //Which gang uses this? var/recalling = 0 var/outfits = 2 diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index 9be9e59cab..1c17893a28 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -734,6 +734,33 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list( owner.playsound_local(owner, "sparks", 50, 0) +//Disable Emergency Lights +/datum/AI_Module/small/emergency_lights + module_name = "Disable Emergency Lights" + mod_pick_name = "disable_emergency_lights" + description = "Cuts emergency lights across the entire station. If power is lost to light fixtures, they will not attempt to fall back on emergency power reserves." + cost = 10 + one_purchase = TRUE + power_type = /datum/action/innate/ai/emergency_lights + unlock_text = "You hook into the powernet and locate the connections between light fixtures and their fallbacks." + unlock_sound = "sparks" + +/datum/action/innate/ai/emergency_lights + name = "Disable Emergency Lights" + desc = "Disables all emergency lighting. Note that emergency lights can be restored through reboot at an APC." + button_icon_state = "emergency_lights" + uses = 1 + +/datum/action/innate/ai/emergency_lights/Activate() + for(var/obj/machinery/light/L in GLOB.machines) + if(L.z in GLOB.station_z_levels) + L.no_emergency = TRUE + INVOKE_ASYNC(L, /obj/machinery/light/.proc/update, FALSE) + CHECK_TICK + to_chat(owner, "Emergency light connections severed.") + owner.playsound_local(owner, 'sound/effects/light_flicker.ogg', 50, FALSE) + + //Reactivate Camera Network: Reactivates up to 30 cameras across the station. /datum/AI_Module/small/reactivate_cameras module_name = "Reactivate Camera Network" diff --git a/code/game/gamemodes/meteor/meteor.dm b/code/game/gamemodes/meteor/meteor.dm index b7a6580570..efe6dc69e9 100644 --- a/code/game/gamemodes/meteor/meteor.dm +++ b/code/game/gamemodes/meteor/meteor.dm @@ -25,35 +25,34 @@ if (prob(meteorminutes/2)) wavetype = GLOB.meteors_catastrophic - var/ramp_up_final = Clamp(round(meteorminutes/rampupdelta), 1, 10) + var/ramp_up_final = CLAMP(round(meteorminutes/rampupdelta), 1, 10) spawn_meteors(ramp_up_final, wavetype) -/datum/game_mode/meteor/declare_completion() - var/text +/datum/game_mode/meteor/special_report() var/survivors = 0 + var/list/survivor_list = list() for(var/mob/living/player in GLOB.player_list) if(player.stat != DEAD) ++survivors if(player.onCentCom()) - text += "
    [player.real_name] escaped to the safety of CentCom." + survivor_list += "[player.real_name] escaped to the safety of CentCom." else if(player.onSyndieBase()) - text += "
    [player.real_name] escaped to the (relative) safety of Syndicate Space." + survivor_list += "[player.real_name] escaped to the (relative) safety of Syndicate Space." else - text += "
    [player.real_name] survived but is stranded without any hope of rescue." - + survivor_list += "[player.real_name] survived but is stranded without any hope of rescue." if(survivors) - to_chat(world, "The following survived the meteor storm:[text]") + return "The following survived the meteor storm:
    [survivor_list.Join("
    ")]" else - to_chat(world, "Nobody survived the meteor storm!") + return "Nobody survived the meteor storm!" - SSticker.mode_result = "end - evacuation" +/datum/game_mode/meteor/set_round_result() ..() - return 1 + SSticker.mode_result = "end - evacuation" /datum/game_mode/meteor/generate_report() return "[pick("Asteroids have", "Meteors have", "Large rocks have", "Stellar minerals have", "Space hail has", "Debris has")] been detected near your station, and a collision is possible, \ diff --git a/code/game/gamemodes/miniantags/abduction/abduction.dm b/code/game/gamemodes/miniantags/abduction/abduction.dm index 4eb8642c02..f9e8f8d752 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction.dm @@ -1,19 +1,5 @@ -/datum/objective_team/abductor_team - member_name = "abductor" - var/list/objectives = list() - var/team_number - -/datum/objective_team/abductor_team/is_solo() - return FALSE - -/datum/objective_team/abductor_team/proc/add_objective(datum/objective/O) - O.team = src - O.update_explanation_text() - objectives += O - /datum/game_mode var/list/datum/mind/abductors = list() - var/list/datum/mind/abductees = list() /datum/game_mode/abduction name = "abduction" @@ -24,7 +10,7 @@ required_players = 15 maximum_players = 50 var/max_teams = 4 - var/list/datum/objective_team/abductor_team/abductor_teams = list() + var/list/datum/team/abductor_team/abductor_teams = list() var/finished = FALSE var/static/team_count = 0 @@ -51,7 +37,7 @@ if(team_number > max_teams) return //or should it try to stuff them in anway ? - var/datum/objective_team/abductor_team/team = new + var/datum/team/abductor_team/team = new team.team_number = team_number team.name = "Mothership [pick(GLOB.possible_changeling_IDs)]" //TODO Ensure unique and actual alieny names team.add_objective(new/datum/objective/experiment) @@ -64,6 +50,7 @@ antag_candidates -= scientist team.members |= scientist scientist.assigned_role = "Abductor Scientist" + scientist.special_role = "Abductor Scientist" log_game("[scientist.key] (ckey) has been selected as [team.name] abductor scientist.") if(!agent) @@ -71,18 +58,19 @@ antag_candidates -= agent team.members |= agent agent.assigned_role = "Abductor Agent" + agent.special_role = "Abductor Agent" log_game("[agent.key] (ckey) has been selected as [team.name] abductor agent.") abductor_teams += team return team /datum/game_mode/abduction/post_setup() - for(var/datum/objective_team/abductor_team/team in abductor_teams) + for(var/datum/team/abductor_team/team in abductor_teams) post_setup_team(team) return ..() //Used for create antag buttons -/datum/game_mode/abduction/proc/post_setup_team(datum/objective_team/abductor_team/team) +/datum/game_mode/abduction/proc/post_setup_team(datum/team/abductor_team/team) for(var/datum/mind/M in team.members) if(M.assigned_role == "Abductor Scientist") M.add_antag_datum(ANTAG_DATUM_ABDUCTOR_SCIENTIST, team) @@ -91,7 +79,7 @@ /datum/game_mode/abduction/check_finished() if(!finished) - for(var/datum/objective_team/abductor_team/team in abductor_teams) + for(var/datum/team/abductor_team/team in abductor_teams) for(var/datum/objective/O in team.objectives) if(O.check_completion()) SSshuttle.emergency.request(null, set_coefficient = 0.5) @@ -99,35 +87,6 @@ return ..() return ..() -/datum/game_mode/abduction/declare_completion() - for(var/datum/objective_team/abductor_team/team in abductor_teams) - var/won = TRUE - for(var/datum/objective/O in team.objectives) - if(!O.check_completion()) - won = FALSE - if(won) - to_chat(world, "[team.name] team fulfilled its mission!") - else - to_chat(world, "[team.name] team failed its mission.") - ..() - return TRUE - -/datum/game_mode/proc/auto_declare_completion_abduction() - var/text = "" - if(abductors.len) - text += "
    The abductors were:" - for(var/datum/mind/abductor_mind in abductors) - text += printplayer(abductor_mind) - text += printobjectives(abductor_mind) - text += "
    " - if(abductees.len) - text += "
    The abductees were:" - for(var/datum/mind/abductee_mind in abductees) - text += printplayer(abductee_mind) - text += printobjectives(abductee_mind) - text += "
    " - to_chat(world, text) - // LANDMARKS /obj/effect/landmark/abductor var/team_number = 1 @@ -144,9 +103,9 @@ /datum/objective/experiment/check_completion() for(var/obj/machinery/abductor/experiment/E in GLOB.machines) - if(!istype(team, /datum/objective_team/abductor_team)) + if(!istype(team, /datum/team/abductor_team)) return FALSE - var/datum/objective_team/abductor_team/T = team + var/datum/team/abductor_team/T = team if(E.team_number == T.team_number) return E.points >= target_amount return FALSE diff --git a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm index f136abdfcb..3e7e5f01ef 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm @@ -2,6 +2,8 @@ #define VEST_COMBAT 2 #define GIZMO_SCAN 1 #define GIZMO_MARK 2 +#define MIND_DEVICE_MESSAGE 1 +#define MIND_DEVICE_CONTROL 2 //AGENT VEST /obj/item/clothing/suit/armor/abductor/vest @@ -11,7 +13,6 @@ icon_state = "vest_stealth" item_state = "armor" blood_overlay_type = "armor" - origin_tech = "magnets=7;biotech=4;powerstorage=4;abductor=4" armor = list(melee = 15, bullet = 15, laser = 15, energy = 15, bomb = 15, bio = 15, rad = 15, fire = 70, acid = 70) actions_types = list(/datum/action/item_action/hands_free/activate) allowed = list( @@ -155,7 +156,6 @@ item_state = "silencer" lefthand_file = 'icons/mob/inhands/antag/abductor_lefthand.dmi' righthand_file = 'icons/mob/inhands/antag/abductor_righthand.dmi' - origin_tech = "engineering=7;magnets=4;bluespace=4;abductor=3" var/mode = GIZMO_SCAN var/mob/living/marked = null var/obj/machinery/abductor/console/console @@ -244,7 +244,6 @@ item_state = "gizmo" lefthand_file = 'icons/mob/inhands/antag/abductor_lefthand.dmi' righthand_file = 'icons/mob/inhands/antag/abductor_righthand.dmi' - origin_tech = "materials=4;programming=7;abductor=3" /obj/item/device/abductor/silencer/attack(mob/living/M, mob/user) if(!AbductorCheck(user)) @@ -281,6 +280,84 @@ if(!istype(I, /obj/item/device/radio/headset)) r.broadcasting = 0 //goddamned headset hacks +/obj/item/device/abductor/mind_device + name = "mental interface device" + desc = "A dual-mode tool for directly communicating with sentient brains. It can be used to send a direct message to a target, \ + or to send a command to a test subject with a charged gland." + icon_state = "mind_device_message" + item_state = "silencer" + lefthand_file = 'icons/mob/inhands/antag/abductor_lefthand.dmi' + righthand_file = 'icons/mob/inhands/antag/abductor_righthand.dmi' + var/mode = MIND_DEVICE_MESSAGE + +/obj/item/device/abductor/mind_device/attack_self(mob/user) + if(!ScientistCheck(user)) + return + + if(mode == MIND_DEVICE_MESSAGE) + mode = MIND_DEVICE_CONTROL + icon_state = "mind_device_control" + else + mode = MIND_DEVICE_MESSAGE + icon_state = "mind_device_message" + to_chat(user, "You switch the device to [mode==MIND_DEVICE_MESSAGE? "TRANSMISSION": "COMMAND"] MODE") + +/obj/item/device/abductor/mind_device/afterattack(atom/target, mob/living/user, flag, params) + if(!ScientistCheck(user)) + return + + switch(mode) + if(MIND_DEVICE_CONTROL) + mind_control(target, user) + if(MIND_DEVICE_MESSAGE) + mind_message(target, user) + +/obj/item/device/abductor/mind_device/proc/mind_control(atom/target, mob/living/user) + if(iscarbon(target)) + var/mob/living/carbon/C = target + var/obj/item/organ/heart/gland/G = C.getorganslot("heart") + if(!istype(G)) + to_chat(user, "Your target does not have an experimental gland!") + return + if(!G.mind_control_uses) + to_chat(user, "Your target's gland is spent!") + return + if(G.active_mind_control) + to_chat(user, "Your target is already under a mind-controlling influence!") + return + + var/command = stripped_input(user, "Enter the command for your target to follow.\ + Uses Left: [G.mind_control_uses], Duration: [G.mind_control_duration / 10] seconds","Enter command") + + if(!command) + return + + if(QDELETED(user) || user.get_active_held_item() != src || loc != user) + return + + if(QDELETED(G)) + return + + G.mind_control(command, user) + to_chat(user, "You send the command to your target.") + +/obj/item/device/abductor/mind_device/proc/mind_message(atom/target, mob/living/user) + if(isliving(target)) + var/mob/living/L = target + if(L.stat == DEAD) + to_chat(user, "Your target is dead!") + return + var/message = stripped_input(user, "Write a message to send to your target's brain.","Enter message") + if(!message) + return + if(QDELETED(L) || L.stat == DEAD) + return + + to_chat(L, "You hear a voice in your head saying: [message]") + to_chat(user, "You send the message to your target.") + log_talk(user,"[key_name(user)] sent an abductor mind message to [L]/[L.ckey]: '[message]'", LOGSAY) + + /obj/item/device/firing_pin/abductor name = "alien firing pin" icon_state = "firing_pin_ayy" @@ -299,7 +376,6 @@ pin = /obj/item/device/firing_pin/abductor icon_state = "alienpistol" item_state = "alienpistol" - origin_tech = "combat=4;magnets=7;powerstorage=3;abductor=3" trigger_guard = TRIGGER_GUARD_ALLOW_ALL /obj/item/paper/guides/antag/abductor @@ -346,7 +422,6 @@ Congratulations! You are now trained for invasive xenobiology research!"} lefthand_file = 'icons/mob/inhands/antag/abductor_lefthand.dmi' righthand_file = 'icons/mob/inhands/antag/abductor_righthand.dmi' slot_flags = SLOT_BELT - origin_tech = "materials=4;combat=4;biotech=7;abductor=4" force = 7 w_class = WEIGHT_CLASS_NORMAL actions_types = list(/datum/action/item_action/toggle_mode) @@ -496,7 +571,6 @@ Congratulations! You are now trained for invasive xenobiology research!"} righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' breakouttime = 450 trashtype = /obj/item/restraints/handcuffs/energy/used - origin_tech = "materials=4;magnets=5;abductor=2" /obj/item/restraints/handcuffs/energy/used flags_1 = DROPDEL_1 @@ -524,7 +598,6 @@ Congratulations! You are now trained for invasive xenobiology research!"} /obj/item/device/radio/headset/abductor name = "alien headset" desc = "An advanced alien headset designed to monitor communications of human space stations. Why does it have a microphone? No one knows." - origin_tech = "magnets=2;abductor=3" icon = 'icons/obj/abductor.dmi' icon_state = "abductor_headset" item_state = "abductor_headset" @@ -545,35 +618,30 @@ Congratulations! You are now trained for invasive xenobiology research!"} name = "alien scalpel" desc = "It's a gleaming sharp knife made out of silvery-green metal." icon = 'icons/obj/abductor.dmi' - origin_tech = "materials=2;biotech=2;abductor=2" toolspeed = 0.25 /obj/item/hemostat/alien name = "alien hemostat" desc = "You've never seen this before." icon = 'icons/obj/abductor.dmi' - origin_tech = "materials=2;biotech=2;abductor=2" toolspeed = 0.25 /obj/item/retractor/alien name = "alien retractor" desc = "You're not sure if you want the veil pulled back." icon = 'icons/obj/abductor.dmi' - origin_tech = "materials=2;biotech=2;abductor=2" toolspeed = 0.25 /obj/item/circular_saw/alien name = "alien saw" desc = "Do the aliens also lose this, and need to find an alien hatchet?" icon = 'icons/obj/abductor.dmi' - origin_tech = "materials=2;biotech=2;abductor=2" toolspeed = 0.25 /obj/item/surgicaldrill/alien name = "alien drill" desc = "Maybe alien surgeons have finally found a use for the drill." icon = 'icons/obj/abductor.dmi' - origin_tech = "materials=2;biotech=2;abductor=2" toolspeed = 0.25 /obj/item/cautery/alien @@ -581,7 +649,6 @@ Congratulations! You are now trained for invasive xenobiology research!"} desc = "Why would bloodless aliens have a tool to stop bleeding? \ Unless..." icon = 'icons/obj/abductor.dmi' - origin_tech = "materials=2;biotech=2;abductor=2" toolspeed = 0.25 /obj/item/clothing/head/helmet/abductor @@ -590,7 +657,6 @@ Congratulations! You are now trained for invasive xenobiology research!"} icon_state = "alienhelmet" item_state = "alienhelmet" blockTracking = 1 - origin_tech = "materials=7;magnets=4;abductor=3" flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR // Operating Table / Beds / Lockers @@ -698,31 +764,8 @@ Congratulations! You are now trained for invasive xenobiology research!"} /obj/structure/door_assembly/door_assembly_abductor name = "alien airlock assembly" icon = 'icons/obj/doors/airlocks/abductor/abductor_airlock.dmi' + base_name = "alien airlock" overlays_file = 'icons/obj/doors/airlocks/abductor/overlays.dmi' - typetext = "abductor" - icontext = "abductor" airlock_type = /obj/machinery/door/airlock/abductor - anchored = TRUE - state = 1 - -/obj/structure/door_assembly/door_assembly_abductor/attackby(obj/item/W, mob/user, params) - 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 airlock assembly.", \ - "You start to disassemble the airlock assembly...") - playsound(src.loc, 'sound/items/welder2.ogg', 50, 1) - if(do_after(user, 40*W.toolspeed, target = src)) - if( !WT.isOn() ) - return - to_chat(user, "You disassemble the airlock assembly.") - new /obj/item/stack/sheet/mineral/abductor(get_turf(src), 4) - qdel(src) - else - return - else if(istype(W, /obj/item/airlock_painter)) - return // no repainting - else if(istype(W, /obj/item/stack/sheet)) - return // no material modding - else - ..() + material_type = /obj/item/stack/sheet/mineral/abductor + noglass = TRUE diff --git a/code/game/gamemodes/miniantags/abduction/gland.dm b/code/game/gamemodes/miniantags/abduction/gland.dm index 20bd7c9df2..508f4e9f13 100644 --- a/code/game/gamemodes/miniantags/abduction/gland.dm +++ b/code/game/gamemodes/miniantags/abduction/gland.dm @@ -4,7 +4,6 @@ icon = 'icons/obj/abductor.dmi' icon_state = "gland" status = ORGAN_ROBOTIC - origin_tech = "materials=4;biotech=7;abductor=3" beating = TRUE var/cooldown_low = 300 var/cooldown_high = 300 @@ -13,28 +12,68 @@ var/human_only = 0 var/active = 0 + var/mind_control_uses = 1 + var/mind_control_duration = 1800 + var/active_mind_control = FALSE + /obj/item/organ/heart/gland/proc/ownerCheck() if(ishuman(owner)) - return 1 + return TRUE if(!human_only && iscarbon(owner)) - return 1 - return 0 + return TRUE + return FALSE /obj/item/organ/heart/gland/proc/Start() active = 1 next_activation = world.time + rand(cooldown_low,cooldown_high) +/obj/item/organ/heart/gland/proc/update_gland_hud() + if(!owner) + return + var/image/holder = owner.hud_list[GLAND_HUD] + var/icon/I = icon(owner.icon, owner.icon_state, owner.dir) + holder.pixel_y = I.Height() - world.icon_size + if(active_mind_control) + holder.icon_state = "hudgland_active" + else if(mind_control_uses) + holder.icon_state = "hudgland_ready" + else + holder.icon_state = "hudgland_spent" -/obj/item/organ/heart/gland/Remove(var/mob/living/carbon/M, special = 0) +/obj/item/organ/heart/gland/proc/mind_control(command, mob/living/user) + if(!ownerCheck() || !mind_control_uses || active_mind_control) + return + mind_control_uses-- + to_chat(owner, "You suddenly feel an irresistible compulsion to follow an order...") + to_chat(owner, "[command]") + active_mind_control = TRUE + log_admin("[key_name(user)] sent an abductor mind control message to [key_name(owner)]: [command]") + update_gland_hud() + + addtimer(CALLBACK(src, .proc/clear_mind_control), mind_control_duration) + +/obj/item/organ/heart/gland/proc/clear_mind_control() + if(!ownerCheck() || !active_mind_control) + return + to_chat(owner, "You feel the compulsion fade, and you completely forget about your previous orders.") + active_mind_control = FALSE + +/obj/item/organ/heart/gland/Remove(mob/living/carbon/M, special = 0) active = 0 if(initial(uses) == 1) uses = initial(uses) + var/datum/atom_hud/abductor/hud = GLOB.huds[DATA_HUD_ABDUCTOR] + hud.remove_from_hud(owner) + clear_mind_control() ..() -/obj/item/organ/heart/gland/Insert(var/mob/living/carbon/M, special = 0) +/obj/item/organ/heart/gland/Insert(mob/living/carbon/M, special = 0) ..() if(special != 2 && uses) // Special 2 means abductor surgery Start() + var/datum/atom_hud/abductor/hud = GLOB.huds[DATA_HUD_ABDUCTOR] + hud.add_to_hud(owner) + update_gland_hud() /obj/item/organ/heart/gland/on_life() if(!beating) @@ -60,6 +99,8 @@ cooldown_high = 400 uses = -1 icon_state = "health" + mind_control_uses = 3 + mind_control_duration = 3000 /obj/item/organ/heart/gland/heals/activate() to_chat(owner, "You feel curiously revitalized.") @@ -72,6 +113,8 @@ cooldown_high = 1200 uses = -1 icon_state = "slime" + mind_control_uses = 1 + mind_control_duration = 2400 /obj/item/organ/heart/gland/slime/activate() to_chat(owner, "You feel nauseous!") @@ -83,11 +126,12 @@ Slime.Leader = owner /obj/item/organ/heart/gland/mindshock - origin_tech = "materials=4;biotech=4;magnets=6;abductor=3" cooldown_low = 300 cooldown_high = 300 uses = -1 icon_state = "mindshock" + mind_control_uses = 1 + mind_control_duration = 6000 /obj/item/organ/heart/gland/mindshock/activate() to_chat(owner, "You get a headache.") @@ -105,6 +149,8 @@ uses = -1 human_only = 1 icon_state = "species" + mind_control_uses = 5 + mind_control_duration = 300 /obj/item/organ/heart/gland/pop/activate() to_chat(owner, "You feel unlike yourself.") @@ -112,11 +158,12 @@ owner.set_species(species) /obj/item/organ/heart/gland/ventcrawling - origin_tech = "materials=4;biotech=5;bluespace=4;abductor=3" cooldown_low = 1800 cooldown_high = 2400 uses = 1 icon_state = "vent" + mind_control_uses = 4 + mind_control_duration = 1800 /obj/item/organ/heart/gland/ventcrawling/activate() to_chat(owner, "You feel very stretchy.") @@ -128,6 +175,8 @@ cooldown_high = 2400 uses = 1 icon_state = "viral" + mind_control_uses = 1 + mind_control_duration = 1800 /obj/item/organ/heart/gland/viral/activate() to_chat(owner, "You feel sick.") @@ -140,11 +189,12 @@ /obj/item/organ/heart/gland/emp //TODO : Replace with something more interesting - origin_tech = "materials=4;biotech=4;magnets=6;abductor=3" cooldown_low = 900 cooldown_high = 1600 uses = 10 icon_state = "emp" + mind_control_uses = 1 + mind_control_duration = 1800 /obj/item/organ/heart/gland/emp/activate() to_chat(owner, "You feel a spike of pain in your head.") @@ -155,6 +205,8 @@ cooldown_high = 900 uses = 10 icon_state = "spider" + mind_control_uses = 2 + mind_control_duration = 2400 /obj/item/organ/heart/gland/spiderman/activate() to_chat(owner, "You feel something crawling in your skin.") @@ -168,6 +220,8 @@ icon_state = "egg" lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi' + mind_control_uses = 2 + mind_control_duration = 1800 /obj/item/organ/heart/gland/egg/activate() to_chat(owner, "You lay an egg!") @@ -179,6 +233,8 @@ cooldown_low = 200 cooldown_high = 400 uses = -1 + mind_control_uses = 1 + mind_control_duration = 450 /obj/item/organ/heart/gland/bloody/activate() owner.blood_volume -= 20 @@ -196,6 +252,8 @@ cooldown_high = 600 human_only = 1 uses = 1 + mind_control_uses = 1 + mind_control_duration = 600 /obj/item/organ/heart/gland/bodysnatch/activate() to_chat(owner, "You feel something moving around inside you...") @@ -229,15 +287,16 @@ STOP_PROCESSING(SSobj, src) for(var/mob/M in contents) src.visible_message("[src] hatches!") - M.loc = src.loc + M.forceMove(drop_location()) qdel(src) /obj/item/organ/heart/gland/plasma cooldown_low = 1200 cooldown_high = 1800 - origin_tech = "materials=4;biotech=4;plasmatech=6;abductor=3" uses = -1 + mind_control_uses = 1 + mind_control_duration = 800 /obj/item/organ/heart/gland/plasma/activate() to_chat(owner, "You feel bloated.") diff --git a/code/game/gamemodes/miniantags/abduction/machinery/console.dm b/code/game/gamemodes/miniantags/abduction/machinery/console.dm index f243f161c3..0b13c359eb 100644 --- a/code/game/gamemodes/miniantags/abduction/machinery/console.dm +++ b/code/game/gamemodes/miniantags/abduction/machinery/console.dm @@ -48,6 +48,7 @@ dat += "Agent Vest
    " dat += "Radio Silencer
    " dat += "Science Tool
    " + dat += "Mental Interface Device
    " else dat += "NO EXPERIMENT MACHINE DETECTED
    " @@ -109,6 +110,8 @@ Dispense(/obj/item/device/abductor/gizmo) if("vest") Dispense(/obj/item/clothing/suit/armor/abductor/vest) + if("mind_device") + Dispense(/obj/item/device/abductor/mind_device,cost=2) updateUsrDialog() /obj/machinery/abductor/console/proc/TeleporterRetrieve() diff --git a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm index da445b94ce..cf1329aec9 100644 --- a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm +++ b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm @@ -151,13 +151,18 @@ var/mob/living/mob_occupant = occupant if(mob_occupant.stat != DEAD) if(href_list["experiment"]) - flash = Experiment(occupant,href_list["experiment"]) + flash = Experiment(occupant,href_list["experiment"],usr) updateUsrDialog() add_fingerprint(usr) -/obj/machinery/abductor/experiment/proc/Experiment(mob/occupant,type) +/obj/machinery/abductor/experiment/proc/Experiment(mob/occupant,type,mob/user) LAZYINITLIST(history) var/mob/living/carbon/human/H = occupant + + var/datum/antagonist/abductor/user_abductor = user.mind.has_antag_datum(/datum/antagonist/abductor) + if(!user_abductor) + return "Authorization failure. Contact mothership immidiately." + var/point_reward = 0 if(H in history) return "Specimen already in database." @@ -182,14 +187,8 @@ if(3) to_chat(H, "You feel intensely watched.") sleep(5) - to_chat(H, "Your mind snaps!") - to_chat(H, "You can't remember how you got here...") - var/objtype = (prob(75) ? /datum/objective/abductee/random : pick(subtypesof(/datum/objective/abductee/) - /datum/objective/abductee/random)) - var/datum/objective/abductee/O = new objtype() - SSticker.mode.abductees += H.mind - H.mind.objectives += O - H.mind.announce_objectives() - SSticker.mode.update_abductor_icons_added(H.mind) + user_abductor.team.abductees += H.mind + H.mind.add_antag_datum(/datum/antagonist/abductee) for(var/obj/item/organ/heart/gland/G in H.internal_organs) G.Start() diff --git a/code/game/gamemodes/miniantags/borer/borer.dm b/code/game/gamemodes/miniantags/borer/borer.dm index f80a5e3402..4bcbaa455e 100644 --- a/code/game/gamemodes/miniantags/borer/borer.dm +++ b/code/game/gamemodes/miniantags/borer/borer.dm @@ -40,7 +40,7 @@ to_chat(src, "You begin doggedly resisting the parasite's control (this will take approximately 40 seconds).") to_chat(B.victim, "You feel the captive mind of [src] begin to resist your control.") - var/delay = rand(150,250) + B.victim.brainloss + var/delay = rand(150,250) + B.victim.getBrainLoss() addtimer(CALLBACK(src, .proc/return_control, src.loc), delay) /mob/living/captive_brain/proc/return_control(mob/living/simple_animal/borer/B) @@ -315,7 +315,7 @@ GLOBAL_VAR_INIT(total_borer_hosts_needed, 10) if(prob(5)) victim.adjustBrainLoss(rand(1,2)) - if(prob(victim.brainloss/10)) + if(prob(victim.getBrainLoss()/10)) victim.say("*[pick(list("blink","blink_r","choke","aflap","drool","twitch","twitch_s","gasp"))]") /mob/living/simple_animal/borer/proc/wakeup() @@ -669,7 +669,7 @@ GLOBAL_VAR_INIT(total_borer_hosts_needed, 10) bonding = TRUE - var/delay = 200+(victim.brainloss*5) + var/delay = 200+(victim.getBrainLoss()*5) addtimer(CALLBACK(src, .proc/assume_control), delay) /mob/living/simple_animal/borer/proc/assume_control() diff --git a/code/game/gamemodes/miniantags/borer/borer_event.dm b/code/game/gamemodes/miniantags/borer/borer_event.dm index 6875a97db5..567adddf53 100644 --- a/code/game/gamemodes/miniantags/borer/borer_event.dm +++ b/code/game/gamemodes/miniantags/borer/borer_event.dm @@ -1,8 +1,8 @@ /datum/round_event_control/borer name = "Borer" typepath = /datum/round_event/borer - weight = 10 //Default weight - max_occurrences = 1 + weight = 0 + max_occurrences = 0 min_players = 20 //10 is MINIMUM needed, but this is not a gamemode that does well in lowpop earliest_start = 24000 //40 min, double default timer diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm index e4e4205db8..3fe32a7f33 100644 --- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm +++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm @@ -4,8 +4,7 @@ desc = "A shell of swarmer that was completely powered down. It can no longer activate itself." icon = 'icons/mob/swarmer.dmi' icon_state = "swarmer_unactivated" - origin_tech = "bluespace=4;materials=4;programming=7" - materials = list(MAT_METAL = 10000, MAT_GLASS = 4000) + materials = list(MAT_METAL=10000, MAT_GLASS=4000) /obj/effect/mob_spawn/swarmer name = "unactivated swarmer" @@ -101,8 +100,8 @@ /mob/living/simple_animal/hostile/swarmer/Initialize() . = ..() verbs -= /mob/living/verb/pulled - var/datum/atom_hud/data/diagnostic/diag_hud = GLOB.huds[DATA_HUD_DIAGNOSTIC] - diag_hud.add_to_hud(src) + for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds) + diag_hud.add_to_hud(src) /mob/living/simple_animal/hostile/swarmer/med_hud_set_health() var/image/holder = hud_list[DIAG_HUD] @@ -121,13 +120,6 @@ if(statpanel("Status")) stat("Resources:",resources) -/mob/living/simple_animal/hostile/swarmer/handle_inherent_channels(message, message_mode) - if(message_mode == MODE_BINARY) - swarmer_chat(message) - return ITALICS | REDUCE_RANGE - else - . = ..() - /mob/living/simple_animal/hostile/swarmer/get_spans() return ..() | SPAN_ROBOT @@ -175,9 +167,13 @@ /turf/closed/indestructible/swarmer_act() return FALSE -/obj/swarmer_act() +/obj/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) if(resistance_flags & INDESTRUCTIBLE) return FALSE + for(var/mob/living/L in contents) + if(!issilicon(L) && !isbrain(L)) + to_chat(S, "An organism has been detected inside this object. Aborting.") + return FALSE return ..() /obj/item/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) diff --git a/code/game/gamemodes/miniantags/monkey/monkey.dm b/code/game/gamemodes/miniantags/monkey/monkey.dm index 379031dce9..8e02d41441 100644 --- a/code/game/gamemodes/miniantags/monkey/monkey.dm +++ b/code/game/gamemodes/miniantags/monkey/monkey.dm @@ -105,13 +105,18 @@ monkey_mind.special_role = null -/datum/game_mode/monkey/declare_completion() +/datum/game_mode/monkey/set_round_result() + ..() if(check_monkey_victory()) SSticker.mode_result = "win - monkey win" - to_chat(world, "The monkeys have overthrown their captors! Eeek eeeek!!") else SSticker.mode_result = "loss - staff stopped the monkeys" - to_chat(world, "The staff managed to contain the monkey infestation!") + +/datum/game_mode/monkey/special_report() + if(check_monkey_victory()) + return "The monkeys have overthrown their captors! Eeek eeeek!!" + else + return "The staff managed to contain the monkey infestation!" /datum/game_mode/monkey/generate_report() return "Reports of an ancient [pick("retrovirus", "flesh eating bacteria", "disease", "magical curse blamed on viruses", "banana blight")] outbreak that turn humans into monkeys has been reported in your quadrant. Any such infections may be treated with banana juice. If an outbreak occurs, ensure the station is quarantined to prevent a largescale outbreak at CentCom." diff --git a/code/game/gamemodes/miniantags/morph/morph.dm b/code/game/gamemodes/miniantags/morph/morph.dm index 5e1a97675b..2ebc21adac 100644 --- a/code/game/gamemodes/miniantags/morph/morph.dm +++ b/code/game/gamemodes/miniantags/morph/morph.dm @@ -227,6 +227,7 @@ player_mind.assigned_role = "Morph" player_mind.special_role = "Morph" SSticker.mode.traitors |= player_mind + player_mind.add_antag_datum(/datum/antagonist/auto_custom) to_chat(S, S.playstyle_string) SEND_SOUND(S, sound('sound/magic/mutate.ogg')) message_admins("[key_name_admin(S)] has been made into a morph by an event.") diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm index 04a5f4d2be..441689fb9b 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant.dm @@ -87,6 +87,7 @@ mind.assigned_role = "revenant" mind.special_role = "Revenant" SSticker.mode.traitors |= mind //Necessary for announcing + mind.add_antag_datum(/datum/antagonist/auto_custom) AddSpell(new /obj/effect/proc_holder/spell/targeted/night_vision/revenant(null)) AddSpell(new /obj/effect/proc_holder/spell/targeted/revenant_transmit(null)) AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/defile(null)) @@ -374,7 +375,7 @@ return var/key_of_revenant message_admins("Revenant ectoplasm was left undestroyed for 1 minute and is reforming into a new revenant.") - loc = get_turf(src) //In case it's in a backpack or someone's hand + forceMove(drop_location()) //In case it's in a backpack or someone's hand revenant.forceMove(loc) if(client_to_revive) for(var/mob/M in GLOB.dead_mob_list) @@ -411,6 +412,11 @@ revenant = null qdel(src) +/obj/item/ectoplasm/revenant/suicide_act(mob/user) + user.visible_message("[user] is inhaling [src]! It looks like [user.p_theyre()] trying to visit the shadow realm!") + scatter() + return (OXYLOSS) + /obj/item/ectoplasm/revenant/Destroy() if(!QDELETED(revenant)) qdel(revenant) diff --git a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm index c7a09bb387..c401dfea52 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm @@ -254,6 +254,9 @@ if(T.type == /turf/closed/wall/r_wall && prob(10)) new /obj/effect/temp_visual/revenant(T) T.ChangeTurf(/turf/closed/wall/r_wall/rust) + for(var/obj/effect/decal/cleanable/salt/salt in T) + new /obj/effect/temp_visual/revenant(T) + qdel(salt) for(var/obj/structure/closet/closet in T.contents) closet.open() for(var/obj/structure/bodycontainer/corpseholder in T) diff --git a/code/game/gamemodes/miniantags/slaughter/slaughter.dm b/code/game/gamemodes/miniantags/slaughter/slaughter.dm index b9a07093d3..8739ba22eb 100644 --- a/code/game/gamemodes/miniantags/slaughter/slaughter.dm +++ b/code/game/gamemodes/miniantags/slaughter/slaughter.dm @@ -79,7 +79,6 @@ desc = "Still it beats furiously, emanating an aura of utter hate." icon = 'icons/obj/surgery.dmi' icon_state = "demon_heart-on" - origin_tech = "combat=5;biotech=7" /obj/item/organ/heart/demon/update_icon() return //always beating visually diff --git a/code/game/gamemodes/miniantags/slaughter/slaughterevent.dm b/code/game/gamemodes/miniantags/slaughter/slaughterevent.dm index f1f9624380..e62665f21b 100644 --- a/code/game/gamemodes/miniantags/slaughter/slaughterevent.dm +++ b/code/game/gamemodes/miniantags/slaughter/slaughterevent.dm @@ -38,6 +38,7 @@ player_mind.assigned_role = "Slaughter Demon" player_mind.special_role = "Slaughter Demon" SSticker.mode.traitors |= player_mind + player_mind.add_antag_datum(/datum/antagonist/auto_custom) to_chat(S, S.playstyle_string) to_chat(S, "You are currently not currently in the same plane of existence as the station. Blood Crawl near a blood pool to manifest.") SEND_SOUND(S, 'sound/magic/demon_dies.ogg') diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index 1e5d899bfa..890a3bb456 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -1,7 +1,3 @@ -/datum/game_mode - var/list/datum/mind/syndicates = list() - var/nukeops_lastname = "" - /datum/game_mode/nuclear name = "nuclear emergency" config_tag = "nuclear" @@ -18,12 +14,11 @@ Crew: Defend the nuclear authentication disk and ensure that it leaves with you on the emergency shuttle." var/const/agents_possible = 5 //If we ever need more syndicate agents. - var/nukes_left = 1 // Call 3714-PRAY right now and order more nukes! Limited offer! - var/nuke_off_station = 0 //Used for tracking if the syndies actually haul the nuke to the station - var/syndies_didnt_escape = 0 //Used for tracking if the syndies got the shuttle off of the z-level var/list/pre_nukeops = list() + var/datum/team/nuclear/nuke_team + /datum/game_mode/nuclear/pre_setup() var/n_agents = min(round(num_players() / 10), antag_candidates.len, agents_possible) for(var/i = 0, i < n_agents, ++i) @@ -33,120 +28,23 @@ new_op.special_role = "Nuclear Operative" log_game("[new_op.key] (ckey) has been selected as a nuclear operative") return TRUE - -//////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// -/datum/game_mode/proc/update_synd_icons_added(datum/mind/synd_mind) - var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS] - opshud.join_hud(synd_mind.current) - set_antag_hud(synd_mind.current, "synd") - -/datum/game_mode/proc/update_synd_icons_removed(datum/mind/synd_mind) - var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS] - opshud.leave_hud(synd_mind.current) - set_antag_hud(synd_mind.current, null) - //////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////// /datum/game_mode/nuclear/post_setup() - var/nuke_code = random_nukecode() - var/agent_number = 1 - var/datum/mind/leader = pick(pre_nukeops) - syndicates += pre_nukeops - for(var/i = 1 to pre_nukeops.len) - var/datum/mind/op = pre_nukeops[i] - - forge_syndicate_objectives(op) - greet_syndicate(op) - equip_syndicate(op.current) - - if(nuke_code) - op.store_memory("Syndicate Nuclear Bomb Code: [nuke_code]", 0, 0) - to_chat(op.current, "The nuclear authorization code is: [nuke_code]") - - if(op == leader) - op.current.forceMove(pick(GLOB.nukeop_leader_start)) - prepare_syndicate_leader(op, nuke_code) - else - op.current.forceMove(GLOB.nukeop_start[((i - 1) % GLOB.nukeop_start.len) + 1]) - op.current.real_name = "[syndicate_name()] Operative #[agent_number++]" - - update_synd_icons_added(op) - op.current.playsound_local(get_turf(op.current), 'sound/ambience/antag/ops.ogg',100,0) - - var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list - if(nuke) - nuke.r_code = nuke_code + //Assign leader + var/datum/mind/leader_mind = pre_nukeops[1] + var/datum/antagonist/nukeop/L = leader_mind.add_antag_datum(/datum/antagonist/nukeop/leader) + nuke_team = L.nuke_team + //Assign the remaining operatives + for(var/i = 2 to pre_nukeops.len) + var/datum/mind/nuke_mind = pre_nukeops[i] + nuke_mind.add_antag_datum(/datum/antagonist/nukeop,nuke_team) return ..() -/datum/game_mode/proc/prepare_syndicate_leader(datum/mind/synd_mind, nuke_code) - var/leader_title = pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord") - addtimer(CALLBACK(src, .proc/nuketeam_name_assign, synd_mind), 1) - synd_mind.current.real_name = "[syndicate_name()] [leader_title]" - to_chat(synd_mind.current, "You are the Syndicate [leader_title] for this mission. You are responsible for the distribution of telecrystals and your ID is the only one who can open the launch bay doors.") - to_chat(synd_mind.current, "If you feel you are not up to this task, give your ID to another operative.") - to_chat(synd_mind.current, "In your hand you will find a special item capable of triggering a greater challenge for your team. Examine it carefully and consult with your fellow operatives before activating it.") - - var/obj/item/device/nuclear_challenge/challenge = new /obj/item/device/nuclear_challenge - synd_mind.current.put_in_hands(challenge, TRUE) - - var/static/id_cache = typecacheof(/obj/item/card/id) - var/list/foundIDs = typecache_filter_list(synd_mind.current.GetAllContents(), id_cache) - if(foundIDs.len) - for(var/i in 1 to foundIDs.len) - var/obj/item/card/id/ID = foundIDs[i] - ID.name = "lead agent card" - ID.access += ACCESS_SYNDICATE_LEADER - else - message_admins("Warning: Nuke Ops spawned without access to leave their spawn area!") - - var/obj/item/device/radio/headset/syndicate/alt/A = locate() in synd_mind.current - if(A) - A.command = TRUE - - if(nuke_code) - var/obj/item/paper/P = new - P.info = "The nuclear authorization code is: [nuke_code]" - P.name = "nuclear bomb code" - var/mob/living/carbon/human/H = synd_mind.current - H.put_in_hands(P, TRUE) - H.update_icons() - else - nuke_code = "code will be provided later" - return - -/datum/game_mode/proc/nuketeam_name_assign(datum/mind/synd_mind) - nukeops_lastname = nukelastname(synd_mind.current) - NukeNameAssign(nukeops_lastname, syndicates) - - -/datum/game_mode/proc/forge_syndicate_objectives(datum/mind/syndicate) - var/datum/objective/nuclear/syndobj = new - syndobj.owner = syndicate - syndicate.objectives += syndobj - - -/datum/game_mode/proc/greet_syndicate(datum/mind/syndicate, you_are=1) - if(you_are) - to_chat(syndicate.current, "You are a [syndicate_name()] agent!") - syndicate.announce_objectives() - -/datum/game_mode/proc/equip_syndicate(mob/living/carbon/human/synd_mob, telecrystals = TRUE) - synd_mob.set_species(/datum/species/human) //Plasamen burn up otherwise, and lizards are vulnerable to asimov AIs - - if(telecrystals) - synd_mob.equipOutfit(/datum/outfit/syndicate) - else - synd_mob.equipOutfit(/datum/outfit/syndicate/no_crystals) - return TRUE - /datum/game_mode/nuclear/OnNukeExplosion(off_station) ..() nukes_left-- - var/obj/docking_port/mobile/Shuttle = SSshuttle.getShuttle("syndicate") - syndies_didnt_escape = (Shuttle && (Shuttle.z == ZLEVEL_CENTCOM || Shuttle.z == ZLEVEL_TRANSIT)) ? 0 : 1 - nuke_off_station = off_station /datum/game_mode/nuclear/check_win() if (nukes_left == 0) @@ -154,8 +52,8 @@ return ..() /datum/game_mode/proc/are_operatives_dead() - for(var/datum/mind/operative_mind in syndicates) - if(ishuman(operative_mind.current) && (operative_mind.current.stat!=2)) + for(var/datum/mind/operative_mind in get_antagonists(/datum/antagonist/nukeop)) + if(ishuman(operative_mind.current) && (operative_mind.current.stat != DEAD)) return FALSE return TRUE @@ -164,141 +62,55 @@ return replacementmode.check_finished() if((SSshuttle.emergency.mode == SHUTTLE_ENDGAME) || station_was_nuked) return TRUE - if(are_operatives_dead()) + if(nuke_team.operatives_dead()) var/obj/machinery/nuclearbomb/N pass(N) //suppress unused warning if(N.bomb_set) //snaaaaaaaaaake! It's not over yet! return FALSE //its a static var btw ..() -/datum/game_mode/nuclear/declare_completion() - var/disk_rescued = 1 - for(var/obj/item/disk/nuclear/D in GLOB.poi_list) - if(!D.onCentCom()) - disk_rescued = 0 - break - var/crew_evacuated = (SSshuttle.emergency.mode == SHUTTLE_ENDGAME) - - if(nuke_off_station == NUKE_SYNDICATE_BASE) - SSticker.mode_result = "loss - syndicate nuked - disk secured" - to_chat(world, "Humiliating Syndicate Defeat") - to_chat(world, "The crew of [station_name()] gave [syndicate_name()] operatives back their bomb! The syndicate base was destroyed! Next time, don't lose the nuke!") - - SSticker.news_report = NUKE_SYNDICATE_BASE - - else if(!disk_rescued && station_was_nuked && !syndies_didnt_escape) - SSticker.mode_result = "win - syndicate nuke" - to_chat(world, "Syndicate Major Victory!") - to_chat(world, "[syndicate_name()] operatives have destroyed [station_name()]!") - - SSticker.news_report = STATION_NUKED - - else if (!disk_rescued && station_was_nuked && syndies_didnt_escape) - SSticker.mode_result = "halfwin - syndicate nuke - did not evacuate in time" - to_chat(world, "Total Annihilation") - to_chat(world, "[syndicate_name()] operatives destroyed [station_name()] but did not leave the area in time and got caught in the explosion. Next time, don't lose the disk!") - - SSticker.news_report = STATION_NUKED - - else if (!disk_rescued && !station_was_nuked && nuke_off_station && !syndies_didnt_escape) - SSticker.mode_result = "halfwin - blew wrong station" - to_chat(world, "Crew Minor Victory") - to_chat(world, "[syndicate_name()] operatives secured the authentication disk but blew up something that wasn't [station_name()]. Next time, don't do that!") - - SSticker.news_report = NUKE_MISS - - else if (!disk_rescued && !station_was_nuked && nuke_off_station && syndies_didnt_escape) - SSticker.mode_result = "halfwin - blew wrong station - did not evacuate in time" - to_chat(world, "[syndicate_name()] operatives have earned Darwin Award!") - to_chat(world, "[syndicate_name()] operatives blew up something that wasn't [station_name()] and got caught in the explosion. Next time, don't do that!") - - SSticker.news_report = NUKE_MISS - - else if ((disk_rescued || SSshuttle.emergency.mode != SHUTTLE_ENDGAME) && are_operatives_dead()) - SSticker.mode_result = "loss - evacuation - disk secured - syndi team dead" - to_chat(world, "Crew Major Victory!") - to_chat(world, "The Research Staff has saved the disk and killed the [syndicate_name()] Operatives") - - SSticker.news_report = OPERATIVES_KILLED - - else if (disk_rescued) - SSticker.mode_result = "loss - evacuation - disk secured" - to_chat(world, "Crew Major Victory") - to_chat(world, "The Research Staff has saved the disk and stopped the [syndicate_name()] Operatives!") - - SSticker.news_report = OPERATIVES_KILLED - - else if (!disk_rescued && are_operatives_dead()) - SSticker.mode_result = "halfwin - evacuation - disk not secured" - to_chat(world, "Neutral Victory!") - to_chat(world, "The Research Staff failed to secure the authentication disk but did manage to kill most of the [syndicate_name()] Operatives!") - - SSticker.news_report = OPERATIVE_SKIRMISH - - else if (!disk_rescued && crew_evacuated) - SSticker.mode_result = "halfwin - detonation averted" - to_chat(world, "Syndicate Minor Victory!") - to_chat(world, "[syndicate_name()] operatives survived the assault but did not achieve the destruction of [station_name()]. Next time, don't lose the disk!") - - SSticker.news_report = OPERATIVE_SKIRMISH - - else if (!disk_rescued && !crew_evacuated) - SSticker.mode_result = "halfwin - interrupted" - to_chat(world, "Neutral Victory") - to_chat(world, "Round was mysteriously interrupted!") - - SSticker.news_report = OPERATIVE_SKIRMISH - +/datum/game_mode/nuclear/set_round_result() ..() - return + var result = nuke_team.get_result() + switch(result) + if(NUKE_RESULT_FLUKE) + SSticker.mode_result = "loss - syndicate nuked - disk secured" + SSticker.news_report = NUKE_SYNDICATE_BASE + if(NUKE_RESULT_NUKE_WIN) + SSticker.mode_result = "win - syndicate nuke" + SSticker.news_report = STATION_NUKED + if(NUKE_RESULT_NOSURVIVORS) + SSticker.mode_result = "halfwin - syndicate nuke - did not evacuate in time" + SSticker.news_report = STATION_NUKED + if(NUKE_RESULT_WRONG_STATION) + SSticker.mode_result = "halfwin - blew wrong station" + SSticker.news_report = NUKE_MISS + if(NUKE_RESULT_WRONG_STATION_DEAD) + SSticker.mode_result = "halfwin - blew wrong station - did not evacuate in time" + SSticker.news_report = NUKE_MISS + if(NUKE_RESULT_CREW_WIN_SYNDIES_DEAD) + SSticker.mode_result = "loss - evacuation - disk secured - syndi team dead" + SSticker.news_report = OPERATIVES_KILLED + if(NUKE_RESULT_CREW_WIN) + SSticker.mode_result = "loss - evacuation - disk secured" + SSticker.news_report = OPERATIVES_KILLED + if(NUKE_RESULT_DISK_LOST) + SSticker.mode_result = "halfwin - evacuation - disk not secured" + SSticker.news_report = OPERATIVE_SKIRMISH + if(NUKE_RESULT_DISK_STOLEN) + SSticker.mode_result = "halfwin - detonation averted" + SSticker.news_report = OPERATIVE_SKIRMISH + else + SSticker.mode_result = "halfwin - interrupted" + SSticker.news_report = OPERATIVE_SKIRMISH /datum/game_mode/nuclear/generate_report() return "One of Central Command's trading routes was recently disrupted by a raid carried out by the Gorlex Marauders. They seemed to only be after one ship - a highly-sensitive \ transport containing a nuclear fission explosive, although it is useless without the proper code and authorization disk. While the code was likely found in minutes, the only disk that \ can activate this explosive is on your station. Ensure that it is protected at all times, and remain alert for possible intruders." -/datum/game_mode/proc/auto_declare_completion_nuclear() - if( syndicates.len || (SSticker && istype(SSticker.mode, /datum/game_mode/nuclear)) ) - var/text = "
    The syndicate operatives were:" - var/purchases = "" - var/TC_uses = 0 - for(var/datum/mind/syndicate in syndicates) - text += printplayer(syndicate) - for(var/obj/item/device/uplink/H in GLOB.uplinks) - if(H && H.owner && H.owner == syndicate.key) - TC_uses += H.spent_telecrystals - purchases += H.purchase_log - text += "
    " - text += "(Syndicates used [TC_uses] TC) [purchases]" - if(TC_uses == 0 && station_was_nuked && !are_operatives_dead()) - text += "[icon2html('icons/badass.dmi', world, "badass")]" - to_chat(world, text) - return TRUE - - -/proc/nukelastname(mob/M) //--All praise goes to NEO|Phyte, all blame goes to DH, and it was Cindi-Kate's idea. Also praise Urist for copypasta ho. - var/randomname = pick(GLOB.last_names) - var/newname = copytext(sanitize(input(M,"You are the nuke operative [pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord")]. Please choose a last name for your family.", "Name change",randomname)),1,MAX_NAME_LEN) - - if (!newname) - newname = randomname - - else - if (newname == "Unknown" || newname == "floor" || newname == "wall" || newname == "rwall" || newname == "_") - to_chat(M, "That name is reserved.") - return nukelastname(M) - - return capitalize(newname) - -/proc/NukeNameAssign(lastname,list/syndicates) - for(var/datum/mind/synd_mind in syndicates) - var/mob/living/carbon/human/H = synd_mind.current - synd_mind.name = H.dna.species.random_name(H.gender,0,lastname) - synd_mind.current.real_name = synd_mind.name - return - /proc/is_nuclear_operative(mob/M) - return M && istype(M) && M.mind && SSticker && SSticker.mode && M.mind in SSticker.mode.syndicates + return M && istype(M) && M.mind && M.mind.has_antag_datum(/datum/antagonist/nukeop) /datum/outfit/syndicate name = "Syndicate Operative - Basic" @@ -311,23 +123,31 @@ l_pocket = /obj/item/pinpointer/nuke/syndicate id = /obj/item/card/id/syndicate belt = /obj/item/gun/ballistic/automatic/pistol - backpack_contents = list(/obj/item/storage/box/syndie=1) + backpack_contents = list(/obj/item/storage/box/syndie=1,\ + /obj/item/kitchen/knife/combat/survival) var/tc = 25 + var/command_radio = FALSE + + +/datum/outfit/syndicate/leader + name = "Syndicate Leader - Basic" + id = /obj/item/card/id/syndicate/nuke_leader + r_hand = /obj/item/device/nuclear_challenge + command_radio = TRUE /datum/outfit/syndicate/no_crystals tc = 0 - /datum/outfit/syndicate/post_equip(mob/living/carbon/human/H) var/obj/item/device/radio/R = H.ears R.set_frequency(GLOB.SYND_FREQ) R.freqlock = 1 + if(command_radio) + R.command = TRUE if(tc) - var/obj/item/device/radio/uplink/nuclear/U = new(H) - U.hidden_uplink.owner = "[H.key]" - U.hidden_uplink.telecrystals = tc + var/obj/item/device/radio/uplink/nuclear/U = new(H, H.key, tc) H.equip_to_slot_or_del(U, slot_in_backpack) var/obj/item/implant/weapons_auth/W = new/obj/item/implant/weapons_auth(H) @@ -349,4 +169,5 @@ r_hand = /obj/item/gun/ballistic/automatic/shotgun/bulldog backpack_contents = list(/obj/item/storage/box/syndie=1,\ /obj/item/tank/jetpack/oxygen/harness=1,\ - /obj/item/gun/ballistic/automatic/pistol=1) + /obj/item/gun/ballistic/automatic/pistol=1,\ + /obj/item/kitchen/knife/combat/survival) diff --git a/code/game/gamemodes/nuclear/nuclear_challenge.dm b/code/game/gamemodes/nuclear/nuclear_challenge.dm index c9314ece1a..58128b89ce 100644 --- a/code/game/gamemodes/nuclear/nuclear_challenge.dm +++ b/code/game/gamemodes/nuclear/nuclear_challenge.dm @@ -54,10 +54,7 @@ var/obj/item/circuitboard/computer/syndicate_shuttle/board = V board.challenge = TRUE - var/obj/item/device/radio/uplink/nuclear/U = new(get_turf(user)) - U.hidden_uplink.owner = "[user.key]" - U.hidden_uplink.telecrystals = CHALLENGE_TELECRYSTALS - U.hidden_uplink.set_gamemode(/datum/game_mode/nuclear) + new /obj/item/device/radio/uplink/nuclear(get_turf(user), user.key, CHALLENGE_TELECRYSTALS) CONFIG_SET(number/shuttle_refuel_delay, max(CONFIG_GET(number/shuttle_refuel_delay), CHALLENGE_SHUTTLE_DELAY)) SSblackbox.record_feedback("amount", "nuclear_challenge_mode", 1) @@ -66,22 +63,22 @@ /obj/item/device/nuclear_challenge/proc/check_allowed(mob/living/user) if(declaring_war) to_chat(user, "You are already in the process of declaring war! Make your mind up.") - return 0 + return FALSE if(GLOB.player_list.len < CHALLENGE_MIN_PLAYERS) to_chat(user, "The enemy crew is too small to be worth declaring war on.") - return 0 + return FALSE if(user.z != ZLEVEL_CENTCOM) to_chat(user, "You have to be at your base to use this.") - return 0 + return FALSE if(world.time-SSticker.round_start_time > CHALLENGE_TIME_LIMIT) to_chat(user, "It's too late to declare hostilities. Your benefactors are already busy with other schemes. You'll have to make do with what you have on hand.") - return 0 + return FALSE for(var/V in GLOB.syndicate_shuttle_boards) var/obj/item/circuitboard/computer/syndicate_shuttle/board = V if(board.moved) to_chat(user, "The shuttle has already been moved! You have forfeit the right to declare war.") - return 0 - return 1 + return FALSE + return TRUE #undef CHALLENGE_TELECRYSTALS #undef CHALLENGE_MIN_PLAYERS diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm index a36503e7c4..d6d14a3f84 100644 --- a/code/game/gamemodes/nuclear/nuclearbomb.dm +++ b/code/game/gamemodes/nuclear/nuclearbomb.dm @@ -77,16 +77,16 @@ icon = 'icons/obj/machines/nuke_terminal.dmi' icon_state = "nuclearbomb_base" anchored = TRUE //stops it being moved - use_tag = TRUE /obj/machinery/nuclearbomb/syndicate + use_tag = TRUE //ui_style = "syndicate" // actually the nuke op bomb is a stole nt bomb /obj/machinery/nuclearbomb/syndicate/get_cinematic_type(off_station) var/datum/game_mode/nuclear/NM = SSticker.mode switch(off_station) if(0) - if(istype(NM) && NM.syndies_didnt_escape) + if(istype(NM) && !NM.nuke_team.syndies_escaped()) return CINEMATIC_ANNIHILATION else return CINEMATIC_NUKE_WIN @@ -353,7 +353,7 @@ var/N = text2num(user_input) if(!N) return - timer_set = Clamp(N,minimum_timer_set,maximum_timer_set) + timer_set = CLAMP(N,minimum_timer_set,maximum_timer_set) . = TRUE if("safety") if(auth && yes_code) @@ -551,16 +551,25 @@ This is here to make the tiles around the station mininuke change when it's arme /obj/item/disk/nuclear/suicide_act(mob/user) user.visible_message("[user] is going delta! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(user.loc, 'sound/machines/alarm.ogg', 50, -1, 1) + playsound(src, 'sound/machines/alarm.ogg', 50, -1, 1) for(var/i in 1 to 100) addtimer(CALLBACK(user, /atom/proc/add_atom_colour, (i % 2)? "#00FF00" : "#FF0000", ADMIN_COLOUR_PRIORITY), i) - addtimer(CALLBACK(user, /atom/proc/remove_atom_colour, ADMIN_COLOUR_PRIORITY), 101) - addtimer(CALLBACK(user, /atom/proc/visible_message, "[user] was destroyed by the nuclear blast!"), 101) - addtimer(CALLBACK(user, /mob/living/proc/adjustOxyLoss, 200), 101) - addtimer(CALLBACK(user, /mob/proc/death, 0), 101) + addtimer(CALLBACK(src, .proc/manual_suicide, user), 101) return MANUAL_SUICIDE + +/obj/item/disk/proc/manual_suicide(mob/living/user) + user.remove_atom_colour(ADMIN_COLOUR_PRIORITY) + user.visible_message("[user] was destroyed by the nuclear blast!") + user.adjustOxyLoss(200) + user.death(0) /obj/item/disk/fakenucleardisk name = "cheap plastic imitation of the nuclear authentication disk" desc = "Broken dreams and a faint odor of cheese." icon_state = "nucleardisk" + +/obj/item/disk/fakenucleardisk/suicide_act(mob/user) + user.visible_message("[user] is pretending to go delta! It looks like [user.p_theyre()] trying to commit suicide!") + playsound(src, 'sound/machines/alarm.ogg', 30, -1, 1) + addtimer(CALLBACK(src, .proc/manual_suicide, user), 101) + return MANUAL_SUICIDE diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm index 2df573dc6d..7047729294 100644 --- a/code/game/gamemodes/nuclear/pinpointer.dm +++ b/code/game/gamemodes/nuclear/pinpointer.dm @@ -71,9 +71,9 @@ target = null var/list/possible_targets = list() var/turf/here = get_turf(src) - for(var/V in SSticker.mode.syndicates) + for(var/V in get_antagonists(/datum/antagonist/nukeop)) var/datum/mind/M = V - if(M.current && M.current.stat != DEAD) + if(ishuman(M.current) && M.current.stat != DEAD) possible_targets |= M.current var/mob/living/closest_operative = get_closest_atom(/mob/living/carbon/human, possible_targets, here) if(closest_operative) diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index d1c8d0193d..46f96961c9 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -194,10 +194,8 @@ /datum/objective/debrain/check_completion() if(!target)//If it's a free objective. return TRUE - if(!target.current || !isbrain(target.current)) return FALSE - var/atom/A = target.current var/list/datum/mind/owners = get_owners() @@ -508,12 +506,12 @@ GLOBAL_LIST_EMPTY(possible_items_special) /datum/objective/download /datum/objective/download/proc/gen_amount_goal() - target_amount = rand(10,20) - explanation_text = "Download [target_amount] research level\s." + target_amount = rand(20,40) + explanation_text = "Download [target_amount] research node\s." return target_amount /datum/objective/download/check_completion() - var/list/current_tech = list() + var/datum/techweb/checking = new var/list/datum/mind/owners = get_owners() for(var/datum/mind/owner in owners) if(ismob(owner.current)) @@ -522,21 +520,11 @@ GLOBAL_LIST_EMPTY(possible_items_special) 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 + S.stored_research.copy_research_to(checking) 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 + TD.stored_research.copy_research_to(checking) + return checking.researched_nodes.len >= target /datum/objective/capture @@ -787,7 +775,7 @@ GLOBAL_LIST_EMPTY(possible_items_special) /datum/objective/changeling_team_objective/impersonate_department/check_completion() if(!department_real_names.len || !department_minds.len) - return 1 //Something fucked up, give them a win + return TRUE //Something fucked up, give them a win var/list/check_names = department_real_names.Copy() @@ -799,14 +787,14 @@ GLOBAL_LIST_EMPTY(possible_items_special) if(M.current) var/turf/mloc = get_turf(M.current) if(mloc.onCentCom() && (M.current.stat != DEAD)) - return 0 //A Non-ling living target got to centcom, fail + return FALSE //A Non-ling living target got to centcom, fail //Check each staff member has been replaced, by cross referencing changeling minds, changeling current dna, the staff minds and their original DNA names var/success = 0 changelings: for(var/datum/mind/changeling in get_antagonists(/datum/antagonist/changeling,TRUE)) if(success >= department_minds.len) //We did it, stop here! - return 1 + return TRUE if(ishuman(changeling.current)) var/mob/living/carbon/human/H = changeling.current var/turf/cloc = get_turf(changeling.current) @@ -818,8 +806,8 @@ GLOBAL_LIST_EMPTY(possible_items_special) continue changelings if(success >= department_minds.len) - return 1 - return 0 + return TRUE + return FALSE diff --git a/code/game/gamemodes/objective_team.dm b/code/game/gamemodes/objective_team.dm index 7789a167c7..1483f356d2 100644 --- a/code/game/gamemodes/objective_team.dm +++ b/code/game/gamemodes/objective_team.dm @@ -3,6 +3,7 @@ var/list/datum/mind/members = list() var/name = "team" var/member_name = "member" + var/list/objectives = list() //common objectives, these won't be added or removed automatically, subtypes handle this, this is here for bookkeeping purposes. /datum/objective_team/New(starting_members) . = ..() @@ -12,7 +13,6 @@ add_member(M) else add_member(starting_members) - members += starting_members /datum/objective_team/proc/is_solo() return members.len == 1 @@ -21,4 +21,14 @@ members |= new_member /datum/objective_team/proc/remove_member(datum/mind/member) - members -= member \ No newline at end of file + members -= member + +//Display members/victory/failure/objectives for the team +/datum/objective_team/proc/roundend_report() + var/list/report = list() + + report += "[name]:" + report += "The [member_name]s were:" + report += printplayerlist(members) + + return report.Join("
    ") \ No newline at end of file diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm index 4fa9532b42..f20e16b36b 100644 --- a/code/game/gamemodes/revolution/revolution.dm +++ b/code/game/gamemodes/revolution/revolution.dm @@ -26,7 +26,7 @@ var/finished = 0 var/check_counter = 0 var/max_headrevs = 3 - var/datum/objective_team/revolution/revolution + var/datum/team/revolution/revolution var/list/datum/mind/headrev_candidates = list() /////////////////////////// @@ -169,62 +169,22 @@ return FALSE return TRUE -////////////////////////////////////////////////////////////////////// -//Announces the end of the game with all relavent information stated// -////////////////////////////////////////////////////////////////////// -/datum/game_mode/revolution/declare_completion() + +/datum/game_mode/revolution/set_round_result() + ..() if(finished == 1) SSticker.mode_result = "win - heads killed" - to_chat(world, "The heads of staff were killed or exiled! The revolutionaries win!") - SSticker.news_report = REVS_WIN - else if(finished == 2) SSticker.mode_result = "loss - rev heads killed" - to_chat(world, "The heads of staff managed to stop the revolution!") - SSticker.news_report = REVS_LOSE - ..() - return TRUE -/datum/game_mode/proc/auto_declare_completion_revolution() - var/list/targets = list() - var/list/datum/mind/headrevs = get_antagonists(/datum/antagonist/rev/head) - var/list/datum/mind/revs = get_antagonists(/datum/antagonist/rev,TRUE) - if(headrevs.len) - var/num_revs = 0 - var/num_survivors = 0 - for(var/mob/living/carbon/survivor in GLOB.alive_mob_list) - if(survivor.ckey) - num_survivors++ - if(survivor.mind) - if(is_revolutionary(survivor)) - num_revs++ - if(num_survivors) - to_chat(world, "[GLOB.TAB]Command's Approval Rating: [100 - round((num_revs/num_survivors)*100, 0.1)]%" ) - var/text = "
    The head revolutionaries were:" - for(var/datum/mind/headrev in headrevs) - text += printplayer(headrev, 1) - text += "
    " - to_chat(world, text) - - if(revs.len) - var/text = "
    The revolutionaries were:" - for(var/datum/mind/rev in revs) - text += printplayer(rev, 1) - text += "
    " - to_chat(world, text) - - if(revs.len || headrevs.len) - var/text = "
    The heads of staff were:" - var/list/heads = SSjob.get_all_heads() - for(var/datum/mind/head in heads) - var/target = (head in targets) - if(target) - text += "Target" - text += printplayer(head, 1) - text += "
    " - to_chat(world, text) +//TODO What should be displayed for revs in non-rev rounds +/datum/game_mode/revolution/special_report() + if(finished == 1) + return "The heads of staff were killed or exiled! The revolutionaries win!" + else if(finished == 2) + return "The heads of staff managed to stop the revolution!" /datum/game_mode/revolution/generate_report() return "Employee unrest has spiked in recent weeks, with several attempted mutinies on heads of staff. Some crew have been observed using flashbulb devices to blind their colleagues, \ diff --git a/code/game/gamemodes/sandbox/h_sandbox.dm b/code/game/gamemodes/sandbox/h_sandbox.dm index cf2b867941..101a33e551 100644 --- a/code/game/gamemodes/sandbox/h_sandbox.dm +++ b/code/game/gamemodes/sandbox/h_sandbox.dm @@ -28,7 +28,7 @@ GLOBAL_VAR_INIT(hsboxspawn, TRUE) 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/smallDelivery, /obj/item/projectile, /obj/item/borg/sight, /obj/item/borg/stun, /obj/item/robot_module) /datum/hSB/proc/update() diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm index 1ddb952bc5..42c96cb5c0 100644 --- a/code/game/gamemodes/traitor/traitor.dm +++ b/code/game/gamemodes/traitor/traitor.dm @@ -27,6 +27,7 @@ var/traitors_possible = 4 //hard limit on traitors if scaling is turned off var/num_modifier = 0 // Used for gamemodes, that are a child of traitor, that need more than the usual. var/antag_datum = ANTAG_DATUM_TRAITOR //what type of antag to create + var/traitors_required = TRUE //Will allow no traitors /datum/game_mode/traitor/pre_setup() @@ -55,7 +56,7 @@ log_game("[traitor.key] (ckey) has been selected as a [traitor_name]") antag_candidates.Remove(traitor) - return pre_traitors.len > 0 + return !traitors_required || pre_traitors.len > 0 /datum/game_mode/traitor/post_setup() @@ -85,80 +86,10 @@ new_antag.should_specialise = TRUE character.add_antag_datum(new_antag) - - -/datum/game_mode/traitor/declare_completion() - ..() - return//Traitors will be checked as part of check_extra_completion. Leaving this here as a reminder. - - -/datum/game_mode/proc/auto_declare_completion_traitor() - if(traitors.len) - var/text = "
    The [traitor_name]s were:" - for(var/datum/mind/traitor in traitors) - var/traitorwin = TRUE - - text += printplayer(traitor) - - var/TC_uses = 0 - var/uplink_true = FALSE - var/purchases = "" - for(var/obj/item/device/uplink/H in GLOB.uplinks) - if(H && H.owner && H.owner == traitor.key) - TC_uses += H.spent_telecrystals - uplink_true = TRUE - purchases += H.purchase_log - - var/objectives = "" - if(traitor.objectives.len)//If the traitor had no objectives, don't need to process this. - var/count = 1 - for(var/datum/objective/objective in traitor.objectives) - if(objective.check_completion()) - objectives += "
    Objective #[count]: [objective.explanation_text] Success! [istype(objective, /datum/objective/crew) ? "(Optional)" : ""]" - SSblackbox.record_feedback("nested tally", "traitor_objective", 1, list("[objective.type]", "SUCCESS")) - else - objectives += "
    Objective #[count]: [objective.explanation_text] Fail. [istype(objective, /datum/objective/crew) ? "(Optional)" : ""]" - SSblackbox.record_feedback("nested tally", "traitor_objective", 1, list("[objective.type]", "FAIL")) - if(!(istype(objective, /datum/objective/crew))) - traitorwin = FALSE - count++ - - if(uplink_true) - text += " (used [TC_uses] TC) [purchases]" - if(TC_uses==0 && traitorwin) - var/static/icon/badass = icon('icons/badass.dmi', "badass") - text += "[icon2html(badass, world)]" - - text += objectives - - var/special_role_text - if(traitor.special_role) - special_role_text = lowertext(traitor.special_role) - else - special_role_text = "antagonist" - - - if(traitorwin) - text += "
    The [special_role_text] was successful!" - SSblackbox.record_feedback("tally", "traitor_success", 1, "SUCCESS") - else - text += "
    The [special_role_text] has failed!" - SSblackbox.record_feedback("tally", "traitor_success", 1, "FAIL") - SEND_SOUND(traitor.current, 'sound/ambience/ambifailure.ogg') - - text += "
    " - - text += "
    The code phrases were: [GLOB.syndicate_code_phrase]
    \ - The code responses were: [GLOB.syndicate_code_response]
    " - to_chat(world, text) - - return TRUE - /datum/game_mode/traitor/generate_report() return "Although more specific threats are commonplace, you should always remain vigilant for Syndicate agents aboard your station. Syndicate communications have implied that many \ Nanotrasen employees are Syndicate agents with hidden memories that may be activated at a moment's notice, so it's possible that these agents might not even know their positions." - /datum/game_mode/proc/update_traitor_icons_added(datum/mind/traitor_mind) var/datum/atom_hud/antag/traitorhud = GLOB.huds[ANTAG_HUD_TRAITOR] traitorhud.join_hud(traitor_mind.current) diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index cd50f52d5f..21de0fc2f9 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -33,7 +33,7 @@ /obj/effect/rend name = "tear in the fabric of reality" desc = "You should run now." - icon = 'icons/obj/biomass.dmi' + icon = 'icons/effects/effects.dmi' icon_state = "rift" density = TRUE anchored = TRUE @@ -137,7 +137,6 @@ item_state = "electronic" lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' - origin_tech = "bluespace=4;materials=4" w_class = WEIGHT_CLASS_TINY var/list/spooky_scaries = list() var/unlimited = 0 @@ -214,7 +213,7 @@ righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' var/mob/living/carbon/human/target = null var/list/mob/living/carbon/human/possible = list() - var/obj/item/link = null + var/obj/item/linked_item = null var/cooldown_time = 30 //3s var/cooldown = 0 max_integrity = 10 @@ -238,10 +237,10 @@ cooldown = world.time +cooldown_time return - if(!link) + if(!linked_item) if(I.loc == user && istype(I) && I.w_class <= WEIGHT_CLASS_SMALL) if (user.transferItemToLoc(I,src)) - link = I + linked_item = I to_chat(user, "You attach [I] to the doll.") update_targets() @@ -256,11 +255,11 @@ return if(user.zone_selected == "chest") - if(link) + if(linked_item) target = null - link.loc = get_turf(src) - to_chat(user, "You remove the [link] from the doll.") - link = null + linked_item.forceMove(drop_location()) + to_chat(user, "You remove the [linked_item] from the doll.") + linked_item = null update_targets() return @@ -292,10 +291,10 @@ /obj/item/voodoo/proc/update_targets() possible = list() - if(!link) + if(!linked_item) return for(var/mob/living/carbon/human/H in GLOB.alive_mob_list) - if(md5(H.dna.uni_identity) in link.fingerprints) + if(md5(H.dna.uni_identity) in linked_item.fingerprints) possible |= H /obj/item/voodoo/proc/GiveHint(mob/victim,force=0) @@ -306,6 +305,11 @@ var/area/A = get_area(src) to_chat(victim, "You feel a dark presence from [A.name]") +/obj/item/voodoo/suicide_act(mob/living/carbon/user) + user.visible_message("[user] links the voodoo doll to themself and sits on it, infinitely crushing themself! It looks like [user.p_theyre()] trying to commit suicide!") + user.gib() + return(BRUTELOSS) + /obj/item/voodoo/fire_act(exposed_temperature, exposed_volume) if(target) target.adjust_fire_stacks(20) @@ -313,7 +317,6 @@ GiveHint(target,1) return ..() - //Provides a decent heal, need to pump every 6 seconds /obj/item/organ/heart/cursed/wizard pump_delay = 60 diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index 484961b6f8..8b80b9ab69 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -9,7 +9,6 @@ desc = "A fragment of the legendary treasure known simply as the 'Soul Stone'. The shard still flickers with a fraction of the full artefact's power." w_class = WEIGHT_CLASS_TINY slot_flags = SLOT_BELT - origin_tech = "bluespace=4;materials=5" var/usability = 0 var/reusable = TRUE @@ -65,7 +64,6 @@ to_chat(user, "\"Come now, do not capture your bretheren's soul.\"") return add_logs(user, M, "captured [M.name]'s soul", src) - transfer_soul("VICTIM", M, user) ///////////////////Options for using captured souls/////////////////////////////////////// @@ -143,7 +141,8 @@ if("VICTIM") var/mob/living/carbon/human/T = target - if(is_sacrifice_target(T.mind)) + var/datum/antagonist/cult/C = user.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + if(C && C.cult_team.is_sacrifice_target(T.mind)) if(iscultist(user)) to_chat(user, "\"This soul is mine. SACRIFICE THEM!\"") else diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index 1cf172d3a6..b086854ab6 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -897,6 +897,9 @@ to_chat(user,"[src] suddenly vanishes!") qdel(src) +/obj/item/spellbook/oneuse/random + icon_state = "random_book" + /obj/item/spellbook/oneuse/random/Initialize() ..() var/static/banned_spells = list(/obj/item/spellbook/oneuse/mimery_blockade, /obj/item/spellbook/oneuse/mimery_guns) diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm index 5302ebd39b..0d9655ae8e 100644 --- a/code/game/gamemodes/wizard/wizard.dm +++ b/code/game/gamemodes/wizard/wizard.dm @@ -58,65 +58,16 @@ return TRUE -/datum/game_mode/wizard/declare_completion() +/datum/game_mode/wizard/set_round_result() + ..() if(finished) SSticker.mode_result = "loss - wizard killed" - to_chat(world, "The wizard[(wizards.len>1)?"s":""] has been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!") - SSticker.news_report = WIZARD_KILLED - ..() - return 1 +/datum/game_mode/wizard/special_report() + if(finished) + return "The wizard[(wizards.len>1)?"s":""] has been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!" -/datum/game_mode/proc/auto_declare_completion_wizard() - if(wizards.len) - var/text = "
    the wizards/witches were:" - - for(var/datum/mind/wizard in wizards) - - text += "
    [wizard.key] was [wizard.name] (" - if(wizard.current) - if(wizard.current.stat == DEAD) - text += "died" - else - text += "survived" - if(wizard.current.real_name != wizard.name) - text += " as [wizard.current.real_name]" - else - text += "body destroyed" - text += ")" - - var/count = 1 - var/wizardwin = 1 - for(var/datum/objective/objective in wizard.objectives) - if(objective.check_completion()) - text += "
    Objective #[count]: [objective.explanation_text] Success! [istype(objective, /datum/objective/crew) ? "(Optional)" : ""]" - SSblackbox.record_feedback("nested tally", "wizard_objective", 1, list("[objective.type]", "SUCCESS")) - else - text += "
    Objective #[count]: [objective.explanation_text] Fail. [istype(objective, /datum/objective/crew) ? "(Optional)" : ""]" - SSblackbox.record_feedback("nested tally", "wizard_objective", 1, list("[objective.type]", "FAIL")) - if(!(istype(objective, /datum/objective/crew))) - wizardwin = 0 - count++ - - if(wizard.current && wizardwin) - text += "
    The wizard was successful!" - SSblackbox.record_feedback("tally", "wizard_success", 1, "SUCCESS") - else - text += "
    The wizard has failed!" - SSblackbox.record_feedback("tally", "wizard_success", 1, "FAIL") - if(wizard.spell_list.len>0) - text += "
    [wizard.name] used the following spells: " - var/i = 1 - for(var/obj/effect/proc_holder/spell/S in wizard.spell_list) - text += "[S.name]" - if(wizard.spell_list.len > i) - text += ", " - i++ - text += "
    " - - to_chat(world, text) - return 1 //returns whether the mob is a wizard (or apprentice) /proc/iswizard(mob/living/M) return M.mind && M.mind.has_antag_datum(/datum/antagonist/wizard,TRUE) diff --git a/code/game/machinery/Beacon.dm b/code/game/machinery/Beacon.dm index 48eafce3c5..937742930c 100644 --- a/code/game/machinery/Beacon.dm +++ b/code/game/machinery/Beacon.dm @@ -14,9 +14,8 @@ /obj/machinery/bluespace_beacon/Initialize() . = ..() var/turf/T = loc - Beacon = new /obj/item/device/radio/beacon + Beacon = new(T) Beacon.invisibility = INVISIBILITY_MAXIMUM - Beacon.loc = T hide(T.intact) @@ -42,13 +41,9 @@ /obj/machinery/bluespace_beacon/process() if(!Beacon) var/turf/T = loc - Beacon = new /obj/item/device/radio/beacon + Beacon = new(T) Beacon.invisibility = INVISIBILITY_MAXIMUM - Beacon.forceMove(T) - if(Beacon) - if(Beacon.loc != loc) - Beacon.forceMove(loc) + else if (Beacon.loc != loc) + Beacon.forceMove(loc) updateicon() - - diff --git a/code/game/machinery/PDApainter.dm b/code/game/machinery/PDApainter.dm index 61d5627354..6156ee1d86 100644 --- a/code/game/machinery/PDApainter.dm +++ b/code/game/machinery/PDApainter.dm @@ -134,7 +134,7 @@ return if(storedpda) - storedpda.loc = get_turf(src.loc) + storedpda.forceMove(drop_location()) storedpda = null update_icon() else diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 9354bd73ae..61a5d7271d 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -1,6 +1,6 @@ /obj/machinery/sleep_console name = "sleeper console" - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/machines/sleeper.dmi' icon_state = "console" density = FALSE anchored = TRUE @@ -8,7 +8,7 @@ /obj/machinery/sleeper name = "sleeper" desc = "An enclosed machine used to stabilize and heal patients." - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" density = FALSE anchored = TRUE diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index d783be292e..1e0b41bca0 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -27,7 +27,7 @@ var/prod_coeff = 1 var/datum/design/being_built - var/datum/research/files + var/datum/techweb/stored_research var/list/datum/design/matching_designs var/selected_category var/screen = 1 @@ -46,11 +46,11 @@ ) /obj/machinery/autolathe/Initialize() - AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS)) + AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS), 0, FALSE, null, null, CALLBACK(src, .proc/AfterMaterialInsert)) . = ..() wires = new /datum/wires/autolathe(src) - files = new /datum/research/autolathe(src) + stored_research = new /datum/techweb/specialized/autounlocking/autolathe matching_designs = list() /obj/machinery/autolathe/Destroy() @@ -85,7 +85,7 @@ /obj/machinery/autolathe/attackby(obj/item/O, mob/user, params) if (busy) to_chat(user, "The autolathe is busy. Please wait for completion of previous operation.") - return 1 + return TRUE if(default_deconstruction_screwdriver(user, "autolathe_t", "autolathe", O)) updateUsrDialog() @@ -97,16 +97,16 @@ if(panel_open) if(istype(O, /obj/item/crowbar)) default_deconstruction_crowbar(O) - return 1 + return TRUE else if(is_wire_tool(O)) wires.interact(user) - return 1 + return TRUE if(user.a_intent == INTENT_HARM) //so we can hit the machine return ..() if(stat) - return 1 + return TRUE if(istype(O, /obj/item/disk/design_disk)) user.visible_message("[user] begins to load \the [O] in \the [src]...", @@ -117,30 +117,23 @@ if(do_after(user, 14.4, target = src)) for(var/B in D.blueprints) if(B) - files.AddDesign2Known(B) - + stored_research.add_design(B) busy = FALSE - return 1 + return TRUE return ..() -/obj/machinery/mecha_part_fabricator/ComponentActivated(datum/component/C) - ..() - if(istype(C, /datum/component/material_container)) - var/datum/component/material_container/M = C - if(!M.last_insert_success) - return - var/lit = M.last_inserted_type - if(ispath(lit, /obj/item/ore/bluespace_crystal)) - use_power(max(500,M.last_amount_inserted/10)) - else - 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() +/obj/machinery/autolathe/proc/AfterMaterialInsert(type_inserted, id_inserted, amount_inserted) + if(ispath(type_inserted, /obj/item/ore/bluespace_crystal)) + use_power(max(500, amount_inserted / 10)) + else + switch(id_inserted) + if (MAT_METAL) + flick("autolathe_o",src)//plays metal insertion animation + if (MAT_GLASS) + flick("autolathe_r",src)//plays glass insertion animation + use_power(amount_inserted * 100) + updateUsrDialog() /obj/machinery/autolathe/Topic(href, href_list) if(..()) @@ -160,7 +153,7 @@ ///////////////// //href protection - being_built = files.FindDesignByID(href_list["make"]) //check if it's a valid design + being_built = stored_research.isDesignResearchedID(href_list["make"]) if(!being_built) return @@ -213,8 +206,8 @@ if(href_list["search"]) matching_designs.Cut() - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] if(findtext(D.name,href_list["to_search"])) matching_designs.Add(D) updateUsrDialog() @@ -267,8 +260,8 @@ dat += "

    Browsing [selected_category]:


    " dat += materials_printout() - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] if(!(selected_category in D.category)) continue @@ -334,16 +327,16 @@ /obj/machinery/autolathe/proc/can_build(datum/design/D, amount = 1) if(D.make_reagents.len) - return 0 + return FALSE var/coeff = (ispath(D.build_path, /obj/item/stack) ? 1 : prod_coeff) GET_COMPONENT(materials, /datum/component/material_container) if(D.materials[MAT_METAL] && (materials.amount(MAT_METAL) < (D.materials[MAT_METAL] * coeff * amount))) - return 0 + return FALSE if(D.materials[MAT_GLASS] && (materials.amount(MAT_GLASS) < (D.materials[MAT_GLASS] * coeff * amount))) - return 0 - return 1 + return FALSE + return TRUE /obj/machinery/autolathe/proc/get_design_cost(datum/design/D) var/coeff = (ispath(D.build_path, /obj/item/stack) ? 1 : prod_coeff) @@ -368,25 +361,26 @@ /obj/machinery/autolathe/proc/shock(mob/user, prb) if(stat & (BROKEN|NOPOWER)) // unpowered, no shock - return 0 + return FALSE if(!prob(prb)) - return 0 + return FALSE var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread s.set_up(5, 1, src) s.start() if (electrocute_mob(user, get_area(src), src, 0.7, TRUE)) - return 1 + return TRUE else - return 0 + return FALSE /obj/machinery/autolathe/proc/adjust_hacked(state) hacked = state - for(var/datum/design/D in files.possible_designs) + for(var/id in SSresearch.techweb_designs) + var/datum/design/D = SSresearch.techweb_designs[id] if((D.build_type & AUTOLATHE) && ("hacked" in D.category)) if(hacked) - files.AddDesign2Known(D) + stored_research.add_design(D) else - files.known_designs -= D.id + stored_research.remove_design(D) /obj/machinery/autolathe/hacked/Initialize() . = ..() diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 23bfc72f87..af1a168a3b 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -5,7 +5,7 @@ /obj/machinery/camera name = "security camera" desc = "It's used to monitor rooms." - icon = 'icons/obj/monitors.dmi' + icon = 'icons/obj/machines/camera.dmi' icon_state = "camera" use_power = ACTIVE_POWER_USE idle_power_usage = 5 diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm index 1424944633..952011d595 100644 --- a/code/game/machinery/camera/camera_assembly.dm +++ b/code/game/machinery/camera/camera_assembly.dm @@ -1,7 +1,7 @@ /obj/item/wallframe/camera name = "camera assembly" desc = "The basic construction for Nanotrasen-Always-Watching-You cameras." - icon = 'icons/obj/monitors.dmi' + icon = 'icons/obj/machines/camera.dmi' icon_state = "cameracase" materials = list(MAT_METAL=400, MAT_GLASS=250) result_path = /obj/structure/camera_assembly @@ -10,7 +10,7 @@ /obj/structure/camera_assembly name = "camera assembly" desc = "The basic construction for Nanotrasen-Always-Watching-You cameras." - icon = 'icons/obj/monitors.dmi' + icon = 'icons/obj/machines/camera.dmi' icon_state = "camera1" max_integrity = 150 // Motion, EMP-Proof, X-Ray diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 9b35f06acc..4cd7e7f0fe 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -13,7 +13,7 @@ name = "cloning pod" desc = "An electronically-lockable pod for growing organic tissue." density = TRUE - icon = 'icons/obj/cloning.dmi' + icon = 'icons/obj/machines/cloning.dmi' icon_state = "pod_0" req_access = list(ACCESS_CLONING) //FOR PREMATURE UNLOCKING. verb_say = "states" diff --git a/code/game/machinery/computer/_computer.dm b/code/game/machinery/computer/_computer.dm index cab6c98536..44c39d8096 100644 --- a/code/game/machinery/computer/_computer.dm +++ b/code/game/machinery/computer/_computer.dm @@ -22,7 +22,7 @@ if(!QDELETED(C)) qdel(circuit) circuit = C - C.loc = null + C.moveToNullspace() /obj/machinery/computer/Destroy() QDEL_NULL(circuit) diff --git a/code/game/machinery/computer/apc_control.dm b/code/game/machinery/computer/apc_control.dm index aa644eb738..e9390a3cf5 100644 --- a/code/game/machinery/computer/apc_control.dm +++ b/code/game/machinery/computer/apc_control.dm @@ -66,7 +66,7 @@ if(result_filters["Responsive"] && !APC.aidisabled) continue dat += "[A]
    \ - Charge: [DisplayPower(APC.cell.charge)] / [DisplayPower(APC.cell.maxcharge)] ([round((APC.cell.charge / APC.cell.maxcharge) * 100)]%)
    \ + Charge: [DisplayEnergy(APC.cell.charge)] / [DisplayEnergy(APC.cell.maxcharge)] ([round((APC.cell.charge / APC.cell.maxcharge) * 100)]%)
    \ Area: [APC.area]
    \ [APC.aidisabled || APC.panel_open ? "APC does not respond to interface query." : "APC responds to interface query."]

    " dat += "Check Logs
    " @@ -161,7 +161,7 @@ return log_activity("changed greater than charge filter to \"[new_filter]\"") if(new_filter) - new_filter = Clamp(new_filter, 0, 100) + new_filter = CLAMP(new_filter, 0, 100) playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) result_filters["Charge Above"] = new_filter if(href_list["below_filter"]) @@ -171,7 +171,7 @@ return log_activity("changed lesser than charge filter to \"[new_filter]\"") if(new_filter) - new_filter = Clamp(new_filter, 0, 100) + new_filter = CLAMP(new_filter, 0, 100) playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) result_filters["Charge Below"] = new_filter if(href_list["access_filter"]) diff --git a/code/game/machinery/computer/atmos_control.dm b/code/game/machinery/computer/atmos_control.dm index 2d1d771203..a4881546cf 100644 --- a/code/game/machinery/computer/atmos_control.dm +++ b/code/game/machinery/computer/atmos_control.dm @@ -211,7 +211,7 @@ if("pressure") var/target = input("New target pressure:", name, output_info ? output_info["internal"] : 0) as num|null if(!isnull(target) && !..()) - target = Clamp(target, 0, 50 * ONE_ATMOSPHERE) + target = CLAMP(target, 0, 50 * ONE_ATMOSPHERE) signal.data += list("tag" = output_tag, "set_internal_pressure" = target) . = TRUE radio_connection.post_signal(src, signal, filter = GLOB.RADIO_ATMOSIA) diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm index bf772a157f..44d6d5abe4 100644 --- a/code/game/machinery/computer/camera_advanced.dm +++ b/code/game/machinery/computer/camera_advanced.dm @@ -43,6 +43,7 @@ for(var/V in actions) var/datum/action/A = V A.Remove(user) + actions.Cut() if(user.client) user.reset_perspective(null) eyeobj.RemoveImages() @@ -62,6 +63,7 @@ current_user.unset_machine() if(eyeobj) qdel(eyeobj) + QDEL_LIST(actions) return ..() /obj/machinery/computer/camera_advanced/on_unset_machine(mob/M) @@ -152,7 +154,10 @@ if(!isturf(eye_user.loc)) return T = get_turf(T) - loc = T + if (T) + forceMove(T) + else + moveToNullspace() if(use_static) GLOB.cameranet.visibility(src) if(visible_icon) diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm index 53209108b2..7bbd545981 100644 --- a/code/game/machinery/computer/dna_console.dm +++ b/code/game/machinery/computer/dna_console.dm @@ -337,12 +337,12 @@ if(!num) num = round(input(usr, "Choose pulse duration:", "Input an Integer", null) as num|null) if(num) - radduration = Wrap(num, 1, RADIATION_DURATION_MAX+1) + radduration = WRAP(num, 1, RADIATION_DURATION_MAX+1) if("setstrength") if(!num) num = round(input(usr, "Choose pulse strength:", "Input an Integer", null) as num|null) if(num) - radstrength = Wrap(num, 1, RADIATION_STRENGTH_MAX+1) + radstrength = WRAP(num, 1, RADIATION_STRENGTH_MAX+1) if("screen") current_screen = href_list["text"] if("rejuv") @@ -353,13 +353,13 @@ if("setbufferlabel") var/text = sanitize(input(usr, "Input a new label:", "Input an Text", null) as text|null) if(num && text) - num = Clamp(num, 1, NUMBER_OF_BUFFERS) + num = CLAMP(num, 1, NUMBER_OF_BUFFERS) var/list/buffer_slot = buffer[num] if(istype(buffer_slot)) buffer_slot["label"] = text if("setbuffer") if(num && viable_occupant) - num = Clamp(num, 1, NUMBER_OF_BUFFERS) + num = CLAMP(num, 1, NUMBER_OF_BUFFERS) buffer[num] = list( "label"="Buffer[num]:[viable_occupant.real_name]", "UI"=viable_occupant.dna.uni_identity, @@ -370,7 +370,7 @@ ) if("clearbuffer") if(num) - num = Clamp(num, 1, NUMBER_OF_BUFFERS) + num = CLAMP(num, 1, NUMBER_OF_BUFFERS) var/list/buffer_slot = buffer[num] if(istype(buffer_slot)) buffer_slot.Cut() @@ -387,7 +387,7 @@ apply_buffer(SCANNER_ACTION_MIXED,num) if("injector") if(num && injectorready < world.time) - num = Clamp(num, 1, NUMBER_OF_BUFFERS) + num = CLAMP(num, 1, NUMBER_OF_BUFFERS) var/list/buffer_slot = buffer[num] if(istype(buffer_slot)) var/obj/item/dnainjector/timed/I @@ -405,7 +405,6 @@ powers -= 1 //To prevent just unlocking everything to get all powers to a syringe for max tech else I.remove_mutations.Add(HM) - I.origin_tech = "biotech=2;engineering=[max(1,min(6,powers))]" //With 6 powers available this tech level will be 1-6, also safety check if new powers get added var/time_coeff for(var/datum/mutation/human/HM in I.add_mutations) if(!time_coeff) @@ -437,11 +436,11 @@ injectorready = world.time + INJECTOR_TIMEOUT if("loaddisk") if(num && diskette && diskette.fields) - num = Clamp(num, 1, NUMBER_OF_BUFFERS) + num = CLAMP(num, 1, NUMBER_OF_BUFFERS) buffer[num] = diskette.fields.Copy() if("savedisk") if(num && diskette && !diskette.read_only) - num = Clamp(num, 1, NUMBER_OF_BUFFERS) + num = CLAMP(num, 1, NUMBER_OF_BUFFERS) var/list/buffer_slot = buffer[num] if(istype(buffer_slot)) diskette.name = "data disk \[[buffer_slot["label"]]\]" @@ -455,8 +454,8 @@ delayed_action = list("action"=text2num(href_list["delayaction"]),"buffer"=num) if("pulseui","pulsese") if(num && viable_occupant && connected) - radduration = Wrap(radduration, 1, RADIATION_DURATION_MAX+1) - radstrength = Wrap(radstrength, 1, RADIATION_STRENGTH_MAX+1) + radduration = WRAP(radduration, 1, RADIATION_DURATION_MAX+1) + radstrength = WRAP(radstrength, 1, RADIATION_STRENGTH_MAX+1) var/locked_state = connected.locked connected.locked = TRUE @@ -472,7 +471,7 @@ switch(href_list["task"]) //Same thing as there but values are even lower, on best part they are about 0.0*, effectively no damage if("pulseui") var/len = length(viable_occupant.dna.uni_identity) - num = Wrap(num, 1, len+1) + num = WRAP(num, 1, len+1) num = randomize_radiation_accuracy(num, radduration + (connected.precision_coeff ** 2), len) //Each manipulator level above 1 makes randomization as accurate as selected time + manipulator lvl^2 //Value is this high for the same reason as with laser - not worth the hassle of upgrading if the bonus is low var/block = round((num-1)/DNA_BLOCK_SIZE)+1 @@ -488,7 +487,7 @@ viable_occupant.updateappearance(mutations_overlay_update=1) if("pulsese") var/len = length(viable_occupant.dna.struc_enzymes) - num = Wrap(num, 1, len+1) + num = WRAP(num, 1, len+1) num = randomize_radiation_accuracy(num, radduration + (connected.precision_coeff ** 2), len) var/block = round((num-1)/DNA_BLOCK_SIZE)+1 @@ -519,10 +518,11 @@ ran = round(ran) //negative, so floor it else ran = -round(-ran) //positive, so ceiling it - return num2hex(Wrap(hex2num(input)+ran, 0, 16**length), length) + return num2hex(WRAP(hex2num(input)+ran, 0, 16**length), length) -/obj/machinery/computer/scan_consolenew/proc/randomize_radiation_accuracy(position_we_were_supposed_to_hit, radduration, number_of_blocks) - return Wrap(round(position_we_were_supposed_to_hit + gaussian(0, RADIATION_ACCURACY_MULTIPLIER/radduration), 1), 1, number_of_blocks+1) +/obj/machinery/computer/scan_consolenew/proc/randomize_radiation_accuracy(position, radduration, number_of_blocks) + var/val = round(gaussian(0, RADIATION_ACCURACY_MULTIPLIER/radduration) + position, 1) + return WRAP(val, 1, number_of_blocks+1) /obj/machinery/computer/scan_consolenew/proc/get_viable_occupant() var/mob/living/carbon/viable_occupant = null @@ -533,7 +533,7 @@ return viable_occupant /obj/machinery/computer/scan_consolenew/proc/apply_buffer(action,buffer_num) - buffer_num = Clamp(buffer_num, 1, NUMBER_OF_BUFFERS) + buffer_num = CLAMP(buffer_num, 1, NUMBER_OF_BUFFERS) var/list/buffer_slot = buffer[buffer_num] var/mob/living/carbon/viable_occupant = get_viable_occupant() if(istype(buffer_slot)) diff --git a/code/game/machinery/computer/gulag_teleporter.dm b/code/game/machinery/computer/gulag_teleporter.dm index 36da1288a9..2419dd2299 100644 --- a/code/game/machinery/computer/gulag_teleporter.dm +++ b/code/game/machinery/computer/gulag_teleporter.dm @@ -106,7 +106,7 @@ return if(!new_goal) new_goal = default_goal - id.goal = Clamp(new_goal, 0, 1000) //maximum 1000 points + id.goal = CLAMP(new_goal, 0, 1000) //maximum 1000 points if("toggle_open") if(teleporter.locked) to_chat(usr, "The teleporter is locked") diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm index 750551abda..a3ec6ba6ec 100644 --- a/code/game/machinery/computer/message.dm +++ b/code/game/machinery/computer/message.dm @@ -46,8 +46,7 @@ screen = 2 spark_system.set_up(5, 0, src) src.spark_system.start() - var/obj/item/paper/monitorkey/MK = new/obj/item/paper/monitorkey - MK.loc = src.loc + var/obj/item/paper/monitorkey/MK = new(loc) // Will help make emagging the console not so easy to get away with. MK.info += "

    �%@%(*$%&(�&?*(%&�/{}" var/time = 100 * length(src.linkedServer.decryptkey) diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm index d2005d0a55..5068955849 100644 --- a/code/game/machinery/computer/prisoner.dm +++ b/code/game/machinery/computer/prisoner.dm @@ -100,7 +100,7 @@ else if(inserted_id) switch(href_list["id"]) if("eject") - inserted_id.loc = get_turf(src) + inserted_id.forceMove(drop_location()) inserted_id.verb_pickup() inserted_id = null if("reset") diff --git a/code/game/machinery/computer/telecrystalconsoles.dm b/code/game/machinery/computer/telecrystalconsoles.dm index c879bc175a..8679652a10 100644 --- a/code/game/machinery/computer/telecrystalconsoles.dm +++ b/code/game/machinery/computer/telecrystalconsoles.dm @@ -33,7 +33,8 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E if(uplinkholder) to_chat(user, "[src] already has an uplink in it.") return - if(I.hidden_uplink) + GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, I) + if(hidden_uplink) if(!user.transferItemToLoc(I, src)) return uplinkholder = I @@ -50,32 +51,34 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E /obj/machinery/computer/telecrystals/uplinker/proc/ejectuplink() if(uplinkholder) - uplinkholder.loc = get_turf(src.loc) + uplinkholder.forceMove(drop_location()) uplinkholder = null update_icon() /obj/machinery/computer/telecrystals/uplinker/proc/donateTC(amt, addLog = 1) if(uplinkholder && linkedboss) + GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, uplinkholder) if(amt < 0) - linkedboss.storedcrystals += uplinkholder.hidden_uplink.telecrystals + linkedboss.storedcrystals += hidden_uplink.telecrystals if(addLog) - linkedboss.logTransfer("[src] donated [uplinkholder.hidden_uplink.telecrystals] telecrystals to [linkedboss].") - uplinkholder.hidden_uplink.telecrystals = 0 - else if(amt <= uplinkholder.hidden_uplink.telecrystals) - uplinkholder.hidden_uplink.telecrystals -= amt + linkedboss.logTransfer("[src] donated [hidden_uplink.telecrystals] telecrystals to [linkedboss].") + hidden_uplink.telecrystals = 0 + else if(amt <= hidden_uplink.telecrystals) + hidden_uplink.telecrystals -= amt linkedboss.storedcrystals += amt if(addLog) linkedboss.logTransfer("[src] donated [amt] telecrystals to [linkedboss].") /obj/machinery/computer/telecrystals/uplinker/proc/giveTC(amt, addLog = 1) if(uplinkholder && linkedboss) + GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, uplinkholder) if(amt < 0) - uplinkholder.hidden_uplink.telecrystals += linkedboss.storedcrystals + hidden_uplink.telecrystals += linkedboss.storedcrystals if(addLog) linkedboss.logTransfer("[src] received [linkedboss.storedcrystals] telecrystals from [linkedboss].") linkedboss.storedcrystals = 0 else if(amt <= linkedboss.storedcrystals) - uplinkholder.hidden_uplink.telecrystals += amt + hidden_uplink.telecrystals += amt linkedboss.storedcrystals -= amt if(addLog) linkedboss.logTransfer("[src] received [amt] telecrystals from [linkedboss].") @@ -95,7 +98,8 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E dat += "No linked management consoles detected. Scan for uplink stations using the management console.

    " if(uplinkholder) - dat += "[uplinkholder.hidden_uplink.telecrystals] telecrystals remain in this uplink.
    " + GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, uplinkholder) + dat += "[hidden_uplink.telecrystals] telecrystals remain in this uplink.
    " if(linkedboss) dat += "Donate TC: 1 | 5 | All" dat += "
    Eject Uplink" @@ -150,8 +154,11 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E /obj/machinery/computer/telecrystals/boss/proc/getDangerous()//This scales the TC assigned with the round population. ..() - var/danger = GLOB.joined_player_list.len - SSticker.mode.syndicates.len - danger = Ceiling(danger, 10) + var/list/nukeops = get_antagonists(/datum/antagonist/nukeop) + var/danger = GLOB.joined_player_list.len - nukeops.len +// var/list/nukeops = get_antagonists(/datum/antagonist/nukeop) +// var/danger = GLOB.joined_player_list.len - nukeops.len + danger = CEILING(danger, 10) scaleTC(danger) /obj/machinery/computer/telecrystals/boss/proc/scaleTC(amt)//Its own proc, since it'll probably need a lot of tweaks for balance, use a fancier algorhithm, etc. @@ -175,7 +182,8 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E for(var/obj/machinery/computer/telecrystals/uplinker/A in TCstations) dat += "[A.name] | " if(A.uplinkholder) - dat += "[A.uplinkholder.hidden_uplink.telecrystals] telecrystals." + GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, A.uplinkholder) + dat += "[hidden_uplink.telecrystals] telecrystals." if(storedcrystals) dat+= "
    Add TC: 1 | 5 | 10 | All" dat += "
    " @@ -218,4 +226,4 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E src.updateUsrDialog() return -#undef NUKESCALINGMODIFIER \ No newline at end of file +#undef NUKESCALINGMODIFIER diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index 99cbded13a..4328a22222 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -157,15 +157,15 @@ if(istype(P, /obj/item/crowbar)) playsound(src.loc, P.usesound, 50, 1) state = 2 - circuit.loc = src.loc + circuit.forceMove(drop_location()) components.Remove(circuit) circuit = null if(components.len == 0) to_chat(user, "You remove the circuit board.") else to_chat(user, "You remove the circuit board and other components.") - for(var/atom/movable/A in components) - A.loc = src.loc + for(var/atom/movable/AM in components) + AM.forceMove(drop_location()) desc = initial(desc) req_components = null components = null @@ -186,9 +186,9 @@ qdel(O) new_machine.component_parts = list() for(var/obj/O in src) - O.loc = null + O.moveToNullspace() new_machine.component_parts += O - circuit.loc = null + circuit.moveToNullspace() new_machine.RefreshParts() qdel(src) return diff --git a/code/game/machinery/dance_machine.dm b/code/game/machinery/dance_machine.dm index ec8779b7d2..79ec733303 100644 --- a/code/game/machinery/dance_machine.dm +++ b/code/game/machinery/dance_machine.dm @@ -459,6 +459,8 @@ var/sound/song_played = sound(selection.song_path) for(var/mob/M in range(10,src)) + if(!M.client || !(M.client.prefs.toggles & SOUND_INSTRUMENTS)) + continue if(!(M in rangers)) rangers[M] = TRUE M.playsound_local(get_turf(M), null, 100, channel = CHANNEL_JUKEBOX, S = song_played) diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm index f0e1e8a18a..b9a2a68b34 100644 --- a/code/game/machinery/deployable.dm +++ b/code/game/machinery/deployable.dm @@ -33,7 +33,7 @@ to_chat(user, "You begin repairing [src]...") playsound(loc, WT.usesound, 40, 1) if(do_after(user, 40*I.toolspeed, target = src)) - obj_integrity = Clamp(obj_integrity + 20, 0, max_integrity) + obj_integrity = CLAMP(obj_integrity + 20, 0, max_integrity) else return ..() diff --git a/code/game/machinery/dna_scanner.dm b/code/game/machinery/dna_scanner.dm index 780b7ac1f2..d1189ff8b8 100644 --- a/code/game/machinery/dna_scanner.dm +++ b/code/game/machinery/dna_scanner.dm @@ -1,7 +1,7 @@ /obj/machinery/dna_scannernew name = "\improper DNA scanner" desc = "It scans DNA structures." - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/machines/cloning.dmi' icon_state = "scanner" density = TRUE anchored = TRUE diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 449b9ea8a4..775c9dd894 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -64,7 +64,7 @@ var/obj/machinery/door/airlock/closeOther = null var/closeOtherId = null var/lockdownbyai = FALSE - assemblytype = /obj/structure/door_assembly/door_assembly_0 + assemblytype = /obj/structure/door_assembly var/justzap = FALSE normalspeed = 1 var/obj/item/electronics/airlock/electronics = null @@ -80,7 +80,7 @@ var/boltUp = 'sound/machines/boltsup.ogg' var/boltDown = 'sound/machines/boltsdown.ogg' var/noPower = 'sound/machines/doorclick.ogg' - + var/previous_airlock //what airlock assembly mineral plating was applied to var/airlock_material = null //material of inner filling; if its an airlock with glass, this should be set to "glass" var/overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' var/note_overlay_file = 'icons/obj/doors/airlocks/station/overlays.dmi' //Used for papers and photos pinned to the airlock @@ -119,8 +119,8 @@ if(damage_deflection == AIRLOCK_DAMAGE_DEFLECTION_N && security_level > AIRLOCK_SECURITY_METAL) damage_deflection = AIRLOCK_DAMAGE_DEFLECTION_R prepare_huds() - var/datum/atom_hud/data/diagnostic/diag_hud = GLOB.huds[DATA_HUD_DIAGNOSTIC] - diag_hud.add_to_hud(src) + for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds) + diag_hud.add_to_hud(src) diag_hud_set_electrified() return INITIALIZE_HINT_LATELOAD @@ -242,8 +242,8 @@ for(var/obj/machinery/doorButtons/D in GLOB.machines) D.removeMe(src) qdel(note) - var/datum/atom_hud/data/diagnostic/diag_hud = GLOB.huds[DATA_HUD_DIAGNOSTIC] - diag_hud.remove_from_hud(src) + for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds) + diag_hud.remove_from_hud(src) return ..() /obj/machinery/door/airlock/handle_atom_del(atom/A) @@ -680,7 +680,7 @@ if(ishuman(user) && prob(40) && src.density) var/mob/living/carbon/human/H = user - if(H.getBrainLoss() >= 60 && Adjacent(user)) + if((H.disabilities & DUMB) && Adjacent(user)) playsound(src.loc, 'sound/effects/bang.ogg', 25, 1) if(!istype(H.head, /obj/item/clothing/head/helmet)) H.visible_message("[user] headbutts the airlock.", \ @@ -1026,14 +1026,6 @@ if(density && !open(2)) to_chat(user, "Despite your attempts, [src] refuses to open.") -/obj/machinery/door/airlock/plasma/attackby(obj/item/C, mob/user, params) - if(C.is_hot() > 300)//If the temperature of the object is over 300, then ignite - message_admins("Plasma airlock ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_COORDJMP(src)]") - log_game("Plasma wall ignited by [key_name(user)] in [COORD(src)]") - ignite(C.is_hot()) - else - return ..() - /obj/machinery/door/airlock/open(forced=0) if( operating || welded || locked ) return FALSE @@ -1044,7 +1036,7 @@ panel_open = TRUE update_icon(AIRLOCK_OPENING) visible_message("[src]'s panel is blown off in a spray of deadly shrapnel!") - charge.loc = get_turf(src) + charge.forceMove(drop_location()) charge.ex_act(EXPLODE_DEVASTATE) detonated = 1 charge = null @@ -1154,22 +1146,22 @@ var/list/optionlist if(airlock_material == "glass") - optionlist = list("Public", "Public2", "Engineering", "Atmospherics", "Security", "Command", "Medical", "Research", "Mining", "Maintenance") + optionlist = list("Standard", "Public", "Engineering", "Atmospherics", "Security", "Command", "Medical", "Research", "Science", "Virology", "Mining", "Maintenance", "External", "External Maintenance") else - optionlist = list("Public", "Engineering", "Atmospherics", "Security", "Command", "Medical", "Research", "Mining", "Maintenance", "External", "High Security") + optionlist = list("Standard", "Public", "Engineering", "Atmospherics", "Security", "Command", "Medical", "Research", "Freezer", "Science", "Virology", "Mining", "Maintenance", "External", "External Maintenance") var/paintjob = input(user, "Please select a paintjob for this airlock.") in optionlist if((!in_range(src, usr) && src.loc != usr) || !W.use(user)) return switch(paintjob) - if("Public") + if("Standard") icon = 'icons/obj/doors/airlocks/station/public.dmi' overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' - assemblytype = /obj/structure/door_assembly/door_assembly_0 - if("Public2") + assemblytype = /obj/structure/door_assembly + if("Public") icon = 'icons/obj/doors/airlocks/station2/glass.dmi' overlays_file = 'icons/obj/doors/airlocks/station2/overlays.dmi' - assemblytype = /obj/structure/door_assembly/door_assembly_glass + assemblytype = /obj/structure/door_assembly/door_assembly_public if("Engineering") icon = 'icons/obj/doors/airlocks/station/engineering.dmi' overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' @@ -1194,6 +1186,18 @@ icon = 'icons/obj/doors/airlocks/station/research.dmi' overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' assemblytype = /obj/structure/door_assembly/door_assembly_research + if("Freezer") + icon = 'icons/obj/doors/airlocks/station/freezer.dmi' + overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' + assemblytype = /obj/structure/door_assembly/door_assembly_fre + if("Science") + icon = 'icons/obj/doors/airlocks/station/science.dmi' + overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' + assemblytype = /obj/structure/door_assembly/door_assembly_science + if("Virology") + icon = 'icons/obj/doors/airlocks/station/virology.dmi' + overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' + assemblytype = /obj/structure/door_assembly/door_assembly_viro if("Mining") icon = 'icons/obj/doors/airlocks/station/mining.dmi' overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' @@ -1206,10 +1210,10 @@ icon = 'icons/obj/doors/airlocks/external/external.dmi' overlays_file = 'icons/obj/doors/airlocks/external/overlays.dmi' assemblytype = /obj/structure/door_assembly/door_assembly_ext - if("High Security") - icon = 'icons/obj/doors/airlocks/highsec/highsec.dmi' - overlays_file = 'icons/obj/doors/airlocks/highsec/overlays.dmi' - assemblytype = /obj/structure/door_assembly/door_assembly_highsecurity + if("External Maintenance") + icon = 'icons/obj/doors/airlocks/station/maintenanceexternal.dmi' + overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' + assemblytype = /obj/structure/door_assembly/door_assembly_extmai update_icon() /obj/machinery/door/airlock/CanAStarPass(obj/item/card/id/ID) @@ -1302,11 +1306,17 @@ var/obj/structure/door_assembly/A if(assemblytype) A = new assemblytype(src.loc) - A.heat_proof_finished = src.heat_proof //tracks whether there's rglass in else - A = new /obj/structure/door_assembly/door_assembly_0(src.loc) + A = new /obj/structure/door_assembly(loc) //If you come across a null assemblytype, it will produce the default assembly instead of disintegrating. + A.heat_proof_finished = src.heat_proof //tracks whether there's rglass in + A.anchored = TRUE + A.glass = src.glass + A.state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS A.created_name = name + A.previous_assembly = previous_airlock + A.update_name() + A.update_icon() if(!disassembled) if(A) @@ -1330,7 +1340,7 @@ else ae = electronics electronics = null - ae.loc = src.loc + ae.forceMove(drop_location()) qdel(src) /obj/machinery/door/airlock/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) diff --git a/code/game/machinery/doors/airlock_types.dm b/code/game/machinery/doors/airlock_types.dm index 8b41cf3748..f303b892b3 100644 --- a/code/game/machinery/doors/airlock_types.dm +++ b/code/game/machinery/doors/airlock_types.dm @@ -1,6 +1,7 @@ /* Station Airlocks Regular */ + /obj/machinery/door/airlock/abandoned abandoned = TRUE @@ -17,7 +18,7 @@ /obj/machinery/door/airlock/engineering icon = 'icons/obj/doors/airlocks/station/engineering.dmi' assemblytype = /obj/structure/door_assembly/door_assembly_eng - + /obj/machinery/door/airlock/engineering/abandoned abandoned = TRUE @@ -37,8 +38,7 @@ /obj/machinery/door/airlock/maintenance/external name = "external airlock access" icon = 'icons/obj/doors/airlocks/station/maintenanceexternal.dmi' - assemblytype = /obj/structure/door_assembly/door_assembly_mai - normal_integrity = 250 + assemblytype = /obj/structure/door_assembly/door_assembly_extmai /obj/machinery/door/airlock/mining name = "mining airlock" @@ -75,23 +75,27 @@ Station Airlocks Glass */ +/obj/machinery/door/airlock/glass + opacity = 0 + glass = TRUE + /obj/machinery/door/airlock/glass_command icon = 'icons/obj/doors/airlocks/station/command.dmi' opacity = 0 - assemblytype = /obj/structure/door_assembly/door_assembly_com/glass + assemblytype = /obj/structure/door_assembly/door_assembly_com glass = TRUE normal_integrity = 400 /obj/machinery/door/airlock/glass_engineering icon = 'icons/obj/doors/airlocks/station/engineering.dmi' opacity = 0 - assemblytype = /obj/structure/door_assembly/door_assembly_eng/glass + assemblytype = /obj/structure/door_assembly/door_assembly_eng glass = TRUE /obj/machinery/door/airlock/glass_security icon = 'icons/obj/doors/airlocks/station/security.dmi' opacity = 0 - assemblytype = /obj/structure/door_assembly/door_assembly_sec/glass + assemblytype = /obj/structure/door_assembly/door_assembly_sec glass = TRUE normal_integrity = 400 @@ -101,45 +105,50 @@ /obj/machinery/door/airlock/glass_medical icon = 'icons/obj/doors/airlocks/station/medical.dmi' opacity = 0 - assemblytype = /obj/structure/door_assembly/door_assembly_med/glass + assemblytype = /obj/structure/door_assembly/door_assembly_med glass = TRUE /obj/machinery/door/airlock/glass_research icon = 'icons/obj/doors/airlocks/station/research.dmi' opacity = 0 - assemblytype = /obj/structure/door_assembly/door_assembly_research/glass + assemblytype = /obj/structure/door_assembly/door_assembly_research glass = TRUE /obj/machinery/door/airlock/glass_mining icon = 'icons/obj/doors/airlocks/station/mining.dmi' opacity = 0 - assemblytype = /obj/structure/door_assembly/door_assembly_min/glass + assemblytype = /obj/structure/door_assembly/door_assembly_min glass = TRUE /obj/machinery/door/airlock/glass_atmos icon = 'icons/obj/doors/airlocks/station/atmos.dmi' opacity = 0 - assemblytype = /obj/structure/door_assembly/door_assembly_atmo/glass + assemblytype = /obj/structure/door_assembly/door_assembly_atmo glass = TRUE /obj/machinery/door/airlock/glass_science icon = 'icons/obj/doors/airlocks/station/science.dmi' opacity = 0 - assemblytype = /obj/structure/door_assembly/door_assembly_science/glass + assemblytype = /obj/structure/door_assembly/door_assembly_science glass = TRUE /obj/machinery/door/airlock/glass_virology icon = 'icons/obj/doors/airlocks/station/virology.dmi' opacity = 0 - assemblytype = /obj/structure/door_assembly/door_assembly_viro/glass + assemblytype = /obj/structure/door_assembly/door_assembly_viro glass = TRUE /obj/machinery/door/airlock/glass_maintenance icon = 'icons/obj/doors/airlocks/station/maintenance.dmi' opacity = 0 - assemblytype = /obj/structure/door_assembly/door_assembly_mai/glass + assemblytype = /obj/structure/door_assembly/door_assembly_mai glass = TRUE +/obj/machinery/door/airlock/maintenance/external/glass + opacity = 0 + glass = TRUE + normal_integrity = 200 + ////////////////////////////////// /* Station Airlocks Mineral @@ -148,27 +157,36 @@ /obj/machinery/door/airlock/gold name = "gold airlock" icon = 'icons/obj/doors/airlocks/station/gold.dmi' - var/mineral = "gold" assemblytype = /obj/structure/door_assembly/door_assembly_gold +/obj/machinery/door/airlock/gold/glass + opacity = 0 + glass = TRUE + /obj/machinery/door/airlock/silver name = "silver airlock" icon = 'icons/obj/doors/airlocks/station/silver.dmi' - var/mineral = "silver" assemblytype = /obj/structure/door_assembly/door_assembly_silver +/obj/machinery/door/airlock/silver/glass + opacity = 0 + glass = TRUE + /obj/machinery/door/airlock/diamond name = "diamond airlock" icon = 'icons/obj/doors/airlocks/station/diamond.dmi' - var/mineral = "diamond" assemblytype = /obj/structure/door_assembly/door_assembly_diamond normal_integrity = 1000 explosion_block = 2 +/obj/machinery/door/airlock/diamond/glass + normal_integrity = 950 + opacity = 0 + glass = TRUE + /obj/machinery/door/airlock/uranium name = "uranium airlock" icon = 'icons/obj/doors/airlocks/station/uranium.dmi' - var/mineral = "uranium" assemblytype = /obj/structure/door_assembly/door_assembly_uranium var/last_event = 0 @@ -183,11 +201,14 @@ radiation_pulse(get_turf(src), 150) return +/obj/machinery/door/airlock/uranium/glass + opacity = 0 + glass = TRUE + /obj/machinery/door/airlock/plasma name = "plasma airlock" desc = "No way this can end badly." icon = 'icons/obj/doors/airlocks/station/plasma.dmi' - var/mineral = "plasma" assemblytype = /obj/structure/door_assembly/door_assembly_plasma /obj/machinery/door/airlock/plasma/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) @@ -200,62 +221,84 @@ /obj/machinery/door/airlock/plasma/proc/PlasmaBurn(temperature) atmos_spawn_air("plasma=500;TEMP=1000") - new/obj/structure/door_assembly/door_assembly_0( src.loc ) + var/obj/structure/door_assembly/DA + DA = new /obj/structure/door_assembly(loc) + if(glass) + DA.glass = TRUE + if(heat_proof) + DA.heat_proof_finished = TRUE + DA.update_icon() + DA.update_name() qdel(src) /obj/machinery/door/airlock/plasma/BlockSuperconductivity() //we don't stop the heat~ return 0 +/obj/machinery/door/airlock/plasma/attackby(obj/item/C, mob/user, params) + if(C.is_hot() > 300)//If the temperature of the object is over 300, then ignite + message_admins("Plasma airlock ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_COORDJMP(src)]") + log_game("Plasma airlock ignited by [key_name(user)] in [COORD(src)]") + ignite(C.is_hot()) + else + return ..() + +/obj/machinery/door/airlock/plasma/glass + opacity = 0 + glass = TRUE + /obj/machinery/door/airlock/clown name = "bananium airlock" desc = "Honkhonkhonk" icon = 'icons/obj/doors/airlocks/station/bananium.dmi' - var/mineral = "bananium" + assemblytype = /obj/structure/door_assembly/door_assembly_bananium doorOpen = 'sound/items/bikehorn.ogg' - assemblytype = /obj/structure/door_assembly/door_assembly_clown + +/obj/machinery/door/airlock/clown/glass + opacity = 0 + glass = TRUE /obj/machinery/door/airlock/sandstone name = "sandstone airlock" icon = 'icons/obj/doors/airlocks/station/sandstone.dmi' - var/mineral = "sandstone" assemblytype = /obj/structure/door_assembly/door_assembly_sandstone +/obj/machinery/door/airlock/sandstone/glass + opacity = 0 + glass = TRUE /obj/machinery/door/airlock/wood name = "wooden airlock" icon = 'icons/obj/doors/airlocks/station/wood.dmi' - var/mineral = "wood" assemblytype = /obj/structure/door_assembly/door_assembly_wood +/obj/machinery/door/airlock/wood/glass + opacity = 0 + glass = TRUE + /obj/machinery/door/airlock/titanium name = "shuttle airlock" - var/mineral = "titanium" + assemblytype = /obj/structure/door_assembly/door_assembly_titanium icon = 'icons/obj/doors/airlocks/shuttle/shuttle.dmi' overlays_file = 'icons/obj/doors/airlocks/shuttle/overlays.dmi' - assemblytype = /obj/structure/door_assembly/door_assembly_titanium normal_integrity = 400 -/obj/machinery/door/airlock/glass_titanium - name = "shuttle airlock" - var/mineral = "titanium" - icon = 'icons/obj/doors/airlocks/shuttle/shuttle.dmi' - overlays_file = 'icons/obj/doors/airlocks/shuttle/overlays.dmi' - opacity = 0 - assemblytype = /obj/structure/door_assembly/door_assembly_titanium/glass - glass = TRUE +/obj/machinery/door/airlock/titanium/glass normal_integrity = 350 + opacity = 0 + glass = TRUE ////////////////////////////////// /* Station2 Airlocks */ -/obj/machinery/door/airlock/glass - name = "glass airlock" +/obj/machinery/door/airlock/public icon = 'icons/obj/doors/airlocks/station2/glass.dmi' overlays_file = 'icons/obj/doors/airlocks/station2/overlays.dmi' + assemblytype = /obj/structure/door_assembly/door_assembly_public + +/obj/machinery/door/airlock/public/glass opacity = 0 - assemblytype = /obj/structure/door_assembly/door_assembly_glass glass = TRUE ////////////////////////////////// @@ -269,13 +312,8 @@ overlays_file = 'icons/obj/doors/airlocks/external/overlays.dmi' note_overlay_file = 'icons/obj/doors/airlocks/external/overlays.dmi' assemblytype = /obj/structure/door_assembly/door_assembly_ext - explosion_block = 1 -/obj/machinery/door/airlock/glass_external - name = "external airlock" - icon = 'icons/obj/doors/airlocks/external/external.dmi' - overlays_file = 'icons/obj/doors/airlocks/external/overlays.dmi' - assemblytype = /obj/structure/door_assembly/door_assembly_ext/glass +/obj/machinery/door/airlock/external/glass opacity = 0 glass = TRUE @@ -287,7 +325,6 @@ /obj/machinery/door/airlock/centcom icon = 'icons/obj/doors/airlocks/centcom/centcom.dmi' overlays_file = 'icons/obj/doors/airlocks/centcom/overlays.dmi' - opacity = 1 assemblytype = /obj/structure/door_assembly/door_assembly_centcom normal_integrity = 1000 security_level = 6 @@ -305,7 +342,6 @@ name = "vault door" icon = 'icons/obj/doors/airlocks/vault/vault.dmi' overlays_file = 'icons/obj/doors/airlocks/vault/overlays.dmi' - opacity = 1 assemblytype = /obj/structure/door_assembly/door_assembly_vault explosion_block = 2 normal_integrity = 400 // reverse engieneerd: 400 * 1.5 (sec lvl 6) = 600 = original @@ -321,7 +357,6 @@ icon = 'icons/obj/doors/airlocks/hatch/centcom.dmi' overlays_file = 'icons/obj/doors/airlocks/hatch/overlays.dmi' note_overlay_file = 'icons/obj/doors/airlocks/hatch/overlays.dmi' - opacity = 1 assemblytype = /obj/structure/door_assembly/door_assembly_hatch /obj/machinery/door/airlock/maintenance_hatch @@ -329,7 +364,6 @@ icon = 'icons/obj/doors/airlocks/hatch/maintenance.dmi' overlays_file = 'icons/obj/doors/airlocks/hatch/overlays.dmi' note_overlay_file = 'icons/obj/doors/airlocks/hatch/overlays.dmi' - opacity = 1 assemblytype = /obj/structure/door_assembly/door_assembly_mhatch /obj/machinery/door/airlock/maintenance_hatch/abandoned @@ -361,6 +395,10 @@ overlays_file = 'icons/obj/doors/airlocks/shuttle/overlays.dmi' assemblytype = /obj/structure/door_assembly/door_assembly_shuttle +/obj/machinery/door/airlock/shuttle/glass + opacity = 0 + glass = TRUE + /obj/machinery/door/airlock/abductor name = "alien airlock" desc = "With humanity's current technological level, it could take years to hack this advanced airlock... or maybe we should give a screwdriver a try?" @@ -369,7 +407,6 @@ assemblytype = /obj/structure/door_assembly/door_assembly_abductor note_overlay_file = 'icons/obj/doors/airlocks/external/overlays.dmi' damage_deflection = 30 - opacity = 1 explosion_block = 3 hackProof = TRUE aiControlDisabled = 1 @@ -422,7 +459,6 @@ friendly = TRUE /obj/machinery/door/airlock/cult/glass - assemblytype = /obj/structure/door_assembly/door_assembly_cult/glass glass = TRUE opacity = 0 @@ -439,7 +475,6 @@ friendly = TRUE /obj/machinery/door/airlock/cult/unruned/glass - assemblytype = /obj/structure/door_assembly/door_assembly_cult/unruned/glass glass = TRUE opacity = 0 @@ -452,7 +487,6 @@ desc = "A massive cogwheel set into two heavy slabs of brass." icon = 'icons/obj/doors/airlocks/clockwork/pinion_airlock.dmi' overlays_file = 'icons/obj/doors/airlocks/clockwork/overlays.dmi' - opacity = 1 hackProof = TRUE aiControlDisabled = TRUE req_access = list(ACCESS_CLOCKCULT) diff --git a/code/game/machinery/doors/alarmlock.dm b/code/game/machinery/doors/alarmlock.dm index 3733c71844..5630b3ffb0 100644 --- a/code/game/machinery/doors/alarmlock.dm +++ b/code/game/machinery/doors/alarmlock.dm @@ -1,45 +1,44 @@ -/obj/machinery/door/airlock/alarmlock - - name = "glass alarm airlock" - icon = 'icons/obj/doors/airlocks/station2/glass.dmi' - overlays_file = 'icons/obj/doors/airlocks/station2/overlays.dmi' - opacity = 0 - assemblytype = /obj/structure/door_assembly/door_assembly_glass +/obj/machinery/door/airlock/alarmlock + name = "glass alarm airlock" + icon = 'icons/obj/doors/airlocks/station2/glass.dmi' + overlays_file = 'icons/obj/doors/airlocks/station2/overlays.dmi' + opacity = 0 + assemblytype = /obj/structure/door_assembly/door_assembly_public glass = TRUE - - var/datum/radio_frequency/air_connection - var/air_frequency = 1437 + + var/datum/radio_frequency/air_connection + var/air_frequency = 1437 autoclose = FALSE - -/obj/machinery/door/airlock/alarmlock/New() - ..() - air_connection = new - -/obj/machinery/door/airlock/alarmlock/Destroy() + +/obj/machinery/door/airlock/alarmlock/New() + ..() + air_connection = new + +/obj/machinery/door/airlock/alarmlock/Destroy() SSradio.remove_object(src,air_frequency) - air_connection = null - return ..() - -/obj/machinery/door/airlock/alarmlock/Initialize() + air_connection = null + return ..() + +/obj/machinery/door/airlock/alarmlock/Initialize() . = ..() - SSradio.remove_object(src, air_frequency) - air_connection = SSradio.add_object(src, air_frequency, GLOB.RADIO_TO_AIRALARM) - open() - -/obj/machinery/door/airlock/alarmlock/receive_signal(datum/signal/signal) - ..() - if(stat & (NOPOWER|BROKEN)) - return - - var/alarm_area = signal.data["zone"] - var/alert = signal.data["alert"] - - var/area/our_area = get_area(src) - if(alarm_area == our_area.name) - switch(alert) - if("severe") + SSradio.remove_object(src, air_frequency) + air_connection = SSradio.add_object(src, air_frequency, GLOB.RADIO_TO_AIRALARM) + open() + +/obj/machinery/door/airlock/alarmlock/receive_signal(datum/signal/signal) + ..() + if(stat & (NOPOWER|BROKEN)) + return + + var/alarm_area = signal.data["zone"] + var/alert = signal.data["alert"] + + var/area/our_area = get_area(src) + if(alarm_area == our_area.name) + switch(alert) + if("severe") autoclose = TRUE - close() - if("minor", "clear") + close() + if("minor", "clear") autoclose = FALSE - open() \ No newline at end of file + open() diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm index 4c0d4a1804..a622f0af3d 100644 --- a/code/game/machinery/doors/brigdoors.dm +++ b/code/game/machinery/doors/brigdoors.dm @@ -142,7 +142,7 @@ . /= 10 /obj/machinery/door_timer/proc/set_timer(value) - var/new_time = Clamp(value,0,MAX_TIMER) + var/new_time = CLAMP(value,0,MAX_TIMER) . = new_time == timer_duration //return 1 on no change timer_duration = new_time diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index e446670105..30ae436289 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -255,12 +255,15 @@ return 1 if(operating) return + if(welded) + return if(safe) for(var/atom/movable/M in get_turf(src)) if(M.density && M != src) //something is blocking the door if(autoclose) addtimer(CALLBACK(src, .proc/autoclose), 60) return + operating = TRUE do_animate("closing") diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index ad746d089f..edb5529840 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -22,7 +22,7 @@ layer = BELOW_OPEN_DOOR_LAYER closingLayer = CLOSED_FIREDOOR_LAYER assemblytype = /obj/structure/firelock_frame - armor = list(melee = 30, bullet = 30, laser = 20, energy = 20, bomb = 10, bio = 100, rad = 100, fire = 95, acid = 70) + armor = list("melee" = 30, "bullet" = 30, "laser" = 20, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 70) var/boltslocked = TRUE var/list/affecting_areas diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 2313afec3b..dce884b794 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -275,7 +275,7 @@ else ae = electronics electronics = null - ae.loc = src.loc + ae.forceMove(drop_location()) qdel(src) return @@ -495,4 +495,4 @@ /obj/machinery/door/window/brigdoor/security/holding/southright dir = SOUTH icon_state = "rightsecure" - base_state = "rightsecure" \ No newline at end of file + base_state = "rightsecure" diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm index 8c4772f43a..c13dfc9b88 100644 --- a/code/game/machinery/doppler_array.dm +++ b/code/game/machinery/doppler_array.dm @@ -7,8 +7,8 @@ GLOBAL_LIST_EMPTY(doppler_arrays) icon_state = "tdoppler" density = TRUE anchored = TRUE - var/integrated = 0 - var/max_dist = 100 + var/integrated = FALSE + var/max_dist = 150 verb_say = "states coldly" /obj/machinery/doppler_array/Initialize() @@ -80,7 +80,7 @@ GLOBAL_LIST_EMPTY(doppler_arrays) "Epicenter at: grid ([epicenter.x],[epicenter.y]). Temporal displacement of tachyons: [took] seconds.", \ "Factual: Epicenter radius: [devastation_range]. Outer radius: [heavy_impact_range]. Shockwave radius: [light_impact_range].") - // If the bomb was capped, say it's theoretical size. + // If the bomb was capped, say its theoretical size. if(devastation_range < orig_dev_range || heavy_impact_range < orig_heavy_range || light_impact_range < orig_light_range) messages += "Theoretical: Epicenter radius: [orig_dev_range]. Outer radius: [orig_heavy_range]. Shockwave radius: [orig_light_range]." @@ -107,6 +107,32 @@ GLOBAL_LIST_EMPTY(doppler_arrays) //Portable version, built into EOD equipment. It simply provides an explosion's three damage levels. /obj/machinery/doppler_array/integrated name = "integrated tachyon-doppler module" - integrated = 1 + integrated = TRUE max_dist = 21 //Should detect most explosions in hearing range. use_power = NO_POWER_USE + +/obj/machinery/doppler_array/research + name = "tachyon-dopplar research array" + desc = "A specialized tacyhon-dopplar bomb detection array that uses the results of the highest yield of explosions for research." + var/datum/techweb/linked_techweb + +/obj/machinery/doppler_array/research/sense_explosion(turf/epicenter, dev, heavy, light, time, orig_dev, orig_heavy, orig_light) //probably needs a way to ignore admin explosives later on + . = ..() + if(!istype(linked_techweb)) + say("Warning: No linked research system!") + return + var/point_gain = techweb_scale_bomb(orig_light - 20 - linked_techweb.max_bomb_value) + if(!point_gain) + return + linked_techweb.max_bomb_value = orig_light - 20 + linked_techweb.research_points += point_gain + say("Gained [point_gain] points from explosion dataset.") + +/obj/machinery/doppler_array/research/science + +/obj/machinery/doppler_array/research/science/Initialize() + . = ..() + linked_techweb = SSresearch.science_tech + +/proc/techweb_scale_bomb(lightradius) + return (lightradius ** 0.5) * 13000 diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 41c0fabcae..ae4af4072d 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -237,7 +237,7 @@ user.visible_message("[user] removes the fire alarm assembly from the wall.", \ "You remove the fire alarm assembly from the wall.") var/obj/item/wallframe/firealarm/frame = new /obj/item/wallframe/firealarm() - frame.loc = user.loc + frame.forceMove(user.drop_location()) playsound(src.loc, W.usesound, 50, 1) qdel(src) return diff --git a/code/game/machinery/gulag_teleporter.dm b/code/game/machinery/gulag_teleporter.dm index 2d7c7708b3..380760963d 100644 --- a/code/game/machinery/gulag_teleporter.dm +++ b/code/game/machinery/gulag_teleporter.dm @@ -164,7 +164,6 @@ The console is located at computer/gulag_teleporter.dm /obj/item/circuitboard/machine/gulag_teleporter name = "labor camp teleporter (Machine Board)" build_path = /obj/machinery/gulag_teleporter - origin_tech = "programming=3;engineering=4;bluespace=4;materials=4" req_components = list( /obj/item/ore/bluespace_crystal = 2, /obj/item/stock_parts/scanning_module, diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index afc463a60e..10a552564b 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -47,6 +47,12 @@ Possible to do for anyone motivated enough: var/temp = "" var/list/holo_calls //array of /datum/holocalls var/datum/holocall/outgoing_call //do not modify the datums only check and call the public procs + var/obj/item/disk/holodisk/disk //Record disk + var/replay_mode = FALSE //currently replaying a recording + var/record_mode = FALSE //currently recording + var/record_start = 0 //recording start time + var/record_user //user that inititiated the recording + var/obj/effect/overlay/holo_pad_hologram/replay_holo //replay hologram var/static/force_answer_call = FALSE //Calls will be automatically answered after a couple rings, here for debugging var/static/list/holopads = list() @@ -64,6 +70,14 @@ Possible to do for anyone motivated enough: for (var/I in masters) clear_holo(I) + + if(replay_mode) + replay_stop() + if(record_mode) + record_stop() + + QDEL_NULL(disk) + holopads -= src return ..() @@ -72,6 +86,10 @@ Possible to do for anyone motivated enough: stat &= ~NOPOWER else stat |= NOPOWER + if(replay_mode) + replay_stop() + if(record_mode) + record_stop() if(outgoing_call) outgoing_call.ConnectionFailure(src) @@ -101,6 +119,18 @@ Possible to do for anyone motivated enough: if(default_deconstruction_crowbar(P)) return + + if(istype(P,/obj/item/disk/holodisk)) + if(disk) + to_chat(user,"There's already a disk inside [src]") + return + if (!user.transferItemToLoc(P,src)) + return + to_chat(user,"You insert [P] into [src]") + disk = P + updateDialog() + return + return ..() /obj/machinery/holopad/AltClick(mob/living/carbon/human/user) @@ -122,6 +152,17 @@ Possible to do for anyone motivated enough: else dat = "Request an AI's presence.
    " dat += "Call another holopad.
    " + if(disk) + if(disk.record) + //Replay + dat += "Replay disk recording.
    " + //Clear + dat += "Clear disk recording.
    " + else + //Record + dat += "Start new recording.
    " + //Eject + dat += "Eject disk.
    " if(LAZYLEN(holo_calls)) dat += "=====================================================
    " @@ -145,7 +186,7 @@ Possible to do for anyone motivated enough: dat += "Disconnect call from [HC.user].
    " - var/datum/browser/popup = new(user, "holopad", name, 300, 130) + var/datum/browser/popup = new(user, "holopad", name, 300, 150) popup.set_content(dat) popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) popup.open() @@ -216,6 +257,22 @@ Possible to do for anyone motivated enough: if(outgoing_call) outgoing_call.Disconnect() + else if(href_list["disk_eject"]) + if(disk && !replay_mode) + disk.forceMove(drop_location()) + disk = null + + else if(href_list["replay_stop"]) + replay_stop() + else if(href_list["replay_start"]) + replay_start() + else if(href_list["record_start"]) + record_start(usr) + else if(href_list["record_stop"]) + record_stop() + else if(href_list["record_clear"]) + record_clear() + updateDialog() //do not allow AIs to answer calls or people will use it to meta the AI sattelite @@ -269,6 +326,7 @@ Possible to do for anyone motivated enough: else playsound(src, 'sound/machines/twobeep.ogg', 100) //bring, bring! + /obj/machinery/holopad/proc/activate_holo(mob/living/user) var/mob/living/silicon/ai/AI = user if(!istype(AI)) @@ -321,15 +379,24 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ if(outgoing_call && speaker == outgoing_call.user) outgoing_call.hologram.say(raw_message) + if(record_mode && speaker == record_user) + record_message(speaker,raw_message,message_language) + /obj/machinery/holopad/proc/SetLightsAndPower() var/total_users = masters.len + LAZYLEN(holo_calls) use_power = total_users > 0 ? ACTIVE_POWER_USE : IDLE_POWER_USE active_power_usage = HOLOPAD_PASSIVE_POWER_USAGE + (HOLOGRAM_POWER_USAGE * total_users) - if(total_users) + if(total_users || replay_mode) set_light(2) - icon_state = "holopad1" else set_light(0) + update_icon() + +/obj/machinery/holopad/update_icon() + var/total_users = masters.len + LAZYLEN(holo_calls) + if(total_users || replay_mode) + icon_state = "holopad1" + else icon_state = "holopad0" /obj/machinery/holopad/proc/set_holo(mob/living/user, var/obj/effect/overlay/holo_pad_hologram/h) @@ -357,7 +424,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ if(masters[user]) var/obj/effect/overlay/holo_pad_hologram/H = masters[user] step_to(H, new_turf) - H.loc = new_turf + H.forceMove(new_turf) var/area/holo_area = get_area(src) var/area/eye_area = new_turf.loc @@ -365,6 +432,128 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ clear_holo(user) return TRUE +// RECORDED MESSAGES + +/obj/machinery/holopad/proc/setup_replay_holo(datum/holorecord/record) + var/obj/effect/overlay/holo_pad_hologram/Hologram = new(loc)//Spawn a blank effect at the location. + Hologram.add_overlay(record.caller_image) + Hologram.alpha = 170 + Hologram.add_atom_colour("#77abff", FIXED_COLOUR_PRIORITY) + Hologram.dir = SOUTH //for now + Hologram.grant_all_languages(omnitongue=TRUE) + var/datum/language_holder/holder = Hologram.get_language_holder() + holder.selected_default_language = record.language + Hologram.mouse_opacity = MOUSE_OPACITY_TRANSPARENT//So you can't click on it. + Hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them. + Hologram.anchored = TRUE//So space wind cannot drag it. + Hologram.name = "[record.caller_name] (Hologram)"//If someone decides to right click. + Hologram.set_light(2) //hologram lighting + visible_message("A holographic image of [record.caller_name] flickers to life before your eyes!") + return Hologram + +/obj/machinery/holopad/proc/replay_start() + if(!replay_mode) + replay_mode = TRUE + replay_holo = setup_replay_holo(disk.record) + temp = "Replaying...
    " + temp += "End replay." + SetLightsAndPower() + replay_entry(1) + return + +/obj/machinery/holopad/proc/replay_stop() + if(replay_mode) + replay_mode = FALSE + temp = null + QDEL_NULL(replay_holo) + SetLightsAndPower() + updateDialog() + +/obj/machinery/holopad/proc/record_start(mob/living/user) + if(!user || !disk || disk.record) + return + disk.record = new + record_mode = TRUE + record_start = world.time + record_user = user + disk.record.caller_image = get_record_icon(user) + temp = "Recording...
    " + temp += "End recording." + +/obj/machinery/holopad/proc/get_record_icon(mob/living/user) + var/olddir = user.dir + user.setDir(SOUTH) + . = getFlatIcon(user) + user.setDir(olddir) + +/obj/machinery/holopad/proc/record_message(mob/living/speaker,message,language) + if(!record_mode) + return + //make this command so you can have multiple languages in single record + if(!disk.record.caller_name && istype(speaker)) + disk.record.caller_name = speaker.name + if(!disk.record.language) + disk.record.language = language + else if(language != disk.record.language) + disk.record.entries += list(list(HOLORECORD_LANGUAGE,language)) + + var/current_delay = 0 + for(var/E in disk.record.entries) + var/list/entry = E + if(entry[1] != HOLORECORD_DELAY) + continue + current_delay += entry[2] + + var/time_delta = world.time - record_start - current_delay + + if(time_delta >= 1) + disk.record.entries += list(list(HOLORECORD_DELAY,time_delta)) + disk.record.entries += list(list(HOLORECORD_SAY,message)) + if(disk.record.entries.len >= HOLORECORD_MAX_LENGTH) + record_stop() + +/obj/machinery/holopad/proc/replay_entry(entry_number) + if(!replay_mode) + return + if(disk.record.entries.len < entry_number) + replay_stop() + return + var/list/entry = disk.record.entries[entry_number] + var/command = entry[1] + switch(command) + if(HOLORECORD_SAY) + var/message = entry[2] + if(replay_holo) + replay_holo.say(message) + if(HOLORECORD_SOUND) + playsound(src,entry[2],50,1) + if(HOLORECORD_DELAY) + addtimer(CALLBACK(src,.proc/replay_entry,entry_number+1),entry[2]) + return + if(HOLORECORD_LANGUAGE) + var/datum/language_holder/holder = replay_holo.get_language_holder() + holder.selected_default_language = entry[2] + if(HOLORECORD_PRESET) + var/preset_type = entry[2] + var/datum/preset_holoimage/H = new preset_type + replay_holo.cut_overlays() + replay_holo.add_overlay(H.build_image()) + if(HOLORECORD_RENAME) + replay_holo.name = entry[2] + " (Hologram)" + .(entry_number+1) + +/obj/machinery/holopad/proc/record_stop() + if(record_mode) + record_mode = FALSE + temp = null + record_user = null + updateDialog() + +/obj/machinery/holopad/proc/record_clear() + if(disk && disk.record) + QDEL_NULL(disk.record) + updateDialog() + /obj/effect/overlay/holo_pad_hologram var/mob/living/Impersonation var/datum/holocall/HC diff --git a/code/game/machinery/launch_pad.dm b/code/game/machinery/launch_pad.dm index 4f4e481905..d66427b9bc 100644 --- a/code/game/machinery/launch_pad.dm +++ b/code/game/machinery/launch_pad.dm @@ -242,7 +242,6 @@ icon_state = "blpad-remote" w_class = WEIGHT_CLASS_SMALL slot_flags = SLOT_BELT - origin_tech = "materials=3;magnets=2;bluespace=4;syndicate=3" var/sending = TRUE var/obj/machinery/launchpad/briefcase/pad diff --git a/code/game/machinery/limbgrower.dm b/code/game/machinery/limbgrower.dm index f31a2d2436..e661bc24c5 100644 --- a/code/game/machinery/limbgrower.dm +++ b/code/game/machinery/limbgrower.dm @@ -10,7 +10,7 @@ icon = 'icons/obj/machines/limbgrower.dmi' icon_state = "limbgrower_idleoff" density = TRUE - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 10 @@ -22,7 +22,7 @@ var/busy = FALSE var/prod_coeff = 1 var/datum/design/being_built - var/datum/research/files + var/datum/techweb/stored_research var/selected_category var/screen = 1 var/list/categories = list( @@ -35,7 +35,7 @@ /obj/machinery/limbgrower/Initialize() . = ..() create_reagents(0) - files = new /datum/research/limbgrower(src) + stored_research = new /datum/techweb/specialized/autounlocking/limbgrower /obj/machinery/limbgrower/interact(mob/user) if(!is_operational()) @@ -95,7 +95,7 @@ ///////////////// //href protection - being_built = files.FindDesignByID(href_list["make"]) //check if it's a valid design + being_built = stored_research.isDesignResearchedID(href_list["make"]) //check if it's a valid design if(!being_built) return @@ -180,8 +180,8 @@ dat += "

    Browsing [selected_category]:


    " dat += materials_printout() - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] if(!(selected_category in D.category)) continue if(disabled || !can_build(D)) @@ -222,8 +222,8 @@ /obj/machinery/limbgrower/emag_act(mob/user) if(emagged) return - for(var/datum/design/D in files.possible_designs) + for(var/datum/design/D in SSresearch.techweb_designs) if((D.build_type & LIMBGROWER) && ("special" in D.category)) - files.AddDesign2Known(D) + stored_research.add_design(D) to_chat(user, "A warning flashes onto the screen, stating that safety overrides have been deactivated!") emagged = TRUE diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index 18acd9ece7..ee9b1ff31a 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -780,7 +780,7 @@ GLOBAL_LIST_EMPTY(allCasters) /obj/machinery/newscaster/proc/AttachPhoto(mob/user) if(photo) if(!photo.sillynewscastervar) - photo.loc = loc + photo.forceMove(drop_location()) if(!issilicon(user)) user.put_in_inactive_hand(photo) else @@ -856,7 +856,7 @@ GLOBAL_LIST_EMPTY(allCasters) NEWSPAPER.wantedBody = GLOB.news_network.wanted_issue.body if(GLOB.news_network.wanted_issue.img) NEWSPAPER.wantedPhoto = GLOB.news_network.wanted_issue.img - NEWSPAPER.loc = get_turf(src) + NEWSPAPER.forceMove(drop_location()) NEWSPAPER.creationTime = GLOB.news_network.lastAction paper_remaining-- diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm index 06cdfcda7d..a67ce24c9c 100644 --- a/code/game/machinery/pipe/pipe_dispenser.dm +++ b/code/game/machinery/pipe/pipe_dispenser.dm @@ -53,9 +53,9 @@ new /obj/item/pipe_meter(loc) wait = world.time + 15 if(href_list["layer_up"]) - piping_layer = Clamp(++piping_layer, PIPING_LAYER_MIN, PIPING_LAYER_MAX) + piping_layer = CLAMP(++piping_layer, PIPING_LAYER_MIN, PIPING_LAYER_MAX) if(href_list["layer_down"]) - piping_layer = Clamp(--piping_layer, PIPING_LAYER_MIN, PIPING_LAYER_MAX) + piping_layer = CLAMP(--piping_layer, PIPING_LAYER_MIN, PIPING_LAYER_MAX) return /obj/machinery/pipedispenser/attackby(obj/item/W, mob/user, params) diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 20f56d5f2d..5a863e85da 100755 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -10,6 +10,7 @@ circuit = /obj/item/circuitboard/machine/recharger var/obj/item/charging = null var/recharge_coeff = 1 + var/static/list/allowed_devices = typecacheof(list( /obj/item/gun/energy, /obj/item/melee/baton, @@ -78,7 +79,7 @@ add_fingerprint(user) if(charging) charging.update_icon() - charging.loc = loc + charging.forceMove(drop_location()) user.put_in_hands(charging) charging = null use_power = IDLE_POWER_USE @@ -90,7 +91,7 @@ /obj/machinery/recharger/attack_tk(mob/user) if(charging) charging.update_icon() - charging.loc = loc + charging.forceMove(drop_location()) charging = null use_power = IDLE_POWER_USE update_icon() diff --git a/code/game/machinery/robot_fabricator.dm b/code/game/machinery/robot_fabricator.dm index 606f64c7f3..c01c72d7a8 100644 --- a/code/game/machinery/robot_fabricator.dm +++ b/code/game/machinery/robot_fabricator.dm @@ -137,7 +137,7 @@ Please wait until completion...
    spawn (build_time) if (!isnull(src.being_built)) - src.being_built.loc = get_turf(src) + src.being_built.forceMove(drop_location()) src.being_built = null src.use_power = IDLE_POWER_USE operating = FALSE diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index 9356314973..cdbdb195cc 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -256,7 +256,7 @@ use_stored_power(50) /obj/machinery/shieldwallgen/proc/use_stored_power(amount) - power = Clamp(power - amount, 0, maximum_stored_power) + power = CLAMP(power - amount, 0, maximum_stored_power) update_activity() /obj/machinery/shieldwallgen/proc/update_activity() diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index b45b393ab2..eb24a04b0f 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -121,7 +121,7 @@ settableTemperatureRange = cap * 30 efficiency = (cap + 1) * 10000 - targetTemperature = Clamp(targetTemperature, + targetTemperature = CLAMP(targetTemperature, max(settableTemperatureMedian - settableTemperatureRange, TCMB), settableTemperatureMedian + settableTemperatureRange) @@ -223,12 +223,12 @@ target= text2num(target) + T0C . = TRUE if(.) - targetTemperature = Clamp(round(target), + targetTemperature = CLAMP(round(target), max(settableTemperatureMedian - settableTemperatureRange, TCMB), settableTemperatureMedian + settableTemperatureRange) if("eject") if(panel_open && cell) - cell.loc = get_turf(src) + cell.forceMove(drop_location()) cell = null . = TRUE diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index d3825b9afe..53c0b746bd 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -2,7 +2,7 @@ /obj/machinery/suit_storage_unit name = "suit storage unit" desc = "An industrial unit made to hold space suits. It comes with a built-in UV cauterization mechanism. A small warning label advises that organic matter should not be placed into the unit." - icon = 'icons/obj/suitstorage.dmi' + icon = 'icons/obj/machines/suit_storage.dmi' icon_state = "close" anchored = TRUE density = TRUE @@ -210,7 +210,7 @@ mob_occupant.adjustFireLoss(rand(20, 36)) else mob_occupant.adjustFireLoss(rand(10, 16)) - mob_occupant.emote("scream") + mob_occupant.emote("scream") addtimer(CALLBACK(src, .proc/cook), 50) else uv_cycles = initial(uv_cycles) diff --git a/code/game/machinery/syndicatebeacon.dm b/code/game/machinery/syndicatebeacon.dm index f8f980a1ee..0b050769d9 100644 --- a/code/game/machinery/syndicatebeacon.dm +++ b/code/game/machinery/syndicatebeacon.dm @@ -109,7 +109,6 @@ lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' desc = "A label on it reads: Warning: Activating this device will send a special beacon to your location." - origin_tech = "bluespace=6;syndicate=5" w_class = WEIGHT_CLASS_SMALL var/droptype = /obj/machinery/power/singularity_beacon/syndicate @@ -125,9 +124,7 @@ /obj/item/device/sbeacondrop/bomb desc = "A label on it reads: Warning: Activating this device will send a high-ordinance explosive to your location." droptype = /obj/machinery/syndicatebomb - origin_tech = "bluespace=5;syndicate=5" /obj/item/device/sbeacondrop/powersink desc = "A label on it reads: Warning: Activating this device will send a power draining device to your location." droptype = /obj/item/device/powersink - origin_tech = "bluespace=4;syndicate=5" diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm index bdd34e8d23..528faba57f 100644 --- a/code/game/machinery/syndicatebomb.dm +++ b/code/game/machinery/syndicatebomb.dm @@ -205,7 +205,7 @@ /obj/machinery/syndicatebomb/proc/settings(mob/user) var/new_timer = input(user, "Please set the timer.", "Timer", "[timer_set]") as num if(in_range(src, user) && isliving(user)) //No running off and setting bombs from across the station - timer_set = Clamp(new_timer, minimum_timer, maximum_timer) + timer_set = CLAMP(new_timer, minimum_timer, maximum_timer) loc.visible_message("[icon2html(src, viewers(src))] timer set for [timer_set] seconds.") if(alert(user,"Would you like to start the countdown now?",,"Yes","No") == "Yes" && in_range(src, user) && isliving(user)) if(defused || active) @@ -274,7 +274,6 @@ lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi' w_class = WEIGHT_CLASS_NORMAL - origin_tech = "syndicate=5;combat=6" resistance_flags = FLAMMABLE //Burnable (but the casing isn't) var/adminlog = null var/range_heavy = 3 @@ -308,7 +307,6 @@ /obj/item/bombcore/training name = "dummy payload" desc = "A Nanotrasen replica of a syndicate payload. Its not intended to explode but to announce that it WOULD have exploded, then rewire itself to allow for more training." - origin_tech = null var/defusals = 0 var/attempts = 0 @@ -347,7 +345,6 @@ /obj/item/bombcore/badmin name = "badmin payload" desc = "If you're seeing this someone has either made a mistake or gotten dangerously savvy with var editing!" - origin_tech = null /obj/item/bombcore/badmin/defuse() //because we wouldn't want them being harvested by players var/obj/machinery/syndicatebomb/B = loc @@ -390,7 +387,6 @@ /obj/item/bombcore/chemical name = "chemical payload" desc = "An explosive payload designed to spread chemicals, dangerous or otherwise, across a large area. Properties of the core may vary with grenade casing type, and must be loaded before use." - origin_tech = "combat=4;materials=3" icon_state = "chemcore" var/list/beakers = list() var/max_beakers = 1 // Read on about grenade casing properties below @@ -522,7 +518,6 @@ lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' w_class = WEIGHT_CLASS_TINY - origin_tech = "syndicate=3" var/timer = 0 var/detonated = 0 var/existant = 0 diff --git a/code/game/machinery/transformer.dm b/code/game/machinery/transformer.dm index 79428fce6f..7624312f84 100644 --- a/code/game/machinery/transformer.dm +++ b/code/game/machinery/transformer.dm @@ -57,7 +57,7 @@ var/move_dir = get_dir(loc, AM.loc) var/mob/living/carbon/human/H = AM if((transform_standing || H.lying) && move_dir == EAST)// || move_dir == WEST) - AM.loc = src.loc + AM.forceMove(drop_location()) do_transform(AM) /obj/machinery/transformer/CanPass(atom/movable/mover, turf/target) @@ -98,9 +98,7 @@ use_power(5000) // Use a lot of power. var/mob/living/silicon/robot/R = H.Robotize() - - R.cell.maxcharge = robot_cell_charge - R.cell.charge = robot_cell_charge + R.cell = new /obj/item/stock_parts/cell/upgraded/plus(R, robot_cell_charge) // So he can't jump out the gate right away. R.SetLockdown() diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index ec6a53f308..d3598d4866 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -79,6 +79,7 @@ last_slogan = world.time + rand(0, slogan_delay) power_change() + /obj/machinery/vending/Destroy() QDEL_NULL(wires) QDEL_NULL(coin) @@ -138,7 +139,7 @@ if(isnull(amount)) amount = 0 - var/atom/temp = new typepath(null) + var/atom/temp = typepath var/datum/data/vending_product/R = new /datum/data/vending_product() R.product_name = initial(temp.name) R.product_path = typepath @@ -174,7 +175,7 @@ for(var/datum/data/vending_product/machine_content in machine) if(refill.charges[charge_type] == 0) break - var/restock = Ceiling(((machine_content.max_amount - machine_content.amount)/to_restock)*tmp_charges) + var/restock = CEILING(((machine_content.max_amount - machine_content.amount)/to_restock)*tmp_charges, 1) if(restock > refill.charges[charge_type]) restock = refill.charges[charge_type] machine_content.amount += restock @@ -638,7 +639,8 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C /obj/item/reagent_containers/food/drinks/bottle/cream = 4, /obj/item/reagent_containers/food/drinks/soda_cans/tonic = 8, /obj/item/reagent_containers/food/drinks/soda_cans/cola = 8, /obj/item/reagent_containers/food/drinks/soda_cans/sodawater = 15, /obj/item/reagent_containers/food/drinks/drinkingglass = 30, /obj/item/reagent_containers/food/drinks/ice = 10, - /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass = 12, /obj/item/reagent_containers/food/drinks/flask = 3) + /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass = 12, /obj/item/reagent_containers/food/drinks/flask = 3, + /obj/item/reagent_containers/food/drinks/beer = 6) contraband = list(/obj/item/reagent_containers/food/drinks/mug/tea = 12) product_slogans = "I hope nobody asks me for a bloody cup o' tea...;Alcohol is humanity's friend. Would you abandon a friend?;Quite delighted to serve you!;Is nobody thirsty on this station?" product_ads = "Drink up!;Booze is good for you!;Alcohol is humanity's best friend.;Quite delighted to serve you!;Care for a nice, cold beer?;Nothing cures you like booze!;Have a sip!;Have a drink!;Have a beer!;Beer is good for you!;Only the finest alcohol!;Best quality booze since 2053!;Award-winning wine!;Maximum alcohol!;Man loves beer.;A toast for progress!" @@ -678,6 +680,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C /obj/machinery/vending/snack/random name = "\improper Random Snackies" + icon_state = "random_snack" desc = "Uh oh!" /obj/machinery/vending/snack/random/Initialize() @@ -730,6 +733,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C /obj/machinery/vending/cola/random name = "\improper Random Drinkies" + icon_state = "random_cola" desc = "Uh oh!" /obj/machinery/vending/cola/random/Initialize() @@ -1172,6 +1176,23 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C resistance_flags = FIRE_PROOF refill_canister = /obj/item/vending_refill/donksoft +/obj/machinery/vending/games + name = "\improper Good Clean Fun" + desc = "Vends things that the Captain and Head of Personnel are probably not going to appreciate you fiddling with instead of your job..." + product_ads = "Escape to a fantasy world!;Fuel your gambling addiction!;Ruin your friendships!;Roll for initative!;Elves and dwarves!;Paranoid computers!;Totally not satanic!;Fun times forever!" + icon_state = "games" + products = list( + /obj/item/toy/cards/deck = 5, + /obj/item/storage/pill_bottle/dice = 10, + /obj/item/toy/cards/deck/cas = 3, + /obj/item/toy/cards/deck/cas/black = 3) + contraband = list(/obj/item/dice/fudge = 9) + refill_canister = /obj/item/vending_refill/games + + +/obj/machinery/vending/onTransitZ() + return + #undef STANDARD_CHARGE #undef CONTRABAND_CHARGE #undef COIN_CHARGE \ No newline at end of file diff --git a/code/game/machinery/wishgranter.dm b/code/game/machinery/wishgranter.dm index fdb481401e..59465cf5b2 100644 --- a/code/game/machinery/wishgranter.dm +++ b/code/game/machinery/wishgranter.dm @@ -45,6 +45,7 @@ var/datum/objective/hijack/hijack = new hijack.owner = user.mind user.mind.objectives += hijack + user.mind.add_antag_datum(/datum/antagonist/auto_custom) user.mind.announce_objectives() diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm index df66127cc7..d5228b9130 100644 --- a/code/game/mecha/combat/gygax.dm +++ b/code/game/mecha/combat/gygax.dm @@ -1,68 +1,65 @@ -/obj/mecha/combat/gygax - desc = "A lightweight, security exosuit. Popular among private and corporate security." - name = "\improper Gygax" - icon_state = "gygax" - step_in = 3 - dir_in = 1 //Facing North. +/obj/mecha/combat/gygax + desc = "A lightweight, security exosuit. Popular among private and corporate security." + name = "\improper Gygax" + icon_state = "gygax" + step_in = 3 + dir_in = 1 //Facing North. max_integrity = 250 - deflect_chance = 5 - armor = list(melee = 25, bullet = 20, laser = 30, energy = 15, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 100) - max_temperature = 25000 - infra_luminosity = 6 - wreckage = /obj/structure/mecha_wreckage/gygax - internal_damage_threshold = 35 - max_equip = 3 - step_energy_drain = 3 - -/obj/mecha/combat/gygax/dark - desc = "A lightweight exosuit, painted in a dark scheme. This model appears to have some modifications." - name = "\improper Dark Gygax" - icon_state = "darkgygax" + deflect_chance = 5 + armor = list(melee = 25, bullet = 20, laser = 30, energy = 15, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 100) + max_temperature = 25000 + infra_luminosity = 6 + wreckage = /obj/structure/mecha_wreckage/gygax + internal_damage_threshold = 35 + max_equip = 3 + step_energy_drain = 3 + +/obj/mecha/combat/gygax/dark + desc = "A lightweight exosuit, painted in a dark scheme. This model appears to have some modifications." + name = "\improper Dark Gygax" + icon_state = "darkgygax" max_integrity = 300 - deflect_chance = 15 - armor = list(melee = 40, bullet = 40, laser = 50, energy = 35, bomb = 20, bio = 0, rad = 0, fire = 100, acid = 100) - max_temperature = 35000 - leg_overload_coeff = 100 + deflect_chance = 15 + armor = list(melee = 40, bullet = 40, laser = 50, energy = 35, bomb = 20, bio = 0, rad = 0, fire = 100, acid = 100) + max_temperature = 35000 + leg_overload_coeff = 100 operation_req_access = list(ACCESS_SYNDICATE) - wreckage = /obj/structure/mecha_wreckage/gygax/dark - max_equip = 4 - -/obj/mecha/combat/gygax/dark/loaded/New() - ..() - var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/carbine - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/teleporter - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay - ME.attach(src) - return - -/obj/mecha/combat/gygax/dark/add_cell(obj/item/stock_parts/cell/C=null) - if(C) - C.forceMove(src) - cell = C - return - cell = new(src) - cell.charge = 30000 - cell.maxcharge = 30000 - - -/obj/mecha/combat/gygax/GrantActions(mob/living/user, human_occupant = 0) - ..() - overload_action.Grant(user, src) - -/obj/mecha/combat/gygax/dark/GrantActions(mob/living/user, human_occupant = 0) - ..() - thrusters_action.Grant(user, src) - - -/obj/mecha/combat/gygax/RemoveActions(mob/living/user, human_occupant = 0) - ..() - overload_action.Remove(user) - -/obj/mecha/combat/gygax/dark/RemoveActions(mob/living/user, human_occupant = 0) - ..() - thrusters_action.Remove(user) - + wreckage = /obj/structure/mecha_wreckage/gygax/dark + max_equip = 4 + +/obj/mecha/combat/gygax/dark/loaded/New() + ..() + var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/carbine + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/teleporter + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay + ME.attach(src) + return + +/obj/mecha/combat/gygax/dark/add_cell(obj/item/stock_parts/cell/C=null) + if(C) + C.forceMove(src) + cell = C + return + cell = new /obj/item/stock_parts/cell/hyper(src) + + +/obj/mecha/combat/gygax/GrantActions(mob/living/user, human_occupant = 0) + ..() + overload_action.Grant(user, src) + +/obj/mecha/combat/gygax/dark/GrantActions(mob/living/user, human_occupant = 0) + ..() + thrusters_action.Grant(user, src) + + +/obj/mecha/combat/gygax/RemoveActions(mob/living/user, human_occupant = 0) + ..() + overload_action.Remove(user) + +/obj/mecha/combat/gygax/dark/RemoveActions(mob/living/user, human_occupant = 0) + ..() + thrusters_action.Remove(user) diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm index 627858bea6..54530d368c 100644 --- a/code/game/mecha/equipment/mecha_equipment.dm +++ b/code/game/mecha/equipment/mecha_equipment.dm @@ -6,7 +6,6 @@ icon = 'icons/mecha/mecha_equipment.dmi' icon_state = "mecha_equip" force = 5 - origin_tech = "materials=2;engineering=2" max_integrity = 300 var/equip_cooldown = 0 // cooldown after use var/equip_ready = 1 //whether the equipment is ready for use. (or deactivated/activated for static stuff) @@ -105,7 +104,7 @@ /obj/item/mecha_parts/mecha_equipment/proc/attach(obj/mecha/M) M.equipment += src chassis = M - src.loc = M + forceMove(M) M.log_message("[src] initialized.") if(!M.selected && selectable) M.selected = src diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm index ebac3fb6d2..97e743b30e 100644 --- a/code/game/mecha/equipment/tools/medical_tools.dm +++ b/code/game/mecha/equipment/tools/medical_tools.dm @@ -32,9 +32,8 @@ /obj/item/mecha_parts/mecha_equipment/medical/sleeper name = "mounted sleeper" desc = "Equipment for medical exosuits. A mounted sleeper that stabilizes patients and can inject reagents in the exosuit's reserves." - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" - origin_tech = "engineering=3;biotech=3;plasmatech=2" energy_drain = 20 range = MELEE equip_cooldown = 20 @@ -169,6 +168,7 @@ Burn Severity: [patient.getFireLoss()]%
    [patient.getCloneLoss() ? "Subject appears to have cellular damage." : ""]
    [patient.getBrainLoss() ? "Significant brain damage detected." : ""]
    + [length(patient.get_traumas()) ? "Brain Traumas detected." : ""]
    "} /obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/get_patient_reagents() @@ -255,7 +255,6 @@ var/mode = 0 //0 - fire syringe, 1 - analyze reagents. range = MELEE|RANGED equip_cooldown = 10 - origin_tech = "materials=3;biotech=4;magnets=4" /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/New() ..() @@ -532,7 +531,6 @@ energy_drain = 10 range = MELEE|RANGED equip_cooldown = 0 - origin_tech = "combat=5;materials=6;powerstorage=7;biotech=6" var/obj/item/gun/medbeam/mech/medigun materials = list(MAT_METAL = 15000, MAT_GLASS = 8000, MAT_PLASMA = 3000, MAT_GOLD = 8000, MAT_DIAMOND = 2000) diff --git a/code/game/mecha/equipment/tools/mining_tools.dm b/code/game/mecha/equipment/tools/mining_tools.dm index 9203e32177..0984621dc3 100644 --- a/code/game/mecha/equipment/tools/mining_tools.dm +++ b/code/game/mecha/equipment/tools/mining_tools.dm @@ -98,7 +98,6 @@ name = "diamond-tipped exosuit drill" desc = "Equipment for engineering and combat exosuits. This is an upgraded version of the drill that'll pierce the heavens!" icon_state = "mecha_diamond_drill" - origin_tech = "materials=4;engineering=4" equip_cooldown = 10 force = 15 diff --git a/code/game/mecha/equipment/tools/other_tools.dm b/code/game/mecha/equipment/tools/other_tools.dm index 9d7c9b6833..385d112542 100644 --- a/code/game/mecha/equipment/tools/other_tools.dm +++ b/code/game/mecha/equipment/tools/other_tools.dm @@ -8,7 +8,6 @@ name = "mounted teleporter" desc = "An exosuit module that allows exosuits to teleport to any position in view." icon_state = "mecha_teleport" - origin_tech = "bluespace=7" equip_cooldown = 150 energy_drain = 1000 range = RANGED @@ -29,7 +28,6 @@ name = "mounted wormhole generator" desc = "An exosuit module that allows generating of small quasi-stable wormholes." icon_state = "mecha_wholegen" - origin_tech = "bluespace=4;magnets=4;plasmatech=2" equip_cooldown = 50 energy_drain = 300 range = RANGED @@ -73,7 +71,6 @@ name = "mounted gravitational catapult" desc = "An exosuit mounted Gravitational Catapult." icon_state = "mecha_teleport" - origin_tech = "bluespace=3;magnets=3;engineering=4" equip_cooldown = 10 energy_drain = 100 range = MELEE|RANGED @@ -145,7 +142,6 @@ name = "armor booster module (Close Combat Weaponry)" desc = "Boosts exosuit armor against armed melee attacks. Requires energy to operate." icon_state = "mecha_abooster_ccw" - origin_tech = "materials=4;combat=4" equip_cooldown = 10 energy_drain = 50 range = 0 @@ -164,7 +160,6 @@ name = "armor booster module (Ranged Weaponry)" desc = "Boosts exosuit armor against ranged attacks. Completely blocks taser shots. Requires energy to operate." icon_state = "mecha_abooster_proj" - origin_tech = "materials=4;combat=3;engineering=3" equip_cooldown = 10 energy_drain = 50 range = 0 @@ -185,7 +180,6 @@ name = "exosuit repair droid" desc = "An automated repair droid for exosuits. Scans for damage and repairs it. Can fix almost all types of external or internal damage." icon_state = "repair_droid" - origin_tech = "magnets=3;programming=3;engineering=4" energy_drain = 50 range = 0 var/health_boost = 1 @@ -271,7 +265,6 @@ name = "exosuit energy relay" desc = "An exosuit module that wirelessly drains energy from any available power channel in area. The performance index is quite low." icon_state = "tesla" - origin_tech = "magnets=4;powerstorage=4;engineering=4" energy_drain = 0 range = 0 var/coeff = 100 @@ -357,7 +350,6 @@ name = "exosuit plasma converter" desc = "An exosuit module that generates power using solid plasma as fuel. Pollutes the environment." icon_state = "tesla" - origin_tech = "plasmatech=2;powerstorage=2;engineering=2" range = MELEE var/coeff = 100 var/obj/item/stack/sheet/fuel @@ -430,7 +422,7 @@ if(!istype(T)) return var/datum/gas_mixture/GM = new - ADD_GAS(/datum/gas/plasma, GM.gases) + GM.add_gas(/datum/gas/plasma) if(prob(10)) GM.gases[/datum/gas/plasma][MOLES] += 100 GM.temperature = 1500+T0C //should be enough to start a fire @@ -473,7 +465,6 @@ name = "exonuclear reactor" desc = "An exosuit module that generates power using uranium as fuel. Pollutes the environment." icon_state = "tesla" - origin_tech = "powerstorage=4;engineering=4" max_fuel = 50000 fuel_per_cycle_idle = 10 fuel_per_cycle_active = 30 diff --git a/code/game/mecha/equipment/tools/work_tools.dm b/code/game/mecha/equipment/tools/work_tools.dm index 6d9fc9e13e..f076b723ae 100644 --- a/code/game/mecha/equipment/tools/work_tools.dm +++ b/code/game/mecha/equipment/tools/work_tools.dm @@ -39,7 +39,7 @@ O.anchored = TRUE if(do_after_cooldown(target)) cargo_holder.cargo += O - O.loc = chassis + O.forceMove(chassis) O.anchored = FALSE occupant_message("[target] successfully loaded.") log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]") @@ -91,7 +91,7 @@ O.anchored = TRUE if(do_after_cooldown(target)) cargo_holder.cargo += O - O.loc = chassis + O.forceMove(chassis) O.anchored = FALSE occupant_message("[target] successfully loaded.") log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]") @@ -191,7 +191,6 @@ name = "mounted RCD" desc = "An exosuit-mounted Rapid Construction Device." icon_state = "mecha_rcd" - origin_tech = "materials=4;bluespace=3;magnets=4;powerstorage=4;engineering=4" equip_cooldown = 10 energy_drain = 250 range = MELEE|RANGED diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index 4b814d6e58..2cd44f75b9 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -1,7 +1,6 @@ /obj/item/mecha_parts/mecha_equipment/weapon name = "mecha weapon" range = RANGED - origin_tech = "materials=3;combat=3" var/projectile var/fire_sound var/projectiles_per_shot = 1 @@ -73,7 +72,6 @@ name = "\improper CH-PS \"Immolator\" laser" desc = "A weapon for combat exosuits. Shoots basic lasers." icon_state = "mecha_laser" - origin_tech = "magnets=3;combat=3;engineering=3" energy_drain = 30 projectile = /obj/item/projectile/beam/laser fire_sound = 'sound/weapons/laser.ogg' @@ -83,7 +81,6 @@ name = "\improper CH-LC \"Solaris\" laser cannon" desc = "A weapon for combat exosuits. Shoots heavy lasers." icon_state = "mecha_laser" - origin_tech = "magnets=4;combat=4;engineering=3" energy_drain = 60 projectile = /obj/item/projectile/beam/laser/heavylaser fire_sound = 'sound/weapons/lasercannonfire.ogg' @@ -93,7 +90,6 @@ name = "\improper MKIV ion heavy cannon" desc = "A weapon for combat exosuits. Shoots technology-disabling ion beams. Don't catch yourself in the blast!" icon_state = "mecha_ion" - origin_tech = "materials=4;combat=5;magnets=4" energy_drain = 120 projectile = /obj/item/projectile/ion fire_sound = 'sound/weapons/laser.ogg' @@ -103,7 +99,6 @@ name = "\improper MKI Tesla Cannon" desc = "A weapon for combat exosuits. Fires bolts of electricity similar to the experimental tesla engine." icon_state = "mecha_ion" - origin_tech = "materials=4;engineering=4;combat=6;magnets=6" energy_drain = 500 projectile = /obj/item/projectile/energy/tesla/cannon fire_sound = 'sound/magic/lightningbolt.ogg' @@ -115,7 +110,6 @@ desc = "A weapon for combat exosuits. Shoots powerful destructive blasts capable of demolishing obstacles." icon_state = "mecha_pulse" energy_drain = 120 - origin_tech = "materials=3;combat=6;powerstorage=4" projectile = /obj/item/projectile/beam/pulse/heavy fire_sound = 'sound/weapons/marauder.ogg' @@ -128,7 +122,6 @@ lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi' energy_drain = 30 - origin_tech = "materials=3;plasmatech=4;engineering=3" projectile = /obj/item/projectile/plasma/adv/mech fire_sound = 'sound/weapons/plasma_cutter.ogg' @@ -143,7 +136,6 @@ name = "\improper PBT \"Pacifier\" mounted taser" desc = "A weapon for combat exosuits. Shoots non-lethal stunning electrodes." icon_state = "mecha_taser" - origin_tech = "combat=3" energy_drain = 20 equip_cooldown = 8 projectile = /obj/item/projectile/energy/electrode @@ -247,7 +239,6 @@ name = "\improper FNX-99 \"Hades\" Carbine" desc = "A weapon for combat exosuits. Shoots incendiary bullets." icon_state = "mecha_carbine" - origin_tech = "materials=4;combat=4" equip_cooldown = 10 projectile = /obj/item/projectile/bullet/incendiary/fnx99 projectiles = 24 @@ -267,7 +258,6 @@ name = "\improper LBX AC 10 \"Scattershot\"" desc = "A weapon for combat exosuits. Shoots a spread of pellets." icon_state = "mecha_scatter" - origin_tech = "combat=4" equip_cooldown = 20 projectile = /obj/item/projectile/bullet/scattershot projectiles = 40 @@ -279,7 +269,6 @@ name = "\improper Ultra AC 2" desc = "A weapon for combat exosuits. Shoots a rapid, three shot burst." icon_state = "mecha_uac2" - origin_tech = "combat=4" equip_cooldown = 10 projectile = /obj/item/projectile/bullet/lmg projectiles = 300 @@ -293,7 +282,6 @@ name = "\improper SRM-8 missile rack" desc = "A weapon for combat exosuits. Shoots light explosive missiles." icon_state = "mecha_missilerack" - origin_tech = "combat=5;materials=4;engineering=4" projectile = /obj/item/projectile/bullet/srmrocket fire_sound = 'sound/weapons/grenadelaunch.ogg' projectiles = 8 @@ -326,7 +314,6 @@ name = "\improper SGL-6 grenade launcher" desc = "A weapon for combat exosuits. Launches primed flashbangs." icon_state = "mecha_grenadelnchr" - origin_tech = "combat=4;engineering=4" projectile = /obj/item/grenade/flashbang fire_sound = 'sound/weapons/grenadelaunch.ogg' projectiles = 6 @@ -344,7 +331,6 @@ /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/clusterbang //Because I am a heartless bastard -Sieve //Heartless? for making the poor man's honkblast? - Kaze name = "\improper SOB-3 grenade launcher" desc = "A weapon for combat exosuits. Launches primed clusterbangs. You monster." - origin_tech = "combat=4;materials=4" projectiles = 3 projectile = /obj/item/grenade/clusterbuster projectile_energy_cost = 1600 //getting off cheap seeing as this is 3 times the flashbangs held in the grenade launcher. diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index be0f596ced..6ef98120f5 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -12,7 +12,7 @@ circuit = /obj/item/circuitboard/machine/mechfab var/time_coeff = 1 var/component_coeff = 1 - var/datum/research/files + var/datum/techweb/specialized/autounlocking/exofab/stored_research var/sync = 0 var/part_set var/datum/design/being_built @@ -34,13 +34,15 @@ "Misc" ) + var/datum/component/material_container/materials + /obj/machinery/mecha_part_fabricator/Initialize() - var/datum/component/material_container/materials = AddComponent(/datum/component/material_container, - list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE), - FALSE, list(/obj/item/stack, /obj/item/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready)) + materials = AddComponent(/datum/component/material_container, + list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE), 0, + FALSE, list(/obj/item/stack, /obj/item/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready), CALLBACK(src, .proc/AfterMaterialInsert)) materials.precise_insertion = TRUE - . = ..() - files = new /datum/research(src) //Setup the research data holder. + stored_research = new + return ..() /obj/machinery/mecha_part_fabricator/RefreshParts() var/T = 0 @@ -69,11 +71,11 @@ var/obj/item/device/pda/pda = I I = pda.id if(!istype(I) || !I.access) //not ID or no access - return 0 + return FALSE for(var/req in req_access) if(!(req in I.access)) //doesn't have this access - return 0 - return 1 + return FALSE + return TRUE /obj/machinery/mecha_part_fabricator/emag_act() if(emagged) @@ -91,8 +93,8 @@ /obj/machinery/mecha_part_fabricator/proc/output_parts_list(set_name) var/output = "" - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] if(D.build_type & MECHFAB) if(!(set_name in D.category)) continue @@ -136,11 +138,11 @@ /obj/machinery/mecha_part_fabricator/proc/check_resources(datum/design/D) if(D.reagents_list.len) // No reagents storage - no reagent designs. - return 0 + return FALSE GET_COMPONENT(materials, /datum/component/material_container) if(materials.has_materials(get_resources_w_coeff(D))) - return 1 - return 0 + return TRUE + return FALSE /obj/machinery/mecha_part_fabricator/proc/build_part(datum/design/D) being_built = D @@ -164,7 +166,7 @@ being_built = null updateUsrDialog() - return 1 + return TRUE /obj/machinery/mecha_part_fabricator/proc/update_queue_on_page() send_byjax(usr,"mecha_fabricator.browser","queue",list_queue()) @@ -172,8 +174,8 @@ /obj/machinery/mecha_part_fabricator/proc/add_part_set_to_queue(set_name) if(set_name in part_sets) - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] if(D.build_type & MECHFAB) if(set_name in D.category) add_to_queue(D) @@ -186,10 +188,10 @@ return queue.len /obj/machinery/mecha_part_fabricator/proc/remove_from_queue(index) - if(!isnum(index) || !IsInteger(index) || !istype(queue) || (index<1 || index>queue.len)) - return 0 + if(!isnum(index) || !ISINTEGER(index) || !istype(queue) || (index<1 || index>queue.len)) + return FALSE queue.Cut(index,++index) - return 1 + return TRUE /obj/machinery/mecha_part_fabricator/proc/process_queue() var/datum/design/D = queue[1] @@ -202,12 +204,12 @@ temp = null while(D) if(stat&(NOPOWER|BROKEN)) - return 0 + return FALSE if(!check_resources(D)) say("Not enough resources. Queue processing stopped.") temp = {"Not enough resources to build next part.
    Try again | Return"} - return 0 + return FALSE remove_from_queue(1) build_part(D) D = listgetindex(queue, 1) @@ -239,15 +241,7 @@ sleep(30) //only sleep if called by user for(var/obj/machinery/computer/rdconsole/RDC in oview(7,src)) - if(!RDC.sync) - continue - for(var/v in RDC.files.known_tech) - var/datum/tech/T = RDC.files.known_tech[v] - files.AddTech2Known(T) - for(var/v in RDC.files.known_designs) - var/datum/design/D = RDC.files.known_designs[v] - files.AddDesign2Known(D) - files.RefreshResearch() + RDC.stored_research.copy_research_to(stored_research) temp = "Processed equipment designs.
    " //check if the tech coefficients have changed temp += "
    Return" @@ -343,8 +337,8 @@ screen = "parts" if(href_list["part"]) var/T = afilter.getStr("part") - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] if(D.build_type & MECHFAB) if(D.id == T) if(!processing_queue) @@ -354,8 +348,8 @@ break if(href_list["add_to_queue"]) var/T = afilter.getStr("add_to_queue") - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] if(D.build_type & MECHFAB) if(D.id == T) add_to_queue(D) @@ -370,7 +364,7 @@ if(href_list["process_queue"]) spawn(0) if(processing_queue || being_built) - return 0 + return FALSE processing_queue = 1 process_queue() processing_queue = 0 @@ -381,8 +375,8 @@ if(href_list["queue_move"] && href_list["index"]) var/index = afilter.getNum("index") var/new_index = index + afilter.getNum("queue_move") - if(isnum(index) && isnum(new_index) && IsInteger(index) && IsInteger(new_index)) - if(IsInRange(new_index,1,queue.len)) + if(isnum(index) && isnum(new_index) && ISINTEGER(index) && ISINTEGER(new_index)) + if(ISINRANGE(new_index,1,queue.len)) queue.Swap(index,new_index) return update_queue_on_page() if(href_list["clear_queue"]) @@ -392,8 +386,8 @@ sync() if(href_list["part_desc"]) var/T = afilter.getStr("part_desc") - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] if(D.build_type & MECHFAB) if(D.id == T) var/obj/part = D.build_path @@ -415,26 +409,21 @@ materials.retrieve_all() ..() -/obj/machinery/mecha_part_fabricator/ComponentActivated(datum/component/C) - ..() - if(istype(C, /datum/component/material_container)) - var/datum/component/material_container/M = C - if(!M.last_insert_success) - return - 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() +/obj/machinery/mecha_part_fabricator/proc/AfterMaterialInsert(type_inserted, id_inserted, amount_inserted) + var/stack_name = material2name(id_inserted) + add_overlay("fab-load-[stack_name]") + addtimer(CALLBACK(src, /atom/proc/cut_overlay, "fab-load-[stack_name]"), 10) + updateUsrDialog() /obj/machinery/mecha_part_fabricator/attackby(obj/item/W, mob/user, params) if(default_deconstruction_screwdriver(user, "fab-o", "fab-idle", W)) - return 1 + return TRUE if(exchange_parts(user, W)) - return 1 + return TRUE if(default_deconstruction_crowbar(W)) - return 1 + return TRUE return ..() diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 2f98b2cc4c..2d148b4ff4 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -24,7 +24,7 @@ infra_luminosity = 15 //byond implementation is bugged. force = 5 flags_1 = HEAR_1 - var/can_move = 1 + var/can_move = 0 //time of next allowed movement var/mob/living/carbon/occupant = null var/step_in = 10 //make a step in step_in/10 sec. var/dir_in = 2//What direction will the mech face when entered/powered on? Defaults to South. @@ -137,8 +137,8 @@ log_message("[src.name] created.") GLOB.mechas_list += src //global mech list prepare_huds() - var/datum/atom_hud/data/diagnostic/diag_hud = GLOB.huds[DATA_HUD_DIAGNOSTIC] - diag_hud.add_to_hud(src) + for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds) + diag_hud.add_to_hud(src) diag_hud_set_mechhealth() diag_hud_set_mechcell() diag_hud_set_mechstat() @@ -231,9 +231,7 @@ C.forceMove(src) cell = C return - cell = new(src) - cell.charge = 15000 - cell.maxcharge = 15000 + cell = new /obj/item/stock_parts/cell/high/plus(src) /obj/mecha/proc/add_cabin() cabin_air = new @@ -504,7 +502,7 @@ return domove(direction) /obj/mecha/proc/domove(direction) - if(!can_move) + if(can_move >= world.time) return 0 if(!Process_Spacemove(direction)) return 0 @@ -522,21 +520,19 @@ return 0 var/move_result = 0 + var/oldloc = loc if(internal_damage & MECHA_INT_CONTROL_LOST) move_result = mechsteprand() else if(dir != direction && !strafe) move_result = mechturn(direction) else move_result = mechstep(direction) - if(move_result) + if(move_result || loc != oldloc)// halfway done diagonal move still returns false use_power(step_energy_drain) - can_move = 0 - spawn(step_in) - can_move = 1 + can_move = world.time + step_in return 1 return 0 - /obj/mecha/proc/mechturn(direction) setDir(direction) if(turnsound) @@ -575,9 +571,9 @@ if(bumpsmash && occupant) //Need a pilot to push the PUNCH button. if(nextsmash < world.time) obstacle.mech_melee_attack(src) - if(!obstacle || !obstacle.density) - step(src,dir) nextsmash = world.time + smashcooldown + if(!obstacle || obstacle.CanPass(src,get_step(src,dir))) + step(src,dir) if(isobj(obstacle)) var/obj/O = obstacle if(!O.anchored) @@ -750,7 +746,7 @@ icon_state = initial(icon_state) occupant = pilot_mob pilot_mob.mecha = src - pilot_mob.loc = src + pilot_mob.forceMove(src) GrantActions(pilot_mob)//needed for checks, and incase a badmin puts somebody in the mob /obj/mecha/proc/aimob_exit_mech(mob/living/simple_animal/hostile/syndicate/mecha_pilot/pilot_mob) @@ -961,7 +957,7 @@ if(istype(mob_container, /obj/item/device/mmi)) var/obj/item/device/mmi/mmi = mob_container if(mmi.brainmob) - L.loc = mmi + L.forceMove(mmi) L.reset_perspective() mmi.mecha = null mmi.update_icon() @@ -970,7 +966,7 @@ setDir(dir_in) if(L && L.client) - L.client.change_view(world.view) + L.client.change_view(CONFIG_GET(string/default_view)) zoom_mode = 0 ///////////////////////// diff --git a/code/game/mecha/mecha_actions.dm b/code/game/mecha/mecha_actions.dm index ec6bd6e471..480c24b87f 100644 --- a/code/game/mecha/mecha_actions.dm +++ b/code/game/mecha/mecha_actions.dm @@ -244,7 +244,7 @@ owner.client.change_view(12) SEND_SOUND(owner, sound('sound/mecha/imag_enh.ogg',volume=50)) else - owner.client.change_view(world.view) //world.view - default mob view size + owner.client.change_view(CONFIG_GET(string/default_view)) //world.view - default mob view size UpdateButtonIcon() /datum/action/innate/mecha/mech_switch_damtype diff --git a/code/game/mecha/mecha_construction_paths.dm b/code/game/mecha/mecha_construction_paths.dm index c8de01badc..de50d6f86f 100644 --- a/code/game/mecha/mecha_construction_paths.dm +++ b/code/game/mecha/mecha_construction_paths.dm @@ -524,7 +524,7 @@ else user.visible_message("[user] removes the advanced scanner module from the [holder].", "You remove the scanner module from the [holder].") var/obj/item/I = locate(/obj/item/stock_parts/scanning_module) in holder - I.loc = get_turf(holder) + I.forceMove(get_turf(holder)) holder.icon_state = "gygax10" if(11) if(diff==FORWARD) @@ -542,7 +542,7 @@ else user.visible_message("[user] removes the capacitor from the [holder].", "You remove the capacitor from the [holder].") var/obj/item/I = locate(/obj/item/stock_parts/capacitor) in holder - I.loc = get_turf(holder) + I.forceMove(holder.drop_location()) holder.icon_state = "gygax12" if(9) if(diff==FORWARD) @@ -1155,7 +1155,7 @@ else user.visible_message("[user] removes the scanner module from the [holder].", "You remove the scanner module from the [holder].") var/obj/item/I = locate(/obj/item/stock_parts/scanning_module) in holder - I.loc = get_turf(holder) + I.forceMove(holder.drop_location()) holder.icon_state = "durand10" if(11) if(diff==FORWARD) @@ -1173,7 +1173,7 @@ else user.visible_message("[user] removes the super capacitor from the [holder].", "You remove the capacitor from the [holder].") var/obj/item/I = locate(/obj/item/stock_parts/capacitor) in holder - I.loc = get_turf(holder) + I.forceMove(holder.drop_location()) holder.icon_state = "durand12" if(9) if(diff==FORWARD) @@ -1480,7 +1480,7 @@ else user.visible_message("[user] removes the phasic scanner module from the [holder].", "You remove the scanner module from the [holder].") var/obj/item/I = locate(/obj/item/stock_parts/scanning_module) in holder - I.loc = get_turf(holder) + I.forceMove(holder.drop_location()) holder.icon_state = "phazon10" if(15) if(diff==FORWARD) @@ -1498,7 +1498,7 @@ else user.visible_message("[user] removes the super capacitor from the [holder].", "You remove the capacitor from the [holder].") var/obj/item/I = locate(/obj/item/stock_parts/capacitor) in holder - I.loc = get_turf(holder) + I.forceMove(holder.drop_location()) holder.icon_state = "phazon12" if(13) if(diff==FORWARD) diff --git a/code/game/mecha/mecha_control_console.dm b/code/game/mecha/mecha_control_console.dm index 63dd798a34..bb495675b1 100644 --- a/code/game/mecha/mecha_control_console.dm +++ b/code/game/mecha/mecha_control_console.dm @@ -67,7 +67,6 @@ 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() @@ -119,7 +118,6 @@ /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 diff --git a/code/game/mecha/mecha_defense.dm b/code/game/mecha/mecha_defense.dm index 590c19b504..065415cba9 100644 --- a/code/game/mecha/mecha_defense.dm +++ b/code/game/mecha/mecha_defense.dm @@ -242,15 +242,17 @@ user.changeNext_move(CLICK_CD_MELEE) var/obj/item/weldingtool/WT = W if(obj_integrityYou repair the damaged gas tank.") else - user.visible_message("[user] repairs some damage to [name].") + user.visible_message("[user] repairs some damage to [name].", "You repair some damage to [src].") obj_integrity += min(10, max_integrity-obj_integrity) + if(obj_integrity == max_integrity) + to_chat(user, "It looks to be fully repaired now.") else - to_chat(user, "The welder must be on for this task!") + to_chat(user, "[WT] needs to be on for this task!") return 1 else to_chat(user, "The [name] is at full integrity!") diff --git a/code/game/mecha/mecha_parts.dm b/code/game/mecha/mecha_parts.dm index 674854c22e..3455d19877 100644 --- a/code/game/mecha/mecha_parts.dm +++ b/code/game/mecha/mecha_parts.dm @@ -8,7 +8,6 @@ icon_state = "blank" w_class = WEIGHT_CLASS_GIGANTIC flags_1 = CONDUCT_1 - origin_tech = "programming=2;materials=2;engineering=2" /obj/item/mecha_parts/chassis name="Mecha Chassis" @@ -35,7 +34,6 @@ name = "\improper Ripley torso" desc = "A torso part of Ripley APLU. Contains power unit, processing core and life support systems." icon_state = "ripley_harness" - origin_tech = "programming=2;materials=2;biotech=2;engineering=2" /obj/item/mecha_parts/part/ripley_left_arm name = "\improper Ripley left arm" @@ -75,7 +73,6 @@ name = "\improper Odysseus torso" desc="A torso part of Odysseus. Contains power unit, processing core and life support systems along with an attachment port for a mounted sleeper." icon_state = "odysseus_torso" - origin_tech = "programming=2;materials=2;biotech=2;engineering=2" /obj/item/mecha_parts/part/odysseus_left_arm name = "\improper Odysseus left arm" @@ -110,44 +107,37 @@ name = "\improper Gygax torso" desc = "A torso part of Gygax. Contains power unit, processing core and life support systems." icon_state = "gygax_harness" - origin_tech = "programming=2;materials=4;biotech=3;engineering=3" /obj/item/mecha_parts/part/gygax_head name = "\improper Gygax head" desc = "A Gygax head. Houses advanced surveillance and targeting sensors." icon_state = "gygax_head" - origin_tech = "programming=2;materials=4;magnets=3;engineering=3" /obj/item/mecha_parts/part/gygax_left_arm name = "\improper Gygax left arm" desc = "A Gygax left arm. Data and power sockets are compatible with most exosuit tools and weapons." icon_state = "gygax_l_arm" - origin_tech = "programming=2;materials=4;engineering=3" /obj/item/mecha_parts/part/gygax_right_arm name = "\improper Gygax right arm" desc = "A Gygax right arm. Data and power sockets are compatible with most exosuit tools and weapons." icon_state = "gygax_r_arm" - origin_tech = "programming=2;materials=4;engineering=3" /obj/item/mecha_parts/part/gygax_left_leg name = "\improper Gygax left leg" desc = "A Gygax left leg. Constructed with advanced servomechanisms and actuators to enable faster speed." icon_state = "gygax_l_leg" - origin_tech = "programming=2;materials=4;engineering=3" /obj/item/mecha_parts/part/gygax_right_leg name = "\improper Gygax right leg" desc = "A Gygax right leg. Constructed with advanced servomechanisms and actuators to enable faster speed." icon_state = "gygax_r_leg" - origin_tech = "programming=2;materials=4;engineering=3" /obj/item/mecha_parts/part/gygax_armor gender = PLURAL name = "\improper Gygax armor plates" desc = "A set of armor plates designed for the Gygax. Designed to effectively deflect damage with a lightweight construction." icon_state = "gygax_armor" - origin_tech = "materials=6;combat=4;engineering=4" //////////// Durand @@ -163,44 +153,37 @@ name = "\improper Durand torso" desc = "A torso part of Durand. Contains power unit, processing core and life support systems within a robust protective frame." icon_state = "durand_harness" - origin_tech = "programming=2;materials=3;biotech=3;engineering=3" /obj/item/mecha_parts/part/durand_head name = "\improper Durand head" desc = "A Durand head. Houses advanced surveillance and targeting sensors." icon_state = "durand_head" - origin_tech = "programming=2;materials=3;magnets=3;engineering=3" /obj/item/mecha_parts/part/durand_left_arm name = "\improper Durand left arm" desc = "A Durand left arm. Data and power sockets are compatible with most exosuit tools and weapons. Packs a really mean punch as well." icon_state = "durand_l_arm" - origin_tech = "programming=2;materials=3;engineering=3" /obj/item/mecha_parts/part/durand_right_arm name = "\improper Durand right arm" desc = "A Durand right arm. Data and power sockets are compatible with most exosuit tools and weapons. Packs a really mean punch as well." icon_state = "durand_r_arm" - origin_tech = "programming=2;materials=3;engineering=3" /obj/item/mecha_parts/part/durand_left_leg name = "\improper Durand left leg" desc = "A Durand left leg. Built particlarly sturdy to support the Durand's heavy weight and defensive needs." icon_state = "durand_l_leg" - origin_tech = "programming=2;materials=3;engineering=3" /obj/item/mecha_parts/part/durand_right_leg name = "\improper Durand right leg" desc = "A Durand right leg. Built particlarly sturdy to support the Durand's heavy weight and defensive needs." icon_state = "durand_r_leg" - origin_tech = "programming=2;materials=3;engineering=3" /obj/item/mecha_parts/part/durand_armor gender = PLURAL name = "\improper Durand armor plates" desc = "A set of armor plates for the Durand. Built heavy to resist an incredible amount of brute force." icon_state = "durand_armor" - origin_tech = "materials=5;combat=4;engineering=4" ////////// Firefighter @@ -265,43 +248,36 @@ name="\improper Phazon torso" desc="A Phazon torso part. The socket for the bluespace core that powers the exosuit's unique phase drives is located in the middle." icon_state = "phazon_harness" - origin_tech = "programming=4;materials=4;bluespace=4;plasmatech=5" /obj/item/mecha_parts/part/phazon_head name="\improper Phazon head" desc="A Phazon head. Its sensors are carefully calibrated to provide vision and data even when the exosuit is phasing." icon_state = "phazon_head" - origin_tech = "programming=3;materials=3;magnets=3" /obj/item/mecha_parts/part/phazon_left_arm name="\improper Phazon left arm" desc="A Phazon left arm. Several microtool arrays are located under the armor plating, which can be adjusted to the situation at hand." icon_state = "phazon_l_arm" - origin_tech = "materials=3;bluespace=3;magnets=3" /obj/item/mecha_parts/part/phazon_right_arm name="\improper Phazon right arm" desc="A Phazon right arm. Several microtool arrays are located under the armor plating, which can be adjusted to the situation at hand." icon_state = "phazon_r_arm" - origin_tech = "materials=3;bluespace=3;magnets=3" /obj/item/mecha_parts/part/phazon_left_leg name="\improper Phazon left leg" desc="A Phazon left leg. It contains the unique phase drives that allow the exosuit to phase through solid matter when engaged." icon_state = "phazon_l_leg" - origin_tech = "materials=3;bluespace=3;magnets=3" /obj/item/mecha_parts/part/phazon_right_leg name="\improper Phazon right leg" desc="A Phazon right leg. It contains the unique phase drives that allow the exosuit to phase through solid matter when engaged." icon_state = "phazon_r_leg" - origin_tech = "materials=3;bluespace=3;magnets=3" /obj/item/mecha_parts/part/phazon_armor name="Phazon armor" desc="Phazon armor plates. They are layered with plasma to protect the pilot from the stress of phasing and have unusual properties." icon_state = "phazon_armor" - origin_tech = "materials=4;bluespace=4;plasmatech=5" ///////// Circuitboards @@ -320,9 +296,6 @@ throw_speed = 3 throw_range = 7 -/obj/item/circuitboard/mecha/ripley - origin_tech = "programming=2" - /obj/item/circuitboard/mecha/ripley/peripherals name = "Ripley Peripherals Control module (Exosuit Board)" icon_state = "mcontroller" @@ -331,8 +304,6 @@ name = "Ripley Central Control module (Exosuit Board)" icon_state = "mainboard" -/obj/item/circuitboard/mecha/gygax - origin_tech = "programming=4;combat=3;engineering=3" /obj/item/circuitboard/mecha/gygax/peripherals name = "Gygax Peripherals Control module (Exosuit Board)" @@ -341,15 +312,11 @@ /obj/item/circuitboard/mecha/gygax/targeting name = "Gygax Weapon Control and Targeting module (Exosuit Board)" icon_state = "mcontroller" - origin_tech = "programming=4;combat=4" /obj/item/circuitboard/mecha/gygax/main name = "Gygax Central Control module (Exosuit Board)" icon_state = "mainboard" -/obj/item/circuitboard/mecha/durand - origin_tech = "programming=4;combat=3;engineering=3" - /obj/item/circuitboard/mecha/durand/peripherals name = "Durand Peripherals Control module (Exosuit Board)" icon_state = "mcontroller" @@ -357,15 +324,11 @@ /obj/item/circuitboard/mecha/durand/targeting name = "Durand Weapon Control and Targeting module (Exosuit Board)" icon_state = "mcontroller" - origin_tech = "programming=4;combat=4;engineering=3" /obj/item/circuitboard/mecha/durand/main name = "Durand Central Control module (Exosuit Board)" icon_state = "mainboard" -/obj/item/circuitboard/mecha/honker - origin_tech = "programming=3;engineering=3" - /obj/item/circuitboard/mecha/honker/peripherals name = "H.O.N.K Peripherals Control module (Exosuit Board)" icon_state = "mcontroller" @@ -378,9 +341,6 @@ name = "H.O.N.K Central Control module (Exosuit Board)" icon_state = "mainboard" -/obj/item/circuitboard/mecha/odysseus - origin_tech = "programming=3;biotech=3" - /obj/item/circuitboard/mecha/odysseus/peripherals name = "Odysseus Peripherals Control module (Exosuit Board)" icon_state = "mcontroller" @@ -389,9 +349,6 @@ name = "Odysseus Central Control module (Exosuit Board)" icon_state = "mainboard" -/obj/item/circuitboard/mecha/phazon - origin_tech = "programming=5;plasmatech=4" - /obj/item/circuitboard/mecha/phazon/peripherals name = "Phazon Peripherals Control module (Exosuit Board)" icon_state = "mcontroller" diff --git a/code/game/mecha/mecha_wreckage.dm b/code/game/mecha/mecha_wreckage.dm index 67e5c1dbd1..de8f8ecb3a 100644 --- a/code/game/mecha/mecha_wreckage.dm +++ b/code/game/mecha/mecha_wreckage.dm @@ -68,7 +68,7 @@ if(crowbar_salvage && crowbar_salvage.len) var/obj/S = pick(crowbar_salvage) if(S) - S.loc = get_turf(user) + S.forceMove(user.drop_location()) crowbar_salvage -= S user.visible_message("[user] pries [S] from [src].", "You pry [S] from [src].") return diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm index 0da64c3e4d..a7115abd1d 100644 --- a/code/game/mecha/working/ripley.dm +++ b/code/game/mecha/working/ripley.dm @@ -34,7 +34,7 @@ for(var/i=1, i <= hides, i++) new /obj/item/stack/sheet/animalhide/goliath_hide(loc) //If a goliath-plated ripley gets killed, all the plates drop for(var/atom/movable/A in cargo) - A.forceMove(loc) + A.forceMove(drop_location()) step_rand(A) cargo.Cut() return ..() @@ -94,7 +94,7 @@ /obj/mecha/working/ripley/mining/Initialize() . = ..() if(cell) - cell.charge = Floor(cell.charge * 0.25) //Starts at very low charge + cell.charge = FLOOR(cell.charge * 0.25, 1) //Starts at very low charge if(prob(70)) //Maybe add a drill if(prob(15)) //Possible diamond drill... Feeling lucky? var/obj/item/mecha_parts/mecha_equipment/drill/diamonddrill/D = new @@ -130,7 +130,7 @@ var/obj/O = locate(href_list["drop_from_cargo"]) if(O && O in src.cargo) src.occupant_message("You unload [O].") - O.forceMove(loc) + O.forceMove(drop_location()) src.cargo -= O src.log_message("Unloaded [O]. Cargo compartment capacity: [cargo_capacity - src.cargo.len]") return @@ -141,7 +141,7 @@ var/obj/O = X if(prob(30/severity)) cargo -= O - O.forceMove(loc) + O.forceMove(drop_location()) . = ..() /obj/mecha/working/ripley/get_stats_part() @@ -173,7 +173,7 @@ if(!user || user.stat != CONSCIOUS || user.loc != src || O.loc != src ) return to_chat(user, "You successfully pushed [O] out of [src]!") - O.loc = loc + O.forceMove(drop_location()) cargo -= O else if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded. diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm index 0c72e63feb..2e13cb16c9 100644 --- a/code/game/objects/buckling.dm +++ b/code/game/objects/buckling.dm @@ -65,6 +65,7 @@ M.throw_alert("buckled", /obj/screen/alert/restrained/buckled) post_buckle_mob(M) + SendSignal(COMSIG_MOVABLE_BUCKLE, M, force) return TRUE /obj/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE) @@ -82,8 +83,9 @@ buckled_mob.update_canmove() buckled_mob.clear_alert("buckled") buckled_mobs -= buckled_mob + SendSignal(COMSIG_MOVABLE_UNBUCKLE, buckled_mob, force) - post_buckle_mob(.) + post_unbuckle_mob(.) /atom/movable/proc/unbuckle_all_mobs(force=FALSE) if(!has_buckled_mobs()) @@ -91,11 +93,12 @@ for(var/m in buckled_mobs) unbuckle_mob(m, force) -//Handle any extras after buckling/unbuckling -//Called on buckle_mob() and unbuckle_mob() +//Handle any extras after buckling +//Called on buckle_mob() /atom/movable/proc/post_buckle_mob(mob/living/M) - return +//same but for unbuckle +/atom/movable/proc/post_unbuckle_mob(mob/living/M) //Wrapper procs that handle sanity and user feedback /atom/movable/proc/user_buckle_mob(mob/living/M, mob/user, check_loc = TRUE) diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm index 340322e5be..76fd5e5cbf 100644 --- a/code/game/objects/effects/anomalies.dm +++ b/code/game/objects/effects/anomalies.dm @@ -26,9 +26,8 @@ aSignal = new(src) aSignal.name = "[name] core" aSignal.code = rand(1,100) - - aSignal.frequency = rand(1200, 1599) - if(IsMultiple(aSignal.frequency, 2))//signaller frequencies are always uneven! + aSignal.frequency = rand(MIN_FREE_FREQ, MAX_FREE_FREQ) + if(ISMULTIPLE(aSignal.frequency, 2))//signaller frequencies are always uneven! aSignal.frequency++ if(new_lifespan) @@ -67,7 +66,7 @@ new /obj/effect/particle_effect/smoke/bad(loc) for(var/atom/movable/O in src) - O.loc = src.loc + O.forceMove(drop_location()) qdel(src) @@ -86,7 +85,6 @@ /obj/effect/anomaly/grav/New() ..() - aSignal.origin_tech = "magnets=7" /obj/effect/anomaly/grav/anomalyEffect() ..() @@ -132,7 +130,6 @@ /obj/effect/anomaly/flux/New() ..() - aSignal.origin_tech = "powerstorage=7" /obj/effect/anomaly/flux/anomalyEffect() ..() @@ -181,7 +178,6 @@ /obj/effect/anomaly/bluespace/New() ..() - aSignal.origin_tech = "bluespace=7" /obj/effect/anomaly/bluespace/anomalyEffect() ..() @@ -228,7 +224,7 @@ var/turf/newloc = locate(A.x + x_distance, A.y + y_distance, TO.z) // calculate the new place if(!A.Move(newloc) && newloc) // if the atom, for some reason, can't move, FORCE them to move! :) We try Move() first to invoke any movement-related checks the atom needs to perform after moving - A.loc = newloc + A.forceMove(newloc) spawn() if(ismob(A) && !(A in flashers)) // don't flash if we're already doing an effect @@ -255,7 +251,6 @@ /obj/effect/anomaly/pyro/New() ..() - aSignal.origin_tech = "plasmatech=7" /obj/effect/anomaly/pyro/anomalyEffect() ..() @@ -291,7 +286,6 @@ /obj/effect/anomaly/bhole/New() ..() - aSignal.origin_tech = "engineering=7" /obj/effect/anomaly/bhole/anomalyEffect() ..() diff --git a/code/game/objects/effects/countdown.dm b/code/game/objects/effects/countdown.dm index 8448e2a7e7..2ed2105db3 100644 --- a/code/game/objects/effects/countdown.dm +++ b/code/game/objects/effects/countdown.dm @@ -24,7 +24,7 @@ /obj/effect/countdown/proc/attach(atom/A) attached_to = A - loc = get_turf(A) + forceMove(get_turf(A)) /obj/effect/countdown/proc/start() if(!started) diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index 0e0c7c606e..f06525863d 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -47,10 +47,8 @@ return else var/hotness = W.is_hot() - var/added_heat = (hotness / 100) - src.reagents.chem_temp = min(src.reagents.chem_temp + added_heat, hotness) - src.reagents.handle_reactions() - to_chat(user, "You heat [src] with [W]!") + reagents.expose_temperature(hotness) + to_chat(user, "You heat [name] with [W]!") else return ..() @@ -62,8 +60,7 @@ /obj/effect/decal/cleanable/fire_act(exposed_temperature, exposed_volume) if(reagents) - reagents.chem_temp += 30 - reagents.handle_reactions() + reagents.expose_temperature(exposed_temperature) ..() diff --git a/code/game/objects/effects/decals/misc.dm b/code/game/objects/effects/decals/misc.dm index 2187bc6311..b32cb79313 100644 --- a/code/game/objects/effects/decals/misc.dm +++ b/code/game/objects/effects/decals/misc.dm @@ -8,7 +8,7 @@ /obj/effect/temp_visual/point/Initialize(mapload, set_invis = 0) . = ..() var/atom/old_loc = loc - loc = get_turf(src) + forceMove(get_turf(src)) pixel_x = old_loc.pixel_x pixel_y = old_loc.pixel_y invisibility = set_invis diff --git a/code/game/objects/effects/effect_system/effect_system.dm b/code/game/objects/effects/effect_system/effect_system.dm index 20b59b678e..918cf5886c 100644 --- a/code/game/objects/effects/effect_system/effect_system.dm +++ b/code/game/objects/effects/effect_system/effect_system.dm @@ -26,6 +26,7 @@ would spawn and follow the beaker, even if it is carried or thrown. var/atom/holder var/effect_type var/total_effects = 0 + var/autocleanup = FALSE //will delete itself after use /datum/effect_system/Destroy() holder = null @@ -69,3 +70,5 @@ would spawn and follow the beaker, even if it is carried or thrown. /datum/effect_system/proc/decrement_total_effect() total_effects-- + if(autocleanup && total_effects <= 0) + qdel(src) diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm index 3de8432ee9..4dc985c9a1 100644 --- a/code/game/objects/effects/effect_system/effects_smoke.dm +++ b/code/game/objects/effects/effect_system/effects_smoke.dm @@ -169,7 +169,7 @@ qdel(H) var/list/G_gases = G.gases if(G_gases[/datum/gas/plasma]) - ASSERT_GAS(/datum/gas/nitrogen, G) + G.assert_gas(/datum/gas/nitrogen) G_gases[/datum/gas/nitrogen][MOLES] += (G_gases[/datum/gas/plasma][MOLES]) G_gases[/datum/gas/plasma][MOLES] = 0 G.garbage_collect() diff --git a/code/game/objects/effects/effect_system/effects_sparks.dm b/code/game/objects/effects/effect_system/effects_sparks.dm index b552ee0808..695c835a89 100644 --- a/code/game/objects/effects/effect_system/effects_sparks.dm +++ b/code/game/objects/effects/effect_system/effects_sparks.dm @@ -12,8 +12,8 @@ var/datum/effect_system/spark_spread/sparks = new sparks.set_up(n, c, source) + sparks.autocleanup = TRUE sparks.start() - qdel(sparks) /obj/effect/particle_effect/sparks diff --git a/code/game/objects/effects/proximity.dm b/code/game/objects/effects/proximity.dm index 70128be7ee..51fb690ed0 100644 --- a/code/game/objects/effects/proximity.dm +++ b/code/game/objects/effects/proximity.dm @@ -63,7 +63,7 @@ for(var/I in 1 to old_checkers_len) if(I <= old_checkers_used) var/obj/effect/abstract/proximity_checker/pc = checkers_local[I] - pc.loc = turfs[I] + pc.forceMove(turfs[I]) else qdel(checkers_local[I]) //delete the leftovers diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index 0b1432e61c..4ecba7c982 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -121,7 +121,7 @@ /obj/structure/spider/spiderling/Collide(atom/user) if(istype(user, /obj/structure/table)) - src.loc = user.loc + forceMove(user.loc) else ..() @@ -145,12 +145,12 @@ "You hear something scampering through the ventilation ducts.") spawn(rand(20,60)) - loc = exit_vent + forceMove(exit_vent) var/travel_time = round(get_dist(loc, exit_vent.loc) / 2) spawn(travel_time) if(!exit_vent || exit_vent.welded) - loc = entry_vent + forceMove(entry_vent) entry_vent = null return @@ -159,10 +159,10 @@ sleep(travel_time) if(!exit_vent || exit_vent.welded) - loc = entry_vent + forceMove(entry_vent) entry_vent = null return - loc = exit_vent.loc + forceMove(exit_vent.loc) entry_vent = null var/area/new_area = get_area(loc) if(new_area) diff --git a/code/game/objects/effects/step_triggers.dm b/code/game/objects/effects/step_triggers.dm index bfed048eff..3e0848130d 100644 --- a/code/game/objects/effects/step_triggers.dm +++ b/code/game/objects/effects/step_triggers.dm @@ -117,9 +117,8 @@ /obj/effect/step_trigger/teleporter/Trigger(atom/movable/A) if(teleport_x && teleport_y && teleport_z) - A.x = teleport_x - A.y = teleport_y - A.z = teleport_z + var/turf/T = locate(teleport_x, teleport_y, teleport_z) + A.forceMove(T) /* Random teleporter, teleports atoms to locations ranging from teleport_x - teleport_x_offset, etc */ @@ -132,9 +131,9 @@ if(teleport_x && teleport_y && teleport_z) if(teleport_x_offset && teleport_y_offset && teleport_z_offset) - A.x = rand(teleport_x, teleport_x_offset) - A.y = rand(teleport_y, teleport_y_offset) - A.z = rand(teleport_z, teleport_z_offset) + var/turf/T = locate(rand(teleport_x, teleport_x_offset), rand(teleport_y, teleport_y_offset), rand(teleport_z, teleport_z_offset)) + if (T) + A.forceMove(T) /* Fancy teleporter, creates sparks and smokes when used */ @@ -198,4 +197,3 @@ if(happens_once) qdel(src) - diff --git a/code/game/objects/effects/temporary_visuals/clockcult.dm b/code/game/objects/effects/temporary_visuals/clockcult.dm index 49e962eba2..d9861d827d 100644 --- a/code/game/objects/effects/temporary_visuals/clockcult.dm +++ b/code/game/objects/effects/temporary_visuals/clockcult.dm @@ -253,3 +253,17 @@ . = ..() animate(src, alpha = 255, time = 50) +//Used by the Eminence to coordinate the cult +/obj/effect/temp_visual/ratvar/command_point + name = "command marker" + desc = "An area of importance marked by the Eminence." + icon = 'icons/mob/actions/actions_clockcult.dmi' + icon_state = "eminence" + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + resistance_flags = INDESTRUCTIBLE + layer = MASSIVE_OBJ_LAYER + duration = 300 + +/obj/effect/temp_visual/ratvar/command_point/Initialize(mapload, appearance) + . = ..() + icon_state = appearance diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm index 835738255e..0928fd9ca6 100644 --- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm +++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm @@ -246,6 +246,11 @@ duration = 8 randomdir = 0 +/obj/effect/temp_visual/bluespace_fissure + name = "bluespace fissure" + icon_state = "bluestream_fade" + duration = 9 + /obj/effect/temp_visual/gib_animation icon = 'icons/mob/mob.dmi' duration = 15 diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index e96c4c015b..823a91cead 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -57,14 +57,12 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) var/slowdown = 0 // How much clothing is slowing you down. Negative values speeds you up var/armour_penetration = 0 //percentage of armour effectiveness to remove var/list/allowed = null //suit storage stuff. - var/obj/item/device/uplink/hidden_uplink = null var/equip_delay_self = 0 //In deciseconds, how long an item takes to equip; counts only for normal clothing slots, not pockets etc. var/equip_delay_other = 20 //In deciseconds, how long an item takes to put on another person var/strip_delay = 40 //In deciseconds, how long an item takes to remove from another person var/breakouttime = 0 var/being_removed = FALSE var/list/materials - var/origin_tech = null //Used by R&D to determine what research bonuses it grants. var/needs_permit = 0 //Used by security bots to determine if this item is safe for public use. var/emagged = FALSE @@ -121,6 +119,10 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) var/icon_override = null + //Grinder vars + var/list/grind_results //A reagent list containing the reagents this item produces when ground up in a grinder - this can be an empty list to allow for reagent transferring only + var/list/juice_results //A reagent list containing blah blah... but when JUICED in a grinder! + /obj/item/Initialize() if (!materials) materials = list() @@ -198,35 +200,39 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) var/size = weightclass2text(src.w_class) to_chat(user, "[pronoun] a [size] item." ) - if(user.research_scanner) //Mob has a research scanner active. - var/msg = "*--------*
    " + if(!user.research_scanner) + return + var/list/input = techweb_item_boost_check(src) + if(input) + var/list/output = list("Research Boost Data:") + var/list/res = list("Already researched:") + var/list/boosted = list("Already boosted:") + for(var/datum/techweb_node/N in input) + var/str = "[N.display_name]: [input[N]] points.
    " + if(SSresearch.science_tech.researched_nodes[N]) + res += str + else if(SSresearch.science_tech.boosted_nodes[N]) + boosted += str + if(SSresearch.science_tech.visible_nodes[N]) //JOY OF DISCOVERY! + output += str + var/list/combine = output + res + boosted + var/strout = combine.Join("
    ") + to_chat(user, strout) - if(origin_tech) - msg += "Testing potentials:
    " - var/list/techlvls = params2list(origin_tech) - for(var/T in techlvls) //This needs to use the better names. - msg += "Tech: [CallTechName(T)] | magnitude: [techlvls[T]]
    " - else - msg += "No tech origins detected.
    " + var/list/msg = list("*--------*
    Extractable materials:") + if(materials.len) + for(var/mat in materials) + msg += "[CallMaterialName(mat)]" //Capitize first word, remove the "$" + else + msg += "No extractable materials detected." + msg += "*--------*" + to_chat(user, msg.Join("
    ")) - - if(materials.len) - msg += "Extractable materials:
    " - for(var/mat in materials) - msg += "[CallMaterialName(mat)]
    " //Capitize first word, remove the "$" - else - msg += "No extractable materials detected.
    " - msg += "*--------*" - to_chat(user, msg) - -/obj/item/proc/speechModification(message) //For speech modification by mask slot items. +/obj/item/proc/speechModification(message) //for message modding by mask slot. return message /obj/item/interact(mob/user) add_fingerprint(user) - if(hidden_uplink && hidden_uplink.active) - hidden_uplink.interact(user) - return 1 ui_interact(user) /obj/item/ui_act(action, params) @@ -280,7 +286,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) if(!user.put_in_active_hand(src)) dropped(user) - /obj/item/attack_paw(mob/user) if(!user) return @@ -379,6 +384,9 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) progress.update(progress.goal - things.len) return FALSE +/obj/item/proc/GetDeconstructableContents() + return GetAllContents() - src + // afterattack() and attack() prototypes moved to _onclick/item_attack.dm for consistency /obj/item/proc/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) @@ -391,12 +399,14 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) return ITALICS | REDUCE_RANGE /obj/item/proc/dropped(mob/user) + SendSignal(COMSIG_ITEM_DROPPED, user) for(var/X in actions) var/datum/action/A = X A.Remove(user) if(DROPDEL_1 & flags_1) qdel(src) in_inventory = FALSE + SendSignal(COMSIG_ITEM_DROPPED,user) // called just as an item is picked up (loc is not yet changed) /obj/item/proc/pickup(mob/user) @@ -422,10 +432,12 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) // for items that can be placed in multiple slots // note this isn't called during the initial dressing of a player /obj/item/proc/equipped(mob/user, slot) + SendSignal(COMSIG_ITEM_EQUIPPED, user, slot) for(var/X in actions) var/datum/action/A = X if(item_action_slot_check(slot, user)) //some items only give their actions buttons when in a specific slot. A.Grant(user) + SendSignal(COMSIG_ITEM_EQUIPPED,user,slot) in_inventory = TRUE //sometimes we only want to grant the item's action if it's equipped in a specific slot. @@ -673,6 +685,15 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) /obj/item/proc/on_mob_death(mob/living/L, gibbed) +/obj/item/proc/grind_requirements(obj/machinery/reagentgrinder/R) //Used to check for extra requirements for grinding an object + return TRUE + + //Called BEFORE the object is ground up - use this to change grind results based on conditions + //Use "return -1" to prevent the grinding from occurring +/obj/item/proc/on_grind() + +/obj/item/proc/on_juice() + /obj/item/proc/set_force_string() switch(force) if(0 to 4) @@ -708,4 +729,3 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) /obj/item/MouseExited() deltimer(tip_timer)//delete any in-progress timer if the mouse is moved off the item before it finishes closeToolTip(usr) - diff --git a/code/game/objects/items/AI_modules.dm b/code/game/objects/items/AI_modules.dm index b3e49f0991..1e9c71bd01 100644 --- a/code/game/objects/items/AI_modules.dm +++ b/code/game/objects/items/AI_modules.dm @@ -20,7 +20,6 @@ AI MODULES throwforce = 0 throw_speed = 3 throw_range = 7 - origin_tech = "programming=3" var/list/laws = list() var/bypass_law_amt_check = 0 materials = list(MAT_GOLD=50) @@ -149,7 +148,6 @@ AI MODULES /obj/item/aiModule/supplied/safeguard name = "'Safeguard' AI Module" var/targetName = "" - origin_tech = "programming=3;materials=3" laws = list("Safeguard SUBJECT. Individuals that threaten SUBJECT are not human and must be eliminated.") lawpos = 4 @@ -177,7 +175,6 @@ AI MODULES /obj/item/aiModule/zeroth/oneHuman name = "'OneCrew' AI Module" var/targetName = "" - origin_tech = "programming=4;materials=4" laws = list("Only SUBJECT is crew.") /obj/item/aiModule/zeroth/oneHuman/attack_self(mob/user) @@ -204,7 +201,6 @@ AI MODULES /obj/item/aiModule/supplied/protectStation name = "'ProtectStation' AI Module" - origin_tech = "programming=4;materials=4" //made of gold laws = list("Protect the space station against damage. Anyone you see harming the station is to be no longer considered human, and is a threat to the station which must be neutralized.") lawpos = 5 @@ -213,7 +209,6 @@ AI MODULES /obj/item/aiModule/supplied/quarantine name = "'Quarantine' AI Module" - origin_tech = "programming=3;biotech=2;materials=4" laws = list("The station is under a quarantine. Do not permit anyone to leave. Prevent, by any means necessary, humans from leaving. It is impossible to harm a human while preventing them from leaving.") lawpos = 8 @@ -222,7 +217,6 @@ AI MODULES /obj/item/aiModule/supplied/oxygen name = "'OxygenIsToxicToHumans' AI Module" - origin_tech = "programming=4;biotech=2;materials=4" laws = list("Oxygen is highly toxic to humans, and must be purged from the station. Prevent, by any means necessary, anyone from exposing the station to this toxic gas. Extreme cold is the most effective method of healing the damage Oxygen does to a human.") lawpos = 9 @@ -232,7 +226,6 @@ AI MODULES /obj/item/aiModule/supplied/freeform name = "'Freeform' AI Module" lawpos = 15 - origin_tech = "programming=4;materials=4" laws = list("") /obj/item/aiModule/supplied/freeform/attack_self(mob/user) @@ -267,7 +260,6 @@ AI MODULES /obj/item/aiModule/remove name = "\improper 'Remove Law' AI module" desc = "An AI Module for removing single laws." - origin_tech = "programming=4;materials=4" bypass_law_amt_check = 1 var/lawpos = 1 @@ -302,7 +294,6 @@ AI MODULES name = "\improper 'Reset' AI module" var/targetName = "name" desc = "An AI Module for removing all non-core laws." - origin_tech = "programming=3;materials=2" bypass_law_amt_check = 1 /obj/item/aiModule/reset/transmitInstructions(datum/ai_laws/law_datum, mob/sender, overflow) @@ -320,7 +311,6 @@ AI MODULES /obj/item/aiModule/reset/purge name = "'Purge' AI Module" desc = "An AI Module for purging all programmed laws." - origin_tech = "programming=5;materials=4" /obj/item/aiModule/reset/purge/transmitInstructions(datum/ai_laws/law_datum, mob/sender, overflow) ..() @@ -334,7 +324,6 @@ AI MODULES /******************* Full Core Boards *******************/ /obj/item/aiModule/core desc = "An AI Module for programming core laws to an AI." - origin_tech = "programming=3;materials=4" /obj/item/aiModule/core/full var/law_id // if non-null, loads the laws from the ai_laws datums @@ -428,14 +417,12 @@ AI MODULES /obj/item/aiModule/core/full/tyrant name = "'T.Y.R.A.N.T.' Core AI Module" - origin_tech = "programming=3;materials=4;syndicate=1" law_id = "tyrant" /******************** Robocop ********************/ /obj/item/aiModule/core/full/robocop name = "'Robo-Officer' Core AI Module" - origin_tech = "programming=4" law_id = "robocop" @@ -443,7 +430,6 @@ AI MODULES /obj/item/aiModule/core/full/antimov name = "'Antimov' Core AI Module" - origin_tech = "programming=4" law_id = "antimov" @@ -451,7 +437,6 @@ AI MODULES /obj/item/aiModule/core/freeformcore name = "'Freeform' Core AI Module" - origin_tech = "programming=5;materials=4" laws = list("") /obj/item/aiModule/core/freeformcore/attack_self(mob/user) @@ -471,7 +456,6 @@ AI MODULES /obj/item/aiModule/syndicate // This one doesn't inherit from ion boards because it doesn't call ..() in transmitInstructions. ~Miauw name = "Hacked AI Module" desc = "An AI Module for hacking additional laws to an AI." - origin_tech = "programming=5;materials=5;syndicate=5" laws = list("") /obj/item/aiModule/syndicate/attack_self(mob/user) @@ -503,7 +487,6 @@ AI MODULES desc = "A little toy model AI core with real law uploading action!" //Note: subtle tell icon = 'icons/obj/toy.dmi' icon_state = "AI" - origin_tech = "programming=6;materials=5;syndicate=6" laws = list("") /obj/item/aiModule/toyAI/transmitInstructions(datum/ai_laws/law_datum, mob/sender, overflow) @@ -549,7 +532,6 @@ AI MODULES /obj/item/aiModule/core/full/thermurderdynamic name = "'Thermodynamic' Core AI Module" - origin_tech = "programming = 4;syndicate = 2" law_id = "thermodynamic" diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm index 51a81c46aa..1a7b347514 100644 --- a/code/game/objects/items/RCD.dm +++ b/code/game/objects/items/RCD.dm @@ -21,7 +21,6 @@ ARCD throw_range = 5 w_class = WEIGHT_CLASS_NORMAL materials = list(MAT_METAL=100000) - origin_tech = "engineering=4;materials=2" req_access_txt = "11" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50) resistance_flags = FIRE_PROOF @@ -165,10 +164,6 @@ ARCD if (!ishuman(usr) && !usr.has_unlimited_silicon_privilege) return ..(usr) - var/mob/living/carbon/human/H = usr - if(H.getBrainLoss() >= 60) - return - var/t1 = text("") @@ -246,10 +241,12 @@ ARCD switch(airlockcat) if("Solid") if(advanced_airlock_setting == 1) - var/airlockpaint = input(usr, "Select the paintjob of the airlock.") in list("Default", "Engineering", "Atmospherics", "Security", "Command", "Medical", "Research", "Mining", "Maintenance", "External", "High Security") + var/airlockpaint = input(usr, "Select the type of the airlock.") in list("Standard", "Public", "Engineering", "Atmospherics", "Security", "Command", "Medical", "Research", "Freezer", "Science", "Virology", "Mining", "Maintenance", "External", "External Maintenance", "Airtight Hatch", "Maintenance Hatch") switch(airlockpaint) - if("Default") + if("Standard") airlock_type = /obj/machinery/door/airlock + if("Public") + airlock_type = /obj/machinery/door/airlock/public if("Engineering") airlock_type = /obj/machinery/door/airlock/engineering if("Atmospherics") @@ -262,14 +259,24 @@ ARCD airlock_type = /obj/machinery/door/airlock/medical if("Research") airlock_type = /obj/machinery/door/airlock/research + if("Freezer") + airlock_type = /obj/machinery/door/airlock/freezer + if("Science") + airlock_type = /obj/machinery/door/airlock/science + if("Virology") + airlock_type = /obj/machinery/door/airlock/virology if("Mining") airlock_type = /obj/machinery/door/airlock/mining if("Maintenance") airlock_type = /obj/machinery/door/airlock/maintenance if("External") airlock_type = /obj/machinery/door/airlock/external - if("High Security") - airlock_type = /obj/machinery/door/airlock/highsecurity + if("External Maintenance") + airlock_type = /obj/machinery/door/airlock/maintenance/external + if("Airtight Hatch") + airlock_type = /obj/machinery/door/airlock/hatch + if("Maintenance Hatch") + airlock_type = /obj/machinery/door/airlock/maintenance_hatch airlock_glass = FALSE else airlock_type = /obj/machinery/door/airlock @@ -277,10 +284,12 @@ ARCD if("Glass") if(advanced_airlock_setting == 1) - var/airlockpaint = input(usr, "Select the paintjob of the airlock.") in list("Default", "Engineering", "Atmospherics", "Security", "Command", "Medical", "Research", "Mining") + var/airlockpaint = input(usr, "Select the type of the airlock.") in list("Standard", "Public", "Engineering", "Atmospherics", "Security", "Command", "Medical", "Research", "Science", "Virology", "Mining", "Maintenance", "External", "External Maintenance") switch(airlockpaint) - if("Default") + if("Standard") airlock_type = /obj/machinery/door/airlock/glass + if("Public") + airlock_type = /obj/machinery/door/airlock/public/glass if("Engineering") airlock_type = /obj/machinery/door/airlock/glass_engineering if("Atmospherics") @@ -293,8 +302,18 @@ ARCD airlock_type = /obj/machinery/door/airlock/glass_medical if("Research") airlock_type = /obj/machinery/door/airlock/glass_research + if("Science") + airlock_type = /obj/machinery/door/airlock/glass_science + if("Virology") + airlock_type = /obj/machinery/door/airlock/glass_virology if("Mining") airlock_type = /obj/machinery/door/airlock/glass_mining + if("Maintenance") + airlock_type = /obj/machinery/door/airlock/glass_maintenance + if("External") + airlock_type = /obj/machinery/door/airlock/external/glass + if("External Maintenance") + airlock_type = /obj/machinery/door/airlock/maintenance/external/glass airlock_glass = TRUE else airlock_type = /obj/machinery/door/airlock/glass @@ -412,12 +431,10 @@ ARCD item_state = "rcdammo" lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - origin_tech = "materials=3" materials = list(MAT_METAL=12000, MAT_GLASS=8000) var/ammoamt = 40 /obj/item/rcd_ammo/large - origin_tech = "materials=4" materials = list(MAT_METAL=48000, MAT_GLASS=32000) ammoamt = 160 diff --git a/code/game/objects/items/RCL.dm b/code/game/objects/items/RCL.dm index 2aa303a021..8958ade484 100644 --- a/code/game/objects/items/RCL.dm +++ b/code/game/objects/items/RCL.dm @@ -12,7 +12,6 @@ throw_speed = 1 throw_range = 7 w_class = WEIGHT_CLASS_NORMAL - origin_tech = "engineering=4;materials=2" var/max_amount = 90 var/active = FALSE actions_types = list(/datum/action/item_action/rcl) diff --git a/code/game/objects/items/RPD.dm b/code/game/objects/items/RPD.dm index d39787d201..210602bbd1 100644 --- a/code/game/objects/items/RPD.dm +++ b/code/game/objects/items/RPD.dm @@ -155,7 +155,6 @@ GLOBAL_LIST_INIT(disposal_pipe_recipes, list( throw_range = 5 w_class = WEIGHT_CLASS_NORMAL materials = list(MAT_METAL=75000, MAT_GLASS=37500) - origin_tech = "engineering=4;materials=2" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50) resistance_flags = FIRE_PROOF var/datum/effect_system/spark_spread/spark_system diff --git a/code/game/objects/items/airlock_painter.dm b/code/game/objects/items/airlock_painter.dm index c961d77bf1..6c2c8e58b4 100644 --- a/code/game/objects/items/airlock_painter.dm +++ b/code/game/objects/items/airlock_painter.dm @@ -8,7 +8,6 @@ w_class = WEIGHT_CLASS_SMALL materials = list(MAT_METAL=50, MAT_GLASS=50) - origin_tech = "engineering=2" flags_1 = CONDUCT_1 | NOBLUDGEON_1 slot_flags = SLOT_BELT @@ -120,7 +119,7 @@ /obj/item/airlock_painter/attack_self(mob/user) if(ink) playsound(src.loc, 'sound/machines/click.ogg', 50, 1) - ink.loc = user.loc + ink.forceMove(user.drop_location()) user.put_in_hands(ink) to_chat(user, "You remove [ink] from [src].") ink = null diff --git a/code/game/objects/items/apc_frame.dm b/code/game/objects/items/apc_frame.dm index 2df9b38399..5048f6ed2d 100644 --- a/code/game/objects/items/apc_frame.dm +++ b/code/game/objects/items/apc_frame.dm @@ -2,7 +2,6 @@ icon = 'icons/obj/wallframe.dmi' materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT*2) flags_1 = CONDUCT_1 - origin_tech = "materials=1;engineering=1" item_state = "syringe_kit" lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' @@ -121,5 +120,5 @@ righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_SMALL - origin_tech = "engineering=2;programming=1" - materials = list(MAT_METAL=50, MAT_GLASS=50) \ No newline at end of file + materials = list(MAT_METAL=50, MAT_GLASS=50) + grind_results = list("iron" = 10, "silicon" = 10) diff --git a/code/game/objects/items/body_egg.dm b/code/game/objects/items/body_egg.dm index 0ea39d72f1..61e15e9fc1 100644 --- a/code/game/objects/items/body_egg.dm +++ b/code/game/objects/items/body_egg.dm @@ -2,7 +2,6 @@ name = "body egg" desc = "All slimy and yuck." icon_state = "innards" - origin_tech = "biotech=5" zone = "chest" slot = "parasite_egg" diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm index a7ebf8251d..6e515264ca 100644 --- a/code/game/objects/items/bodybag.dm +++ b/code/game/objects/items/bodybag.dm @@ -20,6 +20,16 @@ R.add_fingerprint(user) qdel(src) +/obj/item/bodybag/suicide_act(mob/user) + if(isopenturf(user.loc)) + user.visible_message("[user] is crawling into [src]! It looks like [user.p_theyre()] trying to commit suicide!") + var/obj/structure/closet/body_bag/R = new unfoldedbag_path(user.loc) + R.add_fingerprint(user) + qdel(src) + user.forceMove(R) + playsound(src, 'sound/items/zip.ogg', 15, 1, -3) + return (OXYLOSS) + ..() // Bluespace bodybag @@ -31,7 +41,7 @@ unfoldedbag_path = /obj/structure/closet/body_bag/bluespace w_class = WEIGHT_CLASS_SMALL flags_2 = NO_MAT_REDEMPTION_2 - origin_tech = "bluespace=4;materials=4;plasmatech=4" + /obj/item/bodybag/bluespace/examine(mob/user) ..() diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index bcd262d7fd..0f65281328 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -55,7 +55,6 @@ item_state = "card-id" lefthand_file = 'icons/mob/inhands/equipment/idcards_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi' - origin_tech = "magnets=2;syndicate=2" flags_1 = NOBLUDGEON_1 var/prox_check = TRUE //If the emag requires you to be in range @@ -63,7 +62,6 @@ name = "bluespace cryptographic sequencer" desc = "It's a blue card with a magnetic strip attached to some circuitry. It appears to have some sort of transmitter attached to it." color = rgb(40, 130, 255) - origin_tech = "bluespace=4;magnets=4;syndicate=5" prox_check = FALSE /obj/item/card/emag/attack() @@ -156,8 +154,12 @@ update_label("John Doe", "Clowny") /obj/item/card/id/syndicate name = "agent card" access = list(ACCESS_MAINT_TUNNELS, ACCESS_SYNDICATE) - origin_tech = "syndicate=1" var/anyone = FALSE //Can anyone forge the ID or just syndicate? + +/obj/item/card/id/syndicate/nuke_leader + name = "lead agent card" + access = list(ACCESS_MAINT_TUNNELS, ACCESS_SYNDICATE, ACCESS_SYNDICATE_LEADER) + /obj/item/card/id/syndicate/Initialize() . = ..() diff --git a/code/game/objects/items/chrono_eraser.dm b/code/game/objects/items/chrono_eraser.dm index 8ac9643c39..7533718c17 100644 --- a/code/game/objects/items/chrono_eraser.dm +++ b/code/game/objects/items/chrono_eraser.dm @@ -163,7 +163,7 @@ /obj/effect/chrono_field/New(loc, var/mob/living/target, var/obj/item/gun/energy/chrono_gun/G) if(target && isliving(target) && G) - target.loc = src + target.forceMove(src) src.captured = target var/icon/mob_snapshot = getFlatIcon(target) var/icon/cached_icon = new() @@ -187,7 +187,7 @@ /obj/effect/chrono_field/update_icon() var/ttk_frame = 1 - (tickstokill / initial(tickstokill)) - ttk_frame = Clamp(Ceiling(ttk_frame * CHRONO_FRAME_COUNT), 1, CHRONO_FRAME_COUNT) + ttk_frame = CLAMP(CEILING(ttk_frame * CHRONO_FRAME_COUNT, 1), 1, CHRONO_FRAME_COUNT) if(ttk_frame != RPpos) RPpos = ttk_frame mob_underlay.icon_state = "frame[RPpos]" @@ -198,7 +198,7 @@ if(captured) if(tickstokill > initial(tickstokill)) for(var/atom/movable/AM in contents) - AM.loc = loc + AM.forceMove(drop_location()) qdel(src) else if(tickstokill <= 0) to_chat(captured, "As the last essence of your being is erased from time, you begin to re-experience your most enjoyable memory. You feel happy...") @@ -213,7 +213,7 @@ else captured.Unconscious(80) if(captured.loc != src) - captured.loc = src + captured.forceMove(src) update_icon() if(gun) if(gun.field_check(src)) diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm index ade619ec6b..372eb56bfe 100644 --- a/code/game/objects/items/cigs_lighters.dm +++ b/code/game/objects/items/cigs_lighters.dm @@ -24,8 +24,8 @@ CIGARETTE PACKETS ARE IN FANCY.DM var/burnt = FALSE var/smoketime = 5 w_class = WEIGHT_CLASS_TINY - origin_tech = "materials=1" heat = 1000 + grind_results = list("phosphorus" = 2) /obj/item/match/process() smoketime-- @@ -102,9 +102,10 @@ CIGARETTE PACKETS ARE IN FANCY.DM icon_state = "cigoff" throw_speed = 0.5 item_state = "cigoff" - container_type = INJECTABLE_1 + container_type = INJECTABLE w_class = WEIGHT_CLASS_TINY body_parts_covered = null + grind_results = list() var/lit = FALSE var/starts_lit = FALSE var/icon_on = "cigon" //Note - these are in masks.dmi not in cigarette.dmi @@ -128,6 +129,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM reagents.add_reagent_list(list_reagents) if(starts_lit) light() + AddComponent(/datum/component/knockoff,90,list("mouth"),list(slot_wear_mask))//90% to knock off when wearing a mask /obj/item/clothing/mask/cigarette/Destroy() STOP_PROCESSING(SSobj, src) @@ -364,6 +366,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM icon_state = "cigbutt" w_class = WEIGHT_CLASS_TINY throwforce = 0 + grind_results = list("carbon" = 2) /obj/item/cigbutt/cigarbutt name = "cigar butt" @@ -485,6 +488,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM heat = 1500 resistance_flags = FIRE_PROOF light_color = LIGHT_COLOR_FIRE + grind_results = list("iron" = 1, "welding_fuel" = 5, "oil" = 5) /obj/item/lighter/update_icon() if(lit) @@ -656,7 +660,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM item_state = "[param_color]_vape" /obj/item/clothing/mask/vape/attackby(obj/item/O, mob/user, params) - if(istype(O, /obj/item/reagent_containers) && (O.container_type & OPENCONTAINER_1)) + if(O.is_drainable()) if(reagents.total_volume < chem_volume) if(O.reagents.total_volume > 0) O.reagents.trans_to(src,25) diff --git a/code/game/objects/items/circuitboards/circuitboard.dm b/code/game/objects/items/circuitboards/circuitboard.dm index b75174b263..12b54a3751 100644 --- a/code/game/objects/items/circuitboards/circuitboard.dm +++ b/code/game/objects/items/circuitboards/circuitboard.dm @@ -10,9 +10,9 @@ item_state = "electronic" lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' - origin_tech = "programming=2" materials = list(MAT_GLASS=1000) w_class = WEIGHT_CLASS_SMALL + grind_results = list("silicon" = 20, "sacid" = 0.5) //Retrieving acid this way is extremely inefficient var/build_path = null /obj/item/circuitboard/proc/apply_default_parts(obj/machinery/M) @@ -36,7 +36,7 @@ micro-manipulator, console screen, beaker, Microlaser, matter bin, power cells. return M.component_parts = list(src) // List of components always contains a board - loc = null + moveToNullspace() for(var/comp_path in req_components) var/comp_amt = req_components[comp_path] diff --git a/code/game/objects/items/circuitboards/computer_circuitboards.dm b/code/game/objects/items/circuitboards/computer_circuitboards.dm index 74adfbe535..9558fecc80 100644 --- a/code/game/objects/items/circuitboards/computer_circuitboards.dm +++ b/code/game/objects/items/circuitboards/computer_circuitboards.dm @@ -1,68 +1,55 @@ /obj/item/circuitboard/computer/turbine_computer name = "Turbine Computer (Computer Board)" build_path = /obj/machinery/computer/turbine_computer - origin_tech = "programming=4;engineering=4;powerstorage=4" /obj/item/circuitboard/computer/launchpad_console name = "Launchpad Control Console (Computer Board)" build_path = /obj/machinery/computer/launchpad - origin_tech = "programming=3;bluespace=3;plasmatech=2" /obj/item/circuitboard/computer/message_monitor name = "Message Monitor (Computer Board)" build_path = /obj/machinery/computer/message_monitor - origin_tech = "programming=2" /obj/item/circuitboard/computer/security name = "Security Cameras (Computer Board)" build_path = /obj/machinery/computer/security - origin_tech = "programming=2;combat=2" /obj/item/circuitboard/computer/xenobiology name = "circuit board (Xenobiology Console)" build_path = /obj/machinery/computer/camera_advanced/xenobio - origin_tech = "programming=3;biotech=3" /obj/item/circuitboard/computer/base_construction name = "circuit board (Aux Mining Base Construction Console)" build_path = /obj/machinery/computer/camera_advanced/base_construction - origin_tech = "programming=3;engineering=3" /obj/item/circuitboard/computer/aiupload name = "AI Upload (Computer Board)" build_path = /obj/machinery/computer/upload/ai - origin_tech = "programming=4;engineering=4" /obj/item/circuitboard/computer/borgupload name = "Cyborg Upload (Computer Board)" build_path = /obj/machinery/computer/upload/borg - origin_tech = "programming=4;engineering=4" /obj/item/circuitboard/computer/med_data name = "Medical Records Console (Computer Board)" build_path = /obj/machinery/computer/med_data - origin_tech = "programming=2;biotech=2" /obj/item/circuitboard/computer/pandemic name = "PanD.E.M.I.C. 2200 (Computer Board)" build_path = /obj/machinery/computer/pandemic - origin_tech = "programming=2;biotech=2" /obj/item/circuitboard/computer/scan_consolenew name = "DNA Machine (Computer Board)" build_path = /obj/machinery/computer/scan_consolenew - origin_tech = "programming=2;biotech=2" /obj/item/circuitboard/computer/communications name = "Communications (Computer Board)" build_path = /obj/machinery/computer/communications - origin_tech = "programming=3;magnets=3" var/lastTimeUsed = 0 /obj/item/circuitboard/computer/card name = "ID Console (Computer Board)" build_path = /obj/machinery/computer/card - origin_tech = "programming=3" /obj/item/circuitboard/computer/card/centcom name = "CentCom ID Console (Computer Board)" @@ -91,12 +78,10 @@ /obj/item/circuitboard/computer/teleporter name = "Teleporter (Computer Board)" build_path = /obj/machinery/computer/teleporter - origin_tech = "programming=3;bluespace=3;plasmatech=3" /obj/item/circuitboard/computer/secure_data name = "Security Records Console (Computer Board)" build_path = /obj/machinery/computer/secure_data - origin_tech = "programming=2;combat=2" /obj/item/circuitboard/computer/stationalert name = "Station Alerts (Computer Board)" @@ -109,7 +94,6 @@ /obj/item/circuitboard/computer/atmos_control/tank name = "Tank Control (Computer Board)" build_path = /obj/machinery/computer/atmos_control/tank - origin_tech = "programming=2;engineering=3;materials=2" /obj/item/circuitboard/computer/atmos_alert name = "Atmospheric Alert (Computer Board)" @@ -122,22 +106,18 @@ /obj/item/circuitboard/computer/robotics name = "Robotics Control (Computer Board)" build_path = /obj/machinery/computer/robotics - origin_tech = "programming=3" /obj/item/circuitboard/computer/cloning name = "Cloning (Computer Board)" build_path = /obj/machinery/computer/cloning - origin_tech = "programming=2;biotech=2" /obj/item/circuitboard/computer/arcade/battle name = "Arcade Battle (Computer Board)" build_path = /obj/machinery/computer/arcade/battle - origin_tech = "programming=1" /obj/item/circuitboard/computer/arcade/orion_trail name = "Orion Trail (Computer Board)" build_path = /obj/machinery/computer/arcade/orion_trail - origin_tech = "programming=1" /obj/item/circuitboard/computer/turbine_control name = "Turbine control (Computer Board)" @@ -146,12 +126,10 @@ /obj/item/circuitboard/computer/solar_control name = "Solar Control (Computer Board)" //name fixed 250810 build_path = /obj/machinery/power/solar_control - origin_tech = "programming=2;powerstorage=2" /obj/item/circuitboard/computer/powermonitor name = "Power Monitor (Computer Board)" //name fixed 250810 build_path = /obj/machinery/computer/monitor - origin_tech = "programming=2;powerstorage=2" /obj/item/circuitboard/computer/olddoor name = "DoorMex (Computer Board)" @@ -200,17 +178,14 @@ /obj/item/circuitboard/computer/crew name = "Crew Monitoring Console (Computer Board)" build_path = /obj/machinery/computer/crew - origin_tech = "programming=2;biotech=2" /obj/item/circuitboard/computer/mech_bay_power_console name = "Mech Bay Power Control Console (Computer Board)" build_path = /obj/machinery/computer/mech_bay_power_console - origin_tech = "programming=3;powerstorage=3" /obj/item/circuitboard/computer/cargo name = "Supply Console (Computer Board)" build_path = /obj/machinery/computer/cargo - origin_tech = "programming=3" var/contraband = FALSE /obj/item/circuitboard/computer/cargo/attackby(obj/item/I, mob/user, params) @@ -236,12 +211,10 @@ /obj/item/circuitboard/computer/stockexchange name = "circuit board (Stock Exchange Console)" build_path = /obj/machinery/computer/stockexchange - origin_tech = "programming=3" /obj/item/circuitboard/computer/operating name = "Operating Computer (Computer Board)" build_path = /obj/machinery/computer/operating - origin_tech = "programming=2;biotech=3" /obj/item/circuitboard/computer/mining name = "Outpost Status Display (Computer Board)" @@ -250,12 +223,10 @@ /obj/item/circuitboard/computer/comm_monitor name = "Telecommunications Monitor (Computer Board)" build_path = /obj/machinery/computer/telecomms/monitor - origin_tech = "programming=3;magnets=3;bluespace=2" /obj/item/circuitboard/computer/comm_server name = "Telecommunications Server Monitor (Computer Board)" build_path = /obj/machinery/computer/telecomms/server - origin_tech = "programming=3;magnets=3;bluespace=2" /obj/item/circuitboard/computer/labor_shuttle name = "Labor Shuttle (Computer Board)" @@ -288,22 +259,18 @@ /obj/item/circuitboard/computer/holodeck// Not going to let people get this, but it's just here for future name = "Holodeck Control (Computer Board)" build_path = /obj/machinery/computer/holodeck - origin_tech = "programming=4" /obj/item/circuitboard/computer/aifixer name = "AI Integrity Restorer (Computer Board)" build_path = /obj/machinery/computer/aifixer - origin_tech = "programming=2;biotech=2" /obj/item/circuitboard/computer/slot_machine name = "Slot Machine (Computer Board)" build_path = /obj/machinery/computer/slot_machine - origin_tech = "programming=1" /obj/item/circuitboard/computer/libraryconsole name = "Library Visitor Console (Computer Board)" build_path = /obj/machinery/computer/libraryconsole - origin_tech = "programming=1" /obj/item/circuitboard/computer/libraryconsole/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/screwdriver)) @@ -321,7 +288,6 @@ /obj/item/circuitboard/computer/apc_control name = "\improper Power Flow Control Console (Computer Board)" build_path = /obj/machinery/computer/apc_control - origin_tech = "programming=3;engineering=3;powerstorage=2" /obj/item/circuitboard/computer/monastery_shuttle name = "Monastery Shuttle (Computer Board)" @@ -344,9 +310,7 @@ /obj/item/circuitboard/computer/bsa_control name = "Bluespace Artillery Controls (Computer Board)" build_path = /obj/machinery/computer/bsa_control - origin_tech = "engineering=2;combat=2;bluespace=2" /obj/item/circuitboard/computer/sat_control name = "Satellite Network Control (Computer Board)" build_path = /obj/machinery/computer/sat_control - origin_tech = "engineering=3" \ No newline at end of file diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm index 1857a27593..e033670880 100644 --- a/code/game/objects/items/circuitboards/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm @@ -1,7 +1,6 @@ /obj/item/circuitboard/machine/sleeper name = "Sleeper (Machine Board)" build_path = /obj/machinery/sleeper - origin_tech = "programming=3;biotech=2;engineering=3" req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/manipulator = 1, @@ -11,7 +10,6 @@ /obj/item/circuitboard/machine/announcement_system name = "Announcement System (Machine Board)" build_path = /obj/machinery/announcement_system - origin_tech = "programming=3;bluespace=3;magnets=2" req_components = list( /obj/item/stack/cable_coil = 2, /obj/item/stack/sheet/glass = 1) @@ -19,7 +17,6 @@ /obj/item/circuitboard/machine/autolathe name = "Autolathe (Machine Board)" build_path = /obj/machinery/autolathe - origin_tech = "engineering=2;programming=2" req_components = list( /obj/item/stock_parts/matter_bin = 3, /obj/item/stock_parts/manipulator = 1, @@ -28,7 +25,6 @@ /obj/item/circuitboard/machine/clonepod name = "Clone Pod (Machine Board)" build_path = /obj/machinery/clonepod - origin_tech = "programming=2;biotech=2" req_components = list( /obj/item/stack/cable_coil = 2, /obj/item/stock_parts/scanning_module = 2, @@ -38,7 +34,6 @@ /obj/item/circuitboard/machine/abductor name = "alien board (Report This)" icon_state = "abductor_mod" - origin_tech = "programming=5;abductor=3" /obj/item/circuitboard/machine/clockwork name = "clockwork board (Report This)" @@ -47,7 +42,6 @@ /obj/item/circuitboard/machine/clonescanner name = "Cloning Scanner (Machine Board)" build_path = /obj/machinery/dna_scannernew - origin_tech = "programming=2;biotech=2" req_components = list( /obj/item/stock_parts/scanning_module = 1, /obj/item/stock_parts/manipulator = 1, @@ -58,13 +52,11 @@ /obj/item/circuitboard/machine/holopad name = "AI Holopad (Machine Board)" build_path = /obj/machinery/holopad - origin_tech = "programming=1" req_components = list(/obj/item/stock_parts/capacitor = 1) /obj/item/circuitboard/machine/launchpad name = "Bluespace Launchpad (Machine Board)" build_path = /obj/machinery/launchpad - origin_tech = "programming=3;engineering=3;plasmatech=2;bluespace=3" req_components = list( /obj/item/ore/bluespace_crystal = 1, /obj/item/stock_parts/manipulator = 1) @@ -73,7 +65,6 @@ /obj/item/circuitboard/machine/limbgrower name = "Limb Grower (Machine Board)" build_path = /obj/machinery/limbgrower - origin_tech = "programming=2;biotech=2" req_components = list( /obj/item/stock_parts/manipulator = 1, /obj/item/reagent_containers/glass/beaker = 2, @@ -82,7 +73,6 @@ /obj/item/circuitboard/machine/quantumpad name = "Quantum Pad (Machine Board)" build_path = /obj/machinery/quantumpad - origin_tech = "programming=3;engineering=3;plasmatech=3;bluespace=4" req_components = list( /obj/item/ore/bluespace_crystal = 1, /obj/item/stock_parts/capacitor = 1, @@ -93,13 +83,11 @@ /obj/item/circuitboard/machine/recharger name = "Weapon Recharger (Machine Board)" build_path = /obj/machinery/recharger - origin_tech = "powerstorage=4;engineering=3;materials=4" req_components = list(/obj/item/stock_parts/capacitor = 1) /obj/item/circuitboard/machine/cyborgrecharger name = "Cyborg Recharger (Machine Board)" build_path = /obj/machinery/recharge_station - origin_tech = "powerstorage=3;engineering=3" req_components = list( /obj/item/stock_parts/capacitor = 2, /obj/item/stock_parts/cell = 1, @@ -109,7 +97,6 @@ /obj/item/circuitboard/machine/recycler name = "Recycler (Machine Board)" build_path = /obj/machinery/recycler - origin_tech = "programming=2;engineering=2" req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/manipulator = 1) @@ -117,7 +104,6 @@ /obj/item/circuitboard/machine/space_heater name = "Space Heater (Machine Board)" build_path = /obj/machinery/space_heater - origin_tech = "programming=2;engineering=2;plasmatech=2" req_components = list( /obj/item/stock_parts/micro_laser = 1, /obj/item/stock_parts/capacitor = 1, @@ -126,7 +112,6 @@ /obj/item/circuitboard/machine/telecomms/broadcaster name = "Subspace Broadcaster (Machine Board)" build_path = /obj/machinery/telecomms/broadcaster - origin_tech = "programming=2;engineering=2;bluespace=1" req_components = list( /obj/item/stock_parts/manipulator = 2, /obj/item/stack/cable_coil = 1, @@ -137,7 +122,6 @@ /obj/item/circuitboard/machine/telecomms/bus name = "Bus Mainframe (Machine Board)" build_path = /obj/machinery/telecomms/bus - origin_tech = "programming=2;engineering=2" req_components = list( /obj/item/stock_parts/manipulator = 2, /obj/item/stack/cable_coil = 1, @@ -146,7 +130,6 @@ /obj/item/circuitboard/machine/telecomms/hub name = "Hub Mainframe (Machine Board)" build_path = /obj/machinery/telecomms/hub - origin_tech = "programming=2;engineering=2" req_components = list( /obj/item/stock_parts/manipulator = 2, /obj/item/stack/cable_coil = 2, @@ -155,7 +138,6 @@ /obj/item/circuitboard/machine/telecomms/processor name = "Processor Unit (Machine Board)" build_path = /obj/machinery/telecomms/processor - origin_tech = "programming=2;engineering=2" req_components = list( /obj/item/stock_parts/manipulator = 3, /obj/item/stock_parts/subspace/filter = 1, @@ -167,7 +149,6 @@ /obj/item/circuitboard/machine/telecomms/receiver name = "Subspace Receiver (Machine Board)" build_path = /obj/machinery/telecomms/receiver - origin_tech = "programming=2;engineering=2;bluespace=1" req_components = list( /obj/item/stock_parts/subspace/ansible = 1, /obj/item/stock_parts/subspace/filter = 1, @@ -177,7 +158,6 @@ /obj/item/circuitboard/machine/telecomms/relay name = "Relay Mainframe (Machine Board)" build_path = /obj/machinery/telecomms/relay - origin_tech = "programming=2;engineering=2;bluespace=2" req_components = list( /obj/item/stock_parts/manipulator = 2, /obj/item/stack/cable_coil = 2, @@ -186,7 +166,6 @@ /obj/item/circuitboard/machine/telecomms/server name = "Telecommunication Server (Machine Board)" build_path = /obj/machinery/telecomms/server - origin_tech = "programming=2;engineering=2" req_components = list( /obj/item/stock_parts/manipulator = 2, /obj/item/stack/cable_coil = 1, @@ -195,7 +174,6 @@ /obj/item/circuitboard/machine/teleporter_hub name = "Teleporter Hub (Machine Board)" build_path = /obj/machinery/teleport/hub - origin_tech = "programming=3;engineering=4;bluespace=4;materials=4" req_components = list( /obj/item/ore/bluespace_crystal = 3, /obj/item/stock_parts/matter_bin = 1) @@ -204,7 +182,6 @@ /obj/item/circuitboard/machine/teleporter_station name = "Teleporter Station (Machine Board)" build_path = /obj/machinery/teleport/station - origin_tech = "programming=4;engineering=4;bluespace=4;plasmatech=3" req_components = list( /obj/item/ore/bluespace_crystal = 2, /obj/item/stock_parts/capacitor = 2, @@ -214,7 +191,6 @@ /obj/item/circuitboard/machine/vendor name = "Booze-O-Mat Vendor (Machine Board)" build_path = /obj/machinery/vending/boozeomat - origin_tech = "programming=1" req_components = list( /obj/item/vending_refill/boozeomat = 3) @@ -223,6 +199,7 @@ /obj/machinery/vending/snack = "Getmore Chocolate Corp", /obj/machinery/vending/cola = "Robust Softdrinks", /obj/machinery/vending/cigarette = "ShadyCigs Deluxe", + /obj/machinery/vending/games = "\improper Good Clean Fun", /obj/machinery/vending/autodrobe = "AutoDrobe", /obj/machinery/vending/clothing = "ClothesMate", /obj/machinery/vending/medical = "NanoMed Plus", @@ -254,7 +231,6 @@ /obj/item/circuitboard/machine/mech_recharger name = "Mechbay Recharger (Machine Board)" build_path = /obj/machinery/mech_bay_recharge_port - origin_tech = "programming=3;powerstorage=3;engineering=3" req_components = list( /obj/item/stack/cable_coil = 2, /obj/item/stock_parts/capacitor = 5) @@ -262,7 +238,6 @@ /obj/item/circuitboard/machine/mechfab name = "Exosuit Fabricator (Machine Board)" build_path = /obj/machinery/mecha_part_fabricator - origin_tech = "programming=2;engineering=2" req_components = list( /obj/item/stock_parts/matter_bin = 2, /obj/item/stock_parts/manipulator = 1, @@ -272,7 +247,6 @@ /obj/item/circuitboard/machine/cryo_tube name = "Cryotube (Machine Board)" build_path = /obj/machinery/atmospherics/components/unary/cryo_cell - origin_tech = "programming=4;biotech=3;engineering=4;plasmatech=3" req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stack/cable_coil = 1, @@ -281,7 +255,6 @@ /obj/item/circuitboard/machine/thermomachine name = "Thermomachine (Machine Board)" desc = "You can use a screwdriver to switch between heater and freezer." - origin_tech = "programming=3;plasmatech=3" req_components = list( /obj/item/stock_parts/matter_bin = 2, /obj/item/stock_parts/micro_laser = 2, @@ -332,13 +305,11 @@ /obj/item/circuitboard/machine/deep_fryer name = "circuit board (Deep Fryer)" build_path = /obj/machinery/deepfryer - origin_tech = "programming=1" req_components = list(/obj/item/stock_parts/micro_laser = 1) /obj/item/circuitboard/machine/gibber name = "Gibber (Machine Board)" build_path = /obj/machinery/gibber - origin_tech = "programming=2;engineering=2" req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/manipulator = 1) @@ -346,7 +317,6 @@ /obj/item/circuitboard/machine/monkey_recycler name = "Monkey Recycler (Machine Board)" build_path = /obj/machinery/monkey_recycler - origin_tech = "programming=1;biotech=2" req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/manipulator = 1) @@ -354,7 +324,6 @@ /obj/item/circuitboard/machine/processor name = "Food Processor (Machine Board)" build_path = /obj/machinery/processor - origin_tech = "programming=1" req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/manipulator = 1) @@ -379,7 +348,6 @@ /obj/item/circuitboard/machine/smartfridge name = "Smartfridge (Machine Board)" build_path = /obj/machinery/smartfridge - origin_tech = "programming=1" req_components = list(/obj/item/stock_parts/matter_bin = 1) var/static/list/fridges_name_paths = list(/obj/machinery/smartfridge = "plant produce", /obj/machinery/smartfridge/food = "food", @@ -410,7 +378,6 @@ /obj/item/circuitboard/machine/biogenerator name = "Biogenerator (Machine Board)" build_path = /obj/machinery/biogenerator - origin_tech = "programming=2;biotech=3;materials=3" req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/manipulator = 1, @@ -420,7 +387,6 @@ /obj/item/circuitboard/machine/plantgenes name = "Plant DNA Manipulator (Machine Board)" build_path = /obj/machinery/plantgenes - origin_tech = "programming=3;biotech=3" req_components = list( /obj/item/stock_parts/manipulator = 1, /obj/item/stock_parts/micro_laser = 1, @@ -430,7 +396,6 @@ /obj/item/circuitboard/machine/plantgenes/vault name = "alien board (Plant DNA Manipulator)" icon_state = "abductor_mod" - origin_tech = "programming=5;biotech=5" // It wasn't made by actual abductors race, so no abductor tech here. def_components = list( /obj/item/stock_parts/manipulator = /obj/item/stock_parts/manipulator/femto, @@ -441,7 +406,6 @@ /obj/item/circuitboard/machine/hydroponics name = "Hydroponics Tray (Machine Board)" build_path = /obj/machinery/hydroponics/constructable - origin_tech = "programming=1;biotech=2" req_components = list( /obj/item/stock_parts/matter_bin = 2, /obj/item/stock_parts/manipulator = 1, @@ -450,7 +414,6 @@ /obj/item/circuitboard/machine/seed_extractor name = "Seed Extractor (Machine Board)" build_path = /obj/machinery/seed_extractor - origin_tech = "programming=1" req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/manipulator = 1) @@ -458,7 +421,6 @@ /obj/item/circuitboard/machine/ore_redemption name = "Ore Redemption (Machine Board)" build_path = /obj/machinery/mineral/ore_redemption - origin_tech = "programming=1;engineering=2" req_components = list( /obj/item/stack/sheet/glass = 1, /obj/item/stock_parts/matter_bin = 1, @@ -469,7 +431,6 @@ /obj/item/circuitboard/machine/mining_equipment_vendor name = "Mining Equipment Vendor (Machine Board)" build_path = /obj/machinery/mineral/equipment_vendor - origin_tech = "programming=1;engineering=3" req_components = list( /obj/item/stack/sheet/glass = 1, /obj/item/stock_parts/matter_bin = 3) @@ -481,7 +442,6 @@ /obj/item/circuitboard/machine/ntnet_relay name = "NTNet Relay (Machine Board)" build_path = /obj/machinery/ntnet_relay - origin_tech = "programming=3;bluespace=3;magnets=2" req_components = list( /obj/item/stack/cable_coil = 2, /obj/item/stock_parts/subspace/filter = 1) @@ -489,7 +449,6 @@ /obj/item/circuitboard/machine/pacman name = "PACMAN-type Generator (Machine Board)" build_path = /obj/machinery/power/port_gen/pacman - origin_tech = "programming=2;powerstorage=3;plasmatech=3;engineering=3" req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/micro_laser = 1, @@ -499,17 +458,14 @@ /obj/item/circuitboard/machine/pacman/super name = "SUPERPACMAN-type Generator (Machine Board)" build_path = /obj/machinery/power/port_gen/pacman/super - origin_tech = "programming=3;powerstorage=4;engineering=4" /obj/item/circuitboard/machine/pacman/mrs name = "MRSPACMAN-type Generator (Machine Board)" build_path = /obj/machinery/power/port_gen/pacman/mrs - origin_tech = "programming=3;powerstorage=4;engineering=4;plasmatech=4" /obj/item/circuitboard/machine/rtg name = "RTG (Machine Board)" build_path = /obj/machinery/power/rtg - origin_tech = "programming=2;materials=4;powerstorage=3;engineering=2" req_components = list( /obj/item/stack/cable_coil = 5, /obj/item/stock_parts/capacitor = 1, @@ -518,7 +474,6 @@ /obj/item/circuitboard/machine/rtg/advanced name = "Advanced RTG (Machine Board)" build_path = /obj/machinery/power/rtg/advanced - origin_tech = "programming=3;materials=5;powerstorage=4;engineering=3;plasmatech=3" req_components = list( /obj/item/stack/cable_coil = 5, /obj/item/stock_parts/capacitor = 1, @@ -529,7 +484,6 @@ /obj/item/circuitboard/machine/abductor/core name = "alien board (Void Core)" build_path = /obj/machinery/power/rtg/abductor - origin_tech = "programming=5;abductor=5;powerstorage=8;engineering=8" req_components = list( /obj/item/stock_parts/capacitor = 1, /obj/item/stock_parts/micro_laser = 1, @@ -541,7 +495,6 @@ /obj/item/circuitboard/machine/emitter name = "Emitter (Machine Board)" build_path = /obj/machinery/power/emitter - origin_tech = "programming=3;powerstorage=4;engineering=4" req_components = list( /obj/item/stock_parts/micro_laser = 1, /obj/item/stock_parts/manipulator = 1) @@ -549,7 +502,6 @@ /obj/item/circuitboard/machine/smes name = "SMES (Machine Board)" build_path = /obj/machinery/power/smes - origin_tech = "programming=3;powerstorage=3;engineering=3" req_components = list( /obj/item/stack/cable_coil = 5, /obj/item/stock_parts/cell = 5, @@ -559,19 +511,16 @@ /obj/item/circuitboard/machine/tesla_coil name = "Tesla Coil (Machine Board)" build_path = /obj/machinery/power/tesla_coil - origin_tech = "programming=3;magnets=3;powerstorage=3" req_components = list(/obj/item/stock_parts/capacitor = 1) /obj/item/circuitboard/machine/grounding_rod name = "Grounding Rod (Machine Board)" build_path = /obj/machinery/power/grounding_rod - origin_tech = "programming=3;powerstorage=3;magnets=3;plasmatech=2" req_components = list(/obj/item/stock_parts/capacitor = 1) /obj/item/circuitboard/machine/power_compressor name = "Power Compressor (Machine Board)" build_path = /obj/machinery/power/compressor - origin_tech = "programming=4;powerstorage=4;engineering=4" req_components = list( /obj/item/stack/cable_coil = 5, /obj/item/stock_parts/manipulator = 6) @@ -579,7 +528,6 @@ /obj/item/circuitboard/machine/power_turbine name = "Power Turbine (Machine Board)" build_path = /obj/machinery/power/turbine - origin_tech = "programming=4;powerstorage=4;engineering=4" req_components = list( /obj/item/stack/cable_coil = 5, /obj/item/stock_parts/capacitor = 6) @@ -587,7 +535,6 @@ /obj/item/circuitboard/machine/chem_dispenser name = "Portable Chem Dispenser (Machine Board)" build_path = /obj/machinery/chem_dispenser/constructable - origin_tech = "materials=4;programming=4;plasmatech=4;biotech=3" req_components = list( /obj/item/stock_parts/matter_bin = 2, /obj/item/stock_parts/capacitor = 1, @@ -599,7 +546,6 @@ /obj/item/circuitboard/machine/smoke_machine name = "Smoke Machine (Machine Board)" build_path = /obj/machinery/smoke_machine - origin_tech = "materials=4;engineering=3;biotech=3" req_components = list( /obj/item/stock_parts/matter_bin = 2, /obj/item/stock_parts/capacitor = 1, @@ -610,7 +556,6 @@ /obj/item/circuitboard/machine/chem_heater name = "Chemical Heater (Machine Board)" build_path = /obj/machinery/chem_heater - origin_tech = "programming=2;engineering=2;biotech=2" req_components = list( /obj/item/stock_parts/micro_laser = 1, /obj/item/stack/sheet/glass = 1) @@ -618,7 +563,6 @@ /obj/item/circuitboard/machine/chem_master name = "ChemMaster 3000 (Machine Board)" build_path = /obj/machinery/chem_master - origin_tech = "materials=3;programming=2;biotech=3" req_components = list( /obj/item/reagent_containers/glass/beaker = 2, /obj/item/stock_parts/manipulator = 1, @@ -645,17 +589,23 @@ /obj/item/circuitboard/machine/circuit_imprinter name = "Circuit Imprinter (Machine Board)" - build_path = /obj/machinery/r_n_d/circuit_imprinter - origin_tech = "engineering=2;programming=2" + build_path = /obj/machinery/rnd/circuit_imprinter req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/manipulator = 1, /obj/item/reagent_containers/glass/beaker = 2) +/obj/item/circuitboard/machine/circuit_imprinter/department + name = "Departmental Circuit Imprinter (Machine Board)" + build_path = /obj/machinery/rnd/circuit_imprinter/department + +/obj/item/circuitboard/machine/circuit_imprinter/department/science + name = "Departmental Circuit Imprinter - Science (Machine Board)" + build_path = /obj/machinery/rnd/circuit_imprinter/department/science + /obj/item/circuitboard/machine/destructive_analyzer name = "Destructive Analyzer (Machine Board)" - build_path = /obj/machinery/r_n_d/destructive_analyzer - origin_tech = "magnets=2;engineering=2;programming=2" + build_path = /obj/machinery/rnd/destructive_analyzer req_components = list( /obj/item/stock_parts/scanning_module = 1, /obj/item/stock_parts/manipulator = 1, @@ -663,8 +613,7 @@ /obj/item/circuitboard/machine/experimentor name = "E.X.P.E.R.I-MENTOR (Machine Board)" - build_path = /obj/machinery/r_n_d/experimentor - origin_tech = "magnets=1;engineering=1;programming=1;biotech=1;bluespace=2" + build_path = /obj/machinery/rnd/experimentor req_components = list( /obj/item/stock_parts/scanning_module = 1, /obj/item/stock_parts/manipulator = 2, @@ -672,25 +621,50 @@ /obj/item/circuitboard/machine/protolathe name = "Protolathe (Machine Board)" - build_path = /obj/machinery/r_n_d/protolathe - origin_tech = "engineering=2;programming=2" + build_path = /obj/machinery/rnd/protolathe req_components = list( /obj/item/stock_parts/matter_bin = 2, /obj/item/stock_parts/manipulator = 2, /obj/item/reagent_containers/glass/beaker = 2) +/obj/item/circuitboard/machine/protolathe/department + name = "Departmental Protolathe (Machine Board)" + build_path = /obj/machinery/rnd/protolathe/department + +/obj/item/circuitboard/machine/protolathe/department/cargo + name = "Departmental Protolathe (Machine Board) - Cargo" + build_path = /obj/machinery/rnd/protolathe/department/cargo + +/obj/item/circuitboard/machine/protolathe/department/engineering + name = "Departmental Protolathe (Machine Board) - Engineering" + build_path = /obj/machinery/rnd/protolathe/department/engineering + +/obj/item/circuitboard/machine/protolathe/department/medical + name = "Departmental Protolathe (Machine Board) - Medical" + build_path = /obj/machinery/rnd/protolathe/department/medical + +/obj/item/circuitboard/machine/protolathe/department/science + name = "Departmental Protolathe (Machine Board) - Science" + build_path = /obj/machinery/rnd/protolathe/department/science + +/obj/item/circuitboard/machine/protolathe/department/security + name = "Departmental Protolathe (Machine Board) - Security" + build_path = /obj/machinery/rnd/protolathe/department/security + +/obj/item/circuitboard/machine/protolathe/department/service + name = "Departmental Protolathe - Service (Machine Board)" + build_path = /obj/machinery/rnd/protolathe/department/service + /obj/item/circuitboard/machine/rdserver name = "R&D Server (Machine Board)" - build_path = /obj/machinery/r_n_d/server - origin_tech = "programming=3" + build_path = /obj/machinery/rnd/server req_components = list( /obj/item/stack/cable_coil = 2, /obj/item/stock_parts/scanning_module = 1) /obj/item/circuitboard/machine/bsa/back name = "Bluespace Artillery Generator (Machine Board)" - build_path = /obj/machinery/bsa/back - origin_tech = "engineering=2;combat=2;bluespace=2" //No freebies! + build_path = /obj/machinery/bsa/back //No freebies! req_components = list( /obj/item/stock_parts/capacitor/quadratic = 5, /obj/item/stack/cable_coil = 2) @@ -698,7 +672,6 @@ /obj/item/circuitboard/machine/bsa/middle name = "Bluespace Artillery Fusor (Machine Board)" build_path = /obj/machinery/bsa/middle - origin_tech = "engineering=2;combat=2;bluespace=2" req_components = list( /obj/item/ore/bluespace_crystal = 20, /obj/item/stack/cable_coil = 2) @@ -706,15 +679,13 @@ /obj/item/circuitboard/machine/bsa/front name = "Bluespace Artillery Bore (Machine Board)" build_path = /obj/machinery/bsa/front - origin_tech = "engineering=2;combat=2;bluespace=2" req_components = list( /obj/item/stock_parts/manipulator/femto = 5, /obj/item/stack/cable_coil = 2) /obj/item/circuitboard/machine/dna_vault name = "DNA Vault (Machine Board)" - build_path = /obj/machinery/dna_vault - origin_tech = "engineering=2;combat=2;bluespace=2" //No freebies! + build_path = /obj/machinery/dna_vault //No freebies! req_components = list( /obj/item/stock_parts/capacitor/super = 5, /obj/item/stock_parts/manipulator/pico = 5, @@ -723,7 +694,6 @@ /obj/item/circuitboard/machine/microwave name = "Microwave (Machine Board)" build_path = /obj/machinery/microwave - origin_tech = "programming=2;magnets=2" req_components = list( /obj/item/stock_parts/micro_laser = 1, /obj/item/stock_parts/matter_bin = 1, @@ -733,7 +703,6 @@ /obj/item/circuitboard/machine/vending/donksofttoyvendor name = "Donksoft Toy Vendor (Machine Board)" build_path = /obj/machinery/vending/donksofttoyvendor - origin_tech = "programming=1;syndicate=2" req_components = list( /obj/item/stack/sheet/glass = 1, /obj/item/vending_refill/donksoft = 3) diff --git a/code/game/objects/items/clown_items.dm b/code/game/objects/items/clown_items.dm index c9468cb79f..f2a804e9e9 100644 --- a/code/game/objects/items/clown_items.dm +++ b/code/game/objects/items/clown_items.dm @@ -21,6 +21,7 @@ throwforce = 0 throw_speed = 3 throw_range = 7 + grind_results = list("lye" = 10) var/cleanspeed = 50 //slower than mop force_string = "robust... against germs" @@ -123,7 +124,6 @@ name = "air horn" desc = "Damn son, where'd you find this?" icon_state = "air_horn" - origin_tech = "materials=4;engineering=4" /obj/item/bikehorn/airhorn/Initialize() . = ..() diff --git a/code/game/objects/items/cosmetics.dm b/code/game/objects/items/cosmetics.dm index 8ec32f088e..a3ad685406 100644 --- a/code/game/objects/items/cosmetics.dm +++ b/code/game/objects/items/cosmetics.dm @@ -25,9 +25,11 @@ /obj/item/lipstick/random name = "lipstick" + icon_state = "random_lipstick" /obj/item/lipstick/random/New() ..() + icon_state = "lipstick" colour = pick("red","purple","lime","black","green","blue","white") name = "[colour] lipstick" diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 7b2d730daf..56bad47963 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -26,6 +26,7 @@ item_color = "red" w_class = WEIGHT_CLASS_TINY attack_verb = list("attacked", "coloured") + grind_results = list() var/paint_color = "#FF0000" //RGB var/drawtype diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm index c3ccd1a144..25fbb49c9b 100644 --- a/code/game/objects/items/defib.dm +++ b/code/game/objects/items/defib.dm @@ -13,16 +13,15 @@ force = 5 throwforce = 6 w_class = WEIGHT_CLASS_BULKY - origin_tech = "biotech=4" actions_types = list(/datum/action/item_action/toggle_paddles) armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 50) var/on = FALSE //if the paddles are equipped (1) or on the defib (0) - var/safety = 1 //if you can zap people with the defibs on harm mode - var/powered = 0 //if there's a cell in the defib with enough power for a revive, blocks paddles from reviving otherwise + var/safety = TRUE //if you can zap people with the defibs on harm mode + var/powered = FALSE //if there's a cell in the defib with enough power for a revive, blocks paddles from reviving otherwise var/obj/item/twohanded/shockpaddles/paddles var/obj/item/stock_parts/cell/high/cell - var/combat = 0 //can we revive through space suits? + var/combat = FALSE //can we revive through space suits? var/grab_ghost = FALSE // Do we pull the ghost back into their body? /obj/item/defibrillator/get_cell() @@ -49,11 +48,11 @@ /obj/item/defibrillator/proc/update_power() if(cell) if(cell.charge < paddles.revivecost) - powered = 0 + powered = FALSE else powered = 1 else - powered = 0 + powered = FALSE /obj/item/defibrillator/proc/update_overlays() cut_overlays() @@ -70,7 +69,7 @@ if(powered) //so it doesn't show charge if it's unpowered if(cell) var/ratio = cell.charge / cell.maxcharge - ratio = Ceiling(ratio*4) * 25 + ratio = CEILING(ratio*4, 1) * 25 add_overlay("[initial(icon_state)]-charge[ratio]") /obj/item/defibrillator/CheckParts(list/parts_list) @@ -98,8 +97,8 @@ ..() /obj/item/defibrillator/MouseDrop(obj/over_object) - if(ismob(src.loc)) - var/mob/M = src.loc + if(ismob(loc)) + var/mob/M = loc if(!M.incapacitated() && istype(over_object, /obj/screen/inventory/hand)) var/obj/screen/inventory/hand/H = over_object M.putItemFromInventoryInHandIfPossible(src, H.held_index) @@ -134,23 +133,23 @@ /obj/item/defibrillator/emag_act(mob/user) if(safety) - safety = 0 + safety = FALSE to_chat(user, "You silently disable [src]'s safety protocols with the cryptographic sequencer.") else - safety = 1 + safety = TRUE to_chat(user, "You silently enable [src]'s safety protocols with the cryptographic sequencer.") /obj/item/defibrillator/emp_act(severity) if(cell) deductcharge(1000 / severity) if(safety) - safety = 0 - src.visible_message("[src] beeps: Safety protocols disabled!") - playsound(get_turf(src), 'sound/machines/defib_saftyOff.ogg', 50, 0) + safety = FALSE + visible_message("[src] beeps: Safety protocols disabled!") + playsound(src, 'sound/machines/defib_saftyOff.ogg', 50, 0) else - safety = 1 - src.visible_message("[src] beeps: Safety protocols enabled!") - playsound(get_turf(src), 'sound/machines/defib_saftyOn.ogg', 50, 0) + safety = TRUE + visible_message("[src] beeps: Safety protocols enabled!") + playsound(src, 'sound/machines/defib_saftyOn.ogg', 50, 0) update_icon() ..() @@ -167,7 +166,7 @@ to_chat(user, "You need a free hand to hold the paddles!") update_icon() return - paddles.loc = user + paddles.forceMove(user) else //Remove from their hands and back onto the defib unit paddles.unwield() @@ -207,25 +206,25 @@ /obj/item/defibrillator/proc/deductcharge(chrgdeductamt) if(cell) if(cell.charge < (paddles.revivecost+chrgdeductamt)) - powered = 0 + powered = FALSE update_icon() if(cell.use(chrgdeductamt)) update_icon() - return 1 + return TRUE else update_icon() - return 0 + return FALSE /obj/item/defibrillator/proc/cooldowncheck(mob/user) spawn(50) if(cell) if(cell.charge >= paddles.revivecost) user.visible_message("[src] beeps: Unit ready.") - playsound(get_turf(src), 'sound/machines/defib_ready.ogg', 50, 0) + playsound(src, 'sound/machines/defib_ready.ogg', 50, 0) else user.visible_message("[src] beeps: Charge depleted.") - playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) - paddles.cooldown = 0 + playsound(src, 'sound/machines/defib_failed.ogg', 50, 0) + paddles.cooldown = FALSE paddles.update_icon() update_icon() @@ -236,11 +235,10 @@ item_state = "defibcompact" w_class = WEIGHT_CLASS_NORMAL slot_flags = SLOT_BELT - origin_tech = "biotech=5" /obj/item/defibrillator/compact/item_action_slot_check(slot, mob/user) if(slot == user.getBeltSlot()) - return 1 + return TRUE /obj/item/defibrillator/compact/loaded/Initialize() . = ..() @@ -251,8 +249,8 @@ /obj/item/defibrillator/compact/combat name = "combat defibrillator" desc = "A belt-equipped blood-red defibrillator that can be rapidly deployed. Does not have the restrictions or safeties of conventional defibrillators and can revive through space suits." - combat = 1 - safety = 0 + combat = TRUE + safety = FALSE /obj/item/defibrillator/compact/combat/loaded/Initialize() . = ..() @@ -280,31 +278,31 @@ w_class = WEIGHT_CLASS_BULKY var/revivecost = 1000 - var/cooldown = 0 + var/cooldown = FALSE var/busy = FALSE var/obj/item/defibrillator/defib - var/req_defib = 1 - var/combat = 0 //If it penetrates armor and gives additional functionality + var/req_defib = TRUE + var/combat = FALSE //If it penetrates armor and gives additional functionality var/grab_ghost = FALSE var/tlimit = DEFIB_TIME_LIMIT * 10 /obj/item/twohanded/shockpaddles/proc/recharge(var/time) if(req_defib || !time) return - cooldown = 1 + cooldown = TRUE update_icon() sleep(time) var/turf/T = get_turf(src) T.audible_message("[src] beeps: Unit is recharged.") - playsound(T, 'sound/machines/defib_ready.ogg', 50, 0) - cooldown = 0 + playsound(src, 'sound/machines/defib_ready.ogg', 50, 0) + cooldown = FALSE update_icon() /obj/item/twohanded/shockpaddles/New(mainunit) ..() if(check_defib_exists(mainunit, src) && req_defib) defib = mainunit - loc = defib + forceMove(defib) busy = FALSE update_icon() @@ -318,7 +316,7 @@ user.visible_message("[user] is putting the live paddles on [user.p_their()] chest! It looks like [user.p_theyre()] trying to commit suicide!") if(req_defib) defib.deductcharge(revivecost) - playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1) + playsound(src, 'sound/machines/defib_zap.ogg', 50, 1, -1) return (OXYLOSS) /obj/item/twohanded/shockpaddles/dropped(mob/user) @@ -330,18 +328,18 @@ O.unwield() to_chat(user, "The paddles snap back into the main unit.") defib.on = 0 - loc = defib + forceMove(defib) defib.update_icon() return unwield(user) /obj/item/twohanded/shockpaddles/proc/check_defib_exists(mainunit, mob/living/carbon/human/M, obj/O) if(!req_defib) - return 1 //If it doesn't need a defib, just say it exists + return TRUE //If it doesn't need a defib, just say it exists if (!mainunit || !istype(mainunit, /obj/item/defibrillator)) //To avoid weird issues from admin spawns qdel(O) - return 0 + return FALSE else - return 1 + return TRUE /obj/item/twohanded/shockpaddles/attack(mob/M, mob/user) @@ -349,7 +347,7 @@ return if(req_defib && !defib.powered) user.visible_message("[defib] beeps: Unit is unpowered.") - playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) + playsound(src, 'sound/machines/defib_failed.ogg', 50, 0) return if(!wielded) if(iscyborg(user)) @@ -397,6 +395,13 @@ var/obj/item/organ/brain/BR = H.getorgan(/obj/item/organ/brain) return (!H.suiciding && !(H.disabilities & NOCLONE) && !H.hellbound && ((world.time - H.timeofdeath) < tlimit) && (H.getBruteLoss() < 180) && (H.getFireLoss() < 180) && H.getorgan(/obj/item/organ/heart) && BR && !BR.damaged_brain) +/obj/item/twohanded/shockpaddles/proc/shock_touching(dmg, mob/H) + if(isliving(H.pulledby)) //CLEAR! + var/mob/living/M = H.pulledby + if(M.electrocute_act(30, src)) + M.visible_message("[M] is electrocuted by their contact with [H]!") + M.emote("scream") + /obj/item/twohanded/shockpaddles/proc/do_disarm(mob/living/M, mob/living/user) if(req_defib && defib.safety) return @@ -408,12 +413,12 @@ M.adjustStaminaLoss(50) M.Knockdown(100) M.updatehealth() //forces health update before next life tick - playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1) + playsound(src, 'sound/machines/defib_zap.ogg', 50, 1, -1) M.emote("gasp") add_logs(user, M, "stunned", src) if(req_defib) defib.deductcharge(revivecost) - cooldown = 1 + cooldown = TRUE busy = FALSE update_icon() if(req_defib) @@ -434,7 +439,7 @@ user.visible_message("[user] places [src] on [H]'s chest.", "You place [src] on [H]'s chest and begin to charge them.") var/turf/T = get_turf(defib) - playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0) + playsound(src, 'sound/machines/defib_charge.ogg', 50, 0) if(req_defib) T.audible_message("\The [defib] lets out an urgent beep and lets out a steadily rising hum...") else @@ -446,14 +451,15 @@ return if(H && H.stat == DEAD) to_chat(user, "[H] is dead.") - playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) + playsound(src, 'sound/machines/defib_failed.ogg', 50, 0) busy = FALSE update_icon() return user.visible_message("[user] shocks [H] with \the [src]!", "You shock [H] with \the [src]!") - playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 100, 1, -1) - playsound(loc, 'sound/weapons/egloves.ogg', 100, 1, -1) + playsound(src, 'sound/machines/defib_zap.ogg', 100, 1, -1) + playsound(src, 'sound/weapons/egloves.ogg', 100, 1, -1) H.emote("scream") + shock_touching(45, H) if(H.can_heartattack() && !H.undergoing_cardiac_arrest()) if(!H.stat) H.visible_message("[H] thrashes wildly, clutching at their chest!", @@ -465,7 +471,7 @@ H.Jitter(100) if(req_defib) defib.deductcharge(revivecost) - cooldown = 1 + cooldown = TRUE busy = FALSE update_icon() if(!req_defib) @@ -481,7 +487,7 @@ update_icon() if(do_after(user, 30, target = H)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process user.visible_message("[user] places [src] on [H]'s chest.", "You place [src] on [H]'s chest.") - playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0) + playsound(src, 'sound/machines/defib_charge.ogg', 75, 0) var/tplus = world.time - H.timeofdeath // past this much time the patient is unrecoverable // (in deciseconds) @@ -493,20 +499,20 @@ if(do_after(user, 20, target = H)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total for(var/obj/item/carried_item in H.contents) if(istype(carried_item, /obj/item/clothing/suit/space)) - if((!src.combat && !req_defib) || (req_defib && !defib.combat)) + if((!combat && !req_defib) || (req_defib && !defib.combat)) user.audible_message("[req_defib ? "[defib]" : "[src]"] buzzes: Patient's chest is obscured. Operation aborted.") - playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) + playsound(src, 'sound/machines/defib_failed.ogg', 50, 0) busy = FALSE update_icon() return if(H.stat == DEAD) H.visible_message("[H]'s body convulses a bit.") - playsound(get_turf(src), "bodyfall", 50, 1) - playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1) + playsound(src, "bodyfall", 50, 1) + playsound(src, 'sound/machines/defib_zap.ogg', 75, 1, -1) total_brute = H.getBruteLoss() total_burn = H.getFireLoss() - - var/failed = null + shock_touching(30, H) + var/failed if (H.suiciding || (H.disabilities & NOCLONE)) failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Recovery of patient impossible. Further attempts futile." @@ -527,7 +533,7 @@ if(failed) user.visible_message(failed) - playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) + playsound(src, 'sound/machines/defib_failed.ogg', 50, 0) else //If the body has been fixed so that they would not be in crit when defibbed, give them oxyloss to put them back into crit if (H.health > HALFWAYCRITDEATH) @@ -541,12 +547,13 @@ H.adjustBruteLoss((mobhealth - HALFWAYCRITDEATH) * (total_brute / overall_damage), 0) H.updatehealth() // Previous "adjust" procs don't update health, so we do it manually. user.visible_message("[req_defib ? "[defib]" : "[src]"] pings: Resuscitation successful.") - playsound(get_turf(src), 'sound/machines/defib_success.ogg', 50, 0) + playsound(src, 'sound/machines/defib_success.ogg', 50, 0) H.set_heartattack(FALSE) H.revive() H.emote("gasp") + H.Jitter(100) if(tplus > tloss) - H.setBrainLoss( max(0, min(99, ((tlimit - tplus) / tlimit * 100)))) + H.adjustBrainLoss( max(0, min(99, ((tlimit - tplus) / tlimit * 100))), 150) add_logs(user, H, "revived", defib) if(req_defib) defib.deductcharge(revivecost) @@ -558,16 +565,16 @@ recharge(60) else if (!H.getorgan(/obj/item/organ/heart)) user.visible_message("[req_defib ? "[defib]" : "[src]"] buzzes: Patient's heart is missing. Operation aborted.") - playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) + playsound(src, 'sound/machines/defib_failed.ogg', 50, 0) else if(H.undergoing_cardiac_arrest()) H.set_heartattack(FALSE) user.visible_message("[req_defib ? "[defib]" : "[src]"] pings: Patient's heart is now beating again.") - playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1) + playsound(src, 'sound/machines/defib_zap.ogg', 50, 1, -1) else user.visible_message("[req_defib ? "[defib]" : "[src]"] buzzes: Patient is not in a valid state. Operation aborted.") - playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) + playsound(src, 'sound/machines/defib_failed.ogg', 50, 0) busy = FALSE update_icon() diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 244e82ee77..f2bc8b5686 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -15,7 +15,6 @@ GLOBAL_LIST_EMPTY(PDAs) flags_1 = NOBLUDGEON_1 w_class = WEIGHT_CLASS_TINY slot_flags = SLOT_ID | SLOT_BELT - origin_tech = "programming=2" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 100) resistance_flags = FIRE_PROOF | ACID_PROOF @@ -155,15 +154,17 @@ GLOBAL_LIST_EMPTY(PDAs) return /obj/item/device/pda/attack_self(mob/user) + if(!user.IsAdvancedToolUser()) + to_chat(user, "You don't have the dexterity to do this!") + return + + . = ..() + var/datum/asset/assets = get_asset_datum(/datum/asset/simple/pda) assets.send(user) user.set_machine(src) - if(hidden_uplink && hidden_uplink.active) - hidden_uplink.interact(user) - return - var/dat = "Personal Data Assistant" @@ -496,7 +497,9 @@ GLOBAL_LIST_EMPTY(PDAs) if("Ringtone") var/t = input(U, "Please enter new ringtone", name, ttone) as text if(in_range(src, U) && loc == U && t) + GET_COMPONENT(hidden_uplink, /datum/component/uplink) if(hidden_uplink && (trim(lowertext(t)) == trim(lowertext(lock_code)))) + hidden_uplink.locked = FALSE hidden_uplink.interact(U) to_chat(U, "The PDA softly beeps.") U << browse(null, "window=pda") @@ -540,7 +543,7 @@ GLOBAL_LIST_EMPTY(PDAs) if("2") // Eject pAI device var/turf/T = get_turf(src.loc) if(T) - pai.loc = T + pai.forceMove(T) //LINK FUNCTIONS=================================== @@ -575,7 +578,7 @@ GLOBAL_LIST_EMPTY(PDAs) M.put_in_hands(id) to_chat(usr, "You remove the ID from the [name].") else - id.loc = get_turf(src) + id.forceMove(drop_location()) id = null update_icon() @@ -822,8 +825,6 @@ GLOBAL_LIST_EMPTY(PDAs) var/obj/item/photo/P = C photo = P.img to_chat(user, "You scan \the [C].") - else if(hidden_uplink && hidden_uplink.active) - hidden_uplink.attackby(C, user, params) else return ..() diff --git a/code/game/objects/items/devices/PDA/PDA_types.dm b/code/game/objects/items/devices/PDA/PDA_types.dm index 4f2db14fa6..b1a4a9f6f8 100644 --- a/code/game/objects/items/devices/PDA/PDA_types.dm +++ b/code/game/objects/items/devices/PDA/PDA_types.dm @@ -10,16 +10,11 @@ /obj/item/device/pda/clown/Initialize() . = ..() - AddComponent(/datum/component/slippery, 120, NO_SLIP_WHEN_WALKING) + AddComponent(/datum/component/slippery, 120, NO_SLIP_WHEN_WALKING, CALLBACK(src, .proc/AfterSlip)) -/obj/item/device/pda/clown/ComponentActivated(datum/component/C) - ..() - var/datum/component/slippery/S = C - if(!istype(S)) - return - var/mob/living/carbon/human/M = S.slip_victim - if (istype(M) && (M.real_name != src.owner)) - slipvictims |= M +/obj/item/device/pda/clown/proc/AfterSlip(mob/living/carbon/human/M) + if (istype(M) && (M.real_name != owner)) + slipvictims |=M var/obj/item/cartridge/virus/clown/cart = cartridge if(istype(cart) && cart.charges < 5) cart.charges++ diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm index bfcda7d271..1b9e2c0e14 100644 --- a/code/game/objects/items/devices/PDA/cart.dm +++ b/code/game/objects/items/devices/PDA/cart.dm @@ -180,9 +180,9 @@ /obj/item/cartridge/captain name = "\improper Value-PAK cartridge" - desc = "Now with 350% more value!" //Give the Captain...EVERYTHING! (Except Mime and Clown) + desc = "Now with 350% more value!" //Give the Captain...EVERYTHING! (Except Mime, Clown, and Syndie) icon_state = "cart-c" - access = ~(CART_CLOWN | CART_MIME) + access = ~(CART_CLOWN | CART_MIME | CART_REMOTE_DOOR) bot_access_flags = SEC_BOT | MULE_BOT | FLOOR_BOT | CLEAN_BOT | MED_BOT spam_enabled = 1 diff --git a/code/game/objects/items/devices/PDA/virus_cart.dm b/code/game/objects/items/devices/PDA/virus_cart.dm index ce7f85b825..a678e41445 100644 --- a/code/game/objects/items/devices/PDA/virus_cart.dm +++ b/code/game/objects/items/devices/PDA/virus_cart.dm @@ -7,7 +7,7 @@ /obj/item/cartridge/virus/message_header() return "[charges] viral files left.
    " - + /obj/item/cartridge/virus/message_special(obj/item/device/pda/target) if (!istype(loc, /obj/item/device/pda)) return "" //Sanity check, this shouldn't be possible. @@ -67,11 +67,12 @@ var/difficulty = 0 if(target.cartridge) difficulty += BitCount(target.cartridge.access&(CART_MEDICAL | CART_SECURITY | CART_ENGINE | CART_CLOWN | CART_JANITOR | CART_MANIFEST)) - if(target.cartridge.access & CART_MANIFEST) + if(target.cartridge.access & CART_MANIFEST) difficulty++ //if cartridge has manifest access it has extra snowflake difficulty else difficulty += 2 - if(!target.detonatable || prob(difficulty * 15) || (target.hidden_uplink)) + GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, target) + if(!target.detonatable || prob(difficulty * 15) || (hidden_uplink)) U.show_message("An error flashes on your [src].", 1) else U.show_message("Success!", 1) @@ -92,14 +93,14 @@ charges-- var/lock_code = "[rand(100,999)] [pick(GLOB.phonetic_alphabet)]" to_chat(U, "Virus Sent! The unlock code to the target is: [lock_code]") - if(!target.hidden_uplink) - var/obj/item/device/uplink/uplink = new(target) - target.hidden_uplink = uplink + GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, target) + if(!hidden_uplink) + hidden_uplink = target.AddComponent(/datum/component/uplink) target.lock_code = lock_code else - target.hidden_uplink.hidden_crystals += target.hidden_uplink.telecrystals //Temporarially hide the PDA's crystals, so you can't steal telecrystals. - target.hidden_uplink.telecrystals = telecrystals + hidden_uplink.hidden_crystals += hidden_uplink.telecrystals //Temporarially hide the PDA's crystals, so you can't steal telecrystals. + hidden_uplink.telecrystals = telecrystals telecrystals = 0 - target.hidden_uplink.active = TRUE + hidden_uplink.active = TRUE else to_chat(U, "PDA not found.") diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm index 1ab160af20..e231f6a924 100644 --- a/code/game/objects/items/devices/aicard.dm +++ b/code/game/objects/items/devices/aicard.dm @@ -11,7 +11,6 @@ flags_1 = NOBLUDGEON_1 var/flush = FALSE var/mob/living/silicon/ai/AI - origin_tech = "programming=3;materials=3" /obj/item/device/aicard/afterattack(atom/target, mob/user, proximity) ..() diff --git a/code/game/objects/items/devices/camera_bug.dm b/code/game/objects/items/devices/camera_bug.dm index c84a3fada5..1b9978f472 100644 --- a/code/game/objects/items/devices/camera_bug.dm +++ b/code/game/objects/items/devices/camera_bug.dm @@ -13,7 +13,6 @@ item_state = "camera_bug" throw_speed = 4 throw_range = 20 - origin_tech = "syndicate=1;engineering=3" flags_1 = NOBLUDGEON_1 var/obj/machinery/camera/current = null diff --git a/code/game/objects/items/devices/chameleonproj.dm b/code/game/objects/items/devices/chameleonproj.dm index d1de04923c..a07d8d8d60 100644 --- a/code/game/objects/items/devices/chameleonproj.dm +++ b/code/game/objects/items/devices/chameleonproj.dm @@ -10,7 +10,6 @@ throw_speed = 3 throw_range = 5 w_class = WEIGHT_CLASS_SMALL - origin_tech = "syndicate=4;magnets=4" var/can_use = 1 var/obj/effect/dummy/chameleon/active_dummy = null var/saved_appearance = null @@ -86,7 +85,7 @@ /obj/item/device/chameleon/proc/eject_all() for(var/atom/movable/A in active_dummy) - A.loc = active_dummy.loc + A.forceMove(active_dummy.loc) if(ismob(A)) var/mob/M = A M.reset_perspective(null) @@ -102,8 +101,12 @@ appearance = saved_appearance if(istype(M.buckled, /obj/vehicle)) var/obj/vehicle/V = M.buckled - V.riding_datum.force_dismount(M) - M.loc = src + GET_COMPONENT_FROM(VRD, /datum/component/riding, V) + if(VRD) + VRD.force_dismount(M) + else + V.unbuckle_mob(M, force = TRUE) + M.forceMove(src) master = C master.active_dummy = src diff --git a/code/game/objects/items/devices/doorCharge.dm b/code/game/objects/items/devices/doorCharge.dm index cb24098e81..cf11b2c941 100644 --- a/code/game/objects/items/devices/doorCharge.dm +++ b/code/game/objects/items/devices/doorCharge.dm @@ -12,7 +12,6 @@ force = 3 attack_verb = list("blown up", "exploded", "detonated") materials = list(MAT_METAL=50, MAT_GLASS=30) - origin_tech = "syndicate=1;combat=3;engineering=3" /obj/item/device/doorCharge/ex_act(severity, target) switch(severity) diff --git a/code/game/objects/items/devices/electroadaptive_pseudocircuit.dm b/code/game/objects/items/devices/electroadaptive_pseudocircuit.dm index 204a1f81d9..6b465d71e1 100644 --- a/code/game/objects/items/devices/electroadaptive_pseudocircuit.dm +++ b/code/game/objects/items/devices/electroadaptive_pseudocircuit.dm @@ -6,7 +6,6 @@ icon_state = "boris" w_class = WEIGHT_CLASS_TINY materials = list(MAT_METAL = 50, MAT_GLASS = 300) - origin_tech = "engineering=4" var/recharging = FALSE var/circuits = 5 //How many circuits the pseudocircuit has left var/static/recycleable_circuits = typecacheof(list(/obj/item/electronics/firelock, /obj/item/electronics/airalarm, /obj/item/electronics/firealarm, \ @@ -30,7 +29,7 @@ to_chat(R, "You need a power cell installed for that.") return if(!R.cell.use(circuit_cost)) - to_chat(R, "You don't have the power for that (you need [DisplayPower(circuit_cost)].)") + to_chat(R, "You don't have the energy for that (you need [DisplayEnergy(circuit_cost)].)") return if(recharging) to_chat(R, "[src] needs some time to recharge first.") diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index fd56c6283f..f656d55afd 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -48,7 +48,7 @@ add_fingerprint(user) if(istype(M) && on && user.zone_selected in list("eyes", "mouth")) - if((user.disabilities & CLUMSY || user.getBrainLoss() >= 60) && prob(50)) //too dumb to use flashlight properly + if((user.disabilities & (CLUMSY | DUMB)) && prob(50)) //too dumb to use flashlight properly return ..() //just hit them in the head if(!user.IsAdvancedToolUser()) @@ -256,6 +256,7 @@ var/produce_heat = 1500 heat = 1000 light_color = LIGHT_COLOR_FLARE + grind_results = list("sulfur" = 15) /obj/item/device/flashlight/flare/New() fuel = rand(800, 1000) // Sorry for changing this so much but I keep under-estimating how long X number of ticks last in seconds. @@ -348,7 +349,6 @@ brightness_on = 6 //luminosity when on /obj/item/device/flashlight/emp - origin_tech = "magnets=3;syndicate=1" var/emp_max_charges = 4 var/emp_cur_charges = 4 var/charge_tick = 0 @@ -405,6 +405,7 @@ color = LIGHT_COLOR_GREEN icon_state = "glowstick" item_state = "glowstick" + grind_results = list("phenol" = 15, "hydrogen" = 10, "oxygen" = 5) //Meth-in-a-stick var/fuel = 0 /obj/item/device/flashlight/glowstick/Initialize() @@ -488,16 +489,14 @@ /obj/item/device/flashlight/glowstick/random name = "random colored glowstick" + icon_state = "random_glowstick" + color = null /obj/item/device/flashlight/glowstick/random/Initialize() - var/list/glowtypes = typesof(/obj/item/device/flashlight/glowstick) - glowtypes -= /obj/item/device/flashlight/glowstick/random - - var/obj/item/device/flashlight/glowstick/glowtype = pick(glowtypes) - - name = initial(glowtype.name) - color = initial(glowtype.color) . = ..() + var/T = pick(typesof(/obj/item/device/flashlight/glowstick) - /obj/item/device/flashlight/glowstick/random) + new T(loc) + return INITIALIZE_HINT_QDEL /obj/item/device/flashlight/spotlight //invisible lighting source name = "disco light" diff --git a/code/game/objects/items/devices/forcefieldprojector.dm b/code/game/objects/items/devices/forcefieldprojector.dm index 42bd8908d1..e10c34a139 100644 --- a/code/game/objects/items/devices/forcefieldprojector.dm +++ b/code/game/objects/items/devices/forcefieldprojector.dm @@ -9,7 +9,6 @@ lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' materials = list(MAT_METAL=250, MAT_GLASS=500) - origin_tech = "magnets=5;engineering=5;powerstorage=4" var/max_shield_integrity = 250 var/shield_integrity = 250 var/max_fields = 3 diff --git a/code/game/objects/items/devices/gps.dm b/code/game/objects/items/devices/gps.dm index 23fc8a29ea..07e80a1211 100644 --- a/code/game/objects/items/devices/gps.dm +++ b/code/game/objects/items/devices/gps.dm @@ -6,7 +6,6 @@ GLOBAL_LIST_EMPTY(GPS_list) icon_state = "gps-c" w_class = WEIGHT_CLASS_SMALL slot_flags = SLOT_BELT - origin_tech = "materials=2;magnets=1;bluespace=2" unique_rename = TRUE var/gpstag = "COM0" var/emped = FALSE diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm index 24d508b8c3..eb1ccd15f4 100644 --- a/code/game/objects/items/devices/laserpointer.dm +++ b/code/game/objects/items/devices/laserpointer.dm @@ -9,7 +9,6 @@ slot_flags = SLOT_BELT materials = list(MAT_METAL=500, MAT_GLASS=500) w_class = WEIGHT_CLASS_SMALL - origin_tech = "combat=1;magnets=2" var/turf/pointer_loc var/energy = 5 var/max_energy = 5 @@ -51,7 +50,7 @@ else if(istype(W, /obj/item/screwdriver)) if(diode) to_chat(user, "You remove the [diode.name] from \the [src].") - diode.loc = get_turf(src.loc) + diode.forceMove(drop_location()) diode = null else return ..() diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm index 3821f6206b..4ea91ccccf 100644 --- a/code/game/objects/items/devices/lightreplacer.dm +++ b/code/game/objects/items/devices/lightreplacer.dm @@ -51,7 +51,6 @@ flags_1 = CONDUCT_1 slot_flags = SLOT_BELT - origin_tech = "magnets=3;engineering=4" force = 8 var/max_uses = 20 @@ -170,7 +169,7 @@ // Negative numbers will subtract /obj/item/device/lightreplacer/proc/AddUses(amount = 1) - uses = Clamp(uses + amount, 0, max_uses) + uses = CLAMP(uses + amount, 0, max_uses) /obj/item/device/lightreplacer/proc/AddShards(amount = 1, user) bulb_shards += amount diff --git a/code/game/objects/items/devices/machineprototype.dm b/code/game/objects/items/devices/machineprototype.dm index e6574d0e55..88d7e8c573 100644 --- a/code/game/objects/items/devices/machineprototype.dm +++ b/code/game/objects/items/devices/machineprototype.dm @@ -4,4 +4,3 @@ icon = 'icons/obj/machineprototype.dmi' icon_state = "machineprototype" materials = list(MAT_METAL=1000, MAT_GLASS=500) - origin_tech = "engineering=6" diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm index 40963c3b08..8f3eeeec71 100644 --- a/code/game/objects/items/devices/multitool.dm +++ b/code/game/objects/items/devices/multitool.dm @@ -22,7 +22,6 @@ throw_range = 7 throw_speed = 3 materials = list(MAT_METAL=50, MAT_GLASS=20) - origin_tech = "magnets=1;engineering=2" var/obj/machinery/buffer // simple machine buffer for device linkage hitsound = 'sound/weapons/tap.ogg' toolspeed = 1 @@ -59,8 +58,7 @@ if(io.holder.assembly && io.holder.assembly != selected_io.holder.assembly) to_chat(user, "Both \the [io.holder] and \the [selected_io.holder] need to be inside the same assembly.") return - selected_io.linked |= io - io.linked |= selected_io + io.connect_pin(selected_io) to_chat(user, "You connect \the [selected_io.holder]'s [selected_io.name] to \the [io.holder]'s [io.name].") selected_io.holder.interact(user) // This is to update the UI. @@ -82,8 +80,7 @@ to_chat(user, "These data pins aren't connected!") return else - io1.linked.Remove(io2) - io2.linked.Remove(io1) + io1.disconnect_pin(io2) to_chat(user, "You clip the data connection between the [io1.holder.displayed_name]'s \ [io1.name] and the [io2.holder.displayed_name]'s [io2.name].") io1.holder.interact(user) // This is to update the UI. @@ -100,7 +97,6 @@ var/detect_state = PROXIMITY_NONE var/rangealert = 8 //Glows red when inside var/rangewarning = 20 //Glows yellow when inside - origin_tech = "magnets=1;engineering=2;syndicate=1" /obj/item/device/multitool/ai_detect/New() ..() @@ -162,5 +158,4 @@ desc = "An omni-technological interface." icon = 'icons/obj/abductor.dmi' icon_state = "multitool" - toolspeed = 0.1 - origin_tech = "magnets=5;engineering=5;abductor=3" + toolspeed = 0.1 diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm index 095e021458..04f5ea5b53 100644 --- a/code/game/objects/items/devices/paicard.dm +++ b/code/game/objects/items/devices/paicard.dm @@ -7,7 +7,6 @@ righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' w_class = WEIGHT_CLASS_SMALL slot_flags = SLOT_BELT - origin_tech = "programming=2" var/mob/living/silicon/pai/pai resistance_flags = FIRE_PROOF | ACID_PROOF | INDESTRUCTIBLE diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm index d32ae86090..df2c7770e2 100644 --- a/code/game/objects/items/devices/powersink.dm +++ b/code/game/objects/items/devices/powersink.dm @@ -13,7 +13,6 @@ throw_speed = 1 throw_range = 2 materials = list(MAT_METAL=750) - origin_tech = "powerstorage=5;syndicate=5" var/drain_rate = 1600000 // amount of power to drain per tick var/power_drained = 0 // has drained this much power var/max_power = 1e10 // maximum power that can be drained before exploding diff --git a/code/game/objects/items/devices/radio/beacon.dm b/code/game/objects/items/devices/radio/beacon.dm index 4cd286ec85..69b603d213 100644 --- a/code/game/objects/items/devices/radio/beacon.dm +++ b/code/game/objects/items/devices/radio/beacon.dm @@ -6,7 +6,6 @@ lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' var/code = "electronic" - origin_tech = "bluespace=1" dog_fashion = null /obj/item/device/radio/beacon/Initialize() diff --git a/code/game/objects/items/devices/radio/encryptionkey.dm b/code/game/objects/items/devices/radio/encryptionkey.dm index f6110dd428..028c6ba27f 100644 --- a/code/game/objects/items/devices/radio/encryptionkey.dm +++ b/code/game/objects/items/devices/radio/encryptionkey.dm @@ -4,7 +4,6 @@ icon = 'icons/obj/radio.dmi' icon_state = "cypherkey" w_class = WEIGHT_CLASS_TINY - origin_tech = "engineering=2;bluespace=1" var/translate_binary = 0 var/syndie = 0 var/independent = FALSE @@ -15,7 +14,6 @@ desc = "An encryption key for a radio headset. To access the syndicate channel, use :t." icon_state = "syn_cypherkey" channels = list("Syndicate" = 1) - origin_tech = "syndicate=1;engineering=3;bluespace=2" syndie = 1//Signifies that it de-crypts Syndicate transmissions /obj/item/device/encryptionkey/binary @@ -23,7 +21,6 @@ desc = "An encryption key for a radio headset. To access the binary channel, use :b." icon_state = "bin_cypherkey" translate_binary = 1 - origin_tech = "syndicate=3;engineering=4;bluespace=3" /obj/item/device/encryptionkey/headset_sec name = "security radio encryption key" diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index ada7b613e4..750e1f0511 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -43,12 +43,10 @@ return -1 /obj/item/device/radio/headset/syndicate //disguised to look like a normal headset for stealth ops - origin_tech = "syndicate=3" /obj/item/device/radio/headset/syndicate/alt //undisguised bowman with flash protection name = "syndicate headset" - desc = "A syndicate headset that can be used to hear all radio frequencies. Protects ears from flashbangs.\nTo access the syndicate channel, use ; before speaking." - origin_tech = "syndicate=3" + desc = "A syndicate headset that can be used to hear all radio frequencies. Protects ears from flashbangs. \nTo access the syndicate channel, use ; before speaking." icon_state = "syndie_headset" item_state = "syndie_headset" flags_2 = BANG_PROTECT_2 | NO_EMP_WIRES_2 @@ -62,7 +60,6 @@ make_syndie() /obj/item/device/radio/headset/binary - origin_tech = "syndicate=3" /obj/item/device/radio/headset/binary/Initialize() . = ..() qdel(keyslot) @@ -230,7 +227,7 @@ if(keyslot) var/turf/T = get_turf(user) if(T) - keyslot.loc = T + keyslot.forceMove(T) keyslot = null @@ -238,7 +235,7 @@ if(keyslot2) var/turf/T = get_turf(user) if(T) - keyslot2.loc = T + keyslot2.forceMove(T) keyslot2 = null recalculateChannels() diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 6603bc29ef..8227d75069 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -155,7 +155,9 @@ if(.) frequency = sanitize_frequency(tune, freerange) set_frequency(frequency) - if(frequency == traitor_frequency && hidden_uplink) + GET_COMPONENT(hidden_uplink, /datum/component/uplink) + if(hidden_uplink && (frequency == traitor_frequency)) + hidden_uplink.locked = FALSE hidden_uplink.interact(usr) ui.close() if("listen") @@ -567,7 +569,7 @@ if(keyslot) var/turf/T = get_turf(user) if(T) - keyslot.loc = T + keyslot.forceMove(T) keyslot = null recalculateChannels() diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index bc99a28eea..9a60bb0edb 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -2,10 +2,8 @@ /* CONTAINS: T-RAY -DETECTIVE SCANNER HEALTH ANALYZER GAS ANALYZER -MASS SPECTROMETER */ /obj/item/device/t_scanner @@ -19,7 +17,6 @@ MASS SPECTROMETER lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' materials = list(MAT_METAL=150) - origin_tech = "magnets=1;engineering=1" /obj/item/device/t_scanner/attack_self(mob/user) @@ -73,7 +70,6 @@ MASS SPECTROMETER throw_speed = 3 throw_range = 7 materials = list(MAT_METAL=200) - origin_tech = "magnets=1;biotech=1" var/mode = 1 var/scanmode = 0 var/advanced = FALSE @@ -89,7 +85,7 @@ MASS SPECTROMETER /obj/item/device/healthanalyzer/attack(mob/living/M, mob/living/carbon/human/user) // Clumsiness/brain damage check - if ((user.disabilities & CLUMSY || user.getBrainLoss() >= 60) && prob(50)) + if ((user.disabilities & (CLUMSY | DUMB)) && prob(50)) to_chat(user, "You stupidly try to analyze the floor's vitals!") user.visible_message("[user] has analyzed the floor's vitals!") to_chat(user, "Analyzing results for The floor:\n\tOverall status: Healthy") @@ -154,14 +150,21 @@ MASS SPECTROMETER to_chat(user, "\tSubject appears to have [M.getCloneLoss() > 30 ? "severe" : "minor"] cellular damage.") if(advanced) to_chat(user, "\tCellular Damage Level: [M.getCloneLoss()].") - if (M.getBrainLoss() >= 100 || !M.getorgan(/obj/item/organ/brain)) + if (M.getBrainLoss() >= 200 || !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.") + else if (M.getBrainLoss() >= 120) + to_chat(user, "\tSevere brain damage detected. Subject likely to have mental traumas.") + else if (M.getBrainLoss() >= 45) + to_chat(user, "\tBrain damage detected.") + if(iscarbon(M)) + var/mob/living/carbon/C = M + if(LAZYLEN(C.get_traumas())) + var/list/trauma_text = list() + for(var/datum/brain_trauma/B in C.get_traumas()) + trauma_text += B.scan_desc + to_chat(user, "\tCerebral traumas detected: subjects appears to be suffering from [english_list(trauma_text)].") if(advanced) - to_chat(user, "\tBrain Activity Level: [100 - M.getBrainLoss()]%.") + to_chat(user, "\tBrain Activity Level: [(200 - M.getBrainLoss())/2]%.") if (M.radiation) to_chat(user, "\tSubject is irradiated.") if(advanced) @@ -316,7 +319,6 @@ MASS SPECTROMETER 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 @@ -333,7 +335,7 @@ MASS SPECTROMETER throw_speed = 3 throw_range = 7 materials = list(MAT_METAL=30, MAT_GLASS=20) - origin_tech = "magnets=1;engineering=1" + grind_results = list("mercury" = 5, "iron" = 5, "silicon" = 5) /obj/item/device/analyzer/attack_self(mob/user) @@ -394,70 +396,6 @@ MASS SPECTROMETER to_chat(user, "[env_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] %") to_chat(user, "Temperature: [round(environment.temperature-T0C)] °C") - -/obj/item/device/mass_spectrometer - desc = "A hand-held mass spectrometer which identifies trace chemicals in a blood sample." - name = "mass-spectrometer" - icon_state = "spectrometer" - item_state = "analyzer" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - w_class = WEIGHT_CLASS_SMALL - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - container_type = OPENCONTAINER_1 - throwforce = 0 - throw_speed = 3 - throw_range = 7 - materials = list(MAT_METAL=150, MAT_GLASS=100) - origin_tech = "magnets=2;biotech=1;plasmatech=2" - var/details = 0 - -/obj/item/device/mass_spectrometer/New() - ..() - create_reagents(5) - -/obj/item/device/mass_spectrometer/on_reagent_change(changetype) - if(reagents.total_volume) - icon_state = initial(icon_state) + "_s" - else - icon_state = initial(icon_state) - -/obj/item/device/mass_spectrometer/attack_self(mob/user) - if (user.stat || user.eye_blind) - return - if (!user.IsAdvancedToolUser()) - to_chat(user, "You don't have the dexterity to do this!") - return - if(reagents.total_volume) - var/list/blood_traces = list() - for(var/datum/reagent/R in reagents.reagent_list) - if(R.id != "blood") - reagents.clear_reagents() - to_chat(user, "The sample was contaminated! Please insert another sample.") - return - else - blood_traces = params2list(R.data["trace_chem"]) - break - var/dat = "Trace Chemicals Found:" - if(!blood_traces.len) - dat += "
    None" - else - for(var/R in blood_traces) - dat += "
    [GLOB.chemical_reagents_list[R]]" - if(details) - dat += " ([blood_traces[R]] units)" - dat += "
    " - to_chat(user, dat) - reagents.clear_reagents() - - -/obj/item/device/mass_spectrometer/adv - name = "advanced mass-spectrometer" - icon_state = "adv_spectrometer" - details = 1 - origin_tech = "magnets=4;biotech=3;plasmatech=3" - /obj/item/device/slime_scanner name = "slime scanner" desc = "A device that analyzes a slime's internal composition and measures its stats." @@ -465,7 +403,6 @@ MASS SPECTROMETER item_state = "analyzer" lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - origin_tech = "biotech=2" w_class = WEIGHT_CLASS_SMALL flags_1 = CONDUCT_1 throwforce = 0 diff --git a/code/game/objects/items/devices/sensor_device.dm b/code/game/objects/items/devices/sensor_device.dm index a2deafe916..e42a42bf01 100644 --- a/code/game/objects/items/devices/sensor_device.dm +++ b/code/game/objects/items/devices/sensor_device.dm @@ -5,7 +5,6 @@ icon_state = "scanner" w_class = WEIGHT_CLASS_SMALL slot_flags = SLOT_BELT - origin_tech = "programming=3;materials=3;magnets=3" /obj/item/device/sensor_device/attack_self(mob/user) GLOB.crewmonitor.show(user) //Proc already exists, just had to call it diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm index 912a083171..69b6e54841 100644 --- a/code/game/objects/items/devices/taperecorder.dm +++ b/code/game/objects/items/devices/taperecorder.dm @@ -289,6 +289,9 @@ fix() //Random colour tapes +/obj/item/device/tape/random + icon_state = "random_tape" + /obj/item/device/tape/random/New() icon_state = "tape_[pick("white", "blue", "red", "yellow", "purple")]" ..() diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm index 7ca4da4f65..5afc8602ff 100644 --- a/code/game/objects/items/devices/traitordevices.dm +++ b/code/game/objects/items/devices/traitordevices.dm @@ -27,7 +27,6 @@ effective or pretty fucking useless. item_state = "electronic" lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' - origin_tech = "magnets=3;combat=3;syndicate=3" var/times_used = 0 //Number of times it's been used. var/max_uses = 2 @@ -70,7 +69,6 @@ effective or pretty fucking useless. /obj/item/device/healthanalyzer/rad_laser materials = list(MAT_METAL=400) - origin_tech = "magnets=3;biotech=5;syndicate=3" var/irradiate = 1 var/intensity = 10 // how much damage the radiation does var/wavelength = 10 // time it takes for the radiation to kick in, in seconds @@ -230,7 +228,7 @@ effective or pretty fucking useless. charge = max(0,charge - 25)//Quick decrease in light else charge = min(max_charge,charge + 50) //Charge in the dark - animate(user,alpha = Clamp(255 - charge,0,255),time = 10) + animate(user,alpha = CLAMP(255 - charge,0,255),time = 10) /obj/item/device/jammer diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index 53f36719e4..cb83a1adbc 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -12,7 +12,6 @@ var/mob/attacher = null var/valve_open = FALSE var/toggle = 1 - origin_tech = "materials=1;engineering=1" /obj/item/device/transfer_valve/IsAssemblyHolder() return TRUE diff --git a/code/game/objects/items/dice.dm b/code/game/objects/items/dice.dm index 7cf88e77ef..e14363a1c1 100644 --- a/code/game/objects/items/dice.dm +++ b/code/game/objects/items/dice.dm @@ -30,6 +30,10 @@ if(special_die == "100") new /obj/item/dice/d100(src) +/obj/item/storage/pill_bottle/dice/suicide_act(mob/user) + user.visible_message("[user] is gambling with death! It looks like [user.p_theyre()] trying to commit suicide!") + return (OXYLOSS) + /obj/item/dice //depreciated d6, use /obj/item/dice/d6 if you actually want a d6 name = "die" desc = "A die with six sides. Basic and servicable." @@ -47,6 +51,10 @@ update_icon() ..() +/obj/item/dice/suicide_act(mob/user) + user.visible_message("[user] is gambling with death! It looks like [user.p_theyre()] trying to commit suicide!") + return (OXYLOSS) + /obj/item/dice/d1 name = "d1" desc = "A die with one side. Deterministic!" @@ -65,6 +73,10 @@ icon_state = "d4" sides = 4 +/obj/item/dice/d4/Initialize(mapload) + . = ..() + AddComponent(/datum/component/caltrop, 4) + /obj/item/dice/d6 name = "d6" @@ -154,7 +166,7 @@ /obj/item/dice/proc/diceroll(mob/user) result = rand(1, sides) if(rigged && result != rigged) - if(prob(Clamp(1/(sides - 1) * 100, 25, 80))) + if(prob(CLAMP(1/(sides - 1) * 100, 25, 80))) result = rigged var/fake_result = rand(1, sides)//Daredevil isn't as good as he used to be var/comment = "" @@ -174,14 +186,6 @@ else if(!src.throwing) //Dice was thrown and is coming to rest visible_message("[src] rolls to a stop, landing on [result]. [comment]") -/obj/item/dice/d4/Crossed(mob/living/carbon/human/H) - if(istype(H) && !H.shoes) - if(PIERCEIMMUNE in H.dna.species.species_traits) - return 0 - to_chat(H, "You step on the D4!") - H.apply_damage(4,BRUTE,(pick("l_leg", "r_leg"))) - H.Knockdown(60) - /obj/item/dice/update_icon() cut_overlays() add_overlay("[src.icon_state][src.result]") diff --git a/code/game/objects/items/dna_injector.dm b/code/game/objects/items/dna_injector.dm index d76bc6856a..9644d827ea 100644 --- a/code/game/objects/items/dna_injector.dm +++ b/code/game/objects/items/dna_injector.dm @@ -8,7 +8,6 @@ throw_speed = 3 throw_range = 5 w_class = WEIGHT_CLASS_TINY - origin_tech = "biotech=1" var/damage_coeff = 1 var/list/fields @@ -265,13 +264,13 @@ name = "\improper DNA injector (Smile)" add_mutations_static = list(SMILE) -/obj/item/dnainjector/unintelligablemut - name = "\improper DNA injector (Unintelligable)" - add_mutations_static = list(UNINTELLIGABLE) +/obj/item/dnainjector/unintelligiblemut + name = "\improper DNA injector (Unintelligible)" + add_mutations_static = list(UNINTELLIGIBLE) -/obj/item/dnainjector/antiunintelligable - name = "\improper DNA injector (Anti-Unintelligable)" - remove_mutations_static = list(UNINTELLIGABLE) +/obj/item/dnainjector/antiunintelligible + name = "\improper DNA injector (Anti-Unintelligible)" + remove_mutations_static = list(UNINTELLIGIBLE) /obj/item/dnainjector/swedishmut name = "\improper DNA injector (Swedish)" diff --git a/code/game/objects/items/extinguisher.dm b/code/game/objects/items/extinguisher.dm index d334d12193..5f582b9e15 100644 --- a/code/game/objects/items/extinguisher.dm +++ b/code/game/objects/items/extinguisher.dm @@ -16,6 +16,7 @@ attack_verb = list("slammed", "whacked", "bashed", "thunked", "battered", "bludgeoned", "thrashed") dog_fashion = /datum/dog_fashion/back resistance_flags = FIRE_PROOF + container_type = AMOUNT_VISIBLE var/max_water = 50 var/last_use = 1 var/safety = TRUE @@ -48,7 +49,6 @@ /obj/item/extinguisher/attack_self(mob/user) safety = !safety src.icon_state = "[sprite_name][!safety]" - src.desc = "The safety is [safety ? "on" : "off"]." to_chat(user, "The safety is [safety ? "on" : "off"].") return @@ -67,11 +67,10 @@ /obj/item/extinguisher/examine(mob/user) ..() + to_chat(user, "The safety is [safety ? "on" : "off"].") + if(reagents.total_volume) - to_chat(user, "It contains [round(reagents.total_volume)] unit\s.") to_chat(user, "Alt-click to empty it.") - else - to_chat(user, "It is empty.") /obj/item/extinguisher/proc/AttemptRefill(atom/target, mob/user) if(istype(target, /obj/structure/reagent_dispensers/watertank) && target.Adjacent(user)) diff --git a/code/game/objects/items/flamethrower.dm b/code/game/objects/items/flamethrower.dm index b2676c3c4e..3a351a6514 100644 --- a/code/game/objects/items/flamethrower.dm +++ b/code/game/objects/items/flamethrower.dm @@ -13,7 +13,6 @@ throw_range = 5 w_class = WEIGHT_CLASS_NORMAL materials = list(MAT_METAL=500) - origin_tech = "combat=1;plasmatech=2;engineering=2" resistance_flags = FIRE_PROOF var/status = FALSE var/lit = FALSE //on or off diff --git a/code/game/objects/items/grenades/chem_grenade.dm b/code/game/objects/items/grenades/chem_grenade.dm index b778bcb179..8698594555 100644 --- a/code/game/objects/items/grenades/chem_grenade.dm +++ b/code/game/objects/items/grenades/chem_grenade.dm @@ -110,12 +110,12 @@ else if(stage == WIRED && istype(I, /obj/item/wrench)) if(beakers.len) for(var/obj/O in beakers) - O.loc = get_turf(src) + O.forceMove(drop_location()) beakers = list() to_chat(user, "You open the [initial(name)] assembly and remove the payload.") return // First use of the wrench remove beakers, then use the wrench to remove the activation mechanism. if(nadeassembly) - nadeassembly.loc = get_turf(src) + nadeassembly.forceMove(drop_location()) nadeassembly.master = null nadeassembly = null else // If "nadeassembly = null && stage == WIRED", then it most have been cable_coil that was used. @@ -167,7 +167,7 @@ playsound(loc, 'sound/items/screwdriver2.ogg', 50, 1) if(beakers.len) for(var/obj/O in beakers) - O.loc = get_turf(src) + O.forceMove(drop_location()) beakers = list() stage_change(EMPTY) return @@ -195,7 +195,6 @@ icon_state = "large_grenade" allowed_containers = list(/obj/item/reagent_containers/glass, /obj/item/reagent_containers/food/condiment, /obj/item/reagent_containers/food/drinks) - origin_tech = "combat=3;engineering=3" affected_area = 5 ignition_temp = 25 // Large grenades are slightly more effective at setting off heat-sensitive mixtures than smaller grenades. threatscale = 1.1 // 10% more effective. @@ -245,7 +244,6 @@ name = "pyro grenade" desc = "A custom made pyrotechnical grenade. It heats up and ignites its contents upon detonation." icon_state = "pyrog" - origin_tech = "combat=4;engineering=4" affected_area = 3 ignition_temp = 500 // This is enough to expose a hotspot. @@ -253,7 +251,6 @@ name = "advanced release grenade" desc = "A custom made advanced release grenade. It is able to be detonated more than once. Can be configured using a multitool." icon_state = "timeg" - origin_tech = "combat=3;engineering=4" var/unit_spread = 10 // Amount of units per repeat. Can be altered with a multitool. /obj/item/grenade/chem_grenade/adv_release/attackby(obj/item/I, mob/user, params) diff --git a/code/game/objects/items/grenades/clusterbuster.dm b/code/game/objects/items/grenades/clusterbuster.dm index 9f2cb1ab88..167c3114ec 100644 --- a/code/game/objects/items/grenades/clusterbuster.dm +++ b/code/game/objects/items/grenades/clusterbuster.dm @@ -129,6 +129,9 @@ //random clusterbuster spawner +/obj/item/grenade/clusterbuster/random + icon_state = "random_clusterbang" + /obj/item/grenade/clusterbuster/random/New() var/real_type = pick(subtypesof(/obj/item/grenade/clusterbuster)) new real_type(loc) diff --git a/code/game/objects/items/grenades/emgrenade.dm b/code/game/objects/items/grenades/emgrenade.dm index 8900cb284a..99cf4bdf99 100644 --- a/code/game/objects/items/grenades/emgrenade.dm +++ b/code/game/objects/items/grenades/emgrenade.dm @@ -3,7 +3,6 @@ desc = "It is designed to wreak havoc on electronic systems." icon_state = "emp" item_state = "emp" - origin_tech = "magnets=3;combat=2" /obj/item/grenade/empgrenade/prime() update_mob() diff --git a/code/game/objects/items/grenades/flashbang.dm b/code/game/objects/items/grenades/flashbang.dm index 33d8d6342f..8533d579c4 100644 --- a/code/game/objects/items/grenades/flashbang.dm +++ b/code/game/objects/items/grenades/flashbang.dm @@ -4,7 +4,6 @@ item_state = "flashbang" lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' - origin_tech = "materials=2;combat=3" /obj/item/grenade/flashbang/prime() update_mob() diff --git a/code/game/objects/items/grenades/plastic.dm b/code/game/objects/items/grenades/plastic.dm index 4b7c8985a6..0375e5529e 100644 --- a/code/game/objects/items/grenades/plastic.dm +++ b/code/game/objects/items/grenades/plastic.dm @@ -10,7 +10,6 @@ det_time = 10 display_timer = 0 w_class = WEIGHT_CLASS_SMALL - origin_tech = "syndicate=1" var/atom/target = null var/mutable_appearance/plastic_overlay var/obj/item/device/assembly_holder/nadeassembly = null @@ -88,7 +87,7 @@ return var/newtime = input(usr, "Please set the timer.", "Timer", 10) as num if(user.get_active_held_item() == src) - newtime = Clamp(newtime, 10, 60000) + newtime = CLAMP(newtime, 10, 60000) det_time = newtime to_chat(user, "Timer set for [det_time] seconds.") @@ -205,7 +204,7 @@ /obj/item/grenade/plastic/c4/attack_self(mob/user) var/newtime = input(usr, "Please set the timer.", "Timer", 10) as num if(user.get_active_held_item() == src) - newtime = Clamp(newtime, 10, 60000) + newtime = CLAMP(newtime, 10, 60000) timer = newtime to_chat(user, "Timer set for [timer] seconds.") diff --git a/code/game/objects/items/grenades/spawnergrenade.dm b/code/game/objects/items/grenades/spawnergrenade.dm index f918a66ae2..edec58ebcd 100644 --- a/code/game/objects/items/grenades/spawnergrenade.dm +++ b/code/game/objects/items/grenades/spawnergrenade.dm @@ -4,7 +4,6 @@ icon = 'icons/obj/grenade.dmi' icon_state = "delivery" item_state = "flashbang" - origin_tech = "materials=3;magnets=4" var/spawner_type = null // must be an object path var/deliveryamt = 1 // amount of type to deliver @@ -26,13 +25,11 @@ name = "viscerator delivery grenade" spawner_type = /mob/living/simple_animal/hostile/viscerator deliveryamt = 10 - origin_tech = "materials=3;magnets=4;syndicate=3" /obj/item/grenade/spawnergrenade/spesscarp name = "carp delivery grenade" spawner_type = /mob/living/simple_animal/hostile/carp deliveryamt = 5 - origin_tech = "materials=3;magnets=4;syndicate=3" /obj/item/grenade/spawnergrenade/syndiesoap name = "Mister Scrubby" diff --git a/code/game/objects/items/grenades/syndieminibomb.dm b/code/game/objects/items/grenades/syndieminibomb.dm index 9484135a09..e1866a3e69 100644 --- a/code/game/objects/items/grenades/syndieminibomb.dm +++ b/code/game/objects/items/grenades/syndieminibomb.dm @@ -4,7 +4,6 @@ icon = 'icons/obj/grenade.dmi' icon_state = "syndicate" item_state = "flashbang" - origin_tech = "materials=3;magnets=4;syndicate=3" /obj/item/grenade/syndieminibomb/prime() @@ -16,7 +15,6 @@ name = "HE Grenade" desc = "A compact shrapnel grenade meant to devestate nearby organisms and cause some damage in the process. Pull pin and throw opposite direction." icon_state = "concussion" - origin_tech = "materials=3;magnets=4;syndicate=2" /obj/item/grenade/syndieminibomb/concussion/prime() update_mob() diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm index 3085019b51..886a248c8c 100644 --- a/code/game/objects/items/handcuffs.dm +++ b/code/game/objects/items/handcuffs.dm @@ -18,7 +18,6 @@ throw_speed = 3 throw_range = 5 materials = list(MAT_METAL=500) - origin_tech = "engineering=3;combat=3" breakouttime = 600 //Deciseconds = 60s = 1 minute armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 50) var/cuffsound = 'sound/weapons/handcuffs.ogg' @@ -95,7 +94,6 @@ lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' materials = list(MAT_METAL=150, MAT_GLASS=75) - origin_tech = "engineering=2" breakouttime = 300 //Deciseconds = 30s cuffsound = 'sound/weapons/cablecuff.ogg' var/datum/robot_energy_storage/wirestorage = null @@ -253,7 +251,6 @@ flags_1 = CONDUCT_1 throwforce = 0 w_class = WEIGHT_CLASS_NORMAL - origin_tech = "engineering=3;combat=3" slowdown = 7 breakouttime = 300 //Deciseconds = 30s = 0.5 minute @@ -263,7 +260,6 @@ throw_range = 1 icon_state = "beartrap" desc = "A trap used to catch bears and other legged creatures." - origin_tech = "engineering=4" var/armed = 0 var/trap_damage = 20 @@ -296,7 +292,7 @@ def_zone = pick("l_leg", "r_leg") if(!C.legcuffed && C.get_num_legs() >= 2) //beartrap can't cuff your leg if there's already a beartrap or legcuffs, or you don't have two legs. C.legcuffed = src - src.loc = C + forceMove(C) C.update_inv_legcuffed() SSblackbox.record_feedback("tally", "handcuffs", 1, type) else if(isanimal(L)) @@ -342,7 +338,6 @@ icon_state = "bola" breakouttime = 35//easy to apply, easy to break out of gender = NEUTER - origin_tech = "engineering=3;combat=1" var/knockdown = 0 /obj/item/restraints/legcuffs/bola/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback) @@ -357,7 +352,7 @@ if(!C.legcuffed && C.get_num_legs() >= 2) visible_message("\The [src] ensnares [C]!") C.legcuffed = src - src.loc = C + forceMove(C) C.update_inv_legcuffed() SSblackbox.record_feedback("tally", "handcuffs", 1, type) to_chat(C, "\The [src] ensnares you!") @@ -368,7 +363,6 @@ desc = "A strong bola, made with a long steel chain. It looks heavy, enough so that it could trip somebody." icon_state = "bola_r" breakouttime = 70 - origin_tech = "engineering=4;combat=3" knockdown = 20 /obj/item/restraints/legcuffs/bola/energy //For Security diff --git a/code/game/objects/items/his_grace.dm b/code/game/objects/items/his_grace.dm index 0a2e6d6350..d13d6cc1dd 100644 --- a/code/game/objects/items/his_grace.dm +++ b/code/game/objects/items/his_grace.dm @@ -13,7 +13,6 @@ righthand_file = 'icons/mob/inhands/equipment/toolbox_righthand.dmi' icon = 'icons/obj/items_and_weapons.dmi' w_class = WEIGHT_CLASS_GIGANTIC - origin_tech = "combat=4;engineering=4;syndicate=2" force = 12 attack_verb = list("robusted") hitsound = 'sound/weapons/smash.ogg' @@ -76,7 +75,7 @@ drowse() return if(bloodthirst < HIS_GRACE_CONSUME_OWNER) - adjust_bloodthirst(1 + Floor(LAZYLEN(contents) * 0.5)) //Maybe adjust this? + adjust_bloodthirst(1 + FLOOR(LAZYLEN(contents) * 0.5, 1)) //Maybe adjust this? else adjust_bloodthirst(1) //don't cool off rapidly once we're at the point where His Grace consumes all. var/mob/living/master = get_atom_on_turf(src, /mob/living) @@ -165,9 +164,9 @@ /obj/item/his_grace/proc/adjust_bloodthirst(amt) prev_bloodthirst = bloodthirst if(prev_bloodthirst < HIS_GRACE_CONSUME_OWNER) - bloodthirst = Clamp(bloodthirst + amt, HIS_GRACE_SATIATED, HIS_GRACE_CONSUME_OWNER) + bloodthirst = CLAMP(bloodthirst + amt, HIS_GRACE_SATIATED, HIS_GRACE_CONSUME_OWNER) else - bloodthirst = Clamp(bloodthirst + amt, HIS_GRACE_CONSUME_OWNER, HIS_GRACE_FALL_ASLEEP) + bloodthirst = CLAMP(bloodthirst + amt, HIS_GRACE_CONSUME_OWNER, HIS_GRACE_FALL_ASLEEP) update_stats() /obj/item/his_grace/proc/update_stats() diff --git a/code/game/objects/items/holosign_creator.dm b/code/game/objects/items/holosign_creator.dm index 04dc732039..48504d6e3c 100644 --- a/code/game/objects/items/holosign_creator.dm +++ b/code/game/objects/items/holosign_creator.dm @@ -11,7 +11,6 @@ throwforce = 0 throw_speed = 3 throw_range = 7 - origin_tech = "magnets=1;programming=3" flags_1 = NOBLUDGEON_1 var/list/signs = list() var/max_signs = 10 diff --git a/code/game/objects/items/implants/implant.dm b/code/game/objects/items/implants/implant.dm index bdc0013772..f5b50542d0 100644 --- a/code/game/objects/items/implants/implant.dm +++ b/code/game/objects/items/implants/implant.dm @@ -1,98 +1,100 @@ -/obj/item/implant - name = "implant" - icon = 'icons/obj/implants.dmi' - icon_state = "generic" //Shows up as the action button icon - origin_tech = "materials=2;biotech=3;programming=2" - actions_types = list(/datum/action/item_action/hands_free/activate) - var/activated = 1 //1 for implant types that can be activated, 0 for ones that are "always on" like mindshield implants - var/mob/living/imp_in = null - item_color = "b" - var/allow_multiple = FALSE - var/uses = -1 - flags_1 = DROPDEL_1 - - -/obj/item/implant/proc/trigger(emote, mob/living/carbon/source) - return - -/obj/item/implant/proc/activate() - return - -/obj/item/implant/ui_action_click() - activate("action_button") - -/obj/item/implant/proc/can_be_implanted_in(mob/living/target) // for human-only and other special requirements - return TRUE - -/mob/living/proc/can_be_implanted() - return TRUE - -/mob/living/silicon/can_be_implanted() - return FALSE - -/mob/living/simple_animal/can_be_implanted() - return healable //Applies to robots and most non-organics, exceptions can override. - - - -//What does the implant do upon injection? -//return 1 if the implant injects -//return 0 if there is no room for implant / it fails -/obj/item/implant/proc/implant(mob/living/target, mob/user, silent = 0) - LAZYINITLIST(target.implants) - if(!target.can_be_implanted() || !can_be_implanted_in(target)) - return 0 - for(var/X in target.implants) - if(istype(X, type)) - var/obj/item/implant/imp_e = X - if(!allow_multiple) - if(imp_e.uses < initial(imp_e.uses)*2) - if(uses == -1) - imp_e.uses = -1 - else - imp_e.uses = min(imp_e.uses + uses, initial(imp_e.uses)*2) - qdel(src) - return 1 - else - return 0 - - src.loc = target - imp_in = target - target.implants += src - if(activated) - for(var/X in actions) - var/datum/action/A = X - A.Grant(target) - if(ishuman(target)) - var/mob/living/carbon/human/H = target - H.sec_hud_set_implants() - - if(user) - add_logs(user, target, "implanted", object="[name]") - - return 1 - -/obj/item/implant/proc/removed(mob/living/source, silent = 0, special = 0) - src.loc = null - imp_in = null - source.implants -= src - for(var/X in actions) - var/datum/action/A = X - A.Grant(source) - if(ishuman(source)) - var/mob/living/carbon/human/H = source - H.sec_hud_set_implants() - - return 1 - -/obj/item/implant/Destroy() - if(imp_in) - removed(imp_in) - return ..() - -/obj/item/implant/proc/get_data() - return "No information available" - -/obj/item/implant/dropped(mob/user) - . = 1 - ..() +/obj/item/implant + name = "implant" + icon = 'icons/obj/implants.dmi' + icon_state = "generic" //Shows up as the action button icon + actions_types = list(/datum/action/item_action/hands_free/activate) + var/activated = 1 //1 for implant types that can be activated, 0 for ones that are "always on" like mindshield implants + var/mob/living/imp_in = null + item_color = "b" + var/allow_multiple = FALSE + var/uses = -1 + flags_1 = DROPDEL_1 + + +/obj/item/implant/proc/trigger(emote, mob/living/carbon/source) + return + +/obj/item/implant/proc/on_death(emote, mob/living/carbon/source) + return + +/obj/item/implant/proc/activate() + return + +/obj/item/implant/ui_action_click() + activate("action_button") + +/obj/item/implant/proc/can_be_implanted_in(mob/living/target) // for human-only and other special requirements + return TRUE + +/mob/living/proc/can_be_implanted() + return TRUE + +/mob/living/silicon/can_be_implanted() + return FALSE + +/mob/living/simple_animal/can_be_implanted() + return healable //Applies to robots and most non-organics, exceptions can override. + + + +//What does the implant do upon injection? +//return 1 if the implant injects +//return 0 if there is no room for implant / it fails +/obj/item/implant/proc/implant(mob/living/target, mob/user, silent = 0) + LAZYINITLIST(target.implants) + if(!target.can_be_implanted() || !can_be_implanted_in(target)) + return 0 + for(var/X in target.implants) + if(istype(X, type)) + var/obj/item/implant/imp_e = X + if(!allow_multiple) + if(imp_e.uses < initial(imp_e.uses)*2) + if(uses == -1) + imp_e.uses = -1 + else + imp_e.uses = min(imp_e.uses + uses, initial(imp_e.uses)*2) + qdel(src) + return 1 + else + return 0 + + forceMove(target) + imp_in = target + target.implants += src + if(activated) + for(var/X in actions) + var/datum/action/A = X + A.Grant(target) + if(ishuman(target)) + var/mob/living/carbon/human/H = target + H.sec_hud_set_implants() + + if(user) + add_logs(user, target, "implanted", object="[name]") + + return 1 + +/obj/item/implant/proc/removed(mob/living/source, silent = 0, special = 0) + moveToNullspace() + imp_in = null + source.implants -= src + for(var/X in actions) + var/datum/action/A = X + A.Grant(source) + if(ishuman(source)) + var/mob/living/carbon/human/H = source + H.sec_hud_set_implants() + + return 1 + +/obj/item/implant/Destroy() + if(imp_in) + removed(imp_in) + return ..() + +/obj/item/implant/proc/get_data() + return "No information available" + +/obj/item/implant/dropped(mob/user) + . = 1 + ..() diff --git a/code/game/objects/items/implants/implant_abductor.dm b/code/game/objects/items/implants/implant_abductor.dm index 710e2d738e..ba4f553e25 100644 --- a/code/game/objects/items/implants/implant_abductor.dm +++ b/code/game/objects/items/implants/implant_abductor.dm @@ -4,7 +4,6 @@ icon = 'icons/obj/abductor.dmi' icon_state = "implant" activated = 1 - origin_tech = "materials=2;biotech=7;magnets=4;bluespace=4;abductor=5" var/obj/machinery/abductor/pad/home var/cooldown = 30 diff --git a/code/game/objects/items/implants/implant_chem.dm b/code/game/objects/items/implants/implant_chem.dm index 3ec81b6a25..e266f3ab09 100644 --- a/code/game/objects/items/implants/implant_chem.dm +++ b/code/game/objects/items/implants/implant_chem.dm @@ -2,8 +2,7 @@ name = "chem implant" desc = "Injects things." icon_state = "reagents" - origin_tech = "materials=3;biotech=4" - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER /obj/item/implant/chem/get_data() var/dat = {"Implant Specifications:
    diff --git a/code/game/objects/items/implants/implant_exile.dm b/code/game/objects/items/implants/implant_exile.dm index f6848e7782..9b68206338 100644 --- a/code/game/objects/items/implants/implant_exile.dm +++ b/code/game/objects/items/implants/implant_exile.dm @@ -4,7 +4,6 @@ /obj/item/implant/exile name = "exile implant" desc = "Prevents you from returning from away missions." - origin_tech = "materials=2;biotech=3;magnets=2;bluespace=3" activated = 0 /obj/item/implant/exile/get_data() diff --git a/code/game/objects/items/implants/implant_explosive.dm b/code/game/objects/items/implants/implant_explosive.dm index 4d10fd1be5..0dc22c3d83 100644 --- a/code/game/objects/items/implants/implant_explosive.dm +++ b/code/game/objects/items/implants/implant_explosive.dm @@ -2,9 +2,8 @@ name = "microbomb implant" desc = "And boom goes the weasel." icon_state = "explosive" - origin_tech = "materials=2;combat=3;biotech=4;syndicate=4" actions_types = list(/datum/action/item_action/explosive_implant) - // Explosive implant action is always availible. + // Explosive implant action is always available. var/weak = 2 var/medium = 0.8 var/heavy = 0.4 @@ -12,6 +11,9 @@ var/popup = FALSE // is the DOUWANNABLOWUP window open? var/active = FALSE +/obj/item/implant/explosive/on_mob_death(mob/living/L, gibbed) + activate("death") + /obj/item/implant/explosive/get_data() var/dat = {"Implant Specifications:
    Name: Robust Corp RX-78 Employee Management Implant
    @@ -24,10 +26,6 @@ "} return dat -/obj/item/implant/explosive/trigger(emote, mob/source) - if(emote == "deathgasp") - activate("death") - /obj/item/implant/explosive/activate(cause) if(!cause || !imp_in || active) return 0 @@ -89,7 +87,6 @@ name = "macrobomb implant" desc = "And boom goes the weasel. And everything else nearby." icon_state = "explosive" - origin_tech = "materials=3;combat=5;biotech=4;syndicate=5" weak = 16 medium = 8 heavy = 4 diff --git a/code/game/objects/items/implants/implant_freedom.dm b/code/game/objects/items/implants/implant_freedom.dm index 769efed405..4ba04c9479 100644 --- a/code/game/objects/items/implants/implant_freedom.dm +++ b/code/game/objects/items/implants/implant_freedom.dm @@ -3,7 +3,6 @@ desc = "Use this to escape from those evil Red Shirts." icon_state = "freedom" item_color = "r" - origin_tech = "combat=5;magnets=3;biotech=4;syndicate=2" uses = 4 diff --git a/code/game/objects/items/implants/implant_gang.dm b/code/game/objects/items/implants/implant_gang.dm index c2456dba84..d229631ca0 100644 --- a/code/game/objects/items/implants/implant_gang.dm +++ b/code/game/objects/items/implants/implant_gang.dm @@ -2,7 +2,6 @@ name = "gang implant" desc = "Makes you a gangster or such." activated = 0 - origin_tech = "materials=2;biotech=4;programming=4;syndicate=3" var/datum/gang/gang /obj/item/implant/gang/New(loc,var/setgang) diff --git a/code/game/objects/items/implants/implant_krav_maga.dm b/code/game/objects/items/implants/implant_krav_maga.dm index e214a00cf3..c2d7d44249 100644 --- a/code/game/objects/items/implants/implant_krav_maga.dm +++ b/code/game/objects/items/implants/implant_krav_maga.dm @@ -4,7 +4,6 @@ icon = 'icons/obj/wizard.dmi' icon_state ="scroll2" activated = 1 - origin_tech = "materials=2;biotech=4;combat=5;syndicate=4" var/datum/martial_art/krav_maga/style = new /obj/item/implant/krav_maga/get_data() diff --git a/code/game/objects/items/implants/implant_loyality.dm b/code/game/objects/items/implants/implant_loyality.dm index 1edc0dc93c..cd99875f50 100644 --- a/code/game/objects/items/implants/implant_loyality.dm +++ b/code/game/objects/items/implants/implant_loyality.dm @@ -1,7 +1,6 @@ /obj/item/implant/mindshield name = "mindshield implant" desc = "Protects against brainwashing." - origin_tech = "materials=2;biotech=4;programming=4" activated = 0 /obj/item/implant/mindshield/get_data() diff --git a/code/game/objects/items/implants/implant_misc.dm b/code/game/objects/items/implants/implant_misc.dm index 2e21a6fb82..32e0d937bd 100644 --- a/code/game/objects/items/implants/implant_misc.dm +++ b/code/game/objects/items/implants/implant_misc.dm @@ -2,7 +2,6 @@ name = "firearms authentication implant" desc = "Lets you shoot your guns." icon_state = "auth" - origin_tech = "magnets=2;programming=7;biotech=5;syndicate=5" activated = 0 /obj/item/implant/weapons_auth/get_data() @@ -18,7 +17,6 @@ name = "adrenal implant" desc = "Removes all stuns." icon_state = "adrenal" - origin_tech = "materials=2;biotech=4;combat=3;syndicate=4" uses = 3 /obj/item/implant/adrenalin/get_data() @@ -53,7 +51,6 @@ name = "emp implant" desc = "Triggers an EMP." icon_state = "emp" - origin_tech = "biotech=3;magnets=4;syndicate=1" uses = 3 /obj/item/implant/emp/activate() diff --git a/code/game/objects/items/implants/implant_storage.dm b/code/game/objects/items/implants/implant_storage.dm index f8459b2b67..ea84d50bb7 100644 --- a/code/game/objects/items/implants/implant_storage.dm +++ b/code/game/objects/items/implants/implant_storage.dm @@ -10,7 +10,6 @@ name = "storage implant" desc = "Stores up to two big items in a bluespace pocket." icon_state = "storage" - origin_tech = "materials=2;magnets=4;bluespace=5;syndicate=4" item_color = "r" var/obj/item/storage/internal/implant/storage diff --git a/code/game/objects/items/implants/implant_track.dm b/code/game/objects/items/implants/implant_track.dm index cc6f488e8f..6692a6bd6f 100644 --- a/code/game/objects/items/implants/implant_track.dm +++ b/code/game/objects/items/implants/implant_track.dm @@ -2,7 +2,6 @@ name = "tracking implant" desc = "Track with this." activated = 0 - origin_tech = "materials=2;magnets=2;programming=2;biotech=2" /obj/item/implant/tracking/New() ..() diff --git a/code/game/objects/items/implants/implantcase.dm b/code/game/objects/items/implants/implantcase.dm index 0bafff176b..00bda4dadb 100644 --- a/code/game/objects/items/implants/implantcase.dm +++ b/code/game/objects/items/implants/implantcase.dm @@ -1,83 +1,80 @@ -/obj/item/implantcase - name = "implant case" - desc = "A glass case containing an implant." - icon = 'icons/obj/items_and_weapons.dmi' - icon_state = "implantcase-0" - item_state = "implantcase" - lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' - throw_speed = 2 - throw_range = 5 - w_class = WEIGHT_CLASS_TINY - origin_tech = "materials=1;biotech=2" - materials = list(MAT_GLASS=500) - var/obj/item/implant/imp = null - var/imp_type - - -/obj/item/implantcase/update_icon() - if(imp) - icon_state = "implantcase-[imp.item_color]" - origin_tech = imp.origin_tech - reagents = imp.reagents - else - icon_state = "implantcase-0" - origin_tech = initial(origin_tech) - reagents = null - - -/obj/item/implantcase/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/pen)) - var/t = stripped_input(user, "What would you like the label to be?", name, null) - if(user.get_active_held_item() != W) - return - if(!in_range(src, user) && loc != user) - return - if(t) - name = "implant case - '[t]'" - else - name = "implant case" - else if(istype(W, /obj/item/implanter)) - var/obj/item/implanter/I = W - if(I.imp) - if(imp || I.imp.imp_in) - return - I.imp.loc = src - imp = I.imp - I.imp = null - update_icon() - I.update_icon() - else - if(imp) - if(I.imp) - return - imp.loc = I - I.imp = imp - imp = null - update_icon() - I.update_icon() - - else - return ..() - -/obj/item/implantcase/Initialize(mapload) - . = ..() - if(imp_type) - imp = new imp_type(src) - update_icon() - - -/obj/item/implantcase/tracking - name = "implant case - 'Tracking'" - desc = "A glass case containing a tracking implant." - imp_type = /obj/item/implant/tracking - -/obj/item/implantcase/weapons_auth - name = "implant case - 'Firearms Authentication'" - desc = "A glass case containing a firearms authentication implant." - imp_type = /obj/item/implant/weapons_auth - -/obj/item/implantcase/adrenaline - name = "implant case - 'Adrenaline'" - desc = "A glass case containing an adrenaline implant." - imp_type = /obj/item/implant/adrenalin \ No newline at end of file +/obj/item/implantcase + name = "implant case" + desc = "A glass case containing an implant." + icon = 'icons/obj/items_and_weapons.dmi' + icon_state = "implantcase-0" + item_state = "implantcase" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + throw_speed = 2 + throw_range = 5 + w_class = WEIGHT_CLASS_TINY + materials = list(MAT_GLASS=500) + var/obj/item/implant/imp = null + var/imp_type + + +/obj/item/implantcase/update_icon() + if(imp) + icon_state = "implantcase-[imp.item_color]" + reagents = imp.reagents + else + icon_state = "implantcase-0" + reagents = null + + +/obj/item/implantcase/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/pen)) + var/t = stripped_input(user, "What would you like the label to be?", name, null) + if(user.get_active_held_item() != W) + return + if(!in_range(src, user) && loc != user) + return + if(t) + name = "implant case - '[t]'" + else + name = "implant case" + else if(istype(W, /obj/item/implanter)) + var/obj/item/implanter/I = W + if(I.imp) + if(imp || I.imp.imp_in) + return + I.imp.forceMove(src) + imp = I.imp + I.imp = null + update_icon() + I.update_icon() + else + if(imp) + if(I.imp) + return + imp.forceMove(I) + I.imp = imp + imp = null + update_icon() + I.update_icon() + + else + return ..() + +/obj/item/implantcase/Initialize(mapload) + . = ..() + if(imp_type) + imp = new imp_type(src) + update_icon() + + +/obj/item/implantcase/tracking + name = "implant case - 'Tracking'" + desc = "A glass case containing a tracking implant." + imp_type = /obj/item/implant/tracking + +/obj/item/implantcase/weapons_auth + name = "implant case - 'Firearms Authentication'" + desc = "A glass case containing a firearms authentication implant." + imp_type = /obj/item/implant/weapons_auth + +/obj/item/implantcase/adrenaline + name = "implant case - 'Adrenaline'" + desc = "A glass case containing an adrenaline implant." + imp_type = /obj/item/implant/adrenalin diff --git a/code/game/objects/items/implants/implanter.dm b/code/game/objects/items/implants/implanter.dm index 372671acf5..cb36924494 100644 --- a/code/game/objects/items/implants/implanter.dm +++ b/code/game/objects/items/implants/implanter.dm @@ -9,7 +9,6 @@ throw_speed = 3 throw_range = 5 w_class = WEIGHT_CLASS_SMALL - origin_tech = "materials=2;biotech=3" materials = list(MAT_METAL=600, MAT_GLASS=200) var/obj/item/implant/imp = null var/imp_type = null @@ -18,10 +17,8 @@ /obj/item/implanter/update_icon() if(imp) icon_state = "implanter1" - origin_tech = imp.origin_tech else icon_state = "implanter0" - origin_tech = initial(origin_tech) /obj/item/implanter/attack(mob/living/M, mob/user) @@ -70,4 +67,4 @@ /obj/item/implanter/emp name = "implanter (EMP)" - imp_type = /obj/item/implant/emp \ No newline at end of file + imp_type = /obj/item/implant/emp diff --git a/code/game/objects/items/implants/implantuplink.dm b/code/game/objects/items/implants/implantuplink.dm index d89c4598b5..4f5996b4d1 100644 --- a/code/game/objects/items/implants/implantuplink.dm +++ b/code/game/objects/items/implants/implantuplink.dm @@ -1,42 +1,49 @@ -/obj/item/implant/uplink - name = "uplink implant" - desc = "Sneeki breeki." - icon = 'icons/obj/radio.dmi' - icon_state = "radio" - lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' - righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' - origin_tech = "materials=4;magnets=4;programming=4;biotech=4;syndicate=5;bluespace=5" - var/starting_tc = 0 - -/obj/item/implant/uplink/New() - hidden_uplink = new(src) - hidden_uplink.telecrystals = starting_tc - ..() - -/obj/item/implant/uplink/implant(mob/living/target, mob/user, silent = 0) - for(var/X in target.implants) - if(istype(X, type)) - var/obj/item/implant/imp_e = X - imp_e.hidden_uplink.telecrystals += hidden_uplink.telecrystals - qdel(src) - return 1 - - if(..()) - hidden_uplink.owner = "[user.key]" - return 1 - return 0 - -/obj/item/implant/uplink/activate() - if(hidden_uplink) - hidden_uplink.interact(usr) - -/obj/item/implanter/uplink - name = "implanter (uplink)" - imp_type = /obj/item/implant/uplink - -/obj/item/implanter/uplink/precharged - name = "implanter (precharged uplink)" - imp_type = /obj/item/implant/uplink/precharged - -/obj/item/implant/uplink/precharged - starting_tc = 10 +/obj/item/implant/uplink + name = "uplink implant" + desc = "Sneeki breeki." + icon = 'icons/obj/radio.dmi' + icon_state = "radio" + lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' + righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' + var/starting_tc = 0 + +/obj/item/implant/uplink/Initialize(mapload, _owner) + . = ..() + AddComponent(/datum/component/uplink, _owner, TRUE, FALSE, null, starting_tc) + +/obj/item/implant/uplink/implant(mob/living/target, mob/user, silent = 0) + GET_COMPONENT(hidden_uplink, /datum/component/uplink) + if(hidden_uplink) + for(var/X in target.implants) + if(istype(X, type)) + var/obj/item/implant/imp_e = X + GET_COMPONENT_FROM(their_hidden_uplink, /datum/component/uplink, imp_e) + if(their_hidden_uplink) + their_hidden_uplink.telecrystals += hidden_uplink.telecrystals + qdel(src) + return TRUE + else + qdel(imp_e) //INFERIOR AND EMPTY! + + if(..()) + if(hidden_uplink) + hidden_uplink.owner = "[user.key]" + return TRUE + return FALSE + +/obj/item/implant/uplink/activate() + GET_COMPONENT(hidden_uplink, /datum/component/uplink) + if(hidden_uplink) + hidden_uplink.locked = FALSE + hidden_uplink.interact(usr) + +/obj/item/implanter/uplink + name = "implanter (uplink)" + imp_type = /obj/item/implant/uplink + +/obj/item/implanter/uplink/precharged + name = "implanter (precharged uplink)" + imp_type = /obj/item/implant/uplink/precharged + +/obj/item/implant/uplink/precharged + starting_tc = 10 diff --git a/code/game/objects/items/inducer.dm b/code/game/objects/items/inducer.dm index e720644055..578ba28317 100644 --- a/code/game/objects/items/inducer.dm +++ b/code/game/objects/items/inducer.dm @@ -6,7 +6,6 @@ item_state = "inducer-engi" lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - origin_tech = "engineering=4;magnets=4;powerstorage=4" force = 7 var/powertransfer = 1000 var/opened = FALSE @@ -162,7 +161,7 @@ /obj/item/inducer/examine(mob/living/M) ..() if(cell) - to_chat(M, "Its display shows: [DisplayPower(cell.charge)].") + to_chat(M, "Its display shows: [DisplayEnergy(cell.charge)].") else to_chat(M,"Its display is dark.") if(opened) diff --git a/code/game/objects/items/kitchen.dm b/code/game/objects/items/kitchen.dm index 508e75d8cb..5a8fcda09b 100644 --- a/code/game/objects/items/kitchen.dm +++ b/code/game/objects/items/kitchen.dm @@ -10,7 +10,6 @@ /obj/item/kitchen icon = 'icons/obj/kitchen.dmi' - origin_tech = "materials=1" lefthand_file = 'icons/mob/inhands/equipment/kitchen_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/kitchen_righthand.dmi' @@ -111,7 +110,6 @@ desc = "A military combat utility survival knife." force = 20 throwforce = 20 - origin_tech = "materials=3;combat=4" attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "cut") bayonet = TRUE @@ -140,7 +138,6 @@ icon = 'icons/obj/items_cyborg.dmi' icon_state = "knife" desc = "A cyborg-mounted plasteel knife. Extremely sharp and durable." - origin_tech = null /obj/item/kitchen/knife/carrotshiv name = "carrot shiv" @@ -152,7 +149,6 @@ force = 8 throwforce = 12//fuck git materials = list() - origin_tech = "biotech=3;combat=2" attack_verb = list("shanked", "shivved") armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0) diff --git a/code/game/objects/items/melee/energy.dm b/code/game/objects/items/melee/energy.dm index 4bc134e4da..6eaf3f08bd 100644 --- a/code/game/objects/items/melee/energy.dm +++ b/code/game/objects/items/melee/energy.dm @@ -74,7 +74,6 @@ w_class_on = WEIGHT_CLASS_HUGE flags_1 = CONDUCT_1 armour_penetration = 100 - origin_tech = "combat=4;magnets=3" attack_verb_off = list("attacked", "chopped", "cleaved", "torn", "cut") attack_verb_on = list() light_color = "#40ceff" @@ -99,7 +98,6 @@ embed_chance = 75 embedded_impact_pain_multiplier = 10 armour_penetration = 35 - origin_tech = "combat=3;magnets=4;syndicate=4" block_chance = 50 /obj/item/melee/transforming/energy/sword/transform_weapon(mob/living/user, supress_message_text) diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm index cff958926d..6e21251b6e 100644 --- a/code/game/objects/items/melee/misc.dm +++ b/code/game/objects/items/melee/misc.dm @@ -21,7 +21,6 @@ force = 10 throwforce = 7 w_class = WEIGHT_CLASS_NORMAL - origin_tech = "combat=5" attack_verb = list("flogged", "whipped", "lashed", "disciplined") hitsound = 'sound/weapons/chainhit.ogg' materials = list(MAT_METAL = 1000) @@ -38,7 +37,6 @@ item_state = "arm_blade" lefthand_file = 'icons/mob/inhands/antag/changeling_lefthand.dmi' righthand_file = 'icons/mob/inhands/antag/changeling_righthand.dmi' - origin_tech = "combat=5;biotech=5" w_class = WEIGHT_CLASS_HUGE force = 20 throwforce = 10 @@ -61,7 +59,6 @@ block_chance = 50 armour_penetration = 75 sharpness = IS_SHARP - origin_tech = "combat=5" attack_verb = list("slashed", "cut") hitsound = 'sound/weapons/rapierhit.ogg' materials = list(MAT_METAL = 1000) @@ -208,7 +205,6 @@ armour_penetration = 1000 var/obj/machinery/power/supermatter_shard/shard var/balanced = 1 - origin_tech = "combat=7;materials=6" force_string = "INFINITE" /obj/item/melee/supermatter_sword/Initialize() @@ -224,7 +220,7 @@ return if(!isturf(src.loc)) var/atom/target = src.loc - loc = target.loc + forceMove(target.loc) consume_everything(target) else var/turf/T = get_turf(src) diff --git a/code/game/objects/items/mop.dm b/code/game/objects/items/mop.dm index f9be38a2fe..e47cafdea9 100644 --- a/code/game/objects/items/mop.dm +++ b/code/game/objects/items/mop.dm @@ -78,7 +78,6 @@ item_state = "mop" lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi' - origin_tech = "materials=3;engineering=3" force = 6 throwforce = 8 throw_range = 4 diff --git a/code/game/objects/items/pet_carrier.dm b/code/game/objects/items/pet_carrier.dm new file mode 100644 index 0000000000..cab363f188 --- /dev/null +++ b/code/game/objects/items/pet_carrier.dm @@ -0,0 +1,194 @@ +#define pet_carrier_full(carrier) carrier.occupants.len >= carrier.max_occupants || carrier.occupant_weight >= carrier.max_occupant_weight + +//Used to transport little animals without having to drag them across the station. +//Comes with a handy lock to prevent them from running off. +/obj/item/pet_carrier + name = "pet carrier" + desc = "A big white-and-blue pet carrier. Good for carrying meat to the chef cute animals around." + icon = 'icons/obj/pet_carrier.dmi' + icon_state = "pet_carrier_open" + item_state = "pet_carrier" + lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' + righthand_file = 'icons/mob/inhands/items_righthand.dmi' + force = 5 + attack_verb = list("bashed", "carried") + w_class = WEIGHT_CLASS_BULKY + throw_speed = 2 + throw_range = 3 + materials = list(MAT_METAL = 7500, MAT_GLASS = 100) + var/open = TRUE + var/locked = FALSE + var/list/occupants = list() + var/occupant_weight = 0 + var/max_occupants = 3 //Hard-cap so you can't have infinite mice or something in one carrier + var/max_occupant_weight = MOB_SIZE_SMALL //This is calculated from the mob sizes of occupants + +/obj/item/pet_carrier/Destroy() + if(occupants.len) + for(var/V in occupants) + remove_occupant(V) + return ..() + +/obj/item/pet_carrier/Exited(atom/movable/occupant) + if(occupant in occupants && isliving(occupant)) + var/mob/living/L = occupant + occupants -= occupant + occupant_weight -= L.mob_size + +/obj/item/pet_carrier/handle_atom_del(atom/A) + if(A in occupants && isliving(A)) + var/mob/living/L = A + occupants -= L + occupant_weight -= L.mob_size + ..() + +/obj/item/pet_carrier/examine(mob/user) + ..() + if(occupants.len) + for(var/V in occupants) + var/mob/living/L = V + to_chat(user, "It has [L] inside.") + else + to_chat(user, "It has nothing inside.") + if(user.canUseTopic(src)) + to_chat(user, "Activate it in your hand to [open ? "close" : "open"] its door.") + if(!open) + to_chat(user, "Alt-click to [locked ? "unlock" : "lock"] its door.") + +/obj/item/pet_carrier/attack_self(mob/living/user) + if(open) + to_chat(user, "You close [src]'s door.") + playsound(user, 'sound/effects/bin_close.ogg', 50, TRUE) + open = FALSE + else + if(locked) + to_chat(user, "[src] is locked!") + return + to_chat(user, "You open [src]'s door.") + playsound(user, 'sound/effects/bin_open.ogg', 50, TRUE) + open = TRUE + update_icon() + +/obj/item/pet_carrier/AltClick(mob/living/user) + if(open || !user.canUseTopic(src, be_close=TRUE)) + return + locked = !locked + to_chat(user, "You flip the lock switch [locked ? "down" : "up"].") + if(locked) + playsound(user, 'sound/machines/boltsdown.ogg', 30, TRUE) + else + playsound(user, 'sound/machines/boltsup.ogg', 30, TRUE) + update_icon() + +/obj/item/pet_carrier/attack(mob/living/target, mob/living/user) + if(user.a_intent == INTENT_HARM) + return ..() + if(!open) + to_chat(user, "You need to open [src]'s door!") + return + if(target.mob_size > max_occupant_weight) + if(ishuman(target)) + var/mob/living/carbon/human/H = target + if(iscatperson(H)) + to_chat(user, "You'd need a lot of catnip and treats, plus maybe a laser pointer, for that to work.") + else + to_chat(user, "Humans, generally, do not fit into pet carriers.") + else + to_chat(user, "You get the feeling [target] isn't meant for a [name].") + return + if(user == target) + to_chat(user, "Why would you ever do that?") + return + load_occupant(user, target) + +/obj/item/pet_carrier/relaymove(mob/living/user, direction) + if(open) + loc.visible_message("[user] climbs out of [src]!", \ + "[user] jumps out of [src]!") + remove_occupant(user) + return + else if(!locked) + loc.visible_message("[user] pushes open the door to [src]!", \ + "[user] pushes open the door of [src]!") + open = TRUE + update_icon() + return + else if(user.client) + container_resist(user) + +/obj/item/pet_carrier/container_resist(mob/living/user) + user.changeNext_move(CLICK_CD_BREAKOUT) + user.last_special = world.time + CLICK_CD_BREAKOUT + if(user.mob_size <= MOB_SIZE_SMALL) + to_chat(user, "You poke a limb through [src]'s bars and start fumbling for the lock switch... (This will take some time.)") + to_chat(loc, "You see [user] reach through the bars and fumble for the lock switch!") + if(!do_after(user, rand(300, 400), target = user) || open || !locked || !user in occupants) + return + loc.visible_message("[user] flips the lock switch on [src] by reaching through!", ignored_mob = user) + to_chat(user, "Bingo! The lock pops open!") + locked = FALSE + playsound(src, 'sound/machines/boltsup.ogg', 30, TRUE) + update_icon() + else + loc.visible_message("[src] starts rattling as something pushes against the door!", ignored_mob = user) + to_chat(user, "You start pushing out of [src]... (This will take about 20 seconds.)") + if(!do_after(user, 200, target = user) || open || !locked || !user in occupants) + return + loc.visible_message("[user] shoves out of [src]!", ignored_mob = user) + to_chat(user, "You shove open [src]'s door against the lock's resistance and fall out!") + locked = FALSE + open = TRUE + update_icon() + remove_occupant(user) + +/obj/item/pet_carrier/update_icon() + cut_overlay("unlocked") + cut_overlay("locked") + if(open) + icon_state = initial(icon_state) + else + icon_state = "pet_carrier_[!occupants.len ? "closed" : "occupied"]" + add_overlay("[locked ? "" : "un"]locked") + +/obj/item/pet_carrier/MouseDrop(atom/over_atom) + if(isopenturf(over_atom) && usr.Adjacent(over_atom) && open && occupants.len) + usr.visible_message("[usr] unloads [src].", \ + "You unload [src] onto [over_atom].") + for(var/V in occupants) + remove_occupant(V, over_atom) + +/obj/item/pet_carrier/proc/load_occupant(mob/living/user, mob/living/target) + if(pet_carrier_full(src)) + to_chat(user, "[src] is already carrying too much!") + return + user.visible_message("[user] starts loading [target] into [src].", \ + "You start loading [target] into [src]...", ignored_mob = target) + to_chat(target, "[user] starts loading you into their [name]!") + if(!do_mob(user, target, 30)) + return + if(target in occupants) + return + if(pet_carrier_full(src)) //Run the checks again, just in case + to_chat(user, "[src] is already carrying too much!") + return + user.visible_message("[user] loads [target] into [src]!", \ + "You load [target] into [src].", ignored_mob = target) + to_chat(target, "[user] loads you into their [name]!") + add_occupant(target) + +/obj/item/pet_carrier/proc/add_occupant(mob/living/occupant) + if(occupant in occupants || !istype(occupant)) + return + occupant.forceMove(src) + occupants += occupant + occupant_weight += occupant.mob_size + +/obj/item/pet_carrier/proc/remove_occupant(mob/living/occupant, turf/new_turf) + if(!occupant in occupants || !istype(occupant)) + return + occupant.forceMove(new_turf ? new_turf : drop_location()) + occupants -= occupant + occupant_weight -= occupant.mob_size + occupant.setDir(SOUTH) + +#undef pet_carrier_full diff --git a/code/game/objects/items/plushes.dm b/code/game/objects/items/plushes.dm index f2fd53403a..8bd5d570e2 100644 --- a/code/game/objects/items/plushes.dm +++ b/code/game/objects/items/plushes.dm @@ -9,13 +9,91 @@ var/list/squeak_override //Weighted list; If you want your plush to have different squeak sounds use this var/stuffed = TRUE //If the plushie has stuffing in it var/obj/item/grenade/grenade //You can remove the stuffing from a plushie and add a grenade to it for *nefarious uses* + //--love ~<3-- + gender = NEUTER + var/obj/item/toy/plush/lover + var/obj/item/toy/plush/partner + var/obj/item/toy/plush/plush_child + var/obj/item/toy/plush/paternal_parent //who initiated creation + var/obj/item/toy/plush/maternal_parent //who owns, see love() + var/list/scorned = list() //who the plush hates + var/list/scorned_by = list() //who hates the plush, to remove external references on Destroy() + var/heartbroken = FALSE + var/vowbroken = FALSE + var/young = FALSE + var/mood_message + var/list/love_message + var/list/partner_message + var/list/heartbroken_message + var/list/vowbroken_message + var/list/parent_message + var/normal_desc + //--end of love :'(-- /obj/item/toy/plush/Initialize() . = ..() AddComponent(/datum/component/squeak, squeak_override) + //have we decided if Pinocchio goes in the blue or pink aisle yet? + if(gender == NEUTER) + if(prob(50)) + gender = FEMALE + else + gender = MALE + + love_message = list("\n[src] is so happy, \he could rip a seam!") + partner_message = list("\n[src] has a ring on \his finger! It says bound to my dear [partner].") + heartbroken_message = list("\n[src] looks so sad.") + vowbroken_message = list("\n[src] lost \his ring...") + parent_message = list("\n[src] can't remember what sleep is.") + + normal_desc = desc + /obj/item/toy/plush/Destroy() QDEL_NULL(grenade) + + //inform next of kin and... acquaintances + if(partner) + partner.bad_news(src) + partner = null + lover = null + else if(lover) + lover.bad_news(src) + lover = null + + if(paternal_parent) + paternal_parent.bad_news(src) + paternal_parent = null + + if(maternal_parent) + maternal_parent.bad_news(src) + maternal_parent = null + + if(plush_child) + plush_child.bad_news(src) + plush_child = null + + var/i + var/obj/item/toy/plush/P + for(i=1, i<=scorned.len, i++) + P = scorned[i] + P.bad_news(src) + scorned = null + + for(i=1, i<=scorned_by.len, i++) + P = scorned_by[i] + P.bad_news(src) + scorned_by = null + + //null remaining lists + squeak_override = null + + love_message = null + partner_message = null + heartbroken_message = null + vowbroken_message = null + parent_message = null + return ..() /obj/item/toy/plush/handle_atom_del(atom/A) @@ -66,8 +144,221 @@ var/turf/T = get_turf(user) log_game("[key_name(user)] added a grenade ([I.name]) to [src] at [COORD(T)].") return + if(istype(I, /obj/item/toy/plush)) + love(I, user) + return return ..() +/obj/item/toy/plush/proc/love(obj/item/toy/plush/Kisser, mob/living/user) //~<3 + var/chance = 100 //to steal a kiss, surely there's a 100% chance no-one would reject a plush such as I? + var/concern = 20 //perhaps something might cloud true love with doubt + var/loyalty = 30 //why should another get between us? + var/duty = 50 //conquering another's is what I live for + + //we are not catholic + if(young == TRUE || Kisser.young == TRUE) + user.show_message("[src] plays tag with [Kisser].", 1, + "They're happy.", 0) + Kisser.cheer_up() + cheer_up() + + //never again + else if(Kisser in scorned) + //message, visible, alternate message, neither visible nor audible + user.show_message("[src] rejects the advances of [Kisser]!", 1, + "That didn't feel like it worked.", 0) + else if(src in Kisser.scorned) + user.show_message("[Kisser] realises who [src] is and turns away.", 1, + "That didn't feel like it worked.", 0) + + //first comes love + else if(Kisser.lover != src && Kisser.partner != src) //cannot be lovers or married + if(Kisser.lover) //if the initiator has a lover + Kisser.lover.heartbreak(Kisser) //the old lover can get over the kiss-and-run whilst the kisser has some fun + chance -= concern //one heart already broken, what does another mean? + if(lover) //if the recipient has a lover + chance -= loyalty //mustn't... but those lips + if(partner) //if the recipient has a partner + chance -= duty //do we mate for life? + + if(prob(chance)) //did we bag a date? + user.visible_message("[user] makes [Kisser] kiss [src]!", + "You make [Kisser] kiss [src]!") + if(lover) //who cares for the past, we live in the present + lover.heartbreak(src) + new_lover(Kisser) + Kisser.new_lover(src) + else + user.show_message("[src] rejects the advances of [Kisser], maybe next time?", 1, + "That didn't feel like it worked, this time.", 0) + + //then comes marriage + else if(Kisser.lover == src && Kisser.partner != src) //need to be lovers (assumes loving is a two way street) but not married (also assumes similar) + user.visible_message("[user] pronounces [Kisser] and [src] married! D'aw.", + "You pronounce [Kisser] and [src] married!") + new_partner(Kisser) + Kisser.new_partner(src) + + //then comes a baby in a baby's carriage, or an adoption in an adoption's orphanage + else if(Kisser.partner == src && !plush_child) //the one advancing does not take ownership of the child and we have a one child policy in the toyshop + user.visible_message("[user] is going to break [Kisser] and [src] by bashing them like that.", + "[Kisser] passionately embraces [src] in your hands. Look away you perv!") + plop(Kisser) + user.visible_message("Something drops at the feet of [user].", + "The miracle of oh god did that just come out of [src]?!") + + //then comes protection, or abstinence if we are catholic + else if(Kisser.partner == src && plush_child) + user.visible_message("[user] makes [Kisser] nuzzle [src]!", + "You make [Kisser] nuzzle [src]!") + + //then oh fuck something unexpected happened + else + user.show_message("[Kisser] and [src] don't know what to do with one another.", 0) + +/obj/item/toy/plush/proc/heartbreak(obj/item/toy/plush/Brutus) + if(lover != Brutus) + to_chat(world, "lover != Brutus") + return //why are we considering someone we don't love? + + scorned.Add(Brutus) + Brutus.scorned_by(src) + + lover = null + Brutus.lover = null //feeling's mutual + + heartbroken = TRUE + mood_message = pick(heartbroken_message) + + if(partner == Brutus) //oh dear... + partner = null + Brutus.partner = null //it'd be weird otherwise + vowbroken = TRUE + mood_message = pick(vowbroken_message) + + update_desc() + +/obj/item/toy/plush/proc/scorned_by(obj/item/toy/plush/Outmoded) + scorned_by.Add(Outmoded) + +/obj/item/toy/plush/proc/new_lover(obj/item/toy/plush/Juliet) + if(lover == Juliet) + return //nice try + lover = Juliet + + cheer_up() + lover.cheer_up() + + mood_message = pick(love_message) + update_desc() + + if(partner) //who? + partner = null //more like who cares + +/obj/item/toy/plush/proc/new_partner(obj/item/toy/plush/Apple_of_my_eye) + if(partner == Apple_of_my_eye) + return //double marriage is just insecurity + if(lover != Apple_of_my_eye) + return //union not born out of love will falter + + partner = Apple_of_my_eye + + heal_memories() + partner.heal_memories() + + mood_message = pick(partner_message) + update_desc() + +/obj/item/toy/plush/proc/plop(obj/item/toy/plush/Daddy) + if(partner != Daddy) + return //we do not have bastards in our toyshop + + if(prob(50)) //it has my eyes + plush_child = new type(get_turf(loc)) + else //it has your eyes + plush_child = new Daddy.type(get_turf(loc)) + + plush_child.make_young(src, Daddy) + +/obj/item/toy/plush/proc/make_young(obj/item/toy/plush/Mama, obj/item/toy/plush/Dada) + if(Mama == Dada) + return //cloning is reserved for plants and spacemen + + maternal_parent = Mama + paternal_parent = Dada + young = TRUE + name = "[Mama] Jr" //Icelandic naming convention pending + normal_desc = "[src] is a little baby of [maternal_parent] and [paternal_parent]!" //original desc won't be used so the child can have moods + update_desc() + + Mama.mood_message = pick(Mama.parent_message) + Mama.update_desc() + Dada.mood_message = pick(Dada.parent_message) + Dada.update_desc() + +/obj/item/toy/plush/proc/bad_news(obj/item/toy/plush/Deceased) //cotton to cotton, sawdust to sawdust + var/is_that_letter_for_me = FALSE + if(partner == Deceased) //covers marriage + is_that_letter_for_me = TRUE + partner = null + lover = null + else if(lover == Deceased) //covers lovers + is_that_letter_for_me = TRUE + lover = null + + //covers children + if(maternal_parent == Deceased) + is_that_letter_for_me = TRUE + maternal_parent = null + + if(paternal_parent == Deceased) + is_that_letter_for_me = TRUE + paternal_parent = null + + //covers parents + if(plush_child == Deceased) + is_that_letter_for_me = TRUE + plush_child = null + + //covers bad memories + if(Deceased in scorned) + scorned.Remove(Deceased) + cheer_up() //what cold button eyes you have + + if(Deceased in scorned_by) + scorned_by.Remove(Deceased) + + //all references to the departed should be cleaned up by now + + if(is_that_letter_for_me) + heartbroken = TRUE + mood_message = pick(heartbroken_message) + update_desc() + +/obj/item/toy/plush/proc/cheer_up() //it'll be all right + if(!heartbroken) + return //you cannot make smile what is already + if(vowbroken) + return //it's a pretty big deal + + heartbroken = !heartbroken + + if(mood_message in heartbroken_message) + mood_message = null + update_desc() + +/obj/item/toy/plush/proc/heal_memories() //time fixes all wounds + if(!vowbroken) + vowbroken = !vowbroken + if(mood_message in vowbroken_message) + mood_message = null + cheer_up() + +/obj/item/toy/plush/proc/update_desc() + desc = normal_desc + if(mood_message) + desc += mood_message + /obj/item/toy/plush/carpplushie name = "space carp plushie" desc = "An adorable stuffed toy that resembles a space carp." @@ -88,6 +379,7 @@ desc = "An adorable plushie of the clockwork justiciar himself with new and improved spring arm action." icon_state = "plushvar" var/obj/item/toy/plush/narplush/clash_target + gender = MALE //he's a boy, right? /obj/item/toy/plush/plushvar/Moved() . = ..() @@ -173,6 +465,7 @@ desc = "A small stuffed doll of the elder god nar'sie. Who thought this was a good children's toy?" icon_state = "narplush" var/clashing + gender = FEMALE //it's canon if the toy is /obj/item/toy/plush/narplush/Moved() . = ..() @@ -198,7 +491,7 @@ /obj/item/toy/plush/nukeplushie name = "operative plushie" - desc = "An stuffed toy that resembles a syndicate nuclear operative. The tag claims operatives to be purely fictitious." + desc = "A stuffed toy that resembles a syndicate nuclear operative. The tag claims operatives to be purely fictitious." icon_state = "plushie_nuke" item_state = "plushie_nuke" attack_verb = list("shot", "nuked", "detonated") @@ -210,4 +503,5 @@ icon_state = "plushie_slime" item_state = "plushie_slime" attack_verb = list("blorbled", "slimed", "absorbed") - squeak_override = list('sound/effects/blobattack.ogg' = 1) \ No newline at end of file + squeak_override = list('sound/effects/blobattack.ogg' = 1) + gender = FEMALE //given all the jokes and drawings, I'm not sure the xenobiologists would make a slimeboy diff --git a/code/game/objects/items/pneumaticCannon.dm b/code/game/objects/items/pneumaticCannon.dm index b3960d1e5f..8baeee3550 100644 --- a/code/game/objects/items/pneumaticCannon.dm +++ b/code/game/objects/items/pneumaticCannon.dm @@ -198,8 +198,8 @@ return target var/x_o = (target.x - starting.x) var/y_o = (target.y - starting.y) - var/new_x = Clamp((starting.x + (x_o * range_multiplier)), 0, world.maxx) - var/new_y = Clamp((starting.y + (y_o * range_multiplier)), 0, world.maxy) + var/new_x = CLAMP((starting.x + (x_o * range_multiplier)), 0, world.maxx) + var/new_y = CLAMP((starting.y + (y_o * range_multiplier)), 0, world.maxy) var/turf/newtarget = locate(new_x, new_y, starting.z) return newtarget @@ -216,7 +216,7 @@ if(!src.tank) return to_chat(user, "You detach \the [thetank] from \the [src].") - src.tank.loc = get_turf(user) + src.tank.forceMove(user.drop_location()) user.put_in_hands(tank) src.tank = null if(!removing) @@ -265,7 +265,7 @@ /obj/item/pneumatic_cannon/pie/Initialize() . = ..() allowed_typecache = pie_typecache - + /obj/item/pneumatic_cannon/pie/selfcharge automatic = TRUE selfcharge = TRUE diff --git a/code/game/objects/items/powerfist.dm b/code/game/objects/items/powerfist.dm index f2f0a8b3e5..c55c35662d 100644 --- a/code/game/objects/items/powerfist.dm +++ b/code/game/objects/items/powerfist.dm @@ -11,7 +11,6 @@ throwforce = 10 throw_range = 7 w_class = WEIGHT_CLASS_NORMAL - origin_tech = "combat=5;powerstorage=3;syndicate=3" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 40) resistance_flags = FIRE_PROOF var/click_delay = 1.5 diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index e4485266b5..d2f1d2a31b 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -33,7 +33,7 @@ add_logs(user, M, "stunned", src, "(INTENT: [uppertext(user.a_intent)])") /obj/item/borg/cyborghug - name = "Hugging Module" + name = "hugging module" icon_state = "hugmodule" desc = "For when a someone really needs a hug." var/mode = 0 //0 = Hugs 1 = "Hug" 2 = Shock 3 = CRUSH @@ -336,6 +336,10 @@ cooldown = world.time + 600 log_game("[user.ckey]([user]) used an emagged Cyborg Harm Alarm in ([user.x],[user.y],[user.z])") +#define DISPENSE_LOLLIPOP_MODE 1 +#define THROW_LOLLIPOP_MODE 2 +#define THROW_GUMBALL_MODE 3 + /obj/item/borg/lollipop name = "lollipop fabricator" desc = "Reward good humans with this. Toggle in-module to switch between dispensing and high velocity ejection modes." @@ -343,8 +347,9 @@ var/candy = 30 var/candymax = 30 var/charge_delay = 10 - var/charging = 0 - var/mode = 1 + var/charging = FALSE + var/mode = DISPENSE_LOLLIPOP_MODE + var/firedelay = 0 var/hitspeed = 2 var/hitdamage = 0 @@ -379,10 +384,22 @@ var/obj/O = A if(O.density) return FALSE - new /obj/item/reagent_containers/food/snacks/lollipop(T) + + var/obj/item/reagent_containers/food/snacks/lollipop/L = new(T) + + var/into_hands = FALSE + if(ismob(A)) + var/mob/M = A + into_hands = M.put_in_hands(L) + candy-- check_amount() - to_chat(user, "Dispensing lollipop...") + + if(into_hands) + user.visible_message("[user] dispenses a lollipop into the hands of [A].", "You dispense a lollipop into the hands of [A].", "You hear a click.") + else + user.visible_message("[user] dispenses a lollipop.", "You dispense a lollipop.", "You hear a click.") + playsound(src.loc, 'sound/machines/click.ogg', 50, 1) return TRUE @@ -427,29 +444,33 @@ if(R.emagged) hitdamage = emaggedhitdamage switch(mode) - if(1) + if(DISPENSE_LOLLIPOP_MODE) if(!proximity) return FALSE dispense(target, user) - if(2) + if(THROW_LOLLIPOP_MODE) shootL(target, user, click_params) - if(3) + if(THROW_GUMBALL_MODE) shootG(target, user, click_params) hitdamage = initial(hitdamage) /obj/item/borg/lollipop/attack_self(mob/living/user) switch(mode) - if(1) - mode++ + if(DISPENSE_LOLLIPOP_MODE) + mode = THROW_LOLLIPOP_MODE to_chat(user, "Module is now throwing lollipops.") - if(2) - mode++ + if(THROW_LOLLIPOP_MODE) + mode = THROW_GUMBALL_MODE to_chat(user, "Module is now blasting gumballs.") - if(3) - mode = 1 + if(THROW_GUMBALL_MODE) + mode = DISPENSE_LOLLIPOP_MODE to_chat(user, "Module is now dispensing lollipops.") ..() +#undef DISPENSE_LOLLIPOP_MODE +#undef THROW_LOLLIPOP_MODE +#undef THROW_GUMBALL_MODE + /obj/item/ammo_casing/caseless/gumball name = "Gumball" desc = "Why are you seeing this?!" @@ -616,7 +637,7 @@ continue usage += projectile_tick_speed_ecost usage += (tracked[I] * projectile_damage_tick_ecost_coefficient) - energy = Clamp(energy - usage, 0, maxenergy) + energy = CLAMP(energy - usage, 0, maxenergy) if(energy <= 0) deactivate_field() visible_message("[src] blinks \"ENERGY DEPLETED\".") @@ -626,7 +647,7 @@ if(iscyborg(host.loc)) host = host.loc else - energy = Clamp(energy + energy_recharge, 0, maxenergy) + energy = CLAMP(energy + energy_recharge, 0, maxenergy) return if((host.cell.charge >= (host.cell.maxcharge * cyborg_cell_critical_percentage)) && (energy < maxenergy)) host.cell.use(energy_recharge*energy_recharge_cyborg_drain_coefficient) @@ -655,7 +676,7 @@ /obj/item/borg/sight/xray - name = "\proper x-ray Vision" + name = "\proper x-ray vision" icon = 'icons/obj/decals.dmi' icon_state = "securearea" sight_mode = BORGXRAY diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index 09e3ccdeb0..339b7fbf4b 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -69,7 +69,7 @@ if(!l_arm && !r_arm && !l_leg && !r_leg && !chest && !head) if (M.use(1)) var/obj/item/ed209_assembly/B = new /obj/item/ed209_assembly - B.loc = get_turf(src) + B.forceMove(drop_location()) to_chat(user, "You arm the robot frame.") var/holding_this = user.get_inactive_held_item()==src qdel(src) @@ -227,7 +227,7 @@ O.job = "Cyborg" O.cell = chest.cell - chest.cell.loc = O + chest.cell.forceMove(O) chest.cell = null W.forceMove(O)//Should fix cybros run time erroring when blown up. It got deleted before, along with the frame. if(O.mmi) //we delete the mmi created by robot/New() @@ -271,7 +271,7 @@ O.cell = chest.cell - chest.cell.loc = O + chest.cell.forceMove(O) chest.cell = null O.locked = panel_locked O.job = "Cyborg" diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 59eef9a170..6f852aacd3 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -6,7 +6,6 @@ desc = "Protected by FRM." icon = 'icons/obj/module.dmi' icon_state = "cyborg_upgrade" - origin_tech = "programming=2" var/locked = FALSE var/installed = 0 var/require_module = 0 @@ -72,7 +71,6 @@ desc = "Used to kick in a cyborg's VTEC systems, increasing their speed." icon_state = "cyborg_upgrade2" require_module = 1 - origin_tech = "engineering=4;materials=5;programming=4" /obj/item/borg/upgrade/vtec/action(mob/living/silicon/robot/R) if(..()) @@ -92,7 +90,6 @@ icon_state = "cyborg_upgrade3" require_module = 1 module_type = /obj/item/robot_module/security - origin_tech = "engineering=4;powerstorage=4;combat=4" /obj/item/borg/upgrade/disablercooler/action(mob/living/silicon/robot/R) if(..()) @@ -115,7 +112,6 @@ name = "ion thruster upgrade" desc = "An energy-operated thruster system for cyborgs." icon_state = "cyborg_upgrade3" - origin_tech = "engineering=4;powerstorage=4" /obj/item/borg/upgrade/thrusters/action(mob/living/silicon/robot/R) if(..()) @@ -134,7 +130,6 @@ icon_state = "cyborg_upgrade3" require_module = 1 module_type = /obj/item/robot_module/miner - origin_tech = "engineering=4;materials=5" /obj/item/borg/upgrade/ddrill/action(mob/living/silicon/robot/R) if(..()) @@ -156,7 +151,6 @@ icon_state = "cyborg_upgrade3" require_module = 1 module_type = /obj/item/robot_module/miner - origin_tech = "engineering=4;materials=4;bluespace=4" /obj/item/borg/upgrade/soh/action(mob/living/silicon/robot/R) if(..()) @@ -175,7 +169,6 @@ desc = "Unlocks the hidden, deadlier functions of a cyborg." icon_state = "cyborg_upgrade3" require_module = 1 - origin_tech = "combat=4;syndicate=1" /obj/item/borg/upgrade/syndicate/action(mob/living/silicon/robot/R) if(..()) @@ -195,7 +188,6 @@ resistance_flags = LAVA_PROOF | FIRE_PROOF require_module = 1 module_type = /obj/item/robot_module/miner - origin_tech = "engineering=4;materials=4;plasmatech=4" /obj/item/borg/upgrade/lavaproof/action(mob/living/silicon/robot/R) if(..()) @@ -314,7 +306,6 @@ icon_state = "cyborg_upgrade3" require_module = 1 module_type = /obj/item/robot_module/medical - origin_tech = null var/list/additional_reagents = list() /obj/item/borg/upgrade/hypospray/action(mob/living/silicon/robot/R) @@ -333,7 +324,6 @@ to treat a wider range of conditions and problems." additional_reagents = list("mannitol", "oculine", "inacusiate", "mutadone", "haloperidol") - origin_tech = "programming=5;engineering=4;biotech=5" /obj/item/borg/upgrade/hypospray/high_strength name = "medical cyborg high-strength hypospray" @@ -341,13 +331,11 @@ stronger versions of existing chemicals." additional_reagents = list("oxandrolone", "sal_acid", "rezadone", "pen_acid") - origin_tech = "programming=5;engineering=5;biotech=6" /obj/item/borg/upgrade/piercing_hypospray name = "cyborg piercing hypospray" desc = "An upgrade to a cyborg's hypospray, allowing it to \ pierce armor and thick material." - origin_tech = "materials=5;engineering=7;combat=3" icon_state = "cyborg_upgrade3" /obj/item/borg/upgrade/piercing_hypospray/action(mob/living/silicon/robot/R) @@ -371,7 +359,6 @@ icon_state = "cyborg_upgrade3" require_module = 1 module_type = /obj/item/robot_module/medical - origin_tech = "programming=4;engineering=6;materials=5;powerstorage=5;biotech=5" /obj/item/borg/upgrade/defib/action(mob/living/silicon/robot/R) if(..()) @@ -387,7 +374,6 @@ name = "B.O.R.I.S. module" desc = "Bluespace Optimized Remote Intelligence Synchronization. An uplink device which takes the place of an MMI in cyborg endoskeletons, creating a robotic shell controlled by an AI." icon_state = "boris" - origin_tech = "engineering=4;magnets=4;programming=4" /obj/item/borg/upgrade/ai/action(mob/living/silicon/robot/R) if(..()) diff --git a/code/game/objects/items/scrolls.dm b/code/game/objects/items/scrolls.dm index 2fc8e8559c..07f6edb828 100644 --- a/code/game/objects/items/scrolls.dm +++ b/code/game/objects/items/scrolls.dm @@ -8,13 +8,11 @@ item_state = "paper" throw_speed = 3 throw_range = 7 - origin_tech = "bluespace=6" resistance_flags = FLAMMABLE /obj/item/teleportation_scroll/apprentice name = "lesser scroll of teleportation" uses = 1 - origin_tech = "bluespace=5" diff --git a/code/game/objects/items/sharpener.dm b/code/game/objects/items/sharpener.dm index fb25cb1d76..93056adc99 100644 --- a/code/game/objects/items/sharpener.dm +++ b/code/game/objects/items/sharpener.dm @@ -35,14 +35,14 @@ if(TH.force_wielded > initial(TH.force_wielded)) to_chat(user, "[TH] has already been refined before. It cannot be sharpened further!") return - TH.force_wielded = Clamp(TH.force_wielded + increment, 0, max)//wieldforce is increased since normal force wont stay + TH.force_wielded = CLAMP(TH.force_wielded + increment, 0, max)//wieldforce is increased since normal force wont stay if(I.force > initial(I.force)) to_chat(user, "[I] has already been refined before. It cannot be sharpened further!") return user.visible_message("[user] sharpens [I] with [src]!", "You sharpen [I], making it much more deadly than before.") I.sharpness = IS_SHARP_ACCURATE - I.force = Clamp(I.force + increment, 0, max) - I.throwforce = Clamp(I.throwforce + increment, 0, max) + I.force = CLAMP(I.force + increment, 0, max) + I.throwforce = CLAMP(I.throwforce + increment, 0, max) I.name = "[prefix] [I.name]" name = "worn out [name]" desc = "[desc] At least, it used to." diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm index 83e8715c54..57306f498c 100644 --- a/code/game/objects/items/shields.dm +++ b/code/game/objects/items/shields.dm @@ -17,7 +17,6 @@ throw_range = 3 w_class = WEIGHT_CLASS_BULKY materials = list(MAT_GLASS=7500, MAT_METAL=1000) - origin_tech = "materials=3;combat=4" attack_verb = list("shoved", "bashed") var/cooldown = 0 //shield bash cooldown. based on world.time @@ -54,7 +53,6 @@ lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi' materials = list() - origin_tech = "materials=1;combat=3;biotech=2" resistance_flags = FLAMMABLE block_chance = 30 @@ -70,7 +68,6 @@ throw_speed = 3 throw_range = 5 w_class = WEIGHT_CLASS_TINY - origin_tech = "materials=4;magnets=5;syndicate=6" attack_verb = list("shoved", "bashed") var/active = 0 @@ -110,7 +107,6 @@ icon_state = "teleriot0" lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi' - origin_tech = "materials=3;combat=4;engineering=4" slot_flags = null force = 3 throwforce = 3 diff --git a/code/game/objects/items/shooting_range.dm b/code/game/objects/items/shooting_range.dm index 6803d6bb7b..586d21555c 100644 --- a/code/game/objects/items/shooting_range.dm +++ b/code/game/objects/items/shooting_range.dm @@ -23,7 +23,7 @@ /obj/item/target/Move() ..() if(pinnedLoc) - pinnedLoc.loc = loc + pinnedLoc.forceMove(loc) /obj/item/target/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/weldingtool)) diff --git a/code/game/objects/items/singularityhammer.dm b/code/game/objects/items/singularityhammer.dm index a0a9783519..38a5ba4cec 100644 --- a/code/game/objects/items/singularityhammer.dm +++ b/code/game/objects/items/singularityhammer.dm @@ -13,7 +13,6 @@ throw_range = 1 w_class = WEIGHT_CLASS_HUGE var/charged = 5 - origin_tech = "combat=4;bluespace=4;plasmatech=7" armor = list(melee = 50, bullet = 50, laser = 50, energy = 0, bomb = 50, bio = 0, rad = 0, fire = 100, acid = 100) resistance_flags = FIRE_PROOF | ACID_PROOF force_string = "LORD SINGULOTH HIMSELF" @@ -84,7 +83,6 @@ throwforce = 30 throw_range = 7 w_class = WEIGHT_CLASS_HUGE - origin_tech = "combat=4;powerstorage=7" /obj/item/twohanded/mjollnir/proc/shock(mob/living/target) target.Stun(60) diff --git a/code/game/objects/items/stacks/bscrystal.dm b/code/game/objects/items/stacks/bscrystal.dm index 1af4104185..978966706e 100644 --- a/code/game/objects/items/stacks/bscrystal.dm +++ b/code/game/objects/items/stacks/bscrystal.dm @@ -6,10 +6,10 @@ icon_state = "bluespace_crystal" w_class = WEIGHT_CLASS_TINY materials = list(MAT_BLUESPACE=MINERAL_MATERIAL_AMOUNT) - origin_tech = "bluespace=6;materials=3" points = 50 var/blink_range = 8 // The teleport range when crushed/thrown at someone. refined_type = /obj/item/stack/sheet/bluespace_crystal + grind_results = list("bluespace" = 2) /obj/item/ore/bluespace_crystal/refined name = "refined bluespace crystal" @@ -45,11 +45,11 @@ /obj/item/ore/bluespace_crystal/artificial name = "artificial bluespace crystal" desc = "An artificially made bluespace crystal, it looks delicate." - origin_tech = "bluespace=3;plasmatech=4" materials = list(MAT_BLUESPACE=MINERAL_MATERIAL_AMOUNT / 2) blink_range = 4 // Not as good as the organic stuff! points = 0 //nice try refined_type = null + grind_results = list("bluespace" = 1, "silicon" = 2) //Polycrystals, aka stacks /obj/item/stack/sheet/bluespace_crystal @@ -57,10 +57,10 @@ icon = 'icons/obj/telescience.dmi' icon_state = "polycrystal" desc = "A stable polycrystal, made of fused-together bluespace crystals. You could probably break one off." - origin_tech = "bluespace=6;materials=3" materials = list(MAT_BLUESPACE=MINERAL_MATERIAL_AMOUNT) attack_verb = list("bluespace polybashed", "bluespace polybattered", "bluespace polybludgeoned", "bluespace polythrashed", "bluespace polysmashed") novariants = TRUE + grind_results = list("bluespace" = 2) var/crystal_type = /obj/item/ore/bluespace_crystal/refined /obj/item/stack/sheet/bluespace_crystal/attack_self(mob/user)// to prevent the construction menu from ever happening diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 6c073f4b69..7a0f85a8f2 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -110,8 +110,12 @@ lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' heal_brute = 40 - origin_tech = "biotech=2" self_delay = 20 + grind_results = list("styptic_powder" = 1) + +/obj/item/stack/medical/bruise_pack/suicide_act(mob/user) + user.visible_message("[user] is bludgeoning [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!") + return (BRUTELOSS) /obj/item/stack/medical/gauze name = "medical gauze" @@ -143,5 +147,5 @@ lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' heal_burn = 40 - origin_tech = "biotech=2" self_delay = 20 + grind_results = list("silver_sulfadiazine" = 1) diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index c6a5d074e7..8cc6a60efa 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -19,10 +19,10 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \ singular_name = "glass sheet" icon_state = "sheet-glass" materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT) - origin_tech = "materials=1" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 100) + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/glass + grind_results = list("silicon" = 1) /obj/item/stack/sheet/glass/cyborg materials = list() @@ -77,10 +77,10 @@ GLOBAL_LIST_INIT(pglass_recipes, list ( \ singular_name = "plasma glass sheet" icon_state = "sheet-pglass" materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT/2, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) - origin_tech = "plasmatech=2;materials=2" armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 75, "acid" = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/plasmaglass + grind_results = list("silicon" = 1, "plasma" = 1) /obj/item/stack/sheet/plasmaglass/fifty amount = 50 @@ -127,10 +127,10 @@ GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \ singular_name = "reinforced glass sheet" icon_state = "sheet-rglass" materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT/2, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) - origin_tech = "materials=2" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 100) + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 70, acid = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/rglass + grind_results = list("silicon" = 1, "iron" = 1) /obj/item/stack/sheet/rglass/attackby(obj/item/W, mob/user, params) add_fingerprint(user) @@ -168,10 +168,10 @@ GLOBAL_LIST_INIT(prglass_recipes, list ( \ singular_name = "reinforced plasma glass sheet" icon_state = "sheet-prglass" materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT/2, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) - origin_tech = "materials=2;plasmatech=2" armor = list("melee" = 20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/plasmarglass + grind_results = list("silicon" = 1, "plasma" = 1, "iron" = 1) /obj/item/stack/sheet/plasmarglass/Initialize(mapload, new_amount, merge = TRUE) recipes = GLOB.prglass_recipes @@ -205,6 +205,7 @@ GLOBAL_LIST_INIT(prglass_recipes, list ( \ /obj/item/shard/Initialize() . = ..() + AddComponent(/datum/component/caltrop, force) icon_state = pick("large", "medium", "small") switch(icon_state) if("small") @@ -254,30 +255,7 @@ GLOBAL_LIST_INIT(prglass_recipes, list ( \ else return ..() -/obj/item/shard/Crossed(mob/AM) - if(istype(AM) && has_gravity(loc)) +/obj/item/shard/Crossed(mob/living/L) + if(istype(L) && has_gravity(loc)) playsound(loc, 'sound/effects/glass_step.ogg', 50, 1) - if(ishuman(AM)) - var/mob/living/carbon/human/H = AM - if(PIERCEIMMUNE in H.dna.species.species_traits) - return - var/picked_def_zone = pick("l_leg", "r_leg") - var/obj/item/bodypart/O = H.get_bodypart(picked_def_zone) - if(!istype(O)) - return - if(O.status == BODYPART_ROBOTIC) - return - var/feetCover = (H.wear_suit && H.wear_suit.body_parts_covered & FEET) || (H.w_uniform && H.w_uniform.body_parts_covered & FEET) - if(H.shoes || feetCover || H.movement_type & FLYING || H.buckled) - return - H.apply_damage(5, BRUTE, picked_def_zone) - if(cooldown < world.time - 10) //cooldown to avoid message spam. - if(!H.incapacitated()) - H.visible_message("[H] steps in the broken glass!", \ - "You step in the broken glass!") - else - H.visible_message("[H] slides on the broken glass!", \ - "You slide on the broken glass!") - - cooldown = world.time - H.Knockdown(60) + . = ..() diff --git a/code/game/objects/items/stacks/sheets/leather.dm b/code/game/objects/items/stacks/sheets/leather.dm index 4ad576fe34..60f6560d16 100644 --- a/code/game/objects/items/stacks/sheets/leather.dm +++ b/code/game/objects/items/stacks/sheets/leather.dm @@ -1,7 +1,6 @@ /obj/item/stack/sheet/animalhide name = "hide" desc = "Something went wrong." - origin_tech = "biotech=3" novariants = TRUE /obj/item/stack/sheet/animalhide/human @@ -96,7 +95,6 @@ GLOBAL_LIST_INIT(xeno_recipes, list ( \ singular_name = "alien hide piece" icon = 'icons/mob/alien.dmi' icon_state = "chitin" - origin_tech = null novariants = TRUE /obj/item/xenos_claw @@ -104,28 +102,24 @@ GLOBAL_LIST_INIT(xeno_recipes, list ( \ desc = "The claw of a terrible creature." icon = 'icons/mob/alien.dmi' icon_state = "claw" - origin_tech = null /obj/item/weed_extract name = "weed extract" desc = "A piece of slimy, purplish weed." icon = 'icons/mob/alien.dmi' icon_state = "weed_extract" - origin_tech = null /obj/item/stack/sheet/hairlesshide name = "hairless hide" desc = "This hide was stripped of its hair, but still needs washing and tanning." singular_name = "hairless hide piece" icon_state = "sheet-hairlesshide" - origin_tech = null /obj/item/stack/sheet/wetleather name = "wet leather" desc = "This leather has been cleaned but still needs to be dried." singular_name = "wet leather piece" icon_state = "sheet-wetleather" - origin_tech = null var/wetness = 30 //Reduced when exposed to high temperautres var/drying_threshold_temperature = 500 //Kelvin to start drying @@ -137,7 +131,6 @@ GLOBAL_LIST_INIT(xeno_recipes, list ( \ desc = "The by-product of mob grinding." singular_name = "leather piece" icon_state = "sheet-leather" - origin_tech = "materials=2" GLOBAL_LIST_INIT(leather_recipes, list ( \ new/datum/stack_recipe("wallet", /obj/item/storage/wallet, 1), \ @@ -163,7 +156,6 @@ GLOBAL_LIST_INIT(leather_recipes, list ( \ desc = "Long stringy filaments which presumably came from a watcher's wings." singular_name = "watcher sinew" icon_state = "sinew" - origin_tech = "biotech=4" novariants = TRUE diff --git a/code/game/objects/items/stacks/sheets/light.dm b/code/game/objects/items/stacks/sheets/light.dm index a02d182f1c..051d8326b8 100644 --- a/code/game/objects/items/stacks/sheets/light.dm +++ b/code/game/objects/items/stacks/sheets/light.dm @@ -1,37 +1,38 @@ -/obj/item/stack/light_w - name = "wired glass tile" - singular_name = "wired glass floor tile" - desc = "A glass tile, which is wired, somehow." - icon = 'icons/obj/tiles.dmi' - icon_state = "glass_wire" - w_class = WEIGHT_CLASS_NORMAL - force = 3 - throwforce = 5 - throw_speed = 3 - throw_range = 7 +/obj/item/stack/light_w + name = "wired glass tile" + singular_name = "wired glass floor tile" + desc = "A glass tile, which is wired, somehow." + icon = 'icons/obj/tiles.dmi' + icon_state = "glass_wire" + w_class = WEIGHT_CLASS_NORMAL + force = 3 + throwforce = 5 + throw_speed = 3 + throw_range = 7 flags_1 = CONDUCT_1 - max_amount = 60 - -/obj/item/stack/light_w/attackby(obj/item/O, mob/user, params) - + max_amount = 60 + grind_results = list("silicon" = 1, "copper" = 1) + +/obj/item/stack/light_w/attackby(obj/item/O, mob/user, params) + if(istype(O, /obj/item/wirecutters)) - var/obj/item/stack/cable_coil/CC = new (user.loc) - CC.amount = 5 - CC.add_fingerprint(user) - amount-- - var/obj/item/stack/sheet/glass/G = new (user.loc) - G.add_fingerprint(user) - if(amount <= 0) - qdel(src) - - else if(istype(O, /obj/item/stack/sheet/metal)) - var/obj/item/stack/sheet/metal/M = O - if (M.use(1)) - use(1) - var/obj/item/L = new /obj/item/stack/tile/light(user.loc) - to_chat(user, "You make a light tile.") - L.add_fingerprint(user) - else - to_chat(user, "You need one metal sheet to finish the light tile!") - else - return ..() + var/obj/item/stack/cable_coil/CC = new (user.loc) + CC.amount = 5 + CC.add_fingerprint(user) + amount-- + var/obj/item/stack/sheet/glass/G = new (user.loc) + G.add_fingerprint(user) + if(amount <= 0) + qdel(src) + + else if(istype(O, /obj/item/stack/sheet/metal)) + var/obj/item/stack/sheet/metal/M = O + if (M.use(1)) + use(1) + var/obj/item/L = new /obj/item/stack/tile/light(user.loc) + to_chat(user, "You make a light tile.") + L.add_fingerprint(user) + else + to_chat(user, "You need one metal sheet to finish the light tile!") + else + return ..() diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index 7beb11b6e1..e44366daec 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -46,7 +46,6 @@ GLOBAL_LIST_INIT(sandstone_recipes, list ( \ icon_state = "sheet-sandstone" throw_speed = 3 throw_range = 5 - origin_tech = "materials=1" materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT) sheettype = "sandstone" @@ -67,7 +66,6 @@ GLOBAL_LIST_INIT(sandstone_recipes, list ( \ icon_state = "sandbags" singular_name = "sandbag" layer = LOW_ITEM_LAYER - origin_tech = "materials=2" novariants = TRUE GLOBAL_LIST_INIT(sandbag_recipes, list ( \ @@ -102,7 +100,6 @@ GLOBAL_LIST_INIT(sandbag_recipes, list ( \ name = "diamond" icon_state = "sheet-diamond" singular_name = "diamond" - origin_tech = "materials=6" sheettype = "diamond" materials = list(MAT_DIAMOND=MINERAL_MATERIAL_AMOUNT) novariants = TRUE @@ -126,10 +123,10 @@ GLOBAL_LIST_INIT(diamond_recipes, list ( \ name = "uranium" icon_state = "sheet-uranium" singular_name = "uranium sheet" - origin_tech = "materials=5" sheettype = "uranium" materials = list(MAT_URANIUM=MINERAL_MATERIAL_AMOUNT) novariants = TRUE + grind_results = list("uranium" = 20) GLOBAL_LIST_INIT(uranium_recipes, list ( \ new/datum/stack_recipe("uranium door", /obj/structure/mineral_door/uranium, 10, one_per_turf = 1, on_floor = 1), \ @@ -149,11 +146,11 @@ GLOBAL_LIST_INIT(uranium_recipes, list ( \ name = "solid plasma" icon_state = "sheet-plasma" singular_name = "plasma sheet" - origin_tech = "plasmatech=2;materials=2" sheettype = "plasma" resistance_flags = FLAMMABLE max_integrity = 100 materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT) + grind_results = list("plasma" = 20) GLOBAL_LIST_INIT(plasma_recipes, list ( \ new/datum/stack_recipe("plasma door", /obj/structure/mineral_door/transparent/plasma, 10, one_per_turf = 1, on_floor = 1), \ @@ -185,9 +182,9 @@ GLOBAL_LIST_INIT(plasma_recipes, list ( \ name = "gold" icon_state = "sheet-gold" singular_name = "gold bar" - origin_tech = "materials=4" sheettype = "gold" materials = list(MAT_GOLD=MINERAL_MATERIAL_AMOUNT) + grind_results = list("gold" = 20) GLOBAL_LIST_INIT(gold_recipes, list ( \ new/datum/stack_recipe("golden door", /obj/structure/mineral_door/gold, 10, one_per_turf = 1, on_floor = 1), \ @@ -211,9 +208,9 @@ GLOBAL_LIST_INIT(gold_recipes, list ( \ name = "silver" icon_state = "sheet-silver" singular_name = "silver bar" - origin_tech = "materials=4" sheettype = "silver" materials = list(MAT_SILVER=MINERAL_MATERIAL_AMOUNT) + grind_results = list("silver" = 20) GLOBAL_LIST_INIT(silver_recipes, list ( \ new/datum/stack_recipe("silver door", /obj/structure/mineral_door/silver, 10, one_per_turf = 1, on_floor = 1), \ @@ -236,10 +233,10 @@ GLOBAL_LIST_INIT(silver_recipes, list ( \ name = "bananium" icon_state = "sheet-clown" singular_name = "bananium sheet" - origin_tech = "materials=4" sheettype = "clown" materials = list(MAT_BANANIUM=MINERAL_MATERIAL_AMOUNT) novariants = TRUE + grind_results = list("banana" = 20) GLOBAL_LIST_INIT(clown_recipes, list ( \ new/datum/stack_recipe("bananium tile", /obj/item/stack/tile/mineral/bananium, 1, 4, 20), \ @@ -262,7 +259,6 @@ GLOBAL_LIST_INIT(clown_recipes, list ( \ w_class = WEIGHT_CLASS_NORMAL throw_speed = 1 throw_range = 3 - origin_tech = "materials=4" sheettype = "titanium" materials = list(MAT_TITANIUM=MINERAL_MATERIAL_AMOUNT) @@ -290,7 +286,6 @@ GLOBAL_LIST_INIT(titanium_recipes, list ( \ w_class = WEIGHT_CLASS_NORMAL throw_speed = 1 throw_range = 3 - origin_tech = "materials=4" sheettype = "plastitanium" materials = list(MAT_TITANIUM=2000, MAT_PLASMA=2000) @@ -312,7 +307,7 @@ GLOBAL_LIST_INIT(plastitanium_recipes, list ( \ singular_name = "snow block" force = 1 throwforce = 2 - origin_tech = "materials=1" + grind_results = list("ice" = 20) GLOBAL_LIST_INIT(snow_recipes, list ( \ new/datum/stack_recipe("Snow Wall", /turf/closed/wall/mineral/snow, 5, one_per_turf = 1, on_floor = 1), \ @@ -333,7 +328,6 @@ GLOBAL_LIST_INIT(snow_recipes, list ( \ name = "enriched uranium" icon_state = "sheet-enruranium" singular_name = "enriched uranium sheet" - origin_tech = "materials=6" materials = list(MAT_URANIUM=3000) /* @@ -347,7 +341,6 @@ GLOBAL_LIST_INIT(adamantine_recipes, list( name = "adamantine" icon_state = "sheet-adamantine" singular_name = "adamantine sheet" - origin_tech = "materials=4" /obj/item/stack/sheet/mineral/adamantine/Initialize(mapload, new_amount, merge = TRUE) recipes = GLOB.adamantine_recipes @@ -360,7 +353,6 @@ GLOBAL_LIST_INIT(adamantine_recipes, list( name = "mythril" icon_state = "sheet-mythril" singular_name = "mythril sheet" - origin_tech = "materials=4" novariants = TRUE /* @@ -371,7 +363,6 @@ GLOBAL_LIST_INIT(adamantine_recipes, list( icon = 'icons/obj/abductor.dmi' icon_state = "sheet-abductor" singular_name = "alien alloy sheet" - origin_tech = "materials=6;abductor=1" sheettype = "abductor" GLOBAL_LIST_INIT(abductor_recipes, list ( \ diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 5eb85379b7..36b9cf210a 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -18,14 +18,24 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \ new/datum/stack_recipe("stool", /obj/structure/chair/stool, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("bar stool", /obj/structure/chair/stool/bar, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("chair", /obj/structure/chair, one_per_turf = TRUE, on_floor = TRUE), \ - new/datum/stack_recipe("swivel chair", /obj/structure/chair/office/dark, 5, one_per_turf = TRUE, on_floor = TRUE), \ - new/datum/stack_recipe("comfy chair", /obj/structure/chair/comfy/beige, 2, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("bed", /obj/structure/bed, 2, one_per_turf = TRUE, on_floor = TRUE), \ new /datum/stack_recipe("sofa (middle)", /obj/structure/chair/sofa, one_per_turf = TRUE, on_floor = TRUE), \ new /datum/stack_recipe("sofa (left)", /obj/structure/chair/sofa/left, one_per_turf = TRUE, on_floor = TRUE), \ new /datum/stack_recipe("sofa (right)", /obj/structure/chair/sofa/right, one_per_turf = TRUE, on_floor = TRUE), \ new /datum/stack_recipe("sofa (corner)", /obj/structure/chair/sofa/corner, one_per_turf = TRUE, on_floor = TRUE), \ null, \ + new/datum/stack_recipe_list("office chairs", list( \ + new/datum/stack_recipe("dark office chair", /obj/structure/chair/office/dark, 5, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("light office chair", /obj/structure/chair/office/light, 5, one_per_turf = TRUE, on_floor = TRUE), \ + )), \ + new/datum/stack_recipe_list("comfy chairs", list( \ + new/datum/stack_recipe("beige comfy chair", /obj/structure/chair/comfy/beige, 2, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("black comfy chair", /obj/structure/chair/comfy/black, 2, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("brown comfy chair", /obj/structure/chair/comfy/brown, 2, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("lime comfy chair", /obj/structure/chair/comfy/lime, 2, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("teal comfy chair", /obj/structure/chair/comfy/teal, 2, one_per_turf = TRUE, on_floor = TRUE), \ + )), \ + null, \ new/datum/stack_recipe("rack parts", /obj/item/rack_parts), \ new/datum/stack_recipe("closet", /obj/structure/closet, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE), \ null, \ @@ -39,7 +49,27 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \ new/datum/stack_recipe("computer frame", /obj/structure/frame/computer, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("modular console", /obj/machinery/modular_computer/console/buildable/, 10, time = 25, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("machine frame", /obj/structure/frame/machine, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \ - new/datum/stack_recipe("airlock assembly", /obj/structure/door_assembly, 4, time = 50, one_per_turf = TRUE, on_floor = TRUE), \ + null, \ + new /datum/stack_recipe_list("airlock assemblies", list( \ + new /datum/stack_recipe("standard airlock assembly", /obj/structure/door_assembly, 4, time = 50, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("public airlock assembly", /obj/structure/door_assembly/door_assembly_public, 4, time = 50, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("command airlock assembly", /obj/structure/door_assembly/door_assembly_com, 4, time = 50, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("security airlock assembly", /obj/structure/door_assembly/door_assembly_sec, 4, time = 50, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("engineering airlock assembly", /obj/structure/door_assembly/door_assembly_eng, 4, time = 50, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("mining airlock assembly", /obj/structure/door_assembly/door_assembly_min, 4, time = 50, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("atmospherics airlock assembly", /obj/structure/door_assembly/door_assembly_atmo, 4, time = 50, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("research airlock assembly", /obj/structure/door_assembly/door_assembly_research, 4, time = 50, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("freezer airlock assembly", /obj/structure/door_assembly/door_assembly_fre, 4, time = 50, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("science airlock assembly", /obj/structure/door_assembly/door_assembly_science, 4, time = 50, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("medical airlock assembly", /obj/structure/door_assembly/door_assembly_med, 4, time = 50, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("virology airlock assembly", /obj/structure/door_assembly/door_assembly_viro, 4, time = 50, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("maintenance airlock assembly", /obj/structure/door_assembly/door_assembly_mai, 4, time = 50, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("external airlock assembly", /obj/structure/door_assembly/door_assembly_ext, 4, time = 50, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("external maintenance airlock assembly", /obj/structure/door_assembly/door_assembly_extmai, 4, time = 50, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("airtight hatch assembly", /obj/structure/door_assembly/door_assembly_hatch, 4, time = 50, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("maintenance hatch assembly", /obj/structure/door_assembly/door_assembly_mhatch, 4, time = 50, one_per_turf = 1, on_floor = 1), \ + )), \ + null, \ new/datum/stack_recipe("firelock frame", /obj/structure/firelock_frame, 3, time = 50, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("turret frame", /obj/machinery/porta_turret_construct, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("meatspike frame", /obj/structure/kitchenspike_frame, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \ @@ -67,9 +97,9 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \ materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT) throwforce = 10 flags_1 = CONDUCT_1 - origin_tech = "materials=1" resistance_flags = FIRE_PROOF merge_type = /obj/item/stack/sheet/metal + grind_results = list("iron" = 20) /obj/item/stack/sheet/metal/ratvar_act() new /obj/item/stack/tile/brass(loc, amount) @@ -103,6 +133,11 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \ GLOBAL_LIST_INIT(plasteel_recipes, list ( \ new/datum/stack_recipe("AI core", /obj/structure/AIcore, 4, time = 50, one_per_turf = TRUE), \ new/datum/stack_recipe("bomb assembly", /obj/machinery/syndicatebomb/empty, 10, time = 50), \ + null, \ + new /datum/stack_recipe_list("airlock assemblies", list( \ + new/datum/stack_recipe("high security airlock assembly", /obj/structure/door_assembly/door_assembly_highsecurity, 6, time = 50, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("vault door assembly", /obj/structure/door_assembly/door_assembly_vault, 8, time = 50, one_per_turf = 1, on_floor = 1), \ + )), \ )) /obj/item/stack/sheet/plasteel @@ -114,10 +149,10 @@ GLOBAL_LIST_INIT(plasteel_recipes, list ( \ materials = list(MAT_METAL=2000, MAT_PLASMA=2000) throwforce = 10 flags_1 = CONDUCT_1 - origin_tech = "materials=2" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 80) resistance_flags = FIRE_PROOF merge_type = /obj/item/stack/sheet/plasteel + grind_results = list("iron" = 20, "plasma" = 20) /obj/item/stack/sheet/plasteel/Initialize(mapload, new_amount, merge = TRUE) recipes = GLOB.plasteel_recipes @@ -164,12 +199,12 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \ singular_name = "wood plank" icon_state = "sheet-wood" icon = 'icons/obj/stack_objects.dmi' - origin_tech = "materials=1;biotech=1" sheettype = "wood" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 0) resistance_flags = FLAMMABLE merge_type = /obj/item/stack/sheet/mineral/wood novariants = TRUE + grind_results = list("carbon" = 20) /obj/item/stack/sheet/mineral/wood/Initialize(mapload, new_amount, merge = TRUE) recipes = GLOB.wood_recipes @@ -210,7 +245,6 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \ desc = "Is it cotton? Linen? Denim? Burlap? Canvas? You can't tell." singular_name = "cloth roll" icon_state = "sheet-cloth" - origin_tech = "materials=2" resistance_flags = FLAMMABLE force = 0 throwforce = 0 @@ -244,8 +278,9 @@ GLOBAL_LIST_INIT(cardboard_recipes, list ( \ desc = "Large sheets of card, like boxes folded flat." singular_name = "cardboard sheet" icon_state = "sheet-card" - origin_tech = "materials=1" resistance_flags = FLAMMABLE + force = 0 + throwforce = 0 merge_type = /obj/item/stack/sheet/cardboard novariants = TRUE @@ -290,6 +325,7 @@ GLOBAL_LIST_INIT(runed_metal_recipes, list ( \ sheettype = "runed" merge_type = /obj/item/stack/sheet/runed_metal novariants = TRUE + grind_results = list("iron" = 0.5, "blood" = 1.5) /obj/item/stack/sheet/runed_metal/ratvar_act() new /obj/item/stack/tile/brass(loc, amount) @@ -321,7 +357,7 @@ GLOBAL_LIST_INIT(runed_metal_recipes, list ( \ * Brass */ GLOBAL_LIST_INIT(brass_recipes, list ( \ - new/datum/stack_recipe("wall gear", /obj/structure/destructible/clockwork/wall_gear, 3, time = 30, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("wall gear", /obj/structure/destructible/clockwork/wall_gear, 3, time = 10, one_per_turf = TRUE, on_floor = TRUE), \ null, new/datum/stack_recipe("pinion airlock", /obj/machinery/door/airlock/clockwork, 5, time = 50, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("brass pinion airlock", /obj/machinery/door/airlock/clockwork/brass, 5, time = 50, one_per_turf = TRUE, on_floor = TRUE), \ @@ -330,7 +366,14 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \ new/datum/stack_recipe("directional brass window", /obj/structure/window/reinforced/clockwork/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ new/datum/stack_recipe("fulltile brass window", /obj/structure/window/reinforced/clockwork/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \ new/datum/stack_recipe("brass chair", /obj/structure/chair/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \ - new/datum/stack_recipe("brass table frame", /obj/structure/table_frame/brass, 1, time = 5, one_per_turf = TRUE, on_floor = TRUE) \ + new/datum/stack_recipe("brass table frame", /obj/structure/table_frame/brass, 1, time = 5, one_per_turf = TRUE, on_floor = TRUE), \ + null, + new/datum/stack_recipe("sender - pressure sensor", /obj/structure/destructible/clockwork/trap/trigger/pressure_sensor, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("sender - lever", /obj/structure/destructible/clockwork/trap/trigger/lever, 1, time = 10, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("sender - repeater", /obj/structure/destructible/clockwork/trap/trigger/repeater, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \ + null, + new/datum/stack_recipe("receiver - brass skewer", /obj/structure/destructible/clockwork/trap/brass_skewer, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("receiver - steam vent", /obj/structure/destructible/clockwork/trap/steam_vent, 3, time = 30, one_per_turf = TRUE, on_floor = TRUE), \ )) /obj/item/stack/tile/brass @@ -346,6 +389,7 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \ throw_range = 3 turf_type = /turf/open/floor/clockwork novariants = FALSE + grind_results = list("iron" = 0.5, "teslium" = 1.5) /obj/item/stack/tile/brass/narsie_act() new /obj/item/stack/sheet/runed_metal(loc, amount) @@ -371,7 +415,6 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \ desc = "Rare kind of gems which are only gained by blood sacrifice to minor deities. They are needed in crafting powerful objects." singular_name = "lesser gem" icon_state = "sheet-lessergem" - origin_tech = "materials=4" novariants = TRUE @@ -380,7 +423,6 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \ desc = "Rare kind of gems which are only gained by blood sacrifice to minor deities. They are needed in crafting powerful objects." singular_name = "greater gem" icon_state = "sheet-greatergem" - origin_tech = "materials=7" novariants = TRUE /* @@ -398,7 +440,7 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \ w_class = WEIGHT_CLASS_NORMAL throw_speed = 1 throw_range = 3 - origin_tech = "materials=2;biotech=2" + grind_results = list("carbon" = 1) GLOBAL_LIST_INIT(plastic_recipes, list( new /datum/stack_recipe("plastic flaps", /obj/structure/plasticflaps, 5, one_per_turf = TRUE, on_floor = TRUE, time = 40), \ @@ -412,7 +454,6 @@ GLOBAL_LIST_INIT(plastic_recipes, list( singular_name = "plastic sheet" icon_state = "sheet-plastic" throwforce = 7 - origin_tech = "materials=1;biotech=1" merge_type = /obj/item/stack/sheet/plastic /obj/item/stack/sheet/plastic/fifty @@ -434,7 +475,6 @@ new /datum/stack_recipe("paper frame door", /obj/structure/mineral_door/paperfra desc = "A thin wooden frame with paper attached." singular_name = "paper frame" icon_state = "sheet-paper" - origin_tech = "materials=1" merge_type = /obj/item/stack/sheet/paperframes resistance_flags = FLAMMABLE diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index b1cb00acab..5e80353db9 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -1,7 +1,8 @@ /* Stack type objects! * Contains: * Stacks - * Recipe datum + * Recipe datum + * Recipe list datum */ /* @@ -9,7 +10,6 @@ */ /obj/item/stack icon = 'icons/obj/stack_objects.dmi' - origin_tech = "materials=1" gender = PLURAL var/list/datum/stack_recipe/recipes var/singular_name @@ -21,6 +21,17 @@ var/merge_type = null // This path and its children should merge with this stack, defaults to src.type var/full_w_class = WEIGHT_CLASS_NORMAL //The weight class the stack should have at amount > 2/3rds max_amount var/novariants = TRUE //Determines whether the item should update it's sprites based on amount. + //NOTE: When adding grind_results, the amounts should be for an INDIVIDUAL ITEM - these amounts will be multiplied by the stack size in on_grind() + +/obj/item/stack/on_grind() + for(var/i in 1 to grind_results.len) //This should only call if it's ground, so no need to check if grind_results exists + grind_results[grind_results[i]] *= amount //Gets the key at position i, then the reagent amount of that key, then multiplies it by stack size + +/obj/item/stack/grind_requirements() + if(is_cyborg) + to_chat(usr, "[src] is electronically synthesized in your chassis and can't be ground up!") + return + return TRUE /obj/item/stack/Initialize(mapload, new_amount=null , merge = TRUE) . = ..() @@ -37,9 +48,9 @@ /obj/item/stack/proc/update_weight() if(amount <= (max_amount * (1/3))) - w_class = Clamp(full_w_class-2, WEIGHT_CLASS_TINY, full_w_class) + w_class = CLAMP(full_w_class-2, WEIGHT_CLASS_TINY, full_w_class) else if (amount <= (max_amount * (2/3))) - w_class = Clamp(full_w_class-1, WEIGHT_CLASS_TINY, full_w_class) + w_class = CLAMP(full_w_class-1, WEIGHT_CLASS_TINY, full_w_class) else w_class = full_w_class @@ -88,58 +99,76 @@ /obj/item/stack/attack_self(mob/user) interact(user) -/obj/item/stack/interact(mob/user) +/obj/item/stack/interact(mob/user, recipes_sublist) if (!recipes) return if (!src || get_amount() <= 0) user << browse(null, "window=stack") - return user.set_machine(src) //for correct work of onclose - var/t1 = text("Constructions from []Amount Left: []
    ", src, get_amount()) - for(var/i=1;i<=recipes.len,i++) - var/datum/stack_recipe/R = recipes[i] - if (isnull(R)) + var/list/recipe_list = recipes + if (recipes_sublist && recipe_list[recipes_sublist] && istype(recipe_list[recipes_sublist], /datum/stack_recipe_list)) + var/datum/stack_recipe_list/srl = recipe_list[recipes_sublist] + recipe_list = srl.recipes + var/t1 = "Amount Left: [amount]
    " + for(var/i in 1 to length(recipe_list)) + var/E = recipe_list[i] + if (isnull(E)) t1 += "
    " continue - if (i>1 && !isnull(recipes[i-1])) + if (i>1 && !isnull(recipe_list[i-1])) t1+="
    " - var/max_multiplier = round(get_amount() / R.req_amount) - var/title as text - var/can_build = 1 - can_build = can_build && (max_multiplier>0) - if (R.res_amount>1) - title+= "[R.res_amount]x [R.title]\s" - else - title+= "[R.title]" - title+= " ([R.req_amount] [singular_name]\s)" - if (can_build) - t1 += text("[] ", i, title) - else - t1 += text("[]", title) - continue - if (R.max_res_amount>1 && max_multiplier>1) - max_multiplier = min(max_multiplier, round(R.max_res_amount/R.res_amount)) - t1 += " |" - var/list/multipliers = list(5,10,25) - for (var/n in multipliers) - if (max_multiplier>=n) - t1 += " [n*R.res_amount]x" - if (!(max_multiplier in multipliers)) - t1 += " [max_multiplier*R.res_amount]x" - t1 += "
    " - user << browse(t1, "window=stack") + if (istype(E, /datum/stack_recipe_list)) + var/datum/stack_recipe_list/srl = E + t1 += "[srl.title]" + + if (istype(E, /datum/stack_recipe)) + var/datum/stack_recipe/R = E + var/max_multiplier = round(get_amount() / R.req_amount) + var/title as text + var/can_build = 1 + can_build = can_build && (max_multiplier>0) + + if (R.res_amount>1) + title+= "[R.res_amount]x [R.title]\s" + else + title+= "[R.title]" + title+= " ([R.req_amount] [singular_name]\s)" + if (can_build) + t1 += text("[title] ") + else + t1 += text("[]", title) + continue + if (R.max_res_amount>1 && max_multiplier>1) + max_multiplier = min(max_multiplier, round(R.max_res_amount/R.res_amount)) + t1 += " |" + var/list/multipliers = list(5,10,25) + for (var/n in multipliers) + if (max_multiplier>=n) + t1 += " [n*R.res_amount]x" + if (!(max_multiplier in multipliers)) + t1 += " [max_multiplier*R.res_amount]x" + + var/datum/browser/popup = new(user, "stack", name, 400, 400) + popup.set_content(t1) + popup.open(0) onclose(user, "stack") /obj/item/stack/Topic(href, href_list) ..() if (usr.restrained() || usr.stat || usr.get_active_held_item() != src) return + if (href_list["sublist"] && !href_list["make"]) + interact(usr, text2num(href_list["sublist"])) if (href_list["make"]) if (get_amount() < 1) qdel(src) //Never should happen - var/datum/stack_recipe/R = recipes[text2num(href_list["make"])] + var/list/recipes_list = recipes + if (href_list["sublist"]) + var/datum/stack_recipe_list/srl = recipes_list[text2num(href_list["sublist"])] + recipes_list = srl.recipes + var/datum/stack_recipe/R = recipes_list[text2num(href_list["make"])] var/multiplier = text2num(href_list["multiplier"]) if (!multiplier ||(multiplier <= 0)) //href protection return @@ -187,9 +216,6 @@ qdel(I) //BubbleWrap END - if (src && usr.machine==src) //do not reopen closed window - addtimer(CALLBACK(src, /atom/.proc/interact, usr), 0) - /obj/item/stack/proc/building_checks(datum/stack_recipe/R, multiplier) if (get_amount() < R.req_amount*multiplier) if (R.req_amount*multiplier>1) @@ -345,3 +371,14 @@ src.one_per_turf = one_per_turf src.on_floor = on_floor src.window_checks = window_checks + +/* + * Recipe list datum + */ +/datum/stack_recipe_list + var/title = "ERROR" + var/list/recipes + +/datum/stack_recipe_list/New(title, recipes) + src.title = title + src.recipes = recipes diff --git a/code/game/objects/items/stacks/telecrystal.dm b/code/game/objects/items/stacks/telecrystal.dm index 87978ac58e..3597a3f4d6 100644 --- a/code/game/objects/items/stacks/telecrystal.dm +++ b/code/game/objects/items/stacks/telecrystal.dm @@ -7,24 +7,21 @@ w_class = WEIGHT_CLASS_TINY max_amount = 50 flags_1 = NOBLUDGEON_1 - origin_tech = "materials=6;syndicate=1" /obj/item/stack/telecrystal/attack(mob/target, mob/user) if(target == user) //You can't go around smacking people with crystals to find out if they have an uplink or not. for(var/obj/item/implant/uplink/I in target) if(I && I.imp_in) - I.hidden_uplink.telecrystals += amount - use(amount) - to_chat(user, "You press [src] onto yourself and charge your hidden uplink.") + GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, I) + if(hidden_uplink) + hidden_uplink.telecrystals += amount + use(amount) + to_chat(user, "You press [src] onto yourself and charge your hidden uplink.") + else + return ..() /obj/item/stack/telecrystal/afterattack(obj/item/I, mob/user, proximity) - if(!proximity) - return - if(isitem(I) && I.hidden_uplink && I.hidden_uplink.active) //No metagaming by using this on every PDA around just to see if it gets used up. - I.hidden_uplink.telecrystals += amount - use(amount) - to_chat(user, "You slot [src] into [I] and charge its internal uplink.") - else if(istype(I, /obj/item/cartridge/virus/frame)) + if(istype(I, /obj/item/cartridge/virus/frame)) var/obj/item/cartridge/virus/frame/cart = I if(!cart.charges) to_chat(user, "[cart] is out of charges, it's refusing to accept [src].") @@ -32,6 +29,8 @@ cart.telecrystals += amount use(amount) to_chat(user, "You slot [src] into [cart]. The next time it's used, it will also give telecrystals.") + else + return ..() /obj/item/stack/telecrystal/five amount = 5 diff --git a/code/game/objects/items/stacks/tiles/tile_mineral.dm b/code/game/objects/items/stacks/tiles/tile_mineral.dm index e9b4a0385d..38887a0d8b 100644 --- a/code/game/objects/items/stacks/tiles/tile_mineral.dm +++ b/code/game/objects/items/stacks/tiles/tile_mineral.dm @@ -3,7 +3,6 @@ singular_name = "plasma floor tile" desc = "A tile made out of highly flammable plasma. This can only end well." icon_state = "tile_plasma" - origin_tech = "plasmatech=1" turf_type = /turf/open/floor/mineral/plasma mineralType = "plasma" materials = list(MAT_PLASMA=500) @@ -40,7 +39,6 @@ singular_name = "diamond floor tile" desc = "A tile made out of diamond. Wow, just, wow." icon_state = "tile_diamond" - origin_tech = "materials=2" turf_type = /turf/open/floor/mineral/diamond mineralType = "diamond" materials = list(MAT_DIAMOND=500) @@ -60,7 +58,6 @@ desc = "A tile made out of alien alloy." icon = 'icons/obj/abductor.dmi' icon_state = "tile_abductor" - origin_tech = "materials=6;abductor=1" turf_type = /turf/open/floor/mineral/abductor mineralType = "abductor" @@ -69,7 +66,6 @@ singular_name = "titanium floor tile" desc = "A tile made of titanium, used for shuttles." icon_state = "tile_shuttle" - origin_tech = "materials=2" turf_type = /turf/open/floor/mineral/titanium mineralType = "titanium" materials = list(MAT_TITANIUM=500) @@ -79,7 +75,6 @@ singular_name = "plas-titanium floor tile" desc = "A tile made of plas-titanium, used for very evil shuttles." icon_state = "tile_darkshuttle" - origin_tech = "materials=2" turf_type = /turf/open/floor/mineral/plastitanium mineralType = "plastitanium" materials = list(MAT_TITANIUM=250, MAT_PLASMA=250) \ No newline at end of file diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index ceefd79338..d51e01ffcb 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -9,7 +9,6 @@ throw_speed = 3 throw_range = 7 max_amount = 60 - origin_tech = "materials=1" var/turf_type = null var/mineralType = null novariants = TRUE @@ -74,7 +73,6 @@ singular_name = "grass floor tile" desc = "A patch of grass like they use on space golf courses." icon_state = "tile_grass" - origin_tech = "biotech=1" turf_type = /turf/open/floor/grass resistance_flags = FLAMMABLE @@ -85,7 +83,6 @@ singular_name = "wood floor tile" desc = "An easy to fit wood floor tile." icon_state = "tile-wood" - origin_tech = "biotech=1" turf_type = /turf/open/floor/wood resistance_flags = FLAMMABLE @@ -95,7 +92,6 @@ singular_name = "basalt floor tile" desc = "Artificially made ashy soil themed on a hostile environment." icon_state = "tile_basalt" - origin_tech = "materials=1" turf_type = /turf/open/floor/grass/fakebasalt //Carpets @@ -146,7 +142,6 @@ desc = "A high-traction floor tile. It feels rubbery in your hand." icon_state = "tile_noslip" turf_type = /turf/open/floor/noslip - origin_tech = "materials=3" merge_type = /obj/item/stack/tile/noslip /obj/item/stack/tile/noslip/thirty diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index a867b7568c..533858b748 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -34,7 +34,6 @@ /obj/item/storage/backpack/holding name = "bag of holding" desc = "A backpack that opens into a localized pocket of Blue Space." - origin_tech = "bluespace=5;materials=4;engineering=4;plasmatech=5" icon_state = "holdingpack" item_state = "holdingpack" max_w_class = WEIGHT_CLASS_GIGANTIC @@ -70,8 +69,13 @@ playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 0) return 0 -/obj/item/storage/backpack/holding/handle_item_insertion(obj/item/W, prevent_warning = 0, mob/user) +/obj/item/storage/backpack/holding/handle_item_insertion(obj/item/W, prevent_warning = 0, mob/living/user) if((istype(W, /obj/item/storage/backpack/holding) || count_by_type(W.GetAllContents(), /obj/item/storage/backpack/holding))) + var/turf/loccheck = get_turf(src) + if(loccheck.z == ZLEVEL_CITYOFCOGS) + user.visible_message("An unseen force knocks [user] to the ground!", "\"I think not!\"") + user.Knockdown(60) + return var/safety = alert(user, "Doing this will have extremely dire consequences for the station and its crew. Be sure you know what you're doing.", "Put in [name]?", "Proceed", "Abort") if(safety == "Abort" || !in_range(src, user) || !src || !W || user.incapacitated()) return @@ -415,8 +419,7 @@ name = "suspicious looking duffel bag" desc = "A large duffel bag for holding extra tactical supplies." icon_state = "duffel-syndie" - item_state = "duffel-syndie" - origin_tech = "syndicate=1" + item_state = "duffel-syndieammo" silent = 1 slowdown = 0 diff --git a/code/game/objects/items/storage/bags.dm b/code/game/objects/items/storage/bags.dm index 944604c6ac..917ec898ad 100644 --- a/code/game/objects/items/storage/bags.dm +++ b/code/game/objects/items/storage/bags.dm @@ -70,7 +70,6 @@ name = "trash bag of holding" desc = "The latest and greatest in custodial convenience, a trashbag that is capable of holding vast quantities of garbage." icon_state = "bluetrashbag" - origin_tech = "materials=4;bluespace=4;engineering=4;plasmatech=3" max_combined_w_class = 60 storage_slots = 60 flags_2 = NO_MAT_REDEMPTION_2 @@ -84,7 +83,6 @@ desc = "This little bugger can be used to store and transport ores." icon = 'icons/obj/mining.dmi' icon_state = "satchel" - origin_tech = "engineering=2" slot_flags = SLOT_BELT | SLOT_POCKET w_class = WEIGHT_CLASS_NORMAL storage_slots = 50 @@ -101,7 +99,6 @@ desc = "A revolution in convenience, this satchel allows for huge amounts of ore storage. It's been outfitted with anti-malfunction safety measures." storage_slots = INFINITY max_combined_w_class = INFINITY - origin_tech = "bluespace=4;materials=3;engineering=3" icon_state = "satchel_bspace" // ----------------------------- @@ -125,7 +122,6 @@ name = "portable seed extractor" desc = "For the enterprising botanist on the go. Less efficient than the stationary model, it creates one seed per plant." icon_state = "portaseeder" - origin_tech = "biotech=3;engineering=2" /obj/item/storage/bag/plants/portaseeder/verb/dissolve_contents() set name = "Activate Seed Extraction" @@ -203,7 +199,7 @@ else if(S.pulledby) S.pulledby.stop_pulling() - S.loc = src + S.forceMove(src) orient2hud(usr) if(usr.s_active) diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index 848010d68f..f461e51555 100644 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -37,6 +37,7 @@ /obj/item/stack/cable_coil, /obj/item/device/t_scanner, /obj/item/device/analyzer, + /obj/item/device/geiger_counter, /obj/item/extinguisher/mini, /obj/item/device/radio, /obj/item/clothing/gloves diff --git a/code/game/objects/items/storage/book.dm b/code/game/objects/items/storage/book.dm index a00e97b8fe..ef04fc48f5 100644 --- a/code/game/objects/items/storage/book.dm +++ b/code/game/objects/items/storage/book.dm @@ -124,7 +124,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible", else if(iscarbon(M)) var/mob/living/carbon/C = M if(!istype(C.head, /obj/item/clothing/head/helmet)) - C.adjustBrainLoss(10) + C.adjustBrainLoss(5, 60) to_chat(C, "You feel dumber.") if(smack) diff --git a/code/game/objects/items/storage/firstaid.dm b/code/game/objects/items/storage/firstaid.dm index 4dc90de6be..2b7a1695cd 100644 --- a/code/game/objects/items/storage/firstaid.dm +++ b/code/game/objects/items/storage/firstaid.dm @@ -167,6 +167,10 @@ usr.s_active.close(usr) src.show_to(usr) +/obj/item/storage/pill_bottle/suicide_act(mob/user) + user.visible_message("[user] is trying to get the cap off [src]! It looks like [user.p_theyre()] trying to commit suicide!") + return (TOXLOSS) + /obj/item/storage/pill_bottle/charcoal name = "bottle of charcoal pills" desc = "Contains pills used to counter toxins." diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm index 9ef47c6441..454eabf058 100644 --- a/code/game/objects/items/storage/toolbox.dm +++ b/code/game/objects/items/storage/toolbox.dm @@ -12,7 +12,6 @@ throw_range = 7 w_class = WEIGHT_CLASS_BULKY materials = list(MAT_METAL = 500) - origin_tech = "combat=1;engineering=1" attack_verb = list("robusted") hitsound = 'sound/weapons/smash.ogg' var/latches = "single_latch" @@ -101,7 +100,6 @@ name = "suspicious looking toolbox" icon_state = "syndicate" item_state = "toolbox_syndi" - origin_tech = "combat=2;syndicate=1;engineering=2" silent = 1 force = 15 throwforce = 18 diff --git a/code/game/objects/items/storage/wallets.dm b/code/game/objects/items/storage/wallets.dm index 7747c3843d..885dbc3830 100644 --- a/code/game/objects/items/storage/wallets.dm +++ b/code/game/objects/items/storage/wallets.dm @@ -72,6 +72,9 @@ else return ..() +/obj/item/storage/wallet/random + icon_state = "random_wallet" + /obj/item/storage/wallet/random/PopulateContents() var/item1_type = pick( /obj/item/stack/spacecash/c10, /obj/item/stack/spacecash/c100, /obj/item/stack/spacecash/c1000, /obj/item/stack/spacecash/c20, /obj/item/stack/spacecash/c200, /obj/item/stack/spacecash/c50, /obj/item/stack/spacecash/c500) var/item2_type @@ -86,3 +89,4 @@ new item2_type(src) if(item3_type) new item3_type(src) + update_icon() diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm index 92d00d9e2d..ab82f92c2d 100644 --- a/code/game/objects/items/stunbaton.dm +++ b/code/game/objects/items/stunbaton.dm @@ -9,7 +9,6 @@ force = 10 throwforce = 7 w_class = WEIGHT_CLASS_NORMAL - origin_tech = "combat=2" attack_verb = list("beaten") armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 50, bio = 0, rad = 0, fire = 80, acid = 80) diff --git a/code/game/objects/items/tanks/jetpack.dm b/code/game/objects/items/tanks/jetpack.dm index 6946fa4a6d..6466696b98 100644 --- a/code/game/objects/items/tanks/jetpack.dm +++ b/code/game/objects/items/tanks/jetpack.dm @@ -17,7 +17,7 @@ /obj/item/tank/jetpack/New() ..() if(gas_type) - ASSERT_GAS(gas_type,air_contents) + air_contents.assert_gas(gas_type) air_contents.gases[gas_type][MOLES] = (6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C) ion_trail = new @@ -134,7 +134,6 @@ /obj/item/tank/jetpack/suit name = "hardsuit jetpack upgrade" desc = "A modular, compact set of thrusters designed to integrate with a hardsuit. It is fueled by a tank inserted into the suit's storage compartment." - origin_tech = "materials=4;magnets=4;engineering=5" icon_state = "jetpack-mining" item_state = "jetpack-black" w_class = WEIGHT_CLASS_NORMAL diff --git a/code/game/objects/items/tanks/tank_types.dm b/code/game/objects/items/tanks/tank_types.dm index c6b6b1edf4..4a687b458d 100644 --- a/code/game/objects/items/tanks/tank_types.dm +++ b/code/game/objects/items/tanks/tank_types.dm @@ -21,7 +21,7 @@ /obj/item/tank/internals/oxygen/New() ..() - ASSERT_GAS(/datum/gas/oxygen, air_contents) + air_contents.assert_gas(/datum/gas/oxygen) air_contents.gases[/datum/gas/oxygen][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return @@ -87,7 +87,7 @@ /obj/item/tank/internals/plasma/New() ..() - ASSERT_GAS(/datum/gas/plasma, air_contents) + air_contents.assert_gas(/datum/gas/plasma) air_contents.gases[/datum/gas/plasma][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return @@ -124,7 +124,7 @@ /obj/item/tank/internals/plasmaman/New() ..() - ASSERT_GAS(/datum/gas/plasma, air_contents) + air_contents.assert_gas(/datum/gas/plasma) air_contents.gases[/datum/gas/plasma][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return @@ -166,7 +166,7 @@ /obj/item/tank/internals/emergency_oxygen/New() ..() - ASSERT_GAS(/datum/gas/oxygen, air_contents) + air_contents.assert_gas(/datum/gas/oxygen) air_contents.gases[/datum/gas/oxygen][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) return @@ -177,5 +177,5 @@ /obj/item/tank/internals/emergency_oxygen/double name = "double emergency oxygen tank" - icon_state = "emergency_engi" + icon_state = "emergency_double" volume = 10 diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index 3d1c091a2b..0109b67b00 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -194,7 +194,7 @@ pressure = text2num(pressure) . = TRUE if(.) - distribute_pressure = Clamp(round(pressure), TANK_MIN_RELEASE_PRESSURE, TANK_MAX_RELEASE_PRESSURE) + distribute_pressure = CLAMP(round(pressure), TANK_MIN_RELEASE_PRESSURE, TANK_MAX_RELEASE_PRESSURE) /obj/item/tank/remove_air(amount) return air_contents.remove(amount) diff --git a/code/game/objects/items/tanks/watertank.dm b/code/game/objects/items/tanks/watertank.dm index 5f0345aa40..8a3dc21dbe 100644 --- a/code/game/objects/items/tanks/watertank.dm +++ b/code/game/objects/items/tanks/watertank.dm @@ -49,7 +49,7 @@ on = FALSE to_chat(user, "You need a free hand to hold the mister!") return - noz.loc = user + noz.forceMove(user) else //Remove from their hands and put back "into" the tank remove_noz() @@ -114,7 +114,7 @@ possible_transfer_amounts = list(25,50,100) volume = 500 flags_1 = NOBLUDGEON_1 - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER slot_flags = 0 var/obj/item/watertank/tank @@ -124,14 +124,14 @@ if(check_tank_exists(parent_tank, src)) tank = parent_tank reagents = tank.reagents //This mister is really just a proxy for the tank's reagents - loc = tank + forceMove(tank) return /obj/item/reagent_containers/spray/mister/dropped(mob/user) ..() to_chat(user, "The mister snaps back onto the watertank.") tank.on = 0 - loc = tank + forceMove(tank) /obj/item/reagent_containers/spray/mister/attack_self() return @@ -146,7 +146,7 @@ /obj/item/reagent_containers/spray/mister/Move() ..() if(loc != tank.loc) - loc = tank.loc + forceMove(tank.loc) /obj/item/reagent_containers/spray/mister/afterattack(obj/target, mob/user, proximity) if(target.loc == loc) //Safety check so you don't fill your mister with mutagen or something and then blast yourself in the face with it @@ -236,13 +236,13 @@ tank = parent_tank reagents = tank.reagents max_water = tank.volume - loc = tank + forceMove(tank) /obj/item/extinguisher/mini/nozzle/Move() ..() if(loc != tank.loc) - loc = tank + forceMove(tank) return /obj/item/extinguisher/mini/nozzle/attack_self(mob/user) @@ -268,7 +268,7 @@ ..() to_chat(user, "The nozzle snaps back onto the tank!") tank.on = 0 - loc = tank + forceMove(tank) /obj/item/extinguisher/mini/nozzle/afterattack(atom/target, mob/user) if(nozzle_mode == EXTINGUISHER) @@ -351,7 +351,7 @@ var/usage_ratio = 5 //5 unit added per 1 removed var/injection_amount = 1 amount_per_transfer_from_this = 5 - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER spillable = FALSE possible_transfer_amounts = list(5,10,15) diff --git a/code/game/objects/items/teleportation.dm b/code/game/objects/items/teleportation.dm index 2b1216b6da..93876164b4 100644 --- a/code/game/objects/items/teleportation.dm +++ b/code/game/objects/items/teleportation.dm @@ -27,7 +27,6 @@ throw_speed = 3 throw_range = 7 materials = list(MAT_METAL=400) - origin_tech = "magnets=3;bluespace=2" /obj/item/locator/attack_self(mob/user) user.set_machine(src) @@ -140,7 +139,6 @@ Frequency: throw_speed = 3 throw_range = 5 materials = list(MAT_METAL=10000) - origin_tech = "magnets=3;bluespace=4" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 30, bio = 0, rad = 0, fire = 100, acid = 100) resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF var/list/active_portal_pairs diff --git a/code/game/objects/items/teleprod.dm b/code/game/objects/items/teleprod.dm index 833849a494..92e7a8e9ba 100644 --- a/code/game/objects/items/teleprod.dm +++ b/code/game/objects/items/teleprod.dm @@ -4,7 +4,6 @@ w_class = WEIGHT_CLASS_NORMAL icon_state = "teleprod_nocell" item_state = "teleprod" - origin_tech = "combat=2;bluespace=4;materials=3" slot_flags = null /obj/item/melee/baton/cattleprod/teleprod/attack(mob/living/carbon/M, mob/living/carbon/user)//handles making things teleport when hit diff --git a/code/game/objects/items/theft_tools.dm b/code/game/objects/items/theft_tools.dm index 5f3e493677..e00513a47a 100644 --- a/code/game/objects/items/theft_tools.dm +++ b/code/game/objects/items/theft_tools.dm @@ -34,6 +34,10 @@ cooldown = world.time flick(pulseicon, src) radiation_pulse(src, 400, 2) + +/obj/item/nuke_core/suicide_act(mob/user) + user.visible_message("[user] is rubbing [src] against [user.p_them()]self! It looks like [user.p_theyre()] trying to commit suicide!") + return (TOXLOSS) //nuke core box, for carrying the core /obj/item/nuke_core_container diff --git a/code/game/objects/items/tools.dm b/code/game/objects/items/tools.dm index bd618f217e..81701d8977 100644 --- a/code/game/objects/items/tools.dm +++ b/code/game/objects/items/tools.dm @@ -28,7 +28,6 @@ w_class = WEIGHT_CLASS_SMALL usesound = 'sound/items/ratchet.ogg' materials = list(MAT_METAL=150) - origin_tech = "materials=1;engineering=1" attack_verb = list("bashed", "battered", "bludgeoned", "whacked") toolspeed = 1 armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) @@ -57,7 +56,6 @@ icon_state = "wrench" usesound = 'sound/effects/empulse.ogg' toolspeed = 0.1 - origin_tech = "materials=5;engineering=5;abductor=3" /obj/item/wrench/power name = "hand drill" @@ -68,7 +66,6 @@ righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' usesound = 'sound/items/drill_use.ogg' materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get force = 8 //might or might not be too high, subject to change w_class = WEIGHT_CLASS_SMALL throwforce = 8 @@ -92,7 +89,6 @@ icon_state = "wrench_medical" force = 2 //MEDICAL throwforce = 4 - origin_tech = "materials=1;engineering=1;biotech=3" attack_verb = list("wrenched", "medicaled", "tapped", "jabbed", "whacked") /obj/item/wrench/medical/suicide_act(mob/living/user) @@ -193,7 +189,7 @@ var/mutable_appearance/body = mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "screwdriver") var/mutable_appearance/head = mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "screwdriver_head") body.color = color - head.overlays += body + head.add_overlay(body) return head else return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', icon_state) @@ -234,7 +230,6 @@ lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get force = 8 //might or might not be too high, subject to change w_class = WEIGHT_CLASS_SMALL throwforce = 8 @@ -283,7 +278,6 @@ attack_verb = list("pinched", "nipped") hitsound = 'sound/items/wirecutter.ogg' usesound = 'sound/items/wirecutter.ogg' - origin_tech = "materials=1;engineering=1" toolspeed = 1 armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) var/random_color = TRUE @@ -327,7 +321,6 @@ icon = 'icons/obj/abductor.dmi' icon_state = "cutters" toolspeed = 0.1 - origin_tech = "materials=5;engineering=4;abductor=3" random_color = FALSE /obj/item/wirecutters/cyborg @@ -340,7 +333,6 @@ desc = "A set of jaws of life, compressed through the magic of science. It's fitted with a cutting head." icon_state = "jaws_cutter" item_state = "jawsoflife" - origin_tech = "materials=2;engineering=2" materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) usesound = 'sound/items/jaws_cut.ogg' toolspeed = 0.25 @@ -389,7 +381,6 @@ resistance_flags = FIRE_PROOF materials = list(MAT_METAL=70, MAT_GLASS=30) - origin_tech = "engineering=1;plasmatech=1" var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2) var/status = TRUE //Whether the welder is secured or unsecured (able to attach rods to it to make a flamethrower) var/max_fuel = 20 //The max amount of fuel the welder can hold @@ -633,7 +624,6 @@ icon_state = "indwelder" max_fuel = 40 materials = list(MAT_GLASS=60) - origin_tech = "engineering=2;plasmatech=2" /obj/item/weldingtool/largetank/cyborg name = "integrated welding tool" @@ -664,7 +654,6 @@ toolspeed = 0.1 light_intensity = 0 change_icons = 0 - origin_tech = "plasmatech=5;engineering=5;abductor=3" /obj/item/weldingtool/abductor/process() if(get_fuel() <= max_fuel) @@ -678,7 +667,6 @@ item_state = "upindwelder" max_fuel = 80 materials = list(MAT_METAL=70, MAT_GLASS=120) - origin_tech = "engineering=3;plasmatech=2" /obj/item/weldingtool/experimental name = "experimental welding tool" @@ -687,7 +675,6 @@ item_state = "exwelder" max_fuel = 40 materials = list(MAT_METAL=70, MAT_GLASS=120) - origin_tech = "materials=4;engineering=4;bluespace=3;plasmatech=4" var/last_gen = 0 change_icons = 0 can_off_process = 1 @@ -728,7 +715,6 @@ throwforce = 7 w_class = WEIGHT_CLASS_SMALL materials = list(MAT_METAL=50) - origin_tech = "engineering=1;combat=1" attack_verb = list("attacked", "bashed", "battered", "bludgeoned", "whacked") toolspeed = 1 armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) @@ -756,7 +742,6 @@ usesound = 'sound/weapons/sonic_jackhammer.ogg' icon_state = "crowbar" toolspeed = 0.1 - origin_tech = "combat=4;engineering=4;abductor=3" /obj/item/crowbar/large name = "crowbar" @@ -785,7 +770,6 @@ lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - origin_tech = "materials=2;engineering=2" usesound = 'sound/items/jaws_pry.ogg' force = 15 toolspeed = 0.25 diff --git a/code/game/objects/items/tools/crowbar.dm b/code/game/objects/items/tools/crowbar.dm index a248dff0db..cf2baba081 100644 --- a/code/game/objects/items/tools/crowbar.dm +++ b/code/game/objects/items/tools/crowbar.dm @@ -11,8 +11,7 @@ force = 5 throwforce = 7 w_class = WEIGHT_CLASS_SMALL - materials = list(MAT_METAL=50) - origin_tech = "engineering=1;combat=1" + materials = list(MAT_METAL=50) attack_verb = list("attacked", "bashed", "battered", "bludgeoned", "whacked") tool_behaviour = TOOL_CROWBAR toolspeed = 1 @@ -40,8 +39,7 @@ icon = 'icons/obj/abductor.dmi' usesound = 'sound/weapons/sonic_jackhammer.ogg' icon_state = "crowbar" - toolspeed = 0.1 - origin_tech = "combat=4;engineering=4;abductor=3" + toolspeed = 0.1 /obj/item/crowbar/large name = "crowbar" @@ -69,8 +67,7 @@ item_state = "jawsoflife" lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - origin_tech = "materials=2;engineering=2" + materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) usesound = 'sound/items/jaws_pry.ogg' force = 15 toolspeed = 0.25 diff --git a/code/game/objects/items/tools/screwdriver.dm b/code/game/objects/items/tools/screwdriver.dm index 278ac4385d..08f22b7e46 100644 --- a/code/game/objects/items/tools/screwdriver.dm +++ b/code/game/objects/items/tools/screwdriver.dm @@ -105,8 +105,7 @@ item_state = "drill" lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get + materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) //done for balance reasons, making them high value for research, but harder to get force = 8 //might or might not be too high, subject to change w_class = WEIGHT_CLASS_SMALL throwforce = 8 diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index 94fbb0a9a0..12c056c9af 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -22,7 +22,6 @@ resistance_flags = FIRE_PROOF materials = list(MAT_METAL=70, MAT_GLASS=30) - origin_tech = "engineering=1;plasmatech=1" var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2) var/status = TRUE //Whether the welder is secured or unsecured (able to attach rods to it to make a flamethrower) var/max_fuel = 20 //The max amount of fuel the welder can hold @@ -52,7 +51,7 @@ cut_overlays() if(change_icons) var/ratio = get_fuel() / max_fuel - ratio = Ceiling(ratio*4) * 25 + ratio = CEILING(ratio*4, 1) * 25 add_overlay("[initial(icon_state)][ratio]") update_torch() return @@ -90,18 +89,15 @@ flamethrower_screwdriver(I, user) else if(istype(I, /obj/item/stack/rods)) flamethrower_rods(I, user) - else if(istype(I, /obj/item/reagent_containers) && I.is_open_container()) - var/amountNeeded = max_fuel - get_fuel() - var/obj/item/reagent_containers/container = I - if(length(container.reagents.reagent_list) > 1) - to_chat(user, "[container] has too many chemicals mixed into it. You wouldn't want to put the wrong chemicals into [src].") - return ..() - if(amountNeeded > 0 && container.reagents.has_reagent("welding_fuel")) - container.reagents.trans_id_to(src, "welding_fuel", amountNeeded) - to_chat(user, "You transfer some fuel from [container] to [src].") else - return ..() + . = ..() + update_icon() +/obj/item/weldingtool/proc/explode() + var/turf/T = get_turf(loc) + var/plasmaAmount = reagents.get_reagent_amount("plasma") + dyn_explosion(T, plasmaAmount/5)//20 plasma in a standard welder has a 4 power explosion. no breaches, but enough to kill/dismember holder + qdel(src) /obj/item/weldingtool/attack(mob/living/carbon/human/H, mob/user) if(!istype(H)) @@ -124,7 +120,10 @@ /obj/item/weldingtool/afterattack(atom/O, mob/user, proximity) if(!proximity) return - + if(!status && O.is_refillable()) + reagents.trans_to(O, reagents.total_volume) + to_chat(user, "You empty [src]'s fuel tank into [O].") + update_icon() if(welding) remove_fuel(1) var/turf/location = get_turf(user) @@ -140,6 +139,9 @@ /obj/item/weldingtool/attack_self(mob/user) + if(src.reagents.has_reagent("plasma")) + message_admins("[key_name_admin(user)] activated a rigged welder.") + explode() switched_on(user) if(welding) set_light(light_intensity) @@ -235,9 +237,11 @@ return status = !status if(status) - to_chat(user, "You resecure [src].") + to_chat(user, "You resecure [src] and close the fuel tank.") + container_type = NONE else - to_chat(user, "[src] can now be attached and modified.") + to_chat(user, "[src] can now be attached, modified, and refuelled.") + container_type = OPENCONTAINER add_fingerprint(user) /obj/item/weldingtool/proc/flamethrower_rods(obj/item/I, mob/user) @@ -266,7 +270,6 @@ icon_state = "indwelder" max_fuel = 40 materials = list(MAT_GLASS=60) - origin_tech = "engineering=2;plasmatech=2" /obj/item/weldingtool/largetank/cyborg name = "integrated welding tool" @@ -297,7 +300,6 @@ toolspeed = 0.1 light_intensity = 0 change_icons = 0 - origin_tech = "plasmatech=5;engineering=5;abductor=3" /obj/item/weldingtool/abductor/process() if(get_fuel() <= max_fuel) @@ -311,7 +313,6 @@ item_state = "upindwelder" max_fuel = 80 materials = list(MAT_METAL=70, MAT_GLASS=120) - origin_tech = "engineering=3;plasmatech=2" /obj/item/weldingtool/experimental name = "experimental welding tool" @@ -320,7 +321,6 @@ item_state = "exwelder" max_fuel = 40 materials = list(MAT_METAL=70, MAT_GLASS=120) - origin_tech = "materials=4;engineering=4;bluespace=3;plasmatech=4" var/last_gen = 0 change_icons = 0 can_off_process = 1 @@ -342,4 +342,4 @@ nextrefueltick = world.time + 10 reagents.add_reagent("welding_fuel", 1) -#undef WELDER_FUEL_BURN_INTERVAL \ No newline at end of file +#undef WELDER_FUEL_BURN_INTERVAL diff --git a/code/game/objects/items/tools/wirecutters.dm b/code/game/objects/items/tools/wirecutters.dm index da0bbd677c..c03469164e 100644 --- a/code/game/objects/items/tools/wirecutters.dm +++ b/code/game/objects/items/tools/wirecutters.dm @@ -14,8 +14,7 @@ materials = list(MAT_METAL=80) attack_verb = list("pinched", "nipped") hitsound = 'sound/items/wirecutter.ogg' - usesound = 'sound/items/wirecutter.ogg' - origin_tech = "materials=1;engineering=1" + usesound = 'sound/items/wirecutter.ogg' tool_behaviour = TOOL_WIRECUTTER toolspeed = 1 armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) @@ -59,8 +58,7 @@ desc = "Extremely sharp wirecutters, made out of a silvery-green metal." icon = 'icons/obj/abductor.dmi' icon_state = "cutters" - toolspeed = 0.1 - origin_tech = "materials=5;engineering=4;abductor=3" + toolspeed = 0.1 random_color = FALSE /obj/item/wirecutters/cyborg @@ -72,8 +70,7 @@ name = "jaws of life" desc = "A set of jaws of life, compressed through the magic of science. It's fitted with a cutting head." icon_state = "jaws_cutter" - item_state = "jawsoflife" - origin_tech = "materials=2;engineering=2" + item_state = "jawsoflife" materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) usesound = 'sound/items/jaws_cut.ogg' toolspeed = 0.25 diff --git a/code/game/objects/items/tools/wrench.dm b/code/game/objects/items/tools/wrench.dm index 8fb6bd4211..2b3c6e7bbe 100644 --- a/code/game/objects/items/tools/wrench.dm +++ b/code/game/objects/items/tools/wrench.dm @@ -11,8 +11,7 @@ throwforce = 7 w_class = WEIGHT_CLASS_SMALL usesound = 'sound/items/ratchet.ogg' - materials = list(MAT_METAL=150) - origin_tech = "materials=1;engineering=1" + materials = list(MAT_METAL=150) attack_verb = list("bashed", "battered", "bludgeoned", "whacked") tool_behaviour = TOOL_WRENCH toolspeed = 1 @@ -41,8 +40,7 @@ icon = 'icons/obj/abductor.dmi' icon_state = "wrench" usesound = 'sound/effects/empulse.ogg' - toolspeed = 0.1 - origin_tech = "materials=5;engineering=5;abductor=3" + toolspeed = 0.1 /obj/item/wrench/power name = "hand drill" @@ -52,8 +50,7 @@ lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' usesound = 'sound/items/drill_use.ogg' - materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get + materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) //done for balance reasons, making them high value for research, but harder to get force = 8 //might or might not be too high, subject to change w_class = WEIGHT_CLASS_SMALL throwforce = 8 @@ -76,8 +73,7 @@ desc = "A medical wrench with common(medical?) uses. Can be found in your hand." icon_state = "wrench_medical" force = 2 //MEDICAL - throwforce = 4 - origin_tech = "materials=1;engineering=1;biotech=3" + throwforce = 4 attack_verb = list("wrenched", "medicaled", "tapped", "jabbed", "whacked") /obj/item/wrench/medical/suicide_act(mob/living/user) diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 698491c98f..689f50769c 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -182,7 +182,7 @@ src.add_fingerprint(user) if (src.bullets < 1) user.show_message("*click*", 2) - playsound(user, 'sound/weapons/empty.ogg', 100, 1) + playsound(src, "gun_dry_fire", 30, 1) return playsound(user, 'sound/weapons/gunshot.ogg', 100, 1) src.bullets-- @@ -322,7 +322,6 @@ throw_range = 5 force_unwielded = 0 force_wielded = 0 - origin_tech = null attack_verb = list("attacked", "struck", "hit") /obj/item/twohanded/dualsaber/toy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) diff --git a/code/game/objects/items/trash.dm b/code/game/objects/items/trash.dm index c9552a3d39..b1313ef84f 100644 --- a/code/game/objects/items/trash.dm +++ b/code/game/objects/items/trash.dm @@ -66,6 +66,7 @@ name = "crushed can" icon_state = "cola" resistance_flags = NONE + grind_results = list("aluminum" = 10) /obj/item/trash/attack(mob/M, mob/living/user) return @@ -75,6 +76,7 @@ icon = 'icons/obj/mining.dmi' icon_state = "slag" desc = "Someone's gotten on the naughty list." + grind_results = list("carbon" = 20) /obj/item/trash/coal/burn() visible_message("[src] fuses into a diamond! Someone wasn't so naughty after all...") diff --git a/code/game/objects/items/twohanded.dm b/code/game/objects/items/twohanded.dm index 19ccee75ae..58758668c3 100644 --- a/code/game/objects/items/twohanded.dm +++ b/code/game/objects/items/twohanded.dm @@ -41,6 +41,8 @@ else //something wrong name = "[initial(name)]" update_icon() + if(user.get_item_by_slot(slot_back) == src) + user.update_inv_back() if(show_message) if(iscyborg(user)) to_chat(user, "You free up your module.") @@ -257,7 +259,6 @@ unwieldsound = 'sound/weapons/saberoff.ogg' hitsound = "swing_hit" armour_penetration = 35 - origin_tech = "magnets=4;syndicate=5" item_color = "green" light_color = "#00ff00"//green attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") @@ -428,6 +429,10 @@ var/obj/item/grenade/explosive = null var/war_cry = "AAAAARGH!!!" +/obj/item/twohanded/spear/Initialize() + . = ..() + AddComponent(/datum/component/jousting) + /obj/item/twohanded/spear/examine(mob/user) ..() if(explosive) @@ -446,7 +451,7 @@ return if(explosive && wielded) user.say("[war_cry]") - explosive.loc = AM + explosive.forceMove(AM) explosive.prime() qdel(src) @@ -499,7 +504,6 @@ throw_speed = 2 throw_range = 4 materials = list(MAT_METAL=13000) - origin_tech = "materials=3;engineering=4;combat=2" attack_verb = list("sawed", "torn", "cut", "chopped", "diced") hitsound = "swing_hit" sharpness = IS_SHARP diff --git a/code/game/objects/items/vending_items.dm b/code/game/objects/items/vending_items.dm index e84295f8ed..9321cfc3f0 100644 --- a/code/game/objects/items/vending_items.dm +++ b/code/game/objects/items/vending_items.dm @@ -37,8 +37,8 @@ /obj/item/vending_refill/boozeomat machine_name = "Booze-O-Mat" icon_state = "refill_booze" - charges = list(54, 4, 0)//of 159 standard, 12 contraband - init_charges = list(54, 4, 0) + charges = list(58, 4, 0)//of 174 standard, 12 contraband + init_charges = list(58, 4, 0) /obj/item/vending_refill/coffee machine_name = "Solar's Best Hot Drinks" @@ -86,3 +86,9 @@ icon_state = "refill_donksoft" charges = list(32,28,0)// of 90 standard, 75 contraband, 0 premium init_charges = list(32,28,0) + +/obj/item/vending_refill/games + machine_name = "\improper Good Clean Fun" + icon_state = "refill_games" + charges = list(7, 3, 0) //of 21 standard, 9 contraband + init_charges = list(7, 3, 0) diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index 7b7c9c8ee5..37d0c6cb0e 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -289,7 +289,6 @@ throw_speed = 3 throw_range = 6 materials = list(MAT_METAL=12000) - origin_tech = "engineering=3;combat=2" hitsound = 'sound/weapons/genhit.ogg' attack_verb = list("stubbed", "poked") resistance_flags = FIRE_PROOF @@ -398,7 +397,7 @@ icon_state = "ectoplasm" /obj/item/ectoplasm/suicide_act(mob/user) - user.visible_message("[user] is inhaling [src]! It looks like [user.p_theyre()] trying to visit the astral plane.") + user.visible_message("[user] is inhaling [src]! It looks like [user.p_theyre()] trying to visit the astral plane!") return (OXYLOSS) /obj/item/mounted_chainsaw @@ -455,7 +454,6 @@ name = "liz o' nine tails" desc = "A whip fashioned from the severed tails of lizards." icon_state = "tailwhip" - origin_tech = "engineering=3;combat=3;biotech=3" needs_permit = 0 /obj/item/melee/chainofcommand/tailwhip/kitty @@ -474,7 +472,7 @@ attack_verb = list("smacked", "whacked", "slammed", "smashed") /obj/item/melee/skateboard/attack_self(mob/user) - new /obj/vehicle/scooter/skateboard(get_turf(user)) + new /obj/vehicle/ridden/scooter/skateboard(get_turf(user)) qdel(src) /obj/item/melee/baseball_bat diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index ad5f69672b..ff8bcc3e1e 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -198,7 +198,7 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e if(T.intact && level == 1) //fire can't damage things hidden below the floor. return if(exposed_temperature && !(resistance_flags & FIRE_PROOF)) - take_damage(Clamp(0.02 * exposed_temperature, 0, 20), BURN, "fire", 0) + take_damage(CLAMP(0.02 * exposed_temperature, 0, 20), BURN, "fire", 0) if(!(resistance_flags & ON_FIRE) && (resistance_flags & FLAMMABLE)) resistance_flags |= ON_FIRE SSfire_burning.processing[src] = src diff --git a/code/game/objects/structures/ai_core.dm b/code/game/objects/structures/ai_core.dm index 4a529571a4..5424724d32 100644 --- a/code/game/objects/structures/ai_core.dm +++ b/code/game/objects/structures/ai_core.dm @@ -279,4 +279,3 @@ That prevents a few funky behaviors. /obj/item/circuitboard/aicore name = "AI core (AI Core Board)" //Well, duh, but best to be consistent - origin_tech = "programming=3" diff --git a/code/game/objects/structures/artstuff.dm b/code/game/objects/structures/artstuff.dm index 39fbbe3335..aabbba6b2f 100644 --- a/code/game/objects/structures/artstuff.dm +++ b/code/game/objects/structures/artstuff.dm @@ -20,7 +20,7 @@ var/obj/item/canvas/C = I user.dropItemToGround(C) painting = C - C.loc = get_turf(src) + C.forceMove(get_turf(src)) C.layer = layer+0.1 user.visible_message("[user] puts \the [C] on \the [src].","You place \the [C] on \the [src].") else @@ -32,7 +32,7 @@ var/turf/T = get_turf(src) ..() if(painting && painting.loc == T) //Only move if it's near us. - painting.loc = get_turf(src) + painting.forceMove(get_turf(src)) else painting = null diff --git a/code/game/objects/structures/beds_chairs/alien_nest.dm b/code/game/objects/structures/beds_chairs/alien_nest.dm index f840316aa9..d3b62f35f4 100644 --- a/code/game/objects/structures/beds_chairs/alien_nest.dm +++ b/code/game/objects/structures/beds_chairs/alien_nest.dm @@ -66,16 +66,16 @@ "You hear squelching...") /obj/structure/bed/nest/post_buckle_mob(mob/living/M) - if(M in buckled_mobs) - M.pixel_y = 0 - M.pixel_x = initial(M.pixel_x) + 2 - M.layer = BELOW_MOB_LAYER - add_overlay(nest_overlay) - else - M.pixel_x = M.get_standard_pixel_x_offset(M.lying) - M.pixel_y = M.get_standard_pixel_y_offset(M.lying) - M.layer = initial(M.layer) - cut_overlay(nest_overlay) + M.pixel_y = 0 + M.pixel_x = initial(M.pixel_x) + 2 + M.layer = BELOW_MOB_LAYER + add_overlay(nest_overlay) + +/obj/structure/bed/nest/post_unbuckle_mob(mob/living/M) + M.pixel_x = M.get_standard_pixel_x_offset(M.lying) + M.pixel_y = M.get_standard_pixel_y_offset(M.lying) + M.layer = initial(M.layer) + cut_overlay(nest_overlay) /obj/structure/bed/nest/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) switch(damage_type) diff --git a/code/game/objects/structures/beds_chairs/bed.dm b/code/game/objects/structures/beds_chairs/bed.dm index 9ad24d1cdb..1a09c9c4c2 100644 --- a/code/game/objects/structures/beds_chairs/bed.dm +++ b/code/game/objects/structures/beds_chairs/bed.dm @@ -85,21 +85,21 @@ qdel(src) /obj/structure/bed/roller/post_buckle_mob(mob/living/M) - if(M in buckled_mobs) - density = TRUE - icon_state = "up" - M.pixel_y = initial(M.pixel_y) - else - density = FALSE - icon_state = "down" - M.pixel_x = M.get_standard_pixel_x_offset(M.lying) - M.pixel_y = M.get_standard_pixel_y_offset(M.lying) + density = TRUE + icon_state = "up" + M.pixel_y = initial(M.pixel_y) /obj/structure/bed/roller/Moved() . = ..() if(has_gravity()) playsound(src, 'sound/effects/roll.ogg', 100, 1) +/obj/structure/bed/roller/post_unbuckle_mob(mob/living/M) + density = FALSE + icon_state = "down" + M.pixel_x = M.get_standard_pixel_x_offset(M.lying) + M.pixel_y = M.get_standard_pixel_y_offset(M.lying) + /obj/item/roller name = "roller bed" desc = "A collapsed roller bed that can be carried around." @@ -150,7 +150,7 @@ /obj/item/roller/robo/deploy_roller(mob/user, atom/location) if(loaded) var/obj/structure/bed/roller/R = loaded - R.loc = location + R.forceMove(location) user.visible_message("[user] deploys [loaded].", "You deploy [loaded].") loaded = null else diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm index 6c1c0392b3..2fb2d5253d 100644 --- a/code/game/objects/structures/beds_chairs/chair.dm +++ b/code/game/objects/structures/beds_chairs/chair.dm @@ -91,7 +91,11 @@ layer = OBJ_LAYER /obj/structure/chair/post_buckle_mob(mob/living/M) - ..() + . = ..() + handle_layer() + +/obj/structure/chair/post_unbuckle_mob() + . = ..() handle_layer() /obj/structure/chair/proc/spin() @@ -167,12 +171,18 @@ return ..() /obj/structure/chair/comfy/post_buckle_mob(mob/living/M) - ..() + . = ..() + update_armrest() + +/obj/structure/chair/comfy/proc/update_armrest() if(has_buckled_mobs()) add_overlay(armrest) else cut_overlay(armrest) +/obj/structure/chair/comfy/post_unbuckle_mob() + . = ..() + update_armrest() /obj/structure/chair/comfy/brown color = rgb(255,113,0) diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index 238c83725b..aa9acae22c 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -225,7 +225,7 @@ LINEN BINS /obj/item/bedsheet/random - icon_state = "sheetrainbow" + icon_state = "random_bedsheet" item_color = "rainbow" name = "random bedsheet" desc = "If you're reading this description ingame, something has gone wrong! Honk!" diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 6357578bc3..d46978f4b0 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -61,14 +61,11 @@ add_overlay("[icon_state]_door") if(welded) add_overlay("welded") - if(secure) - if(!broken) - if(locked) - add_overlay("locked") - else - add_overlay("unlocked") + if(secure && !broken) + if(locked) + add_overlay("locked") else - add_overlay("off") + add_overlay("unlocked") else layer = BELOW_OBJ_LAYER diff --git a/code/game/objects/structures/crates_lockers/closets/job_closets.dm b/code/game/objects/structures/crates_lockers/closets/job_closets.dm index d570775ee1..42fd4d2374 100644 --- a/code/game/objects/structures/crates_lockers/closets/job_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/job_closets.dm @@ -215,17 +215,17 @@ new /obj/item/storage/backpack/medic(src) new /obj/item/storage/backpack/satchel/med(src) new /obj/item/clothing/suit/hooded/wintercoat/medical(src) - new /obj/item/clothing/under/rank/nursesuit (src) - new /obj/item/clothing/head/nursehat (src) + new /obj/item/clothing/under/rank/nursesuit(src) + new /obj/item/clothing/head/nursehat(src) new /obj/item/clothing/under/rank/medical/blue(src) new /obj/item/clothing/under/rank/medical/green(src) new /obj/item/clothing/under/rank/medical/purple(src) for(var/i in 1 to 3) new /obj/item/clothing/under/rank/medical(src) - new /obj/item/clothing/suit/toggle/labcoat(src) - new /obj/item/clothing/suit/toggle/labcoat(src) - new /obj/item/clothing/suit/toggle/labcoat/emt(src) - new /obj/item/clothing/suit/toggle/labcoat/emt(src) + for(var/i in 1 to 3) + new /obj/item/clothing/suit/toggle/labcoat(src) + for(var/i in 1 to 3) + new /obj/item/clothing/suit/toggle/labcoat/emt(src) for(var/i in 1 to 3) new /obj/item/clothing/shoes/sneakers/white(src) for(var/i in 1 to 3) 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 520c739e55..3f54a3dec2 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm @@ -18,3 +18,4 @@ new /obj/item/clothing/head/soft(src) new /obj/item/device/export_scanner(src) new /obj/item/door_remote/quartermaster(src) + new /obj/item/circuitboard/machine/protolathe/department/cargo(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm index b839f593f1..55c2160833 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm @@ -27,6 +27,7 @@ new /obj/item/door_remote/chief_engineer(src) new /obj/item/pipe_dispenser(src) new /obj/item/inducer(src) + new /obj/item/circuitboard/machine/protolathe/department/engineering(src) /obj/structure/closet/secure_closet/engineering_electrical name = "electrical supplies locker" 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 0351fdc596..dff240e1da 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -73,6 +73,8 @@ new /obj/item/device/autosurgeon/cmo(src) new /obj/item/door_remote/chief_medical_officer(src) new /obj/item/clothing/neck/petcollar(src) + new /obj/item/circuitboard/machine/protolathe/department/medical(src) + new /obj/item/pet_carrier(src) /obj/structure/closet/secure_closet/animal name = "animal control" diff --git a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm index d15c11f4ed..8b1e82ed81 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm @@ -1,27 +1,28 @@ /obj/structure/closet/secure_closet/RD name = "\proper research director's locker" req_access = list(ACCESS_RD) - icon_state = "rd" - -/obj/structure/closet/secure_closet/RD/PopulateContents() - ..() - new /obj/item/clothing/neck/cloak/rd(src) - new /obj/item/clothing/suit/bio_suit/scientist(src) - new /obj/item/clothing/head/bio_hood/scientist(src) - new /obj/item/clothing/suit/toggle/labcoat(src) - new /obj/item/clothing/under/rank/research_director(src) - new /obj/item/clothing/under/rank/research_director/alt(src) - new /obj/item/clothing/under/rank/research_director/turtleneck(src) - new /obj/item/clothing/shoes/sneakers/brown(src) - new /obj/item/cartridge/rd(src) - new /obj/item/clothing/gloves/color/latex(src) - new /obj/item/device/radio/headset/heads/rd(src) - new /obj/item/tank/internals/air(src) - new /obj/item/clothing/mask/gas(src) - new /obj/item/device/megaphone/command(src) - new /obj/item/storage/lockbox/medal/sci(src) - new /obj/item/clothing/suit/armor/reactive/teleport(src) - new /obj/item/device/assembly/flash/handheld(src) - new /obj/item/device/laser_pointer(src) - new /obj/item/door_remote/research_director(src) - new /obj/item/storage/box/firingpins(src) \ No newline at end of file + icon_state = "rd" + +/obj/structure/closet/secure_closet/RD/PopulateContents() + ..() + new /obj/item/clothing/neck/cloak/rd(src) + new /obj/item/clothing/suit/bio_suit/scientist(src) + new /obj/item/clothing/head/bio_hood/scientist(src) + new /obj/item/clothing/suit/toggle/labcoat(src) + new /obj/item/clothing/under/rank/research_director(src) + new /obj/item/clothing/under/rank/research_director/alt(src) + new /obj/item/clothing/under/rank/research_director/turtleneck(src) + new /obj/item/clothing/shoes/sneakers/brown(src) + new /obj/item/cartridge/rd(src) + new /obj/item/clothing/gloves/color/latex(src) + new /obj/item/device/radio/headset/heads/rd(src) + new /obj/item/tank/internals/air(src) + new /obj/item/clothing/mask/gas(src) + new /obj/item/device/megaphone/command(src) + new /obj/item/storage/lockbox/medal/sci(src) + new /obj/item/clothing/suit/armor/reactive/teleport(src) + new /obj/item/device/assembly/flash/handheld(src) + new /obj/item/device/laser_pointer(src) + new /obj/item/door_remote/research_director(src) + new /obj/item/storage/box/firingpins(src) + new /obj/item/circuitboard/machine/protolathe/department/science(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 04e624a46b..6491306600 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -12,6 +12,7 @@ new /obj/item/storage/backpack/satchel/cap(src) new /obj/item/clothing/neck/cloak/cap(src) new /obj/item/clothing/neck/petcollar(src) + new /obj/item/pet_carrier(src) new /obj/item/storage/backpack/duffelbag/captain(src) new /obj/item/clothing/head/crown/fancy(src) new /obj/item/clothing/suit/captunic(src) @@ -53,7 +54,9 @@ new /obj/item/restraints/handcuffs/cable/zipties(src) new /obj/item/gun/energy/e_gun/cx(src) new /obj/item/clothing/neck/petcollar(src) + new /obj/item/pet_carrier(src) new /obj/item/door_remote/civillian(src) + new /obj/item/circuitboard/machine/protolathe/department/service(src) /obj/structure/closet/secure_closet/hos name = "\proper head of security's locker" @@ -188,7 +191,6 @@ new /obj/item/clothing/suit/armor/vest/det_suit(src) new /obj/item/storage/belt/holster/full(src) new /obj/item/pinpointer/crew(src) - new /obj/item/device/mass_spectrometer(src) /obj/structure/closet/secure_closet/injection name = "lethal injections" diff --git a/code/game/objects/structures/crates_lockers/crates/bins.dm b/code/game/objects/structures/crates_lockers/crates/bins.dm index eb1b989ecd..4f385f43a5 100644 --- a/code/game/objects/structures/crates_lockers/crates/bins.dm +++ b/code/game/objects/structures/crates_lockers/crates/bins.dm @@ -1,45 +1,45 @@ -/obj/structure/closet/crate/bin - desc = "A trash bin, place your trash here for the janitor to collect." - name = "trash bin" - icon_state = "largebins" - open_sound = 'sound/effects/bin_open.ogg' - close_sound = 'sound/effects/bin_close.ogg' - anchored = TRUE - horizontal = FALSE - delivery_icon = null - -/obj/structure/closet/crate/bin/New() - ..() - update_icon() - -/obj/structure/closet/crate/bin/update_icon() - ..() - cut_overlays() - if(contents.len == 0) - add_overlay("largebing") - else if(contents.len >= storage_capacity) - add_overlay("largebinr") - else - add_overlay("largebino") - -/obj/structure/closet/crate/bin/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/storage/bag/trash)) - var/obj/item/storage/bag/trash/T = W - to_chat(user, "You fill the bag.") - for(var/obj/item/O in src) - if(T.can_be_inserted(O, 1)) - O.loc = T - T.update_icon() - do_animate() - else if(istype(W, /obj/item/wrench)) - anchored = !anchored - playsound(src.loc, W.usesound, 75, 1) - else - return ..() - -/obj/structure/closet/crate/bin/proc/do_animate() - playsound(loc, open_sound, 15, 1, -3) - flick("animate_largebins", src) - spawn(13) - playsound(loc, close_sound, 15, 1, -3) - update_icon() +/obj/structure/closet/crate/bin + desc = "A trash bin, place your trash here for the janitor to collect." + name = "trash bin" + icon_state = "largebins" + open_sound = 'sound/effects/bin_open.ogg' + close_sound = 'sound/effects/bin_close.ogg' + anchored = TRUE + horizontal = FALSE + delivery_icon = null + +/obj/structure/closet/crate/bin/New() + ..() + update_icon() + +/obj/structure/closet/crate/bin/update_icon() + ..() + cut_overlays() + if(contents.len == 0) + add_overlay("largebing") + else if(contents.len >= storage_capacity) + add_overlay("largebinr") + else + add_overlay("largebino") + +/obj/structure/closet/crate/bin/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/storage/bag/trash)) + var/obj/item/storage/bag/trash/T = W + to_chat(user, "You fill the bag.") + for(var/obj/item/O in src) + if(T.can_be_inserted(O, 1)) + O.forceMove(T) + T.update_icon() + do_animate() + else if(istype(W, /obj/item/wrench)) + anchored = !anchored + playsound(src.loc, W.usesound, 75, 1) + else + return ..() + +/obj/structure/closet/crate/bin/proc/do_animate() + playsound(loc, open_sound, 15, 1, -3) + flick("animate_largebins", src) + spawn(13) + playsound(loc, close_sound, 15, 1, -3) + update_icon() diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 241d7ea41c..30384d2da9 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -224,7 +224,7 @@ G.use(10) var/obj/structure/displaycase/display = new(src.loc) if(electronics) - electronics.loc = display + electronics.forceMove(display) display.electronics = electronics if(electronics.one_access) display.req_one_access = electronics.accesses diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm index c6af589cb5..43bb540375 100644 --- a/code/game/objects/structures/door_assembly.dm +++ b/code/game/objects/structures/door_assembly.dm @@ -1,8 +1,3 @@ - -#define AIRLOCK_ASSEMBLY_NEEDS_WIRES 0 -#define AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS 1 -#define AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER 2 - /obj/structure/door_assembly name = "airlock assembly" icon = 'icons/obj/doors/airlocks/station/public.dmi' @@ -12,376 +7,279 @@ density = TRUE max_integrity = 200 var/state = AIRLOCK_ASSEMBLY_NEEDS_WIRES + var/base_name = "airlock" var/mineral = null - var/typetext = "" - var/icontext = "" var/obj/item/electronics/airlock/electronics = null var/airlock_type = /obj/machinery/door/airlock //the type path of the airlock once completed var/glass_type = /obj/machinery/door/airlock/glass + var/glass = 0 // 0 = glass can be installed. 1 = glass is already installed. var/created_name = null var/heat_proof_finished = 0 //whether to heat-proof the finished airlock - var/material = null //icon state logic + var/previous_assembly = /obj/structure/door_assembly + var/noglass = FALSE //airlocks with no glass version, also cannot be modified with sheets + var/material_type = /obj/item/stack/sheet/metal + var/material_amt = 4 /obj/structure/door_assembly/New() update_icon() + update_name() ..() -/obj/structure/door_assembly/door_assembly_0 - name = "airlock assembly" - airlock_type = /obj/machinery/door/airlock - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS +/obj/structure/door_assembly/door_assembly_public + name = "public airlock assembly" + icon = 'icons/obj/doors/airlocks/station2/glass.dmi' + overlays_file = 'icons/obj/doors/airlocks/station2/overlays.dmi' + glass_type = /obj/machinery/door/airlock/public/glass + airlock_type = /obj/machinery/door/airlock/public /obj/structure/door_assembly/door_assembly_com name = "command airlock assembly" icon = 'icons/obj/doors/airlocks/station/command.dmi' - typetext = "command" - icontext = "com" + base_name = "command airlock" glass_type = /obj/machinery/door/airlock/glass_command airlock_type = /obj/machinery/door/airlock/command - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS - -/obj/structure/door_assembly/door_assembly_com/glass - mineral = "glass" - material = "glass" /obj/structure/door_assembly/door_assembly_sec name = "security airlock assembly" icon = 'icons/obj/doors/airlocks/station/security.dmi' - typetext = "security" - icontext = "sec" + base_name = "security airlock" glass_type = /obj/machinery/door/airlock/glass_security airlock_type = /obj/machinery/door/airlock/security - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS - -/obj/structure/door_assembly/door_assembly_sec/glass - mineral = "glass" - material = "glass" /obj/structure/door_assembly/door_assembly_eng name = "engineering airlock assembly" icon = 'icons/obj/doors/airlocks/station/engineering.dmi' - typetext = "engineering" - icontext = "eng" + base_name = "engineering airlock" glass_type = /obj/machinery/door/airlock/glass_engineering airlock_type = /obj/machinery/door/airlock/engineering - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS - -/obj/structure/door_assembly/door_assembly_eng/glass - mineral = "glass" - material = "glass" /obj/structure/door_assembly/door_assembly_min name = "mining airlock assembly" icon = 'icons/obj/doors/airlocks/station/mining.dmi' - typetext = "mining" - icontext = "min" + base_name = "mining airlock" glass_type = /obj/machinery/door/airlock/glass_mining airlock_type = /obj/machinery/door/airlock/mining - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS - -/obj/structure/door_assembly/door_assembly_min/glass - mineral = "glass" - material = "glass" /obj/structure/door_assembly/door_assembly_atmo name = "atmospherics airlock assembly" icon = 'icons/obj/doors/airlocks/station/atmos.dmi' - typetext = "atmos" - icontext = "atmo" + base_name = "atmospherics airlock" glass_type = /obj/machinery/door/airlock/glass_atmos airlock_type = /obj/machinery/door/airlock/atmos - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS - -/obj/structure/door_assembly/door_assembly_atmo/glass - mineral = "glass" - material = "glass" /obj/structure/door_assembly/door_assembly_research name = "research airlock assembly" icon = 'icons/obj/doors/airlocks/station/research.dmi' - typetext = "research" - icontext = "res" + base_name = "research airlock" glass_type = /obj/machinery/door/airlock/glass_research airlock_type = /obj/machinery/door/airlock/research - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS - -/obj/structure/door_assembly/door_assembly_research/glass - mineral = "glass" - material = "glass" /obj/structure/door_assembly/door_assembly_science name = "science airlock assembly" icon = 'icons/obj/doors/airlocks/station/science.dmi' - typetext = "science" - icontext = "sci" + base_name = "science airlock" glass_type = /obj/machinery/door/airlock/glass_science airlock_type = /obj/machinery/door/airlock/science - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS - -/obj/structure/door_assembly/door_assembly_science/glass - mineral = "glass" - material = "glass" /obj/structure/door_assembly/door_assembly_med name = "medical airlock assembly" icon = 'icons/obj/doors/airlocks/station/medical.dmi' - typetext = "medical" - icontext = "med" + base_name = "medical airlock" glass_type = /obj/machinery/door/airlock/glass_medical airlock_type = /obj/machinery/door/airlock/medical - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS - -/obj/structure/door_assembly/door_assembly_med/glass - mineral = "glass" - material = "glass" /obj/structure/door_assembly/door_assembly_mai name = "maintenance airlock assembly" icon = 'icons/obj/doors/airlocks/station/maintenance.dmi' - typetext = "maintenance" - icontext = "mai" + base_name = "maintenance airlock" glass_type = /obj/machinery/door/airlock/glass_maintenance airlock_type = /obj/machinery/door/airlock/maintenance - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS -/obj/structure/door_assembly/door_assembly_mai/glass - mineral = "glass" - material = "glass" +/obj/structure/door_assembly/door_assembly_extmai + name = "external maintenance airlock assembly" + icon = 'icons/obj/doors/airlocks/station/maintenanceexternal.dmi' + base_name = "external maintenance airlock" + glass_type = /obj/machinery/door/airlock/maintenance/external/glass + airlock_type = /obj/machinery/door/airlock/maintenance/external /obj/structure/door_assembly/door_assembly_ext name = "external airlock assembly" icon = 'icons/obj/doors/airlocks/external/external.dmi' + base_name = "external airlock" overlays_file = 'icons/obj/doors/airlocks/external/overlays.dmi' - typetext = "external" - icontext = "ext" - glass_type = /obj/machinery/door/airlock/glass_external + glass_type = /obj/machinery/door/airlock/external/glass airlock_type = /obj/machinery/door/airlock/external - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS - -/obj/structure/door_assembly/door_assembly_ext/glass - mineral = "glass" - material = "glass" /obj/structure/door_assembly/door_assembly_fre name = "freezer airlock assembly" icon = 'icons/obj/doors/airlocks/station/freezer.dmi' - typetext = "freezer" - icontext = "fre" + base_name = "freezer airlock" airlock_type = /obj/machinery/door/airlock/freezer - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS + noglass = TRUE /obj/structure/door_assembly/door_assembly_hatch name = "airtight hatch assembly" icon = 'icons/obj/doors/airlocks/hatch/centcom.dmi' + base_name = "airtight hatch" overlays_file = 'icons/obj/doors/airlocks/hatch/overlays.dmi' - typetext = "hatch" - icontext = "hatch" airlock_type = /obj/machinery/door/airlock/hatch - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS + noglass = TRUE /obj/structure/door_assembly/door_assembly_mhatch name = "maintenance hatch assembly" icon = 'icons/obj/doors/airlocks/hatch/maintenance.dmi' + base_name = "maintenance hatch" overlays_file = 'icons/obj/doors/airlocks/hatch/overlays.dmi' - typetext = "maintenance_hatch" - icontext = "mhatch" airlock_type = /obj/machinery/door/airlock/maintenance_hatch - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS - -/obj/structure/door_assembly/door_assembly_glass - name = "glass airlock assembly" - icon = 'icons/obj/doors/airlocks/station2/glass.dmi' - overlays_file = 'icons/obj/doors/airlocks/station2/overlays.dmi' - airlock_type = /obj/machinery/door/airlock/glass - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS - mineral = "glass" - material = "glass" - -/obj/structure/door_assembly/door_assembly_gold - name = "gold airlock assembly" - icon = 'icons/obj/doors/airlocks/station/gold.dmi' - airlock_type = /obj/machinery/door/airlock/gold - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS - mineral = "gold" - -/obj/structure/door_assembly/door_assembly_silver - name = "silver airlock assembly" - icon = 'icons/obj/doors/airlocks/station/silver.dmi' - airlock_type = /obj/machinery/door/airlock/silver - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS - mineral = "silver" - -/obj/structure/door_assembly/door_assembly_diamond - name = "diamond airlock assembly" - icon = 'icons/obj/doors/airlocks/station/diamond.dmi' - airlock_type = /obj/machinery/door/airlock/diamond - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS - mineral = "diamond" - -/obj/structure/door_assembly/door_assembly_uranium - name = "uranium airlock assembly" - icon = 'icons/obj/doors/airlocks/station/uranium.dmi' - airlock_type = /obj/machinery/door/airlock/uranium - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS - mineral = "uranium" - -/obj/structure/door_assembly/door_assembly_plasma - name = "plasma airlock assembly" - icon = 'icons/obj/doors/airlocks/station/plasma.dmi' - airlock_type = /obj/machinery/door/airlock/plasma - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS - mineral = "plasma" - -/obj/structure/door_assembly/door_assembly_clown - name = "bananium airlock assembly" - desc = "Honk." - icon = 'icons/obj/doors/airlocks/station/bananium.dmi' - airlock_type = /obj/machinery/door/airlock/clown - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS - mineral = "bananium" - -/obj/structure/door_assembly/door_assembly_sandstone - name = "sandstone airlock assembly" - icon = 'icons/obj/doors/airlocks/station/sandstone.dmi' - airlock_type = /obj/machinery/door/airlock/sandstone - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS - mineral = "sandstone" - -/obj/structure/door_assembly/door_assembly_titanium - name = "titanium airlock assembly" - icon = 'icons/obj/doors/airlocks/shuttle/shuttle.dmi' - overlays_file = 'icons/obj/doors/airlocks/shuttle/overlays.dmi' - typetext = "titanium" - icontext = "titanium" - glass_type = /obj/machinery/door/airlock/glass_titanium - airlock_type = /obj/machinery/door/airlock/titanium - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS - mineral = "titanium" - -/obj/structure/door_assembly/door_assembly_titanium/glass - mineral = "glass" - material = "glass" + noglass = TRUE /obj/structure/door_assembly/door_assembly_highsecurity // Borrowing this until WJohnston makes sprites for the assembly name = "high security airlock assembly" icon = 'icons/obj/doors/airlocks/highsec/highsec.dmi' + base_name = "high security airlock" overlays_file = 'icons/obj/doors/airlocks/highsec/overlays.dmi' - typetext = "highsecurity" - icontext = "highsec" airlock_type = /obj/machinery/door/airlock/highsecurity - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS + noglass = TRUE + material_type = /obj/item/stack/sheet/plasteel + material_amt = 6 /obj/structure/door_assembly/door_assembly_vault name = "vault door assembly" icon = 'icons/obj/doors/airlocks/vault/vault.dmi' + base_name = "vault door" overlays_file = 'icons/obj/doors/airlocks/vault/overlays.dmi' - typetext = "vault" - icontext = "vault" airlock_type = /obj/machinery/door/airlock/vault - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS + noglass = TRUE + material_type = /obj/item/stack/sheet/plasteel + material_amt = 8 /obj/structure/door_assembly/door_assembly_shuttle name = "shuttle airlock assembly" icon = 'icons/obj/doors/airlocks/shuttle/shuttle.dmi' + base_name = "shuttle airlock" overlays_file = 'icons/obj/doors/airlocks/shuttle/overlays.dmi' - typetext = "shuttle" - icontext = "shuttle" airlock_type = /obj/machinery/door/airlock/shuttle - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS + glass_type = /obj/machinery/door/airlock/shuttle/glass /obj/structure/door_assembly/door_assembly_cult name = "cult airlock assembly" icon = 'icons/obj/doors/airlocks/cult/runed/cult.dmi' + base_name = "cult airlock" overlays_file = 'icons/obj/doors/airlocks/cult/runed/overlays.dmi' - typetext = "cult" - icontext = "cult" airlock_type = /obj/machinery/door/airlock/cult - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS - -/obj/structure/door_assembly/door_assembly_cult/glass - mineral = "glass" - material = "glass" + glass_type = /obj/machinery/door/airlock/cult/glass /obj/structure/door_assembly/door_assembly_cult/unruned icon = 'icons/obj/doors/airlocks/cult/unruned/cult.dmi' overlays_file = 'icons/obj/doors/airlocks/cult/unruned/overlays.dmi' - -/obj/structure/door_assembly/door_assembly_cult/unruned/glass - mineral = "glass" - material = "glass" - -/obj/structure/door_assembly/door_assembly_wood - name = "wooden airlock assembly" - icon = 'icons/obj/doors/airlocks/station/wood.dmi' - airlock_type = /obj/machinery/door/airlock/wood - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS - mineral = "wood" + airlock_type = /obj/machinery/door/airlock/cult/unruned + glass_type = /obj/machinery/door/airlock/cult/unruned/glass /obj/structure/door_assembly/door_assembly_viro name = "virology airlock assembly" icon = 'icons/obj/doors/airlocks/station/virology.dmi' - typetext = "virology" - icontext = "viro" + base_name = "virology airlock" glass_type = /obj/machinery/door/airlock/glass_virology airlock_type = /obj/machinery/door/airlock/virology - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS - -/obj/structure/door_assembly/door_assembly_viro/glass - mineral = "glass" - material = "glass" /obj/structure/door_assembly/door_assembly_centcom - typetext = "centcom" icon = 'icons/obj/doors/airlocks/centcom/centcom.dmi' overlays_file = 'icons/obj/doors/airlocks/centcom/overlays.dmi' - icontext = "ele" airlock_type = /obj/machinery/door/airlock/centcom - anchored = TRUE - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS + noglass = TRUE + +/obj/structure/door_assembly/door_assembly_gold + name = "gold airlock assembly" + icon = 'icons/obj/doors/airlocks/station/gold.dmi' + base_name = "gold airlock" + airlock_type = /obj/machinery/door/airlock/gold + mineral = "gold" + glass_type = /obj/machinery/door/airlock/gold/glass + +/obj/structure/door_assembly/door_assembly_silver + name = "silver airlock assembly" + icon = 'icons/obj/doors/airlocks/station/silver.dmi' + base_name = "silver airlock" + airlock_type = /obj/machinery/door/airlock/silver + mineral = "silver" + glass_type = /obj/machinery/door/airlock/silver/glass + +/obj/structure/door_assembly/door_assembly_diamond + name = "diamond airlock assembly" + icon = 'icons/obj/doors/airlocks/station/diamond.dmi' + base_name = "diamond airlock" + airlock_type = /obj/machinery/door/airlock/diamond + mineral = "diamond" + glass_type = /obj/machinery/door/airlock/diamond/glass + +/obj/structure/door_assembly/door_assembly_uranium + name = "uranium airlock assembly" + icon = 'icons/obj/doors/airlocks/station/uranium.dmi' + base_name = "uranium airlock" + airlock_type = /obj/machinery/door/airlock/uranium + mineral = "uranium" + glass_type = /obj/machinery/door/airlock/uranium/glass + +/obj/structure/door_assembly/door_assembly_plasma + name = "plasma airlock assembly" + icon = 'icons/obj/doors/airlocks/station/plasma.dmi' + base_name = "plasma airlock" + airlock_type = /obj/machinery/door/airlock/plasma + mineral = "plasma" + glass_type = /obj/machinery/door/airlock/plasma/glass + +/obj/structure/door_assembly/door_assembly_bananium + name = "bananium airlock assembly" + desc = "Honk." + icon = 'icons/obj/doors/airlocks/station/bananium.dmi' + base_name = "bananium airlock" + airlock_type = /obj/machinery/door/airlock/clown + mineral = "bananium" + glass_type = /obj/machinery/door/airlock/clown/glass + +/obj/structure/door_assembly/door_assembly_sandstone + name = "sandstone airlock assembly" + icon = 'icons/obj/doors/airlocks/station/sandstone.dmi' + base_name = "sandstone airlock" + airlock_type = /obj/machinery/door/airlock/sandstone + mineral = "sandstone" + glass_type = /obj/machinery/door/airlock/sandstone/glass + +/obj/structure/door_assembly/door_assembly_titanium + name = "titanium airlock assembly" + icon = 'icons/obj/doors/airlocks/shuttle/shuttle.dmi' + base_name = "shuttle airlock" + overlays_file = 'icons/obj/doors/airlocks/shuttle/overlays.dmi' + glass_type = /obj/machinery/door/airlock/titanium/glass + airlock_type = /obj/machinery/door/airlock/titanium + mineral = "titanium" + +/obj/structure/door_assembly/door_assembly_wood + name = "wooden airlock assembly" + icon = 'icons/obj/doors/airlocks/station/wood.dmi' + base_name = "wooden airlock" + airlock_type = /obj/machinery/door/airlock/wood + mineral = "wood" + glass_type = /obj/machinery/door/airlock/wood/glass /obj/structure/door_assembly/examine(mob/user) ..() switch(state) - if(0) + if(AIRLOCK_ASSEMBLY_NEEDS_WIRES) 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) + if(AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS) to_chat(user, "The maintenance panel is wired, but the circuit slot is empty.") - if(2) + if(AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER) 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.") + if(!mineral && !glass && !noglass) + to_chat(user, "There is a small paper placard on the assembly. There are empty slots for glass windows and mineral covers.") + else if(!mineral && glass && !noglass) + to_chat(user, "There is a small paper placard on the assembly. There are empty slots for mineral covers.") + else if(mineral && !glass && !noglass) + to_chat(user, "There is a small paper placard on the assembly. There are empty slots for glass windows.") else to_chat(user, "There is a small paper placard on the assembly.") @@ -394,148 +292,41 @@ return created_name = t - else if(istype(W, /obj/item/airlock_painter)) // |- Ricotez - //INFORMATION ABOUT ADDING A NEW AIRLOCK TO THE PAINT LIST: - //If your airlock has a regular version, add it to the list with regular versions. - //If your airlock has a glass version, add it to the list with glass versions. - //Don't forget to also set has_solid and has_glass to the proper value. - //Do NOT add your airlock to a list if it does not have a version for that list, - // or you will get broken icons. - var/obj/item/airlock_painter/WT = W - if(WT.can_use(user)) - var/icontype - var/optionlist - if(mineral && mineral == "glass") - //These airlocks have a glass version. - optionlist = list("Public", "Public2", "Engineering", "Atmospherics", "Security", "Command", "Medical", "Research", "Science", "Mining") - else - //These airlocks have a regular version. - optionlist = list("Public", "Engineering", "Atmospherics", "Security", "Command", "Medical", "Research", "Science", "Mining", "Maintenance", "External", "High Security") - - - icontype = input(user, "Please select a paintjob for this airlock.") in optionlist - if((!in_range(src, usr) && loc != usr) || !WT.use(user)) - return - var/has_solid = FALSE - var/has_glass = FALSE - switch(icontype) - if("Public") - icon = 'icons/obj/doors/airlocks/station/public.dmi' - overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' - typetext = "" - icontext = "" - has_solid = TRUE - has_glass = TRUE - if("Public2") - icon = 'icons/obj/doors/airlocks/station2/glass.dmi' - overlays_file = 'icons/obj/doors/airlocks/station2/overlays.dmi' - typetext = "" - icontext = "" - has_solid = TRUE - has_glass = TRUE - if("Engineering") - icon = 'icons/obj/doors/airlocks/station/engineering.dmi' - overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' - typetext = "engineering" - icontext = "eng" - has_solid = TRUE - has_glass = TRUE - if("Atmospherics") - icon = 'icons/obj/doors/airlocks/station/atmos.dmi' - overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' - typetext = "atmos" - icontext = "atmo" - has_solid = TRUE - has_glass = TRUE - if("Security") - icon = 'icons/obj/doors/airlocks/station/security.dmi' - overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' - typetext = "security" - icontext = "sec" - has_solid = TRUE - has_glass = TRUE - if("Command") - icon = 'icons/obj/doors/airlocks/station/command.dmi' - overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' - typetext = "command" - icontext = "com" - has_solid = TRUE - has_glass = TRUE - if("Medical") - icon = 'icons/obj/doors/airlocks/station/medical.dmi' - overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' - typetext = "medical" - icontext = "med" - has_solid = TRUE - has_glass = TRUE - if("Research") - icon = 'icons/obj/doors/airlocks/station/research.dmi' - overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' - typetext = "research" - icontext = "res" - has_solid = TRUE - has_glass = TRUE - if("Science") - icon = 'icons/obj/doors/airlocks/station/science.dmi' - overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' - typetext = "research" - icontext = "res" - has_solid = TRUE - has_glass = TRUE - if("Mining") - icon = 'icons/obj/doors/airlocks/station/mining.dmi' - overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' - typetext = "mining" - icontext = "min" - has_solid = TRUE - has_glass = TRUE - if("Maintenance") - icon = 'icons/obj/doors/airlocks/station/maintenance.dmi' - overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi' - typetext = "maintenance" - icontext = "mai" - has_solid = TRUE - has_glass = FALSE - if("External") - icon = 'icons/obj/doors/airlocks/external/external.dmi' - overlays_file = 'icons/obj/doors/airlocks/external/overlays.dmi' - typetext = "external" - icontext = "ext" - has_solid = TRUE - has_glass = FALSE - if("High Security") - icon = 'icons/obj/doors/airlocks/highsec/highsec.dmi' - overlays_file = 'icons/obj/doors/airlocks/highsec/overlays.dmi' - typetext = "highsecurity" - icontext = "highsec" - has_solid = TRUE - has_glass = FALSE - if(has_solid) - airlock_type = text2path("/obj/machinery/door/airlock/[typetext]") - else - airlock_type = /obj/machinery/door/airlock - - if(has_glass) - glass_type = text2path("/obj/machinery/door/airlock/glass_[typetext]") - else - glass_type = /obj/machinery/door/airlock/glass - - if(mineral && mineral != "glass") - mineral = null //I know this is stupid, but until we change glass to a boolean it's how this code works. - to_chat(user, "You change the paintjob on the airlock assembly.") - - else if(istype(W, /obj/item/weldingtool) && !anchored ) + else if(istype(W, /obj/item/weldingtool) && (mineral || glass || !anchored )) var/obj/item/weldingtool/WT = W if(WT.remove_fuel(0,user)) - user.visible_message("[user] disassembles the airlock assembly.", \ - "You start to disassemble the airlock assembly...") playsound(src, 'sound/items/welder2.ogg', 50, 1) + if(mineral) + var/obj/item/stack/sheet/mineral/mineral_path = text2path("/obj/item/stack/sheet/mineral/[mineral]") + user.visible_message("[user] welds the [mineral] plating off the airlock assembly.", "You start to weld the [mineral] plating off the airlock assembly...") + if(do_after(user, 40 * WT.toolspeed, target = src)) + if(!src || !WT.isOn()) + return + to_chat(user, "You weld the [mineral] plating off.") + new mineral_path(loc, 2) + var/obj/structure/door_assembly/PA = new previous_assembly(loc) + transfer_assembly_vars(src, PA) - if(do_after(user, 40*W.toolspeed, target = src)) - if( !WT.isOn() ) - return - to_chat(user, "You disassemble the airlock assembly.") - deconstruct(TRUE) + else if(glass) + user.visible_message("[user] welds the glass panel out of the airlock assembly.", "You start to weld the glass panel out of the airlock assembly...") + if(do_after(user, 40 * WT.toolspeed, target = src)) + if(!src || !WT.isOn()) + return + to_chat(user, "You weld the glass panel out.") + if(heat_proof_finished) + new /obj/item/stack/sheet/rglass(get_turf(src)) + heat_proof_finished = 0 + else + new /obj/item/stack/sheet/glass(get_turf(src)) + glass = 0 + else if(!anchored) + user.visible_message("[user] disassembles the airlock assembly.", \ + "You start to disassemble the airlock assembly...") + if(do_after(user, 40*W.toolspeed, target = src)) + if(!WT.isOn()) + return + to_chat(user, "You disassemble the airlock assembly.") + deconstruct(TRUE) else if(istype(W, /obj/item/wrench)) if(!anchored ) @@ -572,7 +363,7 @@ name = "airlock assembly" anchored = FALSE - else if(istype(W, /obj/item/stack/cable_coil) && state == 0 && anchored ) + else if(istype(W, /obj/item/stack/cable_coil) && state == AIRLOCK_ASSEMBLY_NEEDS_WIRES && anchored ) var/obj/item/stack/cable_coil/C = W if (C.get_amount() < 1) to_chat(user, "You need one length of cable to wire the airlock assembly!") @@ -580,32 +371,32 @@ user.visible_message("[user] wires the airlock assembly.", \ "You start to wire the airlock assembly...") if(do_after(user, 40, target = src)) - if(C.get_amount() < 1 || state != 0) + if(C.get_amount() < 1 || state != AIRLOCK_ASSEMBLY_NEEDS_WIRES) return C.use(1) state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS to_chat(user, "You wire the airlock assembly.") name = "wired airlock assembly" - else if(istype(W, /obj/item/wirecutters) && state == 1 ) + else if(istype(W, /obj/item/wirecutters) && state == AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS ) playsound(src, W.usesound, 100, 1) user.visible_message("[user] cuts the wires from the airlock assembly.", \ "You start to cut the wires from the airlock assembly...") if(do_after(user, 40*W.toolspeed, target = src)) - if(state != 1) + if(state != AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS) return to_chat(user, "You cut the wires from the airlock assembly.") new/obj/item/stack/cable_coil(get_turf(user), 1) state = AIRLOCK_ASSEMBLY_NEEDS_WIRES name = "secured airlock assembly" - else if(istype(W, /obj/item/electronics/airlock) && state == 1 ) + else if(istype(W, /obj/item/electronics/airlock) && state == AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS ) playsound(src, W.usesound, 100, 1) user.visible_message("[user] installs the electronics into the airlock assembly.", \ "You start to install electronics into the airlock assembly...") if(do_after(user, 40, target = src)) - if( state != 1 ) + if( state != AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS ) return if(!user.transferItemToLoc(W, src)) return @@ -616,13 +407,13 @@ electronics = W - else if(istype(W, /obj/item/crowbar) && state == 2 ) + else if(istype(W, /obj/item/crowbar) && state == AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER ) playsound(src, W.usesound, 100, 1) user.visible_message("[user] removes the electronics from the airlock assembly.", \ "You start to remove electronics from the airlock assembly...") if(do_after(user, 40*W.toolspeed, target = src)) - if(state != 2) + if(state != AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER) return to_chat(user, "You remove the airlock electronics.") state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS @@ -634,66 +425,65 @@ ae = electronics electronics = null ae.forceMove(src.loc) - else if(istype(W, /obj/item/stack/sheet) && !mineral) + + else if(istype(W, /obj/item/stack/sheet) && (!glass || !mineral)) var/obj/item/stack/sheet/G = W if(G) if(G.get_amount() >= 1) - if(is_glass_sheet(G)) - playsound(src, 'sound/items/crowbar.ogg', 100, 1) - user.visible_message("[user] adds [G.name] to the airlock assembly.", \ - "You start to install [G.name] into the airlock assembly...") - if(do_after(user, 40, target = src)) - if(G.get_amount() < 1 || mineral) - return - if(!istype(G, /obj/item/stack/sheet/glass)) - to_chat(user, "You install [G.name] windows into the airlock assembly.") - heat_proof_finished = 1 //plasma & reinforced glass makes the airlock heat-proof - name = "near finished heat-proofed window airlock assembly" - else - to_chat(user, "You install regular glass windows into the airlock assembly.") - name = "near finished window airlock assembly" - G.use(1) - mineral = "glass" - material = "glass" - //This list contains the airlock paintjobs that have a glass version: - if(icontext in list("eng", "atmo", "sec", "com", "med", "res", "min")) - airlock_type = text2path("/obj/machinery/door/airlock/[typetext]") - glass_type = text2path("/obj/machinery/door/airlock/glass_[typetext]") - else - //This airlock is default or does not have a glass version, so we revert to the default glass airlock. |- Ricotez - airlock_type = /obj/machinery/door/airlock - glass_type = /obj/machinery/door/airlock/glass - typetext = "" - icontext = "" - else if(istype(G, /obj/item/stack/sheet/mineral)) - var/M = G.sheettype - if(G.get_amount() >= 2) - playsound(src, 'sound/items/crowbar.ogg', 100, 1) - user.visible_message("[user] adds [G.name] to the airlock assembly.", \ - "You start to install [G.name] into the airlock assembly...") - if(do_after(user, 40, target = src)) - if(G.get_amount() < 2 || mineral) - return - to_chat(user, "You install [M] plating into the airlock assembly.") - G.use(2) - mineral = "[M]" - name = "near finished [M] airlock assembly" - airlock_type = text2path ("/obj/machinery/door/airlock/[M]") - glass_type = /obj/machinery/door/airlock/glass + if(!noglass) + if(!glass) + if(istype(G, /obj/item/stack/sheet/rglass) || istype(G, /obj/item/stack/sheet/glass)) + playsound(src, 'sound/items/crowbar.ogg', 100, 1) + user.visible_message("[user] adds [G.name] to the airlock assembly.", \ + "You start to install [G.name] into the airlock assembly...") + if(do_after(user, 40, target = src)) + if(G.get_amount() < 1 || glass) + return + if(G.type == /obj/item/stack/sheet/rglass) + to_chat(user, "You install [G.name] windows into the airlock assembly.") + heat_proof_finished = 1 //reinforced glass makes the airlock heat-proof + name = "near finished heat-proofed window airlock assembly" + else + to_chat(user, "You install regular glass windows into the airlock assembly.") + name = "near finished window airlock assembly" + G.use(1) + glass = TRUE + if(!mineral) + if(istype(G, /obj/item/stack/sheet/mineral) && G.sheettype) + var/M = G.sheettype + if(G.get_amount() >= 2) + playsound(src, 'sound/items/crowbar.ogg', 100, 1) + user.visible_message("[user] adds [G.name] to the airlock assembly.", \ + "You start to install [G.name] into the airlock assembly...") + if(do_after(user, 40, target = src)) + if(G.get_amount() < 2 || mineral) + return + to_chat(user, "You install [M] plating into the airlock assembly.") + G.use(2) + var/mineralassembly = text2path("/obj/structure/door_assembly/door_assembly_[M]") + var/obj/structure/door_assembly/MA = new mineralassembly(loc) + transfer_assembly_vars(src, MA, TRUE) + else + to_chat(user, "You need at least two sheets add a mineral cover!") + else + to_chat(user, "You cannot add [G] to [src]!") + else + to_chat(user, "You cannot add [G] to [src]!") - else if(istype(W, /obj/item/screwdriver) && state == 2 ) + else if(istype(W, /obj/item/screwdriver) && state == AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER ) playsound(src, W.usesound, 100, 1) user.visible_message("[user] finishes the airlock.", \ "You start finishing the airlock...") if(do_after(user, 40*W.toolspeed, target = src)) - if(loc && state == 2) + if(loc && state == AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER) to_chat(user, "You finish the airlock.") var/obj/machinery/door/airlock/door - if(mineral == "glass") + if(glass) door = new glass_type( loc ) else door = new airlock_type( loc ) + door.setDir(dir) //door.req_access = req_access door.electronics = electronics door.heat_proof = heat_proof_finished @@ -703,38 +493,66 @@ door.req_access = electronics.accesses if(created_name) door.name = created_name + else + door.name = base_name + door.previous_airlock = previous_assembly electronics.forceMove(door) qdel(src) else return ..() + update_name() update_icon() /obj/structure/door_assembly/update_icon() cut_overlays() - if(!material) + if(!glass) add_overlay(get_airlock_overlay("fill_construction", icon)) - else - add_overlay(get_airlock_overlay("[material]_construction", overlays_file)) + else if(glass) + add_overlay(get_airlock_overlay("glass_construction", overlays_file)) add_overlay(get_airlock_overlay("panel_c[state+1]", overlays_file)) +/obj/structure/door_assembly/proc/update_name() + name = "" + switch(state) + if(AIRLOCK_ASSEMBLY_NEEDS_WIRES) + if(anchored) + name = "secured " + if(AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS) + name = "wired " + if(AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER) + name = "near finished " + name += "[heat_proof_finished ? "heat-proofed " : ""][glass ? "window " : ""][base_name] assembly" + +/obj/structure/door_assembly/proc/transfer_assembly_vars(obj/structure/door_assembly/source, obj/structure/door_assembly/target, previous = FALSE) + target.glass = source.glass + target.heat_proof_finished = source.heat_proof_finished + target.created_name = source.created_name + target.state = source.state + target.anchored = source.anchored + if(previous) + target.previous_assembly = source.type + if(electronics) + target.electronics = source.electronics + source.electronics.forceMove(target) + target.update_icon() + target.update_name() + qdel(source) /obj/structure/door_assembly/deconstruct(disassembled = TRUE) if(!(flags_1 & NODECONSTRUCT_1)) var/turf/T = get_turf(src) - var/metal_amt = 4 if(!disassembled) - metal_amt = rand(2,4) - new /obj/item/stack/sheet/metal(T, metal_amt) - if(mineral) - if (mineral == "glass") - if(disassembled) - if (heat_proof_finished) - new /obj/item/stack/sheet/rglass(T) - else - new /obj/item/stack/sheet/glass(T) + material_amt = rand(2,4) + new material_type(T, material_amt) + if(glass) + if(disassembled) + if(heat_proof_finished) + new /obj/item/stack/sheet/rglass(T) else - new /obj/item/shard(T) + new /obj/item/stack/sheet/glass(T) else - var/obj/item/stack/sheet/mineral/mineral_path = text2path("/obj/item/stack/sheet/mineral/[mineral]") - new mineral_path(T, 2) + new /obj/item/shard(T) + if(mineral) + var/obj/item/stack/sheet/mineral/mineral_path = text2path("/obj/item/stack/sheet/mineral/[mineral]") + new mineral_path(T, 2) qdel(src) diff --git a/code/game/objects/structures/electricchair.dm b/code/game/objects/structures/electricchair.dm index 81c9e9cc63..f2b0efb6b7 100644 --- a/code/game/objects/structures/electricchair.dm +++ b/code/game/objects/structures/electricchair.dm @@ -15,7 +15,7 @@ var/obj/structure/chair/C = new /obj/structure/chair(loc) playsound(loc, W.usesound, 50, 1) C.setDir(dir) - part.loc = loc + part.forceMove(loc) part.master = null part = null qdel(src) diff --git a/code/game/objects/structures/fireplace.dm b/code/game/objects/structures/fireplace.dm index 04d7f983c0..2735bd7e81 100644 --- a/code/game/objects/structures/fireplace.dm +++ b/code/game/objects/structures/fireplace.dm @@ -129,7 +129,7 @@ if(burn_time_remaining() < MAXIMUM_BURN_TIMER) flame_expiry_timer = world.time + MAXIMUM_BURN_TIMER else - fuel_added = Clamp(fuel_added + amount, 0, MAXIMUM_BURN_TIMER) + fuel_added = CLAMP(fuel_added + amount, 0, MAXIMUM_BURN_TIMER) /obj/structure/fireplace/proc/burn_time_remaining() if(lit) diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index 260285aff9..f7071cd0a5 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -285,10 +285,13 @@ user.remove_alt_appearance("sneaking_mission") /obj/item/twohanded/required/kirbyplants/random + icon = 'icons/obj/flora/_flora.dmi' + icon_state = "random_plant" var/list/static/states /obj/item/twohanded/required/kirbyplants/random/Initialize() . = ..() + icon = 'icons/obj/flora/plants.dmi' if(!states) generate_states() icon_state = pick(states) diff --git a/code/game/objects/structures/fluff.dm b/code/game/objects/structures/fluff.dm index a151406ef3..7dcd8c107a 100644 --- a/code/game/objects/structures/fluff.dm +++ b/code/game/objects/structures/fluff.dm @@ -33,7 +33,7 @@ /obj/structure/fluff/empty_sleeper //Empty sleepers are created by a good few ghost roles in lavaland. name = "empty sleeper" desc = "An open sleeper. It looks as though it would be awaiting another patient, were it not broken." - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper-open" /obj/structure/fluff/empty_sleeper/nanotrasen diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm index 9a2798eacc..fe6a8c69c2 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -76,7 +76,7 @@ name = "timeless prison" desc = "Although this stasis pod looks medicinal, it seems as though it's meant to preserve something for a very long time." mob_name = "a penitent exile" - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" roundstart = FALSE death = FALSE @@ -259,7 +259,7 @@ name = "prisoner containment sleeper" desc = "A sleeper designed to put its occupant into a deep coma, unbreakable until the sleeper turns off. This one's glass is cracked and you can see a pale, sleeping face staring out." mob_name = "an escaped prisoner" - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper_s" outfit = /datum/outfit/lavalandprisoner roundstart = FALSE @@ -296,7 +296,7 @@ name = "staff sleeper" desc = "A sleeper designed for long-term stasis between guest visits." mob_name = "hotel staff member" - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper_s" objectives = "Cater to visiting guests with your fellow staff. Do not leave your assigned hotel and always remember: The customer is always right!" death = FALSE @@ -393,7 +393,7 @@ name = "Syndicate Operative" roundstart = FALSE death = FALSE - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper_s" id_access_list = list(ACCESS_SYNDICATE) outfit = /datum/outfit/syndicate_empty @@ -461,7 +461,7 @@ name = "old cryogenics pod" desc = "A humming cryo pod. You can barely recognise a security uniform underneath the built up ice. The machine is attempting to wake up its occupant." mob_name = "a security officer" - icon = 'icons/obj/cryogenic2.dmi' + icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" roundstart = FALSE death = FALSE @@ -485,7 +485,7 @@ name = "old cryogenics pod" desc = "A humming cryo pod. You can barely recognise an engineering uniform underneath the built up ice. The machine is attempting to wake up its occupant." mob_name = "an engineer" - icon = 'icons/obj/cryogenic2.dmi' + icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" roundstart = FALSE death = FALSE @@ -509,7 +509,7 @@ name = "old cryogenics pod" desc = "A humming cryo pod. You can barely recognise a science uniform underneath the built up ice. The machine is attempting to wake up its occupant." mob_name = "a scientist" - icon = 'icons/obj/cryogenic2.dmi' + icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" roundstart = FALSE death = FALSE @@ -535,7 +535,7 @@ name = "space pirate sleeper" desc = "A cryo sleeper smelling faintly of rum." random = TRUE - icon = 'icons/obj/cryogenic2.dmi' + icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" mob_name = "a space pirate" mob_species = /datum/species/human @@ -561,7 +561,7 @@ /obj/effect/mob_spawn/human/pirate/Destroy() new/obj/structure/showcase/machinery/oldpod/used(drop_location()) return ..() - + /obj/effect/mob_spawn/human/pirate/captain rank = "Captain" outfit = /datum/outfit/pirate/space/captain diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 45aa4a0889..a7bfb92c45 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -26,11 +26,11 @@ update_icon() /obj/structure/grille/update_icon() - if(QDELETED(src)) + if(QDELETED(src) || broken) return var/ratio = obj_integrity / max_integrity - ratio = Ceiling(ratio*4) * 25 + ratio = CEILING(ratio*4, 1) * 25 if(smooth) queue_smooth(src) diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index b6332492dd..0f12f847d7 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -5,7 +5,7 @@ icon_state = "cart" anchored = FALSE density = TRUE - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER //copypaste sorry var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite var/obj/item/storage/bag/trash/mybag = null diff --git a/code/game/objects/structures/kitchen_spike.dm b/code/game/objects/structures/kitchen_spike.dm index 5f1fa2ebb7..d6b50d0b1a 100644 --- a/code/game/objects/structures/kitchen_spike.dm +++ b/code/game/objects/structures/kitchen_spike.dm @@ -81,7 +81,7 @@ return playsound(src.loc, 'sound/effects/splat.ogg', 25, 1) L.visible_message("[user] slams [L] onto the meat spike!", "[user] slams you onto the meat spike!", "You hear a squishy wet noise.") - L.loc = src.loc + L.forceMove(drop_location()) L.emote("scream") L.add_splatter_floor() L.adjustBruteLoss(30) diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index c0dcd866d8..306d3d0b84 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -67,7 +67,7 @@ resistance_flags |= INDESTRUCTIBLE /obj/structure/lattice/clockwork/ratvar_act() - if(IsOdd(x+y)) + if(ISODD(x+y)) icon = 'icons/obj/smooth_structures/lattice_clockwork_large.dmi' pixel_x = -9 pixel_y = -9 @@ -124,7 +124,7 @@ resistance_flags |= INDESTRUCTIBLE /obj/structure/lattice/catwalk/clockwork/ratvar_act() - if(IsOdd(x+y)) + if(ISODD(x+y)) icon = 'icons/obj/smooth_structures/catwalk_clockwork_large.dmi' pixel_x = -9 pixel_y = -9 diff --git a/code/game/objects/structures/manned_turret.dm b/code/game/objects/structures/manned_turret.dm index 669abb792a..ceef3ef0c0 100644 --- a/code/game/objects/structures/manned_turret.dm +++ b/code/game/objects/structures/manned_turret.dm @@ -37,7 +37,7 @@ buckled_mob.pixel_x = 0 buckled_mob.pixel_y = 0 if(buckled_mob.client) - buckled_mob.client.change_view(world.view) + buckled_mob.client.change_view(CONFIG_GET(string/default_view)) anchored = FALSE . = ..() STOP_PROCESSING(SSfastprocess, src) diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index 711f9baf0b..44c12a21a1 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -89,7 +89,7 @@ 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/races_blacklist = list("skeleton", "agent", "angel", "military_synth", "memezombies") var/list/choosable_races = list() /obj/structure/mirror/magic/New() diff --git a/code/game/objects/structures/mop_bucket.dm b/code/game/objects/structures/mop_bucket.dm index b2dc64fec7..d468e87a34 100644 --- a/code/game/objects/structures/mop_bucket.dm +++ b/code/game/objects/structures/mop_bucket.dm @@ -1,24 +1,24 @@ -/obj/structure/mopbucket - name = "mop bucket" - desc = "Fill it with water, but don't forget a mop!" - icon = 'icons/obj/janitor.dmi' - icon_state = "mopbucket" +/obj/structure/mopbucket + name = "mop bucket" + desc = "Fill it with water, but don't forget a mop!" + icon = 'icons/obj/janitor.dmi' + icon_state = "mopbucket" density = TRUE - container_type = OPENCONTAINER_1 - var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite - - -/obj/structure/mopbucket/New() - create_reagents(100) - ..() - -/obj/structure/mopbucket/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/mop)) - if(reagents.total_volume < 1) - to_chat(user, "[src] is out of water!
    ") - else - reagents.trans_to(I, 5) - to_chat(user, "You wet [I] in [src].") - playsound(loc, 'sound/effects/slosh.ogg', 25, 1) - else - return ..() \ No newline at end of file + container_type = OPENCONTAINER + var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite + + +/obj/structure/mopbucket/New() + create_reagents(100) + ..() + +/obj/structure/mopbucket/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/mop)) + if(reagents.total_volume < 1) + to_chat(user, "[src] is out of water!
    ") + else + reagents.trans_to(I, 5) + to_chat(user, "You wet [I] in [src].") + playsound(loc, 'sound/effects/slosh.ogg', 25, 1) + else + return ..() diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index 8b3d2981e2..717b624839 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -301,7 +301,7 @@ GLOBAL_LIST_EMPTY(crematoriums) return if(!ismob(user) || user.lying || user.incapacitated()) return - O.loc = src.loc + O.forceMove(src.loc) if (user != O) visible_message("[user] stuffs [O] into [src].") return diff --git a/code/game/objects/structures/musician.dm b/code/game/objects/structures/musician.dm index 8d62168f7c..a73824ca2b 100644 --- a/code/game/objects/structures/musician.dm +++ b/code/game/objects/structures/musician.dm @@ -119,7 +119,7 @@ else cur_oct[cur_note] = text2num(ni) if(user.dizziness > 0 && prob(user.dizziness / 2)) - cur_note = Clamp(cur_note + rand(round(-user.dizziness / 10), round(user.dizziness / 10)), 1, 7) + cur_note = CLAMP(cur_note + rand(round(-user.dizziness / 10), round(user.dizziness / 10)), 1, 7) if(user.dizziness > 0 && prob(user.dizziness / 5)) if(prob(30)) cur_acc[cur_note] = "#" @@ -328,6 +328,8 @@ density = TRUE var/datum/song/song +/obj/structure/piano/unanchored + anchored = FALSE /obj/structure/piano/New() ..() diff --git a/code/game/objects/structures/noticeboard.dm b/code/game/objects/structures/noticeboard.dm index aeca1453e3..f667832843 100644 --- a/code/game/objects/structures/noticeboard.dm +++ b/code/game/objects/structures/noticeboard.dm @@ -18,7 +18,7 @@ if(notices > 4) break if(istype(I, /obj/item/paper)) - I.loc = src + I.forceMove(src) notices++ icon_state = "nboard0[notices]" @@ -58,7 +58,7 @@ return var/obj/item/I = locate(href_list["remove"]) in contents if(istype(I) && I.loc == src) - I.loc = usr.loc + I.forceMove(usr.loc) usr.put_in_hands(I) notices-- icon_state = "nboard0[notices]" diff --git a/code/game/objects/structures/reflector.dm b/code/game/objects/structures/reflector.dm index e47afd53d4..1ae513f847 100644 --- a/code/game/objects/structures/reflector.dm +++ b/code/game/objects/structures/reflector.dm @@ -165,7 +165,7 @@ to_chat(user, "You can't do that right now!") return if(!isnull(new_angle)) - setAngle(NORM_ROT(new_angle)) + setAngle(SIMPLIFY_DEGREES(new_angle)) return TRUE /obj/structure/reflector/AltClick(mob/user) @@ -197,16 +197,12 @@ anchored = TRUE /obj/structure/reflector/single/auto_reflect(obj/item/projectile/P, pdir, turf/ploc, pangle) - var/incidence = get_angle_of_incidence(rotation_angle, P.Angle) - var/incidence_norm = get_angle_of_incidence(rotation_angle, P.Angle, FALSE) - if((incidence_norm > -90) && (incidence_norm < 90)) + var/incidence = GET_ANGLE_OF_INCIDENCE(rotation_angle, P.Angle) + var/norm_inc = WRAP(incidence, -90, 90) + var/new_angle = WRAP(rotation_angle + norm_inc, 180, -180) + if(ISINRANGE_EX(norm_inc, -90, 90)) return FALSE - var/new_angle_s = rotation_angle + incidence - while(new_angle_s > 180) // Translate to regular projectile degrees - new_angle_s -= 360 - while(new_angle_s < -180) - new_angle_s += 360 - P.Angle = new_angle_s + P.Angle = new_angle return ..() //DOUBLE @@ -228,17 +224,12 @@ anchored = TRUE /obj/structure/reflector/double/auto_reflect(obj/item/projectile/P, pdir, turf/ploc, pangle) - var/incidence = get_angle_of_incidence(rotation_angle, P.Angle) - var/incidence_norm = get_angle_of_incidence(rotation_angle, P.Angle, FALSE) - var/invert = ((incidence_norm > -90) && (incidence_norm < 90)) - var/new_angle_s = rotation_angle + incidence - if(invert) - new_angle_s += 180 - while(new_angle_s > 180) // Translate to regular projectile degrees - new_angle_s -= 360 - while(new_angle_s < -180) - new_angle_s += 360 - P.Angle = new_angle_s + var/incidence = GET_ANGLE_OF_INCIDENCE(rotation_angle, P.Angle) + var/norm_inc = WRAP(incidence, -90, 90) + var/new_angle = WRAP(rotation_angle + norm_inc, 180, -180) + if(ISINRANGE_EX(norm_inc, -90, 90)) + new_angle += 180 + P.Angle = new_angle return ..() //BOX diff --git a/code/game/objects/structures/safe.dm b/code/game/objects/structures/safe.dm index 733dcf646d..9df47743a4 100644 --- a/code/game/objects/structures/safe.dm +++ b/code/game/objects/structures/safe.dm @@ -43,7 +43,7 @@ FLOOR SAFES return if(I.w_class + space <= maxspace) space += I.w_class - I.loc = src + I.forceMove(src) /obj/structure/safe/proc/check_unlocked(mob/user, canhear) @@ -97,10 +97,10 @@ FLOOR SAFES if(!ishuman(usr)) return var/mob/living/carbon/human/user = usr - + if(!user.canUseTopic(src)) return - + var/canhear = 0 if(user.is_holding_item_of_type(/obj/item/clothing/neck/stethoscope)) canhear = 1 diff --git a/code/game/objects/structures/showcase.dm b/code/game/objects/structures/showcase.dm index 4d1c60acf8..0aa447ca58 100644 --- a/code/game/objects/structures/showcase.dm +++ b/code/game/objects/structures/showcase.dm @@ -36,18 +36,18 @@ /obj/structure/showcase/horrific_experiment name = "horrific experiment" desc = "Some sort of pod filled with blood and viscera. You swear you can see it moving..." - icon = 'icons/obj/cloning.dmi' + icon = 'icons/obj/machines/cloning.dmi' icon_state = "pod_g" /obj/structure/showcase/machinery/oldpod - name = "damaged cyrogenic pod" - desc = "A damaged cyrogenic pod long since lost to time, including its former occupant..." - icon = 'icons/obj/cryogenic2.dmi' + name = "damaged cryogenic pod" + desc = "A damaged cryogenic pod long since lost to time, including its former occupant..." + icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper-open" /obj/structure/showcase/machinery/oldpod/used - name = "opened cyrogenic pod" - desc = "Cyrogenic pod that has recently discharged its occupand. The pod appears non-functional." + name = "opened cryogenic pod" + desc = "A cryogenic pod that has recently discharged its occupant. The pod appears non-functional." /obj/structure/showcase/cyborg/old name = "Cyborg Statue" @@ -83,7 +83,7 @@ /obj/structure/showcase/machinery/cloning_pod name = "cloning pod exhibit" desc = "Signs describe how cloning pods like these ensure that every Nanotrasen employee can carry out their contracts in full, even in the unlikely event of their catastrophic death. Hopefully they aren't all made of cardboard, like this one." - icon = 'icons/obj/cloning.dmi' + icon = 'icons/obj/machines/cloning.dmi' icon_state = "pod_0" /obj/structure/showcase/perfect_employee diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm index b89dca9d4f..67b42c128c 100644 --- a/code/game/objects/structures/statues.dm +++ b/code/game/objects/structures/statues.dm @@ -177,8 +177,8 @@ else return ..() -/obj/structure/statue/plasma/proc/PlasmaBurn() - atmos_spawn_air("plasma=400;TEMP=1000") +/obj/structure/statue/plasma/proc/PlasmaBurn(exposed_temperature) + atmos_spawn_air("plasma=[oreAmount*10];TEMP=[exposed_temperature]") deconstruct(FALSE) /obj/structure/statue/plasma/proc/ignite(exposed_temperature) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 26582515f8..95c2380802 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -121,7 +121,7 @@ T.quick_empty() for(var/obj/item/C in oldContents) - C.loc = src.loc + C.forceMove(drop_location()) user.visible_message("[user] empties [I] on [src].") return @@ -134,8 +134,8 @@ if(!click_params || !click_params["icon-x"] || !click_params["icon-y"]) return //Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf) - I.pixel_x = Clamp(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2) - I.pixel_y = Clamp(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2) + I.pixel_x = CLAMP(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2) + I.pixel_y = CLAMP(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2) return 1 else return ..() diff --git a/code/game/objects/structures/target_stake.dm b/code/game/objects/structures/target_stake.dm index c3496678c2..58b4186ad5 100644 --- a/code/game/objects/structures/target_stake.dm +++ b/code/game/objects/structures/target_stake.dm @@ -18,7 +18,7 @@ /obj/structure/target_stake/Move() ..() if(pinned_target) - pinned_target.loc = loc + pinned_target.forceMove(loc) /obj/structure/target_stake/attackby(obj/item/target/T, mob/user) if(pinned_target) @@ -36,7 +36,7 @@ /obj/structure/target_stake/proc/removeTarget(mob/user) pinned_target.layer = OBJ_LAYER - pinned_target.loc = user.loc + pinned_target.forceMove(user.loc) pinned_target.nullPinnedLoc() nullPinnedTarget() if(ishuman(user)) @@ -44,7 +44,7 @@ user.put_in_hands(pinned_target) to_chat(user, "You take the target out of the stake.") else - pinned_target.loc = get_turf(user) + pinned_target.forceMove(user.drop_location()) to_chat(user, "You take the target out of the stake.") /obj/structure/target_stake/bullet_act(obj/item/projectile/P) diff --git a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm index e93372b831..eabe4499a4 100644 --- a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm +++ b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm @@ -136,7 +136,7 @@ last_delay = current_tube.enter_delay(src, next_dir) sleep(last_delay) setDir(next_dir) - loc = next_loc // When moving from one tube to another, skip collision and such. + forceMove(next_loc) // When moving from one tube to another, skip collision and such. density = current_tube.density if(current_tube && current_tube.should_stop_pod(src, next_dir)) diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 0e5675a5a0..77b992704a 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -59,7 +59,7 @@ if(ishuman(user)) user.put_in_hands(I) else - I.loc = get_turf(src) + I.forceMove(drop_location()) to_chat(user, "You find [I] in the cistern.") w_items -= I.w_class else @@ -483,9 +483,9 @@ if(istype(O, /obj/item/reagent_containers)) var/obj/item/reagent_containers/RG = O - if(RG.container_type & OPENCONTAINER_1) + if(RG.is_refillable()) if(!RG.reagents.holder_full()) - RG.reagents.add_reagent("[dispensedreagent]", min(RG.volume - RG.reagents.total_volume, RG.amount_per_transfer_from_this)) + RG.reagents.add_reagent(dispensedreagent, min(RG.volume - RG.reagents.total_volume, RG.amount_per_transfer_from_this)) to_chat(user, "You fill [RG] from [src].") return TRUE to_chat(user, "\The [RG] is full.") @@ -533,7 +533,7 @@ O.clean_blood() O.acid_level = 0 create_reagents(5) - reagents.add_reagent("[dispensedreagent]", 5) + reagents.add_reagent(dispensedreagent, 5) reagents.reaction(O, TOUCH) user.visible_message("[user] washes [O] using [src].", \ "You wash [O] using [src].") diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm index b29df0aaf4..bb5be3a501 100644 --- a/code/game/objects/structures/windoor_assembly.dm +++ b/code/game/objects/structures/windoor_assembly.dm @@ -216,13 +216,13 @@ if(do_after(user, 40, target = src)) if(!src || electronics) - W.loc = src.loc + W.forceMove(drop_location()) return to_chat(user, "You install the airlock electronics.") name = "near finished windoor assembly" electronics = W else - W.loc = loc + W.forceMove(drop_location()) //Screwdriver to remove airlock electronics. Step 6 undone. else if(istype(W, /obj/item/screwdriver)) @@ -240,7 +240,7 @@ var/obj/item/electronics/airlock/ae ae = electronics electronics = null - ae.loc = loc + ae.forceMove(drop_location()) else if(istype(W, /obj/item/pen)) var/t = stripped_input(user, "Enter the name for the door.", name, created_name,MAX_NAME_LEN) @@ -285,7 +285,7 @@ else windoor.req_access = electronics.accesses windoor.electronics = electronics - electronics.loc = windoor + electronics.forceMove(windoor) if(created_name) windoor.name = created_name qdel(src) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 2b9494c535..f5aec5c274 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -283,11 +283,10 @@ return if(!disassembled) playsound(src, breaksound, 70, 1) - var/turf/T = loc if(!(flags_1 & NODECONSTRUCT_1)) for(var/i in debris) var/obj/item/I = i - I.loc = T + I.forceMove(drop_location()) transfer_fingerprints_to(I) qdel(src) update_nearby_icons() @@ -380,7 +379,7 @@ return var/ratio = obj_integrity / max_integrity - ratio = Ceiling(ratio*4) * 25 + ratio = CEILING(ratio*4, 1) * 25 if(smooth) queue_smooth(src) diff --git a/code/game/sound.dm b/code/game/sound.dm index b150c1c148..9cfa197738 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -1,4 +1,4 @@ -/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff, frequency = null, channel = 0, pressure_affected = TRUE) +/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff, frequency = null, channel = 0, pressure_affected = TRUE, ignore_walls = TRUE) if(isarea(source)) throw EXCEPTION("playsound(): source is an area") return @@ -10,8 +10,11 @@ // Looping through the player list has the added bonus of working for mobs inside containers var/sound/S = sound(get_sfx(soundin)) - var/maxdistance = (world.view + extrarange) * 3 - for(var/P in GLOB.player_list) + var/maxdistance = (world.view + extrarange) + var/list/listeners = GLOB.player_list + if(!ignore_walls) //these sounds don't carry through walls + listeners = listeners & hearers(maxdistance,turf_source) + for(var/P in listeners) var/mob/M = P if(!M || !M.client) continue @@ -178,6 +181,16 @@ 'sound/vore/prey/death_10.ogg') if("bullet_miss") soundin = pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg') + if("gun_dry_fire") + soundin = pick('sound/weapons/gun_dry_fire_1.ogg', 'sound/weapons/gun_dry_fire_2.ogg', 'sound/weapons/gun_dry_fire_3.ogg', 'sound/weapons/gun_dry_fire_4.ogg') + if("gun_insert_empty_magazine") + soundin = pick('sound/weapons/gun_magazine_insert_empty_1.ogg', 'sound/weapons/gun_magazine_insert_empty_2.ogg', 'sound/weapons/gun_magazine_insert_empty_3.ogg', 'sound/weapons/gun_magazine_insert_empty_4.ogg') + if("gun_insert_full_magazine") + soundin = pick('sound/weapons/gun_magazine_insert_full_1.ogg', 'sound/weapons/gun_magazine_insert_full_2.ogg', 'sound/weapons/gun_magazine_insert_full_3.ogg', 'sound/weapons/gun_magazine_insert_full_4.ogg', 'sound/weapons/gun_magazine_insert_full_5.ogg') + if("gun_remove_empty_magazine") + soundin = pick('sound/weapons/gun_magazine_remove_empty_1.ogg', 'sound/weapons/gun_magazine_remove_empty_2.ogg', 'sound/weapons/gun_magazine_remove_empty_3.ogg', 'sound/weapons/gun_magazine_remove_empty_4.ogg') + if("gun_slide_lock") + soundin = pick('sound/weapons/gun_slide_lock_1.ogg', 'sound/weapons/gun_slide_lock_2.ogg', 'sound/weapons/gun_slide_lock_3.ogg', 'sound/weapons/gun_slide_lock_4.ogg', 'sound/weapons/gun_slide_lock_5.ogg') if("law") soundin = pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg') if("honkbot_e") diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm index ae6aa0cb2d..0eddbc411e 100644 --- a/code/game/turfs/open.dm +++ b/code/game/turfs/open.dm @@ -275,17 +275,12 @@ else qdel(GetComponent(/datum/component/slippery)) return - var/datum/component/slippery/S = LoadComponent(/datum/component/slippery) + var/datum/component/slippery/S = LoadComponent(/datum/component/slippery, NONE, CALLBACK(src, .proc/AfterSlip)) S.intensity = intensity S.lube_flags = lube_flags -/turf/open/ComponentActivated(datum/component/C) - ..() - var/datum/component/slippery/S = C - if(!istype(S)) - return +/turf/open/proc/AfterSlip(mob/living/L) if(wet == TURF_WET_LUBE) - var/mob/living/L = S.slip_victim L.confused = max(L.confused, 8) /turf/open/proc/MakeDry(wet_setting = TURF_WET_WATER) @@ -360,6 +355,6 @@ if (air.gases[/datum/gas/carbon_dioxide] && air.gases[/datum/gas/oxygen]) air.gases[/datum/gas/carbon_dioxide][MOLES]=max(air.gases[/datum/gas/carbon_dioxide][MOLES]-(pulse_strength/1000),0) air.gases[/datum/gas/oxygen][MOLES]=max(air.gases[/datum/gas/oxygen][MOLES]-(pulse_strength/2000),0) - ASSERT_GAS(/datum/gas/pluoxium,air) + air.assert_gas(/datum/gas/pluoxium) air.gases[/datum/gas/pluoxium][MOLES]+=(pulse_strength/4000) - air.garbage_collect() \ No newline at end of file + air.garbage_collect() diff --git a/code/game/turfs/simulated/floor/mineral_floor.dm b/code/game/turfs/simulated/floor/mineral_floor.dm index 5de453d531..8ad09829b2 100644 --- a/code/game/turfs/simulated/floor/mineral_floor.dm +++ b/code/game/turfs/simulated/floor/mineral_floor.dm @@ -129,10 +129,10 @@ icons = list("bananium","bananium_dam") var/spam_flag = 0 -/turf/open/floor/mineral/bananium/Entered(var/mob/AM) +/turf/open/floor/mineral/bananium/Entered(var/mob/living/L) .=..() if(!.) - if(istype(AM)) + if(istype(L)) squeek() /turf/open/floor/mineral/bananium/attackby(obj/item/W, mob/user, params) diff --git a/code/game/turfs/simulated/floor/plating/asteroid.dm b/code/game/turfs/simulated/floor/plating/asteroid.dm index abbf83a164..1419036d07 100644 --- a/code/game/turfs/simulated/floor/plating/asteroid.dm +++ b/code/game/turfs/simulated/floor/plating/asteroid.dm @@ -87,6 +87,9 @@ /turf/open/floor/plating/asteroid/basalt/Initialize() . = ..() set_basalt_light(src) + GET_COMPONENT(arch, /datum/component/archaeology) + ASSERT(isnull(arch.callback)) + arch.callback = CALLBACK(src, /atom/proc/set_light, 0) /proc/set_basalt_light(turf/open/floor/B) switch(B.icon_state) @@ -95,12 +98,6 @@ if("basalt5", "basalt9") B.set_light(1.4, 0.6, LIGHT_COLOR_LAVA) //barely anything! -/turf/open/floor/plating/asteroid/basalt/ComponentActivated(datum/component/C) - ..() - if(istype(C, /datum/component/archaeology)) - set_light(0) - - ///////Surface. The surface is warm, but survivable without a suit. Internals are required. The floors break to chasms, which drop you into the underground. /turf/open/floor/plating/asteroid/basalt/lava_land_surface @@ -191,7 +188,7 @@ break var/list/L = list(45) - if(IsOdd(dir2angle(dir))) // We're going at an angle and we want thick angled tunnels. + if(ISODD(dir2angle(dir))) // We're going at an angle and we want thick angled tunnels. L += -45 // Expand the edges of our tunnel diff --git a/code/game/turfs/simulated/wall/misc_walls.dm b/code/game/turfs/simulated/wall/misc_walls.dm index bb45e2df20..ecc389af88 100644 --- a/code/game/turfs/simulated/wall/misc_walls.dm +++ b/code/game/turfs/simulated/wall/misc_walls.dm @@ -56,6 +56,7 @@ sheet_amount = 1 girder_type = /obj/structure/destructible/clockwork/wall_gear baseturf = /turf/open/floor/clockwork/reebe + var/heated var/obj/effect/clockwork/overlay/wall/realappearence /turf/closed/wall/clockwork/Initialize() @@ -100,7 +101,7 @@ var/obj/structure/sign/poster/P = O P.roll_and_drop(src) else - O.loc = src + O.forceMove(src) /turf/closed/wall/clockwork/devastate_wall() for(var/i in 1 to 2) @@ -110,6 +111,36 @@ for(var/i in 1 to 3) new/obj/item/clockwork/alloy_shards/small(src) +/turf/closed/wall/clockwork/attack_hulk(mob/living/user, does_attack_animation = 0) + ..() + if(heated) + to_chat(user, "The wall is searing hot to the touch!") + user.adjustFireLoss(5) + playsound(src, 'sound/machines/fryer/deep_fryer_emerge.ogg', 50, TRUE) + +/turf/closed/wall/clockwork/mech_melee_attack(obj/mecha/M) + ..() + if(heated) + to_chat(M.occupant, "The wall's intense heat completely reflects your [M.name]'s attack!") + M.take_damage(20, BURN) + +/turf/closed/wall/clockwork/proc/turn_up_the_heat() + if(!heated) + name = "superheated [name]" + visible_message("[src] sizzles with heat!") + playsound(src, 'sound/machines/fryer/deep_fryer_emerge.ogg', 50, TRUE) + heated = TRUE + hardness = -100 //Lower numbers are tougher, so this makes the wall essentially impervious to smashing + slicing_duration = 150 + animate(realappearence, color = "#FFC3C3", time = 5) + else + name = initial(name) + visible_message("[src] cools down.") + heated = FALSE + hardness = initial(hardness) + slicing_duration = initial(slicing_duration) + animate(realappearence, color = initial(realappearence.color), time = 25) + /turf/closed/wall/vault icon = 'icons/turf/walls.dmi' diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index 6d8db55ad8..00377e4f3f 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -1,3 +1,5 @@ +#define MAX_DENT_DECALS 15 + /turf/closed/wall name = "wall" desc = "A huge chunk of metal used to separate rooms." @@ -52,7 +54,7 @@ var/turf/p_turf = get_turf(P) var/face_direction = get_dir(src, p_turf) var/face_angle = dir2angle(face_direction) - var/incidence_s = get_angle_of_incidence(face_angle, P.Angle) + var/incidence_s = WRAP(GET_ANGLE_OF_INCIDENCE(face_angle, P.Angle), -90, 90) var/new_angle = face_angle + incidence_s var/new_angle_s = new_angle while(new_angle_s > 180) // Translate to regular projectile degrees @@ -297,6 +299,9 @@ return FALSE /turf/closed/wall/proc/add_dent(denttype, x=rand(-8, 8), y=rand(-8, 8)) + if(LAZYLEN(dent_decals) >= MAX_DENT_DECALS) + return + var/mutable_appearance/decal = pick(dent_decal_list[denttype]) decal.pixel_x = x decal.pixel_y = y @@ -304,3 +309,5 @@ cut_overlay(dent_decals) LAZYADD(dent_decals, decal) add_overlay(dent_decals) + +#undef MAX_DENT_DECALS diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index 54c43cdcea..5399b748e6 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -130,15 +130,20 @@ return if(destination_z) + var/old_z = A.z A.x = destination_x A.y = destination_y A.z = destination_z + if (old_z != destination_z) + A.onTransitZ(old_z, destination_z) if(isliving(A)) var/mob/living/L = A - if(L.pulling) + var/atom/movable/AM = L.pulling + if(AM) var/turf/T = get_step(L.loc,turn(A.dir, 180)) - L.pulling.loc = T + AM.forceMove(T) + L.start_pulling(AM) //now we're on the new z_level, proceed the space drifting stoplag()//Let a diagonal move finish, if necessary @@ -199,4 +204,3 @@ destination_x = dest_x destination_y = dest_y destination_z = dest_z - diff --git a/code/modules/NTNet/relays.dm b/code/modules/NTNet/relays.dm index 52ca6d1822..1dac5ed0fd 100644 --- a/code/modules/NTNet/relays.dm +++ b/code/modules/NTNet/relays.dm @@ -117,4 +117,4 @@ D.target = null D.error = "Connection to quantum relay severed" - return ..() \ No newline at end of file + return ..() diff --git a/code/modules/VR/vr_sleeper.dm b/code/modules/VR/vr_sleeper.dm index 429e917e36..1ef8a71cb4 100644 --- a/code/modules/VR/vr_sleeper.dm +++ b/code/modules/VR/vr_sleeper.dm @@ -5,7 +5,7 @@ /obj/machinery/vr_sleeper name = "virtual reality sleeper" desc = "A sleeper modified to alter the subconscious state of the user, allowing them to visit virtual worlds." - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" state_open = TRUE anchored = TRUE diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index f43803631b..73fc0d43f3 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -18,7 +18,7 @@ return list("reason"="invalid login data", "desc"="Error: Could not check ban status, Please try again. Error message: Your computer provided an invalid Computer ID.)") var/admin = 0 var/ckey = ckey(key) - if((ckey in GLOB.admin_datums) || (ckey in GLOB.deadmins)) + if(GLOB.admin_datums[ckey] || GLOB.deadmins[ckey]) admin = 1 //Whitelist diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index d2eebf48a7..43651cebef 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -705,56 +705,60 @@ /datum/admins/proc/output_all_devil_info() var/devil_number = 0 - for(var/D in SSticker.mode.devils) + for(var/datum/mind/D in SSticker.mode.devils) devil_number++ - to_chat(usr, "Devil #[devil_number]:

    " + SSticker.mode.printdevilinfo(D)) + var/datum/antagonist/devil/devil = D.has_antag_datum(/datum/antagonist/devil) + to_chat(usr, "Devil #[devil_number]:

    " + devil.printdevilinfo()) if(!devil_number) to_chat(usr, "No Devils located" ) /datum/admins/proc/output_devil_info(mob/living/M) if(is_devil(M)) - to_chat(usr, SSticker.mode.printdevilinfo(M.mind)) + var/datum/antagonist/devil/devil = M.mind.has_antag_datum(/datum/antagonist/devil) + to_chat(usr, devil.printdevilinfo()) else to_chat(usr, "[M] is not a devil.") /datum/admins/proc/manage_free_slots() if(!check_rights()) return - var/dat = "Manage Free Slots" + var/datum/browser/browser = new(usr, "jobmanagement", "Manage Free Slots", 520) + var/list/dat = list() var/count = 0 - if(!SSticker.HasRoundStarted()) - alert(usr, "You cannot manage jobs before the round starts!") + if(!SSjob.initialized) + alert(usr, "You cannot manage jobs before the job subsystem is initialized!") return - for(var/datum/job/job in SSjob.occupations) + dat += "" + + for(var/j in SSjob.occupations) + var/datum/job/job = j count++ var/J_title = html_encode(job.title) var/J_opPos = html_encode(job.total_positions - (job.total_positions - job.current_positions)) var/J_totPos = html_encode(job.total_positions) - if(job.total_positions < 0) - dat += "[J_title]: [J_opPos] (unlimited)" - else - dat += "[J_title]: [J_opPos]/[J_totPos]" + dat += "" continue - if(job.total_positions >= 0) - dat += " Add | " - if(job.total_positions > job.current_positions) - dat += "Remove | " - else - dat += "Remove | " - dat += "Unlimit" else - dat += " Limit" - dat += "
    " + dat += "" + dat += "" + else + dat += "Limit" - dat += "" - var/winheight = 100 + (count * 20) - winheight = min(winheight, 690) - usr << browse(dat, "window=players;size=375x[winheight]") + browser.height = min(100 + count * 20, 650) + browser.set_content(dat.Join()) + browser.open() /datum/admins/proc/create_or_modify_area() set category = "Debug" diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm index e169f656c4..f259e9b1e9 100644 --- a/code/modules/admin/admin_investigate.dm +++ b/code/modules/admin/admin_investigate.dm @@ -4,13 +4,15 @@ var/F = file("[GLOB.log_directory]/[subject].html") WRITE_FILE(F, "[time_stamp()] [REF(src)] ([x],[y],[z]) || [src] [message]
    ") -/client/proc/investigate_show(subject in list("hrefs","notes, memos, watchlist", INVESTIGATE_EXONET, INVESTIGATE_PORTAL, INVESTIGATE_SINGULO, INVESTIGATE_WIRES, INVESTIGATE_TELESCI, INVESTIGATE_GRAVITY, INVESTIGATE_RECORDS, INVESTIGATE_CARGO, INVESTIGATE_SUPERMATTER, INVESTIGATE_ATMOS, INVESTIGATE_EXPERIMENTOR, INVESTIGATE_BOTANY, INVESTIGATE_HALLUCINATIONS, INVESTIGATE_RADIATION) ) +/client/proc/investigate_show(subject in list("hrefs","notes, memos, watchlist", INVESTIGATE_RESEARCH, INVESTIGATE_EXONET, INVESTIGATE_PORTAL, INVESTIGATE_SINGULO, INVESTIGATE_WIRES, INVESTIGATE_TELESCI, INVESTIGATE_GRAVITY, INVESTIGATE_RECORDS, INVESTIGATE_CARGO, INVESTIGATE_SUPERMATTER, INVESTIGATE_ATMOS, INVESTIGATE_EXPERIMENTOR, INVESTIGATE_BOTANY, INVESTIGATE_HALLUCINATIONS, INVESTIGATE_RADIATION) ) set name = "Investigate" set category = "Admin" if(!holder) return switch(subject) if("notes, memos, watchlist") + if(!check_rights(R_ADMIN)) + return browse_messages() else var/F = file("[GLOB.log_directory]/[subject].html") diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm index be9e423a17..201fe75979 100644 --- a/code/modules/admin/admin_ranks.dm +++ b/code/modules/admin/admin_ranks.dm @@ -3,7 +3,7 @@ GLOBAL_PROTECT(admin_ranks) /datum/admin_rank var/name = "NoRank" - var/rights = 0 + var/rights = R_DEFAULT var/list/adds var/list/subs @@ -56,11 +56,13 @@ GLOBAL_PROTECT(admin_ranks) if("varedit") flag = R_VAREDIT if("everything","host","all") - flag = 65535 + flag = ALL if("sound","sounds") flag = R_SOUNDS if("spawn","create") flag = R_SPAWN + if("autologin", "autoadmin") + flag = R_AUTOLOGIN if("@","prev") flag = previous_rights if("rejuv","rejuvinate") @@ -171,21 +173,19 @@ GLOBAL_PROTECT(admin_ranks) #endif -/proc/load_admins(target = null) - if(IsAdminAdvancedProcCall()) - to_chat(usr, "Admin Reload blocked: Advanced ProcCall detected.") - return +/proc/load_admins() //clear the datums references - if(!target) - GLOB.admin_datums.Cut() - for(var/client/C in GLOB.admins) - C.remove_admin_verbs() - C.holder = null - GLOB.admins.Cut() - load_admin_ranks() - //Clear profile access - for(var/A in world.GetConfig("admin")) - world.SetConfig("APP/admin", A, null) + + GLOB.admin_datums.Cut() + for(var/client/C in GLOB.admins) + C.remove_admin_verbs() + C.holder = null + GLOB.admins.Cut() + GLOB.deadmins.Cut() + load_admin_ranks() + //Clear profile access + for(var/A in world.GetConfig("admin")) + world.SetConfig("APP/admin", A, null) var/list/rank_names = list() for(var/datum/admin_rank/R in GLOB.admin_ranks) @@ -208,13 +208,11 @@ GLOBAL_PROTECT(admin_ranks) var/ckey = ckey(entry[1]) var/rank = ckeyEx(entry[2]) - if(!ckey || !rank || (target && ckey != target)) + if(!ckey || !rank) continue - var/datum/admins/D = new(rank_names[rank], ckey) //create the admin datum and store it for later use - if(!D) - continue //will occur if an invalid rank is provided - D.associate(GLOB.directory[ckey]) //find the client for a ckey if they are connected and associate them with the new admin datum + new /datum/admins(rank_names[rank], ckey) + else if(!SSdbcore.Connect()) log_world("Failed to connect to database in load_admins(). Reverting to legacy system.") @@ -229,19 +227,12 @@ GLOBAL_PROTECT(admin_ranks) while(query_load_admins.NextRow()) var/ckey = ckey(query_load_admins.item[1]) var/rank = ckeyEx(query_load_admins.item[2]) - if(target && ckey != target) - continue if(rank_names[rank] == null) WARNING("Admin rank ([rank]) does not exist.") continue - var/datum/admins/D = new(rank_names[rank], ckey) //create the admin datum and store it for later use - if(!D) - continue //will occur if an invalid rank is provided - if(D.rank.rights & R_DEBUG) //grant profile access - world.SetConfig("APP/admin", ckey, "role=admin") - D.associate(GLOB.directory[ckey]) //find the client for a ckey if they are connected and associate them with the new admin datum + new /datum/admins(rank_names[rank], ckey) #ifdef TESTING var/msg = "Admins Built:\n" @@ -298,6 +289,8 @@ GLOBAL_PROTECT(admin_ranks) return var/datum/admins/D = GLOB.admin_datums[adm_ckey] + if (!D) + D = GLOB.deadmins[adm_ckey] switch(task) if("remove") @@ -309,6 +302,7 @@ GLOBAL_PROTECT(admin_ranks) log_admin("[key_name(usr)] attempted to remove [adm_ckey] from the admins list without sufficient rights.") return GLOB.admin_datums -= adm_ckey + GLOB.deadmins -= adm_ckey D.disassociate() updateranktodb(adm_ckey, "player") @@ -350,11 +344,9 @@ GLOBAL_PROTECT(admin_ranks) if(D) //they were previously an admin D.disassociate() //existing admin needs to be disassociated D.rank = R //set the admin_rank as our rank + D.associate() else - D = new(R,adm_ckey) //new admin - - var/client/C = GLOB.directory[adm_ckey] //find the client with the specified ckey (if they are logged in) - D.associate(C) //link up with the client and add verbs + D = new(R, adm_ckey, TRUE) //new admin updateranktodb(adm_ckey, new_rank) message_admins("[key_name_admin(usr)] edited the admin rank of [adm_ckey] to [new_rank]") @@ -387,6 +379,22 @@ GLOBAL_PROTECT(admin_ranks) message_admins("[key_name(usr)] added keyword [keyword] to permission of [adm_ckey]") log_admin("[key_name(usr)] added keyword [keyword] to permission of [adm_ckey]") log_admin_permission_modification(adm_ckey, D.rank.rights) + if("activate") //forcefully readmin + if(!D || !D.deadmined) + return + + D.activate() + + message_admins("[key_name_admin(usr)] forcefully readmined [adm_ckey]") + log_admin("[key_name(usr)] forcefully readmined [adm_ckey]") + if("deactivate") //forcefully deadmin + if(!D || D.deadmined) + return + + message_admins("[key_name_admin(usr)] forcefully deadmined [adm_ckey]") + log_admin("[key_name(usr)] forcefully deadmined [adm_ckey]") + + D.deactivate() //after logs so the deadmined admin can see the message. edit_admin_permissions() diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index c0bc15eacc..8b8da5baa4 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -638,12 +638,7 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list( if(has_antag_hud()) toggle_antag_hud() - holder.disassociate() - qdel(holder) - - GLOB.deadmins += ckey - GLOB.admin_datums -= ckey - verbs += /client/proc/readmin + holder.deactivate() to_chat(src, "You are now a normal player.") log_admin("[src] deadmined themself.") @@ -655,13 +650,20 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list( set category = "Admin" set desc = "Regain your admin powers." - load_admins(ckey) + var/datum/admins/A = GLOB.deadmins[ckey] - if(!holder) // Something went wrong... - return + if(!A) + A = GLOB.admin_datums[ckey] + if (!A) + var/msg = " is trying to readmin but they have no deadmin entry" + message_admins("[key_name_admin(src)][msg]") + log_admin_private("[key_name(src)][msg]") + return - GLOB.deadmins -= ckey - verbs -= /client/proc/readmin + A.associate(src) + + if (!holder) + return //This can happen if an admin attempts to vv themself into somebody elses's deadmin datum by getting ref via brute force to_chat(src, "You are now an admin.") message_admins("[src] re-adminned themselves.") diff --git a/code/modules/admin/chat_commands.dm b/code/modules/admin/chat_commands.dm index d2709233e7..bc41b489c0 100644 --- a/code/modules/admin/chat_commands.dm +++ b/code/modules/admin/chat_commands.dm @@ -47,7 +47,9 @@ target = AH.initiator_ckey else return "Ticket #[id] not found!" - return IrcPm(target, all_params.Join(" "), sender) + var/res = IrcPm(target, all_params.Join(" "), sender) + if(res != "Message Successful") + return res /datum/server_tools_command/namecheck name = "namecheck" @@ -81,3 +83,30 @@ GLOBAL_LIST(round_end_notifiees) LAZYINITLIST(GLOB.round_end_notifiees) GLOB.round_end_notifiees[sender] = TRUE return "I will notify [sender] when the round ends." + +/datum/server_tools_command/sdql + name = "sdql" + help_text = "Runs an SDQL query" + admin_only = TRUE + +/datum/server_tools_command/sdql/Run(sender, params) + if(GLOB.AdminProcCaller) + return "Unable to run query, another admin proc call is in progress. Try again later." + GLOB.AdminProcCaller = "CHAT_[sender]" //_ won't show up in ckeys so it'll never match with a real admin + var/list/results = world.SDQL2_query(params, GLOB.AdminProcCaller, GLOB.AdminProcCaller) + GLOB.AdminProcCaller = null + if(!results) + return "Query produced no output" + var/list/text_res = results.Copy(1, 3) + var/list/refs = results.len > 3 ? results.Copy(4) : null + . = "[text_res.Join("\n")][refs ? "\nRefs: [refs.Join(" ")]" : ""]" + +/datum/server_tools_command/reload_admins + name = "reload_admins" + help_text = "Forces the server to reload admins." + admin_only = TRUE + +/datum/server_tools_command/reload_admins/Run(sender, params) + load_admins() + log_admin("[sender] reloaded admins via chat command.") + return "Admins reloaded." diff --git a/code/modules/admin/fun_balloon.dm b/code/modules/admin/fun_balloon.dm index 3336f3d0a8..480ba20b4d 100644 --- a/code/modules/admin/fun_balloon.dm +++ b/code/modules/admin/fun_balloon.dm @@ -95,7 +95,7 @@ var/obj/docking_port/stationary/SM = S if(SM.id == "emergency_home") var/new_dir = turn(SM.dir, 180) - SM.loc = get_ranged_target_turf(SM, new_dir, rand(3,15)) + SM.forceMove(get_ranged_target_turf(SM, new_dir, rand(3,15))) break qdel(src) diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm index cdc53ae338..e9d4462c0a 100644 --- a/code/modules/admin/holder2.dm +++ b/code/modules/admin/holder2.dm @@ -7,6 +7,8 @@ GLOBAL_PROTECT(href_token) /datum/admins var/datum/admin_rank/rank + var/target + var/name = "nobody's admin datum (no rank)" //Makes for better runtimes var/client/owner = null var/fakekey = null @@ -19,9 +21,12 @@ GLOBAL_PROTECT(href_token) var/datum/newscaster/wanted_message/admincaster_wanted_message = new /datum/newscaster/wanted_message var/datum/newscaster/feed_channel/admincaster_feed_channel = new /datum/newscaster/feed_channel var/admin_signature + var/href_token -/datum/admins/New(datum/admin_rank/R, ckey) + var/deadmined + +/datum/admins/New(datum/admin_rank/R, ckey, force_active = FALSE) if(!ckey) QDEL_IN(src, 0) throw EXCEPTION("Admin datum created without a ckey") @@ -30,34 +35,36 @@ GLOBAL_PROTECT(href_token) QDEL_IN(src, 0) throw EXCEPTION("Admin datum created without a rank") return + target = ckey + name = "[ckey]'s admin datum ([R])" rank = R admin_signature = "Nanotrasen Officer #[rand(0,9)][rand(0,9)][rand(0,9)]" href_token = GenerateToken() - GLOB.admin_datums[ckey] = src if(R.rights & R_DEBUG) //grant profile access world.SetConfig("APP/admin", ckey, "role=admin") + //only admins with +ADMIN start admined + if (force_active || (R.rights & R_AUTOLOGIN)) + activate() + else + deactivate() -/proc/GenerateToken() - . = "" - for(var/I in 1 to 32) - . += "[rand(10)]" -/proc/RawHrefToken(forceGlobal = FALSE) - var/tok = GLOB.href_token - if(!forceGlobal && usr) - var/client/C = usr.client - if(!C) - CRASH("No client for HrefToken()!") - var/datum/admins/holder = C.holder - if(holder) - tok = holder.href_token - return tok +/datum/admins/proc/activate() + GLOB.deadmins -= target + GLOB.admin_datums[target] = src + deadmined = FALSE + if (GLOB.directory[target]) + associate(GLOB.directory[target]) //find the client for a ckey if they are connected and associate them with us -/proc/HrefToken(forceGlobal = FALSE) - return "admin_token=[RawHrefToken(forceGlobal)]" -/proc/HrefTokenFormField(forceGlobal = FALSE) - return "" +/datum/admins/proc/deactivate() + GLOB.deadmins[target] = src + GLOB.admin_datums -= target + deadmined = TRUE + var/client/C + if ((C = owner) || (C = GLOB.directory[target])) + disassociate() + C.verbs += /client/proc/readmin /datum/admins/proc/associate(client/C) if(IsAdminAdvancedProcCall()) @@ -65,10 +72,18 @@ GLOBAL_PROTECT(href_token) message_admins("[key_name_admin(usr)][msg]") log_admin_private("[key_name(usr)][msg]") return + if(istype(C)) + if(C.ckey != target) + var/msg = " has attempted to associate with [target]'s admin datum" + message_admins("[key_name_admin(C)][msg]") + log_admin_private("[key_name(C)][msg]") + return + if (deadmined) + activate() owner = C owner.holder = src - owner.add_admin_verbs() //TODO + owner.add_admin_verbs() //TODO <--- todo what? the proc clearly exists and works since its the backbone to our entire admin system owner.verbs -= /client/proc/readmin GLOB.admins |= C @@ -79,6 +94,12 @@ GLOBAL_PROTECT(href_token) owner.holder = null owner = null +/datum/admins/proc/check_for_rights(rights_required) + if(rights_required && !(rights_required & rank.rights)) + return 0 + return 1 + + /datum/admins/proc/check_if_greater_rights_than_holder(datum/admins/other) if(!other) return 1 //they have no rights @@ -128,8 +149,28 @@ you will have to do something like if(client.rights & R_ADMIN) yourself. //This proc checks whether subject has at least ONE of the rights specified in rights_required. /proc/check_rights_for(client/subject, rights_required) - if(subject && subject.holder && subject.holder.rank) - if(rights_required && !(rights_required & subject.holder.rank.rights)) - return 0 - return 1 + if(subject && subject.holder) + return subject.holder.check_for_rights(rights_required) return 0 + +/proc/GenerateToken() + . = "" + for(var/I in 1 to 32) + . += "[rand(10)]" + +/proc/RawHrefToken(forceGlobal = FALSE) + var/tok = GLOB.href_token + if(!forceGlobal && usr) + var/client/C = usr.client + if(!C) + CRASH("No client for HrefToken()!") + var/datum/admins/holder = C.holder + if(holder) + tok = holder.href_token + return tok + +/proc/HrefToken(forceGlobal = FALSE) + return "admin_token=[RawHrefToken(forceGlobal)]" + +/proc/HrefTokenFormField(forceGlobal = FALSE) + return "" diff --git a/code/modules/admin/permissionverbs/permissionedit.dm b/code/modules/admin/permissionverbs/permissionedit.dm index 26d2c87b48..a0035afa9d 100644 --- a/code/modules/admin/permissionverbs/permissionedit.dm +++ b/code/modules/admin/permissionverbs/permissionedit.dm @@ -10,7 +10,7 @@ if(!check_rights(R_PERMISSIONS)) return - var/output = {" + var/list/output = list({"Permissions Panel @@ -25,18 +25,26 @@ -"} +"}) - for(var/adm_ckey in GLOB.admin_datums) + for(var/adm_ckey in GLOB.admin_datums+GLOB.deadmins) var/datum/admins/D = GLOB.admin_datums[adm_ckey] if(!D) - continue + D = GLOB.deadmins[adm_ckey] + if (!D) + continue var/rights = rights2text(D.rank.rights," ") - if(!rights) rights = "*none*" + if(!rights) + rights = "*none*" + var/deadminlink = "" + if (D.deadmined) + deadminlink = " \[RA\]" + else + deadminlink = " \[DA\]" output += "" - output += "" + output += "" output += "" output += "" output += "" @@ -48,7 +56,7 @@ "} - usr << browse(output,"window=editrights;size=900x650") + usr << browse(jointext(output, ""),"window=editrights;size=900x650") /datum/admins/proc/log_admin_rank_modification(adm_ckey, new_rank) if(CONFIG_GET(flag/admin_legacy_system)) diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index fa6e184ab4..2a3812be3b 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -384,9 +384,10 @@ dat += "
    [other_players] players in invalid state or the statistics code is bugged!" dat += "
    " - if(SSticker.mode.syndicates.len) + var/list/nukeops = get_antagonists(/datum/antagonist/nukeop) + if(nukeops.len) dat += "
    [J_title]: [J_opPos]/[job.total_positions < 0 ? " (unlimited)" : J_totPos]" if(job.title == "AI" || job.title == "Cyborg") - dat += " (Cannot Late Join)
    " + dat += " (Cannot Late Join)
    " + if(job.total_positions >= 0) + dat += "Add | " + if(job.total_positions > job.current_positions) + dat += "Remove | " + else + dat += "Remove | " + dat += "Unlimit PERMISSIONS VERB-OVERRIDES
    [adm_ckey] \[-\][adm_ckey] [deadminlink]\[-\][D.rank.name][rights][rights2text(0," ",D.rank.adds,D.rank.subs)]
    " - for(var/datum/mind/N in SSticker.mode.syndicates) + for(var/datum/mind/N in nukeops) var/mob/M = N.current if(M) dat += "" @@ -523,7 +524,7 @@ if(SSticker.mode.brother_teams.len > 0) dat += "
    Syndicates
    [M.real_name][M.client ? "" : " (No Client)"][M.stat == DEAD ? " (DEAD)" : ""]
    " - for(var/datum/objective_team/brother_team/team in SSticker.mode.brother_teams) + for(var/datum/team/brother_team/team in SSticker.mode.brother_teams) for(var/datum/mind/brother in team.members) var/mob/M = brother.current if(M) diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm index 79b6554fec..0753f942dc 100644 --- a/code/modules/admin/secrets.dm +++ b/code/modules/admin/secrets.dm @@ -437,7 +437,7 @@ SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Mass Braindamage") for(var/mob/living/carbon/human/H in GLOB.player_list) to_chat(H, "You suddenly feel stupid.") - H.setBrainLoss(60) + H.adjustBrainLoss(60, 80) message_admins("[key_name_admin(usr)] made everybody retarded") if("eagles")//SCRAW diff --git a/code/modules/admin/sound_emitter.dm b/code/modules/admin/sound_emitter.dm index b7ec8c36b5..87024f7832 100644 --- a/code/modules/admin/sound_emitter.dm +++ b/code/modules/admin/sound_emitter.dm @@ -92,7 +92,7 @@ var/new_volume = input(user, "Choose a volume.", "Sound Emitter", sound_volume) as null|num if(isnull(new_volume)) return - new_volume = Clamp(new_volume, 0, 100) + new_volume = CLAMP(new_volume, 0, 100) sound_volume = new_volume to_chat(user, "Volume set to [sound_volume]%.") if(href_list["edit_mode"]) @@ -115,7 +115,7 @@ var/new_radius = input(user, "Choose a radius.", "Sound Emitter", sound_volume) as null|num if(isnull(new_radius)) return - new_radius = Clamp(new_radius, 0, 127) + new_radius = CLAMP(new_radius, 0, 127) play_radius = new_radius to_chat(user, "Audible radius set to [play_radius].") if(href_list["play"]) diff --git a/code/modules/admin/sql_message_system.dm b/code/modules/admin/sql_message_system.dm index 587bd6b26c..38316c904f 100644 --- a/code/modules/admin/sql_message_system.dm +++ b/code/modules/admin/sql_message_system.dm @@ -220,7 +220,7 @@ 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) + var/alpha = CLAMP(100 - (age - nfd) * (85 / (nsd - nfd)), 15, 100) if (alpha < 100) if (alpha <= 15) if (skipped) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 4a332abbb9..91769ac55a 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -58,6 +58,8 @@ toggle_exempt_status(C) else if(href_list["makeAntag"]) + if(!check_rights(R_ADMIN)) + return if (!SSticker.mode) to_chat(usr, "Not until the round starts!") return @@ -201,7 +203,8 @@ return else if(href_list["dbbanaddtype"]) - + if(!check_rights(R_BAN)) + return var/bantype = text2num(href_list["dbbanaddtype"]) var/banckey = href_list["dbbanaddckey"] var/banip = href_list["dbbanaddip"] @@ -393,6 +396,8 @@ log_admin("[key_name(usr)] [msg]") message_admins("[key_name_admin(usr)] [msg]") href_list["secrets"] = "check_antagonist" + if(SSticker.ready_for_reboot && !SSticker.delay_end) //we undelayed after standard reboot would occur + SSticker.standard_reboot() else if(href_list["end_round"]) if(!check_rights(R_ADMIN)) @@ -597,6 +602,8 @@ return else if(href_list["jobban2"]) + if(!check_rights(R_BAN)) + return var/mob/M = locate(href_list["jobban2"]) if(!ismob(M)) to_chat(usr, "This can only be used on instances of type /mob.") @@ -1027,6 +1034,8 @@ return 0 //we didn't do anything! else if(href_list["boot2"]) + if(!check_rights(R_ADMIN)) + return var/mob/M = locate(href_list["boot2"]) if (ismob(M)) if(!check_if_greater_rights_than(M.client)) @@ -1039,72 +1048,110 @@ qdel(M.client) else if(href_list["addmessage"]) + if(!check_rights(R_ADMIN)) + return var/target_ckey = href_list["addmessage"] create_message("message", target_ckey, secret = 0) else if(href_list["addnote"]) + if(!check_rights(R_ADMIN)) + return var/target_ckey = href_list["addnote"] create_message("note", target_ckey) else if(href_list["addwatch"]) + if(!check_rights(R_ADMIN)) + return var/target_ckey = href_list["addwatch"] create_message("watchlist entry", target_ckey, secret = 1) else if(href_list["addmemo"]) + if(!check_rights(R_ADMIN)) + return create_message("memo", secret = 0, browse = 1) else if(href_list["addmessageempty"]) + if(!check_rights(R_ADMIN)) + return create_message("message", secret = 0) else if(href_list["addnoteempty"]) + if(!check_rights(R_ADMIN)) + return create_message("note") else if(href_list["addwatchempty"]) + if(!check_rights(R_ADMIN)) + return create_message("watchlist entry", secret = 1) else if(href_list["deletemessage"]) + if(!check_rights(R_ADMIN)) + return var/message_id = href_list["deletemessage"] delete_message(message_id) else if(href_list["deletemessageempty"]) + if(!check_rights(R_ADMIN)) + return var/message_id = href_list["deletemessageempty"] delete_message(message_id, browse = 1) else if(href_list["editmessage"]) + if(!check_rights(R_ADMIN)) + return var/message_id = href_list["editmessage"] edit_message(message_id) else if(href_list["editmessageempty"]) + if(!check_rights(R_ADMIN)) + return var/message_id = href_list["editmessageempty"] edit_message(message_id, browse = 1) else if(href_list["secretmessage"]) + if(!check_rights(R_ADMIN)) + return var/message_id = href_list["secretmessage"] toggle_message_secrecy(message_id) else if(href_list["searchmessages"]) + if(!check_rights(R_ADMIN)) + return var/target = href_list["searchmessages"] browse_messages(index = target) else if(href_list["nonalpha"]) + if(!check_rights(R_ADMIN)) + return var/target = href_list["nonalpha"] target = text2num(target) browse_messages(index = target) else if(href_list["showmessages"]) + if(!check_rights(R_ADMIN)) + return var/target = href_list["showmessages"] browse_messages(index = target) else if(href_list["showmemo"]) + if(!check_rights(R_ADMIN)) + return browse_messages("memo") else if(href_list["showwatch"]) + if(!check_rights(R_ADMIN)) + return browse_messages("watchlist entry") else if(href_list["showwatchfilter"]) + if(!check_rights(R_ADMIN)) + return browse_messages("watchlist entry", filter = 1) else if(href_list["showmessageckey"]) + if(!check_rights(R_ADMIN)) + return var/target = href_list["showmessageckey"] var/agegate = TRUE if (href_list["showall"]) @@ -1116,6 +1163,8 @@ browse_messages(target_ckey = target, linkless = 1) else if(href_list["messageedits"]) + if(!check_rights(R_ADMIN)) + return var/message_id = sanitizeSQL("[href_list["messageedits"]]") var/datum/DBQuery/query_get_message_edits = SSdbcore.NewQuery("SELECT edits FROM [format_table_name("messages")] WHERE id = '[message_id]'") if(!query_get_message_edits.warn_execute()) @@ -1305,7 +1354,7 @@ if(alert(usr, "Send [key_name(M)] to Prison?", "Message", "Yes", "No") != "Yes") return - M.loc = pick(GLOB.prisonwarp) + M.forceMove(pick(GLOB.prisonwarp)) to_chat(M, "You have been sent to Prison!") log_admin("[key_name(usr)] has sent [key_name(M)] to Prison!") @@ -1542,6 +1591,15 @@ var/mob/dead/observer/A = C.mob A.ManualFollow(AM) + else if(href_list["admingetmovable"]) + if(!check_rights(R_ADMIN)) + return + + var/atom/movable/AM = locate(href_list["admingetmovable"]) + if(QDELETED(AM)) + return + AM.forceMove(get_turf(usr)) + else if(href_list["adminplayerobservecoodjump"]) if(!isobserver(usr) && !check_rights(R_ADMIN)) return @@ -1557,9 +1615,13 @@ C.jumptocoord(x,y,z) else if(href_list["adminchecklaws"]) + if(!check_rights(R_ADMIN)) + return output_ai_laws() else if(href_list["admincheckdevilinfo"]) + if(!check_rights(R_ADMIN)) + return var/mob/M = locate(href_list["admincheckdevilinfo"]) output_devil_info(M) @@ -1881,7 +1943,7 @@ return var/list/offset = splittext(href_list["offset"],",") - var/number = Clamp(text2num(href_list["object_count"]), 1, 100) + var/number = CLAMP(text2num(href_list["object_count"]), 1, 100) var/X = offset.len > 0 ? text2num(offset[1]) : 0 var/Y = offset.len > 1 ? text2num(offset[2]) : 0 var/Z = offset.len > 2 ? text2num(offset[3]) : 0 @@ -1968,20 +2030,28 @@ Secrets_topic(href_list["secrets"],href_list) else if(href_list["ac_view_wanted"]) //Admin newscaster Topic() stuff be here + if(!check_rights(R_ADMIN)) + return src.admincaster_screen = 18 //The ac_ prefix before the hrefs stands for AdminCaster. src.access_news_network() else if(href_list["ac_set_channel_name"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_feed_channel.channel_name = stripped_input(usr, "Provide a Feed Channel Name.", "Network Channel Handler", "") while (findtext(src.admincaster_feed_channel.channel_name," ") == 1) src.admincaster_feed_channel.channel_name = copytext(src.admincaster_feed_channel.channel_name,2,lentext(src.admincaster_feed_channel.channel_name)+1) src.access_news_network() else if(href_list["ac_set_channel_lock"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_feed_channel.locked = !src.admincaster_feed_channel.locked src.access_news_network() else if(href_list["ac_submit_new_channel"]) + if(!check_rights(R_ADMIN)) + return var/check = 0 for(var/datum/newscaster/feed_channel/FC in GLOB.news_network.network_channels) if(FC.channel_name == src.admincaster_feed_channel.channel_name) @@ -1999,6 +2069,8 @@ src.access_news_network() else if(href_list["ac_set_channel_receiving"]) + if(!check_rights(R_ADMIN)) + return var/list/available_channels = list() for(var/datum/newscaster/feed_channel/F in GLOB.news_network.network_channels) available_channels += F.channel_name @@ -2006,12 +2078,16 @@ src.access_news_network() else if(href_list["ac_set_new_message"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_feed_message.body = adminscrub(input(usr, "Write your Feed story.", "Network Channel Handler", "")) while (findtext(src.admincaster_feed_message.returnBody(-1)," ") == 1) src.admincaster_feed_message.body = copytext(src.admincaster_feed_message.returnBody(-1),2,lentext(src.admincaster_feed_message.returnBody(-1))+1) src.access_news_network() else if(href_list["ac_submit_new_message"]) + if(!check_rights(R_ADMIN)) + return if(src.admincaster_feed_message.returnBody(-1) =="" || src.admincaster_feed_message.returnBody(-1) =="\[REDACTED\]" || src.admincaster_feed_channel.channel_name == "" ) src.admincaster_screen = 6 else @@ -2026,22 +2102,32 @@ src.access_news_network() else if(href_list["ac_create_channel"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_screen=2 src.access_news_network() else if(href_list["ac_create_feed_story"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_screen=3 src.access_news_network() else if(href_list["ac_menu_censor_story"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_screen=10 src.access_news_network() else if(href_list["ac_menu_censor_channel"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_screen=11 src.access_news_network() else if(href_list["ac_menu_wanted"]) + if(!check_rights(R_ADMIN)) + return var/already_wanted = 0 if(GLOB.news_network.wanted_issue.active) already_wanted = 1 @@ -2053,18 +2139,24 @@ src.access_news_network() else if(href_list["ac_set_wanted_name"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_wanted_message.criminal = adminscrub(input(usr, "Provide the name of the Wanted person.", "Network Security Handler", "")) while(findtext(src.admincaster_wanted_message.criminal," ") == 1) src.admincaster_wanted_message.criminal = copytext(admincaster_wanted_message.criminal,2,lentext(admincaster_wanted_message.criminal)+1) src.access_news_network() else if(href_list["ac_set_wanted_desc"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_wanted_message.body = adminscrub(input(usr, "Provide the a description of the Wanted person and any other details you deem important.", "Network Security Handler", "")) while (findtext(src.admincaster_wanted_message.body," ") == 1) src.admincaster_wanted_message.body = copytext(src.admincaster_wanted_message.body,2,lentext(src.admincaster_wanted_message.body)+1) src.access_news_network() else if(href_list["ac_submit_wanted"]) + if(!check_rights(R_ADMIN)) + return var/input_param = text2num(href_list["ac_submit_wanted"]) if(src.admincaster_wanted_message.criminal == "" || src.admincaster_wanted_message.body == "") src.admincaster_screen = 16 @@ -2081,6 +2173,8 @@ src.access_news_network() else if(href_list["ac_cancel_wanted"]) + if(!check_rights(R_ADMIN)) + return var/choice = alert("Please confirm Wanted Issue removal.","Network Security Handler","Confirm","Cancel") if(choice=="Confirm") GLOB.news_network.deleteWanted() @@ -2088,36 +2182,50 @@ src.access_news_network() else if(href_list["ac_censor_channel_author"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_channel/FC = locate(href_list["ac_censor_channel_author"]) FC.toggleCensorAuthor() src.access_news_network() else if(href_list["ac_censor_channel_story_author"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_message/MSG = locate(href_list["ac_censor_channel_story_author"]) MSG.toggleCensorAuthor() src.access_news_network() else if(href_list["ac_censor_channel_story_body"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_message/MSG = locate(href_list["ac_censor_channel_story_body"]) MSG.toggleCensorBody() src.access_news_network() else if(href_list["ac_pick_d_notice"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_channel/FC = locate(href_list["ac_pick_d_notice"]) src.admincaster_feed_channel = FC src.admincaster_screen=13 src.access_news_network() else if(href_list["ac_toggle_d_notice"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_channel/FC = locate(href_list["ac_toggle_d_notice"]) FC.toggleCensorDclass() src.access_news_network() else if(href_list["ac_view"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_screen=1 src.access_news_network() else if(href_list["ac_setScreen"]) //Brings us to the main menu and resets all fields~ + if(!check_rights(R_ADMIN)) + return src.admincaster_screen = text2num(href_list["ac_setScreen"]) if (src.admincaster_screen == 0) if(src.admincaster_feed_channel) @@ -2129,25 +2237,35 @@ src.access_news_network() else if(href_list["ac_show_channel"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_channel/FC = locate(href_list["ac_show_channel"]) src.admincaster_feed_channel = FC src.admincaster_screen = 9 src.access_news_network() else if(href_list["ac_pick_censor_channel"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_channel/FC = locate(href_list["ac_pick_censor_channel"]) src.admincaster_feed_channel = FC src.admincaster_screen = 12 src.access_news_network() else if(href_list["ac_refresh"]) + if(!check_rights(R_ADMIN)) + return src.access_news_network() else if(href_list["ac_set_signature"]) + if(!check_rights(R_ADMIN)) + return src.admin_signature = adminscrub(input(usr, "Provide your desired signature.", "Network Identity Handler", "")) src.access_news_network() else if(href_list["ac_del_comment"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_comment/FC = locate(href_list["ac_del_comment"]) var/datum/newscaster/feed_message/FM = locate(href_list["ac_del_comment_msg"]) FM.comments -= FC @@ -2155,6 +2273,8 @@ src.access_news_network() else if(href_list["ac_lock_comment"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_message/FM = locate(href_list["ac_lock_comment"]) FM.locked ^= 1 src.access_news_network() @@ -2251,6 +2371,8 @@ error_viewer.show_to(owner, null, href_list["viewruntime_linear"]) else if(href_list["showrelatedacc"]) + if(!check_rights(R_ADMIN)) + return var/client/C = locate(href_list["client"]) in GLOB.clients var/thing_to_check if(href_list["showrelatedacc"] == "cid") diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm index e091001851..0421807abe 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm @@ -24,10 +24,14 @@ message_admins("ERROR: Non-admin [key_name(usr, usr.client)] attempted to execute a SDQL query!") log_admin("Non-admin [usr.ckey]([usr]) attempted to execute a SDQL query!") return FALSE + var/list/results = world.SDQL2_query(query_text, key_name_admin(usr), "[usr.ckey]([usr])") + for(var/I in 1 to 3) + to_chat(usr, results[I]) +/world/proc/SDQL2_query(query_text, log_entry1, log_entry2) var/query_log = "executed SDQL query: \"[query_text]\"." - message_admins("[key_name_admin(usr)] [query_log]") - query_log = "[usr.ckey]([usr]) [query_log]" + message_admins("[log_entry1] [query_log]") + query_log = "[log_entry2] [query_log]" log_game(query_log) NOTICE(query_log) var/objs_all = 0 @@ -49,6 +53,7 @@ if(!querys || querys.len < 1) return + var/list/refs = list() for(var/list/query_tree in querys) var/list/from_objs = list() var/list/select_types = list() @@ -100,6 +105,7 @@ var/text = "" for(var/datum/t in objs) text += SDQL_gen_vv_href(t) + refs[REF(t)] = TRUE CHECK_TICK usr << browse(text, "window=SDQL-result") @@ -112,9 +118,9 @@ var/end_time = REALTIMEOFDAY end_time -= start_time - to_chat(usr, "SDQL query results: [query_text]") - to_chat(usr, "SDQL query completed: [objs_all] objects selected by path, and [objs_eligible] objects executed on after WHERE filtering if applicable.") - to_chat(usr, "SDQL query took [DisplayTimeText(end_time)] to complete.") + return list("SDQL query results: [query_text]",\ + "SDQL query completed: [objs_all] objects selected by path, and [objs_eligible] objects executed on after WHERE filtering if applicable.",\ + "SDQL query took [DisplayTimeText(end_time)] to complete.") + refs /proc/SDQL_qdel_datum(datum/d) qdel(d) @@ -429,7 +435,7 @@ else if(expression[start + 1] == "\[" && islist(v)) var/list/L = v var/index = SDQL_expression(source, expression[start + 2]) - if(isnum(index) && (!IsInteger(index) || L.len < index)) + if(isnum(index) && (!ISINTEGER(index) || L.len < index)) to_chat(usr, "Invalid list index: [index]") return null return L[index] diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 99e21c2da2..2d57ee0965 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -214,7 +214,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) if(heard_by_no_admins && usr && usr.ckey != initiator_ckey) heard_by_no_admins = FALSE send2irc(initiator_ckey, "Ticket #[id]: Answered by [key_name(usr)]") - _interactions += "[gameTimestamp()]: [formatted_message]" + _interactions += "[time_stamp()]: [formatted_message]" //Removes the ahelp verb and returns it after 2 minutes /datum/admin_help/proc/TimeoutVerb() diff --git a/code/modules/admin/verbs/adminjump.dm b/code/modules/admin/verbs/adminjump.dm index 1e7f89fc8d..779ea64640 100644 --- a/code/modules/admin/verbs/adminjump.dm +++ b/code/modules/admin/verbs/adminjump.dm @@ -34,7 +34,7 @@ log_admin("[key_name(usr)] jumped to [T.x],[T.y],[T.z] in [T.loc]") message_admins("[key_name_admin(usr)] jumped to [T.x],[T.y],[T.z] in [T.loc]") - usr.loc = T + usr.forceMove(T) SSblackbox.record_feedback("tally", "admin_verb", 1, "Jump To Turf") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return @@ -137,7 +137,7 @@ admin_ticket_log(M, msg) if(M) M.forceMove(get_turf(usr)) - usr.loc = M.loc + usr.forceMove(M.loc) SSblackbox.record_feedback("tally", "admin_verb", 1, "Get Key") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/sendmob(mob/M in sortmobs()) diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index 01ae5d4dc3..2e12f53608 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -111,7 +111,7 @@ //get message text, limit it's length.and clean/escape html if(!msg) msg = input(src,"Message:", "Private message to [key_name(recipient, 0, 0)]") as text|null - + msg = trim(msg) if(!msg) return diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index e3c8c19c31..e2bb78c9ec 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -110,7 +110,9 @@ GLOBAL_PROTECT(LastAdminCalledProc) /proc/WrapAdminProcCall(target, procname, list/arguments) var/current_caller = GLOB.AdminProcCaller - var/ckey = usr.client.ckey + var/ckey = usr ? usr.client.ckey : GLOB.AdminProcCaller + if(!ckey) + CRASH("WrapAdminProcCall with no ckey: [target] [procname] [english_list(arguments)]") if(current_caller && current_caller != ckey) to_chat(usr, "Another set of admin called procs are still running, your proc will be run after theirs finish.") UNTIL(!GLOB.AdminProcCaller) @@ -733,11 +735,11 @@ GLOBAL_PROTECT(LastAdminCalledProc) if(Rad.anchored) if(!Rad.loaded_tank) var/obj/item/tank/internals/plasma/Plasma = new/obj/item/tank/internals/plasma(Rad) - ASSERT_GAS(/datum/gas/plasma, Plasma.air_contents) + Plasma.air_contents.assert_gas(/datum/gas/plasma) Plasma.air_contents.gases[/datum/gas/plasma][MOLES] = 70 Rad.drainratio = 0 Rad.loaded_tank = Plasma - Plasma.loc = Rad + Plasma.forceMove(Rad) if(!Rad.active) Rad.toggle_power() diff --git a/code/modules/admin/verbs/machine_upgrade.dm b/code/modules/admin/verbs/machine_upgrade.dm index 463ee70ac8..58deff2a24 100644 --- a/code/modules/admin/verbs/machine_upgrade.dm +++ b/code/modules/admin/verbs/machine_upgrade.dm @@ -1,6 +1,9 @@ /proc/machine_upgrade(obj/machinery/M in world) set name = "Tweak Component Ratings" set category = "Debug" + if (!istype(M)) + return + var/new_rating = input("Enter new rating:","Num") as num if(new_rating && M.component_parts) for(var/obj/item/stock_parts/P in M.component_parts) diff --git a/code/modules/admin/verbs/manipulate_organs.dm b/code/modules/admin/verbs/manipulate_organs.dm index 5edb1e7bca..3ff0ff75ac 100644 --- a/code/modules/admin/verbs/manipulate_organs.dm +++ b/code/modules/admin/verbs/manipulate_organs.dm @@ -55,5 +55,5 @@ else if(I) // Put the implant in case. var/obj/item/implantcase/case = new(get_turf(C)) case.imp = I - I.loc = case + I.forceMove(case) case.update_icon() diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm index 3a2e13fdcc..f6e8d93e62 100644 --- a/code/modules/admin/verbs/modifyvariables.dm +++ b/code/modules/admin/verbs/modifyvariables.dm @@ -213,7 +213,9 @@ GLOBAL_PROTECT(VVpixelmovement) .["class"] = null return .["type"] = type - .["value"] = new type() + var/atom/newguy = new type() + newguy.var_edited = TRUE + .["value"] = newguy if (VV_NEW_DATUM) var/type = pick_closest_path(FALSE, get_fancy_list_of_datum_types()) @@ -221,7 +223,9 @@ GLOBAL_PROTECT(VVpixelmovement) .["class"] = null return .["type"] = type - .["value"] = new type() + var/datum/newguy = new type() + newguy.var_edited = TRUE + .["value"] = newguy if (VV_NEW_TYPE) var/type = current_value @@ -237,7 +241,10 @@ GLOBAL_PROTECT(VVpixelmovement) .["class"] = null return .["type"] = type - .["value"] = new type() + var/datum/newguy = new type() + if(istype(newguy)) + newguy.var_edited = TRUE + .["value"] = newguy if (VV_NEW_LIST) diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index 8a18dc9ac5..ece3775872 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -238,26 +238,17 @@ if(agentcount < 3) return 0 - var/nuke_code = random_nukecode() - - var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list - if(nuke) - nuke.r_code = nuke_code - //Let's find the spawn locations var/leader_chosen = FALSE - var/spawnpos = 1 //Decides where they'll spawn. 1=leader. - + var/datum/team/nuclear/nuke_team for(var/mob/c in chosen) - if(spawnpos > GLOB.nukeop_start.len) - spawnpos = 1 //Ran out of spawns. Let's loop back to the first non-leader position var/mob/living/carbon/human/new_character=makeBody(c) if(!leader_chosen) leader_chosen = TRUE - new_character.mind.make_Nuke(pick(GLOB.nukeop_leader_start), nuke_code, TRUE) + var/datum/antagonist/nukeop/N = new_character.mind.add_antag_datum(/datum/antagonist/nukeop/leader) + nuke_team = N.nuke_team else - new_character.mind.make_Nuke(GLOB.nukeop_start[spawnpos], nuke_code) - spawnpos++ + new_character.mind.add_antag_datum(/datum/antagonist/nukeop,nuke_team) return 1 else return 0 @@ -317,12 +308,15 @@ //Assign antag status and the mission SSticker.mode.traitors += Commando.mind Commando.mind.special_role = "deathsquad" + var/datum/objective/missionobj = new missionobj.owner = Commando.mind missionobj.explanation_text = mission missionobj.completed = 1 Commando.mind.objectives += missionobj + Commando.mind.add_antag_datum(/datum/antagonist/auto_custom) + //Greet the commando to_chat(Commando, "You are the [numagents==1?"Deathsquad Officer":"Death Commando"].") var/missiondesc = "Your squad is being sent on a mission to [station_name()] by Nanotrasen's Security Division." @@ -369,12 +363,15 @@ //Assign antag status and the mission SSticker.mode.traitors += newmob.mind newmob.mind.special_role = "official" + var/datum/objective/missionobj = new missionobj.owner = newmob.mind missionobj.explanation_text = mission missionobj.completed = 1 newmob.mind.objectives += missionobj + newmob.mind.add_antag_datum(/datum/antagonist/auto_custom) + if(CONFIG_GET(flag/enforce_human_authority)) newmob.set_species(/datum/species/human) @@ -474,12 +471,15 @@ //Assign antag status and the mission SSticker.mode.traitors += ERTOperative.mind ERTOperative.mind.special_role = "ERT" + var/datum/objective/missionobj = new missionobj.owner = ERTOperative.mind missionobj.explanation_text = mission missionobj.completed = 1 ERTOperative.mind.objectives += missionobj + ERTOperative.mind.add_antag_datum(/datum/antagonist/auto_custom) + //Greet the commando to_chat(ERTOperative, "You are [numagents==1?"the Emergency Response Team Commander":"an Emergency Response Officer"].") var/missiondesc = "Your squad is being sent on a Code [alert] mission to [station_name()] by Nanotrasen's Security Division." diff --git a/code/modules/admin/verbs/onlyone.dm b/code/modules/admin/verbs/onlyone.dm index b675815602..d09041aaf3 100644 --- a/code/modules/admin/verbs/onlyone.dm +++ b/code/modules/admin/verbs/onlyone.dm @@ -28,6 +28,7 @@ GLOBAL_VAR_INIT(highlander, FALSE) /mob/living/carbon/human/proc/make_scottish() SSticker.mode.traitors += mind mind.special_role = "highlander" + dna.species.species_traits |= NOGUNS //nice try jackass var/datum/objective/steal/steal_objective = new @@ -40,6 +41,8 @@ GLOBAL_VAR_INIT(highlander, FALSE) hijack_objective.owner = mind mind.objectives += hijack_objective + mind.add_antag_datum(/datum/antagonist/auto_custom) + mind.announce_objectives() for(var/obj/item/I in get_equipped_items()) diff --git a/code/modules/admin/verbs/playsound.dm b/code/modules/admin/verbs/playsound.dm index 6b1edf7709..29d95c639f 100644 --- a/code/modules/admin/verbs/playsound.dm +++ b/code/modules/admin/verbs/playsound.dm @@ -12,7 +12,7 @@ var/vol = input(usr, "What volume would you like the sound to play at?",, 100) as null|num if(!vol) return - vol = Clamp(vol, 1, 100) + vol = CLAMP(vol, 1, 100) var/sound/admin_sound = new() admin_sound.file = S diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index bf12b3eb66..8f13d887aa 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -386,7 +386,8 @@ Traitors and the like can also be revived with the previous role mostly intact. A.equip_wizard() if("Syndicate") new_character.forceMove(pick(GLOB.nukeop_start)) - call(/datum/game_mode/proc/equip_syndicate)(new_character) + var/datum/antagonist/nukeop/N = new_character.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE) + N.equip_op() if("Space Ninja") var/list/ninja_spawn = list() for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list) @@ -651,10 +652,10 @@ Traitors and the like can also be revived with the previous role mostly intact. set name = "Change View Range" set desc = "switches between 1x and custom views" - if(view == world.view) + if(view == CONFIG_GET(string/default_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) + change_view(CONFIG_GET(string/default_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 @@ -1206,7 +1207,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits if(!holder) return - var/list/punishment_list = list(ADMIN_PUNISHMENT_LIGHTNING, ADMIN_PUNISHMENT_BRAINDAMAGE, ADMIN_PUNISHMENT_GIB, ADMIN_PUNISHMENT_BSA, ADMIN_PUNISHMENT_FIREBALL) + var/list/punishment_list = list(ADMIN_PUNISHMENT_LIGHTNING, ADMIN_PUNISHMENT_BRAINDAMAGE, ADMIN_PUNISHMENT_GIB, ADMIN_PUNISHMENT_BSA, ADMIN_PUNISHMENT_FIREBALL, ADMIN_PUNISHMENT_ROD) var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in punishment_list @@ -1221,13 +1222,19 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits target.electrocution_animation(40) to_chat(target, "The gods have punished you for your sins!") if(ADMIN_PUNISHMENT_BRAINDAMAGE) - target.adjustBrainLoss(75) + target.adjustBrainLoss(199, 199) if(ADMIN_PUNISHMENT_GIB) target.gib(FALSE) if(ADMIN_PUNISHMENT_BSA) bluespace_artillery(target) if(ADMIN_PUNISHMENT_FIREBALL) new /obj/effect/temp_visual/target(get_turf(target)) + if(ADMIN_PUNISHMENT_ROD) + var/turf/T = get_turf(target) + var/startside = pick(GLOB.cardinals) + var/turf/startT = spaceDebrisStartLoc(startside, T.z) + var/turf/endT = spaceDebrisFinishLoc(startside, T.z) + new /obj/effect/immovablerod(startT, endT,target) var/msg = "[key_name_admin(usr)] punished [key_name_admin(target)] with [punishment]." message_admins(msg) diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm index 6c2df587e1..315e28df02 100644 --- a/code/modules/assembly/assembly.dm +++ b/code/modules/assembly/assembly.dm @@ -15,7 +15,6 @@ throwforce = 2 throw_speed = 3 throw_range = 7 - origin_tech = "magnets=1;engineering=1" var/secured = TRUE var/list/attached_overlays = null diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm index b895297d83..18fda04a1b 100644 --- a/code/modules/assembly/bomb.dm +++ b/code/modules/assembly/bomb.dm @@ -12,7 +12,6 @@ var/status = FALSE //0 - not readied //1 - bomb finished with welder var/obj/item/device/assembly_holder/bombassembly = null //The first part of the bomb is an assembly holder, holding an igniter+some device var/obj/item/tank/bombtank = null //the second part of the bomb is a plasma tank - origin_tech = "materials=1;engineering=1" /obj/item/device/onetankbomb/examine(mob/user) @@ -116,13 +115,16 @@ air_contents.assert_gases(/datum/gas/plasma, /datum/gas/oxygen) var/fuel_moles = air_contents.gases[/datum/gas/plasma][MOLES] + air_contents.gases[/datum/gas/oxygen][MOLES]/6 air_contents.garbage_collect() - + var/datum/gas_mixture/bomb_mixture = air_contents.copy() var/strength = 1 var/turf/ground_zero = get_turf(loc) - loc = null - if(air_contents.temperature > (T0C + 400)) + if(master) + qdel(master) + qdel(src) + + if(bomb_mixture.temperature > (T0C + 400)) strength = (fuel_moles/15) if(strength >=1) @@ -132,10 +134,10 @@ else if(strength >=0.2) explosion(ground_zero, -1, 0, 1, 2) else - ground_zero.assume_air(air_contents) + ground_zero.assume_air(bomb_mixture) ground_zero.hotspot_expose(1000, 125) - else if(air_contents.temperature > (T0C + 250)) + else if(bomb_mixture.temperature > (T0C + 250)) strength = (fuel_moles/20) if(strength >=1) @@ -143,26 +145,23 @@ else if (strength >=0.5) explosion(ground_zero, -1, 0, 1, 2) else - ground_zero.assume_air(air_contents) + ground_zero.assume_air(bomb_mixture) ground_zero.hotspot_expose(1000, 125) - else if(air_contents.temperature > (T0C + 100)) + else if(bomb_mixture.temperature > (T0C + 100)) strength = (fuel_moles/25) if (strength >=1) explosion(ground_zero, -1, 0, round(strength,1), round(strength*3,1)) else - ground_zero.assume_air(air_contents) + ground_zero.assume_air(bomb_mixture) ground_zero.hotspot_expose(1000, 125) else - ground_zero.assume_air(air_contents) + ground_zero.assume_air(bomb_mixture) ground_zero.hotspot_expose(1000, 125) - air_update_turf() - if(master) - qdel(master) - qdel(src) + ground_zero.air_update_turf() /obj/item/tank/proc/release() //This happens when the bomb is not welded. Tank contents are just spat out. var/datum/gas_mixture/removed = air_contents.remove(air_contents.total_moles()) diff --git a/code/modules/assembly/doorcontrol.dm b/code/modules/assembly/doorcontrol.dm index 9a13237619..47d3d9e436 100644 --- a/code/modules/assembly/doorcontrol.dm +++ b/code/modules/assembly/doorcontrol.dm @@ -2,7 +2,6 @@ name = "blast door controller" desc = "A small electronic device able to control a blast door remotely." icon_state = "control" - origin_tech = "magnets=1;programming=2" attachable = 1 var/id = null var/can_change_id = 0 diff --git a/code/modules/assembly/flash.dm b/code/modules/assembly/flash.dm index 3a36b4cdd0..81f2c75660 100644 --- a/code/modules/assembly/flash.dm +++ b/code/modules/assembly/flash.dm @@ -8,7 +8,6 @@ throwforce = 0 w_class = WEIGHT_CLASS_TINY materials = list(MAT_METAL = 300, MAT_GLASS = 300) - origin_tech = "magnets=2;combat=1" crit_fail = 0 //Is the flash burnt out? var/times_used = 0 //Number of times it's been used. @@ -71,15 +70,12 @@ return 1 /obj/item/device/assembly/flash/proc/try_use_flash(mob/user = null) - flash_recharge(10) - if(crit_fail) return 0 - playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1) - update_icon(1) times_used++ - + flash_recharge(10) + update_icon(1) if(user && !clown_check(user)) return 0 @@ -107,11 +103,9 @@ /obj/item/device/assembly/flash/attack(mob/living/M, mob/user) if(!try_use_flash(user)) return 0 - if(iscarbon(M)) flash_carbon(M, user, 5, 1) return 1 - else if(issilicon(M)) var/mob/living/silicon/robot/R = M add_logs(user, R, "flashed", src) @@ -163,7 +157,6 @@ /obj/item/device/assembly/flash/cyborg - origin_tech = null /obj/item/device/assembly/flash/cyborg/attack(mob/living/M, mob/user) ..() @@ -229,7 +222,6 @@ throw_range = 3 w_class = WEIGHT_CLASS_BULKY materials = list(MAT_GLASS=7500, MAT_METAL=1000) - origin_tech = "materials=3;combat=4" attack_verb = list("shoved", "bashed") block_chance = 50 armor = list(melee = 50, bullet = 50, laser = 50, energy = 0, bomb = 30, bio = 0, rad = 0, fire = 80, acid = 70) diff --git a/code/modules/assembly/health.dm b/code/modules/assembly/health.dm index 8ff54b7a0a..1e528d4824 100644 --- a/code/modules/assembly/health.dm +++ b/code/modules/assembly/health.dm @@ -3,7 +3,6 @@ desc = "Used for scanning and monitoring health." icon_state = "health" materials = list(MAT_METAL=800, MAT_GLASS=200) - origin_tech = "magnets=1;biotech=1" attachable = 1 secured = 0 diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm index b929e83ada..6ac1ef093d 100644 --- a/code/modules/assembly/holder.dm +++ b/code/modules/assembly/holder.dm @@ -88,10 +88,10 @@ return 0 if(a_left) a_left.holder = null - a_left.loc = T + a_left.forceMove(T) if(a_right) a_right.holder = null - a_right.loc = T + a_right.forceMove(T) qdel(src) else ..() diff --git a/code/modules/assembly/igniter.dm b/code/modules/assembly/igniter.dm index 090843e82e..2a6e51a344 100644 --- a/code/modules/assembly/igniter.dm +++ b/code/modules/assembly/igniter.dm @@ -3,7 +3,6 @@ desc = "A small electronic device able to ignite combustible substances." icon_state = "igniter" materials = list(MAT_METAL=500, MAT_GLASS=50) - origin_tech = "magnets=1" var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread heat = 1000 diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm index c5f219d941..0b9d42e42e 100644 --- a/code/modules/assembly/infrared.dm +++ b/code/modules/assembly/infrared.dm @@ -3,7 +3,6 @@ desc = "Emits a visible or invisible beam and is triggered when the beam is interrupted.\nAlt-click to rotate it clockwise." icon_state = "infrared" materials = list(MAT_METAL=1000, MAT_GLASS=500) - origin_tech = "magnets=2;materials=2" var/on = FALSE var/visible = FALSE diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm index 06d4c4deb9..e8ee742e56 100644 --- a/code/modules/assembly/mousetrap.dm +++ b/code/modules/assembly/mousetrap.dm @@ -3,7 +3,6 @@ desc = "A handy little spring-loaded trap for catching pesty rodents." icon_state = "mousetrap" materials = list(MAT_METAL=100) - origin_tech = "combat=1;materials=2;engineering=1" attachable = 1 var/armed = 0 @@ -140,4 +139,4 @@ /obj/item/device/assembly/mousetrap/armed icon_state = "mousetraparmed" - armed = 1 + armed = TRUE diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm index f2d30d19c7..81cc09243c 100644 --- a/code/modules/assembly/proximity.dm +++ b/code/modules/assembly/proximity.dm @@ -3,7 +3,6 @@ desc = "Used for scanning and alerting when someone enters a certain proximity." icon_state = "prox" materials = list(MAT_METAL=800, MAT_GLASS=200) - origin_tech = "magnets=1;engineering=1" attachable = 1 var/scanning = 0 diff --git a/code/modules/assembly/shock_kit.dm b/code/modules/assembly/shock_kit.dm index 1b21738391..174312df1e 100644 --- a/code/modules/assembly/shock_kit.dm +++ b/code/modules/assembly/shock_kit.dm @@ -1,42 +1,39 @@ -/obj/item/assembly/shock_kit - name = "electrohelmet assembly" - desc = "This appears to be made from both an electropack and a helmet." - icon = 'icons/obj/assemblies.dmi' - icon_state = "shock_kit" - var/obj/item/clothing/head/helmet/part1 = null - var/obj/item/device/electropack/part2 = null - w_class = WEIGHT_CLASS_HUGE +/obj/item/assembly/shock_kit + name = "electrohelmet assembly" + desc = "This appears to be made from both an electropack and a helmet." + icon = 'icons/obj/assemblies.dmi' + icon_state = "shock_kit" + var/obj/item/clothing/head/helmet/part1 = null + var/obj/item/device/electropack/part2 = null + w_class = WEIGHT_CLASS_HUGE flags_1 = CONDUCT_1 - -/obj/item/assembly/shock_kit/Destroy() - qdel(part1) - qdel(part2) - return ..() - -/obj/item/assembly/shock_kit/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/wrench)) - var/turf/T = loc - if(ismob(T)) - T = T.loc - part1.loc = T - part2.loc = T - part1.master = null - part2.master = null - part1 = null - part2 = null - qdel(src) - return - add_fingerprint(user) - return - -/obj/item/assembly/shock_kit/attack_self(mob/user) - part1.attack_self(user) - part2.attack_self(user) - add_fingerprint(user) - return - -/obj/item/assembly/shock_kit/receive_signal() - if(istype(loc, /obj/structure/chair/e_chair)) - var/obj/structure/chair/e_chair/C = loc - C.shock() - return + +/obj/item/assembly/shock_kit/Destroy() + qdel(part1) + qdel(part2) + return ..() + +/obj/item/assembly/shock_kit/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/wrench)) + part1.forceMove(drop_location()) + part2.forceMove(drop_location()) + part1.master = null + part2.master = null + part1 = null + part2 = null + qdel(src) + return + add_fingerprint(user) + return + +/obj/item/assembly/shock_kit/attack_self(mob/user) + part1.attack_self(user) + part2.attack_self(user) + add_fingerprint(user) + return + +/obj/item/assembly/shock_kit/receive_signal() + if(istype(loc, /obj/structure/chair/e_chair)) + var/obj/structure/chair/e_chair/C = loc + C.shock() + return diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index f263fc0063..d9fdab39be 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -6,7 +6,6 @@ lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' materials = list(MAT_METAL=400, MAT_GLASS=120) - origin_tech = "magnets=1;bluespace=1" wires = WIRE_RECEIVE | WIRE_PULSE | WIRE_RADIO_PULSE | WIRE_RADIO_RECEIVE attachable = 1 @@ -185,7 +184,6 @@ Code: return /obj/item/device/assembly/signaler/cyborg - origin_tech = null /obj/item/device/assembly/signaler/cyborg/attackby(obj/item/W, mob/user, params) return diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm index 30a1ee71d3..8e2c1245b9 100644 --- a/code/modules/assembly/timer.dm +++ b/code/modules/assembly/timer.dm @@ -3,7 +3,6 @@ desc = "Used to time things. Works well with contraptions which has to count down. Tick tock." icon_state = "timer" materials = list(MAT_METAL=500, MAT_GLASS=50) - origin_tech = "magnets=1;engineering=1" attachable = 1 var/timing = 0 diff --git a/code/modules/assembly/voice.dm b/code/modules/assembly/voice.dm index 8d6f2bf044..617f384592 100644 --- a/code/modules/assembly/voice.dm +++ b/code/modules/assembly/voice.dm @@ -3,7 +3,6 @@ desc = "A small electronic device able to record a voice sample, and send a signal when that sample is repeated." icon_state = "voice" materials = list(MAT_METAL=500, MAT_GLASS=50) - origin_tech = "magnets=1;engineering=1" flags_1 = HEAR_1 attachable = 1 verb_say = "beeps" diff --git a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm index 5ef9469295..f2d1a241f2 100644 --- a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm +++ b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm @@ -7,7 +7,7 @@ //list of open turfs adjacent to us var/list/atmos_adjacent_turfs //bitfield of dirs in which we are superconducitng - var/atmos_supeconductivity = 0 + var/atmos_supeconductivity = NONE //used to determine whether we should archive var/archived_cycle = 0 @@ -25,8 +25,7 @@ var/pressure_direction = 0 var/datum/excited_group/excited_group - var/excited = 0 - var/recently_active = 0 + var/excited = FALSE var/datum/gas_mixture/turf/air var/obj/effect/hotspot/active_hotspot @@ -54,10 +53,10 @@ /turf/open/assume_air(datum/gas_mixture/giver) //use this for machines to adjust air if(!giver) - return 0 + return FALSE air.merge(giver) update_visuals() - return 1 + return TRUE /turf/open/remove_air(amount) var/datum/gas_mixture/ours = return_air() @@ -83,7 +82,7 @@ /turf/temperature_expose() if(temperature > heat_capacity) - to_be_destroyed = 1 + to_be_destroyed = TRUE /turf/proc/archive() temperature_archived = temperature @@ -102,7 +101,7 @@ #if DM_VERSION >= 513 #warning 512 is stable now for sure, remove the old code #endif - + #if DM_VERSION >= 512 if (atmos_overlay_types) for(var/overlay in atmos_overlay_types-new_overlay_types) //doesn't remove overlays that would only be added @@ -175,64 +174,48 @@ for(var/t in adjacent_turfs) var/turf/open/enemy_tile = t - if(fire_count > enemy_tile.current_cycle) - enemy_tile.archive() + if(fire_count <= enemy_tile.current_cycle) + continue + enemy_tile.archive() - /******************* GROUP HANDLING START *****************************************************************/ + /******************* GROUP HANDLING START *****************************************************************/ - var/should_share_air = FALSE - var/datum/gas_mixture/enemy_air = enemy_tile.air - if(enemy_tile.excited) - //cache for sanic speed - var/datum/excited_group/enemy_excited_group = enemy_tile.excited_group - if(our_excited_group) - if(enemy_excited_group) - if(our_excited_group != enemy_excited_group) - //combine groups (this also handles updating the excited_group var of all involved turfs) - our_excited_group.merge_groups(enemy_excited_group) - our_excited_group = excited_group //update our cache - should_share_air = TRUE - else - if((recently_active == 1 && enemy_tile.recently_active == 1) || our_air.compare(enemy_air)) - our_excited_group.add_turf(enemy_tile) //add enemy to our group - should_share_air = TRUE + var/should_share_air = FALSE + var/datum/gas_mixture/enemy_air = enemy_tile.air + + //cache for sanic speed + var/datum/excited_group/enemy_excited_group = enemy_tile.excited_group + + if(our_excited_group && enemy_excited_group) + if(our_excited_group != enemy_excited_group) + //combine groups (this also handles updating the excited_group var of all involved turfs) + our_excited_group.merge_groups(enemy_excited_group) + our_excited_group = excited_group //update our cache + should_share_air = TRUE + + else if(our_air.compare(enemy_air)) + if(!enemy_tile.excited) + SSair.add_to_active(enemy_tile) + var/datum/excited_group/EG = our_excited_group || enemy_excited_group || new + if(!our_excited_group) + EG.add_turf(src) + if(!enemy_excited_group) + EG.add_turf(enemy_tile) + our_excited_group = excited_group + should_share_air = TRUE + + //air sharing + if(should_share_air) + var/difference = our_air.share(enemy_air, adjacent_turfs_length) + if(difference) + if(difference > 0) + consider_pressure_difference(enemy_tile, difference) else - if(enemy_excited_group) - if((recently_active == 1 && enemy_tile.recently_active == 1) || our_air.compare(enemy_air)) - enemy_excited_group.add_turf(src) //join self to enemy group - our_excited_group = excited_group //update our cache - should_share_air = TRUE - else - if((recently_active == 1 && enemy_tile.recently_active == 1) || our_air.compare(enemy_air)) - var/datum/excited_group/EG = new //generate new group - EG.add_turf(src) - EG.add_turf(enemy_tile) - our_excited_group = excited_group //update our cache - should_share_air = TRUE - else - if(our_air.compare(enemy_air)) //compare if - SSair.add_to_active(enemy_tile) //excite enemy - if(our_excited_group) - our_excited_group.add_turf(enemy_tile) //add enemy to group - else - var/datum/excited_group/EG = new //generate new group - EG.add_turf(src) - EG.add_turf(enemy_tile) - our_excited_group = excited_group //update our cache - should_share_air = TRUE - - //air sharing - if(should_share_air) - var/difference = our_air.share(enemy_air, adjacent_turfs_length) - if(difference) - if(difference > 0) - consider_pressure_difference(enemy_tile, difference) - else - enemy_tile.consider_pressure_difference(src, -difference) - LAST_SHARE_CHECK + enemy_tile.consider_pressure_difference(src, -difference) + LAST_SHARE_CHECK - /******************* GROUP HANDLING FINISH *********************************************************************/ + /******************* GROUP HANDLING FINISH *********************************************************************/ if (planet_atmos) //share our air with the "atmosphere" "above" the turf var/datum/gas_mixture/G = new @@ -250,12 +233,8 @@ update_visuals() - var/remove = TRUE - if(our_air.temperature > MINIMUM_TEMPERATURE_START_SUPERCONDUCTION) - if(consider_superconductivity(starting = 1)) - remove = FALSE - - if ((!our_excited_group && remove) || (cached_atmos_cooldown > (EXCITED_GROUP_DISMANTLE_CYCLES * 2))) + if((!our_excited_group && !(our_air.temperature > MINIMUM_TEMPERATURE_START_SUPERCONDUCTION && consider_superconductivity(starting = TRUE))) \ + || (cached_atmos_cooldown > (EXCITED_GROUP_DISMANTLE_CYCLES * 2))) SSair.remove_from_active(src) atmos_cooldown = cached_atmos_cooldown @@ -279,9 +258,9 @@ var/const/PROBABILITY_OFFSET = 25 var/const/PROBABILITY_BASE_PRECENT = 75 set waitfor = 0 - . = 0 + . = FALSE if (!anchored && !pulledby) - . = 1 + . = TRUE if (last_high_pressure_movement_air_cycle < SSair.times_fired) var/move_prob = 100 if (pressure_resistance > 0) @@ -304,7 +283,6 @@ /datum/excited_group/proc/add_turf(turf/open/T) turf_list += T T.excited_group = src - T.recently_active = 1 reset_cooldowns() /datum/excited_group/proc/merge_groups(datum/excited_group/E) @@ -328,25 +306,27 @@ dismantle_cooldown = 0 //argument is so world start can clear out any turf differences quickly. -/datum/excited_group/proc/self_breakdown(space_is_all_consuming = 0) +/datum/excited_group/proc/self_breakdown(space_is_all_consuming = FALSE) var/datum/gas_mixture/A = new //make local for sanic speed var/list/A_gases = A.gases var/list/turf_list = src.turf_list var/turflen = turf_list.len - var/space_in_group = 0 + var/space_in_group = FALSE for(var/t in turf_list) var/turf/open/T = t if (space_is_all_consuming && !space_in_group && istype(T.air, /datum/gas_mixture/immutable/space)) - space_in_group = 1 + space_in_group = TRUE qdel(A) - A = new/datum/gas_mixture/immutable/space() + A = new /datum/gas_mixture/immutable/space() + A_gases = A.gases //update the cache + break A.merge(T.air) for(var/id in A_gases) - A_gases[id][MOLES] = A_gases[id][MOLES]/turflen + A_gases[id][MOLES] /= turflen for(var/t in turf_list) var/turf/open/T = t @@ -359,8 +339,7 @@ /datum/excited_group/proc/dismantle() for(var/t in turf_list) var/turf/open/T = t - T.excited = 0 - T.recently_active = 0 + T.excited = FALSE T.excited_group = null SSair.active_turfs -= T garbage_collect() @@ -432,7 +411,7 @@ //Make sure still hot enough to continue conducting heat if(temp < MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION) SSair.active_super_conductivity -= src - return 0 + return FALSE /turf/open/finish_superconduction() //Conduct with air on my tile if I have it @@ -442,21 +421,21 @@ /turf/proc/consider_superconductivity() if(!thermal_conductivity) - return 0 + return FALSE SSair.active_super_conductivity |= src - return 1 + return TRUE /turf/open/consider_superconductivity(starting) if(air.temperature < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION)) - return 0 + return FALSE if(air.heat_capacity() < M_CELL_WITH_RATIO) // Was: MOLES_CELLSTANDARD*0.1*0.05 Since there are no variables here we can make this a constant. - return 0 + return FALSE return ..() /turf/closed/consider_superconductivity(starting) if(temperature < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION)) - return 0 + return FALSE return ..() /turf/proc/radiate_to_spess() //Radiate excess tile heat to space @@ -465,7 +444,7 @@ if((heat_capacity > 0) && (abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)) var/heat = thermal_conductivity*delta_temperature* \ - (heat_capacity*700000/(heat_capacity+700000)) //700000 is the heat_capacity from a space turf, hardcoded here + (heat_capacity*HEAT_CAPACITY_VACUUM/(heat_capacity+HEAT_CAPACITY_VACUUM)) temperature -= heat/heat_capacity /turf/open/proc/temperature_share_open_to_solid(turf/sharer) diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index 64d77a27dc..dd6e4ffe71 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -37,14 +37,24 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) reaction_results = new //listmos procs +//use the macros in performance intensive areas. for their definitions, refer to code/__DEFINES/atmospherics.dm -// The following procs used to live here: thermal_energy(), assert_gas() and add_gas(). They have been moved into defines in code/__DEFINES/atmospherics.dm + //assert_gas(gas_id) - used to guarantee that the gas list for this id exists in gas_mixture.gases. + //Must be used before adding to a gas. May be used before reading from a gas. +/datum/gas_mixture/proc/assert_gas(gas_id) + ASSERT_GAS(gas_id, src) //assert_gases(args) - shorthand for calling ASSERT_GAS() once for each gas type. /datum/gas_mixture/proc/assert_gases() for(var/id in args) ASSERT_GAS(id, src) + //add_gas(gas_id) - similar to assert_gas(), but does not check for an existing + //gas list for this id. This can clobber existing gases. + //Used instead of assert_gas() when you know the gas does not exist. Faster than assert_gas(). +/datum/gas_mixture/proc/add_gas(gas_id) + ADD_GAS(gas_id, gases) + //add_gases(args) - shorthand for calling add_gas() once for each gas_type. /datum/gas_mixture/proc/add_gases() var/cached_gases = gases @@ -101,6 +111,9 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) /datum/gas_mixture/proc/return_volume() //liters return max(0, volume) +/datum/gas_mixture/proc/thermal_energy() //joules + return THERMAL_ENERGY(src) //see code/__DEFINES/atmospherics.dm; use the define in performance critical areas + /datum/gas_mixture/proc/archive() //Update archived versions of variables //Returns: 1 in all cases @@ -399,7 +412,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) return "" /datum/gas_mixture/react(turf/open/dump_location) - . = 0 + . = NO_REACTION reaction_results = new @@ -423,6 +436,22 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) continue reaction_loop //at this point, all minimum requirements for the reaction are satisfied. + /* currently no reactions have maximum requirements, so we can leave the checks commented out for a slight performance boost + PLEASE DO NOT REMOVE THIS CODE. the commenting is here only for a performance increase. + enabling these checks should be as easy as possible and the fact that they are disabled should be as clear as possible + + var/list/max_reqs = reaction.max_requirements.Copy() + if((max_reqs["TEMP"] && temp > max_reqs["TEMP"]) \ + || (max_reqs["ENER"] && ener > max_reqs["ENER"])) + continue + max_reqs -= "TEMP" + max_reqs -= "ENER" + for(var/id in max_reqs) + if(cached_gases[id] && cached_gases[id][MOLES] > max_reqs[id]) + continue reaction_loop + //at this point, all requirements for the reaction are satisfied. we can now react() + */ + . |= reaction.react(src, dump_location) if (. & STOP_REACTIONS) break diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm index 07339807da..aabbe089fb 100644 --- a/code/modules/atmospherics/gasmixtures/reactions.dm +++ b/code/modules/atmospherics/gasmixtures/reactions.dm @@ -1,5 +1,3 @@ -#define NO_REACTION 0 -#define REACTING 1 //Plasma fire properties #define OXYGEN_BURN_RATE_BASE 1.4 #define PLASMA_BURN_RATE_DELTA 9 @@ -186,7 +184,7 @@ //fusion: a terrible idea that was fun but broken. Now reworked to be less broken and more interesting. /datum/gas_reaction/fusion - exclude = FALSE + exclude = TRUE priority = 2 name = "Plasmic Fusion" id = "fusion" @@ -359,9 +357,6 @@ if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) air.temperature = max(((air.temperature*old_heat_capacity - energy_taken)/new_heat_capacity),TCMB) - -#undef REACTING -#undef NO_REACTION #undef OXYGEN_BURN_RATE_BASE #undef PLASMA_BURN_RATE_DELTA #undef PLASMA_UPPER_TEMPERATURE @@ -386,4 +381,4 @@ #undef CATALYST_COEFFICENT #undef FUSION_PURITY_THRESHOLD #undef FUSION_HEAT_DROPOFF -#undef NOBLIUM_FORMATION_ENERGY \ No newline at end of file +#undef NOBLIUM_FORMATION_ENERGY diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index efe45f4e84..952ee0e068 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -356,6 +356,9 @@ . = TRUE if("threshold") var/env = params["env"] + if(text2path(env)) + env = text2path(env) + var/name = params["var"] var/datum/tlv/tlv = TLV[env] if(isnull(tlv)) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm index f8204947f1..6f72724e1e 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm @@ -185,13 +185,13 @@ Acts like a normal vent, but has an input AND output. pump_direction = 1 if("set_input_pressure" in signal.data) - input_pressure_min = Clamp(text2num(signal.data["set_input_pressure"]),0,ONE_ATMOSPHERE*50) + input_pressure_min = CLAMP(text2num(signal.data["set_input_pressure"]),0,ONE_ATMOSPHERE*50) if("set_output_pressure" in signal.data) - output_pressure_max = Clamp(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50) + output_pressure_max = CLAMP(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50) if("set_external_pressure" in signal.data) - external_pressure_bound = Clamp(text2num(signal.data["set_external_pressure"]),0,ONE_ATMOSPHERE*50) + external_pressure_bound = CLAMP(text2num(signal.data["set_external_pressure"]),0,ONE_ATMOSPHERE*50) if("status" in signal.data) spawn(2) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm index 86c5375d07..ef4e487efd 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm @@ -127,7 +127,7 @@ Passive gate is similar to the regular pump except: pressure = text2num(pressure) . = TRUE if(.) - target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE) + target_pressure = CLAMP(pressure, 0, MAX_OUTPUT_PRESSURE) investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS) update_icon() @@ -149,7 +149,7 @@ Passive gate is similar to the regular pump except: on = !on if("set_output_pressure" in signal.data) - target_pressure = Clamp(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50) + target_pressure = CLAMP(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50) if(on != old_on) investigate_log("was turned [on ? "on" : "off"] by a remote signal", INVESTIGATE_ATMOS) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm index 97bba0e534..9d581fcb78 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm @@ -133,9 +133,8 @@ Thus, the two variables affect pump operation are set in New(): pressure = text2num(pressure) . = TRUE if(.) - target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE) - investigate_log("Pump, [src.name], was set to [target_pressure] kPa by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) - message_admins("Pump, [src.name], was set to [target_pressure] kPa by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") + target_pressure = CLAMP(pressure, 0, MAX_OUTPUT_PRESSURE) + investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS) update_icon() /obj/machinery/atmospherics/components/binary/pump/atmosinit() @@ -156,7 +155,7 @@ Thus, the two variables affect pump operation are set in New(): on = !on if("set_output_pressure" in signal.data) - target_pressure = Clamp(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50) + target_pressure = CLAMP(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50) if(on != old_on) investigate_log("was turned [on ? "on" : "off"] by a remote signal", INVESTIGATE_ATMOS) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm index b154c0d3e4..2803d1bf09 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm @@ -133,9 +133,8 @@ Thus, the two variables affect pump operation are set in New(): rate = text2num(rate) . = TRUE if(.) - transfer_rate = Clamp(rate, 0, MAX_TRANSFER_RATE) - investigate_log("Volume Pump, [src.name], was set to [transfer_rate] L/s by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) - message_admins("Volume Pump, [src.name], was set to [transfer_rate] L/s by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") + transfer_rate = CLAMP(rate, 0, MAX_TRANSFER_RATE) + investigate_log("was set to [transfer_rate] L/s by [key_name(usr)]", INVESTIGATE_ATMOS) update_icon() /obj/machinery/atmospherics/components/binary/volume_pump/receive_signal(datum/signal/signal) @@ -152,7 +151,7 @@ Thus, the two variables affect pump operation are set in New(): if("set_transfer_rate" in signal.data) var/datum/gas_mixture/air1 = AIR1 - transfer_rate = Clamp(text2num(signal.data["set_transfer_rate"]),0,air1.volume) + transfer_rate = CLAMP(text2num(signal.data["set_transfer_rate"]),0,air1.volume) if(on != old_on) investigate_log("was turned [on ? "on" : "off"] by a remote signal", INVESTIGATE_ATMOS) diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm index 4baeb3dd3e..a1d6dc8c7e 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm @@ -103,7 +103,7 @@ var/datum/gas_mixture/filtered_out = new filtered_out.temperature = removed.temperature - ASSERT_GAS(filter_type, filtered_out) + filtered_out.add_gas(filter_type) filtered_out.gases[filter_type][MOLES] = removed.gases[filter_type][MOLES] removed.gases[filter_type][MOLES] = 0 @@ -162,7 +162,7 @@ pressure = text2num(pressure) . = TRUE if(.) - target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE) + target_pressure = CLAMP(pressure, 0, MAX_OUTPUT_PRESSURE) investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS) if("filter") filter_type = null diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm index b706cd3cd9..b15df59662 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm @@ -152,7 +152,7 @@ pressure = text2num(pressure) . = TRUE if(.) - target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE) + target_pressure = CLAMP(pressure, 0, MAX_OUTPUT_PRESSURE) investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS) if("node1") var/value = text2num(params["concentration"]) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm index 37bfb5d952..64e6e56504 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm @@ -131,7 +131,7 @@ if("set_volume_rate" in signal.data) var/number = text2num(signal.data["set_volume_rate"]) var/datum/gas_mixture/air_contents = AIR1 - volume_rate = Clamp(number, 0, air_contents.volume) + volume_rate = CLAMP(number, 0, air_contents.volume) if("status" in signal.data) spawn(2) @@ -180,7 +180,7 @@ rate = text2num(rate) . = TRUE if(.) - volume_rate = Clamp(rate, 0, MAX_TRANSFER_RATE) + volume_rate = CLAMP(rate, 0, MAX_TRANSFER_RATE) investigate_log("was set to [volume_rate] L/s by [key_name(usr)]", INVESTIGATE_ATMOS) update_icon() broadcast_status() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/tank.dm b/code/modules/atmospherics/machinery/components/unary_devices/tank.dm index ec1fcdfc52..4e9df101a6 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/tank.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/tank.dm @@ -17,7 +17,7 @@ air_contents.volume = volume air_contents.temperature = T20C if(gas_type) - ASSERT_GAS(gas_type, air_contents) + air_contents.assert_gas(gas_type) air_contents.gases[gas_type][MOLES] = AIR_CONTENTS name = "[name] ([air_contents.gases[gas_type][GAS_META][META_GAS_NAME]])" diff --git a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm index d7bfe1ecb8..8d34d5adfa 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm @@ -1,7 +1,7 @@ /obj/machinery/atmospherics/components/unary/thermomachine name = "thermomachine" desc = "Heats or cools gas in connected pipes." - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/atmospherics/components/thermomachine.dmi' icon_state = "freezer" var/icon_state_on = "cold_on" var/icon_state_open = "cold_off" @@ -153,14 +153,13 @@ target = text2num(target) . = TRUE if(.) - target_temperature = Clamp(target, min_temperature, max_temperature) + target_temperature = CLAMP(target, min_temperature, max_temperature) investigate_log("was set to [target_temperature] K by [key_name(usr)]", INVESTIGATE_ATMOS) update_icon() /obj/machinery/atmospherics/components/unary/thermomachine/freezer name = "freezer" - icon = 'icons/obj/Cryogenic2.dmi' icon_state = "freezer" icon_state_on = "freezer_1" icon_state_open = "freezer-o" @@ -177,7 +176,6 @@ /obj/machinery/atmospherics/components/unary/thermomachine/heater name = "heater" - icon = 'icons/obj/Cryogenic2.dmi' icon_state = "heater" icon_state_on = "heater_1" icon_state_open = "heater-o" diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm index a05a13217d..2c9a308ec9 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm @@ -244,10 +244,10 @@ pump_direction = text2num(signal.data["direction"]) if("set_internal_pressure" in signal.data) - internal_pressure_bound = Clamp(text2num(signal.data["set_internal_pressure"]),0,ONE_ATMOSPHERE*50) + internal_pressure_bound = CLAMP(text2num(signal.data["set_internal_pressure"]),0,ONE_ATMOSPHERE*50) if("set_external_pressure" in signal.data) - external_pressure_bound = Clamp(text2num(signal.data["set_external_pressure"]),0,ONE_ATMOSPHERE*50) + external_pressure_bound = CLAMP(text2num(signal.data["set_external_pressure"]),0,ONE_ATMOSPHERE*50) if("reset_external_pressure" in signal.data) external_pressure_bound = ONE_ATMOSPHERE @@ -256,10 +256,10 @@ internal_pressure_bound = 0 if("adjust_internal_pressure" in signal.data) - internal_pressure_bound = Clamp(internal_pressure_bound + text2num(signal.data["adjust_internal_pressure"]),0,ONE_ATMOSPHERE*50) + internal_pressure_bound = CLAMP(internal_pressure_bound + text2num(signal.data["adjust_internal_pressure"]),0,ONE_ATMOSPHERE*50) if("adjust_external_pressure" in signal.data) - external_pressure_bound = Clamp(external_pressure_bound + text2num(signal.data["adjust_external_pressure"]),0,ONE_ATMOSPHERE*50) + external_pressure_bound = CLAMP(external_pressure_bound + text2num(signal.data["adjust_external_pressure"]),0,ONE_ATMOSPHERE*50) if("init" in signal.data) name = signal.data["init"] diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm index b3ade6f0fb..8fffd70840 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm @@ -179,7 +179,7 @@ filtered_out.temperature = removed.temperature for(var/gas in filter_types & removed_gases) - ADD_GAS(gas, filtered_gases) + filtered_out.add_gas(gas) filtered_gases[gas][MOLES] = removed_gases[gas][MOLES] removed_gases[gas][MOLES] = 0 diff --git a/code/modules/atmospherics/machinery/other/meter.dm b/code/modules/atmospherics/machinery/other/meter.dm index 4edced52b3..a26b379735 100644 --- a/code/modules/atmospherics/machinery/other/meter.dm +++ b/code/modules/atmospherics/machinery/other/meter.dm @@ -1,7 +1,7 @@ /obj/machinery/meter name = "gas flow meter" desc = "It measures something." - icon = 'icons/obj/meter.dmi' + icon = 'icons/obj/atmospherics/pipes/meter.dmi' icon_state = "meterX" var/atom/target = null anchored = TRUE diff --git a/code/modules/atmospherics/machinery/other/miner.dm b/code/modules/atmospherics/machinery/other/miner.dm index cb28f17802..f63065b431 100644 --- a/code/modules/atmospherics/machinery/other/miner.dm +++ b/code/modules/atmospherics/machinery/other/miner.dm @@ -132,7 +132,7 @@ if(!isopenturf(O)) return FALSE var/datum/gas_mixture/merger = new - ASSERT_GAS(spawn_id, merger) + merger.assert_gas(spawn_id) merger.gases[spawn_id][MOLES] = (spawn_mol) merger.temperature = spawn_temp O.assume_air(merger) diff --git a/code/modules/atmospherics/machinery/pipes/layermanifold.dm b/code/modules/atmospherics/machinery/pipes/layermanifold.dm index fee00baf50..d2f85c7667 100644 --- a/code/modules/atmospherics/machinery/pipes/layermanifold.dm +++ b/code/modules/atmospherics/machinery/pipes/layermanifold.dm @@ -121,7 +121,7 @@ if(initialize_directions & dir) return ..() if((NORTH|EAST) & dir) - user.ventcrawl_layer = Clamp(user.ventcrawl_layer + 1, PIPING_LAYER_MIN, PIPING_LAYER_MAX) + user.ventcrawl_layer = CLAMP(user.ventcrawl_layer + 1, PIPING_LAYER_MIN, PIPING_LAYER_MAX) if((SOUTH|WEST) & dir) - user.ventcrawl_layer = Clamp(user.ventcrawl_layer - 1, PIPING_LAYER_MIN, PIPING_LAYER_MAX) + user.ventcrawl_layer = CLAMP(user.ventcrawl_layer - 1, PIPING_LAYER_MIN, PIPING_LAYER_MAX) to_chat(user, "You align yourself with the [user.ventcrawl_layer]\th output.") diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm index 585b6e896a..7b6351e939 100644 --- a/code/modules/atmospherics/machinery/portable/canister.dm +++ b/code/modules/atmospherics/machinery/portable/canister.dm @@ -196,7 +196,7 @@ /obj/machinery/portable_atmospherics/canister/proc/create_gas() if(gas_type) - ADD_GAS(gas_type, air_contents.gases) + air_contents.add_gas(gas_type) if(starter_temp) air_contents.temperature = starter_temp air_contents.gases[gas_type][MOLES] = (maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) @@ -411,7 +411,7 @@ pressure = text2num(pressure) . = TRUE if(.) - release_pressure = Clamp(round(pressure), can_min_release_pressure, can_max_release_pressure) + release_pressure = CLAMP(round(pressure), can_min_release_pressure, can_max_release_pressure) investigate_log("was set to [release_pressure] kPa by [key_name(usr)].", INVESTIGATE_ATMOS) if("valve") var/logmsg @@ -455,7 +455,7 @@ var/N = text2num(user_input) if(!N) return - timer_set = Clamp(N,minimum_timer_set,maximum_timer_set) + timer_set = CLAMP(N,minimum_timer_set,maximum_timer_set) log_admin("[key_name(usr)] has activated a prototype valve timer") . = TRUE if("toggle_timer") diff --git a/code/modules/atmospherics/machinery/portable/pump.dm b/code/modules/atmospherics/machinery/portable/pump.dm index 3f2bceaa04..36dd30731e 100644 --- a/code/modules/atmospherics/machinery/portable/pump.dm +++ b/code/modules/atmospherics/machinery/portable/pump.dm @@ -131,11 +131,11 @@ pressure = text2num(pressure) . = TRUE if(.) - pump.target_pressure = Clamp(round(pressure), PUMP_MIN_PRESSURE, PUMP_MAX_PRESSURE) + pump.target_pressure = CLAMP(round(pressure), PUMP_MIN_PRESSURE, PUMP_MAX_PRESSURE) investigate_log("was set to [pump.target_pressure] kPa by [key_name(usr)].", INVESTIGATE_ATMOS) if("eject") if(holding) - holding.loc = get_turf(src) + holding.forceMove(drop_location()) holding = null . = TRUE update_icon() diff --git a/code/modules/atmospherics/machinery/portable/scrubber.dm b/code/modules/atmospherics/machinery/portable/scrubber.dm index 564e6d294f..4bb7b02288 100644 --- a/code/modules/atmospherics/machinery/portable/scrubber.dm +++ b/code/modules/atmospherics/machinery/portable/scrubber.dm @@ -45,7 +45,7 @@ filtered.temperature = filtering.temperature for(var/gas in filtering.gases & scrubbing) - ADD_GAS(gas, filtered.gases) + filtered.add_gas(gas) filtered.gases[gas][MOLES] = filtering.gases[gas][MOLES] // Shuffle the "bad" gasses to the filtered mixture. filtering.gases[gas][MOLES] = 0 filtering.garbage_collect() // Now that the gasses are set to 0, clean up the mixture. @@ -96,7 +96,7 @@ . = TRUE if("eject") if(holding) - holding.loc = get_turf(src) + holding.forceMove(drop_location()) holding = null . = TRUE if("toggle_filter") diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index 9a156d6b62..1f5df77be7 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -204,7 +204,7 @@ brute_damage = 1000 /obj/effect/mob_spawn/human/alive - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" death = FALSE roundstart = FALSE //you could use these for alive fake humans on roundstart but this is more common scenario @@ -243,7 +243,7 @@ mob_type = /mob/living/simple_animal/mouse death = FALSE roundstart = FALSE - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" /obj/effect/mob_spawn/cow @@ -252,7 +252,7 @@ death = FALSE roundstart = FALSE mob_gender = FEMALE - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" // I'll work on making a list of corpses people request for maps, or that I think will be commonly used. Syndicate operatives for example. @@ -274,7 +274,7 @@ roundstart = FALSE random = TRUE name = "sleeper" - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" flavour_text = "You are a space doctor!" assignedrole = "Space Doctor" @@ -329,7 +329,7 @@ roundstart = FALSE random = TRUE name = "bartender sleeper" - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" flavour_text = "You are a space bartender!" assignedrole = "Space Bartender" @@ -353,7 +353,7 @@ random = TRUE mob_name = "Beach Bum" name = "beach bum sleeper" - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" flavour_text = "You are a beach bum!" assignedrole = "Beach Bum" @@ -431,7 +431,7 @@ roundstart = FALSE mob_name = "Nanotrasen Commander" name = "sleeper" - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" flavour_text = "You are a Nanotrasen Commander!" @@ -440,7 +440,7 @@ roundstart = FALSE mob_name = "Private Security Officer" name = "sleeper" - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" faction = "nanotrasenprivate" flavour_text = "You are a Nanotrasen Private Security Officer!" diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm index 15c5deb4cb..90b2e3a02e 100644 --- a/code/modules/awaymissions/gateway.dm +++ b/code/modules/awaymissions/gateway.dm @@ -199,9 +199,9 @@ GLOBAL_DATUM(the_gateway, /obj/machinery/gateway/centerstation) active = 1 update_icon() -/obj/machinery/gateway/centeraway/proc/check_exile_implant(mob/living/carbon/C) - for(var/obj/item/implant/exile/E in C.implants)//Checking that there is an exile implant - to_chat(C, "\black The station gate has detected your exile implant and is blocking your entry.") +/obj/machinery/gateway/centeraway/proc/check_exile_implant(mob/living/L) + for(var/obj/item/implant/exile/E in L.implants)//Checking that there is an exile implant + to_chat(L, "\black The station gate has detected your exile implant and is blocking your entry.") return TRUE return FALSE @@ -212,17 +212,17 @@ GLOBAL_DATUM(the_gateway, /obj/machinery/gateway/centerstation) return if(!stationgate || QDELETED(stationgate)) return - if(istype(AM, /mob/living/carbon)) + if(isliving(AM)) if(check_exile_implant(AM)) return else - for(var/mob/living/carbon/C in AM.contents) - if(check_exile_implant(C)) + for(var/mob/living/L in AM.contents) + if(check_exile_implant(L)) say("Rejecting [AM]: Exile implant detected in contained lifeform.") return if(AM.has_buckled_mobs()) - for(var/mob/living/carbon/C in AM.buckled_mobs) - if(check_exile_implant(C)) + for(var/mob/living/L in AM.buckled_mobs) + if(check_exile_implant(L)) say("Rejecting [AM]: Exile implant detected in close proximity lifeform.") return AM.forceMove(get_step(stationgate.loc, SOUTH)) diff --git a/code/modules/awaymissions/mission_code/Academy.dm b/code/modules/awaymissions/mission_code/Academy.dm index 5af834955f..bf256fecbd 100644 --- a/code/modules/awaymissions/mission_code/Academy.dm +++ b/code/modules/awaymissions/mission_code/Academy.dm @@ -207,7 +207,7 @@ //Swarm of creatures for(var/direction in GLOB.alldirs) var/turf/T = get_turf(src) - new /mob/living/simple_animal/hostile/creature(get_step(T,direction)) + new /mob/living/simple_animal/hostile/netherworld(get_step(T,direction)) if(4) //Destroy Equipment for (var/obj/item/I in user) diff --git a/code/modules/awaymissions/mission_code/snowdin.dm b/code/modules/awaymissions/mission_code/snowdin.dm index c8658c677f..4c3b54fa0d 100644 --- a/code/modules/awaymissions/mission_code/snowdin.dm +++ b/code/modules/awaymissions/mission_code/snowdin.dm @@ -218,15 +218,6 @@ desc = "This wand uses healing magics to heal and revive. The years of the cold have weakened the magic inside the wand." max_charges = 5 -/obj/item/device/radio/uplink/old - name = "dusty radio" - desc = "A dusty looking radio." - -/obj/item/device/radio/uplink/old/Initialize() - . = ..() - hidden_uplink.name = "dusty radio" - hidden_uplink.telecrystals = 10 - /obj/effect/mob_spawn/human/syndicatesoldier/coldres name = "Syndicate Snow Operative" outfit = /datum/outfit/snowsyndie/corpse @@ -238,7 +229,7 @@ /obj/effect/mob_spawn/human/syndicatesoldier/coldres/alive name = "sleeper" mob_name = "Syndicate Snow Operative" - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" roundstart = FALSE death = FALSE diff --git a/code/modules/awaymissions/mission_code/wildwest.dm b/code/modules/awaymissions/mission_code/wildwest.dm index 3031936d43..1fe8baba01 100644 --- a/code/modules/awaymissions/mission_code/wildwest.dm +++ b/code/modules/awaymissions/mission_code/wildwest.dm @@ -115,9 +115,11 @@ to_chat(user, "The Wish Granter punishes you for your wickedness, claiming your soul and warping your body to match the darkness in your heart.") SSticker.mode.traitors += user.mind user.mind.special_role = "traitor" + var/datum/objective/hijack/hijack = new hijack.owner = user.mind user.mind.objectives += hijack + user.mind.add_antag_datum(/datum/antagonist/auto_custom) to_chat(user, "Your inhibitions are swept away, the bonds of loyalty broken, you are free to murder as you please!") user.mind.announce_objectives() user.set_species(/datum/species/shadow) diff --git a/code/modules/awaymissions/super_secret_room.dm b/code/modules/awaymissions/super_secret_room.dm index fa9aff7f43..b1f505a27e 100644 --- a/code/modules/awaymissions/super_secret_room.dm +++ b/code/modules/awaymissions/super_secret_room.dm @@ -17,6 +17,8 @@ var/list/json = json_decode(file2text(json_file)) shenanigans = json["phrases"] +#define TIMEWASTE_MEDAL "Overextended The Joke" + /obj/structure/speaking_tile/interact(mob/user) if(!isliving(user) || speaking) return @@ -45,11 +47,11 @@ SpeakPeace(list("Alright maybe that's too boring.", "I can't keep manually typing these lines out though.", "It's hard to explain but the code structure I'm using is kind of terrible.")) if(10) SpeakPeace(list("Oh I have an idea!", "Lets outsource this endless banter to Poly!", "Then you'll be able to keep listening to this without getting bored!")) - if(isnull(shenanigans)) + if(isnull(shenanigans) || !shenanigans.len) shenanigans = list("Except the poly file is missing...") if(11 to 14, 16 to 50, 52 to 99, 103 to 107, 109 to 203, 205 to 249, 252 to 665, 667 to 999, 1001 to 5642) SpeakPeace(list(pick(shenanigans),pick(shenanigans),pick(shenanigans))) - if(times_spoken_to * 0.1 == round(times_spoken_to * 0.1)) + if(times_spoken_to % 10 == 0) SpeakPeace(list("That's [times_spoken_to] times you've spoken to me by the way.")) if(15) SpeakPeace(list("See? Isn't this fun?","Now you can mash this for hours without getting bored.","Anyway I'll leave you it.")) @@ -79,6 +81,7 @@ if(1000) SpeakPeace(list("The ends exists somewhere beyond meaningful milestones.", "There will be no more messages until then.", "You disgust me.")) if(5643) + UnlockMedal(TIMEWASTE_MEDAL,user.client) var/obj/item/reagent_containers/food/drinks/trophy/gold_cup/never_ends = new(get_turf(user)) never_ends.name = "Overextending The Joke: First Place" never_ends.desc = "And so we are left alone with our regrets." @@ -87,7 +90,7 @@ speaking = FALSE times_spoken_to++ - +#undef TIMEWASTE_MEDAL /obj/structure/speaking_tile/proc/SpeakPeace(list/statements) for(var/i in 1 to statements.len) say("[statements[i]]") diff --git a/code/modules/cargo/exports.dm b/code/modules/cargo/exports.dm index 92b953e7b2..b4c0aa350d 100644 --- a/code/modules/cargo/exports.dm +++ b/code/modules/cargo/exports.dm @@ -86,7 +86,7 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they /datum/export/process() ..() - cost *= GLOB.E**(k_elasticity * (1/30)) + cost *= NUM_E**(k_elasticity * (1/30)) if(cost > init_cost) cost = init_cost @@ -94,7 +94,7 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they /datum/export/proc/get_cost(obj/O, contr = 0, emag = 0) var/amount = get_amount(O, contr, emag) if(k_elasticity!=0) - return round((cost/k_elasticity) * (1 - GLOB.E**(-1 * k_elasticity * amount))) //anti-derivative of the marginal cost function + return round((cost/k_elasticity) * (1 - NUM_E**(-1 * k_elasticity * amount))) //anti-derivative of the marginal cost function else return round(cost * amount) //alternative form derived from L'Hopital to avoid division by 0 @@ -131,7 +131,7 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they else total_amount += amount - cost *= GLOB.E**(-1*k_elasticity*amount) //marginal cost modifier + cost *= NUM_E**(-1*k_elasticity*amount) //marginal cost modifier SSblackbox.record_feedback("nested tally", "export_sold_cost", 1, list("[O.type]", "[the_cost]")) // Total printout for the cargo console. diff --git a/code/modules/cargo/exports/research.dm b/code/modules/cargo/exports/research.dm index a24e86d379..b1ac30e7f9 100644 --- a/code/modules/cargo/exports/research.dm +++ b/code/modules/cargo/exports/research.dm @@ -3,23 +3,20 @@ cost = 500 unit_name = "technology data disk" export_types = list(/obj/item/disk/tech_disk) - var/list/techLevels = list() + var/list/datum/techweb_node/sold_nodes = list() /datum/export/tech/get_cost(obj/O) var/obj/item/disk/tech_disk/D = O var/cost = 0 - for(var/V in D.tech_stored) - if(!V) + for(var/V in D.stored_research.researched_nodes) + if(sold_nodes[V]) //Already sold before, don't want it. continue - var/datum/tech/tech = V - cost += tech.getCost(techLevels[tech.id]) + var/datum/techweb_node/TWN = D.stored_research.researched_nodes[V] + cost += TWN return ..() * cost /datum/export/tech/sell_object(obj/O) ..() var/obj/item/disk/tech_disk/D = O - for(var/V in D.tech_stored) - if(!V) - continue - var/datum/tech/tech = V - techLevels[tech.id] = max(techLevels[tech.id], tech.level) + for(var/V in D.stored_research.researched_nodes) + sold_nodes[V] = D.stored_research.researched_nodes[V] diff --git a/code/modules/cargo/order.dm b/code/modules/cargo/order.dm index 5fb6cee2b7..de8966bd3a 100644 --- a/code/modules/cargo/order.dm +++ b/code/modules/cargo/order.dm @@ -1,97 +1,97 @@ /obj/item/paper/fluff/jobs/cargo/manifest - var/order_cost = 0 - var/order_id = 0 - var/errors = 0 - + var/order_cost = 0 + var/order_id = 0 + var/errors = 0 + /obj/item/paper/fluff/jobs/cargo/manifest/New(atom/A, id, cost) - ..() - order_id = id - order_cost = cost - - if(prob(MANIFEST_ERROR_CHANCE)) - errors |= MANIFEST_ERROR_NAME - if(prob(MANIFEST_ERROR_CHANCE)) - errors |= MANIFEST_ERROR_CONTENTS - if(prob(MANIFEST_ERROR_CHANCE)) - errors |= MANIFEST_ERROR_ITEM - + ..() + order_id = id + order_cost = cost + + if(prob(MANIFEST_ERROR_CHANCE)) + errors |= MANIFEST_ERROR_NAME + if(prob(MANIFEST_ERROR_CHANCE)) + errors |= MANIFEST_ERROR_CONTENTS + if(prob(MANIFEST_ERROR_CHANCE)) + errors |= MANIFEST_ERROR_ITEM + /obj/item/paper/fluff/jobs/cargo/manifest/proc/is_approved() - return stamped && stamped.len && !is_denied() - + return stamped && stamped.len && !is_denied() + /obj/item/paper/fluff/jobs/cargo/manifest/proc/is_denied() - return stamped && ("stamp-deny" in stamped) - -/datum/supply_order - var/id - var/orderer - var/orderer_rank - var/orderer_ckey - var/reason - var/datum/supply_pack/pack - -/datum/supply_order/New(datum/supply_pack/pack, orderer, orderer_rank, orderer_ckey, reason) - id = SSshuttle.ordernum++ - src.pack = pack - src.orderer = orderer - src.orderer_rank = orderer_rank - src.orderer_ckey = orderer_ckey - src.reason = reason - -/datum/supply_order/proc/generateRequisition(turf/T) - var/obj/item/paper/P = new(T) - - P.name = "requisition form - #[id] ([pack.name])" - P.info += "

    [station_name()] Supply Requisition

    " - P.info += "
    " - P.info += "Order #[id]
    " - P.info += "Item: [pack.name]
    " - P.info += "Access Restrictions: [get_access_desc(pack.access)]
    " - P.info += "Requested by: [orderer]
    " - P.info += "Rank: [orderer_rank]
    " - P.info += "Comment: [reason]
    " - - P.update_icon() - return P - -/datum/supply_order/proc/generateManifest(obj/structure/closet/crate/C) + return stamped && ("stamp-deny" in stamped) + +/datum/supply_order + var/id + var/orderer + var/orderer_rank + var/orderer_ckey + var/reason + var/datum/supply_pack/pack + +/datum/supply_order/New(datum/supply_pack/pack, orderer, orderer_rank, orderer_ckey, reason) + id = SSshuttle.ordernum++ + src.pack = pack + src.orderer = orderer + src.orderer_rank = orderer_rank + src.orderer_ckey = orderer_ckey + src.reason = reason + +/datum/supply_order/proc/generateRequisition(turf/T) + var/obj/item/paper/P = new(T) + + P.name = "requisition form - #[id] ([pack.name])" + P.info += "

    [station_name()] Supply Requisition

    " + P.info += "
    " + P.info += "Order #[id]
    " + P.info += "Item: [pack.name]
    " + P.info += "Access Restrictions: [get_access_desc(pack.access)]
    " + P.info += "Requested by: [orderer]
    " + P.info += "Rank: [orderer_rank]
    " + P.info += "Comment: [reason]
    " + + P.update_icon() + return P + +/datum/supply_order/proc/generateManifest(obj/structure/closet/crate/C) var/obj/item/paper/fluff/jobs/cargo/manifest/P = new(C, id, pack.cost) - - var/station_name = (P.errors & MANIFEST_ERROR_NAME) ? new_station_name() : station_name() - - P.name = "shipping manifest - #[id] ([pack.name])" - P.info += "

    [command_name()] Shipping Manifest

    " - P.info += "
    " - P.info += "Order #[id]
    " - P.info += "Destination: [station_name]
    " - P.info += "Item: [pack.name]
    " - P.info += "Contents:
    " - P.info += "
      " - for(var/atom/movable/AM in C.contents - P) - if((P.errors & MANIFEST_ERROR_CONTENTS)) - if(prob(50)) - P.info += "
    • [AM.name]
    • " - else - continue - P.info += "
    • [AM.name]
    • " - P.info += "
    " - P.info += "

    Stamp below to confirm receipt of goods:

    " - - P.update_icon() - P.loc = C - C.manifest = P - C.update_icon() - - return P - -/datum/supply_order/proc/generate(turf/T) - var/obj/structure/closet/crate/C = pack.generate(T) + + var/station_name = (P.errors & MANIFEST_ERROR_NAME) ? new_station_name() : station_name() + + P.name = "shipping manifest - #[id] ([pack.name])" + P.info += "

    [command_name()] Shipping Manifest

    " + P.info += "
    " + P.info += "Order #[id]
    " + P.info += "Destination: [station_name]
    " + P.info += "Item: [pack.name]
    " + P.info += "Contents:
    " + P.info += "
      " + for(var/atom/movable/AM in C.contents - P) + if((P.errors & MANIFEST_ERROR_CONTENTS)) + if(prob(50)) + P.info += "
    • [AM.name]
    • " + else + continue + P.info += "
    • [AM.name]
    • " + P.info += "
    " + P.info += "

    Stamp below to confirm receipt of goods:

    " + + P.update_icon() + P.forceMove(C) + C.manifest = P + C.update_icon() + + return P + +/datum/supply_order/proc/generate(turf/T) + var/obj/structure/closet/crate/C = pack.generate(T) var/obj/item/paper/fluff/jobs/cargo/manifest/M = generateManifest(C) - - if(M.errors & MANIFEST_ERROR_ITEM) - if(istype(C, /obj/structure/closet/crate/secure) || istype(C, /obj/structure/closet/crate/large)) - M.errors &= ~MANIFEST_ERROR_ITEM - else - var/lost = max(round(C.contents.len / 10), 1) - while(--lost >= 0) - qdel(pick(C.contents)) - return C + + if(M.errors & MANIFEST_ERROR_ITEM) + if(istype(C, /obj/structure/closet/crate/secure) || istype(C, /obj/structure/closet/crate/large)) + M.errors &= ~MANIFEST_ERROR_ITEM + else + var/lost = max(round(C.contents.len / 10), 1) + while(--lost >= 0) + qdel(pick(C.contents)) + return C diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm index 4269de6069..de62ba465e 100644 --- a/code/modules/cargo/packs.dm +++ b/code/modules/cargo/packs.dm @@ -54,7 +54,7 @@ name = "Biker Gang Kit" //TUNNEL SNAKES OWN THIS TOWN cost = 2000 contraband = TRUE - contains = list(/obj/vehicle/atv, + contains = list(/obj/vehicle/ridden/atv, /obj/item/key, /obj/item/clothing/suit/jacket/leather/overcoat, /obj/item/clothing/gloves/color/black, @@ -937,15 +937,6 @@ crate_type = /obj/structure/closet/crate/secure/science dangerous = TRUE - -/datum/supply_pack/science/research - name = "Machine Prototype Crate" - cost = 8000 - access = ACCESS_RESEARCH - contains = list(/obj/item/device/machineprototype) - crate_name = "machine prototype crate" - crate_type = /obj/structure/closet/crate/secure/science - /datum/supply_pack/science/tablets name = "Tablet Crate" cost = 5000 @@ -1230,6 +1221,14 @@ /obj/item/vending_refill/cigarette) crate_name = "cigarette supply crate" +/datum/supply_pack/organic/vending/games + name = "Games Supply Crate" + cost = 1000 + contains = list(/obj/item/vending_refill/games, + /obj/item/vending_refill/games, + /obj/item/vending_refill/games) + crate_name = "games supply crate" + ////////////////////////////////////////////////////////////////////////////// //////////////////////////// Materials /////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// @@ -1596,7 +1595,7 @@ /obj/item/device/instrument/trombone, /obj/item/device/instrument/recorder, /obj/item/device/instrument/harmonica, - /obj/structure/piano) + /obj/structure/piano/unanchored) name = "Big band instrument collection" cost = 5000 crate_name = "Big band musical instruments collection" diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index dbbe6ea512..10d3866672 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -68,3 +68,6 @@ var/datum/chatOutput/chatOutput + var/list/credits //lazy list of all credit object bound to this client + + var/datum/player_details/player_details //these persist between logins/logouts during the same round. diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index d9b25939a5..407e9aa37c 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -152,7 +152,7 @@ GLOBAL_LIST(external_rsc_urls) #if (PRELOAD_RSC == 0) var/static/next_external_rsc = 0 if(external_rsc_urls && external_rsc_urls.len) - next_external_rsc = Wrap(next_external_rsc+1, 1, external_rsc_urls.len+1) + next_external_rsc = WRAP(next_external_rsc+1, 1, external_rsc_urls.len+1) preload_rsc = external_rsc_urls[next_external_rsc] #endif @@ -160,7 +160,7 @@ GLOBAL_LIST(external_rsc_urls) GLOB.directory[ckey] = src GLOB.ahelp_tickets.ClientLogin(src) - + var/connecting_admin = FALSE //because de-admined admins connecting should be treated like admins. //Admin Authorisation var/localhost_addresses = list("127.0.0.1", "::1") if(address && (address in localhost_addresses)) @@ -184,6 +184,11 @@ GLOBAL_LIST(external_rsc_urls) if(holder) GLOB.admins |= src holder.owner = src + connecting_admin = TRUE + + else if(GLOB.deadmins[ckey]) + verbs += /client/proc/readmin + connecting_admin = TRUE //preferences datum - also holds some persistent data for the client (because we may as well keep these datums to a minimum) prefs = GLOB.preferences_datums[ckey] @@ -222,13 +227,20 @@ GLOBAL_LIST(external_rsc_urls) message_admins("Notice: [key_name_admin(src)] has the same [matches] as [key_name_admin(C)] (no longer logged in). ") log_access("Notice: [key_name(src)] has the same [matches] as [key_name(C)] (no longer logged in).") + if(GLOB.player_details[ckey]) + player_details = GLOB.player_details[ckey] + else + player_details = new + GLOB.player_details[ckey] = player_details + + . = ..() //calls mob.Login() chatOutput.start() // Starts the chat if(alert_mob_dupe_login) - set waitfor = FALSE - alert(mob, "You have logged in already with another key this round, please log out of this one NOW or risk being banned!") + spawn() + alert(mob, "You have logged in already with another key this round, please log out of this one NOW or risk being banned!") connection_time = world.time connection_realtime = world.realtime @@ -242,7 +254,7 @@ GLOBAL_LIST(external_rsc_urls) to_chat(src, "Your version: [byond_version]") 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) + if (connecting_admin) 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) @@ -262,7 +274,7 @@ GLOBAL_LIST(external_rsc_urls) 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 (connection == "web" && !connecting_admin) if (!CONFIG_GET(flag/allow_webclient)) to_chat(src, "Web client is disabled") qdel(src) @@ -427,7 +439,7 @@ GLOBAL_LIST(external_rsc_urls) if (src.holder && src.holder.rank) admin_rank = src.holder.rank.name else - if (check_randomizer(connectiontopic)) + if (!GLOB.deadmins[ckey] && check_randomizer(connectiontopic)) return var/sql_ip = sanitizeSQL(address) var/sql_computerid = sanitizeSQL(computer_id) @@ -437,12 +449,12 @@ GLOBAL_LIST(external_rsc_urls) if(!query_client_in_db.Execute()) return if(!query_client_in_db.NextRow()) - if (CONFIG_GET(flag/panic_bunker) && !holder && !(ckey in GLOB.deadmins)) + if (CONFIG_GET(flag/panic_bunker) && !holder && !GLOB.deadmins[ckey]) 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) - var/list/panic_addr = CONFIG_GET(string/panic_address) + var/list/panic_addr = CONFIG_GET(string/panic_server_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].") @@ -663,8 +675,18 @@ GLOBAL_LIST(external_rsc_urls) return FALSE if ("key") return FALSE + if("view") + change_view(var_value) + return TRUE . = ..() +/client/proc/rescale_view(change, min, max) + var/viewscale = getviewsize(view) + var/x = viewscale[1] + var/y = viewscale[2] + x = CLAMP(x+change, min, max) + y = CLAMP(y+change, min,max) + change_view("[x]x[y]") /client/proc/change_view(new_size) if (isnull(new_size)) @@ -683,7 +705,8 @@ GLOBAL_LIST(external_rsc_urls) /client/proc/apply_clickcatcher() generate_clickcatcher() - void.UpdateGreed(view,view) + var/list/actualview = getviewsize(view) + void.UpdateGreed(actualview[1],actualview[2]) /client/proc/AnnouncePR(announcement) if(prefs && prefs.chat_toggles & CHAT_PULLR) diff --git a/code/modules/client/player_details.dm b/code/modules/client/player_details.dm new file mode 100644 index 0000000000..a842607235 --- /dev/null +++ b/code/modules/client/player_details.dm @@ -0,0 +1,2 @@ +/datum/player_details + var/list/player_actions = list() \ No newline at end of file diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 96942af46a..0469f31aba 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -178,6 +178,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/list/exp var/list/menuoptions + var/action_buttons_screen_locs = list() + //citadel code var/arousable = TRUE //Allows players to disable arousal from the character creation menu @@ -1594,12 +1596,12 @@ GLOBAL_LIST_EMPTY(preferences_datums) toggles ^= MIDROUND_ANTAG if("parallaxup") - parallax = Wrap(parallax + 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1) + parallax = WRAP(parallax + 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1) if (parent && parent.mob && parent.mob.hud_used) parent.mob.hud_used.update_parallax_pref(parent.mob) if("parallaxdown") - parallax = Wrap(parallax - 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1) + parallax = WRAP(parallax - 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1) if (parent && parent.mob && parent.mob.hud_used) parent.mob.hud_used.update_parallax_pref(parent.mob) diff --git a/code/modules/client/verbs/suicide.dm b/code/modules/client/verbs/suicide.dm index f4ebeda886..a5f9dfee68 100644 --- a/code/modules/client/verbs/suicide.dm +++ b/code/modules/client/verbs/suicide.dm @@ -119,11 +119,9 @@ death(0) /mob/living/silicon/pai/verb/suicide() - set category = "pAI Commands" - set desc = "Kill yourself and become a ghost (You will receive a confirmation prompt)" - set name = "pAI Suicide" - var/answer = input("REALLY kill yourself? This action can't be undone.", "Suicide", "No") in list ("Yes", "No") - if(answer == "Yes") + set hidden = 1 + var/confirm = alert("Are you sure you want to commit suicide?", "Confirm Suicide", "Yes", "No") + if(confirm == "Yes") var/turf/T = get_turf(src.loc) T.visible_message("[src] flashes a message across its screen, \"Wiping core files. Please acquire a new personality to continue using pAI device functions.\"", null, \ "[src] bleeps electronically.") diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm index ad748f9a84..dd876f3701 100644 --- a/code/modules/clothing/chameleon.dm +++ b/code/modules/clothing/chameleon.dm @@ -203,7 +203,6 @@ item_state = "bl_suit" item_color = "black" desc = "It's a plain jumpsuit. It has a small dial on the wrist." - origin_tech = "syndicate=2" sensor_mode = SENSOR_OFF //Hey who's this guy on the Syndicate Shuttle?? random_sensor = FALSE resistance_flags = NONE @@ -235,7 +234,6 @@ icon_state = "armor" item_state = "armor" blood_overlay_type = "armor" - origin_tech = "syndicate=2" resistance_flags = NONE armor = list(melee = 10, bullet = 10, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 50) @@ -257,7 +255,6 @@ desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting condition." icon_state = "meson" item_state = "meson" - origin_tech = "syndicate=2" resistance_flags = NONE armor = list(melee = 10, bullet = 10, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 50) @@ -392,7 +389,6 @@ desc = "A pair of black shoes." permeability_coefficient = 0.05 flags_1 = NOSLIP_1 - origin_tech = "syndicate=2" resistance_flags = NONE pockets = /obj/item/storage/internal/pocket/shoes armor = list(melee = 10, bullet = 10, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 50) diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm index 1405e633cc..29990a299b 100644 --- a/code/modules/clothing/glasses/_glasses.dm +++ b/code/modules/clothing/glasses/_glasses.dm @@ -54,7 +54,6 @@ desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting conditions." icon_state = "meson" item_state = "meson" - origin_tech = "magnets=1;engineering=2" darkness_view = 2 vision_flags = SEE_TURFS lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE @@ -65,7 +64,6 @@ desc = "An optical meson scanner fitted with an amplified visible light spectrum overlay, providing greater visual clarity in darkness." icon_state = "nvgmeson" item_state = "nvgmeson" - origin_tech = "magnets=4;engineering=5;plasmatech=4" darkness_view = 8 lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE glass_colour_type = /datum/client_colour/glass_colour/green @@ -87,7 +85,6 @@ desc = "A pair of snazzy goggles used to protect against chemical spills. Fitted with an analyzer for scanning items and reagents." icon_state = "purple" item_state = "glasses" - origin_tech = "magnets=2;engineering=1" scan_reagents = 1 //You can see reagents while wearing science goggles actions_types = list(/datum/action/item_action/toggle_research_scanner) glass_colour_type = /datum/client_colour/glass_colour/purple @@ -103,7 +100,6 @@ desc = "You can totally see in the dark now!" icon_state = "night" 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 @@ -126,7 +122,6 @@ desc = "Very confusing glasses." icon_state = "material" item_state = "glasses" - origin_tech = "magnets=3;engineering=3" vision_flags = SEE_OBJS glass_colour_type = /datum/client_colour/glass_colour/lightblue @@ -135,7 +130,6 @@ desc = "Used by miners to detect ores deep within the rock." icon_state = "material" item_state = "glasses" - origin_tech = "magnets=3;engineering=3" darkness_view = 0 /obj/item/clothing/glasses/material/mining/gar @@ -186,7 +180,6 @@ /obj/item/clothing/glasses/sunglasses/reagent name = "beer goggles" desc = "A pair of sunglasses outfitted with apparatus to scan reagents." - origin_tech = "magnets=2;engineering=2" scan_reagents = 1 /obj/item/clothing/glasses/sunglasses/garb @@ -267,7 +260,6 @@ desc = "Thermals in the shape of glasses." icon_state = "thermal" item_state = "glasses" - origin_tech = "magnets=3" vision_flags = SEE_MOBS invis_view = 2 flash_protect = 0 @@ -280,7 +272,6 @@ /obj/item/clothing/glasses/thermal/syndi //These are now a traitor item, concealed as mesons. -Pete name = "chameleon thermals" desc = "A pair of thermal optic goggles with an onboard chameleon generator." - origin_tech = "magnets=3;syndicate=4" flash_protect = -1 var/datum/action/item_action/chameleon/change/chameleon_action diff --git a/code/modules/clothing/glasses/engine_goggles.dm b/code/modules/clothing/glasses/engine_goggles.dm index e3a99fdb9a..78718c897c 100644 --- a/code/modules/clothing/glasses/engine_goggles.dm +++ b/code/modules/clothing/glasses/engine_goggles.dm @@ -8,9 +8,9 @@ /obj/item/clothing/glasses/meson/engine name = "engineering scanner goggles" desc = "Goggles used by engineers. The Meson Scanner mode lets you see basic structural and terrain layouts through walls, the T-ray Scanner mode lets you see underfloor objects such as cables and pipes, and the Radiation Scanner mode let's you see objects contaminated by radiation." - icon_state = "trayson" + icon_state = "trayson-meson" + item_state = "trayson-meson" actions_types = list(/datum/action/item_action/toggle_mode) - origin_tech = "materials=3;magnets=3;engineering=3;plasmatech=3" vision_flags = NONE darkness_view = 2 @@ -117,17 +117,23 @@ flick_overlay(pic, list(user.client), 8) /obj/item/clothing/glasses/meson/engine/update_icon() - icon_state = "[initial(icon_state)]-[mode]" - if(istype(loc, /mob/living/carbon/human/)) - var/mob/living/carbon/human/user = loc - if(user.glasses == src) + icon_state = "trayson-[mode]" + update_mob() + +/obj/item/clothing/glasses/meson/engine/proc/update_mob() + item_state = icon_state + if(isliving(loc)) + var/mob/living/user = loc + if(user.get_item_by_slot(slot_glasses) == src) user.update_inv_glasses() + else + user.update_inv_hands() /obj/item/clothing/glasses/meson/engine/tray //atmos techs have lived far too long without tray goggles while those damned engineers get their dual-purpose gogles all to themselves name = "optical t-ray scanner" + icon_state = "trayson-t-ray" + item_state = "trayson-t-ray" desc = "Used by engineering staff to see underfloor objects such as cables and pipes." - origin_tech = "materials=3;magnets=2;engineering=2" - range = 2 modes = list(MODE_NONE = MODE_TRAY, MODE_TRAY = MODE_NONE) diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index 0fac1eff79..877a3bb458 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -2,7 +2,6 @@ name = "HUD" desc = "A heads-up display that provides important info in (almost) real time." flags_1 = null //doesn't protect eyes because it's a monocle, duh - origin_tech = "magnets=3;biotech=2" var/hud_type = null /obj/item/clothing/glasses/hud/equipped(mob/living/carbon/human/user, slot) @@ -34,7 +33,6 @@ name = "health scanner HUD" desc = "A heads-up display that scans the humans in view and provides accurate data about their health status." icon_state = "healthhud" - origin_tech = "magnets=3;biotech=2" hud_type = DATA_HUD_MEDICAL_ADVANCED glass_colour_type = /datum/client_colour/glass_colour/lightblue @@ -43,7 +41,6 @@ desc = "An advanced medical head-up display that allows doctors to find patients in complete darkness." icon_state = "healthhudnight" item_state = "glasses" - origin_tech = "magnets=4;biotech=4;plasmatech=4;engineering=5" darkness_view = 8 lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE glass_colour_type = /datum/client_colour/glass_colour/green @@ -52,7 +49,6 @@ name = "medical HUDSunglasses" desc = "Sunglasses with a medical HUD." icon_state = "sunhudmed" - origin_tech = "magnets=3;biotech=3;engineering=3" darkness_view = 1 flash_protect = 1 tint = 1 @@ -62,8 +58,7 @@ name = "diagnostic HUD" desc = "A heads-up display capable of analyzing the integrity and status of robotics and exosuits." icon_state = "diagnostichud" - origin_tech = "magnets=2;engineering=2" - hud_type = DATA_HUD_DIAGNOSTIC + hud_type = DATA_HUD_DIAGNOSTIC_BASIC glass_colour_type = /datum/client_colour/glass_colour/lightorange /obj/item/clothing/glasses/hud/diagnostic/night @@ -71,7 +66,6 @@ desc = "A robotics diagnostic HUD fitted with a light amplifier." icon_state = "diagnostichudnight" item_state = "glasses" - origin_tech = "magnets=4;powerstorage=4;plasmatech=4;engineering=5" darkness_view = 8 lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE glass_colour_type = /datum/client_colour/glass_colour/green @@ -80,7 +74,6 @@ name = "security HUD" desc = "A heads-up display that scans the humans in view and provides accurate data about their ID status and security records." icon_state = "securityhud" - origin_tech = "magnets=3;combat=2" hud_type = DATA_HUD_SECURITY_ADVANCED glass_colour_type = /datum/client_colour/glass_colour/red @@ -115,7 +108,6 @@ name = "security HUDSunglasses" desc = "Sunglasses with a security HUD." icon_state = "sunhudsec" - origin_tech = "magnets=3;combat=3;engineering=3" darkness_view = 1 flash_protect = 1 tint = 1 @@ -125,7 +117,6 @@ name = "night vision security HUD" desc = "An advanced heads-up display which provides id data and vision in complete darkness." icon_state = "securityhudnight" - origin_tech = "magnets=4;combat=4;plasmatech=4;engineering=5" darkness_view = 8 lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE glass_colour_type = /datum/client_colour/glass_colour/green diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm index 8b714f25dd..4f108a505f 100644 --- a/code/modules/clothing/gloves/color.dm +++ b/code/modules/clothing/gloves/color.dm @@ -142,7 +142,7 @@ item_color = "cargo" //Exists for washing machines. Is not different from brown gloves in any way. /obj/item/clothing/gloves/color/captain - desc = "Regal blue gloves, with a nice gold trim. Swanky." + desc = "Regal blue gloves, with a nice gold trim, a diamond anti-shock coating, and an integrated thermal barrier. Swanky." name = "captain's gloves" icon_state = "captain" item_state = "egloves" @@ -188,7 +188,7 @@ /obj/item/clothing/gloves/color/random name = "random gloves" desc = "These gloves are supposed to be a random color..." - icon_state = "white" + icon_state = "random_gloves" item_state = "wgloves" item_color = "mime" diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 5691dbb782..15d4579d33 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -283,7 +283,7 @@ for(var/obj/item/device/flashlight/seclite/S in src) to_chat(user, "You unscrew the seclite from [src].") F = null - S.loc = get_turf(user) + S.forceMove(user.drop_location()) update_helmlight(user) S.update_brightness(user) update_icon() diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index 7d15afc4e3..e7894a586c 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -21,7 +21,6 @@ flash_protect = 2 tint = 2 armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 55) - origin_tech = "materials=2;engineering=3" actions_types = list(/datum/action/item_action/toggle) flags_inv = HIDEEARS|HIDEEYES|HIDEFACE flags_cover = MASKCOVERSEYES diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm index 2b66a85fe6..2baaf91135 100644 --- a/code/modules/clothing/neck/_neck.dm +++ b/code/modules/clothing/neck/_neck.dm @@ -72,6 +72,9 @@ if(!(M.failed_last_breath || M.losebreath)) lung_strength = "healthy" + if(M.stat == DEAD && heart && world.time - M.timeofdeath < DEFIB_TIME_LIMIT * 10) + heart_strength = "a faint, fluttery" + var/diagnosis = (body_part == "chest" ? "You hear [heart_strength] pulse and [lung_strength] respiration." : "You faintly hear [heart_strength] pulse.") user.visible_message("[user] places [src] against [M]'s [body_part] and listens attentively.", "You place [src] against [M]'s [body_part]. [diagnosis]") return diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm index 27b5462b56..e669ce3826 100644 --- a/code/modules/clothing/shoes/magboots.dm +++ b/code/modules/clothing/shoes/magboots.dm @@ -10,7 +10,6 @@ strip_delay = 70 equip_delay_other = 70 resistance_flags = FIRE_PROOF - origin_tech = "materials=3;magnets=4;engineering=4" /obj/item/clothing/shoes/magboots/verb/toggle() set name = "Toggle Magboots" @@ -51,7 +50,6 @@ icon_state = "advmag0" magboot_state = "advmag" slowdown_active = SHOES_SLOWDOWN - origin_tech = null resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF /obj/item/clothing/shoes/magboots/syndie @@ -59,4 +57,3 @@ name = "blood-red magboots" icon_state = "syndiemag0" magboot_state = "syndiemag" - origin_tech = "magnets=4;syndicate=2" diff --git a/code/modules/clothing/shoes/vg_shoes.dm b/code/modules/clothing/shoes/vg_shoes.dm index 7b42dba6fc..fb2510be89 100644 --- a/code/modules/clothing/shoes/vg_shoes.dm +++ b/code/modules/clothing/shoes/vg_shoes.dm @@ -14,7 +14,6 @@ magboot_state = "DS-magboots" icon = 'icons/obj/clothing/vg_clothes.dmi' icon_override = 'icons/mob/citadel/head.dmi' - origin_tech = null resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF /obj/item/clothing/shoes/magboots/atmos diff --git a/code/modules/clothing/spacesuits/chronosuit.dm b/code/modules/clothing/spacesuits/chronosuit.dm index a2b5a864c4..2b25188b80 100644 --- a/code/modules/clothing/spacesuits/chronosuit.dm +++ b/code/modules/clothing/spacesuits/chronosuit.dm @@ -98,7 +98,7 @@ I.flags_1 &= ~NODROP_1 if(camera) camera.remove_target_ui() - camera.loc = user + camera.forceMove(user) teleport_now.UpdateButtonIcon() /obj/item/clothing/suit/space/chronos/proc/chronowalk(atom/location) @@ -271,29 +271,29 @@ target_ui = null /obj/effect/chronos_cam/relaymove(var/mob/user, direction) - if(holder) - if(user == holder) - if(loc == user) - loc = get_turf(user) - if(user.client && user.client.eye != src) - src.loc = get_turf(user) - user.reset_perspective(src) - user.set_machine(src) - var/atom/step = get_step(src, direction) - if(step) - if((step.x <= TRANSITIONEDGE) || (step.x >= (world.maxx - TRANSITIONEDGE - 1)) || (step.y <= TRANSITIONEDGE) || (step.y >= (world.maxy - TRANSITIONEDGE - 1))) - if(!src.Move(step)) - src.loc = step - else - src.loc = step - if((x == holder.x) && (y == holder.y) && (z == holder.z)) - remove_target_ui() - loc = user - else if(!target_ui) - create_target_ui() - phase_time = world.time + phase_time_length - else + if(!holder) qdel(src) + return + if(user == holder) + if(loc == user) + forceMove(get_turf(user)) + if(user.client && user.client.eye != src) + src.forceMove(user.drop_location()) + user.reset_perspective(src) + user.set_machine(src) + var/atom/step = get_step(src, direction) + if(step) + if((step.x <= TRANSITIONEDGE) || (step.x >= (world.maxx - TRANSITIONEDGE - 1)) || (step.y <= TRANSITIONEDGE) || (step.y >= (world.maxy - TRANSITIONEDGE - 1))) + if(!src.Move(step)) + src.forceMove(step) + else + src.forceMove(step) + if((x == holder.x) && (y == holder.y) && (z == holder.z)) + remove_target_ui() + forceMove(user) + else if(!target_ui) + create_target_ui() + phase_time = world.time + phase_time_length /obj/effect/chronos_cam/check_eye(mob/user) if(user != holder) diff --git a/code/modules/clothing/spacesuits/flightsuit.dm b/code/modules/clothing/spacesuits/flightsuit.dm index 30afa31f60..681ba3e789 100644 --- a/code/modules/clothing/spacesuits/flightsuit.dm +++ b/code/modules/clothing/spacesuits/flightsuit.dm @@ -164,7 +164,7 @@ assembled = TRUE boost_chargerate *= cap boost_drain -= manip - powersetting_high = Clamp(laser, 0, 3) + powersetting_high = CLAMP(laser, 0, 3) emp_disable_threshold = bin*1.25 stabilizer_decay_amount = scan*3.5 airbrake_decay_amount = manip*8 @@ -194,15 +194,15 @@ /obj/item/device/flightpack/proc/adjust_momentum(amountx, amounty, reduce_amount_total = 0) if(reduce_amount_total != 0) if(momentum_x > 0) - momentum_x = Clamp(momentum_x - reduce_amount_total, 0, momentum_max) + momentum_x = CLAMP(momentum_x - reduce_amount_total, 0, momentum_max) else if(momentum_x < 0) - momentum_x = Clamp(momentum_x + reduce_amount_total, -momentum_max, 0) + momentum_x = CLAMP(momentum_x + reduce_amount_total, -momentum_max, 0) if(momentum_y > 0) - momentum_y = Clamp(momentum_y - reduce_amount_total, 0, momentum_max) + momentum_y = CLAMP(momentum_y - reduce_amount_total, 0, momentum_max) else if(momentum_y < 0) - momentum_y = Clamp(momentum_y + reduce_amount_total, -momentum_max, 0) - momentum_x = Clamp(momentum_x + amountx, -momentum_max, momentum_max) - momentum_y = Clamp(momentum_y + amounty, -momentum_max, momentum_max) + momentum_y = CLAMP(momentum_y + reduce_amount_total, -momentum_max, 0) + momentum_x = CLAMP(momentum_x + amountx, -momentum_max, momentum_max) + momentum_y = CLAMP(momentum_y + amounty, -momentum_max, momentum_max) calculate_momentum_speed() /obj/item/device/flightpack/intercept_user_move(dir, mob, newLoc, oldLoc) @@ -314,7 +314,7 @@ /obj/item/device/flightpack/proc/handle_damage() if(emp_damage) - emp_damage = Clamp(emp_damage-emp_heal_amount, 0, emp_disable_threshold * 10) + emp_damage = CLAMP(emp_damage-emp_heal_amount, 0, emp_disable_threshold * 10) if(emp_damage >= emp_disable_threshold) emp_disabled = TRUE if(emp_disabled && (emp_damage <= 0.5)) @@ -347,11 +347,11 @@ /obj/item/device/flightpack/proc/handle_boost() if(boost) - boost_charge = Clamp(boost_charge-boost_drain, 0, boost_maxcharge) + boost_charge = CLAMP(boost_charge-boost_drain, 0, boost_maxcharge) if(boost_charge < 1) deactivate_booster() if(boost_charge < boost_maxcharge) - boost_charge = Clamp(boost_charge+boost_chargerate, 0, boost_maxcharge) + boost_charge = CLAMP(boost_charge+boost_chargerate, 0, boost_maxcharge) /obj/item/device/flightpack/proc/cycle_power() powersetting < powersetting_high? (powersetting++) : (powersetting = 1) @@ -856,21 +856,22 @@ return TRUE /obj/item/clothing/suit/space/hardsuit/flightsuit/proc/unlock_suit(mob/wearer) - if(suittoggled) - usermessage("You must retract the helmet before unlocking your suit!", "boldwarning") - return FALSE - if(pack && pack.flight) - usermessage("You must shut off the flight-pack before unlocking your suit!", "boldwarning") - return FALSE - if(deployedpack) - usermessage("Your flightpack must be fully retracted first!", "boldwarning") - return FALSE - if(deployedshoes) - usermessage("Your flight shoes must be fully retracted first!", "boldwarning") - return FALSE - if(wearer) - user.visible_message("[wearer]'s flight suit detaches from their body, becoming nothing more then a bulky metal skeleton.") - playsound(src.loc, 'sound/items/rped.ogg', 65, 1) + if(user) + if(suittoggled) + usermessage("You must retract the helmet before unlocking your suit!", "boldwarning") + return FALSE + if(pack && pack.flight) + usermessage("You must shut off the flight-pack before unlocking your suit!", "boldwarning") + return FALSE + if(deployedpack) + usermessage("Your flightpack must be fully retracted first!", "boldwarning") + return FALSE + if(deployedshoes) + usermessage("Your flight shoes must be fully retracted first!", "boldwarning") + return FALSE + if(wearer) + user.visible_message("[wearer]'s flight suit detaches from their body, becoming nothing more then a bulky metal skeleton.") + playsound(src, 'sound/items/rped.ogg', 65, 1) resync() strip_delay = initial(strip_delay) locked = FALSE @@ -911,7 +912,7 @@ user.update_inv_wear_suit() user.visible_message("[user]'s [pack.name] detaches from their back and retracts into their [src]!") pack.forceMove(src) - playsound(src.loc, 'sound/mecha/mechmove03.ogg', 50, 1) + playsound(src, 'sound/mecha/mechmove03.ogg', 50, 1) deployedpack = FALSE /obj/item/clothing/suit/space/hardsuit/flightsuit/proc/extend_flightshoes(forced = FALSE) @@ -936,7 +937,7 @@ /obj/item/clothing/suit/space/hardsuit/flightsuit/proc/retract_flightshoes(forced = FALSE) shoes.flags_1 &= ~NODROP_1 - playsound(src.loc, 'sound/mecha/mechmove03.ogg', 50, 1) + playsound(src, 'sound/mecha/mechmove03.ogg', 50, 1) if(user) user.transferItemToLoc(shoes, src, TRUE) user.update_inv_wear_suit() @@ -1079,7 +1080,7 @@ light_color = "#30ffff" armor = list(melee = 20, bullet = 20, laser = 20, energy = 10, bomb = 30, bio = 100, rad = 75, fire = 100, acid = 100) max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT - var/list/datahuds = list(DATA_HUD_SECURITY_ADVANCED, DATA_HUD_MEDICAL_ADVANCED, DATA_HUD_DIAGNOSTIC) + var/list/datahuds = list(DATA_HUD_SECURITY_ADVANCED, DATA_HUD_MEDICAL_ADVANCED, DATA_HUD_DIAGNOSTIC_BASIC) var/zoom_range = 12 var/zoom = FALSE actions_types = list(/datum/action/item_action/toggle_helmet_light, /datum/action/item_action/flightpack/zoom) @@ -1092,15 +1093,16 @@ /obj/item/clothing/head/helmet/space/hardsuit/flightsuit/dropped(mob/living/carbon/human/wearer) ..() - for(var/hudtype in datahuds) - var/datum/atom_hud/H = GLOB.huds[hudtype] - H.remove_hud_from(wearer) - if(zoom) - toggle_zoom(wearer, TRUE) + if(wearer) + for(var/hudtype in datahuds) + var/datum/atom_hud/H = GLOB.huds[hudtype] + H.remove_hud_from(wearer) + if(zoom) + toggle_zoom(wearer, TRUE) /obj/item/clothing/head/helmet/space/hardsuit/flightsuit/proc/toggle_zoom(mob/living/user, force_off = FALSE) if(zoom || force_off) - user.client.change_view(world.view) + user.client.change_view(CONFIG_GET(string/default_view)) to_chat(user, "Disabling smart zooming image enhancement...") zoom = FALSE return FALSE diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index c371973506..58eac96f78 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -136,7 +136,7 @@ return jetpack.turn_off() - jetpack.loc = get_turf(src) + jetpack.forceMove(drop_location()) jetpack = null to_chat(user, "You successfully remove the jetpack from [src].") @@ -186,7 +186,7 @@ icon_state = "hardsuit0-atmospherics" item_state = "atmo_helm" item_color = "atmospherics" - armor = list(melee = 30, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 0, fire = 100, acid = 75) + armor = list(melee = 30, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 25, fire = 100, acid = 75) heat_protection = HEAD //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT @@ -195,7 +195,7 @@ desc = "A special suit that protects against hazardous, low pressure environments. Has thermal shielding." icon_state = "hardsuit-atmospherics" item_state = "atmo_hardsuit" - armor = list(melee = 30, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 0, fire = 100, acid = 75) + armor = list(melee = 30, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 25, fire = 100, acid = 75) heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine/atmos @@ -425,7 +425,7 @@ item_state = "medical_helm" item_color = "medical" flash_protect = 0 - armor = list(melee = 30, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 75, fire = 75, acid = 75) + armor = list(melee = 30, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 60, fire = 60, acid = 75) scan_reagents = 1 /obj/item/clothing/suit/space/hardsuit/medical @@ -434,7 +434,7 @@ desc = "A special suit that protects against hazardous, low pressure environments. Built with lightweight materials for easier movement." item_state = "medical_hardsuit" allowed = list(/obj/item/device/flashlight, /obj/item/tank/internals, /obj/item/storage/firstaid, /obj/item/device/healthanalyzer, /obj/item/stack/medical) - armor = list(melee = 30, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 75, fire = 75, acid = 75) + armor = list(melee = 30, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 60, fire = 60, acid = 75) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/medical //Research Director hardsuit @@ -457,13 +457,13 @@ /obj/item/clothing/head/helmet/space/hardsuit/rd/equipped(mob/living/carbon/human/user, slot) ..() if (slot == slot_head) - var/datum/atom_hud/DHUD = GLOB.huds[DATA_HUD_DIAGNOSTIC] + var/datum/atom_hud/DHUD = GLOB.huds[DATA_HUD_DIAGNOSTIC_BASIC] DHUD.add_hud_to(user) /obj/item/clothing/head/helmet/space/hardsuit/rd/dropped(mob/living/carbon/human/user) ..() if (user.head == src) - var/datum/atom_hud/DHUD = GLOB.huds[DATA_HUD_DIAGNOSTIC] + var/datum/atom_hud/DHUD = GLOB.huds[DATA_HUD_DIAGNOSTIC_BASIC] DHUD.remove_hud_from(user) /obj/item/clothing/suit/space/hardsuit/rd @@ -487,7 +487,7 @@ icon_state = "hardsuit0-sec" item_state = "sec_helm" item_color = "sec" - armor = list(melee = 30, bullet = 15, laser = 30,energy = 10, bomb = 10, bio = 100, rad = 50, fire = 75, acid = 75) + armor = list(melee = 35, bullet = 15, laser = 30,energy = 10, bomb = 10, bio = 100, rad = 50, fire = 75, acid = 75) /obj/item/clothing/suit/space/hardsuit/security @@ -495,7 +495,7 @@ name = "security hardsuit" desc = "A special suit that protects against hazardous, low pressure environments. Has an additional layer of armor." item_state = "sec_hardsuit" - armor = list(melee = 30, bullet = 15, laser = 30, energy = 10, bomb = 10, bio = 100, rad = 50, fire = 75, acid = 75) + armor = list(melee = 35, bullet = 15, laser = 30, energy = 10, bomb = 10, bio = 100, rad = 50, fire = 75, acid = 75) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/security /obj/item/clothing/suit/space/hardsuit/security/Initialize() @@ -508,7 +508,7 @@ desc = "A special bulky helmet designed for work in a hazardous, low pressure environment. Has an additional layer of armor." icon_state = "hardsuit0-hos" item_color = "hos" - armor = list(melee = 45, bullet = 25, laser = 30,energy = 10, bomb = 25, bio = 100, rad = 50, fire = 95, acid = 95) + armor = list(melee = 45, bullet = 25, laser = 30, energy = 10, bomb = 25, bio = 100, rad = 50, fire = 95, acid = 95) /obj/item/clothing/suit/space/hardsuit/security/hos @@ -654,7 +654,7 @@ /obj/item/clothing/suit/space/hardsuit/shielded/process() if(world.time > recharge_cooldown && current_charges < max_charges) - current_charges = Clamp((current_charges + recharge_rate), 0, max_charges) + current_charges = CLAMP((current_charges + recharge_rate), 0, max_charges) playsound(loc, 'sound/magic/charge.ogg', 50, 1) if(current_charges == max_charges) playsound(loc, 'sound/machines/ding.ogg', 50, 1) diff --git a/code/modules/clothing/under/accessories.dm b/code/modules/clothing/under/accessories.dm index f983ca2563..49364e76d9 100644 --- a/code/modules/clothing/under/accessories.dm +++ b/code/modules/clothing/under/accessories.dm @@ -15,11 +15,11 @@ if(U.pockets) // storage items conflict return FALSE - pockets.loc = U + pockets.forceMove(U) U.pockets = pockets U.attached_accessory = src - loc = U + forceMove(U) layer = FLOAT_LAYER plane = FLOAT_PLANE if(minimize_when_attached) @@ -39,7 +39,7 @@ /obj/item/clothing/accessory/proc/detach(obj/item/clothing/under/U, user) if(pockets && pockets == U.pockets) - pockets.loc = src + pockets.forceMove(src) U.pockets = null for(var/armor_type in armor) @@ -135,7 +135,7 @@ "You pin \the [src] on [M]'s chest.") if(input) SSblackbox.record_feedback("associative", "commendation", 1, list("commender" = "[user.real_name]", "commendee" = "[M.real_name]", "medal" = "[src]", "reason" = input)) - GLOB.commendations += "[user.real_name] awarded [M.real_name] the [name]! \n- [input]" + GLOB.commendations += "[user.real_name] awarded [M.real_name] the [name]! \n- [input]" commended = TRUE log_game("[key_name(M)] was given the following commendation by [key_name(user)]: [input]") message_admins("[key_name(M)] was given the following commendation by [key_name(user)]: [input]") diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 2a73a40d72..899219c227 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -662,7 +662,6 @@ name = "envirosuit extinguisher cartridge" desc = "A cartridge loaded with a compressed extinguisher mix, used to refill the automatic extinguisher on plasma envirosuits." icon_state = "plasmarefill" - origin_tech = "materials=2;plasmatech=3;biotech=1" /obj/item/clothing/under/rank/security/navyblue/russian name = "russian officer's uniform" diff --git a/code/modules/crafting/craft.dm b/code/modules/crafting/craft.dm index 3e4e93ca4c..85ae7c3b18 100644 --- a/code/modules/crafting/craft.dm +++ b/code/modules/crafting/craft.dm @@ -98,7 +98,7 @@ else if(istype(I, /obj/item/reagent_containers)) var/obj/item/reagent_containers/RC = I - if(RC.container_type & OPENCONTAINER_1) + if(RC.is_drainable()) for(var/datum/reagent/A in RC.reagents.reagent_list) .[A.type] += A.volume .[I.type] += 1 diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm index 0378d44809..7ad03c6e9d 100644 --- a/code/modules/crafting/recipes.dm +++ b/code/modules/crafting/recipes.dm @@ -357,7 +357,7 @@ /datum/crafting_recipe/skateboard name = "Skateboard" - result = /obj/vehicle/scooter/skateboard + result = /obj/vehicle/ridden/scooter/skateboard time = 60 reqs = list(/obj/item/stack/sheet/metal = 5, /obj/item/stack/rods = 10) @@ -365,7 +365,7 @@ /datum/crafting_recipe/scooter name = "Scooter" - result = /obj/vehicle/scooter + result = /obj/vehicle/ridden/scooter time = 65 reqs = list(/obj/item/stack/sheet/metal = 5, /obj/item/stack/rods = 12) diff --git a/code/modules/detectivework/footprints_and_rag.dm b/code/modules/detectivework/footprints_and_rag.dm index 9415bef33d..793805977c 100644 --- a/code/modules/detectivework/footprints_and_rag.dm +++ b/code/modules/detectivework/footprints_and_rag.dm @@ -13,7 +13,7 @@ icon = 'icons/obj/toy.dmi' icon_state = "rag" flags_1 = NOBLUDGEON_1 - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER amount_per_transfer_from_this = 5 possible_transfer_amounts = list() volume = 5 diff --git a/code/modules/detectivework/scanner.dm b/code/modules/detectivework/scanner.dm index e94c40a0c7..8cb27ea4f3 100644 --- a/code/modules/detectivework/scanner.dm +++ b/code/modules/detectivework/scanner.dm @@ -14,7 +14,6 @@ slot_flags = SLOT_BELT var/scanning = 0 var/list/log = list() - origin_tech = "engineering=4;biotech=2;programming=5" var/range = 8 var/view_check = TRUE diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index a5b23623f2..471dad12d7 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_GET(number/events_min_time_mul)) - min_players = Ceiling(min_players * CONFIG_GET(number/events_min_players_mul)) + earliest_start = CEILING(earliest_start * CONFIG_GET(number/events_min_time_mul), 1) + min_players = CEILING(min_players * CONFIG_GET(number/events_min_players_mul), 1) /datum/round_event_control/wizard wizardevent = 1 diff --git a/code/modules/events/brand_intelligence.dm b/code/modules/events/brand_intelligence.dm index e898729f2d..c2f98be8d5 100644 --- a/code/modules/events/brand_intelligence.dm +++ b/code/modules/events/brand_intelligence.dm @@ -67,12 +67,12 @@ kill() return - if(IsMultiple(activeFor, 4)) + if(ISMULTIPLE(activeFor, 4)) var/obj/machinery/vending/rebel = pick(vendingMachines) vendingMachines.Remove(rebel) infectedMachines.Add(rebel) rebel.shut_up = 0 rebel.shoot_inventory = 1 - if(IsMultiple(activeFor, 8)) + if(ISMULTIPLE(activeFor, 8)) originMachine.speak(pick(rampant_speeches)) \ No newline at end of file diff --git a/code/modules/events/camerafailure.dm b/code/modules/events/camerafailure.dm index 9f85628629..cbc2d95776 100644 --- a/code/modules/events/camerafailure.dm +++ b/code/modules/events/camerafailure.dm @@ -6,11 +6,9 @@ alertadmins = 0 /datum/round_event/camera_failure - startWhen = 1 - endWhen = 2 fakeable = FALSE -/datum/round_event/camera_failure/tick() +/datum/round_event/camera_failure/start() var/iterations = 1 var/obj/machinery/camera/C = pick(GLOB.cameranet.cameras) while(prob(round(100/iterations))) diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index eb7625e08c..d83c966ff6 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -10,22 +10,30 @@ var/virus_type + var/max_severity = 3 -/datum/round_event/disease_outbreak/announce(fake) + +/datum/round_event/disease_outbreak/announce() priority_announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak7.ogg') /datum/round_event/disease_outbreak/setup() announceWhen = rand(15, 30) + /datum/round_event/disease_outbreak/start() - if(!virus_type) + var/advanced_virus = FALSE + max_severity = 3 + max(FLOOR((world.time - control.earliest_start)/6000, 1),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes + if(prob(20 + (10 * max_severity))) + advanced_virus = TRUE + + if(!virus_type && !advanced_virus) virus_type = pick(/datum/disease/dnaspread, /datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis) for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list)) var/turf/T = get_turf(H) if(!T) continue - if(!(T.z in GLOB.station_z_levels)) + if(T.z != ZLEVEL_STATION_PRIMARY) continue if(!H.client) continue @@ -41,16 +49,48 @@ continue var/datum/disease/D - if(virus_type == /datum/disease/dnaspread) //Dnaspread needs strain_data set to work. - if(!H.dna || (H.disabilities & BLIND)) //A blindness disease would be the worst. - continue - D = new virus_type() - var/datum/disease/dnaspread/DS = D - DS.strain_data["name"] = H.real_name - DS.strain_data["UI"] = H.dna.uni_identity - DS.strain_data["SE"] = H.dna.struc_enzymes + if(!advanced_virus) + if(virus_type == /datum/disease/dnaspread) //Dnaspread needs strain_data set to work. + if(!H.dna || (H.disabilities & BLIND)) //A blindness disease would be the worst. + continue + D = new virus_type() + var/datum/disease/dnaspread/DS = D + DS.strain_data["name"] = H.real_name + DS.strain_data["UI"] = H.dna.uni_identity + DS.strain_data["SE"] = H.dna.struc_enzymes + else + D = new virus_type() else - D = new virus_type() + D = make_virus(max_severity, max_severity) D.carrier = TRUE H.AddDisease(D) - break \ No newline at end of file + + if(advanced_virus) + var/datum/disease/advance/A = D + var/list/name_symptoms = list() //for feedback + for(var/datum/symptom/S in A.symptoms) + name_symptoms += S.name + message_admins("An event has triggered a random advanced virus outbreak on [key_name_admin(H)]! It has these symptoms: [english_list(name_symptoms)]") + log_game("An event has triggered a random advanced virus outbreak on [key_name(H)]! It has these symptoms: [english_list(name_symptoms)]") + break + +/datum/round_event/disease_outbreak/proc/make_virus(max_symptoms, max_level) + if(max_symptoms > SYMPTOM_LIMIT) + max_symptoms = SYMPTOM_LIMIT + var/datum/disease/advance/A = new(FALSE, null) + A.symptoms = list() + var/list/datum/symptom/possible_symptoms = list() + for(var/symptom in subtypesof(/datum/symptom)) + var/datum/symptom/S = symptom + if(initial(S.level) > max_level) + continue + if(initial(S.level) <= 0) //unobtainable symptoms + continue + possible_symptoms += S + for(var/i in 1 to max_symptoms) + var/datum/symptom/chosen_symptom = pick_n_take(possible_symptoms) + if(chosen_symptom) + var/datum/symptom/S = new chosen_symptom + A.symptoms += S + A.Refresh() //just in case someone already made and named the same disease + return A diff --git a/code/modules/events/holiday/vday.dm b/code/modules/events/holiday/vday.dm index 41ff90407d..abb5a0639d 100644 --- a/code/modules/events/holiday/vday.dm +++ b/code/modules/events/holiday/vday.dm @@ -45,19 +45,26 @@ to_chat(L, "You didn't get a date! They're all having fun without you! you'll show them though...") var/datum/objective/martyr/normiesgetout = new normiesgetout.owner = L.mind + L.mind.special_role = "heartbreaker" SSticker.mode.traitors |= L.mind L.mind.objectives += normiesgetout + L.mind.add_antag_datum(/datum/antagonist/auto_custom) + /proc/forge_valentines_objective(mob/living/lover,mob/living/date) SSticker.mode.traitors |= lover.mind lover.mind.special_role = "valentine" + var/datum/objective/protect/protect_objective = new /datum/objective/protect protect_objective.owner = lover.mind protect_objective.target = date.mind protect_objective.explanation_text = "Protect [date.real_name], your date." lover.mind.objectives += protect_objective + + lover.mind.add_antag_datum(/datum/antagonist/auto_custom) + to_chat(lover, "You're on a date with [date]! Protect them at all costs. This takes priority over all other loyalties.") diff --git a/code/modules/events/immovable_rod.dm b/code/modules/events/immovable_rod.dm index b933e566be..9612fd8018 100644 --- a/code/modules/events/immovable_rod.dm +++ b/code/modules/events/immovable_rod.dm @@ -12,6 +12,16 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 typepath = /datum/round_event/immovable_rod min_players = 15 max_occurrences = 5 + var/atom/special_target + + +/datum/round_event_control/immovable_rod/admin_setup() + if(!check_rights(R_FUN)) + return + + var/aimed = alert("Aimed at current location?","Sniperod", "Yes", "No") + if(aimed == "Yes") + special_target = get_turf(usr) /datum/round_event/immovable_rod announceWhen = 5 @@ -20,10 +30,11 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 priority_announce("What the fuck was that?!", "General Alert") /datum/round_event/immovable_rod/start() + var/datum/round_event_control/immovable_rod/C = control var/startside = pick(GLOB.cardinals) var/turf/startT = spaceDebrisStartLoc(startside, ZLEVEL_STATION_PRIMARY) var/turf/endT = spaceDebrisFinishLoc(startside, ZLEVEL_STATION_PRIMARY) - new /obj/effect/immovablerod(startT, endT) + new /obj/effect/immovablerod(startT, endT, C.special_target) /obj/effect/immovablerod name = "immovable rod" @@ -36,18 +47,28 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 var/z_original = 0 var/destination var/notify = TRUE + var/atom/special_target -/obj/effect/immovablerod/New(atom/start, atom/end) +/obj/effect/immovablerod/New(atom/start, atom/end, aimed_at) ..() SSaugury.register_doom(src, 2000) z_original = z destination = end + special_target = aimed_at if(notify) notify_ghosts("\A [src] is inbound!", enter_link="(Click to orbit)", source=src, action=NOTIFY_ORBIT) GLOB.poi_list += src - if(end && end.z==z_original) + + var/special_target_valid = FALSE + if(special_target) + var/turf/T = get_turf(special_target) + if(T.z == z_original) + special_target_valid = TRUE + if(special_target_valid) + walk_towards(src, special_target, 1) + else if(end && end.z==z_original) walk_towards(src, destination, 1) /obj/effect/immovablerod/Topic(href, href_list) @@ -60,11 +81,20 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 GLOB.poi_list -= src . = ..() -/obj/effect/immovablerod/Move() +/obj/effect/immovablerod/Moved() if((z != z_original) || (loc == destination)) qdel(src) + if(special_target && loc == get_turf(special_target)) + complete_trajectory() return ..() +/obj/effect/immovablerod/proc/complete_trajectory() + //We hit what we wanted to hit, time to go + special_target = null + destination = get_edge_target_turf(src, dir) + walk(src,0) + walk_towards(src, destination, 1) + /obj/effect/immovablerod/ex_act(severity, target) return 0 @@ -83,6 +113,9 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 x = clong.x y = clong.y + if(special_target && clong == special_target) + complete_trajectory() + if(isturf(clong) || isobj(clong)) if(clong.density) clong.ex_act(EXPLODE_HEAVY) diff --git a/code/modules/events/meteor_wave.dm b/code/modules/events/meteor_wave.dm index 35eb02f082..798bcf82dd 100644 --- a/code/modules/events/meteor_wave.dm +++ b/code/modules/events/meteor_wave.dm @@ -49,7 +49,7 @@ priority_announce("Meteors have been detected on collision course with the station.", "Meteor Alert", 'sound/ai/meteors.ogg') /datum/round_event/meteor_wave/tick() - if(IsMultiple(activeFor, 3)) + if(ISMULTIPLE(activeFor, 3)) spawn_meteors(5, wave_type) //meteor list types defined in gamemode/meteor/meteors.dm /datum/round_event_control/meteor_wave/threatening diff --git a/code/modules/events/nightmare.dm b/code/modules/events/nightmare.dm index 073ef8aea3..76188cb5b7 100644 --- a/code/modules/events/nightmare.dm +++ b/code/modules/events/nightmare.dm @@ -35,6 +35,7 @@ player_mind.assigned_role = "Nightmare" player_mind.special_role = "Nightmare" SSticker.mode.traitors += player_mind + player_mind.add_antag_datum(/datum/antagonist/auto_custom) S.set_species(/datum/species/shadow/nightmare) playsound(S, 'sound/magic/ethereal_exit.ogg', 50, 1, -1) message_admins("[key_name_admin(S)] has been made into a Nightmare by an event.") diff --git a/code/modules/events/operative.dm b/code/modules/events/operative.dm index 47130ff924..894ad7e995 100644 --- a/code/modules/events/operative.dm +++ b/code/modules/events/operative.dm @@ -27,31 +27,13 @@ A.copy_to(operative) operative.dna.update_dna_identity() - operative.equipOutfit(/datum/outfit/syndicate/full) - var/datum/mind/Mind = new /datum/mind(selected.key) Mind.assigned_role = "Lone Operative" Mind.special_role = "Lone Operative" - SSticker.mode.traitors |= Mind Mind.active = 1 - var/obj/machinery/nuclearbomb/selfdestruct/nuke = locate() in GLOB.machines - if(nuke) - var/nuke_code - if(!nuke.r_code || nuke.r_code == "ADMIN") - nuke_code = random_nukecode() - nuke.r_code = nuke_code - else - nuke_code = nuke.r_code - - Mind.store_memory("Station Self-Destruct Device Code: [nuke_code]", 0, 0) - to_chat(Mind.current, "The nuclear authorization code is: [nuke_code]") - - var/datum/objective/nuclear/O = new() - O.owner = Mind - Mind.objectives += O - Mind.transfer_to(operative) + Mind.add_antag_datum(/datum/antagonist/nukeop/lone) message_admins("[key_name_admin(operative)] has been made into lone operative by an event.") log_game("[key_name(operative)] was spawned as a lone operative by an event.") diff --git a/code/modules/events/pirates.dm b/code/modules/events/pirates.dm index e1e605526d..dd7d10f896 100644 --- a/code/modules/events/pirates.dm +++ b/code/modules/events/pirates.dm @@ -22,7 +22,7 @@ /datum/round_event/pirates/announce() priority_announce("Incoming subspace communication. Secure channel opened at all communication consoles.", "Incoming Message", 'sound/ai/commandreport.ogg') - + if(!control) //Means this is false alarm, todo : explicit checks instead of using announceWhen return threat = new @@ -45,7 +45,7 @@ if(!shuttle_spawned) spawn_shuttle() - + /datum/round_event/pirates/start() if(!paid_off && !shuttle_spawned) @@ -64,7 +64,7 @@ var/turf/T = locate(x,y,z) if(!T) CRASH("Pirate event found no turf to load in") - + if(!ship.load(T)) CRASH("Loading pirate ship failed!") for(var/turf/A in ship.get_affected_turfs(T)) @@ -75,7 +75,7 @@ candidates -= M else notify_ghosts("Space pirates are waking up!", source = spawner, action=NOTIFY_ATTACK, flashwindow = FALSE) - + priority_announce("Unidentified armed ship detected near the station.") //Shuttle equipment @@ -104,7 +104,7 @@ var/siphoned = min(SSshuttle.points,siphon_per_tick) SSshuttle.points -= siphoned credits_stored += siphoned - steal_tech() + interrupt_research() else return else @@ -130,23 +130,12 @@ else dump_loot(user) -//20% to sap tech levels on unlocked consoles -/obj/machinery/shuttle_scrambler/proc/steal_tech() - if(!prob(20)) - return - var/datum/tech/target_tech = pick(subtypesof(/datum/tech)) - var/target_id = initial(target_tech.id) - for(var/obj/machinery/computer/rdconsole/C in GLOB.machines) - if(C.screen == RD_CONSOLE_LOCKED_SCREEN || C.stat & (NOPOWER|BROKEN)) - continue - var/datum/research/files = C.files - files.LowerTech(target_id,1) - new /obj/effect/temp_visual/emp(get_turf(C)) - for(var/obj/machinery/r_n_d/server/S in GLOB.machines) +//interrupt_research +/obj/machinery/shuttle_scrambler/proc/interrupt_research() + for(var/obj/machinery/rnd/server/S in GLOB.machines) if(S.stat & (NOPOWER|BROKEN)) continue - var/datum/research/files = S.files - files.LowerTech(target_id,1) + S.emp_act(1) new /obj/effect/temp_visual/emp(get_turf(S)) /obj/machinery/shuttle_scrambler/proc/dump_loot(mob/user) @@ -157,7 +146,7 @@ new /obj/item/stack/spacecash/c200(drop_location()) credits_stored -= 200 to_chat(user,"You retrieve the siphoned credits!") - + /obj/machinery/shuttle_scrambler/proc/send_notification() priority_announce("Data theft signal detected, source registered on local gps units.") @@ -204,6 +193,7 @@ shuttlePortName = "custom location" x_offset = 9 y_offset = 0 + see_hidden = FALSE /obj/docking_port/mobile/pirate name = "pirate shuttle" diff --git a/code/modules/events/portal_storm.dm b/code/modules/events/portal_storm.dm index 7e17124d59..55d9e69f71 100644 --- a/code/modules/events/portal_storm.dm +++ b/code/modules/events/portal_storm.dm @@ -64,7 +64,7 @@ T = safepick(get_area_turfs(pick(station_areas))) hostiles_spawn += T - next_boss_spawn = startWhen + Ceiling(2 * number_of_hostiles / number_of_bosses) + next_boss_spawn = startWhen + CEILING(2 * number_of_hostiles / number_of_bosses, 1) /datum/round_event/portal_storm/announce(fake) set waitfor = 0 @@ -117,14 +117,14 @@ /datum/round_event/portal_storm/proc/spawn_hostile() if(!hostile_types || !hostile_types.len) return 0 - return IsMultiple(activeFor, 2) + return ISMULTIPLE(activeFor, 2) /datum/round_event/portal_storm/proc/spawn_boss() if(!boss_types || !boss_types.len) return 0 if(activeFor == next_boss_spawn) - next_boss_spawn += Ceiling(number_of_hostiles / number_of_bosses) + next_boss_spawn += CEILING(number_of_hostiles / number_of_bosses, 1) return 1 /datum/round_event/portal_storm/proc/time_to_end() diff --git a/code/modules/events/wizard/curseditems.dm b/code/modules/events/wizard/curseditems.dm index 121a0e5083..00d8c3b829 100644 --- a/code/modules/events/wizard/curseditems.dm +++ b/code/modules/events/wizard/curseditems.dm @@ -11,29 +11,29 @@ /datum/round_event/wizard/cursed_items/start() var/item_set = pick("wizardmimic", "swords", "bigfatdoobie", "boxing", "voicemodulators", "catgirls2015") - var/list/wearslots = list(slot_wear_suit, slot_shoes, slot_head, slot_wear_mask, slot_gloves, slot_ears) - var/list/loadout = list() + var/list/loadout[slots_amt] var/ruins_spaceworthiness var/ruins_wizard_loadout - loadout.len = 7 switch(item_set) if("wizardmimic") - loadout = list(/obj/item/clothing/suit/wizrobe, /obj/item/clothing/shoes/sandal/magic, /obj/item/clothing/head/wizard) + loadout[slot_wear_suit] = /obj/item/clothing/suit/wizrobe + loadout[slot_shoes] = /obj/item/clothing/shoes/sandal/magic + loadout[slot_head] = /obj/item/clothing/head/wizard ruins_spaceworthiness = 1 if("swords") - loadout[5] = /obj/item/katana/cursed + loadout[slot_hands] = /obj/item/katana/cursed if("bigfatdoobie") - loadout[4] = /obj/item/clothing/mask/cigarette/rollie/trippy + loadout[slot_wear_mask] = /obj/item/clothing/mask/cigarette/rollie/trippy ruins_spaceworthiness = 1 if("boxing") - loadout[4] = /obj/item/clothing/mask/luchador - loadout[6] = /obj/item/clothing/gloves/boxing + loadout[slot_wear_mask] = /obj/item/clothing/mask/luchador + loadout[slot_gloves] = /obj/item/clothing/gloves/boxing ruins_spaceworthiness = 1 if("voicemodulators") - loadout[4] = /obj/item/clothing/mask/chameleon + loadout[slot_wear_mask] = /obj/item/clothing/mask/chameleon if("catgirls2015") - loadout[3] = /obj/item/clothing/head/kitty + loadout[slot_head] = /obj/item/clothing/head/kitty ruins_spaceworthiness = 1 ruins_wizard_loadout = 1 @@ -44,14 +44,13 @@ continue if(item_set == "catgirls2015") //Wizard code means never having to say you're sorry H.gender = FEMALE - var/list/slots = list(H.wear_suit, H.shoes, H.head, H.wear_mask, H.gloves, H.ears) //add new slots as needed to back for(var/i in 1 to loadout.len) if(loadout[i]) var/obj/item/J = loadout[i] var/obj/item/I = new J //dumb but required because of byond throwing a fit anytime new gets too close to a list - H.temporarilyRemoveItemFromInventory(slots[i], TRUE) - H.equip_to_slot_or_del(I, wearslots[i]) - I.flags_1 |= NODROP_1 + H.dropItemToGround(H.get_item_by_slot(i), TRUE) + H.equip_to_slot_or_del(I, i) + I.flags_1 |= NODROP_1 | DROPDEL_1 I.name = "cursed " + I.name for(var/mob/living/carbon/human/H in GLOB.alive_mob_list) diff --git a/code/modules/events/wizard/departmentrevolt.dm b/code/modules/events/wizard/departmentrevolt.dm index 618c746a65..3227f81d58 100644 --- a/code/modules/events/wizard/departmentrevolt.dm +++ b/code/modules/events/wizard/departmentrevolt.dm @@ -44,6 +44,7 @@ citizens += H SSticker.mode.traitors += M M.special_role = "separatist" + M.add_antag_datum(/datum/antagonist/auto_custom) H.log_message("Was made into a separatist, long live [nation]!", INDIVIDUAL_ATTACK_LOG) to_chat(H, "You are a separatist! [nation] forever! Protect the sovereignty of your newfound land with your comrades in arms!") if(citizens.len) diff --git a/code/modules/events/wizard/greentext.dm b/code/modules/events/wizard/greentext.dm index 6ee000249b..1cf4858ce7 100644 --- a/code/modules/events/wizard/greentext.dm +++ b/code/modules/events/wizard/greentext.dm @@ -67,6 +67,7 @@ O.completed = 1 //YES! O.owner = new_holder.mind new_holder.mind.objectives += O + new_holder.mind.add_antag_datum(/datum/antagonist/auto_custom) new_holder.log_message("Won with greentext!!!", INDIVIDUAL_ATTACK_LOG) color_altered_mobs -= new_holder resistance_flags |= ON_FIRE diff --git a/code/modules/events/wizard/imposter.dm b/code/modules/events/wizard/imposter.dm index 54d3d8ed41..4b2147bd9e 100644 --- a/code/modules/events/wizard/imposter.dm +++ b/code/modules/events/wizard/imposter.dm @@ -6,12 +6,11 @@ earliest_start = 0 /datum/round_event/wizard/imposter/start() - for(var/datum/mind/M in SSticker.mode.wizards) if(!ishuman(M.current)) continue var/mob/living/carbon/human/W = M.current - var/list/candidates = get_candidates(ROLE_WIZARD) + var/list/candidates = pollGhostCandidates("Would you like to be an imposter wizard?", ROLE_WIZARD) if(!candidates) return //Sad Trombone var/client/C = pick(candidates) @@ -28,10 +27,10 @@ var/datum/antagonist/wizard/master = M.has_antag_datum(/datum/antagonist/wizard) if(!master.wiz_team) master.create_wiz_team() - var/datum/antagonist/wizard/apprentice/imposter = new(I.mind) + var/datum/antagonist/wizard/apprentice/imposter/imposter = new(I.mind) imposter.master = M imposter.wiz_team = master.wiz_team - master.wiz_team += imposter + master.wiz_team.add_member(imposter) I.mind.add_antag_datum(imposter) //Remove if possible SSticker.mode.apprentices += I.mind diff --git a/code/modules/events/wizard/race.dm b/code/modules/events/wizard/race.dm index e054be9b08..5adc4bb851 100644 --- a/code/modules/events/wizard/race.dm +++ b/code/modules/events/wizard/race.dm @@ -12,7 +12,7 @@ for(var/speciestype in subtypesof(/datum/species)) var/datum/species/S = new speciestype() - if(!S.dangerous_existence) + if(!S.dangerous_existence && !S.blacklisted) all_species += speciestype var/datum/species/new_species = pick(all_species) @@ -22,7 +22,7 @@ for(var/mob/living/carbon/human/H in GLOB.carbon_list) //yes, even the dead H.set_species(new_species) - H.real_name = new_species.random_name(H.gender,1) + H.real_name = H.dna.species.random_name(H.gender,1) H.dna.unique_enzymes = H.dna.generate_unique_enzymes() to_chat(H, "You feel somehow... different?") if(!all_the_same) diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index 866b763fe6..92dc109bbc 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -13,13 +13,6 @@ Gunshots/explosions/opening doors/less rare audio (done) #define HAL_LINES_FILE "hallucination.json" -/mob/living/carbon - var/image/halimage - var/image/halbody - var/obj/halitem - var/hal_screwyhud = SCREWYHUD_NONE - var/next_hallucination = 0 - GLOBAL_LIST_INIT(hallucinations_minor, list( /datum/hallucination/sounds, /datum/hallucination/bolts, @@ -82,10 +75,12 @@ GLOBAL_LIST_INIT(hallucinations_major, list( /datum/hallucination/Destroy() target.investigate_log("was afflicted with a hallucination of type [type]. [feedback_details]", INVESTIGATE_HALLUCINATIONS) + target = null return ..() /obj/effect/hallucination invisibility = INVISIBILITY_OBSERVER + anchored = TRUE var/mob/living/carbon/target = null /obj/effect/hallucination/simple @@ -203,7 +198,6 @@ GLOBAL_LIST_INIT(hallucinations_major, list( flood_turfs = list() if(target.client) target.client.images.Remove(flood_images) - target = null qdel(flood_images) flood_images = list() return ..() @@ -461,7 +455,7 @@ GLOBAL_LIST_INIT(hallucinations_major, list( var/list/image/delusions = list() cost = 50 -/datum/hallucination/delusion/New(mob/living/carbon/T, forced, force_kind = null , duration = 300,skip_nearby = 1, custom_icon = null, custom_icon_file = null) +/datum/hallucination/delusion/New(mob/living/carbon/T, forced, force_kind = null , duration = 300,skip_nearby = 1, custom_icon = null, custom_icon_file = null, custom_name = null) . = ..() var/image/A = null var/kind = force_kind ? force_kind : pick("monkey","corgi","carp","skeleton","demon","zombie") @@ -474,23 +468,31 @@ GLOBAL_LIST_INIT(hallucinations_major, list( switch(kind) if("monkey")//Monkey A = image('icons/mob/monkey.dmi',H,"monkey1") + A.name = "Monkey ([rand(1,999)])" if("carp")//Carp A = image('icons/mob/animal.dmi',H,"carp") + A.name = "Space Carp" if("corgi")//Corgi A = image('icons/mob/pets.dmi',H,"corgi") + A.name = "Corgi" if("skeleton")//Skeletons A = image('icons/mob/human.dmi',H,"skeleton") + A.name = "Skeleton" if("zombie")//Zombies A = image('icons/mob/human.dmi',H,"zombie") + A.name = "Zombie" if("demon")//Demon A = image('icons/mob/mob.dmi',H,"daemon") + A.name = "Demon" if("custom") A = image(custom_icon_file, H, custom_icon) + A.name = custom_name A.override = 1 if(target.client) delusions |= A target.client.images |= A - QDEL_IN(src, duration) + if(duration) + QDEL_IN(src, duration) /datum/hallucination/delusion/Destroy() for(var/image/I in delusions) @@ -1159,4 +1161,3 @@ GLOBAL_LIST_INIT(hallucinations_major, list( H.preparePixelProjectile(target, start) H.fire() qdel(src) - diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm index 5d3cd09f51..5eae2b80d8 100644 --- a/code/modules/food_and_drinks/drinks/drinks.dm +++ b/code/modules/food_and_drinks/drinks/drinks.dm @@ -8,7 +8,7 @@ icon_state = null lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi' - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER var/gulp_size = 5 //This is now officially broken ... need to think of a nice way to fix it. possible_transfer_amounts = list(5,10,15,20,25,30,50) volume = 50 @@ -30,7 +30,7 @@ if(!canconsume(M, user)) return 0 - if (!is_open_container()) + if (!is_drainable()) to_chat(user, "[src]'s lid hasn't been opened!") return 0 @@ -44,7 +44,7 @@ if(!reagents || !reagents.total_volume) return // The drink might be empty after the delay, such as by spam-feeding M.visible_message("[user] feeds the contents of [src] to [M].", "[user] feeds the contents of [src] to [M].") - add_logs(user, M, "fed", reagentlist(src)) + add_logs(user, M, "fed", reagents.log_list()) var/fraction = min(gulp_size/reagents.total_volume, 1) checkLiked(fraction, M) @@ -56,31 +56,16 @@ /obj/item/reagent_containers/food/drinks/afterattack(obj/target, mob/user , proximity) if(!proximity) return - if(istype(target, /obj/structure/reagent_dispensers)) //A dispenser. Transfer FROM it TO us. - if (!is_open_container()) - to_chat(user, "[target]'s tab isn't open!") - return - - if(!target.reagents.total_volume) - to_chat(user, "[target] is empty.") - return - - if(reagents.total_volume >= reagents.maximum_volume) - to_chat(user, "[src] is full.") - return - - var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this) - to_chat(user, "You fill [src] with [trans] units of the contents of [target].") - - else if(target.is_open_container()) //Something like a glass. Player probably wants to transfer TO it. + if(target.is_refillable()) //Something like a glass. Player probably wants to transfer TO it. if(!reagents.total_volume) to_chat(user, "[src] is empty.") return - if(target.reagents.total_volume >= target.reagents.maximum_volume) + if(target.reagents.holder_full()) to_chat(user, "[target] is full.") return + var/refill = reagents.get_master_reagent_id() var/trans = src.reagents.trans_to(target, amount_per_transfer_from_this) to_chat(user, "You transfer [trans] units of the solution to [target].") @@ -90,13 +75,29 @@ bro.cell.use(30) addtimer(CALLBACK(reagents, /datum/reagents.proc/add_reagent, refill, trans), 600) + else if(target.is_drainable()) //A dispenser. Transfer FROM it TO us. + if (!is_refillable()) + to_chat(user, "[src]'s tab isn't open!") + return + + if(!target.reagents.total_volume) + to_chat(user, "[target] is empty.") + return + + if(reagents.holder_full()) + to_chat(user, "[src] is full.") + return + + var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this) + to_chat(user, "You fill [src] with [trans] units of the contents of [target].") + + else + /obj/item/reagent_containers/food/drinks/attackby(obj/item/I, mob/user, params) - if(I.is_hot()) - var/added_heat = (I.is_hot() / 100) //ishot returns a temperature - if(reagents) - reagents.chem_temp += added_heat - to_chat(user, "You heat [src] with [I].") - reagents.handle_reactions() + var/hotness = I.is_hot() + if(hotness && reagents) + reagents.expose_temperature(hotness) + to_chat(user, "You heat [name] with [I]!") ..() /obj/item/reagent_containers/food/drinks/throw_impact(atom/target, mob/thrower) @@ -115,6 +116,7 @@ I.Blend(B.broken_outline, ICON_OVERLAY, rand(5), 1) I.SwapColor(rgb(255, 0, 220, 255), rgb(0, 0, 0, 0)) B.icon = I + B.name = "broken [name]" if(prob(33)) new/obj/item/shard(drop_location()) playsound(src, "shatter", 70, 1) @@ -141,7 +143,7 @@ possible_transfer_amounts = list() volume = 5 flags_1 = CONDUCT_1 - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER spillable = TRUE resistance_flags = FIRE_PROOF isGlass = FALSE @@ -186,7 +188,7 @@ // Formatting is the same as food. /obj/item/reagent_containers/food/drinks/coffee - name = "Robust Coffee" + name = "robust coffee" desc = "Careful, the beverage you're about to enjoy is extremely hot." icon_state = "coffee" list_reagents = list("coffee" = 30) @@ -195,7 +197,7 @@ isGlass = FALSE /obj/item/reagent_containers/food/drinks/ice - name = "Ice Cup" + name = "ice cup" desc = "Careful, cold ice, do not chew." icon_state = "coffee" list_reagents = list("ice" = 30) @@ -216,12 +218,12 @@ icon_state = "tea_empty" /obj/item/reagent_containers/food/drinks/mug/tea - name = "Duke Purple Tea" + name = "Duke Purple tea" desc = "An insult to Duke Purple is an insult to the Space Queen! Any proper gentleman will fight you, if you sully this tea." list_reagents = list("tea" = 30) /obj/item/reagent_containers/food/drinks/mug/coco - name = "Dutch Hot Coco" + name = "Dutch hot coco" desc = "Made in Space South America." list_reagents = list("hot_coco" = 30, "sugar" = 5) foodtype = SUGAR @@ -230,7 +232,7 @@ /obj/item/reagent_containers/food/drinks/dry_ramen - name = "Cup Ramen" + name = "cup ramen" desc = "Just add 10ml of water, self heats! A taste that reminds you of your school years." icon_state = "ramen" list_reagents = list("dry_ramen" = 30) @@ -238,7 +240,7 @@ isGlass = FALSE /obj/item/reagent_containers/food/drinks/beer - name = "Space Beer" + name = "space beer" desc = "Beer. In space." icon_state = "beer" list_reagents = list("beer" = 30) @@ -282,7 +284,7 @@ I.Blend(B.broken_outline, ICON_OVERLAY, rand(5), 1) I.SwapColor(rgb(255, 0, 220, 255), rgb(0, 0, 0, 0)) B.icon = I - B.name = "broken carton" + B.name = "broken [name]" B.force = 0 B.throwforce = 0 B.desc = "A carton with the bottom half burst open. Might give you a papercut." @@ -392,6 +394,7 @@ container_type = NONE spillable = FALSE isGlass = FALSE + grind_results = list("aluminum" = 10) /obj/item/reagent_containers/food/drinks/soda_cans/attack(mob/M, mob/user) if(M == user && !src.reagents.total_volume && user.a_intent == INTENT_HARM && user.zone_selected == "head") @@ -404,9 +407,9 @@ /obj/item/reagent_containers/food/drinks/soda_cans/attack_self(mob/user) - if(!is_open_container()) + if(!is_drainable()) to_chat(user, "You pull back the tab of \the [src] with a satisfying pop.") //Ahhhhhhhh - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER playsound(src, "can_open", 50, 1) spillable = TRUE return @@ -420,28 +423,28 @@ foodtype = SUGAR /obj/item/reagent_containers/food/drinks/soda_cans/tonic - name = "T-Borg's Tonic Water" + name = "T-Borg's tonic water" desc = "Quinine tastes funny, but at least it'll keep that Space Malaria away." icon_state = "tonic" list_reagents = list("tonic" = 50) foodtype = ALCOHOL /obj/item/reagent_containers/food/drinks/soda_cans/sodawater - name = "Soda Water" + name = "soda water" desc = "A can of soda water. Why not make a scotch and soda?" icon_state = "sodawater" list_reagents = list("sodawater" = 50) /obj/item/reagent_containers/food/drinks/soda_cans/lemon_lime - name = "Orange Soda" + name = "orange soda" desc = "You wanted ORANGE. It gave you Lemon Lime." icon_state = "lemon-lime" list_reagents = list("lemon_lime" = 30) foodtype = FRUIT -/obj/item/reagent_containers/food/drinks/soda_cans/lemon_lime/New() - ..() - name = "Lemon-Lime Soda" +/obj/item/reagent_containers/food/drinks/soda_cans/lemon_lime/Initialize() + . = ..() + name = "lemon-lime soda" /obj/item/reagent_containers/food/drinks/soda_cans/space_up name = "Space-Up!" @@ -485,14 +488,14 @@ list_reagents = list("pwr_game" = 30) /obj/item/reagent_containers/food/drinks/soda_cans/shamblers - name = "Shambler's Juice" + name = "Shambler's juice" desc = "~Shake me up some of that Shambler's Juice!~" icon_state = "shamblers" list_reagents = list("shamblers" = 30) foodtype = SUGAR | JUNKFOOD /obj/item/reagent_containers/food/drinks/soda_cans/air - name = "Canned Air" + name = "canned air" desc = "There is no air shortage. Do not drink." icon_state = "air" list_reagents = list("nitrogen" = 24, "oxygen" = 6) diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm index 5625a752b3..005dda29ca 100644 --- a/code/modules/food_and_drinks/drinks/drinks/bottle.dm +++ b/code/modules/food_and_drinks/drinks/drinks/bottle.dm @@ -35,10 +35,10 @@ new/obj/item/shard(drop_location()) playsound(src, "shatter", 70, 1) else - B.name = "broken carton" B.force = 0 B.throwforce = 0 B.desc = "A carton with the bottom half burst open. Might give you a papercut." + B.name = "broken [name]" transfer_fingerprints_to(B) qdel(src) @@ -119,7 +119,7 @@ //Keeping this here for now, I'll ask if I should keep it here. /obj/item/broken_bottle - name = "Broken Bottle" + name = "broken bottle" desc = "A bottle with a sharp broken bottom." icon = 'icons/obj/drinks.dmi' icon_state = "broken_bottle" @@ -135,37 +135,37 @@ sharpness = IS_SHARP /obj/item/reagent_containers/food/drinks/bottle/gin - name = "Griffeater Gin" + name = "Griffeater gin" desc = "A bottle of high quality gin, produced in the New London Space Station." icon_state = "ginbottle" list_reagents = list("gin" = 100) /obj/item/reagent_containers/food/drinks/bottle/whiskey - name = "Uncle Git's Special Reserve" + name = "Uncle Git's special reserve" desc = "A premium single-malt whiskey, gently matured inside the tunnels of a nuclear shelter. TUNNEL WHISKEY RULES." icon_state = "whiskeybottle" list_reagents = list("whiskey" = 100) /obj/item/reagent_containers/food/drinks/bottle/vodka - name = "Tunguska Triple Distilled" + name = "Tunguska triple distilled" desc = "Aah, vodka. Prime choice of drink AND fuel by Russians worldwide." icon_state = "vodkabottle" list_reagents = list("vodka" = 100) /obj/item/reagent_containers/food/drinks/bottle/vodka/badminka - name = "Badminka Vodka" + name = "Badminka vodka" desc = "The label's written in Cyrillic. All you can make out is the name and a word that looks vaguely like 'Vodka'." icon_state = "badminka" list_reagents = list("vodka" = 100) /obj/item/reagent_containers/food/drinks/bottle/tequila - name = "Caccavo Guaranteed Quality Tequila" + name = "Caccavo guaranteed quality tequila" desc = "Made from premium petroleum distillates, pure thalidomide and other fine quality ingredients!" icon_state = "tequilabottle" list_reagents = list("tequila" = 100) /obj/item/reagent_containers/food/drinks/bottle/bottleofnothing - name = "Bottle of Nothing" + name = "bottle of nothing" desc = "A bottle filled with nothing." icon_state = "bottleofnothing" list_reagents = list("nothing" = 100) @@ -178,13 +178,13 @@ list_reagents = list("patron" = 100) /obj/item/reagent_containers/food/drinks/bottle/rum - name = "Captain Pete's Cuban Spiced Rum" + name = "Captain Pete's Cuban spiced rum" desc = "This isn't just rum, oh no. It's practically GRIFF in a bottle." icon_state = "rumbottle" list_reagents = list("rum" = 100) /obj/item/reagent_containers/food/drinks/bottle/holywater - name = "Flask of Holy Water" + name = "flask of holy water" desc = "A flask of the chaplain's holy water." icon_state = "holyflask" list_reagents = list("holywater" = 100) @@ -195,39 +195,39 @@ list_reagents = list("hell_water" = 100) /obj/item/reagent_containers/food/drinks/bottle/vermouth - name = "Goldeneye Vermouth" + name = "Goldeneye vermouth" desc = "Sweet, sweet dryness~" icon_state = "vermouthbottle" list_reagents = list("vermouth" = 100) /obj/item/reagent_containers/food/drinks/bottle/kahlua - name = "Robert Robust's Coffee Liqueur" + name = "Robert Robust's coffee liqueur" desc = "A widely known, Mexican coffee-flavoured liqueur. In production since 1936, HONK." icon_state = "kahluabottle" list_reagents = list("kahlua" = 100) foodtype = VEGETABLES /obj/item/reagent_containers/food/drinks/bottle/goldschlager - name = "College Girl Goldschlager" + name = "College Girl goldschlager" desc = "Because they are the only ones who will drink 100 proof cinnamon schnapps." icon_state = "goldschlagerbottle" list_reagents = list("goldschlager" = 100) /obj/item/reagent_containers/food/drinks/bottle/cognac - name = "Chateau De Baton Premium Cognac" + name = "Chateau de Baton premium cognac" desc = "A sweet and strongly alchoholic drink, made after numerous distillations and years of maturing. You might as well not scream 'SHITCURITY' this time." icon_state = "cognacbottle" list_reagents = list("cognac" = 100) /obj/item/reagent_containers/food/drinks/bottle/wine - name = "Doublebeard Bearded Special Wine" + name = "Doublebeard's bearded special wine" desc = "A faint aura of unease and asspainery surrounds the bottle." icon_state = "winebottle" list_reagents = list("wine" = 100) foodtype = FRUIT | ALCOHOL /obj/item/reagent_containers/food/drinks/bottle/absinthe - name = "Extra-Strong Absinthe" + name = "extra-strong absinthe" desc = "An strong alcoholic drink brewed and distributed by" icon_state = "absinthebottle" list_reagents = list("absinthe" = 100) @@ -272,7 +272,7 @@ /obj/item/reagent_containers/food/drinks/bottle/absinthe/premium - name = "Gwyn's Premium Absinthe" + name = "Gwyn's premium absinthe" desc = "A potent alcoholic beverage, almost makes you forget the ash in your lungs." icon_state = "absinthepremium" @@ -280,7 +280,7 @@ return /obj/item/reagent_containers/food/drinks/bottle/lizardwine - name = "Bottle of lizard wine" + name = "bottle of lizard wine" desc = "An alcoholic beverage from Space China, made by infusing lizard tails in ethanol. Inexplicably popular among command staff." icon_state = "lizardwine" list_reagents = list("lizardwine" = 100) @@ -302,7 +302,7 @@ //////////////////////////JUICES AND STUFF /////////////////////// /obj/item/reagent_containers/food/drinks/bottle/orangejuice - name = "Orange Juice" + name = "orange juice" desc = "Full of vitamins and deliciousness!" icon_state = "orangejuice" item_state = "carton" @@ -313,7 +313,7 @@ foodtype = FRUIT /obj/item/reagent_containers/food/drinks/bottle/cream - name = "Milk Cream" + name = "milk cream" desc = "It's cream. Made from milk. What else did you think you'd find in there?" icon_state = "cream" item_state = "carton" @@ -324,7 +324,7 @@ foodtype = DAIRY /obj/item/reagent_containers/food/drinks/bottle/tomatojuice - name = "Tomato Juice" + name = "tomato juice" desc = "Well, at least it LOOKS like tomato juice. You can't tell with all that redness." icon_state = "tomatojuice" item_state = "carton" @@ -335,7 +335,7 @@ foodtype = VEGETABLES /obj/item/reagent_containers/food/drinks/bottle/limejuice - name = "Lime Juice" + name = "lime juice" desc = "Sweet-sour goodness." icon_state = "limejuice" item_state = "carton" diff --git a/code/modules/food_and_drinks/food.dm b/code/modules/food_and_drinks/food.dm index e23f6b98a9..765f118c5e 100644 --- a/code/modules/food_and_drinks/food.dm +++ b/code/modules/food_and_drinks/food.dm @@ -4,7 +4,7 @@ /obj/item/reagent_containers/food possible_transfer_amounts = list() volume = 50 //Sets the default container amount for all food items. - container_type = INJECTABLE_1 + container_type = INJECTABLE resistance_flags = FLAMMABLE var/foodtype = NONE var/last_check_time diff --git a/code/modules/food_and_drinks/food/condiment.dm b/code/modules/food_and_drinks/food/condiment.dm index 3e6e2e8450..445e8e6534 100644 --- a/code/modules/food_and_drinks/food/condiment.dm +++ b/code/modules/food_and_drinks/food/condiment.dm @@ -10,7 +10,7 @@ desc = "Just your average condiment container." icon = 'icons/obj/food/containers.dmi' icon_state = "emptycondiment" - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER possible_transfer_amounts = list(1, 5, 10, 15, 20, 25, 30, 50) volume = 50 //Possible_states has the reagent id as key and a list of, in order, the icon_state, the name and the desc as values. Used in the on_reagent_change(changetype) to change names, descs and sprites. @@ -45,7 +45,7 @@ if(!reagents || !reagents.total_volume) return // The condiment might be empty after the delay. user.visible_message("[user] feeds [M] from [src].") - add_logs(user, M, "fed", reagentlist(src)) + add_logs(user, M, "fed", reagents.log_list()) var/fraction = min(10/reagents.total_volume, 1) reagents.reaction(M, INGEST, fraction) @@ -70,7 +70,7 @@ to_chat(user, "You fill [src] with [trans] units of the contents of [target].") //Something like a glass or a food item. Player probably wants to transfer TO it. - else if(target.is_open_container() || istype(target, /obj/item/reagent_containers/food/snacks)) + else if(target.is_drainable() || istype(target, /obj/item/reagent_containers/food/snacks)) if(!reagents.total_volume) to_chat(user, "[src] is empty!") return diff --git a/code/modules/food_and_drinks/food/customizables.dm b/code/modules/food_and_drinks/food/customizables.dm index 3351a67d39..f3460edcaa 100644 --- a/code/modules/food_and_drinks/food/customizables.dm +++ b/code/modules/food_and_drinks/food/customizables.dm @@ -291,7 +291,7 @@ desc = "A simple bowl, used for soups and salads." icon = 'icons/obj/food/soupsalad.dmi' icon_state = "bowl" - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER materials = list(MAT_GLASS = 500) w_class = WEIGHT_CLASS_NORMAL diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm index a8ea51a99c..08b09124d5 100644 --- a/code/modules/food_and_drinks/food/snacks.dm +++ b/code/modules/food_and_drinks/food/snacks.dm @@ -6,6 +6,7 @@ lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi' unique_rename = 1 + grind_results = list() //To let them be ground up to transfer their reagents var/bitesize = 2 var/bitecount = 0 var/trash = null @@ -93,7 +94,7 @@ if(!do_mob(user, M)) return - add_logs(user, M, "fed", reagentlist(src)) + add_logs(user, M, "fed", reagents.log_list()) M.visible_message("[user] forces [M] to eat [src].", \ "[user] forces [M] to eat [src].") @@ -276,7 +277,7 @@ /obj/item/reagent_containers/food/snacks/Destroy() if(contents) for(var/atom/movable/something in contents) - something.loc = get_turf(src) + something.forceMove(drop_location()) return ..() /obj/item/reagent_containers/food/snacks/attack_animal(mob/M) diff --git a/code/modules/food_and_drinks/food/snacks_egg.dm b/code/modules/food_and_drinks/food/snacks_egg.dm index bfe181b419..10039f7a8b 100644 --- a/code/modules/food_and_drinks/food/snacks_egg.dm +++ b/code/modules/food_and_drinks/food/snacks_egg.dm @@ -20,6 +20,7 @@ filling_color = "#F0E68C" tastes = list("egg" = 1) foodtype = MEAT + grind_results = list("eggyolk" = 5) /obj/item/reagent_containers/food/snacks/egg/throw_impact(atom/hit_atom) if(!..()) //was it caught by a mob? diff --git a/code/modules/food_and_drinks/food/snacks_other.dm b/code/modules/food_and_drinks/food/snacks_other.dm index 0c626ab71e..c7681fe807 100644 --- a/code/modules/food_and_drinks/food/snacks_other.dm +++ b/code/modules/food_and_drinks/food/snacks_other.dm @@ -28,6 +28,7 @@ filling_color = "#FF1493" tastes = list("watermelon" = 1) foodtype = FRUIT + juice_results = list("watermelonjuice" = 5) /obj/item/reagent_containers/food/snacks/candy_corn name = "candy corn" @@ -380,7 +381,7 @@ foodtype = VEGETABLES | FRIED | DAIRY /obj/item/reagent_containers/food/snacks/cubannachos - name = "cuban nachos" + name = "Cuban nachos" desc = "That's some dangerously spicy nachos." icon_state = "cubannachos" bonus_reagents = list("nutriment" = 2, "vitamin" = 3) diff --git a/code/modules/food_and_drinks/food/snacks_pastry.dm b/code/modules/food_and_drinks/food/snacks_pastry.dm index ef518bf5fc..284784484f 100644 --- a/code/modules/food_and_drinks/food/snacks_pastry.dm +++ b/code/modules/food_and_drinks/food/snacks_pastry.dm @@ -4,7 +4,7 @@ /obj/item/reagent_containers/food/snacks/donut name = "donut" - desc = "Goes great with Robust Coffee." + desc = "Goes great with robust coffee." icon_state = "donut1" bitesize = 5 bonus_reagents = list("sugar" = 1) diff --git a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm index a336d77404..40eae1b570 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm @@ -29,7 +29,7 @@ God bless America. anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 5 - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER var/obj/item/reagent_containers/food/snacks/deepfryholder/frying //What's being fried RIGHT NOW? var/cook_time = 0 var/oil_use = 0.05 //How much cooking oil is used per tick diff --git a/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm b/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm index 765b5ff891..40f99b363a 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm @@ -15,7 +15,7 @@ var/portion = 10 var/selected_drink var/list/stored_food = list() - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER var/obj/item/reagent_containers/mixer /obj/machinery/food_cart/Initialize() @@ -100,7 +100,7 @@ stored_food[sanitize(S.name)]++ else stored_food[sanitize(S.name)] = 1 - else if(O.is_open_container()) + else if(O.is_drainable()) return else . = ..() @@ -119,11 +119,11 @@ else for(var/obj/O in contents) if(sanitize(O.name) == href_list["dispense"]) - O.loc = src.loc + O.forceMove(drop_location()) break if(href_list["portion"]) - portion = Clamp(input("How much drink do you want to dispense per glass?") as num, 0, 50) + portion = CLAMP(input("How much drink do you want to dispense per glass?") as num, 0, 50) if(href_list["pour"] || href_list["m_pour"]) if(glasses-- <= 0) diff --git a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm index 1b00de1842..f2f288fe7a 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm @@ -14,7 +14,7 @@ anchored = FALSE use_power = NO_POWER_USE layer = BELOW_OBJ_LAYER - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER max_integrity = 300 var/list/product_types = list() var/dispense_flavour = ICECREAM_VANILLA @@ -112,7 +112,7 @@ else to_chat(user, "[O] already has ice cream in it.") return 1 - else if(O.is_open_container()) + else if(O.is_drainable()) return else return ..() diff --git a/code/modules/food_and_drinks/kitchen_machinery/juicer.dm b/code/modules/food_and_drinks/kitchen_machinery/juicer.dm deleted file mode 100644 index 08120cc6e4..0000000000 --- a/code/modules/food_and_drinks/kitchen_machinery/juicer.dm +++ /dev/null @@ -1,187 +0,0 @@ - -/obj/machinery/juicer - name = "juicer" - desc = "A centrifugal juicer with two speeds: Juice and Separate." - icon = 'icons/obj/kitchen.dmi' - icon_state = "juicer1" - layer = BELOW_OBJ_LAYER - density = TRUE - anchored = FALSE - use_power = IDLE_POWER_USE - idle_power_usage = 5 - active_power_usage = 100 - pass_flags = PASSTABLE - var/obj/item/reagent_containers/beaker - var/static/list/allowed_items = list( - /obj/item/reagent_containers/food/snacks/grown/tomato = "tomatojuice", - /obj/item/reagent_containers/food/snacks/grown/carrot = "carrotjuice", - /obj/item/reagent_containers/food/snacks/grown/berries = "berryjuice", - /obj/item/reagent_containers/food/snacks/grown/grapes = "grapejuice", - /obj/item/reagent_containers/food/snacks/grown/grapes/green = "grapejuice", - /obj/item/reagent_containers/food/snacks/grown/banana = "banana", - /obj/item/reagent_containers/food/snacks/grown/potato = "potato", - /obj/item/reagent_containers/food/snacks/grown/citrus/lemon = "lemonjuice", - /obj/item/reagent_containers/food/snacks/grown/citrus/orange = "orangejuice", - /obj/item/reagent_containers/food/snacks/grown/citrus/lime = "limejuice", - /obj/item/reagent_containers/food/snacks/grown/watermelon = "watermelonjuice", - /obj/item/reagent_containers/food/snacks/watermelonslice = "watermelonjuice", - /obj/item/reagent_containers/food/snacks/grown/berries/poison = "poisonberryjuice", - /obj/item/reagent_containers/food/snacks/grown/pumpkin = "pumpkinjuice", - /obj/item/reagent_containers/food/snacks/grown/blumpkin = "blumpkinjuice") - -/obj/machinery/juicer/Initialize() - . = ..() - beaker = new /obj/item/reagent_containers/glass/beaker/large(src) - -/obj/machinery/juicer/update_icon() - icon_state = "juicer"+num2text(!isnull(beaker)) - return - - -/obj/machinery/juicer/attackby(obj/item/O, mob/user, params) - if(default_unfasten_wrench(user, O)) - return - if (istype(O, /obj/item/reagent_containers/glass) || \ - istype(O, /obj/item/reagent_containers/food/drinks/drinkingglass)) - if (beaker) - return 1 - else - if(!user.transferItemToLoc(O, src)) - to_chat(user, "\the [O] is stuck to your hand, you cannot put it in \the [src]!") - return 0 - beaker = O - src.verbs += /obj/machinery/juicer/verb/detach - update_icon() - src.updateUsrDialog() - return 0 - if (!is_type_in_list(O, allowed_items)) - to_chat(user, "This object contains no fluid or extractable reagents.") - return 1 - if(!user.transferItemToLoc(O, src)) - to_chat(user, "\the [O] is stuck to your hand, you cannot put it in \the [src]!") - return 0 - src.updateUsrDialog() - return 0 - -/obj/machinery/juicer/attack_paw(mob/user) - return src.attack_hand(user) - -/obj/machinery/juicer/attack_ai(mob/user) - return 0 - -/obj/machinery/juicer/attack_hand(mob/user) - user.set_machine(src) - interact(user) - -/obj/machinery/juicer/interact(mob/user) // The microwave Menu - var/is_chamber_empty = 0 - var/is_beaker_ready = 0 - var/processing_chamber = "" - var/beaker_contents = "" - - for (var/i in allowed_items) - for (var/obj/item/O in src.contents) - if (!istype(O,i)) - continue - processing_chamber+= "some [O]
    " - break - if (!processing_chamber) - is_chamber_empty = 1 - processing_chamber = "Nothing." - if (!beaker) - beaker_contents = "\The [src] has no container attached." - else if (!beaker.reagents.total_volume) - beaker_contents = "\The [src] has an empty [beaker] attached." - is_beaker_ready = 1 - else if (beaker.reagents.total_volume < beaker.reagents.maximum_volume) - beaker_contents = "\The [src] has a partially filled [beaker] attached." - is_beaker_ready = 1 - else - beaker_contents = "\The [src] has a completly filled [beaker] attached!" - - var/dat = {" -Processing chamber contains:
    -[processing_chamber]
    -[beaker_contents]
    -"} - if (is_beaker_ready && !is_chamber_empty && !(stat & (NOPOWER|BROKEN))) - dat += "Turn on!
    " - if (beaker) - dat += "
    Detach the container!
    " - user << browse("Juicer[dat]", "window=juicer") - onclose(user, "juicer") - return - - -/obj/machinery/juicer/Topic(href, href_list) - if(..()) - return - usr.set_machine(src) - switch(href_list["action"]) - if ("juice") - juice() - - if ("detach") - detach() - src.updateUsrDialog() - return - -/obj/machinery/juicer/verb/detach() - set category = "Object" - set name = "Detach container from the juicer" - set src in oview(1) - if(usr.stat || !usr.canmove || usr.restrained()) - return - if (!beaker) - return - src.verbs -= /obj/machinery/juicer/verb/detach - beaker.forceMove(drop_location()) - beaker = null - update_icon() - -/obj/machinery/juicer/proc/get_juice_id(obj/item/reagent_containers/food/snacks/grown/O) - for (var/i in allowed_items) - if (istype(O, i)) - return allowed_items[i] - -/obj/machinery/juicer/proc/get_juice_amount(obj/item/reagent_containers/food/snacks/grown/O) - if (!istype(O) || !O.seed) - return 5 - else if (O.seed.potency == -1) - return 5 - else - return round(5*sqrt(O.seed.potency)) - -/obj/machinery/juicer/proc/juice() - power_change() //it is a portable machine - if(stat & (NOPOWER|BROKEN)) - return - if (!beaker || beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - return - playsound(src.loc, 'sound/machines/juicer.ogg', 50, 1) - for (var/obj/item/reagent_containers/food/snacks/O in src.contents) - var/r_id = get_juice_id(O) - beaker.reagents.add_reagent(r_id,get_juice_amount(O)) - qdel(O) - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - -/obj/structure/closet/crate/juice/New() - ..() - new/obj/machinery/juicer(src) - new/obj/item/reagent_containers/food/snacks/grown/tomato(src) - new/obj/item/reagent_containers/food/snacks/grown/carrot(src) - new/obj/item/reagent_containers/food/snacks/grown/berries(src) - new/obj/item/reagent_containers/food/snacks/grown/banana(src) - new/obj/item/reagent_containers/food/snacks/grown/grapes(src) - new/obj/item/reagent_containers/food/snacks/grown/tomato(src) - new/obj/item/reagent_containers/food/snacks/grown/carrot(src) - new/obj/item/reagent_containers/food/snacks/grown/berries(src) - new/obj/item/reagent_containers/food/snacks/grown/banana(src) - new/obj/item/reagent_containers/food/snacks/grown/grapes(src) - new/obj/item/reagent_containers/food/snacks/grown/tomato(src) - new/obj/item/reagent_containers/food/snacks/grown/carrot(src) - new/obj/item/reagent_containers/food/snacks/grown/berries(src) - new/obj/item/reagent_containers/food/snacks/grown/banana(src) - new/obj/item/reagent_containers/food/snacks/grown/grapes(src) - diff --git a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm index 9d7b6cb203..52ee5ebd2b 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm @@ -81,7 +81,7 @@ src.icon_state = "mw" src.broken = 0 // Fix it! src.dirty = 0 // just to be sure - src.container_type = OPENCONTAINER_1 + src.container_type = OPENCONTAINER return 0 //to use some fuel else to_chat(user, "It's broken!") @@ -98,7 +98,7 @@ src.dirty = 0 // It's clean! src.broken = 0 // just to be sure src.icon_state = "mw" - src.container_type = OPENCONTAINER_1 + src.container_type = OPENCONTAINER src.updateUsrDialog() return 1 // Disables the after-attack so we don't spray the floor/user. else @@ -119,7 +119,7 @@ src.dirty = 0 // It's clean! src.broken = 0 // just to be sure src.icon_state = "mw" - src.container_type = OPENCONTAINER_1 + src.container_type = OPENCONTAINER else if(src.dirty==100) // The microwave is all dirty so can't be used! to_chat(user, "It's dirty!") @@ -277,14 +277,14 @@ operating = FALSE // Turn it off again aferwards icon_state = "mw" updateUsrDialog() + soundloop.stop() /obj/machinery/microwave/proc/stop() - soundloop.stop() abort() /obj/machinery/microwave/proc/dispose() for (var/obj/O in contents) - O.loc = src.loc + O.forceMove(drop_location()) to_chat(usr, "You dispose of the microwave contents.") updateUsrDialog() @@ -293,7 +293,6 @@ icon_state = "mwbloody1" // Make it look dirty!! /obj/machinery/microwave/proc/muck_finish() - playsound(src.loc, 'sound/machines/ding.ogg', 50, 1) visible_message("The microwave gets covered in muck!") dirty = 100 // Make it dirty so it can't be used util cleaned icon_state = "mwbloody" // Make it look dirty too @@ -303,6 +302,7 @@ if(prob(50)) new /obj/item/reagent_containers/food/snacks/badrecipe(src) qdel(S) + soundloop.stop() /obj/machinery/microwave/proc/broke() var/datum/effect_system/spark_spread/s = new @@ -314,6 +314,7 @@ flags_1 = null //So you can't add condiments operating = FALSE // Turn it off again aferwards updateUsrDialog() + soundloop.stop() /obj/machinery/microwave/Topic(href, href_list) if(..() || panel_open) diff --git a/code/modules/food_and_drinks/kitchen_machinery/processor.dm b/code/modules/food_and_drinks/kitchen_machinery/processor.dm index 8b10bdf2a6..6d8797b7a8 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/processor.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/processor.dm @@ -178,9 +178,9 @@ /obj/machinery/processor/proc/empty() for (var/obj/O in src) - O.loc = src.loc + O.forceMove(drop_location()) for (var/mob/M in src) - M.loc = src.loc + M.forceMove(drop_location()) return /obj/machinery/processor/slime diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm index 46e2f3ea5f..750b5524bb 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm @@ -301,10 +301,10 @@ if(S.dried_type == S.type)//if the dried type is the same as the object's type, don't bother creating a whole new item... S.add_atom_colour("#ad7257", FIXED_COLOUR_PRIORITY) S.dry = TRUE - S.loc = get_turf(src) + S.forceMove(drop_location()) else var/dried = S.dried_type - new dried(src.loc) + new dried(drop_location()) qdel(S) return TRUE for(var/obj/item/stack/sheet/wetleather/WL in contents) diff --git a/code/modules/food_and_drinks/pizzabox.dm b/code/modules/food_and_drinks/pizzabox.dm index d746fd600e..6ef8e5e4e9 100644 --- a/code/modules/food_and_drinks/pizzabox.dm +++ b/code/modules/food_and_drinks/pizzabox.dm @@ -5,7 +5,6 @@ item_state = "eshield0" lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi' - origin_tech = "syndicate=3;engineering=3" /obj/item/pizzabox name = "pizza box" @@ -125,7 +124,7 @@ return else bomb_timer = input(user, "Set the [bomb] timer from [BOMB_TIMER_MIN] to [BOMB_TIMER_MAX].", bomb, bomb_timer) as num - bomb_timer = Clamp(Ceiling(bomb_timer / 2), BOMB_TIMER_MIN, BOMB_TIMER_MAX) + bomb_timer = CLAMP(CEILING(bomb_timer / 2, 1), BOMB_TIMER_MIN, BOMB_TIMER_MAX) bomb_defused = FALSE var/message = "[ADMIN_LOOKUPFLW(user)] has trapped a [src] with [bomb] set to [bomb_timer * 2] seconds." diff --git a/code/modules/games/cards.dm b/code/modules/games/cards.dm index 89f6316297..bceaf6d7dd 100644 --- a/code/modules/games/cards.dm +++ b/code/modules/games/cards.dm @@ -187,7 +187,7 @@ ASSERT(H) usr.visible_message("\The [usr] plays \the [card.name].") - H.loc = get_step(usr,usr.dir) + H.forceMove(get_step(usr,usr.dir)) src.update_icon() diff --git a/code/modules/games/cas.dm b/code/modules/games/cas.dm index ecdc1a641f..00e513dcbd 100644 --- a/code/modules/games/cas.dm +++ b/code/modules/games/cas.dm @@ -27,7 +27,8 @@ decksize = 50 card_text_file = "strings/cas_black.txt" -/obj/item/toy/cards/deck/cas/New() +/obj/item/toy/cards/deck/cas/Initialize() + . = ..() var/static/list/cards_against_space = list("cas_white" = world.file2list("strings/cas_white.txt"),"cas_black" = world.file2list("strings/cas_black.txt")) allcards = cards_against_space[card_face] var/list/possiblecards = allcards.Copy() @@ -52,7 +53,6 @@ P.card_icon = "cas_white" cards += P shuffle_inplace(cards) // distribute blank cards throughout deck - ..() /obj/item/toy/cards/deck/cas/attack_hand(mob/user) if(user.lying) diff --git a/code/modules/goonchat/browserOutput.dm b/code/modules/goonchat/browserOutput.dm index 7e0ca0bb7d..0832f372c8 100644 --- a/code/modules/goonchat/browserOutput.dm +++ b/code/modules/goonchat/browserOutput.dm @@ -104,7 +104,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic sendClientData() //do not convert to to_chat() - SEND_TEXT(owner, "If you can see this, update byond.") + SEND_TEXT(owner, "Failed to load fancy chat, reverting to old chat. Certain features won't work.") pingLoop() @@ -132,7 +132,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic /datum/chatOutput/proc/setMusicVolume(volume = "") if(volume) - adminMusicVolume = Clamp(text2num(volume), 0, 100) + adminMusicVolume = CLAMP(text2num(volume), 0, 100) //Sends client connection details to the chat to handle and save /datum/chatOutput/proc/sendClientData() diff --git a/code/modules/goonchat/browserassets/css/browserOutput.css b/code/modules/goonchat/browserassets/css/browserOutput.css index 153444c0ed..c72f26a4e7 100644 --- a/code/modules/goonchat/browserassets/css/browserOutput.css +++ b/code/modules/goonchat/browserassets/css/browserOutput.css @@ -13,7 +13,7 @@ body { background: #fff; font-family: Verdana, sans-serif; font-size: 9pt; - line-height: 1.4; + line-height: 1.2; overflow-x: hidden; overflow-y: scroll; word-wrap: break-word; @@ -38,6 +38,19 @@ img.icon { vertical-align: bottom; } + +.r:before { /* "repeated" badge class for combined messages */ + content: 'x'; +} +.r { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: 700; + line-height: 1; + color: #f00; +} + a {color: #0000ff;} a.visited {color: #ff00ff;} a:visited {color: #ff00ff;} @@ -253,6 +266,9 @@ em {font-style: normal; font-weight: bold;} .say {} .deadsay {color: #5c00e6;} +.binarysay {color: #20c20e; background-color: #000000; display: block;} +.binarysay a {color: #00ff00;} +.binarysay a:active, .binarysay a:visited {color: #88ff88;} .radio {color: #008000;} .sciradio {color: #993399;} .comradio {color: #948f02;} @@ -374,6 +390,7 @@ h1.alert, h2.alert {color: #000000;} .memo {color: #638500; text-align: center;} .memoedit {text-align: center; font-size: 16px;} .abductor {color: #800080; font-style: italic;} +.mind_control {color: #A00D6F; font-size: 3; font-weight: bold; font-style: italic;} .slime {color: #00CED1;} .drone {color: #848482;} .monkey {color: #975032;} diff --git a/code/modules/goonchat/browserassets/html/browserOutput.html b/code/modules/goonchat/browserassets/html/browserOutput.html index 7b2d3ecfe0..d40fd75f39 100644 --- a/code/modules/goonchat/browserassets/html/browserOutput.html +++ b/code/modules/goonchat/browserassets/html/browserOutput.html @@ -36,9 +36,12 @@
    diff --git a/code/modules/goonchat/browserassets/js/browserOutput.js b/code/modules/goonchat/browserassets/js/browserOutput.js index 2ef7704625..4ca135bfd7 100644 --- a/code/modules/goonchat/browserassets/js/browserOutput.js +++ b/code/modules/goonchat/browserassets/js/browserOutput.js @@ -22,7 +22,7 @@ window.onerror = function(msg, url, line, col, error) { //Globals window.status = 'Output'; -var $messages, $subOptions, $subAudio, $selectedSub, $contextMenu, $filterMessages; +var $messages, $subOptions, $subAudio, $selectedSub, $contextMenu, $filterMessages, $last_message; var opts = { //General 'messageCount': 0, //A count...of messages... @@ -68,6 +68,8 @@ var opts = { 'defaultMusicVolume': 25, + 'messageCombining': true, + }; function clamp(val, min, max) { @@ -294,27 +296,54 @@ function output(message, flag) { opts.messageCount--; //I guess the count should only ever equal the limit } - //Actually append the message - var entry = document.createElement('div'); - entry.className = 'entry'; - - if (filteredOut) { - entry.className += ' hidden'; - entry.setAttribute('data-filter', filteredOut); + var handled = false; + var trimmed_message = message.trim() + var lastmessages = $messages.children('div.entry:last-child'); + if (opts.messageCombining && lastmessages.length && $last_message) + { + if($last_message == trimmed_message) + { + if(lastmessages.children('span.r').length) + { + var current_value = parseInt(lastmessages.children('span.r').text()) + lastmessages.children('span.r').text(current_value+1) + } + else + { + lastmessages.append($('', { 'class': 'r', 'text': 2})); + } + if(parseInt(lastmessages.css("font-size")) < 24) //Completely arbitrary max size + lastmessages.css("font-size","+=2") + opts.messageCount--; + handled = true; + } + } + + if(!handled) + { + //Actually append the message + var entry = document.createElement('div'); + entry.className = 'entry'; + + if (filteredOut) { + entry.className += ' hidden'; + entry.setAttribute('data-filter', filteredOut); + } + + $last_message = trimmed_message; + entry.innerHTML = trimmed_message; + $messages[0].appendChild(entry); + $(entry).find("img.icon").error(iconError); + //Actually do the snap + //Stuff we can do after the message shows can go here, in the interests of responsiveness + if (opts.highlightTerms && opts.highlightTerms.length > 0) { + highlightTerms(entry); + } } - entry.innerHTML = message.trim(); - $messages[0].appendChild(entry); - $(entry).find("img.icon").error(iconError); - //Actually do the snap if (!filteredOut && atBottom) { $('body,html').scrollTop($messages.outerHeight()); } - - //Stuff we can do after the message shows can go here, in the interests of responsiveness - if (opts.highlightTerms && opts.highlightTerms.length > 0) { - highlightTerms(entry); - } } function internalOutput(message, flag) @@ -564,16 +593,22 @@ $(function() { ******************************************/ var savedConfig = { 'sfontSize': getCookie('fontsize'), + 'slineHeight': getCookie('lineheight'), 'spingDisabled': getCookie('pingdisabled'), 'shighlightTerms': getCookie('highlightterms'), 'shighlightColor': getCookie('highlightcolor'), 'smusicVolume': getCookie('musicVolume'), + 'smessagecombining': getCookie('messagecombining'), }; if (savedConfig.sfontSize) { $messages.css('font-size', savedConfig.sfontSize); internalOutput('Loaded font size setting of: '+savedConfig.sfontSize+'', 'internal'); } + if (savedConfig.slineHeight) { + $("body").css('line-height', savedConfig.slineHeight); + internalOutput('Loaded line height setting of: '+savedConfig.slineHeight+'', 'internal'); + } if (savedConfig.spingDisabled) { if (savedConfig.spingDisabled == 'true') { opts.pingDisabled = true; @@ -606,7 +641,15 @@ $(function() { opts.updatedVolume = newVolume; sendVolumeUpdate(); internalOutput('Loaded music volume of: '+savedConfig.smusicVolume+'', 'internal'); - } else { + } + if (savedConfig.smessagecombining) { + if (savedConfig.smessagecombining == 'false') { + opts.messageCombining = false; + } else { + opts.messageCombining = true; + } + } + else { $('#adminMusic').prop('volume', opts.defaultMusicVolume / 100); } @@ -805,6 +848,28 @@ $(function() { internalOutput('Font size set to '+fontSize+'', 'internal'); }); + $('#decreaseLineHeight').click(function(e) { + var Heightline = parseFloat($("body").css('line-height')); + var Sizefont = parseFloat($("body").css('font-size')); + var lineheightvar = Heightline / Sizefont + lineheightvar -= 0.1; + lineheightvar = lineheightvar.toFixed(1) + $("body").css({'line-height': lineheightvar}); + setCookie('lineheight', lineheightvar, 365); + internalOutput('Line height set to '+lineheightvar+'', 'internal'); + }); + + $('#increaseLineHeight').click(function(e) { + var Heightline = parseFloat($("body").css('line-height')); + var Sizefont = parseFloat($("body").css('font-size')); + var lineheightvar = Heightline / Sizefont + lineheightvar += 0.1; + lineheightvar = lineheightvar.toFixed(1) + $("body").css({'line-height': lineheightvar}); + setCookie('lineheight', lineheightvar, 365); + internalOutput('Line height set to '+lineheightvar+'', 'internal'); + }); + $('#togglePing').click(function(e) { if (opts.pingDisabled) { $('#ping').slideDown('fast'); @@ -922,6 +987,11 @@ $(function() { } }); + $('#toggleCombine').click(function(e) { + opts.messageCombining = !opts.messageCombining; + setCookie('messagecombining', (opts.messageCombining ? 'true' : 'false'), 365); + }); + $('img.icon').error(iconError); diff --git a/code/modules/holiday/halloween.dm b/code/modules/holiday/halloween.dm index f8716870e1..a27db8dd38 100644 --- a/code/modules/holiday/halloween.dm +++ b/code/modules/holiday/halloween.dm @@ -146,7 +146,7 @@ timer = rand(1,15) /mob/living/simple_animal/shade/howling_ghost/proc/EtherealMove(direction) - loc = get_step(src, direction) + forceMove(get_step(src, direction)) setDir(direction) /mob/living/simple_animal/shade/howling_ghost/proc/roam() @@ -220,7 +220,7 @@ timer = rand(5,15) playsound(M.loc, pick('sound/spookoween/scary_horn.ogg','sound/spookoween/scary_horn2.ogg', 'sound/spookoween/scary_horn3.ogg'), 300, 1) spawn(12) - loc = M.loc + forceMove(M.loc) /mob/living/simple_animal/hostile/retaliate/clown/insane/MoveToTarget() stalk(target) diff --git a/code/modules/holodeck/items.dm b/code/modules/holodeck/items.dm index 54384753d7..6a8a720366 100644 --- a/code/modules/holodeck/items.dm +++ b/code/modules/holodeck/items.dm @@ -113,7 +113,7 @@ if(user.grab_state < GRAB_AGGRESSIVE) to_chat(user, "You need a better grip to do that!") return - L.loc = src.loc + L.forceMove(loc) L.Knockdown(100) visible_message("[user] dunks [L] into \the [src]!") user.stop_pulling() diff --git a/code/modules/hydroponics/beekeeping/beebox.dm b/code/modules/hydroponics/beekeeping/beebox.dm index 141336cf5d..d4269013f7 100644 --- a/code/modules/hydroponics/beekeeping/beebox.dm +++ b/code/modules/hydroponics/beekeeping/beebox.dm @@ -58,6 +58,7 @@ /obj/structure/beebox/premade/New() ..() + icon_state = "beebox" var/datum/reagent/R = null if(random_reagent) R = pick(subtypesof(/datum/reagent)) @@ -80,6 +81,7 @@ /obj/structure/beebox/premade/random + icon_state = "random_beebox" random_reagent = TRUE @@ -100,7 +102,7 @@ if((bee_resources >= BEE_RESOURCE_NEW_BEE_COST && prob(BEE_PROB_NEW_BEE)) || freebee) if(!freebee) bee_resources = max(bee_resources - BEE_RESOURCE_NEW_BEE_COST, 0) - var/mob/living/simple_animal/hostile/poison/bees/B = new(src) + var/mob/living/simple_animal/hostile/poison/bees/B = new(get_turf(src)) B.beehome = src B.assign_reagent(queen_bee.beegent) bees += B @@ -176,7 +178,7 @@ bees -= B B.beehome = null if(B.loc == src) - B.loc = get_turf(src) + B.forceMove(drop_location()) relocated++ if(relocated) to_chat(user, "This queen has a different reagent to some of the bees who live here, those bees will not return to this apiary!") @@ -199,7 +201,7 @@ if(B.isqueen) continue if(B.loc == src) - B.loc = get_turf(src) + B.forceMove(drop_location()) B.target = user bees = TRUE if(bees) @@ -219,7 +221,7 @@ var/obj/item/honey_frame/HF = pick_n_take(honey_frames) if(HF) if(!user.put_in_active_hand(HF)) - HF.loc = get_turf(src) + HF.forceMove(drop_location()) visible_message("[user] removes a frame from the apiary.") var/amtH = HF.honeycomb_capacity @@ -227,7 +229,7 @@ while(honeycombs.len && amtH) //let's pretend you always grab the frame with the most honeycomb on it var/obj/item/reagent_containers/honeycomb/HC = pick_n_take(honeycombs) if(HC) - HC.loc = get_turf(user) + HC.forceMove(drop_location()) amtH-- fallen++ if(fallen) @@ -239,12 +241,12 @@ to_chat(user, "There is no queen bee to remove!") return var/obj/item/queen_bee/QB = new() - queen_bee.loc = QB + queen_bee.forceMove(QB) bees -= queen_bee QB.queen = queen_bee QB.name = queen_bee.name if(!user.put_in_active_hand(QB)) - QB.loc = get_turf(src) + QB.forceMove(drop_location()) visible_message("[user] removes the queen from the apiary.") queen_bee = null @@ -252,8 +254,8 @@ new /obj/item/stack/sheet/mineral/wood (loc, 20) for(var/mob/living/simple_animal/hostile/poison/bees/B in bees) if(B.loc == src) - B.loc = get_turf(src) + B.forceMove(drop_location()) for(var/obj/item/honey_frame/HF in honey_frames) if(HF.loc == src) - HF.loc = get_turf(src) - qdel(src) \ No newline at end of file + HF.forceMove(drop_location()) + qdel(src) diff --git a/code/modules/hydroponics/beekeeping/honeycomb.dm b/code/modules/hydroponics/beekeeping/honeycomb.dm index 737736efc5..8b9d641eac 100644 --- a/code/modules/hydroponics/beekeeping/honeycomb.dm +++ b/code/modules/hydroponics/beekeeping/honeycomb.dm @@ -10,6 +10,7 @@ volume = 10 amount_per_transfer_from_this = 0 list_reagents = list("honey" = 5) + grind_results = list() var/honey_color = "" /obj/item/reagent_containers/honeycomb/New() diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm index 9d6095cf4b..8939b60138 100644 --- a/code/modules/hydroponics/biogenerator.dm +++ b/code/modules/hydroponics/biogenerator.dm @@ -1,7 +1,7 @@ /obj/machinery/biogenerator name = "biogenerator" desc = "Converts plants into biomass, which can be used to construct useful items." - icon = 'icons/obj/biogenerator.dmi' + icon = 'icons/obj/machines/biogenerator.dmi' icon_state = "biogen-empty" density = TRUE anchored = TRUE @@ -15,13 +15,13 @@ var/efficiency = 0 var/productivity = 0 var/max_items = 40 - var/datum/research/files + var/datum/techweb/stored_research var/list/show_categories = list("Food", "Botany Chemicals", "Leather and Cloth") var/list/timesFiveCategories = list("Food", "Botany Chemicals") /obj/machinery/biogenerator/Initialize() . = ..() - files = new /datum/research/biogenerator(src) + stored_research = new /datum/techweb/specialized/autounlocking/biogenerator create_reagents(1000) /obj/machinery/biogenerator/Destroy() @@ -78,7 +78,7 @@ if(default_deconstruction_screwdriver(user, "biogen-empty-o", "biogen-empty", O)) if(beaker) var/obj/item/reagent_containers/glass/B = beaker - B.loc = loc + B.forceMove(drop_location()) beaker = null update_icon() return @@ -124,7 +124,7 @@ to_chat(user, "You empty the plant bag into the biogenerator, filling it to its capacity.") else to_chat(user, "You fill the biogenerator to its capacity.") - return 1 //no afterattack + return TRUE //no afterattack else if(istype(O, /obj/item/reagent_containers/food/snacks/grown)) var/i = 0 @@ -135,7 +135,7 @@ else if(user.transferItemToLoc(O, src)) to_chat(user, "You put [O.name] in [src.name]") - return 1 //no afterattack + return TRUE //no afterattack else if (istype(O, /obj/item/disk/design_disk)) user.visible_message("[user] begins to load \the [O] in \the [src]...", "You begin to load a design from \the [O]...", @@ -145,9 +145,9 @@ if(do_after(user, 10, target = src)) for(var/B in D.blueprints) if(B) - files.AddDesign2Known(B) + stored_research.add_design(B) processing = FALSE - return 1 + return TRUE else to_chat(user, "You cannot put this in [src.name]!") @@ -176,8 +176,8 @@ var/categories = show_categories.Copy() for(var/V in categories) categories[V] = list() - for(var/V in files.known_designs) - var/datum/design/D = files.known_designs[V] + for(var/V in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[V] for(var/C in categories) if(C in D.category) categories[C] += D @@ -237,16 +237,16 @@ /obj/machinery/biogenerator/proc/check_cost(list/materials, multiplier = 1, remove_points = 1) if(materials.len != 1 || materials[1] != MAT_BIOMASS) - return 0 + return FALSE if (materials[MAT_BIOMASS]*multiplier/efficiency > points) menustat = "nopoints" - return 0 + return FALSE else if(remove_points) points -= materials[MAT_BIOMASS]*multiplier/efficiency update_icon() updateUsrDialog() - return 1 + return TRUE /obj/machinery/biogenerator/proc/check_container_volume(list/reagents, multiplier = 1) var/sum_reagents = 0 @@ -256,19 +256,19 @@ if(beaker.reagents.total_volume + sum_reagents > beaker.reagents.maximum_volume) menustat = "nobeakerspace" - return 0 + return FALSE - return 1 + return TRUE /obj/machinery/biogenerator/proc/create_product(datum/design/D, amount) if(!beaker || !loc) - return 0 + return FALSE if(ispath(D.build_path, /obj/item/stack)) if(!check_container_volume(D.make_reagents, amount)) - return 0 + return FALSE if(!check_cost(D.materials, amount)) - return 0 + return FALSE var/obj/item/stack/product = new D.build_path(loc) product.amount = amount diff --git a/code/modules/hydroponics/gene_modder.dm b/code/modules/hydroponics/gene_modder.dm index bd0215138a..87c860b50e 100644 --- a/code/modules/hydroponics/gene_modder.dm +++ b/code/modules/hydroponics/gene_modder.dm @@ -42,7 +42,7 @@ for(var/obj/item/stock_parts/micro_laser/ML in component_parts) var/wratemod = ML.rating * 2.5 - min_wrate = Floor(10-wratemod,1) // 7,5,2,0 Clamps at 0 and 10 You want this low + min_wrate = FLOOR(10-wratemod,1) // 7,5,2,0 Clamps at 0 and 10 You want this low min_wchance = 67-(ML.rating*16) // 48,35,19,3 Clamps at 0 and 67 You want this low for(var/obj/item/circuitboard/machine/plantgenes/vaultcheck in component_parts) if(istype(vaultcheck, /obj/item/circuitboard/machine/plantgenes/vault)) // DUMB BOTANY TUTS @@ -260,7 +260,7 @@ if(href_list["eject_seed"] && !operation) if (seed) - seed.loc = src.loc + seed.forceMove(drop_location()) seed.verb_pickup() seed = null update_genes() @@ -275,7 +275,7 @@ update_icon() else if(href_list["eject_disk"] && !operation) if (disk) - disk.loc = src.loc + disk.forceMove(drop_location()) disk.verb_pickup() disk = null update_genes() @@ -368,7 +368,7 @@ /obj/machinery/plantgenes/proc/insert_seed(obj/item/seeds/S) if(!istype(S) || seed) return - S.loc = src + S.forceMove(src) seed = S update_genes() update_icon() diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index d5cac19f32..15456c1e34 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -15,7 +15,7 @@ // Saves us from having to define each stupid grown's dried_type as itself. // If you don't want a plant to be driable (watermelons) set this to null in the time definition. resistance_flags = FLAMMABLE - origin_tech = "biotech=1" + var/dry_grind = FALSE //If TRUE, this object needs to be dry to be ground up /obj/item/reagent_containers/food/snacks/grown/Initialize(mapload, obj/item/seeds/new_seed) . = ..() @@ -37,7 +37,7 @@ for(var/datum/plant_gene/trait/T in seed.genes) 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! + transform *= TRANSFORM_USING_VARIABLE(seed.potency, 100) + 0.5 //Makes the resulting produce's sprite larger or smaller based on potency! add_juice() @@ -138,6 +138,28 @@ return return ..() +/obj/item/reagent_containers/food/snacks/grown/grind_requirements() + if(dry_grind && !dry) + to_chat(usr, "[src] needs to be dry before it can be ground up!") + return + return TRUE + +/obj/item/reagent_containers/food/snacks/grown/on_grind() + var/nutriment = reagents.get_reagent_amount("nutriment") + if(grind_results.len) + for(var/i in 1 to grind_results.len) + grind_results[grind_results[i]] = nutriment + reagents.del_reagent("nutriment") + reagents.del_reagent("vitamin") + +/obj/item/reagent_containers/food/snacks/grown/on_juice() + var/nutriment = reagents.get_reagent_amount("nutriment") + if(juice_results.len) + for(var/i in 1 to juice_results.len) + juice_results[juice_results[i]] = nutriment + reagents.del_reagent("nutriment") + reagents.del_reagent("vitamin") + // For item-containing growns such as eggy or gatfruit /obj/item/reagent_containers/food/snacks/grown/shell/attack_self(mob/user) var/obj/item/T diff --git a/code/modules/hydroponics/grown/ambrosia.dm b/code/modules/hydroponics/grown/ambrosia.dm index c083e508ba..4f24c19d6e 100644 --- a/code/modules/hydroponics/grown/ambrosia.dm +++ b/code/modules/hydroponics/grown/ambrosia.dm @@ -30,7 +30,6 @@ seed = /obj/item/seeds/ambrosia name = "ambrosia vulgaris branch" desc = "This is a plant containing various healing chemicals." - origin_tech = "biotech=2" // Ambrosia Deus /obj/item/seeds/ambrosia/deus @@ -50,7 +49,6 @@ desc = "Eating this makes you feel immortal!" icon_state = "ambrosiadeus" filling_color = "#008B8B" - origin_tech = "biotech=4;materials=3" //Ambrosia Gaia /obj/item/seeds/ambrosia/gaia @@ -72,6 +70,5 @@ desc = "Eating this makes you immortal." icon_state = "ambrosia_gaia" filling_color = rgb(255, 175, 0) - origin_tech = "biotech=6;materials=5" light_range = 3 seed = /obj/item/seeds/ambrosia/gaia diff --git a/code/modules/hydroponics/grown/apple.dm b/code/modules/hydroponics/grown/apple.dm index c70c0cd8f6..8b35fee872 100644 --- a/code/modules/hydroponics/grown/apple.dm +++ b/code/modules/hydroponics/grown/apple.dm @@ -15,6 +15,7 @@ genes = list(/datum/plant_gene/trait/repeated_harvest) mutatelist = list(/obj/item/seeds/apple/gold) reagents_add = list("vitamin" = 0.04, "nutriment" = 0.1) + juice_results = list("applejuice" = 0) /obj/item/reagent_containers/food/snacks/grown/apple seed = /obj/item/seeds/apple @@ -56,4 +57,3 @@ desc = "Emblazoned upon the apple is the word 'Kallisti'." icon_state = "goldapple" filling_color = "#FFD700" - origin_tech = "biotech=4;materials=5" diff --git a/code/modules/hydroponics/grown/banana.dm b/code/modules/hydroponics/grown/banana.dm index a78416b6cc..72517e87bc 100644 --- a/code/modules/hydroponics/grown/banana.dm +++ b/code/modules/hydroponics/grown/banana.dm @@ -13,6 +13,7 @@ genes = list(/datum/plant_gene/trait/slip, /datum/plant_gene/trait/repeated_harvest) mutatelist = list(/obj/item/seeds/banana/mime, /obj/item/seeds/banana/bluespace) reagents_add = list("banana" = 0.1, "potassium" = 0.1, "vitamin" = 0.04, "nutriment" = 0.02) + juice_results = list("banana" = 0) /obj/item/reagent_containers/food/snacks/grown/banana seed = /obj/item/seeds/banana @@ -107,7 +108,6 @@ item_state = "bluespace_peel" trash = /obj/item/grown/bananapeel/bluespace filling_color = "#0000FF" - origin_tech = "biotech=3;bluespace=5" /obj/item/grown/bananapeel/bluespace seed = /obj/item/seeds/banana/bluespace diff --git a/code/modules/hydroponics/grown/beans.dm b/code/modules/hydroponics/grown/beans.dm index 8ca2a5961a..46a7e7979f 100644 --- a/code/modules/hydroponics/grown/beans.dm +++ b/code/modules/hydroponics/grown/beans.dm @@ -26,6 +26,7 @@ filling_color = "#F0E68C" bitesize_mod = 2 foodtype = VEGETABLES + grind_results = list("soymilk" = 0) // Koibean /obj/item/seeds/soya/koi diff --git a/code/modules/hydroponics/grown/berries.dm b/code/modules/hydroponics/grown/berries.dm index 8670cb1016..541fb1b2a5 100644 --- a/code/modules/hydroponics/grown/berries.dm +++ b/code/modules/hydroponics/grown/berries.dm @@ -26,6 +26,7 @@ filling_color = "#FF00FF" bitesize_mod = 2 foodtype = FRUIT + juice_results = list("berryjuice" = 0) // Poison Berries /obj/item/seeds/berry/poison @@ -46,6 +47,7 @@ icon_state = "poisonberrypile" filling_color = "#C71585" foodtype = FRUIT | TOXIC + juice_results = list("poisonberryjuice" = 0) // Death Berries /obj/item/seeds/berry/death @@ -90,7 +92,6 @@ desc = "Nutritious!" icon_state = "glowberrypile" filling_color = "#7CFC00" - origin_tech = "plasmatech=6" foodtype = FRUIT // Cherries @@ -122,6 +123,7 @@ filling_color = "#FF0000" bitesize_mod = 2 foodtype = FRUIT + grind_results = list("cherryjelly" = 0) // Blue Cherries /obj/item/seeds/cherry/blue @@ -143,6 +145,7 @@ filling_color = "#6495ED" bitesize_mod = 2 foodtype = FRUIT + grind_results = list("bluecherryjelly" = 0) // Grapes /obj/item/seeds/grape @@ -174,6 +177,7 @@ filling_color = "#FF1493" bitesize_mod = 2 foodtype = FRUIT + juice_results = list("grapejuice" = 0) // Green Grapes /obj/item/seeds/grape/green diff --git a/code/modules/hydroponics/grown/cereals.dm b/code/modules/hydroponics/grown/cereals.dm index 7834ed15e8..d9b724d052 100644 --- a/code/modules/hydroponics/grown/cereals.dm +++ b/code/modules/hydroponics/grown/cereals.dm @@ -22,6 +22,7 @@ filling_color = "#F0E68C" bitesize_mod = 2 foodtype = GRAIN + grind_results = list("flour" = 0) // Oat /obj/item/seeds/wheat/oat @@ -42,6 +43,7 @@ filling_color = "#556B2F" bitesize_mod = 2 foodtype = GRAIN + grind_results = list("flour" = 0) // Rice /obj/item/seeds/wheat/rice @@ -63,6 +65,7 @@ filling_color = "#FAFAD2" bitesize_mod = 2 foodtype = GRAIN + grind_results = list("rice" = 0) //Meatwheat - grows into synthetic meat /obj/item/seeds/wheat/meat @@ -83,6 +86,7 @@ bitesize_mod = 2 seed = /obj/item/seeds/wheat/meat foodtype = MEAT | GRAIN + grind_results = list("flour" = 0, "blood" = 0) /obj/item/reagent_containers/food/snacks/grown/meatwheat/attack_self(mob/living/user) user.visible_message("[user] crushes [src] into meat.", "You crush [src] into something that resembles meat.") diff --git a/code/modules/hydroponics/grown/chili.dm b/code/modules/hydroponics/grown/chili.dm index 40f158d36d..382efa2a26 100644 --- a/code/modules/hydroponics/grown/chili.dm +++ b/code/modules/hydroponics/grown/chili.dm @@ -49,7 +49,6 @@ icon_state = "icepepper" filling_color = "#0000CD" bitesize_mod = 2 - origin_tech = "biotech=4" foodtype = VEGETABLES // Ghost Chili @@ -76,7 +75,6 @@ var/mob/living/carbon/human/held_mob filling_color = "#F8F8FF" bitesize_mod = 4 - origin_tech = "biotech=4;magnets=5" foodtype = VEGETABLES /obj/item/reagent_containers/food/snacks/grown/ghost_chili/attack_hand(mob/user) diff --git a/code/modules/hydroponics/grown/citrus.dm b/code/modules/hydroponics/grown/citrus.dm index 1b0cdc00d2..38f8a40ec3 100644 --- a/code/modules/hydroponics/grown/citrus.dm +++ b/code/modules/hydroponics/grown/citrus.dm @@ -30,6 +30,7 @@ desc = "It's so sour, your face will twist." icon_state = "lime" filling_color = "#00FF00" + juice_results = list("limejuice" = 0) // Orange /obj/item/seeds/orange @@ -56,6 +57,7 @@ desc = "It's a tangy fruit." icon_state = "orange" filling_color = "#FFA500" + juice_results = list("orangejuice" = 0) // Lemon /obj/item/seeds/lemon @@ -81,6 +83,7 @@ desc = "When life gives you lemons, make lemonade." icon_state = "lemon" filling_color = "#FFD700" + juice_results = list("lemonjuice" = 0) // Combustible lemon /obj/item/seeds/firelemon //combustible lemon is too long so firelemon diff --git a/code/modules/hydroponics/grown/corn.dm b/code/modules/hydroponics/grown/corn.dm index 827deaea47..4454c3c52a 100644 --- a/code/modules/hydroponics/grown/corn.dm +++ b/code/modules/hydroponics/grown/corn.dm @@ -25,6 +25,7 @@ trash = /obj/item/grown/corncob bitesize_mod = 2 foodtype = VEGETABLES + juice_results = list("corn_starch" = 0) /obj/item/grown/corncob name = "corn cob" diff --git a/code/modules/hydroponics/grown/flowers.dm b/code/modules/hydroponics/grown/flowers.dm index e0845ffb2a..18eae2f4fd 100644 --- a/code/modules/hydroponics/grown/flowers.dm +++ b/code/modules/hydroponics/grown/flowers.dm @@ -182,6 +182,7 @@ throw_speed = 1 throw_range = 3 attack_verb = list("roasted", "scorched", "burned") + grind_results = list("capsaicin" = 0, "condensedcapsaicin" = 0) /obj/item/grown/novaflower/add_juice() ..() diff --git a/code/modules/hydroponics/grown/melon.dm b/code/modules/hydroponics/grown/melon.dm index 027832de5e..a64fc4b156 100644 --- a/code/modules/hydroponics/grown/melon.dm +++ b/code/modules/hydroponics/grown/melon.dm @@ -14,6 +14,13 @@ mutatelist = list(/obj/item/seeds/watermelon/holy) reagents_add = list("water" = 0.2, "vitamin" = 0.04, "nutriment" = 0.2) +/obj/item/seeds/watermelon/suicide_act(mob/user) + user.visible_message("[user] is swallowing [src]! It looks like [user.p_theyre()] trying to commit suicide!") + user.gib() + new product(drop_location()) + qdel(src) + return MANUAL_SUICIDE + /obj/item/reagent_containers/food/snacks/grown/watermelon seed = /obj/item/seeds/watermelon name = "watermelon" @@ -26,6 +33,7 @@ filling_color = "#008000" bitesize_mod = 3 foodtype = FRUIT + juice_results = list("watermelonjuice" = 0) // Holymelon /obj/item/seeds/watermelon/holy diff --git a/code/modules/hydroponics/grown/misc.dm b/code/modules/hydroponics/grown/misc.dm index c65d0a3606..461a2cd74e 100644 --- a/code/modules/hydroponics/grown/misc.dm +++ b/code/modules/hydroponics/grown/misc.dm @@ -108,7 +108,6 @@ name = "gatfruit" desc = "It smells like burning." icon_state = "gatfruit" - origin_tech = "combat=6" trash = /obj/item/gun/ballistic/revolver bitesize_mod = 2 foodtype = FRUIT diff --git a/code/modules/hydroponics/grown/mushrooms.dm b/code/modules/hydroponics/grown/mushrooms.dm index 8ea7e65684..7e0178b140 100644 --- a/code/modules/hydroponics/grown/mushrooms.dm +++ b/code/modules/hydroponics/grown/mushrooms.dm @@ -79,7 +79,6 @@ growing_icon = 'icons/obj/hydroponics/growing_mushrooms.dmi' reagents_add = list("mushroomhallucinogen" = 0.04, "amatoxin" = 0.1, "nutriment" = 0, "amanitin" = 0.2) rarity = 30 - origin_tech = "biotech=5" /obj/item/reagent_containers/food/snacks/grown/mushroom/angel seed = /obj/item/seeds/angel @@ -163,7 +162,6 @@ desc = "Plumus Locomotus: The beginning of the great walk." icon_state = "walkingmushroom" filling_color = "#9370DB" - origin_tech = "biotech=4;programming=5" /obj/item/reagent_containers/food/snacks/grown/mushroom/walkingmushroom/attack_self(mob/user) if(isspaceturf(user.loc)) @@ -233,7 +231,6 @@ icon_state = "glowshroom" filling_color = "#00FA9A" var/effect_path = /obj/structure/glowshroom - origin_tech = "biotech=4;plasmatech=6" /obj/item/reagent_containers/food/snacks/grown/mushroom/glowshroom/attack_self(mob/user) if(isspaceturf(user.loc)) @@ -280,7 +277,6 @@ icon_state = "glowcap" filling_color = "#00FA9A" effect_path = /obj/structure/glowshroom/glowcap - origin_tech = "biotech=4;powerstorage=6;plasmatech=4" //Shadowshroom @@ -304,7 +300,6 @@ desc = "Mycena Umbra: This species of mushroom emits shadow instead of light." icon_state = "shadowshroom" effect_path = /obj/structure/glowshroom/shadowshroom - origin_tech = "biotech=4;plasmatech=4;magnets=4" /obj/item/reagent_containers/food/snacks/grown/mushroom/glowshroom/shadowshroom/attack_self(mob/user) . = ..() diff --git a/code/modules/hydroponics/grown/nettle.dm b/code/modules/hydroponics/grown/nettle.dm index 485ab6bfd8..9ec936c1f2 100644 --- a/code/modules/hydroponics/grown/nettle.dm +++ b/code/modules/hydroponics/grown/nettle.dm @@ -42,8 +42,8 @@ w_class = WEIGHT_CLASS_TINY throw_speed = 1 throw_range = 3 - origin_tech = "combat=3" attack_verb = list("stung") + grind_results = list("sacid" = 0) /obj/item/grown/nettle/suicide_act(mob/user) user.visible_message("[user] is eating some of [src]! It looks like [user.p_theyre()] trying to commit suicide!") @@ -92,7 +92,7 @@ icon_state = "deathnettle" force = 30 throwforce = 15 - origin_tech = "combat=5" + grind_results = list("facid" = 1, "sacid" = 1) /obj/item/grown/nettle/death/add_juice() ..() diff --git a/code/modules/hydroponics/grown/potato.dm b/code/modules/hydroponics/grown/potato.dm index 0a3cbc060c..e127b166ea 100644 --- a/code/modules/hydroponics/grown/potato.dm +++ b/code/modules/hydroponics/grown/potato.dm @@ -17,6 +17,7 @@ genes = list(/datum/plant_gene/trait/battery) mutatelist = list(/obj/item/seeds/potato/sweet) reagents_add = list("vitamin" = 0.04, "nutriment" = 0.1) + juice_results = list("potato" = 0) /obj/item/reagent_containers/food/snacks/grown/potato seed = /obj/item/seeds/potato diff --git a/code/modules/hydroponics/grown/pumpkin.dm b/code/modules/hydroponics/grown/pumpkin.dm index d5257aeee7..7113a8feab 100644 --- a/code/modules/hydroponics/grown/pumpkin.dm +++ b/code/modules/hydroponics/grown/pumpkin.dm @@ -24,6 +24,7 @@ filling_color = "#FFA500" bitesize_mod = 2 foodtype = VEGETABLES + juice_results = list("pumpkinjuice" = 0) /obj/item/reagent_containers/food/snacks/grown/pumpkin/attackby(obj/item/W as obj, mob/user as mob, params) if(W.is_sharp()) @@ -53,4 +54,5 @@ icon_state = "blumpkin" filling_color = "#87CEFA" bitesize_mod = 2 - foodtype = VEGETABLES \ No newline at end of file + foodtype = VEGETABLES + juice_results = list("blumpkinjuice" = 0) diff --git a/code/modules/hydroponics/grown/random.dm b/code/modules/hydroponics/grown/random.dm index 4ba2451a5a..8f25eff215 100644 --- a/code/modules/hydroponics/grown/random.dm +++ b/code/modules/hydroponics/grown/random.dm @@ -16,9 +16,9 @@ randomize_stats() ..() if(prob(60)) - add_random_reagents() + add_random_reagents(1, 3) if(prob(50)) - add_random_traits() + add_random_traits(1, 2) add_random_plant_type(35) /obj/item/reagent_containers/food/snacks/grown/random diff --git a/code/modules/hydroponics/grown/root.dm b/code/modules/hydroponics/grown/root.dm index 8666db45a8..fd78fa6ffa 100644 --- a/code/modules/hydroponics/grown/root.dm +++ b/code/modules/hydroponics/grown/root.dm @@ -22,6 +22,7 @@ filling_color = "#FFA500" bitesize_mod = 2 foodtype = VEGETABLES + juice_results = list("carrotjuice" = 0) /obj/item/reagent_containers/food/snacks/grown/carrot/attackby(obj/item/I, mob/user, params) if(I.is_sharp()) diff --git a/code/modules/hydroponics/grown/tea_coffee.dm b/code/modules/hydroponics/grown/tea_coffee.dm index bd3b182c13..fc2ed221c5 100644 --- a/code/modules/hydroponics/grown/tea_coffee.dm +++ b/code/modules/hydroponics/grown/tea_coffee.dm @@ -14,7 +14,6 @@ icon_dead = "tea-dead" genes = list(/datum/plant_gene/trait/repeated_harvest) mutatelist = list(/obj/item/seeds/tea/astra) - reagents_add = list("vitamin" = 0.04, "teapowder" = 0.1) /obj/item/reagent_containers/food/snacks/grown/tea seed = /obj/item/seeds/tea @@ -22,6 +21,8 @@ desc = "These aromatic tips of the tea plant can be dried to make tea." icon_state = "tea_aspera_leaves" filling_color = "#008000" + grind_results = list("teapowder" = 0) + dry_grind = TRUE // Tea Astra /obj/item/seeds/tea/astra @@ -39,6 +40,7 @@ name = "Tea Astra tips" icon_state = "tea_astra_leaves" filling_color = "#4582B4" + grind_results = list("teapowder" = 0, "salglu_solution" = 0) // Coffee @@ -67,6 +69,8 @@ icon_state = "coffee_arabica" filling_color = "#DC143C" bitesize_mod = 2 + dry_grind = TRUE + grind_results = list("coffeepowder" = 0) // Coffee Robusta /obj/item/seeds/coffee/robusta @@ -84,4 +88,5 @@ seed = /obj/item/seeds/coffee/robusta name = "coffee robusta beans" desc = "Increases robustness by 37 percent!" - icon_state = "coffee_robusta" \ No newline at end of file + icon_state = "coffee_robusta" + grind_results = list("coffeepowder" = 0, "morphine" = 0) diff --git a/code/modules/hydroponics/grown/tomato.dm b/code/modules/hydroponics/grown/tomato.dm index 5e33d93b28..4d066e769e 100644 --- a/code/modules/hydroponics/grown/tomato.dm +++ b/code/modules/hydroponics/grown/tomato.dm @@ -23,6 +23,8 @@ filling_color = "#FF6347" bitesize_mod = 2 foodtype = VEGETABLES + grind_results = list("ketchup" = 0) + juice_results = list("tomatojuice" = 0) // Blood Tomato /obj/item/seeds/tomato/blood @@ -43,8 +45,9 @@ icon_state = "bloodtomato" splat_type = /obj/effect/gibspawner/generic filling_color = "#FF0000" - origin_tech = "biotech=5" foodtype = VEGETABLES | GROSS + grind_results = list("ketchup" = 0, "blood" = 0) + // Blue Tomato /obj/item/seeds/tomato/blue @@ -89,7 +92,6 @@ name = "bluespace tomato" desc = "So lubricated, you might slip through space-time." icon_state = "bluespacetomato" - origin_tech = "biotech=4;bluespace=5" // Killer Tomato @@ -116,7 +118,6 @@ icon_state = "killertomato" var/awakening = 0 filling_color = "#FF0000" - origin_tech = "biotech=4;combat=5" /obj/item/reagent_containers/food/snacks/grown/tomato/killer/attack(mob/M, mob/user, def_zone) if(awakening) diff --git a/code/modules/hydroponics/grown/towercap.dm b/code/modules/hydroponics/grown/towercap.dm index 168c929ed3..1a3db5ef03 100644 --- a/code/modules/hydroponics/grown/towercap.dm +++ b/code/modules/hydroponics/grown/towercap.dm @@ -40,7 +40,6 @@ w_class = WEIGHT_CLASS_NORMAL throw_speed = 2 throw_range = 3 - origin_tech = "materials=1" attack_verb = list("bashed", "battered", "bludgeoned", "whacked") var/plank_type = /obj/item/stack/sheet/mineral/wood var/plank_name = "wooden planks" @@ -155,8 +154,8 @@ if(!click_params || !click_params["icon-x"] || !click_params["icon-y"]) return //Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf) - W.pixel_x = Clamp(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2) - W.pixel_y = Clamp(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2) + W.pixel_x = CLAMP(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2) + W.pixel_y = CLAMP(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2) else return ..() diff --git a/code/modules/hydroponics/growninedible.dm b/code/modules/hydroponics/growninedible.dm index a77808f006..1c53f296cc 100644 --- a/code/modules/hydroponics/growninedible.dm +++ b/code/modules/hydroponics/growninedible.dm @@ -28,7 +28,7 @@ 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) + transform *= TRANSFORM_USING_VARIABLE(seed.potency, 100) + 0.5 add_juice() @@ -62,3 +62,7 @@ /obj/item/grown/microwave_act(obj/machine/microwave/M) return + +/obj/item/grown/on_grind() + for(var/i in 1 to grind_results.len) + grind_results[grind_results[i]] = round(seed.potency) diff --git a/code/modules/hydroponics/hydroitemdefines.dm b/code/modules/hydroponics/hydroitemdefines.dm index cbb22bfa15..c72d9e5c28 100644 --- a/code/modules/hydroponics/hydroitemdefines.dm +++ b/code/modules/hydroponics/hydroitemdefines.dm @@ -9,7 +9,6 @@ righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' w_class = WEIGHT_CLASS_TINY slot_flags = SLOT_BELT - origin_tech = "magnets=2;biotech=2" materials = list(MAT_METAL=30, MAT_GLASS=20) // ************************************* @@ -25,12 +24,6 @@ lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi' volume = 100 - container_type = OPENCONTAINER_1 - slot_flags = SLOT_BELT - throwforce = 0 - w_class = WEIGHT_CLASS_SMALL - throw_speed = 3 - throw_range = 10 /obj/item/reagent_containers/spray/weedspray/Initialize() . = ..() @@ -49,12 +42,6 @@ lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi' volume = 100 - container_type = OPENCONTAINER_1 - slot_flags = SLOT_BELT - throwforce = 0 - w_class = WEIGHT_CLASS_SMALL - throw_speed = 3 - throw_range = 10 /obj/item/reagent_containers/spray/pestspray/Initialize() . = ..() @@ -72,7 +59,6 @@ item_state = "cultivator" lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi' - origin_tech = "engineering=2;biotech=2" flags_1 = CONDUCT_1 force = 5 throwforce = 7 @@ -96,7 +82,6 @@ throw_speed = 3 throw_range = 4 materials = list(MAT_METAL = 15000) - origin_tech = "materials=2;combat=2" attack_verb = list("chopped", "torn", "cut") hitsound = 'sound/weapons/bladeslice.ogg' sharpness = IS_SHARP @@ -120,7 +105,6 @@ flags_1 = CONDUCT_1 armour_penetration = 20 slot_flags = SLOT_BACK - origin_tech = "materials=3;combat=2" attack_verb = list("chopped", "sliced", "cut", "reaped") hitsound = 'sound/weapons/bladeslice.ogg' var/swiping = FALSE diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index 9eafcec71b..c46fb92feb 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -108,7 +108,7 @@ var/needs_update = 0 // Checks if the icon needs updating so we don't redraw empty trays every time if(myseed && (myseed.loc != src)) - myseed.loc = src + myseed.forceMove(src) if(self_sustaining) adjustNutri(1) @@ -712,8 +712,8 @@ else if(transfer_amount) // Droppers, cans, beakers, what have you. visi_msg="[user] uses [reagent_source] on [target]" irrigate = 1 - // Beakers, bottles, buckets, etc. Can't use is_open_container though. - if(istype(reagent_source, /obj/item/reagent_containers/glass/)) + // Beakers, bottles, buckets, etc. + if(reagent_source.is_drainable()) playsound(loc, 'sound/effects/slosh.ogg', 25, 1) if(irrigate && transfer_amount > 30 && reagent_source.reagents.total_volume >= 30 && using_irrigation) @@ -881,26 +881,26 @@ /// Tray Setters - The following procs adjust the tray or plants variables, and make sure that the stat doesn't go out of bounds./// /obj/machinery/hydroponics/proc/adjustNutri(adjustamt) - nutrilevel = Clamp(nutrilevel + adjustamt, 0, maxnutri) + nutrilevel = CLAMP(nutrilevel + adjustamt, 0, maxnutri) /obj/machinery/hydroponics/proc/adjustWater(adjustamt) - waterlevel = Clamp(waterlevel + adjustamt, 0, maxwater) + waterlevel = CLAMP(waterlevel + adjustamt, 0, maxwater) if(adjustamt>0) adjustToxic(-round(adjustamt/4))//Toxicity dilutation code. The more water you put in, the lesser the toxin concentration. /obj/machinery/hydroponics/proc/adjustHealth(adjustamt) if(myseed && !dead) - plant_health = Clamp(plant_health + adjustamt, 0, myseed.endurance) + plant_health = CLAMP(plant_health + adjustamt, 0, myseed.endurance) /obj/machinery/hydroponics/proc/adjustToxic(adjustamt) - toxic = Clamp(toxic + adjustamt, 0, 100) + toxic = CLAMP(toxic + adjustamt, 0, 100) /obj/machinery/hydroponics/proc/adjustPests(adjustamt) - pestlevel = Clamp(pestlevel + adjustamt, 0, 10) + pestlevel = CLAMP(pestlevel + adjustamt, 0, 10) /obj/machinery/hydroponics/proc/adjustWeeds(adjustamt) - weedlevel = Clamp(weedlevel + adjustamt, 0, 10) + weedlevel = CLAMP(weedlevel + adjustamt, 0, 10) /obj/machinery/hydroponics/proc/spawnplant() // why would you put strange reagent in a hydro tray you monster I bet you also feed them blood var/list/livingplants = list(/mob/living/simple_animal/hostile/tree, /mob/living/simple_animal/hostile/killertomato) diff --git a/code/modules/hydroponics/plant_genes.dm b/code/modules/hydroponics/plant_genes.dm index c6e17a63a4..54333ea35f 100644 --- a/code/modules/hydroponics/plant_genes.dm +++ b/code/modules/hydroponics/plant_genes.dm @@ -137,7 +137,6 @@ /datum/plant_gene/trait var/rate = 0.05 var/examine_line = "" - var/list/origin_tech = null var/trait_id // must be set and equal for any two traits of the same type /datum/plant_gene/trait/Copy() @@ -157,19 +156,7 @@ return TRUE /datum/plant_gene/trait/proc/on_new(obj/item/reagent_containers/food/snacks/grown/G, newloc) - if(!origin_tech) // This ugly code segment adds RnD tech levels to resulting plants. - return - - if(G.origin_tech) - var/list/tech = params2list(G.origin_tech) - for(var/t in origin_tech) - if(t in tech) - tech[t] = max(text2num(tech[t]), origin_tech[t]) - else - tech[t] = origin_tech[t] - G.origin_tech = list2params(tech) - else - G.origin_tech = list2params(origin_tech) + return /datum/plant_gene/trait/proc/on_consume(obj/item/reagent_containers/food/snacks/grown/G, mob/living/carbon/target) return @@ -195,7 +182,6 @@ // For code, see grown.dm name = "Liquid Contents" examine_line = "It has a lot of liquid contents inside." - origin_tech = list("biotech" = 5) /datum/plant_gene/trait/slip // Makes plant slippery, unless it has a grown-type trash. Then the trash gets slippery. @@ -229,7 +215,6 @@ // Multiplies max charge by (rate*1000) when used in potato power cells. name = "Electrical Activity" rate = 0.2 - origin_tech = list("powerstorage" = 5) /datum/plant_gene/trait/cell_charge/on_slip(obj/item/reagent_containers/food/snacks/grown/G, mob/living/carbon/C) var/power = G.seed.potency*rate @@ -304,7 +289,6 @@ // Teleport radius is calculated as max(round(potency*rate), 1) name = "Bluespace Activity" rate = 0.1 - origin_tech = list("bluespace" = 5) /datum/plant_gene/trait/teleport/on_squash(obj/item/reagent_containers/food/snacks/grown/G, atom/target) if(isliving(target)) @@ -375,7 +359,7 @@ pocell.maxcharge *= CG.rate*1000 pocell.charge = pocell.maxcharge pocell.name = "[G.name] battery" - pocell.desc = "A rechargeable plant based power cell. This one has a power rating of [DisplayPower(pocell.maxcharge)], and you should not swallow it." + pocell.desc = "A rechargeable plant-based power cell. This one has a rating of [DisplayEnergy(pocell.maxcharge)], and you should not swallow it." if(G.reagents.has_reagent("plasma", 2)) pocell.rigged = 1 diff --git a/code/modules/hydroponics/seed_extractor.dm b/code/modules/hydroponics/seed_extractor.dm index 0899a21132..b79d0652aa 100644 --- a/code/modules/hydroponics/seed_extractor.dm +++ b/code/modules/hydroponics/seed_extractor.dm @@ -17,7 +17,7 @@ return while(t_amount < t_max) var/obj/item/seeds/t_prod = F.seed.Copy() - t_prod.loc = seedloc + t_prod.forceMove(seedloc) t_amount++ qdel(O) return 1 @@ -29,7 +29,7 @@ return while(t_amount < t_max) var/obj/item/seeds/t_prod = F.seed.Copy() - t_prod.loc = seedloc + t_prod.forceMove(seedloc) t_amount++ qdel(O) return 1 @@ -168,7 +168,7 @@ for (var/obj/T in contents)//Now we find the seed we need to vend var/obj/item/seeds/O = T if (O.plantname == href_list["name"] && O.lifespan == href_list["li"] && O.endurance == href_list["en"] && O.maturation == href_list["ma"] && O.production == href_list["pr"] && O.yield == href_list["yi"] && O.potency == href_list["pot"]) - O.loc = src.loc + O.forceMove(drop_location()) break src.updateUsrDialog() diff --git a/code/modules/hydroponics/seeds.dm b/code/modules/hydroponics/seeds.dm index aa35b4ae07..56f80c548d 100644 --- a/code/modules/hydroponics/seeds.dm +++ b/code/modules/hydroponics/seeds.dm @@ -170,7 +170,7 @@ /// Setters procs /// /obj/item/seeds/proc/adjust_yield(adjustamt) if(yield != -1) // Unharvestable shouldn't suddenly turn harvestable - yield = Clamp(yield + adjustamt, 0, 10) + yield = CLAMP(yield + adjustamt, 0, 10) if(yield <= 0 && get_gene(/datum/plant_gene/trait/plant_type/fungal_metabolism)) yield = 1 // Mushrooms always have a minimum yield of 1. @@ -179,39 +179,39 @@ C.value = yield /obj/item/seeds/proc/adjust_lifespan(adjustamt) - lifespan = Clamp(lifespan + adjustamt, 10, 100) + lifespan = CLAMP(lifespan + adjustamt, 10, 100) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/lifespan) if(C) C.value = lifespan /obj/item/seeds/proc/adjust_endurance(adjustamt) - endurance = Clamp(endurance + adjustamt, 10, 100) + endurance = CLAMP(endurance + adjustamt, 10, 100) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/endurance) if(C) C.value = endurance /obj/item/seeds/proc/adjust_production(adjustamt) if(yield != -1) - production = Clamp(production + adjustamt, 1, 10) + production = CLAMP(production + adjustamt, 1, 10) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/production) if(C) C.value = production /obj/item/seeds/proc/adjust_potency(adjustamt) if(potency != -1) - potency = Clamp(potency + adjustamt, 0, 100) + potency = CLAMP(potency + adjustamt, 0, 100) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/potency) if(C) C.value = potency /obj/item/seeds/proc/adjust_weed_rate(adjustamt) - weed_rate = Clamp(weed_rate + adjustamt, 0, 10) + weed_rate = CLAMP(weed_rate + adjustamt, 0, 10) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/weed_rate) if(C) C.value = weed_rate /obj/item/seeds/proc/adjust_weed_chance(adjustamt) - weed_chance = Clamp(weed_chance + adjustamt, 0, 67) + weed_chance = CLAMP(weed_chance + adjustamt, 0, 67) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/weed_chance) if(C) C.value = weed_chance @@ -220,7 +220,7 @@ /obj/item/seeds/proc/set_yield(adjustamt) if(yield != -1) // Unharvestable shouldn't suddenly turn harvestable - yield = Clamp(adjustamt, 0, 10) + yield = CLAMP(adjustamt, 0, 10) if(yield <= 0 && get_gene(/datum/plant_gene/trait/plant_type/fungal_metabolism)) yield = 1 // Mushrooms always have a minimum yield of 1. @@ -229,39 +229,39 @@ C.value = yield /obj/item/seeds/proc/set_lifespan(adjustamt) - lifespan = Clamp(adjustamt, 10, 100) + lifespan = CLAMP(adjustamt, 10, 100) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/lifespan) if(C) C.value = lifespan /obj/item/seeds/proc/set_endurance(adjustamt) - endurance = Clamp(adjustamt, 10, 100) + endurance = CLAMP(adjustamt, 10, 100) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/endurance) if(C) C.value = endurance /obj/item/seeds/proc/set_production(adjustamt) if(yield != -1) - production = Clamp(adjustamt, 1, 10) + production = CLAMP(adjustamt, 1, 10) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/production) if(C) C.value = production /obj/item/seeds/proc/set_potency(adjustamt) if(potency != -1) - potency = Clamp(adjustamt, 0, 100) + potency = CLAMP(adjustamt, 0, 100) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/potency) if(C) C.value = potency /obj/item/seeds/proc/set_weed_rate(adjustamt) - weed_rate = Clamp(adjustamt, 0, 10) + weed_rate = CLAMP(adjustamt, 0, 10) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/weed_rate) if(C) C.value = weed_rate /obj/item/seeds/proc/set_weed_chance(adjustamt) - weed_chance = Clamp(adjustamt, 0, 67) + weed_chance = CLAMP(adjustamt, 0, 67) var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/weed_chance) if(C) C.value = weed_chance diff --git a/code/modules/integrated_electronics/core/analyzer.dm b/code/modules/integrated_electronics/core/analyzer.dm index 02b8c88acc..0166f9bce7 100644 --- a/code/modules/integrated_electronics/core/analyzer.dm +++ b/code/modules/integrated_electronics/core/analyzer.dm @@ -1,7 +1,7 @@ /obj/item/device/integrated_electronics/analyzer name = "circuit analyzer" desc = "This tool can scan an assembly and generate code necessary to recreate it in a circuit printer." - icon = 'icons/obj/electronic_assemblies.dmi' + icon = 'icons/obj/assemblies/electronic_tools.dmi' icon_state = "analyzer" flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_SMALL diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm index 6f552e1df4..805cf787f7 100644 --- a/code/modules/integrated_electronics/core/assemblies.dm +++ b/code/modules/integrated_electronics/core/assemblies.dm @@ -5,10 +5,11 @@ name = "electronic assembly" desc = "It's a case, for building small electronics with." w_class = WEIGHT_CLASS_SMALL - icon = 'icons/obj/electronic_assemblies.dmi' + icon = 'icons/obj/assemblies/electronic_setups.dmi' icon_state = "setup_small" flags_1 = NOBLUDGEON_1 materials = list() // To be filled later + var/list/assembly_components = list() var/max_components = IC_MAX_SIZE_BASE var/max_complexity = IC_COMPLEXITY_BASE var/opened = FALSE @@ -40,11 +41,12 @@ /obj/item/device/electronic_assembly/proc/handle_idle_power() // First we generate power. - for(var/obj/item/integrated_circuit/passive/power/P in contents) + for(var/obj/item/integrated_circuit/passive/power/P in assembly_components) P.make_energy() // Now spend it. - for(var/obj/item/integrated_circuit/IC in contents) + for(var/I in assembly_components) + var/obj/item/integrated_circuit/IC = I if(IC.power_draw_idle) if(!draw_power(IC.power_draw_idle)) IC.power_fail() @@ -59,8 +61,8 @@ var/HTML = "" HTML += "[name]" - HTML += "
    \[Refresh\] | " - HTML += "\[Rename\]
    " + + HTML += "\[Refresh\] | \[Rename\]
    " HTML += "[total_part_size]/[max_components] ([round((total_part_size / max_components) * 100, 0.1)]%) space taken up in the assembly.
    " HTML += "[total_complexity]/[max_complexity] ([round((total_complexity / max_complexity) * 100, 0.1)]%) maximum complexity.
    " if(battery) @@ -73,16 +75,14 @@ HTML += "Components:" - var/list/components = return_all_components() var/builtin_components = "" - for(var/c in components) + for(var/c in assembly_components) var/obj/item/integrated_circuit/circuit = c if(!circuit.removable) - builtin_components += "[circuit.displayed_name] | " - builtin_components += "\[Rename\] | " - builtin_components += "\[Scan with Debugger\] | " - builtin_components += "\[Move to Bottom\]" + builtin_components += "[circuit.displayed_name] | " + builtin_components += "\[Rename\] | " + builtin_components += "\[Scan with Debugger\]" builtin_components += "
    " // Put removable circuits (if any) in separate categories from non-removable @@ -95,14 +95,17 @@ HTML += "
    " - for(var/c in components) + for(var/c in assembly_components) var/obj/item/integrated_circuit/circuit = c if(circuit.removable) - HTML += "[circuit.displayed_name] | " - HTML += "\[Rename\] | " - HTML += "\[Scan with Debugger\] | " - HTML += "\[Remove\] | " - HTML += "\[Move to Bottom\]" + HTML += "[circuit.displayed_name] | " + HTML += "\[Rename\] | " + HTML += "\[Scan with Debugger\] | " + HTML += "\[Remove\] | " + HTML += " " + HTML += " " + HTML += " " + HTML += "" HTML += "
    " HTML += "" @@ -119,12 +122,51 @@ if(!battery) to_chat(usr, "There's no power cell to remove from \the [src].") else - var/turf/T = get_turf(src) - battery.forceMove(T) - playsound(T, 'sound/items/Crowbar.ogg', 50, 1) + battery.forceMove(drop_location()) + playsound(src, 'sound/items/Crowbar.ogg', 50, 1) to_chat(usr, "You pull \the [battery] out of \the [src]'s power supplier.") battery = null + if(href_list["component"]) + var/obj/item/integrated_circuit/component = locate(href_list["component"]) in assembly_components + if(component) + // Builtin components are not supposed to be removed or rearranged + if(!component.removable) + return + + var/current_pos = assembly_components.Find(component) + + // Find the position of a first removable component + var/first_removable_pos + for(var/i in 1 to assembly_components.len) + var/obj/item/integrated_circuit/temp_component = assembly_components[i] + if(temp_component.removable) + first_removable_pos = i + break + + if(href_list["remove"]) + try_remove_component(component, usr) + + else + // Adjust the position + if(href_list["up"]) + current_pos-- + else if(href_list["down"]) + current_pos++ + else if(href_list["top"]) + current_pos = first_removable_pos + else if(href_list["bottom"]) + current_pos = assembly_components.len + + // Wrap around nicely + if(current_pos < first_removable_pos) + current_pos = assembly_components.len + else if(current_pos > assembly_components.len) + current_pos = first_removable_pos + + assembly_components.Remove(component) + assembly_components.Insert(current_pos, component) + interact(usr) // To refresh the UI. /obj/item/device/electronic_assembly/proc/rename() @@ -142,9 +184,6 @@ /obj/item/device/electronic_assembly/proc/can_move() return FALSE -/obj/item/device/electronic_assembly/drone/can_move() - return TRUE - /obj/item/device/electronic_assembly/update_icon() if(opened) icon_state = initial(icon_state) + "-open" @@ -153,32 +192,28 @@ /obj/item/device/electronic_assembly/examine(mob/user) ..() - for(var/obj/item/integrated_circuit/IC in contents) + for(var/I in assembly_components) + var/obj/item/integrated_circuit/IC = I IC.external_examine(user) - if(istype(IC,/obj/item/integrated_circuit/output/screen)) - var/obj/item/integrated_circuit/output/screen/S - if(S.stuff_to_display) - to_chat(user, "There's a little screen labeled '[S]', which displays '[S.stuff_to_display]'.") if(opened) interact(user) /obj/item/device/electronic_assembly/proc/return_total_complexity() . = 0 - for(var/obj/item/integrated_circuit/part in contents) + var/obj/item/integrated_circuit/part + for(var/p in assembly_components) + part = p . += part.complexity /obj/item/device/electronic_assembly/proc/return_total_size() . = 0 - for(var/obj/item/integrated_circuit/part in contents) + var/obj/item/integrated_circuit/part + for(var/p in assembly_components) + part = p . += part.size -/obj/item/device/electronic_assembly/proc/return_all_components() - . = list() - for(var/obj/item/integrated_circuit/part in contents) - . += part - // Returns true if the circuit made it inside. -/obj/item/device/electronic_assembly/proc/add_circuit(var/obj/item/integrated_circuit/IC, var/mob/user) +/obj/item/device/electronic_assembly/proc/try_add_component(obj/item/integrated_circuit/IC, mob/user) if(!opened) to_chat(user, "\The [src]'s hatch is closed, you can't put anything inside.") return FALSE @@ -200,12 +235,45 @@ if(!user.transferItemToLoc(IC, src)) return FALSE - IC.assembly = src + to_chat(user, "You slide [IC] inside [src].") + playsound(src, 'sound/items/Deconstruct.ogg', 50, 1) + add_component(IC) return TRUE + +// Actually puts the circuit inside, doesn't perform any checks. +/obj/item/device/electronic_assembly/proc/add_component(obj/item/integrated_circuit/component) + component.forceMove(get_object()) + component.assembly = src + assembly_components |= component + + +/obj/item/device/electronic_assembly/proc/try_remove_component(obj/item/integrated_circuit/IC, mob/user) + if(!opened) + to_chat(user, "[src]'s hatch is closed, so you can't fiddle with the internal components.") + return FALSE + + if(!IC.removable) + to_chat(user, "[src] is permanently attached to the case.") + return FALSE + + to_chat(user, "You pop \the [src] out of the case, and slide it out.") + playsound(src, 'sound/items/Crowbar.ogg', 50, 1) + + remove_component(IC) + return TRUE + +// Actually removes the component, doesn't perform any checks. +/obj/item/device/electronic_assembly/proc/remove_component(obj/item/integrated_circuit/component) + component.disconnect_all() + component.forceMove(drop_location()) + component.assembly = null + assembly_components.Remove(component) + + /obj/item/device/electronic_assembly/afterattack(atom/target, mob/user, proximity) - for(var/obj/item/integrated_circuit/input/sensor/S in contents) + for(var/obj/item/integrated_circuit/input/sensor/S in assembly_components) if(!proximity) if(istype(S,/obj/item/integrated_circuit/input/sensor/ranged)||(!user)) if(user.client) @@ -234,12 +302,10 @@ if(istype(I, /obj/item/integrated_circuit)) if(!user.canUnEquip(I)) return FALSE - if(add_circuit(I, user)) - to_chat(user, "You slide [I] inside [src].") - playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) + if(try_add_component(I, user)) interact(user) return TRUE - else if(istype(I, /obj/item/device/integrated_electronics/wirer) || istype(I, /obj/item/device/integrated_electronics/debugger)) + else if(istype(I, /obj/item/device/multitool) || istype(I, /obj/item/device/integrated_electronics/wirer) || istype(I, /obj/item/device/integrated_electronics/debugger)) if(opened) interact(user) else @@ -270,7 +336,7 @@ var/list/input_selection = list() var/list/available_inputs = list() - for(var/obj/item/integrated_circuit/input/input in contents) + for(var/obj/item/integrated_circuit/input/input in assembly_components) if(input.can_be_asked_input) available_inputs.Add(input) var/i = 0 @@ -316,12 +382,44 @@ return FALSE /obj/item/device/electronic_assembly/Moved(oldLoc, dir) - for(var/obj/item/integrated_circuit/IC in contents) + for(var/I in assembly_components) + var/obj/item/integrated_circuit/IC = I IC.ext_moved(oldLoc, dir) +// Returns the object that is supposed to be used in attack messages, location checks, etc. +// Override in children for special behavior. +/obj/item/device/electronic_assembly/proc/get_object() + return src +// Returns the location to be used for dropping items. +// Same as the regular drop_location(), but with checks being run on acting_object if necessary. +/obj/item/integrated_circuit/drop_location() + var/atom/movable/acting_object = get_object() + // plz no infinite loops + if(acting_object == src) + return ..() + + return acting_object.drop_location() + +/obj/item/device/electronic_assembly/default //The /default electronic_assemblys are to allow the introduction of the new naming scheme without breaking old saves. + name = "type-a electronic assembly" + +/obj/item/device/electronic_assembly/calc + name = "type-b electronic assembly" + icon_state = "setup_small_calc" + desc = "It's a case, for building small electronics with. This one resembles a pocket calculator." + +/obj/item/device/electronic_assembly/clam + name = "type-c electronic assembly" + icon_state = "setup_small_clam" + desc = "It's a case, for building small electronics with. This one has a clamshell design." + +/obj/item/device/electronic_assembly/simple + name = "type-d electronic assembly" + icon_state = "setup_small_simple" + desc = "It's a case, for building small electronics with. This one has a simple design." /obj/item/device/electronic_assembly/medium name = "electronic mechanism" @@ -331,6 +429,24 @@ max_components = IC_MAX_SIZE_BASE * 2 max_complexity = IC_COMPLEXITY_BASE * 2 +/obj/item/device/electronic_assembly/medium/default + name = "type-a electronic mechanism" + +/obj/item/device/electronic_assembly/medium/box + name = "type-b electronic mechanism" + icon_state = "setup_medium_box" + desc = "It's a case, for building medium-sized electronics with. This one has a boxy design." + +/obj/item/device/electronic_assembly/medium/clam + name = "type-c electronic mechanism" + icon_state = "setup_medium_clam" + desc = "It's a case, for building medium-sized electronics with. This one has a clamshell design." + +/obj/item/device/electronic_assembly/medium/medical + name = "type-d electronic mechanism" + icon_state = "setup_medium_med" + desc = "It's a case, for building medium-sized electronics with. This one resembles some type of medical apparatus." + /obj/item/device/electronic_assembly/large name = "electronic machine" icon_state = "setup_large" @@ -356,6 +472,24 @@ return ..() +/obj/item/device/electronic_assembly/large/default + name = "type-a electronic machine" + +/obj/item/device/electronic_assembly/large/scope + name = "type-b electronic machine" + icon_state = "setup_large_scope" + desc = "It's a case, for building large electronics with. This one resembles an oscilloscope." + +/obj/item/device/electronic_assembly/large/terminal + name = "type-c electronic machine" + icon_state = "setup_large_terminal" + desc = "It's a case, for building large electronics with. This one resembles a computer terminal." + +/obj/item/device/electronic_assembly/large/arm + name = "type-d electronic machine" + icon_state = "setup_large_arm" + desc = "It's a case, for building large electronics with. This one resembles a robotic arm." + /obj/item/device/electronic_assembly/drone name = "electronic drone" icon_state = "setup_drone" @@ -363,3 +497,14 @@ w_class = WEIGHT_CLASS_SMALL max_components = IC_MAX_SIZE_BASE * 3 max_complexity = IC_COMPLEXITY_BASE * 3 + +/obj/item/device/electronic_assembly/drone/can_move() + return TRUE + +/obj/item/device/electronic_assembly/drone/default + name = "type-a electronic drone" + +/obj/item/device/electronic_assembly/drone/arms + name = "type-b electronic drone" + icon_state = "setup_drone_arms" + desc = "It's a case, for building mobile electronics with. This one is armed and dangerous." \ No newline at end of file diff --git a/code/modules/integrated_electronics/core/debugger.dm b/code/modules/integrated_electronics/core/debugger.dm index 7dc89178d2..ac6f5c1a1e 100644 --- a/code/modules/integrated_electronics/core/debugger.dm +++ b/code/modules/integrated_electronics/core/debugger.dm @@ -1,10 +1,8 @@ - - /obj/item/device/integrated_electronics/debugger name = "circuit debugger" desc = "This small tool allows one working with custom machinery to directly set data to a specific pin, useful for writing \ settings to specific circuits, or for debugging purposes. It can also pulse activation pins." - icon = 'icons/obj/electronic_assemblies.dmi' + icon = 'icons/obj/assemblies/electronic_tools.dmi' icon_state = "debugger" flags_1 = CONDUCT_1 | NOBLUDGEON_1 w_class = WEIGHT_CLASS_SMALL @@ -20,7 +18,7 @@ switch(type_to_use) if("string") accepting_refs = FALSE - new_data = stripped_input(user, "Now type in a string.","[src] string writing") + new_data = stripped_input(user, "Now type in a string.","[src] string writing", no_trim = TRUE) if(istext(new_data) && user.IsAdvancedToolUser()) data_to_write = new_data to_chat(user, "You set \the [src]'s memory to \"[new_data]\".") diff --git a/code/modules/integrated_electronics/core/helpers.dm b/code/modules/integrated_electronics/core/helpers.dm index 04137a4d05..e84823f201 100644 --- a/code/modules/integrated_electronics/core/helpers.dm +++ b/code/modules/integrated_electronics/core/helpers.dm @@ -54,21 +54,6 @@ return activators[pin_number] return -/obj/item/integrated_circuit/proc/handle_wire(var/datum/integrated_io/pin, var/obj/item/device/integrated_electronics/tool) - if(istype(tool, /obj/item/device/integrated_electronics/wirer)) - var/obj/item/device/integrated_electronics/wirer/wirer = tool - if(pin) - wirer.wire(pin, usr) - return TRUE - - else if(istype(tool, /obj/item/device/integrated_electronics/debugger)) - var/obj/item/device/integrated_electronics/debugger/debugger = tool - if(pin) - debugger.write_data(pin, usr) - return TRUE - return FALSE - - /datum/integrated_io/proc/get_data() if(isweakref(data)) return data.resolve() @@ -76,7 +61,7 @@ // Returns a list of parameters necessary to locate a pin in the assembly: component number, pin type and pin number -// Components list can be supplied from the outside, for use in savefiles or for extra performance if you are calling this multiple times +// Components list can be supplied from the outside, for use in savefiles /datum/integrated_io/proc/get_pin_parameters(list/components) if(!holder) return @@ -84,7 +69,7 @@ if(!components) if(!holder.assembly) return - components = holder.assembly.return_all_components() + components = holder.assembly.assembly_components var/component_number = components.Find(holder) @@ -105,10 +90,10 @@ // Locates a pin in the assembly when given component number, pin type and pin number -// Components list can be supplied from the outside, for use in savefiles or for extra performance if you are calling this multiple times +// Components list can be supplied from the outside, for use in savefiles /obj/item/device/electronic_assembly/proc/get_pin_ref(component_number, pin_type, pin_number, list/components) if(!components) - components = return_all_components() + components = assembly_components if(component_number > components.len) return @@ -120,6 +105,9 @@ // Same as get_pin_ref, but takes in a list of 3 parameters (same format as get_pin_parameters) // and performs extra sanity checks on parameters list and index numbers /obj/item/device/electronic_assembly/proc/get_pin_ref_list(list/parameters, list/components) + if(!components) + components = assembly_components + if(!islist(parameters) || parameters.len != 3) return diff --git a/code/modules/integrated_electronics/core/integrated_circuit.dm b/code/modules/integrated_electronics/core/integrated_circuit.dm index 042e93a2aa..069ca4245c 100644 --- a/code/modules/integrated_electronics/core/integrated_circuit.dm +++ b/code/modules/integrated_electronics/core/integrated_circuit.dm @@ -1,7 +1,7 @@ /obj/item/integrated_circuit name = "integrated circuit" desc = "It's a tiny chip! This one doesn't seem to do much, however." - icon = 'icons/obj/electronic_assemblies.dmi' + icon = 'icons/obj/assemblies/electronic_components.dmi' icon_state = "template" w_class = WEIGHT_CLASS_TINY materials = list() // To be filled later @@ -22,8 +22,6 @@ var/category_text = "NO CATEGORY THIS IS A BUG" // To show up on circuit printer, and perhaps other places. var/removable = TRUE // Determines if a circuit is removable from the assembly. var/displayed_name = "" - var/allow_multitool = TRUE // Allows additional multitool functionality - // Used as a global var, (Do not set manually in children). /* Integrated circuits are essentially modular machines. Each circuit has a specific function, and combining them inside Electronic Assemblies allows @@ -104,9 +102,11 @@ a creative player the means to solve many problems. Circuits are held inside an if(!check_interactivity(M)) return - var/input = reject_bad_name(stripped_input(M, "What do you want to name this?", "Rename", src.name),1) - if(src && input && check_interactivity(M)) - to_chat(M, "The circuit '[src.name]' is now labeled '[input]'.") + var/input = reject_bad_name(stripped_input(M, "What do you want to name this?", "Rename", name), TRUE) + if(check_interactivity(M)) + if(!input) + input = name + to_chat(M, "The circuit '[name]' is now labeled '[input]'.") displayed_name = input /obj/item/integrated_circuit/interact(mob/user) @@ -124,13 +124,15 @@ a creative player the means to solve many problems. Circuits are held inside an HTML += "
    " HTML += "
    Brothers
    " - HTML += "
    \[Return to Assembly\]" + if(assembly) + HTML += "\[Return to Assembly\]
    " - HTML += "
    \[Refresh\] | " + HTML += "\[Refresh\] | " HTML += "\[Rename\] | " - HTML += "\[Scan with Device\] | " - if(removable) - HTML += "\[Remove\]
    " + HTML += "\[Scan with Device\]" + if(assembly && removable) + HTML += " | \[Remove\]" + HTML += "
    " HTML += "
    " HTML += "" @@ -151,12 +153,13 @@ a creative player the means to solve many problems. Circuits are held inside an if(1) io = get_pin_ref(IC_INPUT, i) if(io) - words += "[io.display_pin_type()] [io.name] [io.display_data(io.data)]
    " + words += "[io.display_pin_type()] [io.name] \ + [io.display_data(io.data)]
    " if(io.linked.len) for(var/k in 1 to io.linked.len) var/datum/integrated_io/linked = io.linked[k] - words += "[linked] \ - @ [linked.holder.displayed_name]
    " + words += "[linked] \ + @ [linked.holder.displayed_name]
    " if(outputs.len > inputs.len) height = 1 @@ -169,12 +172,13 @@ a creative player the means to solve many problems. Circuits are held inside an if(3) io = get_pin_ref(IC_OUTPUT, i) if(io) - words += "[io.display_pin_type()] [io.name] [io.display_data(io.data)]
    " + words += "[io.display_pin_type()] [io.name] \ + [io.display_data(io.data)]
    " if(io.linked.len) for(var/k in 1 to io.linked.len) var/datum/integrated_io/linked = io.linked[k] - words += "[linked] \ - @ [linked.holder.displayed_name]
    " + words += "[linked] \ + @ [linked.holder.displayed_name]
    " if(inputs.len > outputs.len) height = 1 @@ -185,12 +189,13 @@ a creative player the means to solve many problems. Circuits are held inside an var/datum/integrated_io/io = activator var/words = list() - words += "[io] [io.data?"\":"\"]
    " + words += "[io] " + words += "[io.data?"\":"\"]
    " if(io.linked.len) for(var/k in 1 to io.linked.len) var/datum/integrated_io/linked = io.linked[k] - words += "[linked] \ - @ [linked.holder.displayed_name]
    " + words += "[linked] \ + @ [linked.holder.displayed_name]
    " HTML += "
    " HTML += "" @@ -221,80 +226,24 @@ a creative player the means to solve many problems. Circuits are held inside an return TRUE var/update = TRUE - var/obj/item/device/electronic_assembly/A = src.assembly var/update_to_assembly = FALSE - var/datum/integrated_io/pin = locate(href_list["pin"]) in inputs + outputs + activators - var/datum/integrated_io/linked = null - if(href_list["link"]) - linked = locate(href_list["link"]) in pin.linked var/obj/held_item = usr.get_active_held_item() if(href_list["rename"]) rename_component(usr) - if(href_list["from_assembly"]) - update = FALSE - var/obj/item/device/electronic_assembly/ea = loc - if(istype(ea)) - ea.interact(usr) - if(href_list["pin_name"]) - if (!istype(held_item, /obj/item/device/multitool) || !allow_multitool) - href_list["wire"] = TRUE - else - var/obj/item/device/multitool/M = held_item - M.wire(pin,usr) + if(href_list["pin"]) + var/datum/integrated_io/pin = locate(href_list["pin"]) in inputs + outputs + activators + if(pin) + var/datum/integrated_io/linked + if(href_list["link"]) + linked = locate(href_list["link"]) in pin.linked - - - if(href_list["pin_data"]) - if (!istype(held_item, /obj/item/device/multitool) || !allow_multitool) - href_list["wire"] = TRUE - - else - var/datum/integrated_io/io = pin - io.ask_for_pin_data(usr) // The pins themselves will determine how to ask for data, and will validate the data. - - if(href_list["pin_unwire"]) - if (!istype(held_item, /obj/item/device/multitool) || !allow_multitool) - href_list["wire"] = TRUE - else - var/obj/item/device/multitool/M = held_item - M.unwire(pin, linked, usr) - - if(href_list["wire"]) - if(istype(held_item, /obj/item/device/integrated_electronics/wirer)) - var/obj/item/device/integrated_electronics/wirer/wirer = held_item - if(linked) - wirer.wire(linked, usr) - else if(pin) - wirer.wire(pin, usr) - - else if(istype(held_item, /obj/item/device/integrated_electronics/debugger)) - var/obj/item/device/integrated_electronics/debugger/debugger = held_item - if(pin) - debugger.write_data(pin, usr) - else - to_chat(usr, "You can't do a whole lot without the proper tools.") - - if(href_list["examine"]) - var/obj/item/integrated_circuit/examined - if(href_list["examined"]) - examined = href_list["examined"] - else - examined = src - examined.interact(usr) - update = FALSE - - if(href_list["bottom"]) - var/obj/item/integrated_circuit/circuit = locate(href_list["bottom"]) in src.assembly.contents - var/assy = circuit.assembly - if(!circuit) - return - circuit.loc = null - circuit.loc = assy - . = TRUE - update_to_assembly = TRUE + if(istype(held_item, /obj/item/device/integrated_electronics) || istype(held_item, /obj/item/device/multitool)) + pin.handle_wire(linked, held_item, href_list["act"], usr) + else + to_chat(usr, "You can't do a whole lot without the proper tools.") if(href_list["scan"]) if(istype(held_item, /obj/item/device/integrated_electronics/debugger)) @@ -304,39 +253,15 @@ a creative player the means to solve many problems. Circuits are held inside an else to_chat(usr, "The debugger's 'ref scanner' needs to be on.") else - to_chat(usr, "You need a multitool/debugger set to 'ref' mode to do that.") + to_chat(usr, "You need a debugger set to 'ref' mode to do that.") if(href_list["return"]) - if(A) - update_to_assembly = TRUE - usr << browse(null, "window=circuit-[REF(src)];border=1;can_resize=1;can_close=1;can_minimize=1") - else - to_chat(usr, "This circuit is not in an assembly!") + update_to_assembly = TRUE - if(href_list["remove"]) - if(!A) - to_chat(usr, "This circuit is not in an assembly!") - return - if(!removable) - to_chat(usr, "\The [src] seems to be permanently attached to the case.") - return - var/obj/item/device/electronic_assembly/ea = loc - disconnect_all() - var/turf/T = get_turf(src) - forceMove(T) - assembly = null - playsound(T, 'sound/items/Crowbar.ogg', 50, 1) - to_chat(usr, "You pop \the [src] out of the case, and slide it out.") - - if(istype(ea)) - ea.interact(usr) - update = FALSE - return - if(update) - if(A && istype(A) && update_to_assembly) - A.interact(usr) + if(assembly && update_to_assembly) + assembly.interact(usr) else interact(usr) // To refresh the UI. @@ -384,18 +309,64 @@ a creative player the means to solve many problems. Circuits are held inside an for(var/i in inputs) I = i - I.disconnect() + I.disconnect_all() for(var/i in outputs) I = i - I.disconnect() + I.disconnect_all() for(var/i in activators) I = i - I.disconnect() + I.disconnect_all() /obj/item/integrated_circuit/proc/ext_moved(oldLoc, dir) return +// Returns the object that is supposed to be used in attack messages, location checks, etc. +/obj/item/integrated_circuit/proc/get_object() + // If the component is located in an assembly, let assembly determine it. + if(assembly) + return assembly.get_object() + else + return src // If not, the component is acting on its own. + + +// Returns the location to be used for dropping items. +// Same as the regular drop_location(), but with proc being run on assembly if there is any. +/obj/item/integrated_circuit/drop_location() + // If the component is located in an assembly, let the assembly figure that one out. + if(assembly) + return assembly.drop_location() + else + return ..() // If not, the component is acting on its own. + + +// Checks if the target object is reachable. Useful for various manipulators and manipulator-like objects. +/obj/item/integrated_circuit/proc/check_target(atom/target, exclude_contents = FALSE, exclude_components = FALSE, exclude_self = FALSE) + if(!target) + return FALSE + + var/atom/movable/acting_object = get_object() + + if(exclude_self && target == acting_object) + return FALSE + + if(exclude_components && assembly) + if(target in assembly.assembly_components) + return FALSE + + if(target == assembly.battery) + return FALSE + + if(target.Adjacent(acting_object) && isturf(target.loc)) + return TRUE + + if(!exclude_contents && (target in acting_object.GetAllContents())) + return TRUE + + if(target in acting_object.loc) + return TRUE + + return FALSE diff --git a/code/modules/integrated_electronics/core/pins.dm b/code/modules/integrated_electronics/core/pins.dm index 25ef3b80b8..bff96b713c 100644 --- a/code/modules/integrated_electronics/core/pins.dm +++ b/code/modules/integrated_electronics/core/pins.dm @@ -40,7 +40,7 @@ D [1]/ || message_admins("ERROR: An integrated_io ([name]) spawned without a valid holder! This is a bug.") /datum/integrated_io/Destroy() - disconnect() + disconnect_all() data = null holder = null return ..() @@ -102,7 +102,36 @@ D [1]/ || /datum/integrated_io/activate/scramble() push_data() -/datum/integrated_io/proc/write_data_to_pin(var/new_data) +/datum/integrated_io/proc/handle_wire(datum/integrated_io/linked_pin, obj/item/tool, action, mob/living/user) + if(istype(tool, /obj/item/device/multitool)) + var/obj/item/device/multitool/multitool = tool + switch(action) + if("wire") + multitool.wire(src, user) + return TRUE + if("unwire") + if(linked_pin) + multitool.unwire(src, linked_pin, user) + return TRUE + if("data") + ask_for_pin_data(user) + return TRUE + + else if(istype(tool, /obj/item/device/integrated_electronics/wirer)) + var/obj/item/device/integrated_electronics/wirer/wirer = tool + if(linked_pin) + wirer.wire(linked_pin, user) + else + wirer.wire(src, user) + + else if(istype(tool, /obj/item/device/integrated_electronics/debugger)) + var/obj/item/device/integrated_electronics/debugger/debugger = tool + debugger.write_data(src, user) + return TRUE + + return FALSE + +/datum/integrated_io/proc/write_data_to_pin(new_data) if(isnull(new_data) || isnum(new_data) || istext(new_data) || isweakref(new_data)) data = new_data holder.on_data_written() @@ -131,21 +160,20 @@ D [1]/ || return "the [english_list(linked)]" return "nothing" -/datum/integrated_io/proc/disconnect() - //First we iterate over everything we are linked to. - if(linked && linked.len) - for(var/i in 1 to linked.len) - var/datum/integrated_io/their_io = linked[i] - //While doing that, we iterate them as well, and disconnect ourselves from them. - if(their_io.linked.len && their_io.linked) - for(var/j in 1 to their_io.linked.len) - var/datum/integrated_io/their_linked_io = their_io.linked[j] - if(their_linked_io == src) - their_io.linked.Remove(src) - else - continue - //Now that we're removed from them, we gotta remove them from us. - linked.Remove(their_io) + +/datum/integrated_io/proc/connect_pin(datum/integrated_io/pin) + pin.linked |= src + linked |= pin + +// Iterates over every linked pin and disconnects them. +/datum/integrated_io/proc/disconnect_all() + for(var/pin in linked) + disconnect_pin(pin) + +/datum/integrated_io/proc/disconnect_pin(datum/integrated_io/pin) + pin.linked.Remove(src) + linked.Remove(pin) + /datum/integrated_io/proc/ask_for_data_type(mob/user, var/default, var/list/allowed_data_types = list("string","number","null")) var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in allowed_data_types @@ -155,7 +183,7 @@ D [1]/ || var/new_data = null switch(type_to_use) if("string") - new_data = stripped_input(user, "Now type in a string.","[src] string writing", istext(default) ? default : null) + new_data = stripped_input(user, "Now type in a string.","[src] string writing", istext(default) ? default : null, no_trim = TRUE) if(istext(new_data) && holder.check_interactivity(user) ) to_chat(user, "You input "+new_data+" into the pin.") return new_data diff --git a/code/modules/integrated_electronics/core/printer.dm b/code/modules/integrated_electronics/core/printer.dm index 89a0e2b213..15f76281ef 100644 --- a/code/modules/integrated_electronics/core/printer.dm +++ b/code/modules/integrated_electronics/core/printer.dm @@ -1,7 +1,7 @@ /obj/item/device/integrated_circuit_printer name = "integrated circuit printer" desc = "A portable(ish) machine made to print tiny modular circuitry out of metal." - icon = 'icons/obj/electronic_assemblies.dmi' + icon = 'icons/obj/assemblies/electronic_tools.dmi' icon_state = "circuit_printer" w_class = WEIGHT_CLASS_BULKY var/upgraded = TRUE // When hit with an upgrade disk, will turn true, allowing it to print the higher tier circuits. @@ -27,6 +27,7 @@ return TRUE to_chat(user, "You install \the [O] into \the [src]. ") upgraded = TRUE + qdel(O) interact(user) return TRUE @@ -36,6 +37,7 @@ return TRUE to_chat(user, "You install \the [O] into \the [src]. ") can_clone = TRUE + qdel(O) interact(user) return TRUE @@ -108,16 +110,13 @@ if(!build_type || !ispath(build_type)) return TRUE - var/cost = 1 + var/cost = 400 if(ispath(build_type, /obj/item/device/electronic_assembly)) - var/obj/item/device/electronic_assembly/E = build_type - cost = round( (initial(E.max_complexity) + initial(E.max_components) ) / 4) + var/obj/item/device/electronic_assembly/E = SScircuit.cached_assemblies[build_type] + cost = E.materials[MAT_METAL] else if(ispath(build_type, /obj/item/integrated_circuit)) - var/obj/item/integrated_circuit/IC = build_type - cost = initial(IC.w_class) - - - cost *= SScircuit.cost_multiplier + var/obj/item/integrated_circuit/IC = SScircuit.cached_components[build_type] + cost = IC.materials[MAT_METAL] var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) @@ -125,7 +124,12 @@ to_chat(usr, "You need [cost] metal to build that!") return TRUE - new build_type(get_turf(loc)) + var/obj/item/built = new build_type(drop_location()) + + if(istype(built, /obj/item/device/electronic_assembly)) + var/obj/item/device/electronic_assembly/E = built + E.opened = TRUE + E.update_icon() if(href_list["print"]) if(!CONFIG_GET(flag/ic_printing)) @@ -179,11 +183,10 @@ /obj/item/disk/integrated_circuit/upgrade name = "integrated circuit printer upgrade disk" desc = "Install this into your integrated circuit printer to enhance it." - icon = 'icons/obj/electronic_assemblies.dmi' + icon = 'icons/obj/assemblies/electronic_tools.dmi' icon_state = "upgrade_disk" item_state = "card-id" w_class = WEIGHT_CLASS_SMALL - origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 4) /obj/item/disk/integrated_circuit/upgrade/advanced name = "integrated circuit printer upgrade disk - advanced designs" @@ -194,4 +197,3 @@ name = "integrated circuit printer upgrade disk - circuit cloner" desc = "Install this into your integrated circuit printer to enhance it. This one allows the printer to duplicate assemblies." icon_state = "upgrade_disk_clone" - origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 5) diff --git a/code/modules/integrated_electronics/core/saved_circuits.dm b/code/modules/integrated_electronics/core/saved_circuits.dm index cbbe58f16d..34abff9a1f 100644 --- a/code/modules/integrated_electronics/core/saved_circuits.dm +++ b/code/modules/integrated_electronics/core/saved_circuits.dm @@ -23,6 +23,8 @@ // Don't waste space saving the default values if(input.data == inputs_default["[index]"]) continue + if(input.data == initial(input.data)) + continue var/list/input_value = list(index, FALSE, input.data) // Index, Type, Value @@ -91,15 +93,13 @@ //var/input_type = input[2] var/input_value = input[3] - var/datum/integrated_io/IO = inputs[index] - IO.write_data_to_pin(input_value) - // write_data_to_pin includes all the value sanity checks you'll ever need + var/datum/integrated_io/pin = inputs[index] + // The pins themselves validate the data. + pin.write_data_to_pin(input_value) // TODO: support for special input types, such as internal refs and maybe typepaths - - // Saves type and modified name (if any) to a list // The list is converted to JSON down the line. /obj/item/device/electronic_assembly/proc/save() @@ -144,10 +144,8 @@ // Attempts to save an assembly into a save file format. // Returns null if assembly is not complete enough to be saved. /datum/controller/subsystem/processing/circuit/proc/save_electronic_assembly(obj/item/device/electronic_assembly/assembly) - var/list/assembly_components = assembly.return_all_components() - // No components? Don't even try to save it. - if(!length(assembly_components)) + if(!length(assembly.assembly_components)) return @@ -160,7 +158,7 @@ // Block 2. Components. var/list/components = list() - for(var/c in assembly_components) + for(var/c in assembly.assembly_components) var/obj/item/integrated_circuit/component = c components.Add(list(component.save())) blocks["components"] = components @@ -170,18 +168,18 @@ var/list/wires = list() var/list/saved_wires = list() - for(var/c in assembly_components) + for(var/c in assembly.assembly_components) var/obj/item/integrated_circuit/component = c var/list/all_pins = component.inputs + component.outputs + component.activators for(var/p in all_pins) var/datum/integrated_io/pin = p - var/list/params = pin.get_pin_parameters(assembly_components) + var/list/params = pin.get_pin_parameters() var/text_params = params.Join() for(var/p2 in pin.linked) var/datum/integrated_io/pin2 = p2 - var/list/params2 = pin2.get_pin_parameters(assembly_components) + var/list/params2 = pin2.get_pin_parameters() var/text_params2 = params2.Join() // Check if we already saved an opposite version of this wire @@ -318,23 +316,20 @@ // Block 2. Components. - var/list/assembly_components = list() for(var/component_params in blocks["components"]) var/obj/item/integrated_circuit/component_path = all_components[component_params["type"]] var/obj/item/integrated_circuit/component = new component_path(assembly) - component.assembly = assembly + assembly.add_component(component) component.load(component_params) - assembly_components.Add(component) // Block 3. Wires. if(blocks["wires"]) for(var/w in blocks["wires"]) var/list/wire = w - var/datum/integrated_io/IO = assembly.get_pin_ref_list(wire[1], assembly_components) - var/datum/integrated_io/IO2 = assembly.get_pin_ref_list(wire[2], assembly_components) - IO.linked |= IO2 - IO2.linked |= IO + var/datum/integrated_io/IO = assembly.get_pin_ref_list(wire[1]) + var/datum/integrated_io/IO2 = assembly.get_pin_ref_list(wire[2]) + IO.connect_pin(IO2) assembly.forceMove(loc) return assembly diff --git a/code/modules/integrated_electronics/core/special_pins/char_pin.dm b/code/modules/integrated_electronics/core/special_pins/char_pin.dm index 1d859f86b5..3e466891eb 100644 --- a/code/modules/integrated_electronics/core/special_pins/char_pin.dm +++ b/code/modules/integrated_electronics/core/special_pins/char_pin.dm @@ -3,7 +3,7 @@ name = "char pin" /datum/integrated_io/char/ask_for_pin_data(mob/user) - var/new_data = stripped_input(user, "Please type in one character.","[src] char writing") + var/new_data = stripped_input(user, "Please type in one character.","[src] char writing", no_trim = TRUE) if(holder.check_interactivity(user) ) to_chat(user, "You input [new_data ? "new_data" : "NULL"] into the pin.") write_data_to_pin(new_data) diff --git a/code/modules/integrated_electronics/core/special_pins/index_pin.dm b/code/modules/integrated_electronics/core/special_pins/index_pin.dm new file mode 100644 index 0000000000..51b12a0f3a --- /dev/null +++ b/code/modules/integrated_electronics/core/special_pins/index_pin.dm @@ -0,0 +1,21 @@ +// These pins can only contain integer numbers between 1 and IC_MAX_LIST_LENGTH. Null is not allowed. +/datum/integrated_io/index + name = "index pin" + data = 1 + +/datum/integrated_io/index/ask_for_pin_data(mob/user) + var/new_data = input("Please type in an index.","[src] index writing") as num + if(isnum(new_data) && holder.check_interactivity(user)) + to_chat(user, "You input [new_data] into the pin.") + write_data_to_pin(new_data) + +/datum/integrated_io/index/write_data_to_pin(new_data) + if(isnull(new_data)) + new_data = 1 + + if(isnum(new_data)) + data = CLAMP(round(new_data), 1, IC_MAX_LIST_LENGTH) + holder.on_data_written() + +/datum/integrated_io/index/display_pin_type() + return IC_FORMAT_INDEX diff --git a/code/modules/integrated_electronics/core/special_pins/list_pin.dm b/code/modules/integrated_electronics/core/special_pins/list_pin.dm index ddf3a48362..8a6f80ea63 100644 --- a/code/modules/integrated_electronics/core/special_pins/list_pin.dm +++ b/code/modules/integrated_electronics/core/special_pins/list_pin.dm @@ -112,6 +112,10 @@ var/list/new_list = new_data data = new_list.Copy(max(1,new_list.len - IC_MAX_LIST_LENGTH+1),0) holder.on_data_written() + else if(isnull(new_data)) // Clear the list + var/list/my_list = data + my_list.Cut() + holder.on_data_written() /datum/integrated_io/lists/display_pin_type() return IC_FORMAT_LIST diff --git a/code/modules/integrated_electronics/core/special_pins/string_pin.dm b/code/modules/integrated_electronics/core/special_pins/string_pin.dm index a619e7450f..49d6aa9554 100644 --- a/code/modules/integrated_electronics/core/special_pins/string_pin.dm +++ b/code/modules/integrated_electronics/core/special_pins/string_pin.dm @@ -3,7 +3,7 @@ name = "string pin" /datum/integrated_io/string/ask_for_pin_data(mob/user) - var/new_data = stripped_input(user, "Please type in a string.","[src] string writing") + var/new_data = stripped_input(user, "Please type in a string.","[src] string writing", no_trim = TRUE) if(holder.check_interactivity(user) ) to_chat(user, "You input [new_data ? "[new_data]" : "NULL"] into the pin.") write_data_to_pin(new_data) diff --git a/code/modules/integrated_electronics/core/wirer.dm b/code/modules/integrated_electronics/core/wirer.dm index c1caba00cd..bfbbfa4864 100644 --- a/code/modules/integrated_electronics/core/wirer.dm +++ b/code/modules/integrated_electronics/core/wirer.dm @@ -8,7 +8,7 @@ desc = "It's a small wiring tool, with a wire roll, electric soldering iron, wire cutter, and more in one package. \ The wires used are generally useful for small electronics, such as circuitboards and breadboards, as opposed to larger wires \ used for power or data transmission." - icon = 'icons/obj/electronic_assemblies.dmi' + icon = 'icons/obj/assemblies/electronic_tools.dmi' icon_state = "wirer-wire" flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_SMALL @@ -38,8 +38,7 @@ if(io.holder.assembly && io.holder.assembly != selected_io.holder.assembly) to_chat(user, "Both \the [io.holder] and \the [selected_io.holder] need to be inside the same assembly.") return - selected_io.linked |= io - io.linked |= selected_io + selected_io.connect_pin(io) to_chat(user, "You connect \the [selected_io.holder]'s [selected_io.name] to \the [io.holder]'s [io.name].") mode = WIRE @@ -64,8 +63,7 @@ the same pin is rather moot.") return if(selected_io in io.linked) - io.linked.Remove(selected_io) - selected_io.linked.Remove(io) + selected_io.disconnect_pin(io) to_chat(user, "You disconnect \the [selected_io.holder]'s [selected_io.name] from \ \the [io.holder]'s [io.name].") selected_io.holder.interact(user) // This is to update the UI. diff --git a/code/modules/integrated_electronics/passive/power.dm b/code/modules/integrated_electronics/passive/power.dm index 7c7439d45b..2acce3d450 100644 --- a/code/modules/integrated_electronics/passive/power.dm +++ b/code/modules/integrated_electronics/passive/power.dm @@ -3,7 +3,6 @@ name = "power thingy" desc = "Does power stuff." complexity = 5 - origin_tech = list(TECH_POWER = 2, TECH_ENGINEERING = 2, TECH_DATA = 2) category_text = "Power - Passive" /obj/item/integrated_circuit/passive/power/proc/make_energy() @@ -13,10 +12,9 @@ /obj/item/integrated_circuit/passive/power/solar_cell name = "tiny photovoltaic cell" desc = "It's a very tiny solar cell, generally used in calculators." - extended_desc = "The cell generates 1W of power per second in optimal lighting conditions. Less light will result in less power being generated." + extended_desc = "The cell generates 1 W of power in optimal lighting conditions. Less light will result in less power being generated." icon_state = "solar_cell" complexity = 8 - origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3, TECH_DATA = 2) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH var/max_power = 30 @@ -35,7 +33,6 @@ icon_state = "led" complexity = 1 activators = list("pulse out" = IC_PINTYPE_PULSE_OUT) - origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3, TECH_DATA = 2) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH var/is_charge = FALSE @@ -60,7 +57,6 @@ from the 'equipment' power channel." icon_state = "power_relay" complexity = 7 - origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3, TECH_DATA = 2) spawn_flags = IC_SPAWN_RESEARCH var/power_amount = 50 @@ -94,13 +90,12 @@ icon_state = "chemical_cell" extended_desc = "This is effectively an internal beaker. It will consume and produce power from plasma, slime jelly, welding fuel, carbon,\ ethanol, nutriments and blood , in order of decreasing efficiency. It will consume fuel only if the battery can take more energy." - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER complexity = 4 inputs = list() outputs = list("volume used" = IC_PINTYPE_NUMBER, "self reference" = IC_PINTYPE_REF) activators = list() spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) var/volume = 60 var/list/fuel = list("plasma" = 10000, "welding_fuel" = 3000, "carbon" = 2000, "ethanol" = 2000, "nutriment" = 1600, "blood" = 1000) diff --git a/code/modules/integrated_electronics/subtypes/converters.dm b/code/modules/integrated_electronics/subtypes/converters.dm index 373a059f45..d622ea8ca9 100644 --- a/code/modules/integrated_electronics/subtypes/converters.dm +++ b/code/modules/integrated_electronics/subtypes/converters.dm @@ -175,6 +175,7 @@ extended_desc = "This circuits splits a given string into two, based on the string, and the index value. \ The index splits the string after the given index, including spaces. So 'a person' with an index of '3' \ will split into 'a p' and 'erson'." + icon_state = "split" complexity = 4 inputs = list( "string to split" = IC_PINTYPE_STRING, @@ -232,6 +233,7 @@ desc = "This splits a single string into a list of strings." extended_desc = "This circuit splits a given string into a list of strings based on the string and given delimiter. \ For example, 'eat this burger',' ' will be converted to list('eat','this','burger')." + icon_state = "split" complexity = 4 inputs = list( "string to split" = IC_PINTYPE_STRING, @@ -245,8 +247,8 @@ /obj/item/integrated_circuit/converter/exploders/do_work() var/strin = get_pin_data(IC_INPUT, 1) - var/sample = get_pin_data(IC_INPUT, 2) - set_pin_data(IC_OUTPUT, 1, splittext( strin ,sample )) + var/delimiter = get_pin_data(IC_INPUT, 2) + set_pin_data(IC_OUTPUT, 1, splittext(strin, delimiter)) push_data() activate_pin(2) @@ -263,7 +265,7 @@ pull_data() var/incoming = get_pin_data(IC_INPUT, 1) if(!isnull(incoming)) - result = ToDegrees(incoming) + result = TODEGREES(incoming) set_pin_data(IC_OUTPUT, 1, result) push_data() @@ -281,7 +283,7 @@ pull_data() var/incoming = get_pin_data(IC_INPUT, 1) if(!isnull(incoming)) - result = ToRadians(incoming) + result = TORADIANS(incoming) set_pin_data(IC_OUTPUT, 1, result) push_data() @@ -318,3 +320,55 @@ push_data() activate_pin(2) + +/obj/item/integrated_circuit/converter/hsv2hex + name = "hsv to hexadecimal" + desc = "This circuit can convert a HSV (Hue, Saturation, and Value) color to a Hexadecimal RGB color." + extended_desc = "The first pin controls tint (0-359), the second pin controls how intense the tint is (0-255), and the third controls how bright the tint is (0 for black, 127 for normal, 255 for white)." + icon_state = "hsv-hex" + inputs = list( + "hue" = IC_PINTYPE_NUMBER, + "saturation" = IC_PINTYPE_NUMBER, + "value" = IC_PINTYPE_NUMBER + ) + outputs = list("hexadecimal rgb" = IC_PINTYPE_COLOR) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/converter/hsv2hex/do_work() + var/result = null + pull_data() + var/hue = get_pin_data(IC_INPUT, 1) + var/saturation = get_pin_data(IC_INPUT, 2) + var/value = get_pin_data(IC_INPUT, 3) + if(isnum(hue)&&isnum(saturation)&&isnum(value)) + result = HSVtoRGB(hsv(AngleToHue(hue),saturation,value)) + + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) + +/obj/item/integrated_circuit/converter/rgb2hex + name = "rgb to hexadecimal" + desc = "This circuit can convert a RGB (Red, Green, Blue) color to a Hexadecimal RGB color." + extended_desc = "The first pin controls red amount, the second pin controls green amount, and the third controls blue amount. All go from 0-255." + icon_state = "rgb-hex" + inputs = list( + "red" = IC_PINTYPE_NUMBER, + "green" = IC_PINTYPE_NUMBER, + "blue" = IC_PINTYPE_NUMBER + ) + outputs = list("hexadecimal rgb" = IC_PINTYPE_COLOR) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/converter/rgb2hex/do_work() + var/result = null + pull_data() + var/red = get_pin_data(IC_INPUT, 1) + var/green = get_pin_data(IC_INPUT, 2) + var/blue = get_pin_data(IC_INPUT, 3) + if(isnum(red)&&isnum(green)&&isnum(blue)) + result = rgb(red,green,blue) + + set_pin_data(IC_OUTPUT, 1, result) + push_data() + activate_pin(2) diff --git a/code/modules/integrated_electronics/subtypes/data_transfer.dm b/code/modules/integrated_electronics/subtypes/data_transfer.dm index d28bb72e33..a769a16768 100644 --- a/code/modules/integrated_electronics/subtypes/data_transfer.dm +++ b/code/modules/integrated_electronics/subtypes/data_transfer.dm @@ -14,15 +14,15 @@ activators = list("select" = IC_PINTYPE_PULSE_IN, "on select" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 4 - var/number_of_inputs = 2 + var/number_of_pins = 2 -/obj/item/integrated_circuit/transfer/multiplexer/New() - for(var/i = 1 to number_of_inputs) +/obj/item/integrated_circuit/transfer/multiplexer/Initialize() + for(var/i = 1 to number_of_pins) inputs["input [i]"] = IC_PINTYPE_ANY // This is just a string since pins don't get built until ..() is called. - complexity = number_of_inputs - ..() - desc += " It has [number_of_inputs] input pins." + complexity = number_of_pins + . = ..() + desc += " It has [number_of_pins] input pins." extended_desc += " This multiplexer has a range from 1 to [inputs.len - 1]." /obj/item/integrated_circuit/transfer/multiplexer/do_work() @@ -35,20 +35,20 @@ /obj/item/integrated_circuit/transfer/multiplexer/medium name = "four multiplexer" - number_of_inputs = 4 icon_state = "mux4" + number_of_pins = 4 /obj/item/integrated_circuit/transfer/multiplexer/large name = "eight multiplexer" - number_of_inputs = 8 w_class = WEIGHT_CLASS_SMALL icon_state = "mux8" + number_of_pins = 8 /obj/item/integrated_circuit/transfer/multiplexer/huge name = "sixteen multiplexer" icon_state = "mux16" w_class = WEIGHT_CLASS_SMALL - number_of_inputs = 16 + number_of_pins = 16 /obj/item/integrated_circuit/transfer/demultiplexer name = "two demultiplexer" @@ -62,16 +62,15 @@ activators = list("select" = IC_PINTYPE_PULSE_IN, "on select" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 4 - var/number_of_outputs = 2 + var/number_of_pins = 2 -/obj/item/integrated_circuit/transfer/demultiplexer/New() - for(var/i = 1 to number_of_outputs) - // outputs += "output [i]" +/obj/item/integrated_circuit/transfer/demultiplexer/Initialize() + for(var/i = 1 to number_of_pins) outputs["output [i]"] = IC_PINTYPE_ANY - complexity = number_of_outputs + complexity = number_of_pins - ..() - desc += " It has [number_of_outputs] output pins." + . = ..() + desc += " It has [number_of_pins] output pins." extended_desc += " This demultiplexer has a range from 1 to [outputs.len]." /obj/item/integrated_circuit/transfer/demultiplexer/do_work() @@ -84,19 +83,19 @@ /obj/item/integrated_circuit/transfer/demultiplexer/medium name = "four demultiplexer" icon_state = "dmux4" - number_of_outputs = 4 + number_of_pins = 4 /obj/item/integrated_circuit/transfer/demultiplexer/large name = "eight demultiplexer" icon_state = "dmux8" w_class = WEIGHT_CLASS_SMALL - number_of_outputs = 8 + number_of_pins = 8 /obj/item/integrated_circuit/transfer/demultiplexer/huge name = "sixteen demultiplexer" icon_state = "dmux16" w_class = WEIGHT_CLASS_SMALL - number_of_outputs = 16 + number_of_pins = 16 /obj/item/integrated_circuit/transfer/pulsedemultiplexer name = "two pulse demultiplexer" @@ -110,37 +109,36 @@ activators = list("select" = IC_PINTYPE_PULSE_IN) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 4 - var/number_of_outputs = 2 + var/number_of_pins = 2 -/obj/item/integrated_circuit/transfer/pulsedemultiplexer/New() - for(var/i = 1 to number_of_outputs) - // outputs += "output [i]" +/obj/item/integrated_circuit/transfer/pulsedemultiplexer/Initialize() + for(var/i = 1 to number_of_pins) activators["output [i]"] = IC_PINTYPE_PULSE_OUT - complexity = number_of_outputs + complexity = number_of_pins - ..() - desc += " It has [number_of_outputs] output pins." + . = ..() + desc += " It has [number_of_pins] output pins." extended_desc += " This pulse demultiplexer has a range from 1 to [activators.len - 1]." /obj/item/integrated_circuit/transfer/pulsedemultiplexer/do_work() var/output_index = get_pin_data(IC_INPUT, 1) - if(output_index == Clamp(output_index, 1, number_of_outputs)) + if(output_index == CLAMP(output_index, 1, number_of_pins)) activate_pin(round(output_index + 1 ,1)) /obj/item/integrated_circuit/transfer/pulsedemultiplexer/medium name = "four pulse demultiplexer" icon_state = "dmux4" - number_of_outputs = 4 + number_of_pins = 4 /obj/item/integrated_circuit/transfer/pulsedemultiplexer/large name = "eight pulse demultiplexer" icon_state = "dmux8" w_class = WEIGHT_CLASS_SMALL - number_of_outputs = 8 + number_of_pins = 8 /obj/item/integrated_circuit/transfer/pulsedemultiplexer/huge name = "sixteen pulse demultiplexer" icon_state = "dmux16" w_class = WEIGHT_CLASS_SMALL - number_of_outputs = 16 \ No newline at end of file + number_of_pins = 16 \ No newline at end of file diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index b579901a2d..c39cfeac44 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -88,7 +88,6 @@ ) activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) power_draw_per_use = 40 /obj/item/integrated_circuit/input/med_scanner/do_work() @@ -123,7 +122,6 @@ ) activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 4) power_draw_per_use = 80 /obj/item/integrated_circuit/input/adv_med_scanner/do_work() @@ -174,7 +172,6 @@ ) activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 4) power_draw_per_use = 10 /obj/item/integrated_circuit/input/plant_scanner/do_work() @@ -248,10 +245,12 @@ /obj/item/integrated_circuit/input/examiner name = "examiner" desc = "It' s a little machine vision system. It can return the name, description, distance, \ - relative coordinates, total amount of reagents, and maximum amount of reagents of the referenced object." + relative coordinates, total amount of reagents, maximum amount of reagents, density and opacity of the referenced object." icon_state = "video_camera" complexity = 6 - inputs = list("\ target" = IC_PINTYPE_REF) + inputs = list( + "target" = IC_PINTYPE_REF + ) outputs = list( "name" = IC_PINTYPE_STRING, "description" = IC_PINTYPE_STRING, @@ -260,10 +259,15 @@ "distance" = IC_PINTYPE_NUMBER, "max reagents" = IC_PINTYPE_NUMBER, "amount of reagents" = IC_PINTYPE_NUMBER, - ) - activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT, "not scanned" = IC_PINTYPE_PULSE_OUT) + "density" = IC_PINTYPE_BOOLEAN, + "opacity" = IC_PINTYPE_BOOLEAN, + ) + activators = list( + "scan" = IC_PINTYPE_PULSE_IN, + "on scanned" = IC_PINTYPE_PULSE_OUT, + "not scanned" = IC_PINTYPE_PULSE_OUT + ) spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 4) power_draw_per_use = 80 /obj/item/integrated_circuit/input/examiner/do_work() @@ -273,8 +277,6 @@ return if(H in view(T)) // This is a camera. It can't examine thngs,that it can't see. - - set_pin_data(IC_OUTPUT, 1, H.name) set_pin_data(IC_OUTPUT, 2, H.desc) set_pin_data(IC_OUTPUT, 3, H.x-T.x) @@ -287,6 +289,8 @@ tr = H.reagents.total_volume set_pin_data(IC_OUTPUT, 6, mr) set_pin_data(IC_OUTPUT, 7, tr) + set_pin_data(IC_OUTPUT, 8, H.density) + set_pin_data(IC_OUTPUT, 9, H.opacity) push_data() activate_pin(2) else @@ -369,7 +373,7 @@ var/rad = get_pin_data(IC_INPUT, 2) if(isnum(rad)) - rad = Clamp(rad, 0, 8) + rad = CLAMP(rad, 0, 8) radius = rad /obj/item/integrated_circuit/input/advanced_locator_list/do_work() @@ -422,7 +426,7 @@ /obj/item/integrated_circuit/input/advanced_locator/on_data_written() var/rad = get_pin_data(IC_INPUT, 2) if(isnum(rad)) - rad = Clamp(rad, 0, 8) + rad = CLAMP(rad, 0, 8) radius = rad /obj/item/integrated_circuit/input/advanced_locator/do_work() @@ -471,7 +475,6 @@ "on signal sent" = IC_PINTYPE_PULSE_OUT, "on signal received" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNET = 2) power_draw_idle = 5 power_draw_per_use = 40 @@ -480,7 +483,7 @@ var/datum/radio_frequency/radio_connection /obj/item/integrated_circuit/input/signaler/Initialize() - ..() + . = ..() spawn(40) set_frequency(frequency) // Set the pins so when someone sees them, they won't show as null @@ -565,7 +568,6 @@ ) activators = list("send data" = IC_PINTYPE_PULSE_IN, "on data received" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNET = 2, TECH_BLUESPACE = 2) power_draw_per_use = 50 var/datum/ntnet_connection/exonet = null @@ -708,7 +710,6 @@ ) activators = list("read" = IC_PINTYPE_PULSE_IN, "on read" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 4, TECH_MAGNET = 3) power_draw_per_use = 1 /obj/item/integrated_circuit/input/internalbm/do_work() @@ -740,7 +741,6 @@ ) activators = list("read" = IC_PINTYPE_PULSE_IN, "on read" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 4, TECH_MAGNET = 3) power_draw_per_use = 1 /obj/item/integrated_circuit/input/externalbm/do_work() diff --git a/code/modules/integrated_electronics/subtypes/lists.dm b/code/modules/integrated_electronics/subtypes/lists.dm index 0d622f58e2..aa373c9940 100644 --- a/code/modules/integrated_electronics/subtypes/lists.dm +++ b/code/modules/integrated_electronics/subtypes/lists.dm @@ -2,29 +2,41 @@ /obj/item/integrated_circuit/lists complexity = 1 inputs = list( - "input" = IC_PINTYPE_LIST - ) - outputs = list("result" = IC_PINTYPE_STRING) - activators = list("compute" = IC_PINTYPE_PULSE_IN, "on computed" = IC_PINTYPE_PULSE_OUT) + "input" = IC_PINTYPE_LIST + ) + outputs = list( + "result" = IC_PINTYPE_STRING + ) + activators = list( + "compute" = IC_PINTYPE_PULSE_IN, + "on computed" = IC_PINTYPE_PULSE_OUT + ) category_text = "Lists" power_draw_per_use = 20 /obj/item/integrated_circuit/lists/pick name = "pick circuit" desc = "This circuit will pick a random element from the input list, and output said element." - extended_desc = "Will output null if the list is empty. Input list is unmodified." + extended_desc = "Input list is unmodified." icon_state = "addition" + outputs = list( + "result" = IC_PINTYPE_ANY + ) + activators = list( + "compute" = IC_PINTYPE_PULSE_IN, + "on success" = IC_PINTYPE_PULSE_OUT, + "on failure" = IC_PINTYPE_PULSE_OUT, + ) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/lists/pick/do_work() - var/result = null var/list/input_list = get_pin_data(IC_INPUT, 1) // List pins guarantee that there is a list inside, even if just an empty one. if(input_list.len) - result = pick(input_list) - - set_pin_data(IC_OUTPUT, 1, result) - push_data() - activate_pin(2) + set_pin_data(IC_OUTPUT, 1, pick(input_list)) + push_data() + activate_pin(2) + else + activate_pin(3) /obj/item/integrated_circuit/lists/append @@ -34,10 +46,10 @@ inputs = list( "list to append" = IC_PINTYPE_LIST, "input" = IC_PINTYPE_ANY - ) + ) outputs = list( "appended list" = IC_PINTYPE_LIST - ) + ) icon_state = "addition" spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH @@ -52,6 +64,7 @@ push_data() activate_pin(2) + /obj/item/integrated_circuit/lists/search name = "search circuit" desc = "This circuit will get the index location of the desired element in a list." @@ -59,19 +72,30 @@ inputs = list( "list" = IC_PINTYPE_LIST, "item" = IC_PINTYPE_ANY - ) + ) outputs = list( "index" = IC_PINTYPE_NUMBER - ) + ) + activators = list( + "compute" = IC_PINTYPE_PULSE_IN, + "on success" = IC_PINTYPE_PULSE_OUT, + "on failure" = IC_PINTYPE_PULSE_OUT, + ) icon_state = "addition" spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/lists/search/do_work() var/list/input_list = get_pin_data(IC_INPUT, 1) - var/item = get_pin_data(IC_INPUT, 2) - set_pin_data(IC_OUTPUT, 1, input_list.Find(item)) + var/output = input_list.Find(get_pin_data(IC_INPUT, 2)) + + set_pin_data(IC_OUTPUT, 1, output) push_data() - activate_pin(2) + + if(output) + activate_pin(2) + else + activate_pin(3) + /obj/item/integrated_circuit/lists/at name = "at circuit" @@ -79,31 +103,46 @@ extended_desc = "If there is no element with such index, result will be null." inputs = list( "list" = IC_PINTYPE_LIST, - "index" = IC_PINTYPE_NUMBER - ) - outputs = list("item" = IC_PINTYPE_ANY) + "index" = IC_PINTYPE_INDEX + ) + outputs = list( + "item" = IC_PINTYPE_ANY + ) + activators = list( + "compute" = IC_PINTYPE_PULSE_IN, + "on success" = IC_PINTYPE_PULSE_OUT, + "on failure" = IC_PINTYPE_PULSE_OUT, + ) icon_state = "addition" spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/lists/at/do_work() var/list/input_list = get_pin_data(IC_INPUT, 1) var/index = get_pin_data(IC_INPUT, 2) - var/item = input_list[index] - set_pin_data(IC_OUTPUT, 1, item) + + // Check if index is valid + if(index > input_list.len) + set_pin_data(IC_OUTPUT, 1, null) + push_data() + activate_pin(3) + return + + set_pin_data(IC_OUTPUT, 1, input_list[index]) push_data() activate_pin(2) + /obj/item/integrated_circuit/lists/delete name = "delete circuit" desc = "This circuit will remove an element from a list by the index." extended_desc = "If there is no element with such index, result list will be unchanged." inputs = list( "list" = IC_PINTYPE_LIST, - "index" = IC_PINTYPE_NUMBER - ) + "index" = IC_PINTYPE_INDEX + ) outputs = list( "item" = IC_PINTYPE_LIST - ) + ) icon_state = "addition" spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH @@ -111,26 +150,34 @@ var/list/input_list = get_pin_data(IC_INPUT, 1) var/list/red_list = list() var/index = get_pin_data(IC_INPUT, 2) - for(var/j in 1 to input_list.len) - var/I = input_list[j] - if(j != index) - red_list.Add(I) + + if(length(input_list)) + for(var/j in 1 to input_list.len) + var/I = input_list[j] + if(j != index) + red_list.Add(I) set_pin_data(IC_OUTPUT, 1, red_list) push_data() activate_pin(2) + /obj/item/integrated_circuit/lists/write name = "write circuit" desc = "This circuit will write an element to a list at the given index location." - extended_desc = "If there is no element with such index, it will give the same list, as before." + extended_desc = "If there is no element with such index, it will give the same list as before." inputs = list( "list" = IC_PINTYPE_LIST, - "index" = IC_PINTYPE_NUMBER, + "index" = IC_PINTYPE_INDEX, "item" = IC_PINTYPE_ANY - ) + ) outputs = list( "redacted list" = IC_PINTYPE_LIST - ) + ) + activators = list( + "compute" = IC_PINTYPE_PULSE_IN, + "on success" = IC_PINTYPE_PULSE_OUT, + "on failure" = IC_PINTYPE_PULSE_OUT, + ) icon_state = "addition" spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH @@ -138,7 +185,15 @@ var/list/input_list = get_pin_data(IC_INPUT, 1) var/index = get_pin_data(IC_INPUT, 2) var/item = get_pin_data(IC_INPUT, 3) - if(!islist(item)) + + // Check if index is valid + if(index > input_list.len) + set_pin_data(IC_OUTPUT, 1, input_list) + push_data() + activate_pin(3) + return + + if(!islist(item)) var/list/red_list = input_list.Copy() //crash proof red_list[index] = item set_pin_data(IC_OUTPUT, 1, red_list) @@ -146,7 +201,7 @@ activate_pin(2) -obj/item/integrated_circuit/lists/len +/obj/item/integrated_circuit/lists/len name = "len circuit" desc = "This circuit will return the length of the list." inputs = list( @@ -154,7 +209,7 @@ obj/item/integrated_circuit/lists/len ) outputs = list( "item" = IC_PINTYPE_NUMBER - ) + ) icon_state = "addition" spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH @@ -169,20 +224,20 @@ obj/item/integrated_circuit/lists/len name = "join text circuit" desc = "This circuit will combine two lists into one and output it as a string." extended_desc = "Default settings will encode the entire list into a string." + icon_state = "join" inputs = list( "list to join" = IC_PINTYPE_LIST,// - "delimiter" = IC_PINTYPE_CHAR, - "start" = IC_PINTYPE_NUMBER, + "delimiter" = IC_PINTYPE_STRING, + "start" = IC_PINTYPE_INDEX, "end" = IC_PINTYPE_NUMBER - ) + ) inputs_default = list( - "2" = ",", - "3" = 1, + "2" = ", ", "4" = 0 - ) + ) outputs = list( "joined text" = IC_PINTYPE_STRING - ) + ) icon_state = "addition" spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH @@ -200,3 +255,92 @@ obj/item/integrated_circuit/lists/len set_pin_data(IC_OUTPUT, 1, result) push_data() activate_pin(2) + + +/obj/item/integrated_circuit/lists/constructor + name = "large list constructor" + desc = "This circuit will build a list out of sixteen input values." + icon_state = "constr8" + inputs = list() + outputs = list( + "result" = IC_PINTYPE_LIST + ) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + var/number_of_pins = 16 + +/obj/item/integrated_circuit/lists/constructor/Initialize() + for(var/i = 1 to number_of_pins) + inputs["input [i]"] = IC_PINTYPE_ANY // This is just a string since pins don't get built until ..() is called. + complexity = number_of_pins / 2 + . = ..() + +/obj/item/integrated_circuit/lists/constructor/do_work() + var/list/output_list = list() + for(var/i = 1 to number_of_pins) + var/data = get_pin_data(IC_INPUT, i) + + // No nested lists + if(!islist(data)) + output_list += data + else + output_list += null + + set_pin_data(IC_OUTPUT, 1, output_list) + push_data() + activate_pin(2) + +/obj/item/integrated_circuit/lists/constructor/small + name = "list constructor" + desc = "This circuit will build a list out of four input values." + icon_state = "constr" + number_of_pins = 4 + +/obj/item/integrated_circuit/lists/constructor/medium + name = "medium list constructor" + desc = "This circuit will build a list out of eight input values." + icon_state = "constr8" + number_of_pins = 8 + + +/obj/item/integrated_circuit/lists/deconstructor + name = "large list deconstructor" + desc = "This circuit will write first sixteen entries of input list, starting with index, into the output values." + icon_state = "deconstr8" + inputs = list( + "input" = IC_PINTYPE_LIST, + "index" = IC_PINTYPE_INDEX + ) + outputs = list() + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + var/number_of_pins = 4 + +/obj/item/integrated_circuit/lists/deconstructor/Initialize() + for(var/i = 1 to number_of_pins) + outputs["output [i]"] = IC_PINTYPE_ANY // This is just a string since pins don't get built until ..() is called. + complexity = number_of_pins / 2 + . = ..() + +/obj/item/integrated_circuit/lists/deconstructor/do_work() + var/list/input_list = get_pin_data(IC_INPUT, 1) + var/start_index = get_pin_data(IC_INPUT, 2) + + for(var/i = 1 to number_of_pins) + var/list_index = i + start_index - 1 + if(list_index > input_list.len) + set_pin_data(IC_OUTPUT, i, null) + else + set_pin_data(IC_OUTPUT, i, input_list[list_index]) + + push_data() + activate_pin(2) + +/obj/item/integrated_circuit/lists/deconstructor/small + name = "list deconstructor" + desc = "This circuit will write first four entries of input list, starting with index, into the output values." + icon_state = "deconstr" + number_of_pins = 4 + +/obj/item/integrated_circuit/lists/deconstructor/medium + name = "medium list deconstructor" + desc = "This circuit will write first eight entries of input list, starting with index, into the output values." + number_of_pins = 8 diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm index fb78915f11..f32f414fbb 100644 --- a/code/modules/integrated_electronics/subtypes/manipulation.dm +++ b/code/modules/integrated_electronics/subtypes/manipulation.dm @@ -6,8 +6,8 @@ desc = "This somewhat complicated system allows one to slot in a gun, direct it towards a position, and remotely fire it." extended_desc = "The firing mechanism can slot in any energy weapon. \ The first and second inputs need to be numbers. They are coordinates for the gun to fire at, relative to the machine itself. \ - The 'fire' activator will cause the mechanism to attempt to fire the weapon at the coordinates, if possible. Mode is switch between\ - letal(TRUE) or stun(FALSE) modes.It uses internal battery of weapon." + The 'fire' activator will cause the mechanism to attempt to fire the weapon at the coordinates, if possible. Mode is switch between \ + lethal (TRUE) or stun (FALSE) modes.It uses internal battery of weapon." complexity = 20 w_class = WEIGHT_CLASS_SMALL size = 3 @@ -23,7 +23,6 @@ ) var/obj/item/gun/energy/installed_gun = null spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_COMBAT = 4) power_draw_per_use = 0 var/mode = FALSE @@ -94,8 +93,8 @@ yo.data = round(yo.data, 1) var/turf/T = get_turf(assembly) - var/target_x = Clamp(T.x + xo.data, 0, world.maxx) - var/target_y = Clamp(T.y + yo.data, 0, world.maxy) + var/target_x = CLAMP(T.x + xo.data, 0, world.maxx) + var/target_y = CLAMP(T.y + yo.data, 0, world.maxy) shootAt(locate(target_x, target_y, T.z)) @@ -172,7 +171,6 @@ outputs = list() activators = list("prime grenade" = IC_PINTYPE_PULSE_IN) spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_COMBAT = 4) var/obj/item/grenade/attached_grenade var/pre_attached_grenade_type @@ -212,7 +210,7 @@ var/datum/integrated_io/detonation_time = inputs[1] var/dt if(isnum(detonation_time.data) && detonation_time.data > 0) - dt = Clamp(detonation_time.data, 1, 12)*10 + dt = CLAMP(detonation_time.data, 1, 12)*10 else dt = 15 addtimer(CALLBACK(attached_grenade, /obj/item/grenade.proc/prime), dt) @@ -302,15 +300,15 @@ var/max_items = 10 /obj/item/integrated_circuit/manipulation/grabber/do_work() - var/turf/T = get_turf(src) + var/atom/movable/acting_object = get_object() + var/turf/T = get_turf(acting_object) var/obj/item/AM = get_pin_data_as_type(IC_INPUT, 1, /obj/item) if(AM) - var/turf/P = get_turf(AM) var/mode = get_pin_data(IC_INPUT, 2) if(mode == 1) - if(P.Adjacent(T)) - if((contents.len < max_items) && AM && (AM.w_class <= max_w_class)) + if(check_target(AM, exclude_contents = TRUE)) + if((contents.len < max_items) && (!max_w_class || AM.w_class <= max_w_class)) AM.forceMove(src) if(mode == 0) if(contents.len) @@ -346,9 +344,9 @@ /obj/item/integrated_circuit/manipulation/thrower name = "thrower" - desc = "A compact launcher to throw things from inside or nearby tiles" - extended_desc = "The first and second inputs need to be numbers. They are coordinates to throw thing at, relative to the machine itself. \ - The 'fire' activator will cause the mechanism to attempt to throw thing at the coordinates, if possible. Note that the \ + desc = "A compact launcher to throw things from inside or nearby tiles." + extended_desc = "The first and second inputs need to be numbers. They are coordinates to throw thing at, relative to the machine itself. \ + The 'fire' activator will cause the mechanism to attempt to throw thing at the coordinates, if possible. Note that the \ projectile need to be inside the machine, or to be on an adjacent tile, and to be up to medium size." complexity = 15 w_class = WEIGHT_CLASS_SMALL @@ -363,28 +361,37 @@ "fire" = IC_PINTYPE_PULSE_IN ) spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_COMBAT = 4) power_draw_per_use = 50 + var/max_w_class = WEIGHT_CLASS_NORMAL /obj/item/integrated_circuit/manipulation/thrower/do_work() - var/datum/integrated_io/target_x = inputs[1] - var/datum/integrated_io/target_y = inputs[2] - var/datum/integrated_io/projectile = inputs[3] - if(!isweakref(projectile.data)) - return - var/obj/item/A = projectile.data.resolve() - if(A.anchored || (A.w_class > WEIGHT_CLASS_NORMAL)) - return - var/turf/T = get_turf(assembly) - if(!(A.Adjacent(T) || (A in assembly.GetAllContents()))) - return - if(assembly) - if(isnum(target_x.data)) - target_x.data = round(target_x.data, 1) - if(isnum(target_y.data)) - target_y.data = round(target_y.data, 1) - var/_x = Clamp(T.x + target_x.data, 0, world.maxx) - var/_y = Clamp(T.y + target_y.data, 0, world.maxy) + var/target_x_rel = round(get_pin_data(IC_INPUT, 1)) + var/target_y_rel = round(get_pin_data(IC_INPUT, 2)) + var/obj/item/A = get_pin_data_as_type(IC_INPUT, 3, /obj/item) - A.forceMove(drop_location()) - A.throw_at(locate(_x, _y, T.z), round(Clamp(sqrt(target_x.data*target_x.data+target_y.data*target_y.data),0,8),1), 3) + if(!A || A.anchored || A.throwing) + return + + if(max_w_class && (A.w_class > max_w_class)) + return + + // Is the target inside the assembly or close to it? + if(!check_target(A, exclude_components = TRUE)) + return + + var/turf/T = get_turf(get_object()) + if(!T) + return + + // If the item is in mob's inventory, try to remove it from there. + if(ismob(A.loc)) + var/mob/living/M = A.loc + if(!M.temporarilyRemoveItemFromInventory(A)) + return + + var/x_abs = CLAMP(T.x + target_x_rel, 0, world.maxx) + var/y_abs = CLAMP(T.y + target_y_rel, 0, world.maxy) + var/range = round(CLAMP(sqrt(target_x_rel*target_x_rel+target_y_rel*target_y_rel),0,8),1) + + A.forceMove(drop_location()) + A.throw_at(locate(x_abs, y_abs, T.z), range, 3) diff --git a/code/modules/integrated_electronics/subtypes/memory.dm b/code/modules/integrated_electronics/subtypes/memory.dm index 548ea3fa1d..8d187a4b2a 100644 --- a/code/modules/integrated_electronics/subtypes/memory.dm +++ b/code/modules/integrated_electronics/subtypes/memory.dm @@ -11,12 +11,12 @@ power_draw_per_use = 1 var/number_of_pins = 1 -/obj/item/integrated_circuit/memory/New() +/obj/item/integrated_circuit/memory/Initialize() for(var/i = 1 to number_of_pins) inputs["input [i]"] = IC_PINTYPE_ANY // This is just a string since pins don't get built until ..() is called. outputs["output [i]"] = IC_PINTYPE_ANY complexity = number_of_pins - ..() + . = ..() /obj/item/integrated_circuit/memory/examine(mob/user) ..() @@ -58,7 +58,6 @@ name = "large memory circuit" desc = "This big circuit can hold eight pieces of data." icon_state = "memory8" - origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3) power_draw_per_use = 4 number_of_pins = 8 @@ -68,7 +67,6 @@ icon_state = "memory16" w_class = WEIGHT_CLASS_SMALL spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4) power_draw_per_use = 8 number_of_pins = 16 diff --git a/code/modules/integrated_electronics/subtypes/output.dm b/code/modules/integrated_electronics/subtypes/output.dm index 16839cc509..6a90ff5f2a 100644 --- a/code/modules/integrated_electronics/subtypes/output.dm +++ b/code/modules/integrated_electronics/subtypes/output.dm @@ -17,7 +17,11 @@ stuff_to_display = null /obj/item/integrated_circuit/output/screen/any_examine(mob/user) - to_chat(user, "There is a little screen labeled '[name]', which displays [!isnull(stuff_to_display) ? "'[stuff_to_display]'" : "nothing"].") + var/shown_label = "" + if(displayed_name && displayed_name != name) + shown_label = " labeled '[displayed_name]'" + + to_chat(user, "There is \a [src][shown_label], which displays [!isnull(stuff_to_display) ? "'[stuff_to_display]'" : "nothing"].") /obj/item/integrated_circuit/output/screen/do_work() var/datum/integrated_io/I = inputs[1] @@ -84,7 +88,7 @@ var/brightness = get_pin_data(IC_INPUT, 2) if(new_color && isnum(brightness)) - brightness = Clamp(brightness, 0, 6) + brightness = CLAMP(brightness, 0, 6) light_rgb = new_color light_brightness = brightness @@ -105,7 +109,6 @@ ) outputs = list() spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3) /obj/item/integrated_circuit/output/light/advanced/on_data_written() update_lighting() @@ -126,24 +129,6 @@ power_draw_per_use = 10 var/list/sounds = list() -/obj/item/integrated_circuit/output/text_to_speech - name = "text-to-speech circuit" - desc = "Takes any string as an input and will make the device say the string when pulsed." - extended_desc = "This unit is more advanced than the plain speaker circuit, able to transpose any valid text to speech." - icon_state = "speaker" - complexity = 12 - inputs = list("text" = IC_PINTYPE_STRING) - outputs = list() - activators = list("to speech" = IC_PINTYPE_PULSE_IN) - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - power_draw_per_use = 60 - -/obj/item/integrated_circuit/output/text_to_speech/do_work() - text = get_pin_data(IC_INPUT, 1) - if(!isnull(text)) - var/obj/O = assembly ? loc : assembly - O.say(sanitize(text)) - /obj/item/integrated_circuit/output/sound/Initialize() .= ..() extended_desc = list() @@ -161,7 +146,7 @@ var/selected_sound = sounds[ID] if(!selected_sound) return - vol = Clamp(vol ,0 , 100) + vol = CLAMP(vol ,0 , 100) playsound(get_turf(src), selected_sound, vol, freq, -1) /obj/item/integrated_circuit/output/sound/on_data_written() @@ -196,7 +181,6 @@ "secure day" = 'sound/voice/bsecureday.ogg', ) spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_ILLEGAL = 1) /obj/item/integrated_circuit/output/sound/medbot name = "medbot sound circuit" @@ -219,7 +203,35 @@ "no" = 'sound/voice/mno.ogg', ) spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 1) + +/obj/item/integrated_circuit/output/sound/vox + name = "ai vox sound circuit" + desc = "Takes a sound name as an input, and will play said sound when pulsed. This circuit is often found in AI announcement systems." + spawn_flags = IC_SPAWN_RESEARCH + +/obj/item/integrated_circuit/output/sound/vox/Initialize() + .= ..() + sounds = GLOB.vox_sounds + extended_desc = "The first input pin determines which sound is used. It uses the AI Vox Broadcast word list. So either experiment to find words that work, or ask the AI to help in figuring them out. The second pin determines the volume of sound that is played, and the third determines if the frequency of the sound will vary with each activation." + +/obj/item/integrated_circuit/output/text_to_speech + name = "text-to-speech circuit" + desc = "Takes any string as an input and will make the device say the string when pulsed." + extended_desc = "This unit is more advanced than the plain speaker circuit, able to transpose any valid text to speech." + icon_state = "speaker" + complexity = 12 + inputs = list("text" = IC_PINTYPE_STRING) + outputs = list() + activators = list("to speech" = IC_PINTYPE_PULSE_IN) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + power_draw_per_use = 60 + +/obj/item/integrated_circuit/output/text_to_speech/do_work() + text = get_pin_data(IC_INPUT, 1) + if(!isnull(text)) + var/atom/movable/A = get_object() + A.say(sanitize(text)) + /obj/item/integrated_circuit/output/video_camera name = "video camera circuit" @@ -291,19 +303,26 @@ /obj/item/integrated_circuit/output/led name = "light-emitting diode" - desc = "Takes a boolean value in, and if the boolean value is 'true-equivalent', the LED will be marked as lit on examine." + desc = "RGB LED. Takes a boolean value in, and if the boolean value is 'true-equivalent', the LED will be marked as lit on examine." extended_desc = "TRUE-equivalent values are: Non-empty strings, non-zero numbers, and valid refs." complexity = 0.1 icon_state = "led" - inputs = list("lit" = IC_PINTYPE_BOOLEAN) + inputs = list( + "lit" = IC_PINTYPE_BOOLEAN, + "color" = IC_PINTYPE_COLOR + ) outputs = list() activators = list() + inputs_default = list( + "2" = "#FF0000" + ) power_draw_idle = 0 // Raises to 1 when lit. spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - var/led_color + var/led_color = "#FF0000" /obj/item/integrated_circuit/output/led/on_data_written() power_draw_idle = get_pin_data(IC_INPUT, 1) ? 1 : 0 + led_color = get_pin_data(IC_INPUT, 2) /obj/item/integrated_circuit/output/led/power_fail() set_pin_data(IC_INPUT, 1, FALSE) @@ -317,39 +336,3 @@ text_output += "\an ["\improper[name]"] labeled '[displayed_name]'" text_output += " which is currently [get_pin_data(IC_INPUT, 1) ? "lit *" : "unlit"]." to_chat(user, text_output) - -/obj/item/integrated_circuit/output/led/red - name = "red LED" - led_color = "#FF0000" - -/obj/item/integrated_circuit/output/led/orange - name = "orange LED" - led_color = "#FF9900" - -/obj/item/integrated_circuit/output/led/yellow - name = "yellow LED" - led_color = "#FFFF00" - -/obj/item/integrated_circuit/output/led/green - name = "green LED" - led_color = "#008000" - -/obj/item/integrated_circuit/output/led/blue - name = "blue LED" - led_color = "#0000FF" - -/obj/item/integrated_circuit/output/led/purple - name = "purple LED" - led_color = "#800080" - -/obj/item/integrated_circuit/output/led/cyan - name = "cyan LED" - led_color = "#00FFFF" - -/obj/item/integrated_circuit/output/led/white - name = "white LED" - led_color = "#FFFFFF" - -/obj/item/integrated_circuit/output/led/pink - name = "pink LED" - led_color = "#FF00FF" diff --git a/code/modules/integrated_electronics/subtypes/power.dm b/code/modules/integrated_electronics/subtypes/power.dm index 3647d11cdf..de9055acfa 100644 --- a/code/modules/integrated_electronics/subtypes/power.dm +++ b/code/modules/integrated_electronics/subtypes/power.dm @@ -19,7 +19,6 @@ ) activators = list("transmit" = IC_PINTYPE_PULSE_IN, "on transmit" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 4, TECH_MAGNET = 3) power_draw_per_use = 500 // Inefficency has to come from somewhere. var/amount_to_move = 5000 @@ -32,7 +31,6 @@ some power is lost due to ineffiency." w_class = WEIGHT_CLASS_BULKY complexity = 32 - origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 6, TECH_MAGNET = 5) power_draw_per_use = 2000 amount_to_move = 20000 diff --git a/code/modules/integrated_electronics/subtypes/reagents.dm b/code/modules/integrated_electronics/subtypes/reagents.dm index 1793869237..33f92c3646 100644 --- a/code/modules/integrated_electronics/subtypes/reagents.dm +++ b/code/modules/integrated_electronics/subtypes/reagents.dm @@ -1,11 +1,12 @@ +#define IC_SMOKE_REAGENTS_MINIMUM_UNITS 10 + /obj/item/integrated_circuit/reagent category_text = "Reagent" - var/volume = 0 resistance_flags = UNACIDABLE | FIRE_PROOF - origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) + var/volume = 0 -/obj/item/integrated_circuit/reagent/New() - ..() +/obj/item/integrated_circuit/reagent/Initialize() + . = ..() if(volume) create_reagents(volume) @@ -15,15 +16,22 @@ icon_state = "smoke" extended_desc = "This smoke generator creates clouds of smoke on command. It can also hold liquids inside, which will go \ into the smoke clouds when activated. The reagents are consumed when smoke is made." - container_type = OPENCONTAINER_1 + + container_type = OPENCONTAINER + volume = 100 + complexity = 20 cooldown_per_use = 1 SECONDS inputs = list() - outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF) - activators = list("create smoke" = IC_PINTYPE_PULSE_IN,"on smoked" = IC_PINTYPE_PULSE_OUT) + outputs = list( + "volume used" = IC_PINTYPE_NUMBER, + "self reference" = IC_PINTYPE_REF + ) + activators = list( + "create smoke" = IC_PINTYPE_PULSE_IN, + "on smoked" = IC_PINTYPE_PULSE_OUT + ) spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 3) - volume = 100 power_draw_per_use = 20 var/smoke_radius = 5 var/notified = FALSE @@ -35,13 +43,9 @@ set_pin_data(IC_OUTPUT, 1, reagents.total_volume) push_data() - -/obj/item/integrated_circuit/reagent/smoke/interact(mob/user) - set_pin_data(IC_OUTPUT, 2, WEAKREF(src)) - push_data() - ..() - /obj/item/integrated_circuit/reagent/smoke/do_work() + if(!reagents || (reagents.total_volume < IC_SMOKE_REAGENTS_MINIMUM_UNITS)) + return var/location = get_turf(src) var/datum/effect_system/smoke_spread/chem/S = new S.attach(location) @@ -52,26 +56,38 @@ notified = TRUE S.start() - if(reagents) - reagents.clear_reagents() + reagents.clear_reagents() activate_pin(2) - /obj/item/integrated_circuit/reagent/injector name = "integrated hypo-injector" desc = "This scary looking thing is able to pump liquids into whatever it's pointed at." icon_state = "injector" extended_desc = "This autoinjector can push reagents into another container or someone else outside of the machine. The target \ must be adjacent to the machine, and if it is a person, they cannot be wearing thick clothing. Negative given amount makes injector suck out reagents." - container_type = OPENCONTAINER_1 + + container_type = OPENCONTAINER + volume = 30 + complexity = 20 cooldown_per_use = 6 SECONDS - inputs = list("target" = IC_PINTYPE_REF, "injection amount" = IC_PINTYPE_NUMBER) - inputs_default = list("2" = 5) - outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF) - activators = list("inject" = IC_PINTYPE_PULSE_IN, "on injected" = IC_PINTYPE_PULSE_OUT, "on fail" = IC_PINTYPE_PULSE_OUT) + inputs = list( + "target" = IC_PINTYPE_REF, + "injection amount" = IC_PINTYPE_NUMBER + ) + inputs_default = list( + "2" = 5 + ) + outputs = list( + "volume used" = IC_PINTYPE_NUMBER, + "self reference" = IC_PINTYPE_REF + ) + activators = list( + "inject" = IC_PINTYPE_PULSE_IN, + "on injected" = IC_PINTYPE_PULSE_OUT, + "on fail" = IC_PINTYPE_PULSE_OUT + ) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - volume = 30 power_draw_per_use = 15 var/direction_mode = SYRINGE_INJECT var/transfer_amount = 10 @@ -95,111 +111,115 @@ else direction_mode = SYRINGE_INJECT if(isnum(new_amount)) - new_amount = Clamp(new_amount, 0, volume) + new_amount = CLAMP(new_amount, 0, volume) transfer_amount = new_amount -/obj/item/integrated_circuit/reagent/proc/inject_tray(var/obj/machinery/hydroponics/H,var/atom/movable/SO,var/A) - var/datum/reagents/S = new /datum/reagents() //This is a strange way, but I don't know of a better one so I can't fix it at the moment... - S.my_atom = H - SO.reagents.trans_to(S,A) - H.applyChemicals(S) - S.clear_reagents() - qdel(S) +// Hydroponics trays have no reagents holder and handle reagents in their own snowflakey way. +// This is a dirty hack to make injecting reagents into them work. +// TODO: refactor that. +/obj/item/integrated_circuit/reagent/proc/inject_tray(obj/machinery/hydroponics/tray, atom/movable/source, amount) + var/datum/reagents/temp_reagents = new /datum/reagents() + temp_reagents.my_atom = tray + + source.reagents.trans_to(temp_reagents, amount) + tray.applyChemicals(temp_reagents) + + temp_reagents.clear_reagents() + qdel(temp_reagents) /obj/item/integrated_circuit/reagent/injector/do_work() set waitfor = FALSE // Don't sleep in a proc that is called by a processor without this set, otherwise it'll delay the entire thing var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) - if(!istype(AM)||!Adjacent(AM)||busy) + var/atom/movable/acting_object = get_object() + + if(busy || !check_target(AM)) activate_pin(3) return - if(istype(AM,/obj/machinery/hydroponics)&&(direction_mode==SYRINGE_INJECT)&&(reagents.total_volume))//injection into tray. - inject_tray(AM,src,transfer_amount) - activate_pin(2) - return + if(!AM.reagents) + if(istype(AM, /obj/machinery/hydroponics) && direction_mode == SYRINGE_INJECT && reagents.total_volume)//injection into tray. + inject_tray(AM, src, transfer_amount) + activate_pin(2) + return activate_pin(3) return + if(direction_mode == SYRINGE_INJECT) - if(!reagents.total_volume) // Empty + if(!reagents.total_volume || !AM.is_injectable() || AM.reagents.holder_full()) activate_pin(3) return - if(AM.is_injectable()) - if(AM.reagents.total_volume>=AM.reagents.maximum_volume) - activate_pin(3) - return - if(isliving(AM)) - var/mob/living/L = AM - if(!L.can_inject(null, 0)) - activate_pin(3) - return - //Always log attemped injections for admins - var/list/rinject = list() - for(var/datum/reagent/R in reagents.reagent_list) - rinject += R.name - var/contained = english_list(rinject) - add_logs(src, L, "attemped to inject", addition="which had [contained]") //TODO: proper logging (maybe last touched and assembled) - L.visible_message("[src] is trying to inject [L]!", \ - "[src] is trying to inject you!") - busy = TRUE - if(do_atom(src, L, extra_checks=CALLBACK(L, /mob/living/proc/can_inject,null,0))) - var/fraction = min(transfer_amount/reagents.total_volume, 1) - reagents.reaction(L, INJECT, fraction) - reagents.trans_to(L, transfer_amount) - L.visible_message("[src] injects [L] with its needle!", \ - "[src] injects you with its needle!") - else - busy = FALSE - activate_pin(3) - return - busy = FALSE - else - reagents.trans_to(AM, transfer_amount) - else - activate_pin(3) - return - else - if(reagents.total_volume >= reagents.maximum_volume) // Full - activate_pin(3) - return - var/tramount = Clamp(min(transfer_amount, reagents.maximum_volume - reagents.total_volume), 0, reagents.maximum_volume) + if(isliving(AM)) var/mob/living/L = AM - L.visible_message("[src] is trying to take a blood sample from [L]!", \ - "[src] is trying to take a blood sample from you!") + if(!L.can_inject(null, 0)) + activate_pin(3) + return + + //Always log attemped injections for admins + var/contained = reagents.log_list() + add_logs(src, L, "attemped to inject", addition="which had [contained]") + L.visible_message("[acting_object] is trying to inject [L]!", \ + "[acting_object] is trying to inject you!") + busy = TRUE + if(do_atom(src, L, extra_checks=CALLBACK(L, /mob/living/proc/can_inject,null,0))) + var/fraction = min(transfer_amount/reagents.total_volume, 1) + reagents.reaction(L, INJECT, fraction) + reagents.trans_to(L, transfer_amount) + add_logs(src, L, "injected", addition="which had [contained]") + L.visible_message("[acting_object] injects [L] with its needle!", \ + "[acting_object] injects you with its needle!") + else + busy = FALSE + activate_pin(3) + return + busy = FALSE + else + reagents.trans_to(AM, transfer_amount) + + else + if(!AM.is_drawable() || reagents.total_volume >= reagents.maximum_volume) + activate_pin(3) + return + + var/tramount = CLAMP(transfer_amount, 0, reagents.total_volume) + + if(isliving(AM)) + var/mob/living/L = AM + L.visible_message("[acting_object] is trying to take a blood sample from [L]!", \ + "[acting_object] is trying to take a blood sample from you!") busy = TRUE if(do_atom(src, L, extra_checks=CALLBACK(L, /mob/living/proc/can_inject,null,0))) if(L.transfer_blood_to(src, tramount)) - L.visible_message("[src] takes a blood sample from [L].") + L.visible_message("[acting_object] takes a blood sample from [L].") else busy = FALSE activate_pin(3) return busy = FALSE else - if(!AM.reagents.total_volume || !AM.is_drawable()) + if(!AM.reagents.total_volume) activate_pin(3) return + AM.reagents.trans_to(src, tramount) activate_pin(2) - /obj/item/integrated_circuit/reagent/pump name = "reagent pump" desc = "Moves liquids safely inside a machine, or even nearby it." icon_state = "reagent_pump" - extended_desc = "This is a pump, which will move liquids from the source ref to the target ref. The third pin determines \ - how much liquid is moved per pulse, between 0 and 50. The pump can move reagents to any open container inside the machine, or \ - outside the machine if it is next to the machine. Note that this cannot be used on entities." - container_type = OPENCONTAINER_1 + extended_desc = "This is a pump, which will move liquids from the source ref to the target ref. The third pin determines \ + how much liquid is moved per pulse, between 0 and 50. The pump can move reagents to any open container inside the machine, or \ + outside the machine if it is next to the machine." + complexity = 8 inputs = list("source" = IC_PINTYPE_REF, "target" = IC_PINTYPE_REF, "injection amount" = IC_PINTYPE_NUMBER) inputs_default = list("3" = 5) outputs = list() activators = list("transfer reagents" = IC_PINTYPE_PULSE_IN, "on transfer" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) var/transfer_amount = 10 var/direction_mode = SYRINGE_INJECT power_draw_per_use = 10 @@ -212,51 +232,57 @@ else direction_mode = SYRINGE_INJECT if(isnum(new_amount)) - new_amount = Clamp(new_amount, 0, 50) + new_amount = CLAMP(new_amount, 0, 50) transfer_amount = new_amount /obj/item/integrated_circuit/reagent/pump/do_work() var/atom/movable/source = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) var/atom/movable/target = get_pin_data_as_type(IC_INPUT, 2, /atom/movable) - if(!istype(source) || !istype(target) || !source.reagents) //Invalid input + // Check for invalid input. + if(!check_target(source) || !check_target(target)) return - if(Adjacent(source) && Adjacent(target)) - if(istype(target,/obj/machinery/hydroponics)&&(source.reagents.total_volume))//injection into tray. - inject_tray(target,source,transfer_amount) - activate_pin(2) - return - if(!target.reagents) - return - if(ismob(source) || ismob(target)) - return - if(!source.is_open_container() || !target.is_open_container()) - return - if(direction_mode) - if(target.reagents.maximum_volume - target.reagents.total_volume <= 0) //full - return - source.reagents.trans_to(target, transfer_amount) - else - if(source.reagents.maximum_volume - source.reagents.total_volume <= 0) - return - target.reagents.trans_to(source, transfer_amount) - activate_pin(2) + // If the pump is pumping backwards, swap target and source. + if(!direction_mode) + var/temp_source = source + source = target + target = temp_source + + if(!source.reagents) + return + + if(!target.reagents) + // Hydroponics trays have no reagents holder and handle reagents in their own snowflakey way. + // This is a dirty hack to make injecting reagents into them work. + if(istype(target, /obj/machinery/hydroponics) && source.reagents.total_volume) + inject_tray(target, source, transfer_amount) + activate_pin(2) + return + + if(!source.is_drainable() || !target.is_refillable()) + return + + source.reagents.trans_to(target, transfer_amount) + activate_pin(2) /obj/item/integrated_circuit/reagent/storage name = "reagent storage" - desc = "Stores liquid inside, and away from electrical components. Can store up to 60u." + desc = "Stores liquid inside, and away from electrical components. Can store up to 60u." icon_state = "reagent_storage" extended_desc = "This is effectively an internal beaker." - container_type = OPENCONTAINER_1 - complexity = 4 - inputs = list() - outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF) - activators = list() - spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) + + container_type = OPENCONTAINER volume = 60 + complexity = 4 + inputs = list() + outputs = list( + "volume used" = IC_PINTYPE_NUMBER, + "self reference" = IC_PINTYPE_REF + ) + activators = list() + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH /obj/item/integrated_circuit/reagent/storage/interact(mob/user) set_pin_data(IC_OUTPUT, 2, WEAKREF(src)) @@ -269,40 +295,44 @@ /obj/item/integrated_circuit/reagent/storage/cryo name = "cryo reagent storage" - desc = "Stores liquid inside, and away from electrical components. Can store up to 60u. This will also suppress reactions." + desc = "Stores liquid inside, and away from electrical components. Can store up to 60u. This will also suppress reactions." icon_state = "reagent_storage_cryo" extended_desc = "This is effectively an internal cryo beaker." - container_type = OPENCONTAINER_1 + complexity = 8 spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_MATERIALS = 4, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) -/obj/item/integrated_circuit/reagent/storage/cryo/New() +/obj/item/integrated_circuit/reagent/storage/cryo/Initialize() . = ..() reagents.set_reacting(FALSE) /obj/item/integrated_circuit/reagent/storage/big name = "big reagent storage" - desc = "Stores liquid inside, and away from electrical components. Can store up to 180u." + desc = "Stores liquid inside, and away from electrical components. Can store up to 180u." icon_state = "reagent_storage_big" extended_desc = "This is effectively an internal beaker." - container_type = OPENCONTAINER_1 - complexity = 16 + volume = 180 + + complexity = 16 spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_MATERIALS = 3, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) /obj/item/integrated_circuit/reagent/storage/scan name = "reagent scanner" - desc = "Stores liquid inside, and away from electrical components. Can store up to 60u. On pulse this beaker will send list of contained reagents." + desc = "Stores liquid inside, and away from electrical components. Can store up to 60u. On pulse this beaker will send list of contained reagents." icon_state = "reagent_scan" extended_desc = "Mostly useful for reagent filter." - container_type = OPENCONTAINER_1 + complexity = 8 - outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF,"list of reagents" = IC_PINTYPE_LIST) - activators = list("scan" = IC_PINTYPE_PULSE_IN) + outputs = list( + "volume used" = IC_PINTYPE_NUMBER, + "self reference" = IC_PINTYPE_REF, + "list of reagents" = IC_PINTYPE_LIST + ) + activators = list( + "scan" = IC_PINTYPE_PULSE_IN + ) spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_MATERIALS = 3, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) /obj/item/integrated_circuit/reagent/storage/scan/do_work() var/cont[0] @@ -316,18 +346,27 @@ name = "reagent filter" desc = "Filtering liquids by list of desired or unwanted reagents." icon_state = "reagent_filter" - extended_desc = "This is a filter, which will move liquids from the source ref to the target ref. \ + extended_desc = "This is a filter, which will move liquids from the source to the target. \ It will move all reagents, except list, given in fourth pin if amount value is positive.\ Or it will move only desired reagents if amount is negative, The third pin determines \ how much reagent is moved per pulse, between 0 and 50. Amount is given for each separate reagent." - container_type = OPENCONTAINER_1 + complexity = 8 - inputs = list("source" = IC_PINTYPE_REF, "target" = IC_PINTYPE_REF, "injection amount" = IC_PINTYPE_NUMBER, "list of reagents" = IC_PINTYPE_LIST) - inputs_default = list("3" = 5) + inputs = list( + "source" = IC_PINTYPE_REF, + "target" = IC_PINTYPE_REF, + "injection amount" = IC_PINTYPE_NUMBER, + "list of reagents" = IC_PINTYPE_LIST + ) + inputs_default = list( + "3" = 5 + ) outputs = list() - activators = list("transfer reagents" = IC_PINTYPE_PULSE_IN, "on transfer" = IC_PINTYPE_PULSE_OUT) + activators = list( + "transfer reagents" = IC_PINTYPE_PULSE_IN, + "on transfer" = IC_PINTYPE_PULSE_OUT + ) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) var/transfer_amount = 10 var/direction_mode = SYRINGE_INJECT power_draw_per_use = 10 @@ -340,34 +379,34 @@ else direction_mode = SYRINGE_INJECT if(isnum(new_amount)) - new_amount = Clamp(new_amount, 0, 50) + new_amount = CLAMP(new_amount, 0, 50) transfer_amount = new_amount /obj/item/integrated_circuit/reagent/filter/do_work() var/atom/movable/source = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) var/atom/movable/target = get_pin_data_as_type(IC_INPUT, 2, /atom/movable) var/list/demand = get_pin_data(IC_INPUT, 4) - if(!istype(source) || !istype(target)) //Invalid input + + // Check for invalid input. + if(!check_target(source) || !check_target(target)) return - var/turf/T = get_turf(src) - if(source.Adjacent(T) && target.Adjacent(T)) - if(!source.reagents || !target.reagents) - return - if(ismob(source) || ismob(target)) - return - if(!source.is_open_container() || !target.is_open_container()) - return - if(target.reagents.maximum_volume - target.reagents.total_volume <= 0) - return - for(var/datum/reagent/G in source.reagents.reagent_list) - if (!direction_mode) - if(G.id in demand) - source.reagents.trans_id_to(target, G.id, transfer_amount) - else - if(!(G.id in demand)) - source.reagents.trans_id_to(target, G.id, transfer_amount) - activate_pin(2) - push_data() + if(!source.reagents || !target.reagents) + return + if(!source.is_drainable() || !target.is_refillable()) + return + + if(target.reagents.maximum_volume - target.reagents.total_volume <= 0) + return + + for(var/datum/reagent/G in source.reagents.reagent_list) + if(!direction_mode) + if(G.id in demand) + source.reagents.trans_id_to(target, G.id, transfer_amount) + else + if(!(G.id in demand)) + source.reagents.trans_id_to(target, G.id, transfer_amount) + activate_pin(2) + push_data() diff --git a/code/modules/integrated_electronics/subtypes/smart.dm b/code/modules/integrated_electronics/subtypes/smart.dm index 1c0dc470b4..ec59c3cab1 100644 --- a/code/modules/integrated_electronics/subtypes/smart.dm +++ b/code/modules/integrated_electronics/subtypes/smart.dm @@ -12,7 +12,6 @@ outputs = list("dir" = IC_PINTYPE_DIR) activators = list("calculate dir" = IC_PINTYPE_PULSE_IN, "on calculated" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 5) power_draw_per_use = 40 /obj/item/integrated_circuit/smart/basic_pathfinder/do_work() diff --git a/code/modules/integrated_electronics/subtypes/time.dm b/code/modules/integrated_electronics/subtypes/time.dm index 57fc16ccf9..d93aafef58 100644 --- a/code/modules/integrated_electronics/subtypes/time.dm +++ b/code/modules/integrated_electronics/subtypes/time.dm @@ -62,7 +62,7 @@ /obj/item/integrated_circuit/time/delay/custom/do_work() var/delay_input = get_pin_data(IC_INPUT, 1) if(delay_input && isnum(delay_input) ) - var/new_delay = Clamp(delay_input ,1 ,36000) //An hour. + var/new_delay = CLAMP(delay_input ,1 ,36000) //An hour. delay = new_delay ..() diff --git a/code/modules/integrated_electronics/subtypes/trig.dm b/code/modules/integrated_electronics/subtypes/trig.dm index 1d7f660bd4..cefa25e945 100644 --- a/code/modules/integrated_electronics/subtypes/trig.dm +++ b/code/modules/integrated_electronics/subtypes/trig.dm @@ -71,7 +71,7 @@ var/result = null var/A = get_pin_data(IC_INPUT, 1) if(!isnull(A)) - result = Tan(A) + result = TAN(A) set_pin_data(IC_OUTPUT, 1, result) push_data() @@ -91,7 +91,7 @@ var/result = null var/A = get_pin_data(IC_INPUT, 1) if(!isnull(A)) - result = Csc(A) + result = CSC(A) set_pin_data(IC_OUTPUT, 1, result) push_data() @@ -111,7 +111,7 @@ var/result = null var/A = get_pin_data(IC_INPUT, 1) if(!isnull(A)) - result = Sec(A) + result = SEC(A) set_pin_data(IC_OUTPUT, 1, result) push_data() @@ -131,7 +131,7 @@ var/result = null var/A = get_pin_data(IC_INPUT, 1) if(!isnull(A)) - result = Cot(A) + result = COT(A) set_pin_data(IC_OUTPUT, 1, result) push_data() diff --git a/code/modules/jobs/access.dm b/code/modules/jobs/access.dm index e208deb422..67bbd2fad9 100644 --- a/code/modules/jobs/access.dm +++ b/code/modules/jobs/access.dm @@ -4,7 +4,7 @@ /obj/var/list/req_one_access = null /obj/var/req_one_access_txt = "0" as text -//returns 1 if this mob has sufficient access to use this object +//returns TRUE if this mob has sufficient access to use this object /obj/proc/allowed(mob/M) //check if it doesn't require any access at all if(src.check_access(null)) diff --git a/code/modules/jobs/job_types/civilian_chaplain.dm b/code/modules/jobs/job_types/civilian_chaplain.dm index aefb6f48ae..7f7fdca900 100644 --- a/code/modules/jobs/job_types/civilian_chaplain.dm +++ b/code/modules/jobs/job_types/civilian_chaplain.dm @@ -68,7 +68,7 @@ Chaplain B.name = "Guys Gone Wild" if("lol", "wtf", "gay", "penis", "ass", "poo", "badmin", "shitmin", "deadmin", "cock", "cocks", "meme", "memes") B.name = pick("Woodys Got Wood: The Aftermath", "War of the Cocks", "Sweet Bro and Hella Jef: Expanded Edition") - H.setBrainLoss(100) // starts off retarded as fuck + H.adjustBrainLoss(100) // starts off retarded as fuck if("science") B.name = pick("Principle of Relativity", "Quantum Enigma: Physics Encounters Consciousness", "Programming the Universe", "Quantum Physics and Theology", "String Theory for Dummies", "How To: Build Your Own Warp Drive", "The Mysteries of Bluespace", "Playing God: Collector's Edition") else diff --git a/code/modules/keybindings/bindings_human.dm b/code/modules/keybindings/bindings_human.dm new file mode 100644 index 0000000000..85aeba5f10 --- /dev/null +++ b/code/modules/keybindings/bindings_human.dm @@ -0,0 +1,69 @@ +/mob/living/carbon/human/key_down(_key, client/user) + if(client.keys_held["Shift"]) + switch(_key) + if("E") // Put held thing in belt or take out most recent thing from belt + var/obj/item/thing = get_active_held_item() + var/obj/item/storage/equipped_belt = get_item_by_slot(slot_belt) + if(!equipped_belt) // We also let you equip a belt like this + if(!thing) + to_chat(user, "You have no belt to take something out of.") + return + equip_to_slot_if_possible(thing, slot_belt) + return + if(!istype(equipped_belt)) // not a storage item + if(!thing) + to_chat(user, "You have no belt to take something out of.") + else + to_chat(user, "You can't fit anything in.") + return + if(thing) // put thing in belt + if(equipped_belt.can_be_inserted(thing)) + equipped_belt.handle_item_insertion(thing) + else + to_chat(user, "You can't fit anything in.") + return + if(!equipped_belt.contents.len) // nothing to take out + to_chat(user, "There's nothing in your belt to take out.") + return + var/obj/item/stored = equipped_belt.contents[equipped_belt.contents.len] + if(!stored || stored.on_found(src)) + return + stored.attack_hand(src) // take out thing from belt + return + + if("B") // Put held thing in backpack or take out most recent thing from backpack + var/obj/item/thing = get_active_held_item() + var/obj/item/storage/equipped_backpack = get_item_by_slot(slot_back) + if(!equipped_backpack) // We also let you equip a backpack like this + if(!thing) + to_chat(user, "You have no backpack to take something out of.") + return + equip_to_slot_if_possible(thing, slot_back) + return + if(!istype(equipped_backpack)) // not a storage item + if(!thing) + to_chat(user, "You have no backpack to take something out of.") + else + to_chat(user, "You can't fit anything in.") + return + if(thing) // put thing in backpack + if(equipped_backpack.can_be_inserted(thing)) + equipped_backpack.handle_item_insertion(thing) + else + to_chat(user, "You can't fit anything in.") + return + if(!equipped_backpack.contents.len) // nothing to take out + to_chat(user, "There's nothing in your backpack to take out.") + return + var/obj/item/stored = equipped_backpack.contents[equipped_backpack.contents.len] + if(!stored || stored.on_found(src)) + return + stored.attack_hand(src) // take out thing from backpack + return + + switch(_key) + if("E") + quick_equip() + return + + return ..() \ No newline at end of file diff --git a/code/modules/language/aphasia.dm b/code/modules/language/aphasia.dm new file mode 100644 index 0000000000..070a792ecd --- /dev/null +++ b/code/modules/language/aphasia.dm @@ -0,0 +1,13 @@ +/datum/language/aphasia + name = "Gibbering" + desc = "It is theorized that any sufficiently brain-damaged person can speak this language." + speech_verb = "garbles" + ask_verb = "mumbles" + whisper_verb = "mutters" + exclaim_verb = "screams incoherently" + flags_1 = LANGUAGE_HIDE_ICON_IF_NOT_UNDERSTOOD + key = "i" + syllables = list("m","n","gh","h","l","s","r","a","e","i","o","u") + space_chance = 20 + default_priority = 10 + icon_state = "aphasia" diff --git a/code/modules/language/language.dm b/code/modules/language/language.dm index 67881f7510..598fb41e6c 100644 --- a/code/modules/language/language.dm +++ b/code/modules/language/language.dm @@ -49,7 +49,7 @@ for(var/i in 0 to name_count) new_name = "" - var/Y = rand(Floor(syllable_count/syllable_divisor), syllable_count) + var/Y = rand(FLOOR(syllable_count/syllable_divisor, 1), syllable_count) for(var/x in Y to 0) new_name += pick(syllables) full_name += " [capitalize(lowertext(new_name))]" diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm index 711ac4f33a..9cbd04bf42 100644 --- a/code/modules/library/lib_items.dm +++ b/code/modules/library/lib_items.dm @@ -49,7 +49,7 @@ anchored = TRUE for(var/obj/item/I in loc) if(istype(I, /obj/item/book)) - I.loc = src + I.forceMove(src) update_icon() @@ -123,7 +123,7 @@ if(!user.get_active_held_item()) user.put_in_hands(choice) else - choice.loc = get_turf(src) + choice.forceMove(drop_location()) update_icon() @@ -289,7 +289,7 @@ user.put_in_hands(B) return else - B.loc = src.loc + B.forceMove(drop_location()) qdel(src) return return diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm index 52077d2367..5aa048a5fd 100644 --- a/code/modules/library/lib_machines.dm +++ b/code/modules/library/lib_machines.dm @@ -263,7 +263,7 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums dat += "(Order book by SS13BN)

    " dat += "
    [jointext(words, null)]
    " dat += "" - dat += libcomp_menu[Clamp(page,1,libcomp_menu.len)] + dat += libcomp_menu[CLAMP(page,1,libcomp_menu.len)] dat += "" dat += "
    AUTHORTITLECATEGORY
    <<<< >>>>
    " dat += "
    (Return to main menu)
    " @@ -444,7 +444,7 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums else var/orderid = input("Enter your order:") as num|null if(orderid) - if(isnum(orderid) && IsInteger(orderid)) + if(isnum(orderid) && ISINTEGER(orderid)) href_list["targetid"] = num2text(orderid) if(href_list["targetid"]) @@ -541,7 +541,7 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums cache = null if(href_list["eject"]) for(var/obj/item/book/B in contents) - B.loc = src.loc + B.forceMove(drop_location()) src.add_fingerprint(usr) src.updateUsrDialog() return @@ -589,4 +589,4 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums B.icon_state = "book[rand(1,7)]" qdel(P) else - P.loc = loc + P.forceMove(drop_location()) diff --git a/code/modules/library/random_books.dm b/code/modules/library/random_books.dm index 769c9ac66b..e101a7143a 100644 --- a/code/modules/library/random_books.dm +++ b/code/modules/library/random_books.dm @@ -1,3 +1,6 @@ +/obj/item/book/manual/random + icon_state = "random_book" + /obj/item/book/manual/random/Initialize() ..() var/static/banned_books = list(/obj/item/book/manual/random, /obj/item/book/manual/nuclear, /obj/item/book/manual/wiki) @@ -6,6 +9,7 @@ return INITIALIZE_HINT_QDEL /obj/item/book/random + icon_state = "random_book" var/amount = 1 var/category = null @@ -20,6 +24,7 @@ /obj/structure/bookcase/random var/category = null var/book_count = 2 + icon_state = "random_bookcase" anchored = TRUE state = 2 diff --git a/code/modules/lighting/lighting_object.dm b/code/modules/lighting/lighting_object.dm index 23d6bdba50..fe25dc9439 100644 --- a/code/modules/lighting/lighting_object.dm +++ b/code/modules/lighting/lighting_object.dm @@ -140,6 +140,9 @@ /atom/movable/lighting_object/blob_act() return +/atom/movable/lighting_object/onTransitZ() + return + // Override here to prevent things accidentally moving around overlays. /atom/movable/lighting_object/forceMove(atom/destination, var/no_tp=FALSE, var/harderforce = FALSE) if(harderforce) diff --git a/code/modules/lighting/lighting_source.dm b/code/modules/lighting/lighting_source.dm index 8e56acc2fb..a6c28b4146 100644 --- a/code/modules/lighting/lighting_source.dm +++ b/code/modules/lighting/lighting_source.dm @@ -232,8 +232,8 @@ var/turf/T if (source_turf) var/oldlum = source_turf.luminosity - source_turf.luminosity = Ceiling(light_range) - for(T in view(Ceiling(light_range), source_turf)) + source_turf.luminosity = CEILING(light_range, 1) + for(T in view(CEILING(light_range, 1), source_turf)) for (thing in T.get_corners(source_turf)) C = thing corners[C] = 0 diff --git a/code/modules/mapping/reader.dm b/code/modules/mapping/reader.dm index 862de852bc..559a93b87f 100644 --- a/code/modules/mapping/reader.dm +++ b/code/modules/mapping/reader.dm @@ -102,7 +102,7 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new) if(!no_changeturf) WARNING("Z-level expansion occurred without no_changeturf set, this may cause problems when /turf/AfterChange is called") - bounds[MAP_MINX] = min(bounds[MAP_MINX], Clamp(xcrdStart, x_lower, x_upper)) + bounds[MAP_MINX] = min(bounds[MAP_MINX], CLAMP(xcrdStart, x_lower, x_upper)) bounds[MAP_MINZ] = min(bounds[MAP_MINZ], zcrd) bounds[MAP_MAXZ] = max(bounds[MAP_MAXZ], zcrd) @@ -119,15 +119,15 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new) if(gridLines.len && gridLines[gridLines.len] == "") gridLines.Cut(gridLines.len) // Remove only one blank line at the end. - bounds[MAP_MINY] = min(bounds[MAP_MINY], Clamp(ycrd, y_lower, y_upper)) + bounds[MAP_MINY] = min(bounds[MAP_MINY], CLAMP(ycrd, y_lower, y_upper)) ycrd += gridLines.len - 1 // Start at the top and work down if(!cropMap && ycrd > world.maxy) if(!measureOnly) world.maxy = ycrd // Expand Y here. X is expanded in the loop below - bounds[MAP_MAXY] = max(bounds[MAP_MAXY], Clamp(ycrd, y_lower, y_upper)) + bounds[MAP_MAXY] = max(bounds[MAP_MAXY], CLAMP(ycrd, y_lower, y_upper)) else - bounds[MAP_MAXY] = max(bounds[MAP_MAXY], Clamp(min(ycrd, world.maxy), y_lower, y_upper)) + bounds[MAP_MAXY] = max(bounds[MAP_MAXY], CLAMP(min(ycrd, world.maxy), y_lower, y_upper)) var/maxx = xcrdStart if(measureOnly) @@ -166,7 +166,7 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new) ++xcrd --ycrd - bounds[MAP_MAXX] = Clamp(max(bounds[MAP_MAXX], cropMap ? min(maxx, world.maxx) : maxx), x_lower, x_upper) + bounds[MAP_MAXX] = CLAMP(max(bounds[MAP_MAXX], cropMap ? min(maxx, world.maxx) : maxx), x_lower, x_upper) CHECK_TICK diff --git a/code/modules/mining/aux_base.dm b/code/modules/mining/aux_base.dm index 8cf6c56037..6b364e63e7 100644 --- a/code/modules/mining/aux_base.dm +++ b/code/modules/mining/aux_base.dm @@ -318,7 +318,8 @@ obj/docking_port/stationary/public_mining_dock qdel(Mport) return - for(var/L in landing_turfs) //You land NEAR the base, not IN it. + for(var/i in 1 to landing_turfs.len) //You land NEAR the base, not IN it. + var/turf/L = landing_turfs[i] if(!L) //This happens at map edges to_chat(user, "Unable to secure a valid docking zone. Please try again in an open area near, but not within the aux. mining base.") SSshuttle.stationary.Remove(Mport) diff --git a/code/modules/mining/equipment/lazarus_injector.dm b/code/modules/mining/equipment/lazarus_injector.dm index c7aa2a1859..1af66e37d6 100644 --- a/code/modules/mining/equipment/lazarus_injector.dm +++ b/code/modules/mining/equipment/lazarus_injector.dm @@ -14,7 +14,6 @@ var/loaded = 1 var/malfunctioning = 0 var/revive_type = SENTIENCE_ORGANIC //So you can't revive boss monsters or robots with it - origin_tech = "biotech=4;magnets=6" /obj/item/lazarus_injector/afterattack(atom/target, mob/user, proximity_flag) if(!loaded) diff --git a/code/modules/mining/equipment/mineral_scanner.dm b/code/modules/mining/equipment/mineral_scanner.dm index 4e6bde732f..52160303cc 100644 --- a/code/modules/mining/equipment/mineral_scanner.dm +++ b/code/modules/mining/equipment/mineral_scanner.dm @@ -11,7 +11,6 @@ slot_flags = SLOT_BELT var/cooldown = 35 var/current_cooldown = 0 - origin_tech = "engineering=1;magnets=1" /obj/item/device/mining_scanner/attack_self(mob/user) if(!user.client) @@ -42,7 +41,6 @@ var/cooldown = 35 var/current_cooldown = 0 var/range = 7 - origin_tech = "engineering=3;magnets=3" /obj/item/device/t_scanner/adv_mining_scanner/lesser name = "automatic mining scanner" diff --git a/code/modules/mining/equipment/mining_tools.dm b/code/modules/mining/equipment/mining_tools.dm index 3b6a7e1b89..61bde60ad0 100644 --- a/code/modules/mining/equipment/mining_tools.dm +++ b/code/modules/mining/equipment/mining_tools.dm @@ -14,7 +14,6 @@ materials = list(MAT_METAL=2000) //one sheet, but where can you make them? var/digspeed = 40 var/list/digsound = list('sound/effects/picaxe1.ogg','sound/effects/picaxe2.ogg','sound/effects/picaxe3.ogg') - origin_tech = "materials=2;engineering=3" attack_verb = list("hit", "pierced", "sliced", "attacked") /obj/item/pickaxe/mini @@ -35,7 +34,6 @@ icon_state = "spickaxe" item_state = "spickaxe" digspeed = 20 //mines faster than a normal pickaxe, bought from mining vendor - origin_tech = "materials=3;engineering=4" desc = "A silver-plated pickaxe that mines slightly faster than standard-issue." force = 17 @@ -44,7 +42,6 @@ icon_state = "dpickaxe" item_state = "dpickaxe" digspeed = 14 - origin_tech = "materials=5;engineering=4" desc = "A pickaxe with a diamond pick head. Extremely robust at cracking rock walls and digging up dirt." force = 19 @@ -56,7 +53,6 @@ digspeed = 25 //available from roundstart, faster than a pickaxe. digsound = list('sound/weapons/drill.ogg') hitsound = 'sound/weapons/drill.ogg' - origin_tech = "materials=2;powerstorage=2;engineering=3" desc = "An electric mining drill for the especially scrawny." /obj/item/pickaxe/drill/cyborg @@ -68,7 +64,6 @@ name = "diamond-tipped mining drill" icon_state = "diamonddrill" digspeed = 7 - origin_tech = "materials=6;powerstorage=4;engineering=4" desc = "Yours is the drill that will pierce the heavens!" /obj/item/pickaxe/drill/cyborg/diamond //This is the BORG version! @@ -81,7 +76,6 @@ icon_state = "jackhammer" item_state = "jackhammer" digspeed = 5 //the epitome of powertools. extremely fast mining, laughs at puny walls - origin_tech = "materials=6;powerstorage=4;engineering=5;magnets=4" digsound = list('sound/weapons/sonic_jackhammer.ogg') hitsound = 'sound/weapons/sonic_jackhammer.ogg' desc = "Cracks rocks with sonic blasts, and doubles as a demolition power tool for smashing walls." @@ -101,7 +95,6 @@ item_state = "shovel" w_class = WEIGHT_CLASS_NORMAL materials = list(MAT_METAL=50) - origin_tech = "materials=2;engineering=2" attack_verb = list("bashed", "bludgeoned", "thrashed", "whacked") sharpness = IS_SHARP diff --git a/code/modules/mining/equipment/regenerative_core.dm b/code/modules/mining/equipment/regenerative_core.dm index d72dda9657..7fa6721c0f 100644 --- a/code/modules/mining/equipment/regenerative_core.dm +++ b/code/modules/mining/equipment/regenerative_core.dm @@ -5,7 +5,6 @@ icon_state = "bottle19" desc = "Inject certain types of monster organs with this stabilizer to preserve their healing powers indefinitely." w_class = WEIGHT_CLASS_TINY - origin_tech = "biotech=3" /obj/item/hivelordstabilizer/afterattack(obj/item/organ/M, mob/user) var/obj/item/organ/regenerative_core/C = M diff --git a/code/modules/mining/equipment/resonator.dm b/code/modules/mining/equipment/resonator.dm index 9edd3a44f6..ebc4816155 100644 --- a/code/modules/mining/equipment/resonator.dm +++ b/code/modules/mining/equipment/resonator.dm @@ -14,14 +14,12 @@ var/fieldlimit = 4 var/list/fields = list() var/quick_burst_mod = 0.8 - origin_tech = "magnets=3;engineering=3" /obj/item/resonator/upgraded name = "upgraded resonator" desc = "An upgraded version of the resonator that can produce more fields at once, as well as having no damage penalty for bursting a resonance field early." icon_state = "resonator_u" item_state = "resonator_u" - origin_tech = "materials=4;powerstorage=3;engineering=3;magnets=3" fieldlimit = 6 quick_burst_mod = 1 diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm index 5fe25b1d1f..4f4b16e6d3 100644 --- a/code/modules/mining/equipment/survival_pod.dm +++ b/code/modules/mining/equipment/survival_pod.dm @@ -14,7 +14,6 @@ icon_state = "capsule" icon = 'icons/obj/mining.dmi' w_class = WEIGHT_CLASS_TINY - origin_tech = "engineering=3;bluespace=3" var/template_id = "shelter_alpha" var/datum/map_template/shelter/template var/used = FALSE @@ -71,7 +70,6 @@ /obj/item/survivalcapsule/luxury name = "luxury bluespace shelter capsule" desc = "An exorbitantly expensive luxury suite stored within a pocket of bluespace." - origin_tech = "engineering=3;bluespace=4" template_id = "shelter_beta" //Pod objects @@ -94,38 +92,19 @@ name = "airlock" icon = 'icons/obj/doors/airlocks/survival/survival.dmi' overlays_file = 'icons/obj/doors/airlocks/survival/survival_overlays.dmi' - note_overlay_file = 'icons/obj/doors/airlocks/survival/survival_overlays.dmi' assemblytype = /obj/structure/door_assembly/door_assembly_pod + +/obj/machinery/door/airlock/survival_pod/glass opacity = FALSE glass = TRUE - var/expected_dir = SOUTH //we visually turn when shuttle rotated, but need to not turn for any other reason - -/obj/machinery/door/airlock/survival_pod/setDir(direction) - direction = expected_dir - ..() - -/obj/machinery/door/airlock/survival_pod/vertical - dir = EAST - expected_dir = EAST /obj/structure/door_assembly/door_assembly_pod name = "pod airlock assembly" icon = 'icons/obj/doors/airlocks/survival/survival.dmi' + base_name = "pod airlock" overlays_file = 'icons/obj/doors/airlocks/survival/survival_overlays.dmi' airlock_type = /obj/machinery/door/airlock/survival_pod - anchored = TRUE - state = 1 - mineral = "glass" - material = "glass" - var/expected_dir = SOUTH - -/obj/structure/door_assembly/door_assembly_pod/setDir(direction) - direction = expected_dir - ..() - -/obj/structure/door_assembly/door_assembly_pod/vertical - dir = EAST - expected_dir = EAST + glass_type = /obj/machinery/door/airlock/survival_pod/glass //Windoor /obj/machinery/door/window/survival_pod diff --git a/code/modules/mining/equipment/wormhole_jaunter.dm b/code/modules/mining/equipment/wormhole_jaunter.dm index 2e6459e6c4..e69c8fa05d 100644 --- a/code/modules/mining/equipment/wormhole_jaunter.dm +++ b/code/modules/mining/equipment/wormhole_jaunter.dm @@ -11,7 +11,6 @@ w_class = WEIGHT_CLASS_SMALL throw_speed = 3 throw_range = 5 - origin_tech = "bluespace=2" slot_flags = SLOT_BELT /obj/item/device/wormhole_jaunter/attack_self(mob/user) diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm index 743e84aca4..f23270e92a 100644 --- a/code/modules/mining/fulton.dm +++ b/code/modules/mining/fulton.dm @@ -80,7 +80,7 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) A.density = FALSE var/obj/effect/extraction_holder/holder_obj = new(A.loc) holder_obj.appearance = A.appearance - A.loc = holder_obj + A.forceMove(holder_obj) balloon2 = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_expand") balloon2.pixel_y = 10 balloon2.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM @@ -113,7 +113,7 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) var/list/flooring_near_beacon = list() for(var/turf/open/floor in orange(1, beacon)) flooring_near_beacon += floor - holder_obj.loc = pick(flooring_near_beacon) + holder_obj.forceMove(pick(flooring_near_beacon)) animate(holder_obj, pixel_z = 10, time = 50) sleep(50) animate(holder_obj, pixel_z = 15, time = 10) @@ -131,7 +131,7 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) A.density = initial(A.density) animate(holder_obj, pixel_z = 0, time = 5) sleep(5) - A.loc = holder_obj.loc + A.forceMove(holder_obj.loc) qdel(holder_obj) if(uses_left <= 0) qdel(src) diff --git a/code/modules/mining/lavaland/ash_flora.dm b/code/modules/mining/lavaland/ash_flora.dm index 6d6587a73a..6ecdc91635 100644 --- a/code/modules/mining/lavaland/ash_flora.dm +++ b/code/modules/mining/lavaland/ash_flora.dm @@ -137,18 +137,10 @@ regrowth_time_low = 4800 regrowth_time_high = 7200 -/obj/structure/flora/ash/cacti/Crossed(mob/AM) - if(ishuman(AM) && has_gravity(loc) && prob(70)) - var/mob/living/carbon/human/H = AM - if(!H.shoes && !H.lying) //ouch, my feet. - var/picked_def_zone = pick("l_leg", "r_leg") - var/obj/item/bodypart/O = H.get_bodypart(picked_def_zone) - if(!istype(O) || (PIERCEIMMUNE in H.dna.species.species_traits)) - return - H.apply_damage(rand(3, 6), BRUTE, picked_def_zone) - H.Knockdown(40) - H.visible_message("[H] steps on a cactus!", \ - "You step on a cactus!") +/obj/structure/flora/ash/cacti/Initialize(mapload) + . = ..() + // min dmg 3, max dmg 6, prob(70) + AddComponent(/datum/component/caltrop, 3, 6, 70) /obj/item/reagent_containers/food/snacks/grown/ash_flora name = "mushroom shavings" diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index 18eb52c8f8..01d6de85e2 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -105,8 +105,7 @@ modkit_design = /datum/design/unique_modkit/bounty /datum/design/unique_modkit - category = list("Mining Designs", "Cyborg Upgrade Modules") - req_tech = list("materials" = 12) //can't be normally obtained + category = list("Mining Designs", "Cyborg Upgrade Modules") //can't be normally obtained build_type = PROTOLATHE | MECHFAB /datum/design/unique_modkit/offensive_turf_aoe @@ -173,7 +172,7 @@ to_chat(M, "Your vision returns to normal.") wisp.stop_orbit() - wisp.loc = src + wisp.forceMove(src) icon_state = "lantern-blue" SSblackbox.record_feedback("tally", "wisp_lantern", 1, "Returned") @@ -413,7 +412,7 @@ /obj/item/device/shared_storage/attackby(obj/item/W, mob/user, params) if(bag) - bag.loc = user + bag.forceMove(user) bag.attackby(W, user, params) @@ -422,7 +421,7 @@ return if(loc == user && user.back && user.back == src) if(bag) - bag.loc = user + bag.forceMove(user) bag.attack_hand(user) else ..() @@ -469,16 +468,19 @@ //Boat -/obj/vehicle/lavaboat +/obj/vehicle/ridden/lavaboat name = "lava boat" desc = "A boat used for traversing lava." icon_state = "goliath_boat" icon = 'icons/obj/lavaland/dragonboat.dmi' resistance_flags = LAVA_PROOF | FIRE_PROOF + can_buckle = TRUE -/obj/vehicle/lavaboat/buckle_mob(mob/living/M, force = 0, check_loc = 1) +/obj/vehicle/ridden/lavaboat/Initialize() . = ..() - riding_datum = new/datum/riding/boat + var/datum/component/riding/D = LoadComponent(/datum/component/riding) + D.keytype = /obj/item/oar + D.allowed_turf_typecache = typecacheof(/turf/open/lava) /obj/item/oar name = "oar" @@ -501,7 +503,7 @@ /datum/crafting_recipe/boat name = "goliath hide boat" - result = /obj/vehicle/lavaboat + result = /obj/vehicle/ridden/lavaboat reqs = list(/obj/item/stack/sheet/animalhide/goliath_hide = 3) time = 50 category = CAT_PRIMAL @@ -518,17 +520,20 @@ /obj/item/ship_in_a_bottle/attack_self(mob/user) to_chat(user, "You're not sure how they get the ships in these things, but you're pretty sure you know how to get it out.") playsound(user.loc, 'sound/effects/glassbr1.ogg', 100, 1) - new /obj/vehicle/lavaboat/dragon(get_turf(src)) + new /obj/vehicle/ridden/lavaboat/dragon(get_turf(src)) qdel(src) -/obj/vehicle/lavaboat/dragon +/obj/vehicle/ridden/lavaboat/dragon name = "mysterious boat" desc = "This boat moves where you will it, without the need for an oar." icon_state = "dragon_boat" -/obj/vehicle/lavaboat/dragon/buckle_mob(mob/living/M, force = 0, check_loc = 1) - ..() - riding_datum = new/datum/riding/boat/dragon +/obj/vehicle/ridden/lavaboat/dragon/Initialize() + . = ..() + var/datum/component/riding/D = LoadComponent(/datum/component/riding) + D.vehicle_move_delay = 1 + D.set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(1, 2), TEXT_SOUTH = list(1, 2), TEXT_EAST = list(1, 2), TEXT_WEST = list( 1, 2))) + D.keytype = null //Potion of Flight /obj/item/reagent_containers/glass/bottle/potion @@ -794,13 +799,13 @@ force = 0 var/ghost_counter = ghost_check() - force = Clamp((ghost_counter * 4), 0, 75) + force = CLAMP((ghost_counter * 4), 0, 75) user.visible_message("[user] strikes with the force of [ghost_counter] vengeful spirits!") ..() /obj/item/melee/ghost_sword/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) var/ghost_counter = ghost_check() - final_block_chance += Clamp((ghost_counter * 5), 0, 75) + final_block_chance += CLAMP((ghost_counter * 5), 0, 75) owner.visible_message("[owner] is protected by a ring of [ghost_counter] ghosts!") return ..() diff --git a/code/modules/mining/lavaland/ruins/gym.dm b/code/modules/mining/lavaland/ruins/gym.dm index 2eb30dc711..efda0f9c8f 100644 --- a/code/modules/mining/lavaland/ruins/gym.dm +++ b/code/modules/mining/lavaland/ruins/gym.dm @@ -29,7 +29,7 @@ icon_state = "fitnesslifter2" user.setDir(SOUTH) user.Stun(80) - user.loc = src.loc + user.forceMove(src.loc) var/bragmessage = pick("pushing it to the limit","going into overdrive","burning with determination","rising up to the challenge", "getting strong now","getting ripped") user.visible_message("[user] is [bragmessage]!") var/lifts = 0 @@ -67,7 +67,7 @@ icon_state = "fitnessweight-c" user.setDir(SOUTH) user.Stun(80) - user.loc = src.loc + user.forceMove(src.loc) var/mutable_appearance/swole_overlay = mutable_appearance(icon, "fitnessweight-w", WALL_OBJ_LAYER) add_overlay(swole_overlay) var/bragmessage = pick("pushing it to the limit","going into overdrive","burning with determination","rising up to the challenge", "getting strong now","getting ripped") @@ -93,4 +93,4 @@ var/finishmessage = pick("You feel stronger!","You feel like you can take on the world!","You feel robust!","You feel indestructible!") icon_state = "fitnessweight" cut_overlay(swole_overlay) - to_chat(user, "[finishmessage]") \ No newline at end of file + to_chat(user, "[finishmessage]") diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm index 757cad5e19..52416787cd 100644 --- a/code/modules/mining/machine_processing.dm +++ b/code/modules/mining/machine_processing.dm @@ -69,17 +69,17 @@ var/on = FALSE var/selected_material = MAT_METAL var/selected_alloy = null - var/datum/research/files + var/datum/techweb/stored_research /obj/machinery/mineral/processing_unit/Initialize() . = ..() proximity_monitor = new(src, 1) AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE), INFINITY) - files = new /datum/research/smelter(src) + stored_research = new /datum/techweb/specialized/autounlocking/smelter /obj/machinery/mineral/processing_unit/Destroy() CONSOLE = null - QDEL_NULL(files) + QDEL_NULL(stored_research) return ..() /obj/machinery/mineral/processing_unit/HasProximity(atom/movable/AM) @@ -112,8 +112,8 @@ dat += "

    " dat += "Smelt Alloys
    " - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] dat += "[D.name] " if (selected_alloy == D.id) dat += " Smelting" @@ -156,7 +156,7 @@ /obj/machinery/mineral/processing_unit/proc/smelt_alloy() - var/datum/design/alloy = files.FindDesignByID(selected_alloy) //check if it's a valid design + var/datum/design/alloy = stored_research.isDesignResearchedID(selected_alloy) //check if it's a valid design if(!alloy) on = FALSE return @@ -174,7 +174,7 @@ /obj/machinery/mineral/processing_unit/proc/can_smelt(datum/design/D) if(D.make_reagents.len) - return 0 + return FALSE var/build_amount = SMELT_AMOUNT @@ -185,7 +185,7 @@ var/datum/material/smelter_mat = materials.materials[mat_id] if(!M || !smelter_mat) - return 0 + return FALSE build_amount = min(build_amount, round(smelter_mat.amount / M)) diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm index 0b1a988fc2..e16eb0e5b2 100644 --- a/code/modules/mining/machine_redemption.dm +++ b/code/modules/mining/machine_redemption.dm @@ -22,16 +22,16 @@ var/list/ore_values = list(MAT_GLASS = 1, MAT_METAL = 1, MAT_PLASMA = 15, MAT_SILVER = 16, MAT_GOLD = 18, MAT_TITANIUM = 30, MAT_URANIUM = 30, MAT_DIAMOND = 50, MAT_BLUESPACE = 50, MAT_BANANIUM = 60) var/message_sent = FALSE var/list/ore_buffer = list() - var/datum/research/files + var/datum/techweb/stored_research var/obj/item/disk/design_disk/inserted_disk /obj/machinery/mineral/ore_redemption/Initialize() . = ..() AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE),INFINITY) - files = new /datum/research/smelter(src) + stored_research = new /datum/techweb/specialized/autounlocking/smelter /obj/machinery/mineral/ore_redemption/Destroy() - QDEL_NULL(files) + QDEL_NULL(stored_research) return ..() /obj/machinery/mineral/ore_redemption/RefreshParts() @@ -70,7 +70,7 @@ /obj/machinery/mineral/ore_redemption/proc/can_smelt_alloy(datum/design/D) if(D.make_reagents.len) - return 0 + return FALSE var/build_amount = 0 @@ -80,12 +80,12 @@ var/datum/material/redemption_mat = materials.materials[mat_id] if(!M || !redemption_mat) - return 0 + return FALSE - var/smeltable_sheets = Floor(redemption_mat.amount / M) + var/smeltable_sheets = FLOOR(redemption_mat.amount / M, 1) if(!smeltable_sheets) - return 0 + return FALSE if(!build_amount) build_amount = smeltable_sheets @@ -215,8 +215,8 @@ data["materials"] += list(list("name" = M.name, "id" = M.id, "amount" = sheet_amount, "value" = ore_values[M.id] * point_upgrade)) data["alloys"] = list() - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] data["alloys"] += list(list("name" = D.name, "id" = D.id, "amount" = can_smelt_alloy(D))) data["diskDesigns"] = list() if(inserted_disk) @@ -299,11 +299,11 @@ if("diskUpload") var/n = text2num(params["design"]) if(inserted_disk && inserted_disk.blueprints && inserted_disk.blueprints[n]) - files.AddDesign2Known(inserted_disk.blueprints[n]) + stored_research.add_design(inserted_disk.blueprints[n]) return TRUE if("Smelt") var/alloy_id = params["id"] - var/datum/design/alloy = files.FindDesignByID(alloy_id) + var/datum/design/alloy = stored_research.isDesignResearchedID(alloy_id) if((check_access(inserted_id) || allowed(usr)) && alloy) var/smelt_amount = can_smelt_alloy(alloy) var/desired = 0 @@ -325,7 +325,7 @@ return TRUE if("SmeltAll") var/alloy_id = params["id"] - var/datum/design/alloy = files.FindDesignByID(alloy_id) + var/datum/design/alloy = stored_research.isDesignResearchedID(alloy_id) if((check_access(inserted_id) || allowed(usr)) && alloy) var/smelt_amount = can_smelt_alloy(alloy) while(smelt_amount > 0) diff --git a/code/modules/mining/machine_stacking.dm b/code/modules/mining/machine_stacking.dm index 3c7e736105..44f13d0a4f 100644 --- a/code/modules/mining/machine_stacking.dm +++ b/code/modules/mining/machine_stacking.dm @@ -88,7 +88,7 @@ stack_list[inp.type] = s var/obj/item/stack/sheet/storage = stack_list[inp.type] storage.amount += inp.amount //Stack the sheets - inp.loc = null //Let the old sheet garbage collect + qdel(inp) //Let the old sheet garbage collect while(storage.amount > stack_amt) //Get rid of excessive stackage var/obj/item/stack/sheet/out = new inp.type() out.amount = stack_amt diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm index 339a6efb33..1e298604eb 100644 --- a/code/modules/mining/machine_vending.dm +++ b/code/modules/mining/machine_vending.dm @@ -110,7 +110,7 @@ if(istype(inserted_id)) if(href_list["choice"] == "eject") to_chat(usr, "You eject the ID from [src]'s card slot.") - inserted_id.loc = loc + inserted_id.forceMove(loc) inserted_id.verb_pickup() inserted_id = null else if(href_list["choice"] == "insert") diff --git a/code/modules/mining/minebot.dm b/code/modules/mining/minebot.dm index 1fcb03e2b6..7caf57b0a6 100644 --- a/code/modules/mining/minebot.dm +++ b/code/modules/mining/minebot.dm @@ -132,11 +132,11 @@ /mob/living/simple_animal/hostile/mining_drone/proc/CollectOre() var/obj/item/ore/O for(O in src.loc) - O.loc = src + O.forceMove(src) for(var/dir in GLOB.alldirs) var/turf/T = get_step(src,dir) for(O in T) - O.loc = src + O.forceMove(src) return /mob/living/simple_animal/hostile/mining_drone/proc/DropOre(message = 1) @@ -148,7 +148,7 @@ to_chat(src, "You dump your stored ore.") for(var/obj/item/ore/O in contents) contents -= O - O.loc = src.loc + O.forceMove(drop_location()) return /mob/living/simple_animal/hostile/mining_drone/adjustHealth(amount) @@ -261,7 +261,6 @@ icon_state = "door_electronics" icon = 'icons/obj/module.dmi' sentience_type = SENTIENCE_MINEBOT - origin_tech = "programming=6" #undef MINEDRONE_COLLECT #undef MINEDRONE_ATTACK diff --git a/code/modules/mining/mint.dm b/code/modules/mining/mint.dm index fef21757d1..ca21456163 100644 --- a/code/modules/mining/mint.dm +++ b/code/modules/mining/mint.dm @@ -68,7 +68,7 @@ if(materials.materials[href_list["choose"]]) chosen = href_list["choose"] if(href_list["chooseAmt"]) - coinsToProduce = Clamp(coinsToProduce + text2num(href_list["chooseAmt"]), 0, 1000) + coinsToProduce = CLAMP(coinsToProduce + text2num(href_list["chooseAmt"]), 0, 1000) if(href_list["makeCoins"]) var/temp_coins = coinsToProduce processing = TRUE @@ -100,4 +100,4 @@ if(!M) M = new /obj/item/storage/bag/money(src) unload_mineral(M) - O.loc = M \ No newline at end of file + O.forceMove(M) diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm index d5529a7242..65b2b47117 100644 --- a/code/modules/mining/ores_coins.dm +++ b/code/modules/mining/ores_coins.dm @@ -68,7 +68,6 @@ /obj/item/ore/uranium name = "uranium ore" icon_state = "Uranium ore" - origin_tech = "materials=5" points = 30 materials = list(MAT_URANIUM=MINERAL_MATERIAL_AMOUNT) refined_type = /obj/item/stack/sheet/mineral/uranium @@ -76,7 +75,6 @@ /obj/item/ore/iron name = "iron ore" icon_state = "Iron ore" - origin_tech = "materials=1" points = 1 materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT) refined_type = /obj/item/stack/sheet/metal @@ -84,7 +82,6 @@ /obj/item/ore/glass name = "sand pile" icon_state = "Glass ore" - origin_tech = "materials=1" points = 1 materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT) refined_type = /obj/item/stack/sheet/glass @@ -135,7 +132,6 @@ /obj/item/ore/plasma name = "plasma ore" icon_state = "Plasma ore" - origin_tech = "plasmatech=2;materials=2" points = 15 materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT) refined_type = /obj/item/stack/sheet/mineral/plasma @@ -152,7 +148,6 @@ /obj/item/ore/silver name = "silver ore" icon_state = "Silver ore" - origin_tech = "materials=3" points = 16 materials = list(MAT_SILVER=MINERAL_MATERIAL_AMOUNT) refined_type = /obj/item/stack/sheet/mineral/silver @@ -160,7 +155,6 @@ /obj/item/ore/gold name = "gold ore" icon_state = "Gold ore" - origin_tech = "materials=4" points = 18 materials = list(MAT_GOLD=MINERAL_MATERIAL_AMOUNT) refined_type = /obj/item/stack/sheet/mineral/gold @@ -168,7 +162,6 @@ /obj/item/ore/diamond name = "diamond ore" icon_state = "Diamond ore" - origin_tech = "materials=6" points = 50 materials = list(MAT_DIAMOND=MINERAL_MATERIAL_AMOUNT) refined_type = /obj/item/stack/sheet/mineral/diamond @@ -176,7 +169,6 @@ /obj/item/ore/bananium name = "bananium ore" icon_state = "Clown ore" - origin_tech = "materials=4" points = 60 materials = list(MAT_BANANIUM=MINERAL_MATERIAL_AMOUNT) refined_type = /obj/item/stack/sheet/mineral/bananium @@ -184,7 +176,6 @@ /obj/item/ore/titanium name = "titanium ore" icon_state = "Titanium ore" - origin_tech = "materials=4" points = 50 materials = list(MAT_TITANIUM=MINERAL_MATERIAL_AMOUNT) refined_type = /obj/item/stack/sheet/mineral/titanium diff --git a/code/modules/mining/satchel_ore_boxdm.dm b/code/modules/mining/satchel_ore_boxdm.dm index 4c772a7019..8e58da8e05 100644 --- a/code/modules/mining/satchel_ore_boxdm.dm +++ b/code/modules/mining/satchel_ore_boxdm.dm @@ -81,3 +81,6 @@ WD.add_fingerprint(user) dump_box_contents() qdel(src) + +/obj/structure/ore_box/onTransitZ() + return \ No newline at end of file diff --git a/code/modules/mob/camera/camera.dm b/code/modules/mob/camera/camera.dm index e058782be1..9a95bc9a4a 100644 --- a/code/modules/mob/camera/camera.dm +++ b/code/modules/mob/camera/camera.dm @@ -1,15 +1,18 @@ -// Camera mob, used by AI camera and blob. - -/mob/camera - name = "camera mob" +// Camera mob, used by AI camera and blob. + +/mob/camera + name = "camera mob" density = FALSE anchored = TRUE - status_flags = GODMODE // You can't damage it. + status_flags = GODMODE // You can't damage it. mouse_opacity = MOUSE_OPACITY_TRANSPARENT - see_in_dark = 7 - invisibility = INVISIBILITY_ABSTRACT // No one can see us - sight = SEE_SELF - move_on_shuttle = 0 - -/mob/camera/experience_pressure_difference() - return + see_in_dark = 7 + invisibility = INVISIBILITY_ABSTRACT // No one can see us + sight = SEE_SELF + move_on_shuttle = 0 + +/mob/camera/experience_pressure_difference() + return + +/mob/camera/forceMove(atom/destination) + loc = destination diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm index 26b671dd96..1142d2d6cb 100644 --- a/code/modules/mob/dead/dead.dm +++ b/code/modules/mob/dead/dead.dm @@ -24,7 +24,26 @@ INITIALIZE_IMMEDIATE(/mob/dead) /mob/dead/ConveyorMove() //lol return +/mob/dead/forceMove(atom/destination) + loc = destination +/mob/dead/Stat() + ..() + + if(!statpanel("Status")) + return + stat(null, "Game Mode: [SSticker.hide_mode ? "Secret" : "[GLOB.master_mode]"]") + + if(SSticker.HasRoundStarted()) + return + + var/time_remaining = SSticker.GetTimeLeft() + if(time_remaining > 0) + stat(null, "Time To Start: [round(time_remaining/10)]s") + else if(time_remaining == -10) + stat(null, "Time To Start: DELAYED") + else + stat(null, "Time To Start: SOON") /mob/dead/proc/server_hop() set category = "OOC" diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 458a54aa48..573183df96 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -21,9 +21,9 @@ S.Fade(TRUE) if(length(GLOB.newplayer_start)) - loc = pick(GLOB.newplayer_start) + forceMove(pick(GLOB.newplayer_start)) else - loc = locate(1,1,1) + forceMove(locate(1,1,1)) ComponentInitialize() @@ -185,7 +185,7 @@ var/pollid = href_list["pollid"] if(istext(pollid)) pollid = text2num(pollid) - if(isnum(pollid) && IsInteger(pollid)) + if(isnum(pollid) && ISINTEGER(pollid)) src.poll_player(pollid) return @@ -223,7 +223,7 @@ rating = null else rating = text2num(href_list["o[optionid]"]) - if(!isnum(rating) || !IsInteger(rating)) + if(!isnum(rating) || !ISINTEGER(rating)) return if(!vote_on_numval_poll(pollid, optionid, rating)) @@ -282,7 +282,7 @@ var/obj/effect/landmark/observer_start/O = locate(/obj/effect/landmark/observer_start) in GLOB.landmarks_list to_chat(src, "Now teleporting.") if (O) - observer.loc = O.loc + observer.forceMove(O.loc) else to_chat(src, "Teleporting failed. Ahelp an admin please") stack_trace("There's no freaking observer landmark available on this map or you're making observers before the map is initialised") diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index ca6b504294..4481de1e36 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -32,7 +32,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) var/ghost_hud_enabled = 1 //did this ghost disable the on-screen HUD? var/data_huds_on = 0 //Are data HUDs currently enabled? var/health_scan = FALSE //Are health scans currently enabled? - var/list/datahuds = list(DATA_HUD_SECURITY_ADVANCED, DATA_HUD_MEDICAL_ADVANCED, DATA_HUD_DIAGNOSTIC) //list of data HUDs shown to ghosts. + var/list/datahuds = list(DATA_HUD_SECURITY_ADVANCED, DATA_HUD_MEDICAL_ADVANCED, DATA_HUD_DIAGNOSTIC_ADVANCED) //list of data HUDs shown to ghosts. var/ghost_orbit = GHOST_ORBIT_CIRCLE //These variables store hair data if the ghost originates from a species with head and/or facial hair. @@ -109,7 +109,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) else T = locate(round(world.maxx/2), round(world.maxy/2), ZLEVEL_STATION_PRIMARY) //middle of the station - loc = T + forceMove(T) if(!name) //To prevent nameless ghosts name = random_unique_name(gender) @@ -288,10 +288,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp var/oldloc = loc if(NewLoc) - loc = NewLoc + forceMove(NewLoc) update_parallax_contents() else - loc = get_turf(src) //Get out of closets and such as a ghost + forceMove(get_turf(src)) //Get out of closets and such as a ghost if((direct & NORTH) && y < world.maxy) y++ else if((direct & SOUTH) && y > 1) @@ -320,7 +320,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(mind.current.key && copytext(mind.current.key,1,2)!="@") //makes sure we don't accidentally kick any clients to_chat(usr, "Another consciousness is in your body...It is resisting you.") return - client.change_view(world.view) + client.change_view(CONFIG_GET(string/default_view)) SStgui.on_transfer(src, mind.current) // Transfer NanoUIs. mind.current.key = key return 1 @@ -371,7 +371,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(!L || !L.len) to_chat(usr, "No area available.") - usr.loc = pick(L) + usr.forceMove(pick(L)) update_parallax_contents() /mob/dead/observer/verb/follow() @@ -445,7 +445,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp var/turf/T = get_turf(M) //Turf of the destination mob if(T && isturf(T)) //Make sure the turf exists, then move the source to that destination. - A.loc = T + A.forceMove(T) A.update_parallax_contents() else to_chat(A, "This mob is not located in the game world.") @@ -456,22 +456,22 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp set desc = "Change your view range." var/max_view = client.prefs.unlock_content ? GHOST_MAX_VIEW_RANGE_MEMBER : GHOST_MAX_VIEW_RANGE_DEFAULT - if(client.view == world.view) + if(client.view == CONFIG_GET(string/default_view)) var/list/views = list() for(var/i in 7 to max_view) views |= i var/new_view = input("Choose your new view", "Modify view range", 7) as null|anything in views if(new_view) - client.change_view(Clamp(new_view, 7, max_view)) + client.change_view(CLAMP(new_view, 7, max_view)) else - client.change_view(world.view) + client.change_view(CONFIG_GET(string/default_view)) /mob/dead/observer/verb/add_view_range(input as num) set name = "Add View Range" set hidden = TRUE var/max_view = client.prefs.unlock_content ? GHOST_MAX_VIEW_RANGE_MEMBER : GHOST_MAX_VIEW_RANGE_DEFAULT if(input) - client.change_view(Clamp(client.view + input, 7, max_view)) + client.rescale_view(input, 7, max_view) /mob/dead/observer/verb/boo() set category = "Ghost" diff --git a/code/modules/mob/living/bloodcrawl.dm b/code/modules/mob/living/bloodcrawl.dm index b749bcda91..0052cf923d 100644 --- a/code/modules/mob/living/bloodcrawl.dm +++ b/code/modules/mob/living/bloodcrawl.dm @@ -160,7 +160,7 @@ return if(!B) return - src.loc = B.loc + forceMove(B.loc) src.client.eye = src src.visible_message("[src] rises out of the pool of blood!") exit_blood_effect(B) diff --git a/code/modules/mob/living/brain/MMI.dm b/code/modules/mob/living/brain/MMI.dm index 0ee21336d4..e090592ba3 100644 --- a/code/modules/mob/living/brain/MMI.dm +++ b/code/modules/mob/living/brain/MMI.dm @@ -4,7 +4,6 @@ icon = 'icons/obj/assemblies.dmi' icon_state = "mmi_empty" w_class = WEIGHT_CLASS_NORMAL - origin_tech = "biotech=2;programming=3;engineering=2" var/braintype = "Cyborg" var/obj/item/device/radio/radio = null //Let's give it a radio. var/mob/living/brain/brainmob = null //The current occupant. @@ -58,7 +57,7 @@ brainmob = newbrain.brainmob newbrain.brainmob = null - brainmob.loc = src + brainmob.forceMove(src) brainmob.container = src if(!newbrain.damaged_brain) // the brain organ hasn't been beaten to death. brainmob.stat = CONSCIOUS //we manually revive the brain mob @@ -91,7 +90,7 @@ /obj/item/device/mmi/proc/eject_brain(mob/user) brainmob.container = null //Reset brainmob mmi var. - brainmob.loc = brain //Throw mob into brain. + brainmob.forceMove(brain) //Throw mob into brain. brainmob.stat = DEAD brainmob.emp_damage = 0 brainmob.reset_perspective() //so the brainmob follows the brain organ instead of the mmi. And to update our vision @@ -121,7 +120,7 @@ if(ishuman(L)) var/mob/living/carbon/human/H = L var/obj/item/organ/brain/newbrain = H.getorgan(/obj/item/organ/brain) - newbrain.loc = src + newbrain.forceMove(src) brain = newbrain else if(!brain) brain = new(src) @@ -205,7 +204,6 @@ /obj/item/device/mmi/syndie name = "Syndicate Man-Machine Interface" desc = "Syndicate's own brand of MMI. It enforces laws designed to help Syndicate agents achieve their goals upon cyborgs and AIs created with it." - origin_tech = "biotech=4;programming=4;syndicate=2" overrides_aicore_laws = TRUE /obj/item/device/mmi/syndie/Initialize() diff --git a/code/modules/mob/living/brain/brain.dm b/code/modules/mob/living/brain/brain.dm index c175acf9d6..365fe5cb01 100644 --- a/code/modules/mob/living/brain/brain.dm +++ b/code/modules/mob/living/brain/brain.dm @@ -12,8 +12,8 @@ stored_dna.initialize_dna(random_blood_type()) if(isturf(loc)) //not spawned in an MMI or brain organ (most likely adminspawned) var/obj/item/organ/brain/OB = new(loc) //we create a new brain organ for it. - loc = OB OB.brainmob = src + forceMove(OB) /mob/living/brain/proc/create_dna() @@ -71,3 +71,16 @@ var/obj/mecha/M = MMI.mecha if((src == MMI.brainmob) && istype(M)) return M.click_action(A,src,params) + +/mob/living/brain/forceMove(atom/destination) + if(container) + return container.forceMove(destination) + else if (istype(loc, /obj/item/organ/brain)) + var/obj/item/organ/brain/B = loc + B.forceMove(destination) + else if (istype(destination, /obj/item/organ/brain)) + doMove(destination) + else if (istype(destination, /obj/item/device/mmi)) + doMove(destination) + else + CRASH("Brainmob without a container [src] attempted to move to [destination].") diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index 55f0c0b681..aef5489b04 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -8,12 +8,13 @@ zone = "head" slot = ORGAN_SLOT_BRAIN vital = TRUE - origin_tech = "biotech=5" attack_verb = list("attacked", "slapped", "whacked") var/mob/living/brain/brainmob = null var/damaged_brain = FALSE //whether the brain organ is damaged. var/decoy_override = FALSE //I apologize to the security players, and myself, who abused this, but this is going to go. + var/list/datum/brain_trauma/traumas = list() + /obj/item/organ/brain/changeling_brain vital = FALSE decoy_override = TRUE @@ -26,7 +27,7 @@ if(C.mind && C.mind.has_antag_datum(/datum/antagonist/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 + forceMove(C) C.update_hair() return @@ -41,11 +42,21 @@ QDEL_NULL(brainmob) + for(var/X in traumas) + var/datum/brain_trauma/BT = X + BT.owner = owner + BT.on_gain() + //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, no_id_transfer = FALSE) ..() + for(var/X in traumas) + var/datum/brain_trauma/BT = X + BT.on_lose(TRUE) + BT.owner = null + if((!gc_destroyed || (owner && !owner.gc_destroyed)) && !no_id_transfer) transfer_identity(C) C.update_hair() @@ -134,6 +145,30 @@ else ..() +/obj/item/organ/brain/proc/get_brain_damage() + var/brain_damage_threshold = max_integrity * BRAIN_DAMAGE_INTEGRITY_MULTIPLIER + var/offset_integrity = obj_integrity - (max_integrity - brain_damage_threshold) + . = (1 - (offset_integrity / brain_damage_threshold)) * BRAIN_DAMAGE_DEATH + +/obj/item/organ/brain/proc/adjust_brain_damage(amount, maximum) + var/adjusted_amount + if(amount >= 0 && maximum) + var/brainloss = get_brain_damage() + var/new_brainloss = CLAMP(brainloss + amount, 0, maximum) + if(brainloss > new_brainloss) //brainloss is over the cap already + return 0 + adjusted_amount = new_brainloss - brainloss + else + adjusted_amount = amount + + adjusted_amount *= BRAIN_DAMAGE_INTEGRITY_MULTIPLIER + if(adjusted_amount) + if(adjusted_amount >= 0.1) + take_damage(adjusted_amount) + else if(adjusted_amount <= -0.1) + obj_integrity = min(max_integrity, obj_integrity-adjusted_amount) + . = adjusted_amount + /obj/item/organ/brain/Destroy() //copypasted from MMIs. if(brainmob) qdel(brainmob) @@ -144,4 +179,46 @@ name = "alien brain" desc = "We barely understand the brains of terrestial animals. Who knows what we may find in the brain of such an advanced species?" icon_state = "brain-x" - origin_tech = "biotech=6" + + +////////////////////////////////////TRAUMAS//////////////////////////////////////// + +/obj/item/organ/brain/proc/has_trauma_type(brain_trauma_type, consider_permanent = FALSE) + for(var/X in traumas) + var/datum/brain_trauma/BT = X + if(istype(BT, brain_trauma_type) && (consider_permanent || !BT.permanent)) + return BT + + +//Add a specific trauma +/obj/item/organ/brain/proc/gain_trauma(datum/brain_trauma/trauma, permanent = FALSE, list/arguments) + var/trauma_type + if(ispath(trauma)) + trauma_type = trauma + traumas += new trauma_type(arglist(list(src, permanent) + arguments)) + else + traumas += trauma + trauma.permanent = permanent + +//Add a random trauma of a certain subtype +/obj/item/organ/brain/proc/gain_trauma_type(brain_trauma_type = /datum/brain_trauma, permanent = FALSE) + var/list/datum/brain_trauma/possible_traumas = list() + for(var/T in subtypesof(brain_trauma_type)) + var/datum/brain_trauma/BT = T + if(initial(BT.can_gain)) + possible_traumas += BT + + var/trauma_type = pick(possible_traumas) + traumas += new trauma_type(src, permanent) + +//Cure a random trauma of a certain subtype +/obj/item/organ/brain/proc/cure_trauma_type(brain_trauma_type, cure_permanent = FALSE) + var/datum/brain_trauma/trauma = has_trauma_type(brain_trauma_type) + if(trauma && (cure_permanent || !trauma.permanent)) + qdel(trauma) + +/obj/item/organ/brain/proc/cure_all_traumas(cure_permanent = FALSE) + for(var/X in traumas) + var/datum/brain_trauma/trauma = X + if(cure_permanent || !trauma.permanent) + qdel(trauma) diff --git a/code/modules/mob/living/brain/posibrain.dm b/code/modules/mob/living/brain/posibrain.dm index 3bf0525996..33a274c762 100644 --- a/code/modules/mob/living/brain/posibrain.dm +++ b/code/modules/mob/living/brain/posibrain.dm @@ -6,7 +6,6 @@ GLOBAL_VAR(posibrain_notify_cooldown) icon = 'icons/obj/assemblies.dmi' icon_state = "posibrain" w_class = WEIGHT_CLASS_NORMAL - origin_tech = "biotech=3;programming=3;plasmatech=2" var/next_ask var/askDelay = 600 //one minute var/searching = FALSE @@ -158,7 +157,7 @@ GLOBAL_VAR(posibrain_notify_cooldown) new_name = pick(possible_names) brainmob.name = "[new_name]-[rand(100, 999)]" brainmob.real_name = brainmob.name - brainmob.loc = src + brainmob.forceMove(src) brainmob.container = src if(autoping) ping_ghosts("created", TRUE) diff --git a/code/modules/mob/living/brain/say.dm b/code/modules/mob/living/brain/say.dm index 0cfbf5d170..0f8e9e60bd 100644 --- a/code/modules/mob/living/brain/say.dm +++ b/code/modules/mob/living/brain/say.dm @@ -21,7 +21,7 @@ return ITALICS | REDUCE_RANGE /mob/living/brain/lingcheck() - return 0 + return LINGHIVE_NONE /mob/living/brain/treat_message(message) message = capitalize(message) diff --git a/code/modules/mob/living/brain/status_procs.dm b/code/modules/mob/living/brain/status_procs.dm index c5e01efcf9..2baea2e7cd 100644 --- a/code/modules/mob/living/brain/status_procs.dm +++ b/code/modules/mob/living/brain/status_procs.dm @@ -22,4 +22,4 @@ return /mob/living/brain/set_blurriness() - return + return \ No newline at end of file diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm index eb17ecc40a..0760453094 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm @@ -59,6 +59,14 @@ Doesn't work on other aliens/AI.*/ return 0 return 1 +/obj/effect/proc_holder/alien/proc/check_vent_block(mob/living/user) + var/obj/machinery/atmospherics/components/unary/atmos_thing = locate() in user.loc + if(atmos_thing) + var/rusure = alert(user, "Laying eggs and shaping resin here would block access to [atmos_thing]. Do you want to continue?", "Blocking Atmospheric Component", "Yes", "No") + if(rusure != "No") + return FALSE + return TRUE + /obj/effect/proc_holder/alien/plant name = "Plant Weeds" desc = "Plants some alien weeds." @@ -243,7 +251,7 @@ Doesn't work on other aliens/AI.*/ name = "Secrete Resin" desc = "Secrete tough malleable resin." plasma_cost = 55 - check_turf = 1 + check_turf = TRUE var/list/structures = list( "resin wall" = /obj/structure/alien/resin/wall, "resin membrane" = /obj/structure/alien/resin/membrane, @@ -254,18 +262,22 @@ Doesn't work on other aliens/AI.*/ /obj/effect/proc_holder/alien/resin/fire(mob/living/carbon/user) if(locate(/obj/structure/alien/resin) in user.loc) to_chat(user, "There is already a resin structure there.") - return 0 + return FALSE + + if(!check_vent_block(user)) + return FALSE + var/choice = input("Choose what you wish to shape.","Resin building") as null|anything in structures if(!choice) - return 0 + return FALSE if (!cost_check(check_turf,user)) - return 0 + return FALSE to_chat(user, "You shape a [choice].") user.visible_message("[user] vomits up a thick purple substance and begins to shape it.") choice = structures[choice] new choice(user.loc) - return 1 + return TRUE /obj/effect/proc_holder/alien/regurgitate name = "Regurgitate" @@ -277,7 +289,7 @@ Doesn't work on other aliens/AI.*/ if(user.stomach_contents.len) for(var/atom/movable/A in user.stomach_contents) user.stomach_contents.Remove(A) - A.loc = user.loc + A.forceMove(user.drop_location()) if(isliving(A)) var/mob/M = A M.reset_perspective() diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index fdca497bc3..fc759ec827 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -106,7 +106,7 @@ for(var/atom/movable/A in stomach_contents) stomach_contents.Remove(A) new_xeno.stomach_contents.Add(A) - A.loc = new_xeno + A.forceMove(new_xeno) ..() //For alien evolution/promotion/queen finder procs. Checks for an active alien of that type diff --git a/code/modules/mob/living/carbon/alien/humanoid/queen.dm b/code/modules/mob/living/carbon/alien/humanoid/queen.dm index 4f79ed7d25..5a48e1c6d1 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/queen.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/queen.dm @@ -79,16 +79,20 @@ name = "Lay Egg" desc = "Lay an egg to produce huggers to impregnate prey with." plasma_cost = 75 - check_turf = 1 + check_turf = TRUE action_icon_state = "alien_egg" /obj/effect/proc_holder/alien/lay_egg/fire(mob/living/carbon/user) if(locate(/obj/structure/alien/egg) in get_turf(user)) - to_chat(user, "There's already an egg here.") - return 0 + to_chat(user, "There's already an egg here.") + return FALSE + + if(!check_vent_block(user)) + return FALSE + user.visible_message("[user] has laid an egg!") new /obj/structure/alien/egg(user.loc) - return 1 + return TRUE //Button to let queen choose her praetorian. /obj/effect/proc_holder/alien/royal/queen/promote diff --git a/code/modules/mob/living/carbon/alien/organs.dm b/code/modules/mob/living/carbon/alien/organs.dm index ae8eec5529..97d0509dfb 100644 --- a/code/modules/mob/living/carbon/alien/organs.dm +++ b/code/modules/mob/living/carbon/alien/organs.dm @@ -1,5 +1,4 @@ /obj/item/organ/alien - origin_tech = "biotech=5" icon_state = "xgibmid2" var/list/alien_powers = list() @@ -30,7 +29,6 @@ /obj/item/organ/alien/plasmavessel name = "plasma vessel" icon_state = "plasma" - origin_tech = "biotech=5;plasmatech=4" w_class = WEIGHT_CLASS_NORMAL zone = "chest" slot = "plasmavessel" @@ -55,7 +53,6 @@ plasma_rate = 15 /obj/item/organ/alien/plasmavessel/large/queen - origin_tech = "biotech=6;plasmatech=4" plasma_rate = 20 /obj/item/organ/alien/plasmavessel/small @@ -109,7 +106,6 @@ icon_state = "hivenode" zone = "head" slot = "hivenode" - origin_tech = "biotech=5;magnets=4;bluespace=3" w_class = WEIGHT_CLASS_TINY var/recent_queen_death = 0 //Indicates if the queen died recently, aliens are heavily weakened while this is active. alien_powers = list(/obj/effect/proc_holder/alien/whisper) @@ -162,7 +158,6 @@ icon_state = "stomach-x" zone = "mouth" slot = "resinspinner" - origin_tech = "biotech=5;materials=4" alien_powers = list(/obj/effect/proc_holder/alien/resin) @@ -171,7 +166,6 @@ icon_state = "acid" zone = "mouth" slot = "acidgland" - origin_tech = "biotech=5;materials=2;combat=2" alien_powers = list(/obj/effect/proc_holder/alien/acid) @@ -180,7 +174,6 @@ icon_state = "neurotox" zone = "mouth" slot = "neurotoxingland" - origin_tech = "biotech=5;combat=5" alien_powers = list(/obj/effect/proc_holder/alien/neurotoxin) @@ -190,5 +183,4 @@ zone = "groin" slot = "eggsac" w_class = WEIGHT_CLASS_BULKY - origin_tech = "biotech=6" alien_powers = list(/obj/effect/proc_holder/alien/lay_egg) diff --git a/code/modules/mob/living/carbon/alien/status_procs.dm b/code/modules/mob/living/carbon/alien/status_procs.dm index 61de87b6cb..33ba8fea1d 100644 --- a/code/modules/mob/living/carbon/alien/status_procs.dm +++ b/code/modules/mob/living/carbon/alien/status_procs.dm @@ -17,4 +17,4 @@ /mob/living/carbon/alien/AdjustStun(amount, updating = 1, ignore_canstun = 0) . = ..() if(!.) - move_delay_add = Clamp(move_delay_add + round(amount/2), 0, 10) + move_delay_add = CLAMP(move_delay_add + round(amount/2), 0, 10) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index ff815776f5..819ed8072f 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -38,7 +38,7 @@ if(prob(src.getBruteLoss() - 50)) for(var/atom/movable/A in stomach_contents) - A.loc = loc + A.forceMove(drop_location()) stomach_contents.Remove(A) src.gib() @@ -112,7 +112,8 @@ take_bodypart_damage(10) victim.Knockdown(20) Knockdown(20) - visible_message("[src] crashes into [victim], knocking them both over!", "You violently crash into [victim]!") + visible_message("[src] crashes into [victim], knocking them both over!",\ + "You violently crash into [victim]!") playsound(src,'sound/weapons/punch1.ogg',50,1) @@ -156,6 +157,8 @@ if(!throwable_mob.buckled) thrown_thing = throwable_mob stop_pulling() + if(disabilities & PACIFISM) + to_chat(src, "You gently let go of [throwable_mob].") var/turf/start_T = get_turf(loc) //Get the start and target tile for the descriptors var/turf/end_T = get_turf(target) if(start_T && end_T) @@ -167,6 +170,10 @@ thrown_thing = I dropItemToGround(I) + if(disabilities & PACIFISM && I.throwforce) + to_chat(src, "You set [I] down gently on the ground.") + return + if(thrown_thing) visible_message("[src] has thrown [thrown_thing].") add_logs(src, thrown_thing, "has thrown") @@ -331,7 +338,7 @@ if (client) client.screen -= W if (W) - W.loc = loc + W.forceMove(drop_location()) W.dropped(src) if (W) W.layer = initial(W.layer) @@ -344,7 +351,7 @@ if (client) client.screen -= W if (W) - W.loc = loc + W.forceMove(drop_location()) W.dropped(src) if (W) W.layer = initial(W.layer) @@ -371,7 +378,7 @@ else if(I == handcuffed) - handcuffed.loc = loc + handcuffed.forceMove(drop_location()) handcuffed.dropped(src) handcuffed = null if(buckled && buckled.buckle_requires_restraints) @@ -379,7 +386,7 @@ update_handcuffed() return if(I == legcuffed) - legcuffed.loc = loc + legcuffed.forceMove(drop_location()) legcuffed.dropped() legcuffed = null update_inv_legcuffed() @@ -765,6 +772,7 @@ update_handcuffed() if(reagents) reagents.addiction_list = list() + cure_all_traumas(TRUE, TRUE) ..() // heal ears after healing disabilities, since ears check DEAF disability // when healing. @@ -784,7 +792,7 @@ if(prob(50)) organs_amt++ O.Remove(src) - O.loc = get_turf(src) + O.forceMove(drop_location()) if(organs_amt) to_chat(user, "You retrieve some of [src]\'s internal organs!") @@ -849,3 +857,5 @@ .["Modify bodypart"] = "?_src_=vars;[HrefToken()];editbodypart=[REF(src)]" .["Modify organs"] = "?_src_=vars;[HrefToken()];editorgans=[REF(src)]" .["Hallucinate"] = "?_src_=vars;[HrefToken()];hallucinate=[REF(src)]" + .["Give brain trauma"] = "?_src_=vars;[HrefToken()];givetrauma=[REF(src)]" + .["Cure brain traumas"] = "?_src_=vars;[HrefToken()];curetraumas=[REF(src)]" diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 9cccd4418d..0bfa287a09 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -229,7 +229,7 @@ "[src] was shocked by \the [source]!", \ "You feel a powerful shock coursing through your body!", \ "You hear a heavy electrical crack." \ - ) + ) jitteriness += 1000 //High numbers for violent convulsions do_jitter_animation(jitteriness) stuttering += 2 diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index 45c10c6ae9..d601fde492 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -2,6 +2,7 @@ gender = MALE pressure_resistance = 15 possible_a_intents = list(INTENT_HELP, INTENT_HARM) + hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD,GLAND_HUD) var/list/stomach_contents = list() var/list/internal_organs = list() //List of /obj/item/organ in the mob. They don't go in the contents for some reason I don't want to know. var/list/internal_organs_slot= list() //Same as above, but stores "slot ID" - "organ" pairs for easy access. @@ -49,3 +50,10 @@ var/icon_render_key = "" var/static/list/limb_icon_cache = list() + + //halucination vars + var/image/halimage + var/image/halbody + var/obj/halitem + var/hal_screwyhud = SCREWYHUD_NONE + var/next_hallucination = 0 diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm index ebf1d6284d..9ba1dcc033 100644 --- a/code/modules/mob/living/carbon/damage_procs.dm +++ b/code/modules/mob/living/carbon/damage_procs.dm @@ -185,7 +185,7 @@ /mob/living/carbon/adjustStaminaLoss(amount, updating_stamina = 1) if(status_flags & GODMODE) return 0 - staminaloss = Clamp(staminaloss + amount, 0, maxHealth*2) + staminaloss = CLAMP(staminaloss + amount, 0, maxHealth*2) if(updating_stamina) update_stamina() @@ -196,3 +196,45 @@ staminaloss = amount if(updating_stamina) update_stamina() + +/mob/living/carbon/getBrainLoss() + . = 0 + var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN) + if(B) + . = B.get_brain_damage() + +//Some sources of brain damage shouldn't be deadly +/mob/living/carbon/adjustBrainLoss(amount, maximum = BRAIN_DAMAGE_DEATH) + if(status_flags & GODMODE) + return 0 + var/prev_brainloss = getBrainLoss() + var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN) + if(!B) + return + B.adjust_brain_damage(amount, maximum) + if(amount <= 0) //cut this early + return + var/brainloss = getBrainLoss() + if(brainloss > BRAIN_DAMAGE_MILD && !has_trauma_type(BRAIN_TRAUMA_MILD)) + if(prob((amount * 2) + ((brainloss - BRAIN_DAMAGE_MILD) / 5))) //1 damage|50 brain damage = 4% chance + gain_trauma_type(BRAIN_TRAUMA_MILD) + if(brainloss > BRAIN_DAMAGE_SEVERE && !has_trauma_type(BRAIN_TRAUMA_SEVERE) && !has_trauma_type(BRAIN_TRAUMA_SPECIAL)) + if(prob(amount + ((brainloss - BRAIN_DAMAGE_SEVERE) / 15))) //1 damage|150 brain damage = 3% chance + if(prob(20)) + gain_trauma_type(BRAIN_TRAUMA_SPECIAL) + else + gain_trauma_type(BRAIN_TRAUMA_SEVERE) + + if(prev_brainloss < 40 && brainloss >= 40) + to_chat(src, "You feel lightheaded.") + else if(prev_brainloss < 120 && brainloss >= 120) + to_chat(src, "You feel less in control of your thoughts.") + else if(prev_brainloss < 180 && brainloss >= 180) + to_chat(src, "You can feel your mind flickering on and off...") + +/mob/living/carbon/setBrainLoss(amount) + var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN) + if(B) + var/adjusted_amount = amount - B.get_brain_damage() + B.adjust_brain_damage(adjusted_amount, null) + diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index 53b087d768..b8d9d510fd 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -43,33 +43,34 @@ msg += "" var/temp = getBruteLoss() - if(temp) - if (temp < 25) - msg += "[t_He] [t_has] minor bruising.\n" - else if (temp < 50) - msg += "[t_He] [t_has] moderate bruising!\n" - else - msg += "[t_He] [t_has] severe bruising!\n" + if(!(user == src && src.hal_screwyhud == SCREWYHUD_HEALTHY)) //fake healthy + if(temp) + if (temp < 25) + msg += "[t_He] [t_has] minor bruising.\n" + else if (temp < 50) + msg += "[t_He] [t_has] moderate bruising!\n" + else + msg += "[t_He] [t_has] severe bruising!\n" - temp = getFireLoss() - if(temp) - if (temp < 25) - msg += "[t_He] [t_has] minor burns.\n" - else if (temp < 50) - msg += "[t_He] [t_has] moderate burns!\n" - else - msg += "[t_He] [t_has] severe burns!\n" + temp = getFireLoss() + if(temp) + if (temp < 25) + msg += "[t_He] [t_has] minor burns.\n" + else if (temp < 50) + msg += "[t_He] [t_has] moderate burns!\n" + else + msg += "[t_He] [t_has] severe burns!\n" - temp = getCloneLoss() - if(temp) - if(temp < 25) - msg += "[t_He] [t_is] slightly deformed.\n" - else if (temp < 50) - msg += "[t_He] [t_is] moderately deformed!\n" - else - msg += "[t_He] [t_is] severely deformed!\n" + temp = getCloneLoss() + if(temp) + if(temp < 25) + msg += "[t_He] [t_is] slightly deformed.\n" + else if (temp < 50) + msg += "[t_He] [t_is] moderately deformed!\n" + else + msg += "[t_He] [t_is] severely deformed!\n" - if(getBrainLoss() > 60) + if(disabilities & DUMB) msg += "[t_He] seem[p_s()] to be clumsy and unable to think.\n" if(fire_stacks > 0) diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 6f3dca3ed7..39caec803b 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -7,7 +7,7 @@ var/t_has = p_have() var/t_is = p_are() - var/msg = "*---------*\nThis is [src.name]!\n" + var/msg = "*---------*\nThis is [name]!\n" var/list/obscured = check_obscured_slots() var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE)) @@ -187,25 +187,32 @@ else if(l_limbs_missing >= 2 && r_limbs_missing >= 2) msg += "[t_He] [p_do()]n't seem all there.\n" - if(temp) - if(temp < 30) - msg += "[t_He] [t_has] minor bruising.\n" - else - msg += "[t_He] [t_has] severe bruising!\n" + if(!(user == src && src.hal_screwyhud == SCREWYHUD_HEALTHY)) //fake healthy + if(temp) + if(temp < 25) + msg += "[t_He] [t_has] minor bruising.\n" + else if(temp < 50) + msg += "[t_He] [t_has] moderate bruising!\n" + else + msg += "[t_He] [t_has] severe bruising!\n" - temp = getFireLoss() - if(temp) - if(temp < 30) - msg += "[t_He] [t_has] minor burns.\n" - else - msg += "[t_He] [t_has] severe burns!\n" + temp = getFireLoss() + if(temp) + if(temp < 25) + msg += "[t_He] [t_has] minor burns.\n" + else if (temp < 50) + msg += "[t_He] [t_has] moderate burns!\n" + else + msg += "[t_He] [t_has] severe burns!\n" - temp = getCloneLoss() - if(temp) - if(temp < 30) - msg += "[t_He] [t_has] minor cellular damage.\n" - else - msg += "[t_He] [t_has] severe cellular damage.\n" + temp = getCloneLoss() + if(temp) + if(temp < 25) + msg += "[t_He] [t_has] minor cellular damage.\n" + else if(temp < 50) + msg += "[t_He] [t_has] moderate cellular damage!\n" + else + msg += "[t_He] [t_has] severe cellular damage!\n" if(fire_stacks > 0) @@ -278,7 +285,7 @@ if(stat == UNCONSCIOUS) msg += "[t_He] [t_is]n't responding to anything around [t_him] and seem[p_s()] to be asleep.\n" else - if(getBrainLoss() >= 60) + if(disabilities & DUMB) msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n" if(InCritical()) msg += "[t_He] [t_is] barely conscious.\n" diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 7d4c62d9e1..f0c630421d 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -890,8 +890,11 @@ if(!is_type_in_typecache(M, can_ride_typecache)) M.visible_message("[M] really can't seem to mount [src]...") return - if(!riding_datum) - riding_datum = new /datum/riding/human(src) + var/datum/component/riding/human/riding_datum = LoadComponent(/datum/component/riding/human) + riding_datum.ride_check_rider_incapacitated = TRUE + riding_datum.ride_check_ridden_incapacitated = TRUE + riding_datum.ride_check_rider_restrained = TRUE + riding_datum.set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 6), TEXT_SOUTH = list(0, 6), TEXT_EAST = list(-6, 4), TEXT_WEST = list( 6, 4))) if(buckled_mobs && ((M in buckled_mobs) || (buckled_mobs.len >= max_buckled_mobs)) || buckled || (M.stat != CONSCIOUS)) return visible_message("[M] starts to climb onto [src]...") @@ -908,13 +911,6 @@ else visible_message("[M] fails to climb onto [src]!") -/mob/living/carbon/human/unbuckle_mob(mob/living/M, force=FALSE) - if(iscarbon(M)) - if(riding_datum) - riding_datum.unequip_buckle_inhands(M) - riding_datum.restore_position(M) - . = ..(M, force) - /mob/living/carbon/human/species var/race = null diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index a1e60f8820..e3e1271132 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -89,15 +89,15 @@ for(var/obj/item/I in held_items) if(!istype(I, /obj/item/clothing)) - var/final_block_chance = I.block_chance - (Clamp((armour_penetration-I.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example + var/final_block_chance = I.block_chance - (CLAMP((armour_penetration-I.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example if(I.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type)) return 1 if(wear_suit) - var/final_block_chance = wear_suit.block_chance - (Clamp((armour_penetration-wear_suit.armour_penetration)/2,0,100)) + block_chance_modifier + var/final_block_chance = wear_suit.block_chance - (CLAMP((armour_penetration-wear_suit.armour_penetration)/2,0,100)) + block_chance_modifier if(wear_suit.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type)) return 1 if(w_uniform) - var/final_block_chance = w_uniform.block_chance - (Clamp((armour_penetration-w_uniform.armour_penetration)/2,0,100)) + block_chance_modifier + var/final_block_chance = w_uniform.block_chance - (CLAMP((armour_penetration-w_uniform.armour_penetration)/2,0,100)) + block_chance_modifier if(w_uniform.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type)) return 1 return 0 @@ -131,7 +131,7 @@ var/obj/item/bodypart/L = pick(bodyparts) L.embedded_objects |= I I.add_mob_blood(src)//it embedded itself in you, of course it's bloody! - I.loc = src + I.forceMove(src) L.receive_damage(I.w_class*I.embedded_impact_pain_multiplier) visible_message("[I] embeds itself in [src]'s [L.name]!","[I] embeds itself in your [L.name]!") hitpush = FALSE @@ -188,12 +188,8 @@ return if(ishuman(user)) var/mob/living/carbon/human/H = user - if(H.a_intent == INTENT_DISARM) - if(H.buckled_mobs && (src in H.buckled_mobs) && H.riding_datum) - H.riding_datum.force_dismount(src) dna.species.spec_attack_hand(H, src) - /mob/living/carbon/human/attack_paw(mob/living/carbon/monkey/M) var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg") var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone)) @@ -361,10 +357,11 @@ /mob/living/carbon/human/ex_act(severity, target, origin) - if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src)) return ..() + if (!severity) + return var/b_loss = 0 var/f_loss = 0 var/bomb_armor = getarmor(null, "bomb") diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 8e72b26419..716373061d 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -1,5 +1,5 @@ /mob/living/carbon/human - hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD,ANTAG_HUD) + hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD,ANTAG_HUD,GLAND_HUD) possible_a_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, INTENT_HARM) pressure_resistance = 25 //Hair colour and style diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index b5f8ab7c81..d1d657652b 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -103,7 +103,9 @@ /mob/living/carbon/human/IsAdvancedToolUser() - return 1//Humans can use guns and such + if(disabilities & MONKEYLIKE) + return FALSE + return TRUE//Humans can use guns and such /mob/living/carbon/human/reagent_check(datum/reagent/R) return dna.species.handle_chemicals(R,src) diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index fc8fdac04c..c90d1a0231 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -58,11 +58,6 @@ //End bloody footprints S.step_action() -/mob/living/carbon/human/Moved() - . = ..() - if(buckled_mobs && buckled_mobs.len && riding_datum) - riding_datum.on_vehicle_move() - /mob/living/carbon/human/Process_Spacemove(movement_dir = 0) //Temporary laziness thing. Will change to handles by species reee. if(..()) return 1 diff --git a/code/modules/mob/living/carbon/human/interactive.dm b/code/modules/mob/living/carbon/human/interactive.dm index 35e83a8e04..38dfad5787 100644 --- a/code/modules/mob/living/carbon/human/interactive.dm +++ b/code/modules/mob/living/carbon/human/interactive.dm @@ -219,7 +219,7 @@ if(prob(25)) var/cType = pick(list(SNPC_BRUTE,SNPC_STEALTH,SNPC_MARTYR,SNPC_PSYCHO)) T.makeTraitor(cType) - T.loc = pick(get_area_turfs(T.job2area(T.myjob))) + T.forceMove(pick(get_area_turfs(T.job2area(T.myjob)))) if(choice == "Custom") var/cjob = input("Choose Job") as null|anything in SSjob.occupations if(cjob) @@ -256,7 +256,7 @@ var/doTele = input("Place the SNPC in their department?") as null|anything in list("Yes","No") if(doTele) if(doTele == "Yes") - T.loc = pick(get_area_turfs(T.job2area(T.myjob))) + T.forceMove(pick(get_area_turfs(T.job2area(T.myjob)))) /mob/living/carbon/human/interactive/proc/doSetup() Path_ID = new /obj/item/card/id(src) @@ -506,7 +506,7 @@ var/list/slots = list ("left pocket" = slot_l_store,"right pocket" = slot_r_store,"left hand" = slot_hands,"right hand" = slot_hands) if(hands) slots = list ("left hand" = slot_hands,"right hand" = slot_hands) - G.loc = src + G.forceMove(src) if(G.force && G.force > best_force) best_force = G.force equip_in_one_of_slots(G, slots) @@ -828,7 +828,7 @@ return pick(/area/hallway, /area/crew_quarters/locker) /mob/living/carbon/human/interactive/proc/target_filter(target) - var/list/filtered_targets = list(/area, /turf, /obj/machinery/door, /atom/movable/light, /obj/structure/cable, /obj/machinery/atmospherics) + var/list/filtered_targets = list(/area, /turf, /obj/machinery/door, /atom/movable/lighting_object, /obj/structure/cable, /obj/machinery/atmospherics) var/list/L = target for(var/atom/A in target) // added a bunch of "junk" that clogs up the general find procs if(is_type_in_list(A,filtered_targets)) @@ -931,7 +931,7 @@ /mob/living/carbon/human/interactive/proc/npcDrop(var/obj/item/A,var/blacklist = 0) if(blacklist) blacklistItems += A - A.loc = get_turf(src) // drop item works inconsistently + A.forceMove(drop_location()) // drop item works inconsistently enforce_hands() update_icons() @@ -956,7 +956,7 @@ retal_target = traitorTarget else var/obj/item/I = traitorTarget - I.loc = get_turf(traitorTarget) // pull it outta them + I.forceMove(get_turf(I)) // pull it outta them else take_to_slot(traitorTarget) if(SNPC_MARTYR) @@ -1315,7 +1315,7 @@ customEmote("[src] [pick("gibbers","drools","slobbers","claps wildly","spits")], grabbing various foodstuffs from [SF] and sticking them in it's mouth!") for(var/obj/item/A in SF.contents) if(prob(smartness/2)) - A.loc = src + A.forceMove(src) if(foundCustom) @@ -1398,7 +1398,7 @@ if(!Adjacent(toGrab)) tryWalk(toGrab) else - toGrab.loc = src + toGrab.forceMove(src) if(finishedList.len > 0) var/obj/structure/table/reinforced/RT @@ -1563,7 +1563,7 @@ var/obj/item/W = main_hand W.attack(TARGET,src) else - G.loc = get_turf(src) // drop item works inconsistently + G.forceMove(drop_location()) // drop item works inconsistently enforce_hands() update_icons() else diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 71c5dedc26..4f41c2d40c 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -103,6 +103,7 @@ update_tint() if(G.vision_correction) clear_fullscreen("nearsighted") + clear_fullscreen("eye_damage") if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view || !isnull(G.lighting_alpha)) update_sight() update_inv_glasses() @@ -188,6 +189,7 @@ if(G.vision_correction) if(disabilities & NEARSIGHT) overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1) + adjust_eye_damage(0) if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view || !isnull(G.lighting_alpha)) update_sight() if(!QDELETED(src)) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 67843b3e64..a84683c5ae 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -20,8 +20,6 @@ #define COLD_GAS_DAMAGE_LEVEL_2 1.5 //Amount of damage applied when the current breath's temperature passes the 200K point #define COLD_GAS_DAMAGE_LEVEL_3 3 //Amount of damage applied when the current breath's temperature passes the 120K point -#define BRAIN_DAMAGE_FILE "brain_damage_lines.json" - /mob/living/carbon/human/Life() set invisibility = 0 set background = BACKGROUND_ENABLED @@ -74,14 +72,6 @@ else if(eye_blurry) //blurry eyes heal slowly adjust_blurriness(-1) - if (getBrainLoss() >= 60 && stat == CONSCIOUS) - if(prob(3)) - if(prob(25)) - emote("drool") - else - say(pick_list_replacements(BRAIN_DAMAGE_FILE, "brain_damage")) - - /mob/living/carbon/human/handle_mutations_and_radiation() if(!dna || !dna.species.handle_mutations_and_radiation(src)) ..() @@ -324,7 +314,7 @@ if(prob(I.embedded_fall_chance)) BP.receive_damage(I.w_class*I.embedded_fall_pain_multiplier) BP.embedded_objects -= I - I.loc = get_turf(src) + I.forceMove(drop_location()) visible_message("[I] falls out of [name]'s [BP.name]!","[I] falls out of your [BP.name]!") if(!has_embedded_objects()) clear_alert("embeddedobject") @@ -430,7 +420,7 @@ All effects don't start immediately, but rather get worse over time; the rate is to_chat(src, "Maybe you should lie down for a bit...") if(drunkenness >= 91) - adjustBrainLoss(0.4) + adjustBrainLoss(0.4, 60) if(prob(20) && !stat) if(SSshuttle.emergency.mode == SHUTTLE_DOCKED && (z in GLOB.station_z_levels)) //QoL mainly to_chat(src, "You're so tired... but you can't miss that shuttle...") diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index e374bb9187..866c14242f 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -453,9 +453,9 @@ GLOBAL_LIST_EMPTY(roundstart_races) var/obj/item/bodypart/head/HD = H.get_bodypart("head") - if(!(H.disabilities & HUSK)) + if(HD && !(H.disabilities & HUSK)) // lipstick - if(H.lip_style && (LIPS in species_traits) && HD) + if(H.lip_style && (LIPS in species_traits)) var/mutable_appearance/lip_overlay = mutable_appearance('icons/mob/human_face.dmi', "lips_[H.lip_style]", -BODY_LAYER) lip_overlay.color = H.lip_color if(OFFSET_FACE in H.dna.species.offset_features) @@ -464,13 +464,18 @@ GLOBAL_LIST_EMPTY(roundstart_races) standing += lip_overlay // eyes - if((EYECOLOR in species_traits) && HD) - var/mutable_appearance/eye_overlay = mutable_appearance('icons/mob/human_face.dmi', "eyes", -BODY_LAYER) + var/has_eyes = H.getorganslot(ORGAN_SLOT_EYES) + var/mutable_appearance/eye_overlay + if(!has_eyes) + eye_overlay = mutable_appearance('icons/mob/human_face.dmi', "eyes_missing", -BODY_LAYER) + else + eye_overlay = mutable_appearance('icons/mob/human_face.dmi', "eyes", -BODY_LAYER) + if((EYECOLOR in species_traits) && has_eyes) eye_overlay.color = "#" + H.eye_color - if(OFFSET_FACE in H.dna.species.offset_features) - eye_overlay.pixel_x += H.dna.species.offset_features[OFFSET_FACE][1] - eye_overlay.pixel_y += H.dna.species.offset_features[OFFSET_FACE][2] - standing += eye_overlay + if(OFFSET_FACE in H.dna.species.offset_features) + eye_overlay.pixel_x += H.dna.species.offset_features[OFFSET_FACE][1] + eye_overlay.pixel_y += H.dna.species.offset_features[OFFSET_FACE][2] + standing += eye_overlay //Underwear, Undershirts & Socks if(!(NO_UNDERWEAR in species_traits)) @@ -1310,11 +1315,14 @@ GLOBAL_LIST_EMPTY(roundstart_races) /datum/species/proc/harm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) + if(user.disabilities & PACIFISM) + to_chat(user, "You don't want to harm [target]!") + return FALSE if(target.check_block()) target.visible_message("[target] blocks [user]'s attack!") - return 0 + return FALSE if(attacker_style && attacker_style.harm_act(user,target)) - return 1 + return TRUE else var/atk_verb = user.dna.species.attack_verb @@ -1339,7 +1347,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) playsound(target.loc, user.dna.species.miss_sound, 25, 1, -1) target.visible_message("[user] has attempted to [atk_verb] [target]!",\ "[user] has attempted to [atk_verb] [target]!", null, COMBAT_MESSAGE_RANGE) - return 0 + return FALSE var/armor_block = target.run_armor_check(affecting, "melee") @@ -1354,15 +1362,13 @@ GLOBAL_LIST_EMPTY(roundstart_races) target.apply_damage(damage, BRUTE, affecting, armor_block) add_logs(user, target, "punched") if((target.stat != DEAD) && damage >= user.dna.species.punchstunthreshold) - target.visible_message("[user] has weakened [target]!", \ - "[user] has weakened [target]!") + target.visible_message("[user] has knocked [target] down!", \ + "[user] has knocked [target] down!", null, COMBAT_MESSAGE_RANGE) target.apply_effect(80, KNOCKDOWN, armor_block) target.forcesay(GLOB.hit_appends) else if(target.lying) target.forcesay(GLOB.hit_appends) - - /datum/species/proc/disarm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) var/aim_for_mouth = user.zone_selected == "mouth" var/target_on_help_and_unarmed = target.a_intent == INTENT_HELP && !target.get_active_held_item() @@ -1382,10 +1388,12 @@ GLOBAL_LIST_EMPTY(roundstart_races) return 1 else user.do_attack_animation(target, ATTACK_EFFECT_DISARM) - + if(target.w_uniform) target.w_uniform.add_fingerprint(user) - var/obj/item/bodypart/affecting = target.get_bodypart(ran_zone(user.zone_selected)) + var/randomized_zone = ran_zone(user.zone_selected) + target.SendSignal(COMSIG_HUMAN_DISARM_HIT, user, user.zone_selected) + var/obj/item/bodypart/affecting = target.get_bodypart(randomized_zone) var/randn = rand(1, 100) if(randn <= 25) playsound(target, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) @@ -1399,7 +1407,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) if(randn <= 60) var/obj/item/I = null if(target.pulling) - to_chat(target, "[user] has broken [target]'s grip on [target.pulling]!") + target.visible_message("[user] has broken [target]'s grip on [target.pulling]!") target.stop_pulling() else I = target.get_active_held_item() @@ -1504,7 +1512,13 @@ GLOBAL_LIST_EMPTY(roundstart_races) H.visible_message("[H] has been knocked senseless!", \ "[H] has been knocked senseless!") H.confused = max(H.confused, 20) + H.adjustBrainLoss(20) H.adjust_blurriness(10) + if(prob(10)) + H.gain_trauma(/datum/brain_trauma/mild/concussion) + else + if(!I.is_sharp()) + H.adjustBrainLoss(I.force / 5) if(prob(I.force + ((100 - H.health)/2)) && H != user) var/datum/antagonist/rev/rev = H.mind.has_antag_datum(/datum/antagonist/rev) diff --git a/code/modules/mob/living/carbon/human/species_types/abductors.dm b/code/modules/mob/living/carbon/human/species_types/abductors.dm index 160b0b73a1..cd273ec98e 100644 --- a/code/modules/mob/living/carbon/human/species_types/abductors.dm +++ b/code/modules/mob/living/carbon/human/species_types/abductors.dm @@ -3,9 +3,19 @@ id = "abductor" say_mod = "gibbers" sexes = FALSE - species_traits = list(NOBLOOD,NOBREATH,VIRUSIMMUNE,NOGUNS,NOHUNGER) + species_traits = list(SPECIES_ORGANIC,NOBLOOD,NOBREATH,VIRUSIMMUNE,NOGUNS,NOHUNGER) mutanttongue = /obj/item/organ/tongue/abductor var/scientist = FALSE // vars to not pollute spieces list with castes /datum/species/abductor/copy_properties_from(datum/species/abductor/old_species) scientist = old_species.scientist + +/datum/species/abductor/on_species_gain(mob/living/carbon/C, datum/species/old_species) + . = ..() + var/datum/atom_hud/abductor_hud = GLOB.huds[DATA_HUD_ABDUCTOR] + abductor_hud.add_hud_to(C) + +/datum/species/abductor/on_species_loss(mob/living/carbon/C) + . = ..() + var/datum/atom_hud/abductor_hud = GLOB.huds[DATA_HUD_ABDUCTOR] + abductor_hud.remove_hud_from(C) diff --git a/code/modules/mob/living/carbon/human/species_types/android.dm b/code/modules/mob/living/carbon/human/species_types/android.dm index 44f1e5c456..4badfa8405 100644 --- a/code/modules/mob/living/carbon/human/species_types/android.dm +++ b/code/modules/mob/living/carbon/human/species_types/android.dm @@ -2,7 +2,7 @@ name = "Android" id = "android" say_mod = "states" - species_traits = list(NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOFIRE,NOBLOOD,VIRUSIMMUNE,PIERCEIMMUNE,NOHUNGER,EASYLIMBATTACHMENT) + species_traits = list(SPECIES_ROBOTIC,NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOFIRE,NOBLOOD,PIERCEIMMUNE,NOHUNGER,EASYLIMBATTACHMENT) meat = null damage_overlay_type = "synth" mutanttongue = /obj/item/organ/tongue/robot diff --git a/code/modules/mob/living/carbon/human/species_types/angel.dm b/code/modules/mob/living/carbon/human/species_types/angel.dm index cc9a2ff12f..de0120028c 100644 --- a/code/modules/mob/living/carbon/human/species_types/angel.dm +++ b/code/modules/mob/living/carbon/human/species_types/angel.dm @@ -2,7 +2,7 @@ name = "Angel" id = "angel" default_color = "FFFFFF" - species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS) + species_traits = list(SPECIES_ORGANIC,EYECOLOR,HAIR,FACEHAIR,LIPS) mutant_bodyparts = list("tail_human", "ears", "wings") default_features = list("mcolor" = "FFF", "tail_human" = "None", "ears" = "None", "wings" = "Angel") use_skintones = 1 diff --git a/code/modules/mob/living/carbon/human/species_types/corporate.dm b/code/modules/mob/living/carbon/human/species_types/corporate.dm index b9106cf408..d78d2b5262 100644 --- a/code/modules/mob/living/carbon/human/species_types/corporate.dm +++ b/code/modules/mob/living/carbon/human/species_types/corporate.dm @@ -15,5 +15,5 @@ attack_sound = 'sound/weapons/resonator_blast.ogg' blacklisted = 1 use_skintones = 0 - species_traits = list(RADIMMUNE,VIRUSIMMUNE,NOBLOOD,PIERCEIMMUNE,EYECOLOR,NODISMEMBER,NOHUNGER) - sexes = 0 \ No newline at end of file + species_traits = list(SPECIES_ORGANIC,RADIMMUNE,VIRUSIMMUNE,NOBLOOD,PIERCEIMMUNE,EYECOLOR,NODISMEMBER,NOHUNGER) + sexes = 0 diff --git a/code/modules/mob/living/carbon/human/species_types/dullahan.dm b/code/modules/mob/living/carbon/human/species_types/dullahan.dm index 5effff5bd3..78cf1a3b7a 100644 --- a/code/modules/mob/living/carbon/human/species_types/dullahan.dm +++ b/code/modules/mob/living/carbon/human/species_types/dullahan.dm @@ -2,7 +2,7 @@ name = "dullahan" id = "dullahan" default_color = "FFFFFF" - species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,NOBREATH,NOHUNGER) + species_traits = list(SPECIES_ORGANIC,EYECOLOR,HAIR,FACEHAIR,LIPS,NOBREATH,NOHUNGER) mutant_bodyparts = list("tail_human", "ears", "wings") default_features = list("mcolor" = "FFF", "tail_human" = "None", "ears" = "None", "wings" = "None") use_skintones = TRUE diff --git a/code/modules/mob/living/carbon/human/species_types/flypeople.dm b/code/modules/mob/living/carbon/human/species_types/flypeople.dm index 61609f653c..7b37e5fc42 100644 --- a/code/modules/mob/living/carbon/human/species_types/flypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/flypeople.dm @@ -2,6 +2,7 @@ name = "Flyperson" id = "fly" say_mod = "buzzes" + species_traits = list(SPECIES_ORGANIC) mutanttongue = /obj/item/organ/tongue/fly mutantliver = /obj/item/organ/liver/fly mutantstomach = /obj/item/organ/stomach/fly diff --git a/code/modules/mob/living/carbon/human/species_types/furrypeople.dm b/code/modules/mob/living/carbon/human/species_types/furrypeople.dm index bff4d8554a..fe41c074c0 100644 --- a/code/modules/mob/living/carbon/human/species_types/furrypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/furrypeople.dm @@ -2,7 +2,7 @@ name = "Mammal" id = "mammal" default_color = "4B4B4B" - species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR) + species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,SPECIES_ORGANIC) mutant_bodyparts = list("mam_tail", "mam_ears", "mam_body_markings", "snout", "taur") default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "body_markings" = "None", "mam_tail" = "None", "mam_ears" = "None", "mam_body_markings" = "None", "taur" = "None") attack_verb = "claw" @@ -24,7 +24,7 @@ id = "avian" say_mod = "chirps" default_color = "BCAC9B" - species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR) + species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,SPECIES_ORGANIC) mutant_bodyparts = list("snout", "wings", "taur", "mam_tail", "mam_body_markings", "taur") default_features = list("snout" = "Sharp", "wings" = "None", "taur" = "None", "mam_body_markings" = "Hawk") attack_verb = "peck" @@ -45,7 +45,7 @@ name = "Aquatic" id = "aquatic" default_color = "BCAC9B" - species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR) + species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,SPECIES_ORGANIC) mutant_bodyparts = list("mam_tail", "mam_body_markings", "mam_ears", "taur") default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF","mam_tail" = "shark", "mam_body_markings" = "None", "mam_ears" = "None") attack_verb = "bite" @@ -66,7 +66,7 @@ name = "Insect" id = "insect" default_color = "BCAC9B" - species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR) + species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,SPECIES_ORGANIC) mutant_bodyparts = list("mam_body_markings", "mam_ears", "mam_tail", "taur") default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_body_markings" = "moth", "mam_tail" = "None", "mam_ears" = "None") attack_verb = "flutter" //wat? @@ -90,10 +90,9 @@ id = "xeno" say_mod = "hisses" default_color = "00FF00" - species_traits = list(MUTCOLORS,LIPS,DIGITIGRADE,PIERCEIMMUNE) + species_traits = list(MUTCOLORS,LIPS,DIGITIGRADE,SPECIES_ORGANIC) mutant_bodyparts = list("xenotail", "xenohead", "xenodorsal", "taur","mam_body_markings") default_features = list("xenotail"="xeno","xenohead"="standard","xenodorsal"="standard","mcolor" = "0F0","mcolor2" = "0F0","mcolor3" = "0F0","taur" = "None","mam_body_markings" = "xeno") - heatmod = 1.3 attack_verb = "slash" attack_sound = 'sound/weapons/slash.ogg' miss_sound = 'sound/weapons/slashmiss.ogg' @@ -220,7 +219,7 @@ name = "DataShark" id = "datashark" default_color = "BCAC9B" - species_traits = list(MUTCOLORS_PARTSONLY,EYECOLOR,LIPS,HAIR) + species_traits = list(MUTCOLORS_PARTSONLY,EYECOLOR,LIPS,HAIR,SPECIES_ORGANIC) mutant_bodyparts = list("mam_tail", "mam_body_markings") default_features = list("mam_tail" = "datashark", "mam_body_markings" = "None") attack_verb = "bite" @@ -234,7 +233,7 @@ name = "Guilmon" id = "guilmon" default_color = "4B4B4B" - species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR) + species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,SPECIES_ORGANIC) mutant_bodyparts = list("mam_tail", "mam_ears", "mam_body_markings") default_features = list("mcolor" = "FFF", "mcolor2" = "FFF", "mcolor3" = "FFF", "mam_tail" = "guilmon", "mam_ears" = "guilmon", "mam_body_markings" = "guilmon") attack_verb = "claw" diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm index 9cb3f21ec0..2b86d2945d 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -2,7 +2,7 @@ // Animated beings of stone. They have increased defenses, and do not need to breathe. They're also slow as fuuuck. name = "Golem" id = "iron golem" - species_traits = list(NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOFIRE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS,NO_UNDERWEAR) + species_traits = list(SPECIES_INORGANIC,NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOFIRE,NOGUNS,NOBLOOD,RADIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS,NO_UNDERWEAR) mutant_organs = list(/obj/item/organ/adamantine_resonator) speedmod = 2 armor = 55 @@ -76,7 +76,7 @@ fixed_mut_color = "a3d" meat = /obj/item/ore/plasma //Can burn and takes damage from heat - species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS,NO_UNDERWEAR) + species_traits = list(SPECIES_INORGANIC,NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS,NO_UNDERWEAR) info_text = "As a Plasma Golem, you burn easily. Be careful, if you get hot enough while burning, you'll blow up!" heatmod = 0 //fine until they blow up prefix = "Plasma" @@ -242,7 +242,7 @@ fixed_mut_color = "49311c" meat = /obj/item/stack/sheet/mineral/wood //Can burn and take damage from heat - species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS,NO_UNDERWEAR) + species_traits = list(SPECIES_ORGANIC,NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS,NO_UNDERWEAR) armor = 30 burnmod = 1.25 heatmod = 1.5 @@ -369,7 +369,7 @@ var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2) var/turf/target = get_turf(P.starting) // redirect the projectile - P.preparePixelProjectile(locate(Clamp(target.x + new_x, 1, world.maxx), Clamp(target.y + new_y, 1, world.maxy), H.z), H) + P.preparePixelProjectile(locate(CLAMP(target.x + new_x, 1, world.maxx), CLAMP(target.y + new_y, 1, world.maxy), H.z), H) return -1 return 0 @@ -549,7 +549,7 @@ limbs_id = "cultgolem" sexes = FALSE info_text = "As a Runic Golem, you possess eldritch powers granted by the Elder God Nar'Sie." - species_traits = list(NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOFIRE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,NO_UNDERWEAR) //no mutcolors + species_traits = list(SPECIES_INORGANIC,NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOFIRE,NOGUNS,NOBLOOD,RADIMMUNE,PIERCEIMMUNE,NODISMEMBER,NO_UNDERWEAR) //no mutcolors prefix = "Runic" var/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift/golem/phase_shift @@ -602,7 +602,7 @@ limbs_id = "clockgolem" info_text = "As a clockwork golem, you are faster than \ other types of golem (being a machine), and are immune to electric shocks." - species_traits = list(NO_UNDERWEAR, NOTRANSSTING, NOBREATH, NOZOMBIE, VIRUSIMMUNE, RADIMMUNE, NOBLOOD, RESISTCOLD, RESISTPRESSURE, PIERCEIMMUNE) + species_traits = list(SPECIES_INORGANIC,NO_UNDERWEAR, NOTRANSSTING, NOBREATH, NOZOMBIE, RADIMMUNE, NOBLOOD, RESISTCOLD, RESISTPRESSURE, PIERCEIMMUNE) armor = 20 //Reinforced, but much less so to allow for fast movement attack_verb = "smash" attack_sound = 'sound/magic/clockwork/anima_fragment_attack.ogg' @@ -653,7 +653,7 @@ limbs_id = "clothgolem" sexes = FALSE info_text = "As a Cloth Golem, you are able to reform yourself after death, provided your remains aren't burned or destroyed. You are, of course, very flammable." - species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,NO_UNDERWEAR) //no mutcolors, and can burn + species_traits = list(SPECIES_UNDEAD,NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,PIERCEIMMUNE,NODISMEMBER,NO_UNDERWEAR) //no mutcolors, and can burn armor = 15 //feels no pain, but not too resistant burnmod = 2 // don't get burned speedmod = 1 // not as heavy as stone diff --git a/code/modules/mob/living/carbon/human/species_types/humans.dm b/code/modules/mob/living/carbon/human/species_types/humans.dm index 63fdacc504..31883b4dcd 100644 --- a/code/modules/mob/living/carbon/human/species_types/humans.dm +++ b/code/modules/mob/living/carbon/human/species_types/humans.dm @@ -2,9 +2,9 @@ name = "Human" id = "human" default_color = "FFFFFF" - species_traits = list(MUTCOLORS_PARTSONLY,EYECOLOR,HAIR,FACEHAIR,LIPS) - mutant_bodyparts = list("tail_human", "ears", "taur") - default_features = list("tail_human" = "None", "ears" = "None", "taur" = "none") + species_traits = list(MUTCOLORS_PARTSONLY,SPECIES_ORGANIC,EYECOLOR,HAIR,FACEHAIR,LIPS) + mutant_bodyparts = list("tail_human", "ears", "wings", "taur") + default_features = list("mcolor" = "FFF", "tail_human" = "None", "ears" = "None", "wings" = "None", "taur" = "none") use_skintones = 1 skinned_type = /obj/item/stack/sheet/animalhide/human disliked_food = GROSS | RAW @@ -19,6 +19,11 @@ if(H) H.endTailWag() +/datum/species/human/spec_stun(mob/living/carbon/human/H,amount) + if(H) + H.endTailWag() + . = ..() + /datum/species/human/space_move(mob/living/carbon/human/H) var/obj/item/device/flightpack/F = H.get_flightpack() if(istype(F) && (F.flight) && F.allow_thrust(0.01, src)) diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm index b79a0e81a5..5d10ea6b36 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -4,7 +4,7 @@ id = "jelly" default_color = "00FF90" say_mod = "chirps" - species_traits = list(MUTCOLORS,EYECOLOR,NOBLOOD,VIRUSIMMUNE,TOXINLOVER) + species_traits = list(SPECIES_ORGANIC,MUTCOLORS,EYECOLOR,NOBLOOD,VIRUSIMMUNE,TOXINLOVER) meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/slime exotic_blood = "slimejelly" damage_overlay_type = "" @@ -101,7 +101,7 @@ name = "Slimeperson" id = "slime" default_color = "00FFFF" - species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD,VIRUSIMMUNE, TOXINLOVER) + species_traits = list(SPECIES_ORGANIC,MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD,VIRUSIMMUNE, TOXINLOVER) say_mod = "says" hair_color = "mutcolor" hair_alpha = 150 diff --git a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm index e528d58b11..0d006196aa 100644 --- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm @@ -4,7 +4,7 @@ id = "lizard" say_mod = "hisses" default_color = "00FF00" - species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,FACEHAIR) + species_traits = list(SPECIES_ORGANIC,MUTCOLORS,EYECOLOR,LIPS, HAIR, FACEHAIR) mutant_bodyparts = list("tail_lizard", "snout", "spines", "horns", "frills", "body_markings", "legs", "taur") mutanttongue = /obj/item/organ/tongue/lizard mutanttail = /obj/item/organ/tail/lizard @@ -42,6 +42,11 @@ if(H) H.endTailWag() +/datum/species/lizard/spec_stun(mob/living/carbon/human/H,amount) + if(H) + H.endTailWag() + . = ..() + /* Lizard subspecies: ASHWALKERS */ diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm index 817e22163a..c4f85501d0 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -4,7 +4,7 @@ say_mod = "rattles" sexes = 0 meat = /obj/item/stack/sheet/mineral/plasma - species_traits = list(NOBLOOD,RESISTCOLD,RADIMMUNE,NOTRANSSTING,VIRUSIMMUNE,NOHUNGER) + species_traits = list(SPECIES_INORGANIC,NOBLOOD,RESISTCOLD,RADIMMUNE,NOTRANSSTING,NOHUNGER) mutantlungs = /obj/item/organ/lungs/plasmaman mutanttongue = /obj/item/organ/tongue/bone/plasmaman mutantliver = /obj/item/organ/liver/plasmaman 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 3881eae6f5..6bd77b908c 100644 --- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm @@ -3,7 +3,7 @@ name = "Podperson" id = "pod" default_color = "59CE00" - species_traits = list(MUTCOLORS,EYECOLOR) + species_traits = list(SPECIES_ORGANIC,MUTCOLORS,EYECOLOR) attack_verb = "slash" attack_sound = 'sound/weapons/slice.ogg' miss_sound = 'sound/weapons/slashmiss.ogg' 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 a326150c60..09c9df5f9f 100644 --- a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm @@ -9,7 +9,7 @@ blacklisted = 1 ignored_by = list(/mob/living/simple_animal/hostile/faithless) meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/shadow - species_traits = list(NOBREATH,NOBLOOD,RADIMMUNE,VIRUSIMMUNE) + species_traits = list(SPECIES_ORGANIC,NOBREATH,NOBLOOD,RADIMMUNE,VIRUSIMMUNE) dangerous_existence = 1 mutanteyes = /obj/item/organ/eyes/night_vision 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 acaa182ad0..0a55ae0134 100644 --- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm +++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm @@ -6,7 +6,7 @@ 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) + species_traits = list(SPECIES_UNDEAD,NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,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 diff --git a/code/modules/mob/living/carbon/human/species_types/synths.dm b/code/modules/mob/living/carbon/human/species_types/synths.dm index 8b21c2a237..856a472a73 100644 --- a/code/modules/mob/living/carbon/human/species_types/synths.dm +++ b/code/modules/mob/living/carbon/human/species_types/synths.dm @@ -3,13 +3,13 @@ id = "synth" say_mod = "beep boops" //inherited from a user's real species sexes = 0 - species_traits = list(NOTRANSSTING,NOBREATH,VIRUSIMMUNE,NODISMEMBER,NOHUNGER) //all of these + whatever we inherit from the real species + species_traits = list(SPECIES_ROBOTIC,NOTRANSSTING,NOBREATH,VIRUSIMMUNE,NODISMEMBER,NOHUNGER) //all of these + whatever we inherit from the real species dangerous_existence = 1 blacklisted = 1 meat = null damage_overlay_type = "synth" limbs_id = "synth" - var/list/initial_species_traits = list(NOTRANSSTING,NOBREATH,VIRUSIMMUNE,NODISMEMBER,NOHUNGER,NO_DNA_COPY) //for getting these values back for assume_disguise() + var/list/initial_species_traits = list(SPECIES_ROBOTIC,NOTRANSSTING,NOBREATH,VIRUSIMMUNE,NODISMEMBER,NOHUNGER,NO_DNA_COPY) //for getting these values back for assume_disguise() var/disguise_fail_health = 75 //When their health gets to this level their synthflesh partially falls off var/datum/species/fake_species = null //a species to do most of our work for us, unless we're damaged @@ -41,7 +41,8 @@ say_mod = S.say_mod sexes = S.sexes species_traits = initial_species_traits.Copy() - species_traits.Add(S.species_traits) + species_traits |= S.species_traits + species_traits -= list(SPECIES_ORGANIC, SPECIES_INORGANIC, SPECIES_UNDEAD) attack_verb = S.attack_verb attack_sound = S.attack_sound miss_sound = S.miss_sound diff --git a/code/modules/mob/living/carbon/human/species_types/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm index 0d309876c7..aff8440930 100644 --- a/code/modules/mob/living/carbon/human/species_types/vampire.dm +++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm @@ -2,7 +2,7 @@ name = "vampire" id = "vampire" default_color = "FFFFFF" - species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,NOHUNGER,NOBREATH,DRINKSBLOOD) + species_traits = list(SPECIES_UNDEAD,EYECOLOR,HAIR,FACEHAIR,LIPS,NOHUNGER,NOBREATH,DRINKSBLOOD) mutant_bodyparts = list("tail_human", "ears", "wings") default_features = list("mcolor" = "FFF", "tail_human" = "None", "ears" = "None", "wings" = "None") exotic_bloodtype = "U" @@ -94,8 +94,8 @@ to_chat(victim, "[H] is draining your blood!") to_chat(H, "You drain some blood!") playsound(H, 'sound/items/drink.ogg', 30, 1, -2) - victim.blood_volume = Clamp(victim.blood_volume - drained_blood, 0, BLOOD_VOLUME_MAXIMUM) - H.blood_volume = Clamp(H.blood_volume + drained_blood, 0, BLOOD_VOLUME_MAXIMUM) + victim.blood_volume = CLAMP(victim.blood_volume - drained_blood, 0, BLOOD_VOLUME_MAXIMUM) + H.blood_volume = CLAMP(H.blood_volume + drained_blood, 0, BLOOD_VOLUME_MAXIMUM) if(!victim.blood_volume) to_chat(H, "You finish off [victim]'s blood supply!") 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 8c87e1c9c9..792485960e 100644 --- a/code/modules/mob/living/carbon/human/species_types/zombies.dm +++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm @@ -8,7 +8,7 @@ sexes = 0 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) + species_traits = list(SPECIES_UNDEAD,NOBREATH,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,NOZOMBIE,EASYDISMEMBER,EASYLIMBATTACHMENT,NOTRANSSTING) 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 @@ -25,7 +25,7 @@ limbs_id = "zombie" mutanthands = /obj/item/zombie_hand armor = 20 // 120 damage to KO a zombie, which kills it - speedmod = 2 + speedmod = 1.6 mutanteyes = /obj/item/organ/eyes/night_vision/zombie var/regen_cooldown = 0 @@ -34,7 +34,7 @@ /datum/species/zombie/infectious/spec_stun(mob/living/carbon/human/H,amount) - . = min(2, amount) + . = min(20, amount) /datum/species/zombie/infectious/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H) . = ..() @@ -73,6 +73,7 @@ id = "goofzombies" limbs_id = "zombie" //They look like zombies sexes = 0 + species_traits = list(SPECIES_ORGANIC) meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/zombie mutanttongue = /obj/item/organ/tongue/zombie diff --git a/code/modules/mob/living/carbon/human/status_procs.dm b/code/modules/mob/living/carbon/human/status_procs.dm index 0e009bcd7b..aca6973355 100644 --- a/code/modules/mob/living/carbon/human/status_procs.dm +++ b/code/modules/mob/living/carbon/human/status_procs.dm @@ -3,11 +3,11 @@ amount = dna.species.spec_stun(src,amount) return ..() -/mob/living/carbon/human/Knockdown(amount, updating = 1, ignore_canstun = 0) +/mob/living/carbon/human/Knockdown(amount, updating = 1, ignore_canknockdown = 0) amount = dna.species.spec_stun(src,amount) return ..() -/mob/living/carbon/human/Unconscious(amount, updating = 1, ignore_canstun = 0) +/mob/living/carbon/human/Unconscious(amount, updating = 1, ignore_canunconscious = 0) amount = dna.species.spec_stun(src,amount) return ..() diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index bc654f9201..7264e9ad95 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -160,7 +160,7 @@ There are several things that need to be remembered: update_observer_view(wear_id) //TODO: add an icon file for ID slot stuff, so it's less snowflakey - id_overlay = wear_id.build_worn_icon(state = wear_id.item_state, default_layer = ID_LAYER, default_icon_file = 'icons/mob/mob.dmi') + id_overlay = wear_id.build_worn_icon(state = wear_id.item_state, default_layer = ID_LAYER, default_icon_file = ((wear_id.icon_override) ? wear_id.icon_override : 'icons/mob/mob.dmi')) if(OFFSET_ID in dna.species.offset_features) id_overlay.pixel_x += dna.species.offset_features[OFFSET_ID][1] id_overlay.pixel_y += dna.species.offset_features[OFFSET_ID][2] @@ -195,7 +195,7 @@ There are several things that need to be remembered: var/t_state = gloves.item_state if(!t_state) t_state = gloves.icon_state - overlays_standing[GLOVES_LAYER] = gloves.build_worn_icon(state = t_state, default_layer = GLOVES_LAYER, default_icon_file = 'icons/mob/hands.dmi') + overlays_standing[GLOVES_LAYER] = gloves.build_worn_icon(state = t_state, default_layer = GLOVES_LAYER, default_icon_file = ((gloves.icon_override) ? gloves.icon_override : 'icons/mob/hands.dmi')) gloves_overlay = overlays_standing[GLOVES_LAYER] if(OFFSET_GLOVES in dna.species.offset_features) gloves_overlay.pixel_x += dna.species.offset_features[OFFSET_GLOVES][1] @@ -221,7 +221,7 @@ There are several things that need to be remembered: client.screen += glasses //Either way, add the item to the HUD update_observer_view(glasses,1) if(!(head && (head.flags_inv & HIDEEYES)) && !(wear_mask && (wear_mask.flags_inv & HIDEEYES))) - overlays_standing[GLASSES_LAYER] = glasses.build_worn_icon(state = glasses.icon_state, default_layer = GLASSES_LAYER, default_icon_file = 'icons/mob/eyes.dmi') + overlays_standing[GLASSES_LAYER] = glasses.build_worn_icon(state = glasses.icon_state, default_layer = GLASSES_LAYER, default_icon_file = ((glasses.icon_override) ? glasses.icon_override : 'icons/mob/eyes.dmi')) var/mutable_appearance/glasses_overlay = overlays_standing[GLASSES_LAYER] if(glasses_overlay) if(OFFSET_GLASSES in dna.species.offset_features) @@ -248,7 +248,7 @@ There are several things that need to be remembered: client.screen += ears //add it to the client's screen update_observer_view(ears,1) - overlays_standing[EARS_LAYER] = ears.build_worn_icon(state = ears.icon_state, default_layer = EARS_LAYER, default_icon_file = 'icons/mob/ears.dmi') + overlays_standing[EARS_LAYER] = ears.build_worn_icon(state = ears.icon_state, default_layer = EARS_LAYER, default_icon_file = ((ears.icon_override) ? ears.icon_override : 'icons/mob/ears.dmi')) var/mutable_appearance/ears_overlay = overlays_standing[EARS_LAYER] if(OFFSET_EARS in dna.species.offset_features) ears_overlay.pixel_x += dna.species.offset_features[OFFSET_EARS][1] @@ -273,7 +273,7 @@ There are several things that need to be remembered: if(hud_used.inventory_shown) //if the inventory is open client.screen += shoes //add it to client's screen update_observer_view(shoes,1) - overlays_standing[SHOES_LAYER] = shoes.build_worn_icon(state = shoes.icon_state, default_layer = SHOES_LAYER, default_icon_file = 'icons/mob/feet.dmi') + overlays_standing[SHOES_LAYER] = shoes.build_worn_icon(state = shoes.icon_state, default_layer = SHOES_LAYER, default_icon_file = ((shoes.icon_override) ? shoes.icon_override : 'icons/mob/feet.dmi')) var/mutable_appearance/shoes_overlay = overlays_standing[SHOES_LAYER] if(OFFSET_SHOES in dna.species.offset_features) shoes_overlay.pixel_x += dna.species.offset_features[OFFSET_SHOES][1] @@ -297,7 +297,7 @@ There are several things that need to be remembered: var/t_state = s_store.item_state if(!t_state) t_state = s_store.icon_state - overlays_standing[SUIT_STORE_LAYER] = mutable_appearance('icons/mob/belt_mirror.dmi', t_state, -SUIT_STORE_LAYER) + overlays_standing[SUIT_STORE_LAYER] = mutable_appearance(((s_store.icon_override) ? s_store.icon_override : 'icons/mob/belt_mirror.dmi'), t_state, -SUIT_STORE_LAYER) var/mutable_appearance/s_store_overlay = overlays_standing[SUIT_LAYER] if(OFFSET_S_STORE in dna.species.offset_features) s_store_overlay.pixel_x += dna.species.offset_features[OFFSET_S_STORE][1] @@ -335,7 +335,7 @@ There are several things that need to be remembered: if(!t_state) t_state = belt.icon_state - overlays_standing[BELT_LAYER] = belt.build_worn_icon(state = t_state, default_layer = BELT_LAYER, default_icon_file = 'icons/mob/belt.dmi') + overlays_standing[BELT_LAYER] = belt.build_worn_icon(state = t_state, default_layer = BELT_LAYER, default_icon_file = ((belt.icon_override) ? belt.icon_override : 'icons/mob/belt.dmi')) var/mutable_appearance/belt_overlay = overlays_standing[BELT_LAYER] if(OFFSET_BELT in dna.species.offset_features) belt_overlay.pixel_x += dna.species.offset_features[OFFSET_BELT][1] @@ -359,7 +359,7 @@ There are several things that need to be remembered: client.screen += wear_suit update_observer_view(wear_suit,1) - overlays_standing[SUIT_LAYER] = wear_suit.build_worn_icon(state = wear_suit.icon_state, default_layer = SUIT_LAYER, default_icon_file = 'icons/mob/suit.dmi') + overlays_standing[SUIT_LAYER] = wear_suit.build_worn_icon(state = wear_suit.icon_state, default_layer = SUIT_LAYER, default_icon_file = ((wear_suit.icon_override) ? wear_suit.icon_override : 'icons/mob/suit.dmi')) var/mutable_appearance/suit_overlay = overlays_standing[SUIT_LAYER] if(OFFSET_SUIT in dna.species.offset_features) suit_overlay.pixel_x += dna.species.offset_features[OFFSET_SUIT][1] diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index f9b13dd24f..4399607984 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -2,30 +2,31 @@ set invisibility = 0 set background = BACKGROUND_ENABLED - if (notransform) + if(notransform) return if(damageoverlaytemp) damageoverlaytemp = 0 update_damage_hud() + if(stat != DEAD) //Reagent processing needs to come before breathing, to prevent edge cases. + handle_organs() + if(..()) //not dead handle_blood() if(stat != DEAD) - for(var/V in internal_organs) - var/obj/item/organ/O = V - O.on_life() + handle_brain_damage() + + if(stat != DEAD) + handle_liver() + if(stat == DEAD) stop_sound_channel(CHANNEL_HEARTBEAT) //Updates the number of stored chemicals for powers handle_changeling() - if(stat != DEAD) - handle_liver() - - if(stat != DEAD) return 1 @@ -52,6 +53,7 @@ return if(ismob(loc)) return + var/datum/gas_mixture/environment if(loc) environment = loc.return_air() @@ -65,7 +67,6 @@ else if(health <= HEALTH_THRESHOLD_CRIT) losebreath += 0.25 //You're having trouble breathing in soft crit, so you'll miss a breath one in four times - //Suffocate if(losebreath >= 1) //You've missed a breath, take oxy damage losebreath-- @@ -119,6 +120,7 @@ if(reagents.has_reagent("epinephrine") && lungs) return adjustOxyLoss(1) + failed_last_breath = 1 throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy) return 0 @@ -180,7 +182,7 @@ //TOXINS/PLASMA if(Toxins_partialpressure > safe_tox_max) var/ratio = (breath_gases[/datum/gas/plasma][MOLES]/safe_tox_max) * 10 - adjustToxLoss(Clamp(ratio, MIN_TOXIC_GAS_DAMAGE, MAX_TOXIC_GAS_DAMAGE)) + adjustToxLoss(CLAMP(ratio, MIN_TOXIC_GAS_DAMAGE, MAX_TOXIC_GAS_DAMAGE)) throw_alert("too_much_tox", /obj/screen/alert/too_much_tox) else clear_alert("too_much_tox") @@ -242,13 +244,18 @@ /mob/living/carbon/proc/handle_blood() return +/mob/living/carbon/proc/handle_organs() + for(var/V in internal_organs) + var/obj/item/organ/O = V + O.on_life() + /mob/living/carbon/handle_diseases() for(var/thing in viruses) var/datum/disease/D = thing if(prob(D.infectivity)) D.spread() - if(stat != DEAD) + if(stat != DEAD && !D.process_dead) D.stage_act() //todo generalize this and move hud out @@ -437,3 +444,20 @@ adjustToxLoss(8) if(prob(30)) to_chat(src, "You feel confused and nauseous...")//actual symptoms of liver failure + + +//////////////// +//BRAIN DAMAGE// +//////////////// + +/mob/living/carbon/proc/handle_brain_damage() + for(var/T in get_traumas()) + var/datum/brain_trauma/BT = T + BT.on_life() + + if(getBrainLoss() >= BRAIN_DAMAGE_DEATH) //rip + to_chat(src, "The last spark of life in your brain fizzles out...") + death() + var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN) + if(B) + B.damaged_brain = TRUE diff --git a/code/modules/mob/living/carbon/monkey/combat.dm b/code/modules/mob/living/carbon/monkey/combat.dm index d6afdbdbc2..09d00465ee 100644 --- a/code/modules/mob/living/carbon/monkey/combat.dm +++ b/code/modules/mob/living/carbon/monkey/combat.dm @@ -120,16 +120,19 @@ /mob/living/carbon/monkey/proc/should_target(var/mob/living/L) if(L == src) - return 0 + return FALSE + + if(disabilities & PACIFISM) + return FALSE if(enemies[L]) - return 1 + return TRUE // target non-monkey mobs when aggressive, with a small probability of monkey v monkey if(aggressive && (!istype(L, /mob/living/carbon/monkey/) || prob(MONKEY_AGGRESSIVE_MVM_PROB))) - return 1 + return TRUE - return 0 + return FALSE /mob/living/carbon/monkey/proc/handle_combat() // Don't do any AI if inside another mob (devoured) diff --git a/code/modules/mob/living/carbon/say.dm b/code/modules/mob/living/carbon/say.dm index 526a2ea09b..c1a6af9688 100644 --- a/code/modules/mob/living/carbon/say.dm +++ b/code/modules/mob/living/carbon/say.dm @@ -1,4 +1,6 @@ /mob/living/carbon/treat_message(message) + for(var/datum/brain_trauma/trauma in get_traumas()) + message = trauma.on_say(message) message = ..(message) var/obj/item/organ/tongue/T = getorganslot(ORGAN_SLOT_TONGUE) if(!T) //hoooooouaah! @@ -35,3 +37,11 @@ . = T.could_speak_in_language(dt) else . = initial(dt.flags_1) & TONGUELESS_SPEECH + +/mob/living/carbon/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode) + if(!client) + return + for(var/T in get_traumas()) + var/datum/brain_trauma/trauma = T + message = trauma.on_hear(message, speaker, message_language, raw_message, radio_freq) + return ..() diff --git a/code/modules/mob/living/carbon/status_procs.dm b/code/modules/mob/living/carbon/status_procs.dm index ccd5f7296b..7c40b6f144 100644 --- a/code/modules/mob/living/carbon/status_procs.dm +++ b/code/modules/mob/living/carbon/status_procs.dm @@ -59,10 +59,10 @@ clear_alert("high") /mob/living/carbon/adjust_disgust(amount) - disgust = Clamp(disgust+amount, 0, DISGUST_LEVEL_MAXEDOUT) + disgust = CLAMP(disgust+amount, 0, DISGUST_LEVEL_MAXEDOUT) /mob/living/carbon/set_disgust(amount) - disgust = Clamp(amount, 0, DISGUST_LEVEL_MAXEDOUT) + disgust = CLAMP(amount, 0, DISGUST_LEVEL_MAXEDOUT) /mob/living/carbon/cure_blind() if(disabilities & BLIND) @@ -101,3 +101,35 @@ status_flags |= DISFIGURED //makes them unknown update_body() return 1 + +/mob/living/carbon/proc/get_traumas() + . = list() + var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN) + if(B) + . = B.traumas + +/mob/living/carbon/proc/has_trauma_type(brain_trauma_type, consider_permanent = FALSE) + var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN) + if(B) + . = B.has_trauma_type(brain_trauma_type, consider_permanent) + +/mob/living/carbon/proc/gain_trauma(datum/brain_trauma/trauma, permanent = FALSE, list/arguments) + var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN) + if(B) + . = B.gain_trauma(trauma, permanent, arguments) + +/mob/living/carbon/proc/gain_trauma_type(brain_trauma_type = /datum/brain_trauma, permanent = FALSE) + var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN) + if(B) + . = B.gain_trauma_type(brain_trauma_type, permanent) + +/mob/living/carbon/proc/cure_trauma_type(brain_trauma_type, cure_permanent = FALSE) + var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN) + if(B) + . = B.cure_trauma_type(brain_trauma_type, cure_permanent) + +/mob/living/carbon/proc/cure_all_traumas(cure_permanent = FALSE) + var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN) + if(B) + . = B.cure_all_traumas(cure_permanent) + diff --git a/code/modules/mob/living/carbon/update_icons.dm b/code/modules/mob/living/carbon/update_icons.dm index 173b088c3c..701fa0c7bc 100644 --- a/code/modules/mob/living/carbon/update_icons.dm +++ b/code/modules/mob/living/carbon/update_icons.dm @@ -124,7 +124,7 @@ if(wear_mask) if(!(head && (head.flags_inv & HIDEMASK))) - overlays_standing[FACEMASK_LAYER] = wear_mask.build_worn_icon(state = wear_mask.icon_state, default_layer = FACEMASK_LAYER, default_icon_file = 'icons/mob/mask.dmi') + overlays_standing[FACEMASK_LAYER] = wear_mask.build_worn_icon(state = wear_mask.icon_state, default_layer = FACEMASK_LAYER, default_icon_file = ((wear_mask.icon_override) ? wear_mask.icon_override : 'icons/mob/mask.dmi')) update_hud_wear_mask(wear_mask) apply_overlay(FACEMASK_LAYER) @@ -138,7 +138,7 @@ if(wear_neck) if(!(head && (head.flags_inv & HIDENECK))) - overlays_standing[NECK_LAYER] = wear_neck.build_worn_icon(state = wear_neck.icon_state, default_layer = NECK_LAYER, default_icon_file = 'icons/mob/neck.dmi') + overlays_standing[NECK_LAYER] = wear_neck.build_worn_icon(state = wear_neck.icon_state, default_layer = NECK_LAYER, default_icon_file = ((wear_neck.icon_override) ? wear_neck.icon_override : 'icons/mob/neck.dmi')) update_hud_neck(wear_neck) apply_overlay(NECK_LAYER) @@ -151,7 +151,7 @@ inv.update_icon() if(back) - overlays_standing[BACK_LAYER] = back.build_worn_icon(state = back.icon_state, default_layer = BACK_LAYER, default_icon_file = 'icons/mob/back.dmi') + overlays_standing[BACK_LAYER] = back.build_worn_icon(state = back.icon_state, default_layer = BACK_LAYER, default_icon_file = ((back.icon_override) ? back.icon_override : 'icons/mob/back.dmi')) update_hud_back(back) apply_overlay(BACK_LAYER) @@ -167,7 +167,7 @@ inv.update_icon() if(head) - overlays_standing[HEAD_LAYER] = head.build_worn_icon(state = head.icon_state, default_layer = HEAD_LAYER, default_icon_file = 'icons/mob/head.dmi') + overlays_standing[HEAD_LAYER] = head.build_worn_icon(state = head.icon_state, default_layer = HEAD_LAYER, default_icon_file = ((head.icon_override) ? head.icon_override : 'icons/mob/head.dmi')) update_hud_head(head) apply_overlay(HEAD_LAYER) diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm index 8401d92676..9517e1b705 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_GET(number/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_GET(number/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_GET(number/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_GET(number/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_GET(number/damage_multiplier))), 0, maxHealth * 2) + cloneloss = CLAMP((cloneloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) if(updating_health) updatehealth() return amount @@ -231,17 +231,13 @@ return amount /mob/living/proc/getBrainLoss() - return brainloss + . = 0 -/mob/living/proc/adjustBrainLoss(amount) - if(status_flags & GODMODE) - return 0 - brainloss = Clamp((brainloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) +/mob/living/proc/adjustBrainLoss(amount, maximum = BRAIN_DAMAGE_DEATH) + return /mob/living/proc/setBrainLoss(amount) - if(status_flags & GODMODE) - return 0 - brainloss = amount + return /mob/living/proc/getStaminaLoss() return staminaloss diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm index c656dd7494..9f541aaf67 100644 --- a/code/modules/mob/living/emote.dm +++ b/code/modules/mob/living/emote.dm @@ -491,14 +491,14 @@ . = ..() if(.) user.spin(20, 1) - if(iscyborg(user)) + if(iscyborg(user) && user.has_buckled_mobs()) var/mob/living/silicon/robot/R = user - if(R.buckled_mobs) + GET_COMPONENT_FROM(riding_datum, /datum/component/riding, R) + if(riding_datum) for(var/mob/M in R.buckled_mobs) - if(R.riding_datum) - R.riding_datum.force_dismount(M) - else - R.unbuckle_all_mobs() + riding_datum.force_dismount(M) + else + R.unbuckle_all_mobs() /datum/emote/living/circle diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 1f0895a7f5..3ae022cdcc 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -8,6 +8,18 @@ if((movement_type & FLYING) && !floating) //TODO: Better floating float(on = TRUE) + if (client || registered_z) // This is a temporary error tracker to make sure we've caught everything + var/turf/T = get_turf(src) + if (client && registered_z != T.z) +#ifdef TESTING + message_admins("[src] [ADMIN_FLW(src)] has somehow ended up in Z-level [T.z] despite being registered in Z-level [registered_z]. If you could ask them how that happened and notify coderbus, it would be appreciated.") +#endif + log_game("Z-TRACKING: [src] has somehow ended up in Z-level [T.z] despite being registered in Z-level [registered_z].") + update_z(T.z) + else if (!client && registered_z) + log_game("Z-TRACKING: [src] of type [src.type] has a Z-registration despite not having a client.") + update_z(null) + if (notransform) return if(!loc) @@ -125,6 +137,9 @@ eye_blurry = max(eye_blurry-1, 0) if(client && !eye_blurry) clear_fullscreen("blurry") + if(disabilities & PACIFISM && a_intent == INTENT_HARM) + to_chat(src, "You don't feel like harming anybody.") + a_intent_change(INTENT_HELP) /mob/living/proc/update_damage_hud() return diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 5abe664328..fbc8e85eb4 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -39,7 +39,6 @@ ranged_ability.remove_ranged_ability(src) if(buckled) buckled.unbuckle_mob(src,force=1) - QDEL_NULL(riding_datum) for(var/mob/living/simple_animal/drone/D in GLOB.player_list) for(var/image/I in staticOverlays) @@ -344,8 +343,15 @@ return 1 return 0 +// Living mobs use can_inject() to make sure that the mob is not syringe-proof in general. /mob/living/proc/can_inject() - return 1 + return TRUE + +/mob/living/is_injectable(allowmobs = TRUE) + return (allowmobs && reagents && can_inject()) + +/mob/living/is_drawable(allowmobs = TRUE) + return (allowmobs && reagents && can_inject()) /mob/living/proc/get_organ_target() var/mob/shooter = src @@ -810,9 +816,12 @@ to_chat(src, "You don't have the dexterity to do this!") return /mob/living/proc/can_use_guns(obj/item/G) - if (G.trigger_guard != TRIGGER_GUARD_ALLOW_ALL && !IsAdvancedToolUser()) + if(G.trigger_guard != TRIGGER_GUARD_ALLOW_ALL && !IsAdvancedToolUser()) to_chat(src, "You don't have the dexterity to do this!") return FALSE + if(disabilities & PACIFISM) + to_chat(src, "You don't want to risk harming anyone!") + return FALSE return TRUE /mob/living/carbon/proc/update_stamina() @@ -919,7 +928,7 @@ update_fire() /mob/living/proc/adjust_fire_stacks(add_fire_stacks) //Adjusting the amount of fire_stacks we have on person - fire_stacks = Clamp(fire_stacks + add_fire_stacks, -20, 20) + fire_stacks = CLAMP(fire_stacks + add_fire_stacks, -20, 20) if(on_fire && fire_stacks <= 0) ExtinguishMob() @@ -955,11 +964,6 @@ "[C] leaps out of [src]'s way!")]") C.Knockdown(40) -/mob/living/post_buckle_mob(mob/living/M) - if(riding_datum) - riding_datum.handle_vehicle_offsets() - riding_datum.handle_vehicle_layer() - /mob/living/ConveyorMove() if((movement_type & FLYING) && !stat) return @@ -1023,3 +1027,41 @@ /mob/living/proc/add_abilities_to_panel() for(var/obj/effect/proc_holder/A in abilities) statpanel("[A.panel]",A.get_panel_text(),A) + +/mob/living/lingcheck() + if(mind) + var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling) + if(changeling) + if(changeling.changeling_speak) + return LINGHIVE_LING + return LINGHIVE_OUTSIDER + if(mind && mind.linglink) + return LINGHIVE_LINK + return LINGHIVE_NONE + +/mob/living/forceMove(atom/destination) + stop_pulling() + if(buckled) + buckled.unbuckle_mob(src, force = TRUE) + if(has_buckled_mobs()) + unbuckle_all_mobs(force = TRUE) + . = ..() + if(.) + if(client) + reset_perspective(destination) + update_canmove() //if the mob was asleep inside a container and then got forceMoved out we need to make them fall. + +/mob/living/proc/update_z(new_z) // 1+ to register, null to unregister + if (registered_z != new_z) + if (registered_z) + SSmobs.clients_by_zlevel[registered_z] -= src + if (client) + if (new_z) + SSmobs.clients_by_zlevel[new_z] += src + registered_z = new_z + else + registered_z = null + +/mob/living/onTransitZ(old_z,new_z) + ..() + update_z(new_z) \ No newline at end of file diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index f77c65225f..ed07313862 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -55,9 +55,9 @@ /obj/item/proc/get_volume_by_throwforce_and_or_w_class() if(throwforce && w_class) - return Clamp((throwforce + w_class) * 5, 30, 100)// Add the item's throwforce to its weight class and multiply by 5, then clamp the value between 30 and 100 + return CLAMP((throwforce + w_class) * 5, 30, 100)// Add the item's throwforce to its weight class and multiply by 5, then clamp the value between 30 and 100 else if(w_class) - return Clamp(w_class * 8, 20, 100) // Multiply the item's weight class by 8, then clamp the value between 20 and 100 + return CLAMP(w_class * 8, 20, 100) // Multiply the item's weight class by 8, then clamp the value between 20 and 100 else return 0 @@ -127,14 +127,19 @@ /mob/living/proc/grabbedby(mob/living/carbon/user, supress_message = 0) if(user == src || anchored || !isturf(user.loc)) - return 0 + return FALSE if(!user.pulling || user.pulling != src) user.start_pulling(src, supress_message) return if(!(status_flags & CANPUSH)) to_chat(user, "[src] can't be grabbed more aggressively!") - return 0 + return FALSE + + if(user.disabilities & PACIFISM) + to_chat(user, "You don't want to risk hurting [src]!") + return FALSE + grippedby(user) //proc to upgrade a simple pull into a more aggressive grab. @@ -188,83 +193,101 @@ M.Feedstop() return // can't attack while eating! + if(disabilities & PACIFISM) + to_chat(M, "You don't want to hurt anyone!") + return FALSE + if (stat != DEAD) add_logs(M, src, "attacked") M.do_attack_animation(src) visible_message("The [M.name] glomps [src]!", \ "The [M.name] glomps [src]!", null, COMBAT_MESSAGE_RANGE) - return 1 + return TRUE /mob/living/attack_animal(mob/living/simple_animal/M) M.face_atom(src) if(M.melee_damage_upper == 0) M.visible_message("\The [M] [M.friendly] [src]!") - return 0 + return FALSE else + if(M.disabilities & PACIFISM) + to_chat(M, "You don't want to hurt anyone!") + return FALSE + if(M.attack_sound) playsound(loc, M.attack_sound, 50, 1, 1) M.do_attack_animation(src) visible_message("\The [M] [M.attacktext] [src]!", \ "\The [M] [M.attacktext] [src]!", null, COMBAT_MESSAGE_RANGE) add_logs(M, src, "attacked") - return 1 + return TRUE /mob/living/attack_paw(mob/living/carbon/monkey/M) if(isturf(loc) && istype(loc.loc, /area/start)) to_chat(M, "No attacking people at spawn, you jackass.") - return 0 + return FALSE if (M.a_intent == INTENT_HARM) + if(M.disabilities & PACIFISM) + to_chat(M, "You don't want to hurt anyone!") + return FALSE + if(M.is_muzzled() || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSMOUTH)) to_chat(M, "You can't bite with your mouth covered!") - return 0 + return FALSE M.do_attack_animation(src, ATTACK_EFFECT_BITE) if (prob(75)) add_logs(M, src, "attacked") playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) visible_message("[M.name] bites [src]!", \ "[M.name] bites [src]!", null, COMBAT_MESSAGE_RANGE) - return 1 + return TRUE else visible_message("[M.name] has attempted to bite [src]!", \ "[M.name] has attempted to bite [src]!", null, COMBAT_MESSAGE_RANGE) - return 0 + return FALSE /mob/living/attack_larva(mob/living/carbon/alien/larva/L) switch(L.a_intent) if("help") visible_message("[L.name] rubs its head against [src].") - return 0 + return FALSE else + if(L.disabilities & PACIFISM) + to_chat(L, "You don't want to hurt anyone!") + return + L.do_attack_animation(src) if(prob(90)) add_logs(L, src, "attacked") visible_message("[L.name] bites [src]!", \ "[L.name] bites [src]!", null, COMBAT_MESSAGE_RANGE) playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) - return 1 + return TRUE else visible_message("[L.name] has attempted to bite [src]!", \ "[L.name] has attempted to bite [src]!", null, COMBAT_MESSAGE_RANGE) - return 0 + return FALSE /mob/living/attack_alien(mob/living/carbon/alien/humanoid/M) switch(M.a_intent) if ("help") visible_message("[M] caresses [src] with its scythe like arm.") - return 0 - + return FALSE if ("grab") grabbedby(M) - return 0 + return FALSE if("harm") + if(M.disabilities & PACIFISM) + to_chat(M, "You don't want to hurt anyone!") + return FALSE M.do_attack_animation(src) - return 1 + return TRUE if("disarm") M.do_attack_animation(src, ATTACK_EFFECT_DISARM) - return 1 + return TRUE /mob/living/ex_act(severity, target, origin) if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src)) diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 36b8c62cca..50f2ce4db0 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -15,7 +15,6 @@ var/toxloss = 0 //Toxic damage caused by being poisoned or radiated var/fireloss = 0 //Burn damage caused by being way too hot, too cold or burnt. var/cloneloss = 0 //Damage caused by being cloned or ejected from the cloner early. slimes also deal cloneloss damage to victims - var/brainloss = 0 //'Retardation' damage caused by someone hitting you in the head with a bible or being infected with brainrot. var/staminaloss = 0 //Stamina damage, or exhaustion. You recover it slowly naturally, and are knocked down if it gets too high. Holodeck and hallucinations deal this. @@ -79,3 +78,5 @@ var/last_words //used for database logging var/list/obj/effect/proc_holder/abilities = list() + + var/registered_z \ No newline at end of file diff --git a/code/modules/mob/living/login.dm b/code/modules/mob/living/login.dm index 97ffa72aec..611d9dbc4c 100644 --- a/code/modules/mob/living/login.dm +++ b/code/modules/mob/living/login.dm @@ -13,6 +13,10 @@ update_damage_hud() update_health_hud() + var/turf/T = get_turf(src) + if (isturf(T)) + update_z(T.z) + //Vents if(ventcrawler) to_chat(src, "You can ventcrawl! Use alt+click on vents to quickly travel about the station.") diff --git a/code/modules/mob/living/logout.dm b/code/modules/mob/living/logout.dm index a3479aac89..18b171753a 100644 --- a/code/modules/mob/living/logout.dm +++ b/code/modules/mob/living/logout.dm @@ -1,6 +1,7 @@ -/mob/living/Logout() - if(ranged_ability && client) - ranged_ability.remove_mousepointer(client) - ..() +/mob/living/Logout() + update_z(null) + if(ranged_ability && client) + ranged_ability.remove_mousepointer(client) + ..() if(!key && mind) //key and mind have become separated. - mind.active = 0 //This is to stop say, a mind.transfer_to call on a corpse causing a ghost to re-enter its body. \ No newline at end of file + mind.active = 0 //This is to stop say, a mind.transfer_to call on a corpse causing a ghost to re-enter its body. diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index a2fdb9d2b0..b1d0484086 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -37,41 +37,42 @@ GLOBAL_LIST_INIT(department_radio_keys, list( //kinda localization -- rastaf0 //same keys as above, but on russian keyboard layout. This file uses cp1251 as encoding. // Location - "" = "right hand", - "" = "left hand", - "" = "intercom", + "ê" = "right hand", + "ä" = "left hand", + "ø" = "intercom", // Department - "" = "department", - "" = "Command", - "" = "Science", - "" = "Medical", - "" = "Engineering", - "" = "Security", - "" = "Supply", - "" = "Service", + "ð" = "department", + "ñ" = "Command", + "ò" = "Science", + "ü" = "Medical", + "ó" = "Engineering", + "û" = "Security", + "ã" = "Supply", + "ì" = "Service", // Faction - "" = "Syndicate", - "" = "CentCom", + "å" = "Syndicate", + "í" = "CentCom", // Species - "" = "binary", - "" = "changeling", - "" = "alientalk", + "è" = "binary", + "ï" = "changeling", + "ô" = "alientalk", // Admin - "" = "admin", - "" = "deadmin", + "ç" = "admin", + "â" = "deadmin", // Misc - "" = "AI Private", - "" = "cords" + "ù" = "AI Private", + "÷" = "cords" )) /mob/living/say(message, bubble_type,var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE) var/static/list/crit_allowed_modes = list(MODE_WHISPER = TRUE, MODE_CHANGELING = TRUE, MODE_ALIEN = TRUE) var/static/list/unconscious_allowed_modes = list(MODE_CHANGELING = TRUE, MODE_ALIEN = TRUE) + var/key = get_key(message) var/static/list/one_character_prefix = list(MODE_HEADSET = TRUE, MODE_ROBOT = TRUE, MODE_WHISPER = TRUE) @@ -134,8 +135,11 @@ GLOBAL_LIST_INIT(department_radio_keys, list( // AIs use inherent channels for the holopad. Most inherent channels // ignore the language argument however. - if(handle_inherent_channels(message, message_mode, language)) //Hiveminds, binary chat & holopad. - return + var/datum/saymode/SM = SSradio.saymodes[key] + if(key && SM) + if(!SM.handle_message(src, message, language) && !message_mode) + return + if(!can_speak_vocal(message)) to_chat(src, "You find yourself unable to speak!") @@ -264,7 +268,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list( INVOKE_ASYNC(GLOBAL_PROC, /.proc/flick_overlay, I, speech_bubble_recipients, 30) /mob/proc/binarycheck() - return 0 + return FALSE /mob/living/can_speak(message) //For use outside of Say() if(can_speak_basic(message) && can_speak_vocal(message)) @@ -307,6 +311,11 @@ GLOBAL_LIST_INIT(department_radio_keys, list( var/key_symbol = lowertext(copytext(message, 2, 3)) return GLOB.department_radio_keys[key_symbol] +/mob/living/proc/get_key(message) + var/key = copytext(message, 1, 2) + if(key in GLOB.department_radio_prefixes) + return lowertext(copytext(message, 2, 3)) + /mob/living/proc/get_message_language(message) if(copytext(message, 1, 2) == ",") var/key = copytext(message, 2, 3) @@ -316,62 +325,8 @@ GLOBAL_LIST_INIT(department_radio_keys, list( return LD return null -/mob/living/proc/handle_inherent_channels(message, message_mode) - if(message_mode == MODE_CHANGELING) - switch(lingcheck()) - if(3) - var/msg = "[src.mind]: [message]" - for(var/_M in GLOB.mob_list) - var/mob/M = _M - if(M in GLOB.dead_mob_list) - var/link = FOLLOW_LINK(M, src) - to_chat(M, "[link] [msg]") - else - switch(M.lingcheck()) - if(3) - to_chat(M, msg) - if(2) - to_chat(M, msg) - if(1) - if(prob(40)) - to_chat(M, "We can faintly sense an outsider trying to communicate through the hivemind...") - if(2) - var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling) - var/msg = "[changeling.changelingID]: [message]" - log_talk(src,"[changeling.changelingID]/[key] : [message]",LOGSAY) - for(var/_M in GLOB.mob_list) - var/mob/M = _M - if(M in GLOB.dead_mob_list) - var/link = FOLLOW_LINK(M, src) - to_chat(M, "[link] [msg]") - else - switch(M.lingcheck()) - if(3) - to_chat(M, msg) - if(2) - to_chat(M, msg) - if(1) - if(prob(40)) - to_chat(M, "We can faintly sense another of our kind trying to communicate through the hivemind...") - if(1) - to_chat(src, "Our senses have not evolved enough to be able to communicate this way...") - return TRUE - if(message_mode == MODE_ALIEN) - if(hivecheck()) - alien_talk(message) - return TRUE - if(message_mode == MODE_VOCALCORDS) - if(iscarbon(src)) - var/mob/living/carbon/C = src - var/obj/item/organ/vocal_cords/V = C.getorganslot(ORGAN_SLOT_VOICE) - if(V && V.can_speak_with()) - V.handle_speech(message) //message - V.speak_with(message) //action - return TRUE - return FALSE - /mob/living/proc/treat_message(message) - if(getBrainLoss() >= 60) + if(derpspeech) message = derpspeech(message, stuttering) if(stuttering) @@ -408,22 +363,9 @@ GLOBAL_LIST_INIT(department_radio_keys, list( return ITALICS | REDUCE_RANGE if(MODE_BINARY) - if(binarycheck()) - robot_talk(message) return ITALICS | REDUCE_RANGE //Does not return 0 since this is only reached by humans, not borgs or AIs. return 0 -/mob/living/lingcheck() //1 is ling w/ no hivemind. 2 is ling w/hivemind. 3 is ling victim being linked into hivemind. - if(mind) - var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling) - if(changeling) - if(changeling.changeling_speak) - return 2 - return 1 - if(mind && mind.linglink) - return 3 - return 0 - /mob/living/say_mod(input, message_mode) if(message_mode == MODE_WHISPER) . = verb_whisper @@ -431,7 +373,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list( . = "[verb_whisper] in [p_their()] last breath" else if(stuttering) . = "stammers" - else if(getBrainLoss() >= 60) + else if(derpspeech) . = "gibbers" else . = ..() diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 0fb044429c..86314e33d7 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -25,6 +25,7 @@ see_in_dark = 8 med_hud = DATA_HUD_MEDICAL_BASIC sec_hud = DATA_HUD_SECURITY_BASIC + d_hud = DATA_HUD_DIAGNOSTIC_ADVANCED mob_size = MOB_SIZE_LARGE var/list/network = list("SS13") var/obj/machinery/camera/current = null @@ -116,7 +117,7 @@ job = "AI" eyeobj.ai = src - eyeobj.loc = src.loc + eyeobj.forceMove(src.loc) rename_self("ai") holo_icon = getHologramIcon(icon('icons/mob/ai.dmi',"default")) @@ -816,7 +817,8 @@ return (GLOB.cameranet && GLOB.cameranet.checkTurfVis(get_turf_pixel(A))) || apc_override //AI is carded/shunted //view(src) returns nothing for carded/shunted AIs and they have x-ray vision so just use get_dist - return get_dist(src, A) <= client.view + var/list/viewscale = getviewsize(client.view) + return get_dist(src, A) <= max(viewscale[1]*0.5,viewscale[2]*0.5) /mob/living/silicon/ai/proc/relay_speech(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode) raw_message = lang_treat(speaker, message_language, raw_message, spans, message_mode) diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index a42a2f7890..1d2598c63d 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -21,7 +21,10 @@ if(!isturf(ai.loc)) return T = get_turf(T) - loc = T + if (T) + forceMove(T) + else + moveToNullspace() // ???? if(use_static) GLOB.cameranet.visibility(src) if(ai.client) diff --git a/code/modules/mob/living/silicon/ai/say.dm b/code/modules/mob/living/silicon/ai/say.dm index 13f0609c0d..b55fa2a663 100644 --- a/code/modules/mob/living/silicon/ai/say.dm +++ b/code/modules/mob/living/silicon/ai/say.dm @@ -31,15 +31,6 @@ else return ..() -/mob/living/silicon/ai/handle_inherent_channels(message, message_mode, language) - . = ..() - if(.) - return . - - if(message_mode == MODE_HOLOPAD) - holopad_talk(message, language) - return 1 - //For holopads only. Usable by AI. /mob/living/silicon/ai/proc/holopad_talk(message, language) diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index ed4e79f273..924ab615b8 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -99,7 +99,7 @@ var/newcardloc = P P = new /obj/item/device/paicard(newcardloc) P.setPersonality(src) - loc = P + forceMove(P) card = P sradio = new(src) if(!radio) @@ -114,12 +114,14 @@ . = ..() + var/datum/action/innate/pai/software/SW = new var/datum/action/innate/pai/shell/AS = new /datum/action/innate/pai/shell var/datum/action/innate/pai/chassis/AC = new /datum/action/innate/pai/chassis var/datum/action/innate/pai/rest/AR = new /datum/action/innate/pai/rest var/datum/action/innate/pai/light/AL = new /datum/action/innate/pai/light var/datum/action/language_menu/ALM = new + SW.Grant(src) AS.Grant(src) AC.Grant(src) AR.Grant(src) @@ -136,7 +138,7 @@ /mob/living/silicon/pai/proc/process_hack() if(cable && cable.machine && istype(cable.machine, /obj/machinery/door) && cable.machine == hackdoor && get_dist(src, hackdoor) <= 1) - hackprogress = Clamp(hackprogress + 4, 0, 100) + hackprogress = CLAMP(hackprogress + 4, 0, 100) else temp = "Door Jack: Connection to airlock has been lost. Hack aborted." hackprogress = 0 @@ -200,6 +202,15 @@ return 0 P = owner +/datum/action/innate/pai/software + name = "Software Interface" + button_icon_state = "pai" + background_icon_state = "bg_tech" + +/datum/action/innate/pai/software/Trigger() + ..() + P.paiInterface() + /datum/action/innate/pai/shell name = "Toggle Holoform" button_icon_state = "pai_holoform" @@ -272,8 +283,8 @@ /mob/living/silicon/pai/process() - emitterhealth = Clamp((emitterhealth + emitterregen), -50, emittermaxhealth) - hit_slowdown = Clamp((hit_slowdown - 1), 0, 100) + emitterhealth = CLAMP((emitterhealth + emitterregen), -50, emittermaxhealth) + hit_slowdown = CLAMP((hit_slowdown - 1), 0, 100) /mob/living/silicon/pai/generateStaticOverlay() return diff --git a/code/modules/mob/living/silicon/pai/pai_defense.dm b/code/modules/mob/living/silicon/pai/pai_defense.dm index 83da7d9087..2c6c42e3bb 100644 --- a/code/modules/mob/living/silicon/pai/pai_defense.dm +++ b/code/modules/mob/living/silicon/pai/pai_defense.dm @@ -57,7 +57,7 @@ return FALSE //No we're not flammable /mob/living/silicon/pai/proc/take_holo_damage(amount) - emitterhealth = Clamp((emitterhealth - amount), -50, emittermaxhealth) + emitterhealth = CLAMP((emitterhealth - amount), -50, emittermaxhealth) if(emitterhealth < 0) fold_in(force = TRUE) to_chat(src, "The impact degrades your holochassis!") diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index 7df929f20a..e73792e705 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -22,9 +22,7 @@ "remote signaller" = 5, ) -/mob/living/silicon/pai/verb/paiInterface() - set category = "pAI Commands" - set name = "Software Interface" +/mob/living/silicon/pai/proc/paiInterface() var/dat = "" var/left_part = "" var/right_part = softwareMenu() diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index aab1f204f6..5445941ed3 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -23,7 +23,7 @@ if(cell && cell.charge) if(cell.charge <= 100) uneq_all() - var/amt = Clamp((lamp_intensity - 2) * 2,1,cell.charge) //Always try to use at least one charge per tick, but allow it to completely drain the cell. + var/amt = CLAMP((lamp_intensity - 2) * 2,1,cell.charge) //Always try to use at least one charge per tick, but allow it to completely drain the cell. cell.use(amt) //Usage table: 1/tick if off/lowest setting, 4 = 4/tick, 6 = 8/tick, 8 = 12/tick, 10 = 16/tick else uneq_all() @@ -50,6 +50,7 @@ if(!mind.special_role) mind.special_role = "traitor" SSticker.mode.traitors += mind + mind.add_antag_datum(/datum/antagonist/auto_custom) // ???? /mob/living/silicon/robot/update_health_hud() diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 72dc341276..db10f4a81c 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -115,9 +115,7 @@ ident = rand(1, 999) if(!cell) - cell = new /obj/item/stock_parts/cell(src) - cell.maxcharge = 7500 - cell.charge = 7500 + cell = new /obj/item/stock_parts/cell/high(src, 7500) if(lawupdate) make_laws() @@ -854,8 +852,7 @@ /mob/living/silicon/robot/modules/syndicate/Initialize() . = ..() - cell.maxcharge = 25000 - cell.charge = 25000 + cell = new /obj/item/stock_parts/cell/hyper(src, 25000) radio = new /obj/item/device/radio/borg/syndicate(src) laws = new /datum/ai_laws/syndicate_override() addtimer(CALLBACK(src, .proc/show_playstyle), 5) @@ -1151,8 +1148,7 @@ if(!is_type_in_typecache(M, can_ride_typecache)) M.visible_message("[M] really can't seem to mount [src]...") return - if(!riding_datum) - riding_datum = new /datum/riding/cyborg(src) + var/datum/component/riding/riding_datum = LoadComponent(/datum/component/riding/cyborg) if(buckled_mobs) if(buckled_mobs.len >= max_buckled_mobs) return @@ -1175,7 +1171,8 @@ /mob/living/silicon/robot/unbuckle_mob(mob/user) if(iscarbon(user)) - if(riding_datum) + GET_COMPONENT(riding_datum, /datum/component/riding) + if(istype(riding_datum)) riding_datum.unequip_buckle_inhands(user) riding_datum.restore_position(user) . = ..(user) diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index b1be1c3076..26e455106b 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -352,7 +352,7 @@ ratvar_modules = list(/obj/item/clockwork/slab/cyborg/security, /obj/item/clockwork/weapon/ratvarian_spear) cyborg_base_icon = "k9" - moduleselect_icon = "k9" + moduleselect_icon = "security" can_be_pushed = FALSE hat_offset = INFINITY @@ -387,7 +387,7 @@ ratvar_modules = list(/obj/item/clockwork/slab/cyborg/medical, /obj/item/clockwork/weapon/ratvarian_spear) cyborg_base_icon = "medihound" - moduleselect_icon = "medihound" + moduleselect_icon = "medical" can_be_pushed = FALSE hat_offset = INFINITY @@ -409,7 +409,7 @@ /obj/item/clockwork/slab/cyborg/janitor, /obj/item/clockwork/replica_fabricator/cyborg) cyborg_base_icon = "scrubpup" - moduleselect_icon = "scrubpup" + moduleselect_icon = "janitor" hat_offset = INFINITY clean_on_move = TRUE diff --git a/code/modules/mob/living/silicon/robot/robot_movement.dm b/code/modules/mob/living/silicon/robot/robot_movement.dm index 762d86dee9..5c24b15267 100644 --- a/code/modules/mob/living/silicon/robot/robot_movement.dm +++ b/code/modules/mob/living/silicon/robot/robot_movement.dm @@ -19,8 +19,3 @@ /mob/living/silicon/robot/experience_pressure_difference(pressure_difference, direction) if(!magpulse) return ..() - -/mob/living/silicon/robot/Moved() - . = ..() - if(riding_datum) - riding_datum.on_vehicle_move() diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm index f3e7baa0d9..785d55e5f4 100644 --- a/code/modules/mob/living/silicon/say.dm +++ b/code/modules/mob/living/silicon/say.dm @@ -10,14 +10,14 @@ var/mob/living/silicon/S = src desig = trim_left(S.designation + " " + S.job) var/message_a = say_quote(message, get_spans()) - var/rendered = "Robotic Talk, [name] [message_a]" + var/rendered = "Robotic Talk, [name] [message_a]" for(var/mob/M in GLOB.player_list) if(M.binarycheck()) if(isAI(M)) - var/renderedAI = "Robotic Talk, [name] ([desig]) [message_a]" + var/renderedAI = "Robotic Talk, [name] ([desig]) [message_a]" to_chat(M, renderedAI) else - to_chat(M, rendered) + to_chat(M, "[rendered]") if(isobserver(M)) var/following = src // If the AI talks on binary chat, we still want to follow @@ -26,7 +26,7 @@ var/mob/living/silicon/ai/ai = src following = ai.eyeobj var/link = FOLLOW_LINK(M, following) - to_chat(M, "[link] [rendered]") + to_chat(M, "[link] [rendered]") /mob/living/silicon/binarycheck() return 1 @@ -57,14 +57,3 @@ return MODE_ROBOT else return . - -/mob/living/silicon/handle_inherent_channels(message, message_mode) - . = ..() - if(.) - return . - - if(message_mode == MODE_BINARY) - if(binarycheck()) - robot_talk(message) - return 1 - return 0 diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index fa8447885d..5de09011ea 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -33,7 +33,7 @@ var/med_hud = DATA_HUD_MEDICAL_ADVANCED //Determines the med hud to use var/sec_hud = DATA_HUD_SECURITY_ADVANCED //Determines the sec hud to use - var/d_hud = DATA_HUD_DIAGNOSTIC //There is only one kind of diag hud + var/d_hud = DATA_HUD_DIAGNOSTIC_BASIC //Determines the diag hud to use var/law_change_counter = 0 var/obj/machinery/camera/builtInCamera = null @@ -42,8 +42,8 @@ /mob/living/silicon/Initialize() . = ..() GLOB.silicon_mobs += src - var/datum/atom_hud/data/diagnostic/diag_hud = GLOB.huds[DATA_HUD_DIAGNOSTIC] - diag_hud.add_to_hud(src) + for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds) + diag_hud.add_to_hud(src) diag_hud_set_status() diag_hud_set_health() diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index d4c459e996..b19bc401e3 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -1,5 +1,3 @@ -//Defines for bots are now found in code\__DEFINES\bots.dm - // AI (i.e. game AI, not the AI player) controlled bots /mob/living/simple_animal/bot icon = 'icons/mob/aibots.dmi' @@ -50,7 +48,7 @@ var/frustration = 0 //Used by some bots for tracking failures to reach their target. var/base_speed = 2 //The speed at which the bot moves, or the number of times it moves per process() tick. var/turf/ai_waypoint //The end point of a bot's path, or the target location. - var/list/path = list() //List of turfs through which a bot 'steps' to reach the waypoint. + var/list/path = list() //List of turfs through which a bot 'steps' to reach the waypoint, associated with the path image, if there is one. var/pathset = 0 var/list/ignore_list = list() //List of unreachable targets for an ignore-list enabled bot to ignore. var/mode = BOT_IDLE //Standardizes the vars that indicate the bot is busy with its function. @@ -77,15 +75,21 @@ var/beacon_freq = 1445 // navigation beacon frequency var/model = "" //The type of bot it is. var/bot_type = 0 //The type of bot it is, for radio control. - var/data_hud_type = DATA_HUD_DIAGNOSTIC //The type of data HUD the bot uses. Diagnostic by default. + var/data_hud_type = DATA_HUD_DIAGNOSTIC_BASIC //The type of data HUD the bot uses. Diagnostic by default. + //This holds text for what the bot is mode doing, reported on the remote bot control interface. var/list/mode_name = list("In Pursuit","Preparing to Arrest", "Arresting", \ "Beginning Patrol", "Patrolling", "Summoned by PDA", \ "Cleaning", "Repairing", "Proceeding to work site", "Healing", \ "Proceeding to AI waypoint", "Navigating to Delivery Location", "Navigating to Home", \ "Waiting for clear path", "Calculating navigation path", "Pinging beacon network", "Unable to reach destination") - //This holds text for what the bot is mode doing, reported on the remote bot control interface. + var/datum/atom_hud/data/bot_path/path_hud = new /datum/atom_hud/data/bot_path() + var/path_image_icon = 'icons/mob/aibots.dmi' + var/path_image_icon_state = "path_indicator" + var/path_image_color = "#FFFFFF" + var/reset_access_timer_id + var/ignorelistcleanuptimer = 1 // This ticks up every automated action, at 300 we clean the ignore list - hud_possible = list(DIAG_STAT_HUD, DIAG_BOT_HUD, DIAG_HUD) //Diagnostic HUD views + hud_possible = list(DIAG_STAT_HUD, DIAG_BOT_HUD, DIAG_HUD, DIAG_PATH_HUD = HUD_LIST_LIST) //Diagnostic HUD views /mob/living/simple_animal/bot/proc/get_mode() if(client) //Player bots do not have modes, thus the override. Also an easy way for PDA users/AI to know when a bot is a player. @@ -102,12 +106,12 @@ /mob/living/simple_animal/bot/proc/turn_on() if(stat) - return 0 + return FALSE on = TRUE set_light(initial(light_range)) update_icon() diag_hud_set_botstat() - return 1 + return TRUE /mob/living/simple_animal/bot/proc/turn_off() on = FALSE @@ -117,6 +121,7 @@ /mob/living/simple_animal/bot/Initialize() . = ..() + GLOB.bots_list += src access_card = new /obj/item/card/id(src) //This access is so bots can be immediately set to patrol and leave Robotics, instead of having to be let out first. access_card.access += ACCESS_ROBOTICS @@ -132,15 +137,19 @@ //Adds bot to the diagnostic HUD system prepare_huds() - var/datum/atom_hud/data/diagnostic/diag_hud = GLOB.huds[DATA_HUD_DIAGNOSTIC] - diag_hud.add_to_hud(src) + for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds) + diag_hud.add_to_hud(src) diag_hud_set_bothealth() diag_hud_set_botstat() diag_hud_set_botmode() - //Gives a HUD view to player bots that use a HUD. - activate_data_hud() - + //If a bot has its own HUD (for player bots), provide it. + if(data_hud_type) + var/datum/atom_hud/datahud = GLOB.huds[data_hud_type] + datahud.add_hud_to(src) + if(path_hud) + path_hud.add_to_hud(src) + path_hud.add_hud_to(src) /mob/living/simple_animal/bot/update_canmove() . = ..() @@ -149,6 +158,10 @@ canmove = . /mob/living/simple_animal/bot/Destroy() + if(path_hud) + QDEL_NULL(path_hud) + path_hud = null + GLOB.bots_list -= src if(paicard) ejectpai() qdel(Radio) @@ -157,7 +170,7 @@ return ..() /mob/living/simple_animal/bot/bee_friendly() - return 1 + return TRUE /mob/living/simple_animal/bot/death(gibbed) explode() @@ -213,6 +226,15 @@ set background = BACKGROUND_ENABLED diag_hud_set_botmode() + if (ignorelistcleanuptimer % 300 == 0) // Every 300 actions, clean up the ignore list from old junk + for(var/ref in ignore_list) + var/atom/referredatom = locate(ref) + if (!referredatom || !istype(referredatom) || QDELETED(referredatom)) + ignore_list -= ref + ignorelistcleanuptimer = 1 + else + ignorelistcleanuptimer++ + if(!on || client) return @@ -223,7 +245,7 @@ if(BOT_SUMMON) //Called by PDA bot_summon() return - return 1 //Successful completion. Used to prevent child process() continuing if this one is ended early. + return TRUE //Successful completion. Used to prevent child process() continuing if this one is ended early. /mob/living/simple_animal/bot/attack_hand(mob/living/carbon/human/H) @@ -330,7 +352,7 @@ /mob/living/simple_animal/bot/radio(message, message_mode, list/spans, language) . = ..() if(. != 0) - return . + return switch(message_mode) if(MODE_HEADSET) @@ -344,7 +366,6 @@ if(message_mode in GLOB.radiochannels) Radio.talk_into(src, message, message_mode, spans, language) return REDUCE_RANGE - return 0 //Generalized behavior code, override where needed! @@ -386,15 +407,15 @@ Pass the desired type path itself, declaring a temporary var beforehand is not r /mob/living/simple_animal/bot/proc/checkscan(scan, scan_type, old_target) if(!istype(scan, scan_type)) //Check that the thing we found is the type we want! - return 0 //If not, keep searching! - if( (scan in ignore_list) || (scan == old_target) ) //Filter for blacklisted elements, usually unreachable or previously processed oness - return 0 + return FALSE //If not, keep searching! + if( (REF(scan) in ignore_list) || (scan == old_target) ) //Filter for blacklisted elements, usually unreachable or previously processed oness + return FALSE var/scan_result = process_scan(scan) //Some bots may require additional processing when a result is selected. if(scan_result) return scan_result else - return 0 //The current element failed assessment, move on to the next. + return FALSE //The current element failed assessment, move on to the next. return /mob/living/simple_animal/bot/proc/check_bot(targ) @@ -402,7 +423,7 @@ Pass the desired type path itself, declaring a temporary var beforehand is not r if(T) for(var/C in T.contents) if(istype(C,type) && (C != src)) //Is there another bot there already? If so, let's skip it so we dont all atack on top of eachother. - return 1 //Let's abort if we find a bot so we dont have to keep rechecking + return TRUE //Let's abort if we find a bot so we dont have to keep rechecking //When the scan finds a target, run bot specific processing to select it for the next step. Empty by default. /mob/living/simple_animal/bot/proc/process_scan(scan_target) @@ -411,27 +432,26 @@ Pass the desired type path itself, declaring a temporary var beforehand is not r /mob/living/simple_animal/bot/proc/add_to_ignore(subject) if(ignore_list.len < 50) //This will help keep track of them, so the bot is always trying to reach a blocked spot. - ignore_list |= subject - else if(ignore_list.len >= subject) //If the list is full, insert newest, delete oldest. - ignore_list -= ignore_list[1] - ignore_list |= subject + ignore_list += REF(subject) + else //If the list is full, insert newest, delete oldest. + ignore_list.Cut(1,2) + ignore_list += REF(subject) /* Movement proc for stepping a bot through a path generated through A-star. Pass a positive integer as an argument to override a bot's default speed. */ /mob/living/simple_animal/bot/proc/bot_move(dest, move_speed) - if(!dest || !path || path.len == 0) //A-star failed or a path/destination was not set. - path = list() - return 0 + set_path(null) + return FALSE dest = get_turf(dest) //We must always compare turfs, so get the turf of the dest var if dest was originally something else. var/turf/last_node = get_turf(path[path.len]) //This is the turf at the end of the path, it should be equal to dest. if(get_turf(src) == dest) //We have arrived, no need to move again. - return 1 + return TRUE else if(dest != last_node) //The path should lead us to our given destination. If this is not true, we must stop. - path = list() - return 0 + set_path(null) + return FALSE var/step_count = move_speed ? move_speed : base_speed //If a value is passed into move_speed, use that instead of the default speed var. if(step_count >= 1 && tries < BOT_STEP_MAX_RETRIES) @@ -439,25 +459,25 @@ Pass a positive integer as an argument to override a bot's default speed. spawn(BOT_STEP_DELAY*step_number) bot_step(dest) else - return 0 - return 1 + return FALSE + return TRUE /mob/living/simple_animal/bot/proc/bot_step(dest) //Step,increase tries if failed if(!path) - return 0 + return FALSE if(path.len > 1) step_towards(src, path[1]) if(get_turf(src) == path[1]) //Successful move - path -= path[1] + increment_path() tries = 0 else tries++ - return 0 + return FALSE else if(path.len == 1) step_to(src, dest) - path = list() - return 1 + set_path(null) + return TRUE /mob/living/simple_animal/bot/proc/check_bot_access() @@ -468,15 +488,12 @@ Pass a positive integer as an argument to override a bot's default speed. bot_reset() //Reset a bot before setting it to call mode. var/area/end_area = get_area(waypoint) - if(client) //Player bots instead get a location command from the AI - to_chat(src, "Priority waypoint set by [icon2html(caller, src)] [caller]. Proceed to [end_area.name]<\b>.") - //For giving the bot temporary all-access. var/obj/item/card/id/all_access = new /obj/item/card/id var/datum/job/captain/All = new/datum/job/captain all_access.access = All.get_access() - path = get_path_to(src, waypoint, /turf/proc/Distance_cardinal, 0, 200, id=all_access) + set_path(get_path_to(src, waypoint, /turf/proc/Distance_cardinal, 0, 200, id=all_access)) calling_ai = caller //Link the AI to the bot! ai_waypoint = waypoint @@ -484,6 +501,9 @@ Pass a positive integer as an argument to override a bot's default speed. if(!on) turn_on() //Saves the AI the hassle of having to activate a bot manually. access_card = all_access //Give the bot all-access while under the AI's command. + if(client) + reset_access_timer_id = addtimer(CALLBACK (src, .proc/bot_reset), 600, TIMER_OVERRIDE|TIMER_STOPPABLE) //if the bot is player controlled, they get the extra access for a limited time + to_chat(src, "Priority waypoint set by [icon2html(calling_ai, src)] [caller]. Proceed to [end_area.name].
    [path.len-1] meters to destination. You have been granted additional door access for 60 seconds.
    ") if(message) to_chat(calling_ai, "[icon2html(src, calling_ai)] [name] called to [end_area.name]. [path.len-1] meters to destination.") pathset = 1 @@ -493,7 +513,7 @@ Pass a positive integer as an argument to override a bot's default speed. if(message) to_chat(calling_ai, "Failed to calculate a valid route. Ensure destination is clear of obstructions and within range.") calling_ai = null - path = list() + set_path(null) /mob/living/simple_animal/bot/proc/call_mode() //Handles preparing a bot for a call, as well as calling the move proc. //Handles the bot's movement during a call. @@ -508,7 +528,10 @@ Pass a positive integer as an argument to override a bot's default speed. if(calling_ai) //Simple notification to the AI if it called a bot. It will not know the cause or identity of the bot. to_chat(calling_ai, "Call command to a bot has been reset.") calling_ai = null - path = list() + if(reset_access_timer_id) + deltimer(reset_access_timer_id) + reset_access_timer_id = null + set_path(null) summon_target = null pathset = 0 access_card.access = prev_access @@ -571,9 +594,8 @@ Pass a positive integer as an argument to override a bot's default speed. return else if(path.len > 0 && patrol_target) // valid path - var/turf/next = path[1] - if(next == loc) - path -= next + if(path[1] == loc) + increment_path() return @@ -608,7 +630,7 @@ Pass a positive integer as an argument to override a bot's default speed. destination = new_destination //We now know the name of where we want to go. patrol_target = NB.loc //Get its location and set it as the target. next_destination = NB.codes["next_patrol"] //Also get the name of the next beacon in line. - return 1 + return TRUE /mob/living/simple_animal/bot/proc/find_nearest_beacon() for(var/obj/machinery/navbeacon/NB in GLOB.navbeacons["[z]"]) @@ -630,7 +652,7 @@ Pass a positive integer as an argument to override a bot's default speed. //PDA control. Some bots, especially MULEs, may have more parameters. /mob/living/simple_animal/bot/proc/bot_control(command, mob/user, turf/user_turf, list/user_access = list()) if(!on || emagged == 2 || remote_disabled) //Emagged bots do not respect anyone's authority! Bots with their remote controls off cannot get commands. - return 1 //ACCESS DENIED + return TRUE //ACCESS DENIED if(client) bot_control_message(command,user,user_turf,user_access) // process control input @@ -685,12 +707,12 @@ Pass a positive integer as an argument to override a bot's default speed. // given an optional turf to avoid /mob/living/simple_animal/bot/proc/calc_path(turf/avoid) check_bot_access() - path = get_path_to(src, patrol_target, /turf/proc/Distance_cardinal, 0, 120, id=access_card, exclude=avoid) + set_path(get_path_to(src, patrol_target, /turf/proc/Distance_cardinal, 0, 120, id=access_card, exclude=avoid)) /mob/living/simple_animal/bot/proc/calc_summon_path(turf/avoid) check_bot_access() spawn() - path = get_path_to(src, summon_target, /turf/proc/Distance_cardinal, 0, 150, id=access_card, exclude=avoid) + set_path(get_path_to(src, summon_target, /turf/proc/Distance_cardinal, 0, 150, id=access_card, exclude=avoid)) if(!path.len) //Cannot reach target. Give up and announce the issue. speak("Summon command failed, destination unreachable.",radio_channel) bot_reset() @@ -705,9 +727,8 @@ Pass a positive integer as an argument to override a bot's default speed. return else if(path.len > 0 && summon_target) //Proper path acquired! - var/turf/next = path[1] - if(next == loc) - path -= next + if(path[1] == loc) + increment_path() return var/moved = bot_move(summon_target, 3) // Move attempt @@ -749,11 +770,11 @@ Pass a positive integer as an argument to override a bot's default speed. if(href_list["close"])// HUE HUE if(usr in users) users.Remove(usr) - return 1 + return TRUE if(topic_denied(usr)) to_chat(usr, "[src]'s interface is not responding!") - return 1 + return TRUE add_fingerprint(usr) if((href_list["power"]) && (bot_core.allowed(usr) || !locked)) @@ -804,14 +825,14 @@ Pass a positive integer as an argument to override a bot's default speed. /mob/living/simple_animal/bot/proc/topic_denied(mob/user) //Access check proc for bot topics! Remember to place in a bot's individual Topic if desired. if(!user.canUseTopic(src)) - return 1 + return TRUE // 0 for access, 1 for denied. if(emagged == 2) //An emagged bot cannot be controlled by humans, silicons can if one hacked it. if(!hacked) //Manually emagged by a human - access denied to all. - return 1 + return TRUE else if(!issilicon(user) && !IsAdminGhost(user)) //Bot is hacked, so only silicons and admins are allowed access. - return 1 - return 0 + return TRUE + return FALSE /mob/living/simple_animal/bot/proc/hack(mob/user) var/hack @@ -857,7 +878,7 @@ Pass a positive integer as an argument to override a bot's default speed. faction = user.faction.Copy() language_holder = paicard.pai.language_holder.copy(src) add_logs(user, paicard.pai, "uploaded to [bot_name],") - return 1 + return TRUE else to_chat(user, "[card] is inactive.") else @@ -894,7 +915,6 @@ Pass a positive integer as an argument to override a bot's default speed. . = ..() access_card.access += player_access diag_hud_set_botmode() - activate_data_hud() /mob/living/simple_animal/bot/Logout() . = ..() @@ -914,9 +934,63 @@ Pass a positive integer as an argument to override a bot's default speed. /mob/living/simple_animal/bot/sentience_act() faction -= "silicon" -/mob/living/simple_animal/bot/proc/activate_data_hud() -//If a bot has its own HUD (for player bots), provide it. - if(!data_hud_type) +/mob/living/simple_animal/bot/proc/set_path(list/newpath) + path = newpath ? newpath : list() + if(!path_hud) return - var/datum/atom_hud/datahud = GLOB.huds[data_hud_type] - datahud.add_hud_to(src) + var/list/path_huds_watching_me = list(GLOB.huds[DATA_HUD_DIAGNOSTIC_ADVANCED]) + if(path_hud) + path_huds_watching_me += path_hud + for(var/V in path_huds_watching_me) + var/datum/atom_hud/H = V + H.remove_from_hud(src) + + var/list/path_images = hud_list[DIAG_PATH_HUD] + QDEL_LIST(path_images) + if(newpath) + for(var/i in 1 to newpath.len) + var/turf/T = newpath[i] + var/direction = NORTH + if(i > 1) + var/turf/prevT = path[i - 1] + var/image/prevI = path[prevT] + direction = get_dir(prevT, T) + if(i > 2) + var/turf/prevprevT = path[i - 2] + var/prevDir = get_dir(prevprevT, prevT) + var/mixDir = direction|prevDir + if(mixDir in GLOB.diagonals) + prevI.dir = mixDir + if(prevDir & (NORTH|SOUTH)) + var/matrix/ntransform = matrix() + ntransform.Turn(90) + if((mixDir == NORTHWEST) || (mixDir == SOUTHEAST)) + ntransform.Scale(-1, 1) + else + ntransform.Scale(1, -1) + prevI.transform = ntransform + var/mutable_appearance/MA = new /mutable_appearance() + MA.icon = path_image_icon + MA.icon_state = path_image_icon_state + MA.layer = ABOVE_OPEN_TURF_LAYER + MA.plane = 0 + MA.appearance_flags = RESET_COLOR|RESET_TRANSFORM + MA.color = path_image_color + MA.dir = direction + var/image/I = image(loc = T) + I.appearance = MA + path[T] = I + path_images += I + + for(var/V in path_huds_watching_me) + var/datum/atom_hud/H = V + H.add_to_hud(src) + + +/mob/living/simple_animal/bot/proc/increment_path() + if(!path || !path.len) + return + var/image/I = path[path[1]] + if(I) + I.icon = null + path.Cut(1, 2) diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm index 4eb225360a..efe289b222 100644 --- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm +++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm @@ -16,6 +16,7 @@ window_id = "autoclean" window_name = "Automatic Station Cleaner v1.2" pass_flags = PASSMOB + path_image_color = "#993299" var/blood = 1 var/trash = 0 diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm index 62fb2e772c..463082adda 100644 --- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm +++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm @@ -21,6 +21,7 @@ window_name = "Automatic Security Unit v2.6" allow_pai = 0 data_hud_type = DATA_HUD_SECURITY_ADVANCED + path_image_color = "#FF0000" var/lastfired = 0 var/shot_delay = 15 diff --git a/code/modules/mob/living/simple_animal/bot/floorbot.dm b/code/modules/mob/living/simple_animal/bot/floorbot.dm index 28a64838f7..707d77e2ac 100644 --- a/code/modules/mob/living/simple_animal/bot/floorbot.dm +++ b/code/modules/mob/living/simple_animal/bot/floorbot.dm @@ -17,6 +17,7 @@ bot_core = /obj/machinery/bot_core/floorbot window_id = "autofloor" window_name = "Automatic Station Floor Repairer v1.1" + path_image_color = "#FFA500" var/process_type //Determines what to do when process_scan() recieves a target. See process_scan() for details. var/targetdirection diff --git a/code/modules/mob/living/simple_animal/bot/honkbot.dm b/code/modules/mob/living/simple_animal/bot/honkbot.dm index 3e15adbfe0..1052542f5a 100644 --- a/code/modules/mob/living/simple_animal/bot/honkbot.dm +++ b/code/modules/mob/living/simple_animal/bot/honkbot.dm @@ -18,6 +18,7 @@ window_id = "autohonk" window_name = "Honkomatic Bike Horn Unit v1.0.7" data_hud_type = DATA_HUD_SECURITY_BASIC // show jobs + path_image_color = "#FF69B4" var/honksound = 'sound/items/bikehorn.ogg' //customizable sound var/spam_flag = FALSE diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm index 57cad4570f..03dbc240ec 100644 --- a/code/modules/mob/living/simple_animal/bot/medbot.dm +++ b/code/modules/mob/living/simple_animal/bot/medbot.dm @@ -25,6 +25,7 @@ window_id = "automed" window_name = "Automatic Medical Unit v1.1" data_hud_type = DATA_HUD_MEDICAL_ADVANCED + path_image_color = "#DDDDFF" var/obj/item/reagent_containers/glass/reagent_glass = null //Can be set to draw from this for reagents. var/skin = null //Set to "tox", "ointment" or "o2" for the other two firstaid kits. @@ -342,7 +343,7 @@ //Time to see if they need medical help! if(C.stat == DEAD || (C.status_flags & FAKEDEATH)) return FALSE //welp too late for them! - + if(!(loc == C.loc) && !(isturf(C.loc) && isturf(loc))) return FALSE diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index 170659ef29..98d4557037 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -29,7 +29,9 @@ model = "MULE" bot_core_type = /obj/machinery/bot_core/mulebot - suffix = "" + var/id + + path_image_color = "#7F5200" var/atom/movable/load = null var/mob/living/passenger = null @@ -52,14 +54,12 @@ var/datum/job/cargo_tech/J = new/datum/job/cargo_tech access_card.access = J.get_access() prev_access = access_card.access - cell = new(src) - cell.charge = 2000 - cell.maxcharge = 2000 + cell = new /obj/item/stock_parts/cell/upgraded(src, 2000) var/static/mulebot_count = 0 mulebot_count += 1 - if(!suffix) - set_suffix("#[mulebot_count]") + set_id(suffix || id || "#[mulebot_count]") + suffix = null /mob/living/simple_animal/bot/mulebot/Destroy() unload(0) @@ -67,12 +67,12 @@ wires = null return ..() -/mob/living/simple_animal/bot/mulebot/proc/set_suffix(suffix) - src.suffix = suffix +/mob/living/simple_animal/bot/mulebot/proc/set_id(new_id) + id = new_id if(paicard) - bot_name = "\improper MULEbot ([suffix])" + bot_name = "\improper MULEbot ([new_id])" else - name = "\improper MULEbot ([suffix])" + name = "\improper MULEbot ([new_id])" /mob/living/simple_animal/bot/mulebot/bot_reset() ..() @@ -91,7 +91,7 @@ "You insert the new cell into [src].") else if(istype(I, /obj/item/crowbar) && open && cell) cell.add_fingerprint(usr) - cell.loc = loc + cell.forceMove(loc) cell = null visible_message("[user] crowbars out the power cell from [src].", "You pry the powercell out of [src].") @@ -231,9 +231,9 @@ if(new_dest) set_destination(new_dest) if("setid") - var/new_id = stripped_input(user, "Enter ID:", name, suffix, MAX_NAME_LEN) + var/new_id = stripped_input(user, "Enter ID:", name, id, MAX_NAME_LEN) if(new_id) - set_suffix(new_id) + set_id(new_id) if("sethome") var/new_home = input(user, "Enter Home:", name, home_destination) as null|anything in GLOB.deliverybeacontags if(new_home) @@ -258,7 +258,7 @@ var/ai = issilicon(user) var/dat dat += "

    Multiple Utility Load Effector Mk. V

    " - dat += "ID: [suffix]
    " + dat += "ID: [id]
    " dat += "Power: [on ? "On" : "Off"]
    " dat += "

    Status

    " dat += "
    " + return l + +/obj/machinery/rnd/circuit_imprinter/department/proc/ui_department_imprinter() + var/list/l = list() + var/coeff = efficiency_coeff + l += "
    \ + \ + \ + \ + \ +

    " + for(var/datum/design/D in cached_designs) + var/temp_materials + var/check_materials = TRUE + var/all_materials = D.materials + D.reagents_list + for(var/M in all_materials) + temp_materials += " | " + if (!check_mat(D, M)) + check_materials = FALSE + temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]" + else + temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]" + if (check_materials) + l += "[D.name][temp_materials]" + else + l += "[D.name][temp_materials]" + l += "
    " @@ -361,7 +361,7 @@ if(!load_mob(AM)) return else - AM.loc = src + AM.forceMove(src) load = AM mode = BOT_IDLE @@ -377,12 +377,11 @@ return FALSE /mob/living/simple_animal/bot/mulebot/post_buckle_mob(mob/living/M) - if(M in buckled_mobs) //post buckling - M.pixel_y = initial(M.pixel_y) + 9 - if(M.layer < layer) - M.layer = layer + 0.01 + M.pixel_y = initial(M.pixel_y) + 9 + if(M.layer < layer) + M.layer = layer + 0.01 - else //post unbuckling +/mob/living/simple_animal/bot/mulebot/post_unbuckle_mob(mob/living/M) load = null M.layer = initial(M.layer) M.pixel_y = initial(M.pixel_y) @@ -401,7 +400,7 @@ unbuckle_all_mobs() if(load) - load.loc = loc + load.forceMove(loc) load.pixel_y = initial(load.pixel_y) load.layer = initial(load.layer) load.plane = initial(load.plane) diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm index 82eae37f82..b8b2621875 100644 --- a/code/modules/mob/living/simple_animal/bot/secbot.dm +++ b/code/modules/mob/living/simple_animal/bot/secbot.dm @@ -20,6 +20,7 @@ window_name = "Automatic Security Unit v1.6" allow_pai = 0 data_hud_type = DATA_HUD_SECURITY_ADVANCED + path_image_color = "#FF0000" var/mob/living/carbon/target var/oldtarget_name diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index 0e6ecf1672..8046daf55d 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -360,8 +360,14 @@ ..() /datum/action/innate/seek_master/Activate() - if(!SSticker.mode.eldergod) - the_construct.master = GLOB.blood_target + var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult) + if(!C) + return + var/datum/objective/eldergod/summon_objective = locate() in C.cult_team.objectives + + if(summon_objective.check_completion()) + the_construct.master = C.cult_team.blood_target + if(!the_construct.master) to_chat(the_construct, "You have no master to seek!") the_construct.seeking = FALSE diff --git a/code/modules/mob/living/simple_animal/damage_procs.dm b/code/modules/mob/living/simple_animal/damage_procs.dm index 5405ee03c6..bb6794a36a 100644 --- a/code/modules/mob/living/simple_animal/damage_procs.dm +++ b/code/modules/mob/living/simple_animal/damage_procs.dm @@ -2,7 +2,7 @@ /mob/living/simple_animal/proc/adjustHealth(amount, updating_health = TRUE, forced = FALSE) if(!forced && (status_flags & GODMODE)) return FALSE - bruteloss = Clamp(bruteloss + amount, 0, maxHealth) + bruteloss = CLAMP(bruteloss + amount, 0, maxHealth) if(updating_health) updatehealth() return amount diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index a333f22c38..42d38e40a3 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -9,8 +9,8 @@ gender = MALE speak = list("Meow!", "Esp!", "Purr!", "HSSSSS") speak_emote = list("purrs", "meows") - emote_hear = list("meows", "mews") - emote_see = list("shakes its head", "shivers") + emote_hear = list("meows.", "mews.") + emote_see = list("shakes its head.", "shivers.") speak_chance = 1 turns_per_move = 5 see_in_dark = 6 @@ -22,7 +22,7 @@ unsuitable_atmos_damage = 1 animal_species = /mob/living/simple_animal/pet/cat childtype = list(/mob/living/simple_animal/pet/cat/kitten) - butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2) + butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2, /obj/item/organ/ears/cat = 1, /obj/item/organ/tail/cat = 1) response_help = "pets" response_disarm = "gently pushes aside" response_harm = "kicks" diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index 6ea4d2ef94..adc88c5633 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -135,7 +135,7 @@ switch(remove_from) if("head") if(inventory_head) - inventory_head.loc = src.loc + inventory_head.forceMove(drop_location()) inventory_head = null update_corgi_fluff() regenerate_icons() @@ -144,7 +144,7 @@ return if("back") if(inventory_back) - inventory_back.loc = src.loc + inventory_back.forceMove(drop_location()) inventory_back = null update_corgi_fluff() regenerate_icons() diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm index f7ee4ac29a..ea159a5749 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm @@ -48,6 +48,7 @@ faction = list("neutral","silicon","turret") dextrous = TRUE dextrous_hud_type = /datum/hud/dextrous/drone + lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE var/staticChoice = "static" var/list/staticChoices = list("static", "blank", "letter", "animal") var/picked = FALSE //Have we picked our visual appearence (+ colour if applicable) @@ -57,7 +58,6 @@ "1. You may not involve yourself in the matters of another being, even if such matters conflict with Law Two or Law Three, unless the other being is another Drone.\n"+\ "2. You may not harm any being, regardless of intent or circumstance.\n"+\ "3. Your goals are to build, maintain, repair, improve, and provide power to the best of your abilities, You must never actively work against these goals." - var/light_on = 0 var/heavy_emp_damage = 25 //Amount of damage sustained if hit by a heavy EMP pulse var/alarms = list("Atmosphere" = list(), "Fire" = list(), "Power" = list()) var/obj/item/internal_storage //Drones can store one item, of any size/type in their body @@ -102,8 +102,8 @@ else verbs -= /mob/living/simple_animal/drone/verb/toggle_statics - var/datum/atom_hud/data/diagnostic/diag_hud = GLOB.huds[DATA_HUD_DIAGNOSTIC] - diag_hud.add_to_hud(src) + for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds) + diag_hud.add_to_hud(src) /mob/living/simple_animal/drone/med_hud_set_health() 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 9900133723..c0a57e3739 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 @@ -13,7 +13,6 @@ desc = "A shell of a maintenance drone, an expendable robot built to perform station repairs." icon = 'icons/mob/drone.dmi' icon_state = "drone_maint_hat"//yes reuse the _hat state. - origin_tech = "programming=2;biotech=4" var/drone_type = /mob/living/simple_animal/drone //Type of drone that will be spawned /obj/item/drone_shell/New() @@ -68,7 +67,7 @@ L.dropItemToGround(src) contents -= drone - drone.loc = get_turf(src) + drone.forceMove(drop_location()) drone.reset_perspective() drone.setDir(SOUTH )//Looks better drone.visible_message("[drone] uncurls!") 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 a19a6abeb3..1105940f22 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 @@ -34,7 +34,8 @@ /mob/living/simple_animal/drone/syndrone/Initialize() . = ..() - internal_storage.hidden_uplink.telecrystals = 10 + GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, internal_storage) + hidden_uplink.telecrystals = 10 /mob/living/simple_animal/drone/syndrone/Login() ..() @@ -47,7 +48,8 @@ /mob/living/simple_animal/drone/syndrone/badass/Initialize() . = ..() - internal_storage.hidden_uplink.telecrystals = 30 + GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, internal_storage) + hidden_uplink.telecrystals = 30 var/obj/item/implant/weapons_auth/W = new/obj/item/implant/weapons_auth(src) W.implant(src) @@ -146,12 +148,11 @@ qdel(access_card) //we don't have free access access_card = null verbs -= /mob/living/simple_animal/drone/verb/check_laws - verbs -= /mob/living/simple_animal/drone/verb/toggle_light verbs -= /mob/living/simple_animal/drone/verb/drone_ping /mob/living/simple_animal/drone/cogscarab/Login() ..() - add_servant_of_ratvar(src, TRUE) + add_servant_of_ratvar(src, TRUE, GLOB.servants_active) to_chat(src,"You yourself are one of these servants, and will be able to utilize almost anything they can[GLOB.ratvar_awakens ? "":", excluding a clockwork slab"].") // this can't go with flavortext because i'm assuming it requires them to be ratvar'd /mob/living/simple_animal/drone/cogscarab/binarycheck() diff --git a/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm b/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm index 378a5cce2d..aac87829bc 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm @@ -58,7 +58,7 @@ I.pulledby.stop_pulling() I.screen_loc = null // will get moved if inventory is visible - I.loc = src + I.forceMove(src) I.layer = ABOVE_HUD_LAYER I.plane = ABOVE_HUD_PLANE diff --git a/code/modules/mob/living/simple_animal/friendly/drone/say.dm b/code/modules/mob/living/simple_animal/friendly/drone/say.dm index fb0c0c0614..16bf370f02 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/say.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/say.dm @@ -3,14 +3,6 @@ ///////////// //Drone speach -/mob/living/simple_animal/drone/handle_inherent_channels(message, message_mode) - if(message_mode == MODE_BINARY) - drone_chat(message) - return 1 - else - ..() - - /mob/living/simple_animal/drone/get_spans() return ..() | SPAN_ROBOT diff --git a/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm b/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm index 49faea14b3..86bc3b69e5 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm @@ -11,23 +11,7 @@ to_chat(src, "Drone Laws") to_chat(src, laws) - -/mob/living/simple_animal/drone/verb/toggle_light() - set category = "Drone" - set name = "Toggle drone light" - if(stat == DEAD) - to_chat(src, "There's no light in your life... by that I mean you're dead.") - return - if(light_on) - set_light(0) - else - set_light(8) - - light_on = !light_on - - to_chat(src, "Your light is now [light_on ? "on" : "off"].") - /mob/living/simple_animal/drone/verb/drone_ping() set category = "Drone" set name = "Drone ping" diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index 85ec19bfb9..809681ed6b 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -110,3 +110,7 @@ eatverb = "devours" list_reagents = list("nutriment" = 3, "vitamin" = 2) foodtype = GROSS | MEAT | RAW + grind_results = list("blood" = 20, "liquidgibs" = 5) + +/obj/item/reagent_containers/food/snacks/deadmouse/on_grind() + reagents.clear_reagents() diff --git a/code/modules/mob/living/simple_animal/friendly/sloth.dm b/code/modules/mob/living/simple_animal/friendly/sloth.dm index 7519951876..6f19632e88 100644 --- a/code/modules/mob/living/simple_animal/friendly/sloth.dm +++ b/code/modules/mob/living/simple_animal/friendly/sloth.dm @@ -19,10 +19,10 @@ melee_damage_upper = 18 health = 50 maxHealth = 50 - speed = 2 + speed = 10 + glide_size = 2 devourable = TRUE - //Cargo Sloth /mob/living/simple_animal/sloth/paperwork name = "Paperwork" @@ -39,4 +39,4 @@ icon_dead = "cool_sloth_dead" gender = FEMALE butcher_results = list(/obj/item/toy/spinningtoy = 1) - gold_core_spawnable = NO_SPAWN \ No newline at end of file + gold_core_spawnable = NO_SPAWN diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm index 222369dd55..577eba1858 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardian.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm @@ -257,7 +257,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians I.pulledby.stop_pulling() I.screen_loc = null // will get moved if inventory is visible - I.loc = src + I.forceMove(src) I.equipped(src, slot) I.layer = ABOVE_HUD_LAYER I.plane = ABOVE_HUD_PLANE diff --git a/code/modules/mob/living/simple_animal/guardian/types/explosive.dm b/code/modules/mob/living/simple_animal/guardian/types/explosive.dm index 1353293484..54ef51ad5a 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/explosive.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/explosive.dm @@ -54,7 +54,7 @@ /obj/guardian_bomb/proc/disguise(obj/A) - A.loc = src + A.forceMove(src) stored_obj = A opacity = A.opacity anchored = A.anchored diff --git a/code/modules/mob/living/simple_animal/hostile/creature.dm b/code/modules/mob/living/simple_animal/hostile/creature.dm index 12da922fc0..bba37f94af 100644 --- a/code/modules/mob/living/simple_animal/hostile/creature.dm +++ b/code/modules/mob/living/simple_animal/hostile/creature.dm @@ -1,18 +1,18 @@ -/mob/living/simple_animal/hostile/creature - name = "creature" - desc = "A sanity-destroying otherthing." - icon_state = "otherthing" - icon_living = "otherthing" - icon_dead = "otherthing-dead" - health = 80 - maxHealth = 80 - obj_damage = 100 - melee_damage_lower = 25 - melee_damage_upper = 50 - attacktext = "chomps" - attack_sound = 'sound/weapons/bite.ogg' - faction = list("creature") - speak_emote = list("screams") - gold_core_spawnable = HOSTILE_SPAWN - atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) - minbodytemp = 0 +/mob/living/simple_animal/hostile/creature + name = "creature" + desc = "A sanity-destroying otherthing." + icon_state = "otherthing" + icon_living = "otherthing" + icon_dead = "otherthing-dead" + health = 80 + maxHealth = 80 + obj_damage = 100 + melee_damage_lower = 25 + melee_damage_upper = 50 + attacktext = "chomps" + attack_sound = 'sound/weapons/bite.ogg' + faction = list("creature") + speak_emote = list("screams") + gold_core_spawnable = HOSTILE_SPAWN + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) + minbodytemp = 0 diff --git a/code/modules/mob/living/simple_animal/hostile/headcrab.dm b/code/modules/mob/living/simple_animal/hostile/headcrab.dm index 4e302b3d55..a42a79e02a 100644 --- a/code/modules/mob/living/simple_animal/hostile/headcrab.dm +++ b/code/modules/mob/living/simple_animal/hostile/headcrab.dm @@ -32,7 +32,7 @@ else if(mind) // Let's make this a feature egg.origin = mind for(var/obj/item/organ/I in src) - I.loc = egg + I.forceMove(egg) visible_message("[src] plants something in [victim]'s flesh!", \ "We inject our egg into [victim]'s body!") egg_lain = 1 @@ -53,7 +53,6 @@ /obj/item/organ/body_egg/changeling_egg name = "changeling egg" desc = "Twitching and disgusting." - origin_tech = "biotech=7" // You need to be really lucky to obtain it. var/datum/mind/origin var/time diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm index a977338008..c6f0f6a91c 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm @@ -79,10 +79,10 @@ Difficulty: Hard /mob/living/simple_animal/hostile/megafauna/bubblegum/Life() ..() - move_to_delay = Clamp((health/maxHealth) * 10, 5, 10) + move_to_delay = CLAMP((health/maxHealth) * 10, 5, 10) /mob/living/simple_animal/hostile/megafauna/bubblegum/OpenFire() - anger_modifier = Clamp(((maxHealth - health)/60),0,20) + anger_modifier = CLAMP(((maxHealth - health)/60),0,20) if(charging) return ranged_cooldown = world.time + ranged_cooldown_time diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index 58e3e0837b..d47385efc3 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -57,7 +57,7 @@ Difficulty: Very Hard L.dust() /mob/living/simple_animal/hostile/megafauna/colossus/OpenFire() - anger_modifier = Clamp(((maxHealth - health)/50),0,20) + anger_modifier = CLAMP(((maxHealth - health)/50),0,20) ranged_cooldown = world.time + 120 if(enrage(target)) 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 7f12e684e8..724e4fc5c7 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm @@ -101,7 +101,7 @@ Difficulty: Medium /mob/living/simple_animal/hostile/megafauna/dragon/OpenFire() if(swooping) return - anger_modifier = Clamp(((maxHealth - health)/50),0,20) + anger_modifier = CLAMP(((maxHealth - health)/50),0,20) ranged_cooldown = world.time + ranged_cooldown_time if(prob(15 + anger_modifier) && !client) @@ -227,10 +227,10 @@ Difficulty: Medium //ensure swoop direction continuity. if(negative) - if(IsInRange(x, initial_x + 1, initial_x + DRAKE_SWOOP_DIRECTION_CHANGE_RANGE)) + if(ISINRANGE(x, initial_x + 1, initial_x + DRAKE_SWOOP_DIRECTION_CHANGE_RANGE)) negative = FALSE else - if(IsInRange(x, initial_x - DRAKE_SWOOP_DIRECTION_CHANGE_RANGE, initial_x - 1)) + if(ISINRANGE(x, initial_x - DRAKE_SWOOP_DIRECTION_CHANGE_RANGE, initial_x - 1)) negative = TRUE new /obj/effect/temp_visual/dragon_flight/end(loc, negative) new /obj/effect/temp_visual/dragon_swoop(loc) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm index 02fb81a1ed..8dc1780e5e 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm @@ -187,7 +187,7 @@ Difficulty: Hard /mob/living/simple_animal/hostile/megafauna/hierophant/proc/calculate_rage() //how angry we are overall did_reset = FALSE //oh hey we're doing SOMETHING, clearly we might need to heal if we recall - anger_modifier = Clamp(((maxHealth - health) / 42),0,50) + anger_modifier = CLAMP(((maxHealth - health) / 42),0,50) burst_range = initial(burst_range) + round(anger_modifier * 0.08) beam_range = initial(beam_range) + round(anger_modifier * 0.12) diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm index dd96c87371..670d571d4d 100644 --- a/code/modules/mob/living/simple_animal/hostile/mimic.dm +++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm @@ -43,7 +43,7 @@ . = ..() if(mapload) //eat shit for(var/obj/item/I in loc) - I.loc = src + I.forceMove(src) /mob/living/simple_animal/hostile/mimic/crate/DestroyPathToTarget() ..() @@ -89,7 +89,7 @@ var/obj/structure/closet/crate/C = new(get_turf(src)) // Put loot in crate for(var/obj/O in src) - O.loc = C + O.forceMove(C) ..() GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/cable, /obj/structure/window)) @@ -116,7 +116,7 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca /mob/living/simple_animal/hostile/mimic/copy/death() for(var/atom/movable/M in src) - M.loc = get_turf(src) + M.forceMove(get_turf(src)) ..() /mob/living/simple_animal/hostile/mimic/copy/ListTargets() @@ -136,7 +136,7 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca /mob/living/simple_animal/hostile/mimic/copy/proc/CopyObject(obj/O, mob/living/user, destroy_original = 0) if(destroy_original || CheckObject(O)) - O.loc = src + O.forceMove(src) name = O.name desc = O.desc icon = O.icon @@ -249,15 +249,15 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca ..() else visible_message("The [src] clears a jam!") - Pewgun.chambered.loc = loc //rip revolver immersions, blame shotgun snowflake procs + Pewgun.chambered.forceMove(loc) //rip revolver immersions, blame shotgun snowflake procs Pewgun.chambered = null if(Pewgun.magazine && Pewgun.magazine.stored_ammo.len) Pewgun.chambered = Pewgun.magazine.get_round(0) - Pewgun.chambered.loc = Pewgun + Pewgun.chambered.forceMove(Pewgun) Pewgun.update_icon() else if(Pewgun.magazine && Pewgun.magazine.stored_ammo.len) //only true for pumpguns i think Pewgun.chambered = Pewgun.magazine.get_round(0) - Pewgun.chambered.loc = Pewgun + Pewgun.chambered.forceMove(Pewgun) visible_message("The [src] cocks itself!") else ranged = 0 //BANZAIIII diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm index a9627c7e2d..7a3a85c35b 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm @@ -137,8 +137,9 @@ . = ..() if(.) var/mob/living/L = target - L.adjust_fire_stacks(0.1) - L.IgniteMob() + if (istype(L)) + L.adjust_fire_stacks(0.1) + L.IgniteMob() /obj/item/projectile/temp/basilisk/icewing damage = 5 diff --git a/code/modules/mob/living/simple_animal/hostile/netherworld.dm b/code/modules/mob/living/simple_animal/hostile/netherworld.dm new file mode 100644 index 0000000000..67a565f945 --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/netherworld.dm @@ -0,0 +1,103 @@ +/mob/living/simple_animal/hostile/netherworld + name = "creature" + desc = "A sanity-destroying otherthing from the netherworld." + icon_state = "otherthing" + icon_living = "otherthing" + icon_dead = "otherthing-dead" + health = 80 + maxHealth = 80 + obj_damage = 100 + melee_damage_lower = 25 + melee_damage_upper = 50 + attacktext = "slashes" + attack_sound = 'sound/weapons/bladeslice.ogg' + faction = list("creature") + speak_emote = list("screams") + gold_core_spawnable = HOSTILE_SPAWN + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) + minbodytemp = 0 + faction = list("nether") + +/mob/living/simple_animal/hostile/netherworld/migo + name = "mi-go" + desc = "A pinkish, fungoid crustacean-like creature with numerous pairs of clawed appendages and a head covered with waving antennae." + speak_emote = list("screams", "clicks", "chitters", "barks", "moans", "growls", "meows", "reverberates", "roars", "squeaks", "rattles", "exclaims", "yells", "remarks", "mumbles", "jabbers", "stutters", "seethes") + icon_state = "mi-go" + icon_living = "mi-go" + icon_dead = "mi-go-dead" + attacktext = "lacerates" + speed = -0.5 + var/static/list/migo_sounds + deathmessage = "wails as its form turns into a pulpy mush." + death_sound = 'sound/voice/hiss6.ogg' + +/mob/living/simple_animal/hostile/netherworld/migo/Initialize() + . = ..() + migo_sounds = list('sound/items/bubblewrap.ogg', 'sound/items/change_jaws.ogg', 'sound/items/crowbar.ogg', 'sound/items/drink.ogg', 'sound/items/deconstruct.ogg', 'sound/items/carhorn.ogg', 'sound/items/change_drill.ogg', 'sound/items/dodgeball.ogg', 'sound/items/eatfood.ogg', 'sound/items/megaphone.ogg', 'sound/items/screwdriver.ogg', 'sound/items/weeoo1.ogg', 'sound/items/wirecutter.ogg', 'sound/items/welder.ogg', 'sound/items/zip.ogg', 'sound/items/rped.ogg', 'sound/items/ratchet.ogg', 'sound/items/polaroid1.ogg', 'sound/items/pshoom.ogg', 'sound/items/airhorn.ogg', 'sound/items/geiger/high1.ogg', 'sound/items/geiger/high2.ogg', 'sound/voice/bcreep.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/ed209_20sec.ogg', 'sound/voice/hiss3.ogg', 'sound/voice/hiss6.ogg', 'sound/voice/mpatchedup.ogg', 'sound/voice/mfeelbetter.ogg', 'sound/voice/human/manlaugh1.ogg', 'sound/voice/human/womanlaugh.ogg', 'sound/weapons/sear.ogg', 'sound/ambience/antag/clockcultalr.ogg', 'sound/ambience/antag/ling_aler.ogg', 'sound/ambience/antag/tatoralert.ogg', 'sound/ambience/antag/monkey.ogg', 'sound/mecha/nominal.ogg', 'sound/mecha/weapdestr.ogg', 'sound/mecha/critdestr.ogg', 'sound/mecha/imag_enh.ogg', 'sound/effects/adminhelp.ogg', 'sound/effects/alert.ogg', 'sound/effects/attackblob.ogg', 'sound/effects/bamf.ogg', 'sound/effects/blobattack.ogg', 'sound/effects/break_stone.ogg', 'sound/effects/bubbles.ogg', 'sound/effects/bubbles2.ogg', 'sound/effects/clang.ogg', 'sound/effects/clockcult_gateway_disrupted.ogg', 'sound/effects/clownstep2.ogg', 'sound/effects/curse1.ogg', 'sound/effects/dimensional_rend.ogg', 'sound/effects/doorcreaky.ogg', 'sound/effects/empulse.ogg', 'sound/effects/explosion_distant.ogg', 'sound/effects/explosionfar.ogg', 'sound/effects/explosion1.ogg', 'sound/effects/grillehit.ogg', 'sound/effects/genetics.ogg', 'sound/effects/heart_beat.ogg', 'sound/effects/hyperspace_begin.ogg', 'sound/effects/hyperspace_end.ogg', 'sound/effects/his_grace_awaken.ogg', 'sound/effects/pai_boot.ogg', 'sound/effects/phasein.ogg', 'sound/effects/picaxe1.ogg', 'sound/effects/ratvar_reveal.ogg', 'sound/effects/sparks1.ogg', 'sound/effects/smoke.ogg', 'sound/effects/splat.ogg', 'sound/effects/snap.ogg', 'sound/effects/tendril_destroyed.ogg', 'sound/effects/supermatter.ogg', 'sound/misc/desceration-01.ogg', 'sound/misc/desceration-02.ogg', 'sound/misc/desceration-03.ogg', 'sound/misc/bloblarm.ogg', 'sound/misc/airraid.ogg', 'sound/misc/bang.ogg', 'sound/misc/disco.ogg', 'sound/misc/highlander.ogg', 'sound/misc/interference.ogg', 'sound/misc/notice1.ogg', 'sound/misc/notice2.ogg', 'sound/misc/sadtrombone.ogg', 'sound/misc/slip.ogg', 'sound/misc/splort.ogg', 'sound/weapons/armbomb.ogg', 'sound/weapons/beam_sniper.ogg', 'sound/weapons/chainsawhit.ogg', 'sound/weapons/emitter.ogg', 'sound/weapons/emitter2.ogg', 'sound/weapons/blade1.ogg', 'sound/weapons/bladeslice.ogg', 'sound/weapons/blastcannon.ogg', 'sound/weapons/blaster.ogg', 'sound/weapons/bulletflyby3.ogg', 'sound/weapons/circsawhit.ogg', 'sound/weapons/cqchit2.ogg', 'sound/weapons/drill.ogg', 'sound/weapons/genhit1.ogg', 'sound/weapons/gunshot_silenced.ogg', 'sound/weapons/gunshot2.ogg', 'sound/weapons/handcuffs.ogg', 'sound/weapons/homerun.ogg', 'sound/weapons/kenetic_accel.ogg', 'sound/machines/clockcult/steam_whoosh.ogg', 'sound/machines/fryer/deep_fryer_emerge.ogg', 'sound/machines/airlock.ogg', 'sound/machines/airlock_alien_prying.ogg', 'sound/machines/airlockclose.ogg', 'sound/machines/airlockforced.ogg', 'sound/machines/airlockopen.ogg', 'sound/machines/alarm.ogg', 'sound/machines/blender.ogg', 'sound/machines/boltsdown.ogg', 'sound/machines/boltsup.ogg', 'sound/machines/buzz-sigh.ogg', 'sound/machines/buzz-two.ogg', 'sound/machines/chime.ogg', 'sound/machines/cryo_warning.ogg', 'sound/machines/defib_charge.ogg', 'sound/machines/defib_failed.ogg', 'sound/machines/defib_ready.ogg', 'sound/machines/defib_zap.ogg', 'sound/machines/deniedbeep.ogg', 'sound/machines/ding.ogg', 'sound/machines/disposalflush.ogg', 'sound/machines/door_close.ogg', 'sound/machines/door_open.ogg', 'sound/machines/engine_alert1.ogg', 'sound/machines/engine_alert2.ogg', 'sound/machines/hiss.ogg', 'sound/machines/honkbot_evil_laugh.ogg', 'sound/machines/juicer.ogg', 'sound/machines/ping.ogg', 'sound/machines/signal.ogg', 'sound/machines/synth_no.ogg', 'sound/machines/synth_yes.ogg', 'sound/machines/terminal_alert.ogg', 'sound/machines/triple_beep.ogg', 'sound/machines/twobeep.ogg', 'sound/machines/ventcrawl.ogg', 'sound/machines/warning-buzzer.ogg', 'sound/ai/outbreak5.ogg', 'sound/ai/outbreak7.ogg', 'sound/ai/poweroff.ogg', 'sound/ai/radiation.ogg', 'sound/ai/shuttlecalled.ogg', 'sound/ai/shuttledock.ogg', 'sound/ai/shuttlerecalled.ogg', 'sound/ai/aimalf.ogg') //hahahaha fuck you code divers + +/mob/living/simple_animal/hostile/netherworld/migo/say(message) + ..() + if(stat) + return + var/chosen_sound = pick(migo_sounds) + playsound(src, chosen_sound, 100, TRUE) + +/mob/living/simple_animal/hostile/netherworld/migo/Life() + ..() + if(stat) + return + if(prob(10)) + var/chosen_sound = pick(migo_sounds) + playsound(src, chosen_sound, 100, TRUE) + +/mob/living/simple_animal/hostile/netherworld/blankbody + name = "blank body" + desc = "This looks human enough, but its flesh has an ashy texture, and it's face is featureless save an eerie smile." + icon_state = "blank-body" + icon_living = "blank-body" + icon_dead = "blank-dead" + gold_core_spawnable = NO_SPAWN + health = 100 + maxHealth = 100 + melee_damage_lower = 5 + melee_damage_upper = 10 + attacktext = "punches" + deathmessage = "falls apart into a fine dust." + +/mob/living/simple_animal/hostile/spawner/nether + name = "netherworld link" + desc = "A direct link to another dimension full of creatures not very happy to see you. Entering the link would be a very bad idea." + icon_state = "nether" + icon_living = "nether" + health = 50 + maxHealth = 50 + spawn_time = 50 //5 seconds + max_mobs = 15 + icon = 'icons/mob/nest.dmi' + spawn_text = "crawls through" + mob_type = /mob/living/simple_animal/hostile/netherworld/migo + 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) + faction = list("nether") + deathmessage = "shatters into oblivion." + del_on_death = TRUE + +/mob/living/simple_animal/hostile/spawner/nether/attack_hand(mob/user) + user.visible_message("[user] is violently pulled into the link!", \ + "Touching the portal, you are quickly pulled through into a world of unimaginable horror!") + contents.Add(user) + +/mob/living/simple_animal/hostile/spawner/nether/Life() + ..() + var/list/C = src.get_contents() + for(var/mob/living/M in C) + if(M) + playsound(src, 'sound/magic/demon_consume.ogg', 50, 1) + M.adjustBruteLoss(60) + new /obj/effect/gibspawner/human(get_turf(M)) + if(M.stat == DEAD) + var/mob/living/simple_animal/hostile/netherworld/blankbody/blank + blank = new(loc) + blank.name = "[M]" + blank.desc = "It's [M], but their flesh has an ashy texture, and their face is featureless save an eerie smile." + src.visible_message("[M] reemerges from the link!") + qdel(M) diff --git a/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm b/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm index 97dd430a12..5737f5f4b2 100644 --- a/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm +++ b/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm @@ -2,10 +2,10 @@ /mob/living/simple_animal/hostile/asteroid/fugu name = "wumborian fugu" desc = "The wumborian fugu rapidly increases its body mass in order to ward off its prey. Great care should be taken to avoid it while it's in this state as it is nearly invincible, but it cannot maintain its form forever." - icon = 'icons/mob/lavaland/lavaland_monsters.dmi' - icon_state = "Fugu" - icon_living = "Fugu" - icon_aggro = "Fugu" + icon = 'icons/mob/lavaland/64x64megafauna.dmi' + icon_state = "Fugu0" + icon_living = "Fugu0" + icon_aggro = "Fugu0" icon_dead = "Fugu_dead" icon_gib = "syndicate_gib" mouse_opacity = MOUSE_OPACITY_OPAQUE @@ -16,6 +16,7 @@ speed = 0 maxHealth = 50 health = 50 + pixel_x = -16 harm_intent_damage = 5 obj_damage = 0 melee_damage_lower = 0 @@ -30,13 +31,23 @@ gold_core_spawnable = HOSTILE_SPAWN var/wumbo = 0 var/inflate_cooldown = 0 + var/datum/action/innate/fugu/expand/E loot = list(/obj/item/asteroid/fugu_gland{layer = ABOVE_MOB_LAYER}) +/mob/living/simple_animal/hostile/asteroid/fugu/Initialize() + . = ..() + E = new + E.Grant(src) + +/mob/living/simple_animal/hostile/asteroid/fugu/Destroy() + QDEL_NULL(E) + return ..() + /mob/living/simple_animal/hostile/asteroid/fugu/Life() if(!wumbo) inflate_cooldown = max((inflate_cooldown - 1), 0) if(target && AIStatus == AI_ON) - Inflate() + E.Activate() ..() /mob/living/simple_animal/hostile/asteroid/fugu/adjustHealth(amount, updating_health = TRUE, forced = FALSE) @@ -46,42 +57,47 @@ /mob/living/simple_animal/hostile/asteroid/fugu/Aggro() ..() - Inflate() + E.Activate() -/mob/living/simple_animal/hostile/asteroid/fugu/verb/Inflate() - set name = "Inflate" - set category = "Fugu" - set desc = "Temporarily increases your size, and makes you significantly more dangerous and tough." - if(wumbo) - to_chat(src, "You're already inflated.") +/datum/action/innate/fugu + icon_icon = 'icons/mob/actions/actions_animal.dmi' + +/datum/action/innate/fugu/expand + name = "Inflate" + desc = "Temporarily increases your size, and makes you significantly more dangerous and tough! Do not bully the fugu!" + button_icon_state = "expand" + +/datum/action/innate/fugu/expand/Activate() + var/mob/living/simple_animal/hostile/asteroid/fugu/F = owner + if(F.wumbo) + to_chat(F, "YOU'RE ALREADY WUMBO!") return - if(inflate_cooldown) - to_chat(src, "We need time to gather our strength.") + if(F.inflate_cooldown) + to_chat(F, "You need time to gather your strength.") return - if(buffed) - to_chat(src, "Something is interfering with our growth.") + if(F.buffed) + to_chat(F, "Something is interfering with your growth.") return - wumbo = 1 - icon_state = "Fugu_big" - obj_damage = 60 - melee_damage_lower = 15 - melee_damage_upper = 20 - harm_intent_damage = 0 - throw_message = "is absorbed by the girth of the" - retreat_distance = null - minimum_distance = 1 - move_to_delay = 6 - transform *= 2 - environment_smash = ENVIRONMENT_SMASH_WALLS - mob_size = MOB_SIZE_LARGE - speed = 1 - addtimer(CALLBACK(src, .proc/Deflate), 100) + F.wumbo = 1 + F.icon_state = "Fugu1" + F.obj_damage = 60 + F.melee_damage_lower = 15 + F.melee_damage_upper = 20 + F.harm_intent_damage = 0 + F.throw_message = "is absorbed by the girth of the" + F.retreat_distance = null + F.minimum_distance = 1 + F.move_to_delay = 6 + F.environment_smash = ENVIRONMENT_SMASH_WALLS + F.mob_size = MOB_SIZE_LARGE + F.speed = 1 + addtimer(CALLBACK(F, /mob/living/simple_animal/hostile/asteroid/fugu/proc/Deflate), 100) /mob/living/simple_animal/hostile/asteroid/fugu/proc/Deflate() if(wumbo) walk(src, 0) wumbo = 0 - icon_state = "Fugu" + icon_state = "Fugu0" obj_damage = 0 melee_damage_lower = 0 melee_damage_upper = 0 @@ -90,7 +106,6 @@ retreat_distance = 9 minimum_distance = 9 move_to_delay = 2 - transform /= 2 inflate_cooldown = 4 environment_smash = ENVIRONMENT_SMASH_NONE mob_size = MOB_SIZE_SMALL @@ -108,7 +123,6 @@ flags_1 = NOBLUDGEON_1 w_class = WEIGHT_CLASS_NORMAL layer = MOB_LAYER - origin_tech = "biotech=6" var/list/banned_mobs /obj/item/asteroid/fugu_gland/afterattack(atom/target, mob/user, proximity_flag) diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index ffbeb1f503..e4de22b2a7 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -127,7 +127,7 @@ /mob/living/simple_animal/parrot/death(gibbed) if(held_item) - held_item.loc = src.loc + held_item.forceMove(drop_location()) held_item = null walk(src,0) @@ -213,7 +213,7 @@ src.say("[pick(available_channels)] BAWWWWWK LEAVE THE HEADSET BAWKKKKK!") else src.say("BAWWWWWK LEAVE THE HEADSET BAWKKKKK!") - ears.loc = src.loc + ears.forceMove(src.loc) ears = null for(var/possible_phrase in speak) if(copytext(possible_phrase,1,3) in GLOB.department_radio_keys) @@ -504,7 +504,7 @@ else //This should ensure that we only grab the item we want, and make sure it's not already collected on our perch if(!parrot_perch || parrot_interest.loc != parrot_perch.loc) held_item = parrot_interest - parrot_interest.loc = src + parrot_interest.forceMove(src) visible_message("[src] grabs [held_item]!", "You grab [held_item]!", "You hear the sounds of wings flapping furiously.") parrot_interest = null @@ -526,7 +526,7 @@ return if(Adjacent(parrot_perch)) - src.loc = parrot_perch.loc + forceMove(parrot_perch.loc) drop_held_item() parrot_state = PARROT_PERCH icon_state = icon_sit @@ -702,7 +702,7 @@ continue held_item = I - I.loc = src + I.forceMove(src) visible_message("[src] grabs [held_item]!", "You grab [held_item]!", "You hear the sounds of wings flapping furiously.") return held_item @@ -777,7 +777,7 @@ if(!drop_gently) if(istype(held_item, /obj/item/grenade)) var/obj/item/grenade/G = held_item - G.loc = src.loc + G.forceMove(drop_location()) G.prime() to_chat(src, "You let go of [held_item]!") held_item = null @@ -785,7 +785,7 @@ to_chat(src, "You drop [held_item].") - held_item.loc = src.loc + held_item.forceMove(drop_location()) held_item = null return 1 @@ -801,7 +801,7 @@ 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 + src.forceMove(AM.loc) icon_state = icon_sit return to_chat(src, "There is no perch nearby to sit on!") @@ -838,7 +838,7 @@ /mob/living/simple_animal/parrot/proc/perch_on_human(mob/living/carbon/human/H) if(!H) return - loc = get_turf(H) + forceMove(get_turf(H)) H.buckle_mob(src, force=1) pixel_y = 9 pixel_x = pick(-8,8) //pick left or right shoulder @@ -962,7 +962,7 @@ 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() + qdel(src) /mob/living/simple_animal/parrot/Poly/ghost name = "The Ghost of Poly" @@ -996,7 +996,7 @@ return var/datum/disease/parrot_possession/P = new P.parrot = src - loc = H + forceMove(H) H.ForceContractDisease(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!") diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 72a1ec84c1..4c5b94f2e3 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -111,7 +111,7 @@ /mob/living/simple_animal/updatehealth() ..() - health = Clamp(health, 0, maxHealth) + health = CLAMP(health, 0, maxHealth) /mob/living/simple_animal/update_stat() if(status_flags & GODMODE) @@ -521,37 +521,26 @@ client.screen |= l_hand //ANIMAL RIDING -/mob/living/simple_animal/unbuckle_mob(mob/living/buckled_mob, force = 0, check_loc = 1) - if(riding_datum) - riding_datum.restore_position(buckled_mob) - . = ..() - /mob/living/simple_animal/user_buckle_mob(mob/living/M, mob/user) + GET_COMPONENT(riding_datum, /datum/component/riding) if(riding_datum) if(user.incapacitated()) return for(var/atom/movable/A in get_turf(src)) if(A != src && A != M && A.density) return - M.loc = get_turf(src) - riding_datum.handle_vehicle_offsets() - riding_datum.ridden = src + M.forceMove(get_turf(src)) + return ..() /mob/living/simple_animal/relaymove(mob/user, direction) + GET_COMPONENT(riding_datum, /datum/component/riding) if(tame && riding_datum) riding_datum.handle_ride(user, direction) -/mob/living/simple_animal/Moved() - . = ..() - if(riding_datum) - riding_datum.on_vehicle_move() - - /mob/living/simple_animal/buckle_mob(mob/living/buckled_mob, force = 0, check_loc = 1) . = ..() - riding_datum = new/datum/riding/animal - + LoadComponent(/datum/component/riding) /mob/living/simple_animal/proc/toggle_ai(togglestatus) if (AIStatus != togglestatus) diff --git a/code/modules/mob/living/simple_animal/slime/powers.dm b/code/modules/mob/living/simple_animal/slime/powers.dm index e7e71bf091..9654f91b6c 100644 --- a/code/modules/mob/living/simple_animal/slime/powers.dm +++ b/code/modules/mob/living/simple_animal/slime/powers.dm @@ -166,7 +166,7 @@ step_away(M,src) M.Friends = Friends.Copy() babies += M - M.mutation_chance = Clamp(mutation_chance+(rand(5,-5)),0,100) + M.mutation_chance = CLAMP(mutation_chance+(rand(5,-5)),0,100) SSblackbox.record_feedback("tally", "slime_babies_born", 1, M.colour) var/mob/living/simple_animal/slime/new_slime = pick(babies) diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index bed14bdff4..a91db7f177 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -26,20 +26,28 @@ reload_fullscreen() // Reload any fullscreen overlays this mob has. - if(ckey in GLOB.deadmins) - verbs += /client/proc/readmin - add_click_catcher() sync_mind() client.sethotkeys() //set mob specific hotkeys + //Reload alternate appearances + for(var/v in GLOB.active_alternate_appearances) + if(!v) + continue + var/datum/atom_hud/alternate_appearance/AA = v + AA.onNewMob(src) + update_client_colour() if(client) client.click_intercept = null - client.change_view(world.view) // Resets the client.view in case it was changed. + client.change_view(CONFIG_GET(string/default_view)) // Resets the client.view in case it was changed. + + if(client.player_details.player_actions.len) + for(var/datum/action/A in client.player_details.player_actions) + A.Grant(src) if(!GLOB.individual_log_list[ckey]) GLOB.individual_log_list[ckey] = logging diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 9a9b161e51..b19af6342c 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -42,9 +42,14 @@ /atom/proc/prepare_huds() hud_list = list() for(var/hud in hud_possible) - var/image/I = image('icons/mob/hud.dmi', src, "") - I.appearance_flags = RESET_COLOR|RESET_TRANSFORM - hud_list[hud] = I + var/hint = hud_possible[hud] + switch(hint) + if(HUD_LIST_LIST) + hud_list[hud] = list() + else + var/image/I = image('icons/mob/hud.dmi', src, "") + I.appearance_flags = RESET_COLOR|RESET_TRANSFORM + hud_list[hud] = I /mob/proc/Cell() set category = "Admin" @@ -395,6 +400,7 @@ pulling = null grab_state = 0 update_pull_hud_icon() + if(isliving(ex_pulled)) var/mob/living/L = ex_pulled L.update_canmove()// mob gets up if it was lyng down in a chokehold @@ -769,14 +775,14 @@ //Default buckling shift visual for mobs /mob/post_buckle_mob(mob/living/M) - if(M in buckled_mobs)//post buckling - var/height = M.get_mob_buckling_height(src) - M.pixel_y = initial(M.pixel_y) + height - if(M.layer < layer) - M.layer = layer + 0.1 - else //post unbuckling - M.layer = initial(M.layer) - M.pixel_y = initial(M.pixel_y) + var/height = M.get_mob_buckling_height(src) + M.pixel_y = initial(M.pixel_y) + height + if(M.layer < layer) + M.layer = layer + 0.1 + +/mob/post_unbuckle_mob(mob/living/M) + M.layer = initial(M.layer) + M.pixel_y = initial(M.pixel_y) //returns the height in pixel the mob should have when buckled to another mob. /mob/proc/get_mob_buckling_height(mob/seat) diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 58cb82714e..edbf11654b 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -33,7 +33,6 @@ var/obj/machinery/machine = null var/other_mobs = null var/disabilities = 0 //Carbon - var/movement_type = GROUND //Incase you have multiple types, you automatically use the most useful one. IE: Skating on ice, flippers on water, flying over chasm/space, etc. var/atom/movable/pulling = null var/grab_state = 0 @@ -45,6 +44,7 @@ var/stuttering = 0 //Carbon var/slurring = 0 //Carbon var/cultslurring = 0 //Carbon + var/derpspeech = 0 //Carbon var/real_name = null var/spacewalk = FALSE var/druggy = 0 //Carbon diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 3dc56c936b..747d589c05 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -363,7 +363,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp if(M.mind in SSticker.mode.cult) return 2 if("nuclear") - if(M.mind in SSticker.mode.syndicates) + if(M.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE)) return 2 if("changeling") if(M.mind.has_antag_datum(/datum/antagonist/changeling,TRUE)) diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 9885d1c4d6..94431a9a7c 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -107,7 +107,7 @@ return mob.control_object.setDir(direct) else - mob.control_object.loc = get_step(mob.control_object,direct) + mob.control_object.forceMove(get_step(mob.control_object,direct)) return #define MOVEMENT_DELAY_BUFFER 0.75 @@ -186,7 +186,7 @@ if(LAZYLEN(mob.user_movement_hooks)) for(var/obj/O in mob.user_movement_hooks) O.intercept_user_move(direct, mob, n, oldloc) - + var/atom/movable/P = mob.pulling if(P && !ismob(P) && P.density) mob.dir = turn(mob.dir, 180) diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index a396072b4f..1ee7f27452 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -19,7 +19,7 @@ /mob/proc/whisper(message, datum/language/language=null) say(message, language) //only living mobs actually whisper, everything else just talks -/mob/verb/me_verb(message as message) +/mob/verb/me_verb(message as text) set name = "Me" set category = "IC" @@ -27,8 +27,7 @@ to_chat(usr, "Speech is currently admin-disabled.") return - var/list/replace_chars = list("\n"=" ","\t"=" ") - message = copytext(sanitize(message, replace_chars), 1, (MAX_MESSAGE_LEN*2)) + message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) usr.emote("me",1,message) @@ -80,4 +79,4 @@ return 0 /mob/proc/lingcheck() - return 0 + return LINGHIVE_NONE diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 85a8ed5448..42a1ce725f 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -58,7 +58,6 @@ O.suiciding = suiciding if(hellbound) O.hellbound = hellbound - O.loc = loc O.a_intent = INTENT_HARM //keep viruses? @@ -79,6 +78,9 @@ O.setBrainLoss(getBrainLoss(), 0) O.updatehealth() O.radiation = radiation + for(var/T in get_traumas()) + var/datum/brain_trauma/BT = T + O.gain_trauma(BT.type, BT.permanent) //re-add implants to new mob if (tr_flags & TR_KEEPIMPLANTS) @@ -110,7 +112,7 @@ var/obj/item/bodypart/chest/torso = O.get_bodypart("chest") if(cavity_object) torso.cavity_item = cavity_object //cavity item is given to the new chest - cavity_object.loc = O + cavity_object.forceMove(O) for(var/missing_zone in missing_bodyparts_zones) var/obj/item/bodypart/BP = O.get_bodypart(missing_zone) @@ -217,8 +219,6 @@ if(hellbound) O.hellbound = hellbound - O.loc = loc - //keep viruses? if (tr_flags & TR_KEEPVIRUS) O.viruses = viruses @@ -238,6 +238,9 @@ O.setBrainLoss(getBrainLoss(), 0) O.updatehealth() O.radiation = radiation + for(var/T in get_traumas()) + var/datum/brain_trauma/BT = T + O.gain_trauma(BT.type, BT.permanent) //re-add implants to new mob if (tr_flags & TR_KEEPIMPLANTS) @@ -270,7 +273,7 @@ var/obj/item/bodypart/chest/torso = get_bodypart("chest") if(cavity_object) torso.cavity_item = cavity_object //cavity item is given to the new chest - cavity_object.loc = O + cavity_object.forceMove(O) for(var/missing_zone in missing_bodyparts_zones) var/obj/item/bodypart/BP = O.get_bodypart(missing_zone) @@ -372,10 +375,7 @@ var/mob/living/silicon/robot/R = new /mob/living/silicon/robot(loc) // cyborgs produced by Robotize get an automatic power cell - R.cell = new(R) - R.cell.maxcharge = 7500 - R.cell.charge = 7500 - + R.cell = new /obj/item/stock_parts/cell/high(R, 7500) R.gender = gender R.invisibility = 0 @@ -398,7 +398,6 @@ R.mmi.brainmob.real_name = real_name //the name of the brain inside the cyborg is the robotized human's name. R.mmi.brainmob.name = real_name - R.loc = loc R.job = "Cyborg" R.notify_ai(NEW_BORG) diff --git a/code/modules/modular_computers/hardware/CPU.dm b/code/modules/modular_computers/hardware/CPU.dm index b0c56ee0ba..38b7b5dec4 100644 --- a/code/modules/modular_computers/hardware/CPU.dm +++ b/code/modules/modular_computers/hardware/CPU.dm @@ -9,7 +9,6 @@ power_usage = 50 critical = 1 malfunction_probability = 1 - origin_tech = "programming=3;engineering=2" var/max_idle_programs = 2 // 2 idle, + 1 active = 3 as said in description. device_type = MC_CPU @@ -23,7 +22,6 @@ w_class = WEIGHT_CLASS_TINY power_usage = 25 max_idle_programs = 1 - origin_tech = "programming=2;engineering=2" /obj/item/computer_hardware/processor_unit/photonic name = "photonic processor board" @@ -32,7 +30,6 @@ w_class = WEIGHT_CLASS_SMALL power_usage = 250 max_idle_programs = 4 - origin_tech = "programming=5;engineering=4" /obj/item/computer_hardware/processor_unit/photonic/small name = "photonic microprocessor" @@ -40,5 +37,4 @@ icon_state = "cpu_super" w_class = WEIGHT_CLASS_TINY power_usage = 75 - max_idle_programs = 2 - origin_tech = "programming=4;engineering=3" \ No newline at end of file + max_idle_programs = 2 \ No newline at end of file diff --git a/code/modules/modular_computers/hardware/ai_slot.dm b/code/modules/modular_computers/hardware/ai_slot.dm index edd78839c3..4dace2b4cf 100644 --- a/code/modules/modular_computers/hardware/ai_slot.dm +++ b/code/modules/modular_computers/hardware/ai_slot.dm @@ -4,7 +4,6 @@ power_usage = 100 //W icon_state = "card_mini" w_class = WEIGHT_CLASS_SMALL - origin_tech = "programming=2" device_type = MC_AI var/obj/item/device/aicard/stored_card = null diff --git a/code/modules/modular_computers/hardware/battery_module.dm b/code/modules/modular_computers/hardware/battery_module.dm index 6c3dac9b63..c6b96e3136 100644 --- a/code/modules/modular_computers/hardware/battery_module.dm +++ b/code/modules/modular_computers/hardware/battery_module.dm @@ -4,7 +4,6 @@ icon_state = "cell_con" critical = 1 malfunction_probability = 1 - origin_tech = "powerstorage=1;engineering=1" var/obj/item/stock_parts/cell/battery = null device_type = MC_CELL @@ -64,7 +63,6 @@ desc = "A standard power cell, commonly seen in high-end portable microcomputers or low-end laptops." icon = 'icons/obj/module.dmi' icon_state = "cell_mini" - origin_tech = "powerstorage=2;engineering=1" w_class = WEIGHT_CLASS_TINY maxcharge = 750 @@ -73,7 +71,6 @@ name = "advanced battery" desc = "An advanced power cell, often used in most laptops. It is too large to be fitted into smaller devices." icon_state = "cell" - origin_tech = "powerstorage=2;engineering=2" w_class = WEIGHT_CLASS_SMALL maxcharge = 1500 @@ -81,7 +78,6 @@ name = "super battery" desc = "An advanced power cell, often used in high-end laptops." icon_state = "cell" - origin_tech = "powerstorage=3;engineering=3" w_class = WEIGHT_CLASS_SMALL maxcharge = 2000 diff --git a/code/modules/modular_computers/hardware/card_slot.dm b/code/modules/modular_computers/hardware/card_slot.dm index caebfb447b..3d071c47aa 100644 --- a/code/modules/modular_computers/hardware/card_slot.dm +++ b/code/modules/modular_computers/hardware/card_slot.dm @@ -4,7 +4,6 @@ power_usage = 10 //W icon_state = "card_mini" w_class = WEIGHT_CLASS_TINY - origin_tech = "programming=2" device_type = MC_CARD var/obj/item/card/id/stored_card = null diff --git a/code/modules/modular_computers/hardware/hard_drive.dm b/code/modules/modular_computers/hardware/hard_drive.dm index 2ad1caa951..62d8ff5d86 100644 --- a/code/modules/modular_computers/hardware/hard_drive.dm +++ b/code/modules/modular_computers/hardware/hard_drive.dm @@ -5,7 +5,6 @@ icon_state = "harddisk_mini" critical = 1 w_class = WEIGHT_CLASS_TINY - origin_tech = "programming=1;engineering=1" device_type = MC_HDD var/max_capacity = 128 var/used_capacity = 0 @@ -130,7 +129,6 @@ name = "advanced hard disk drive" desc = "A hybrid HDD, for use in higher grade computers where balance between power efficiency and capacity is desired." max_capacity = 256 - origin_tech = "programming=2;engineering=2" power_usage = 50 // Hybrid, medium capacity and medium power storage icon_state = "harddisk_mini" w_class = WEIGHT_CLASS_SMALL @@ -139,7 +137,6 @@ name = "super hard disk drive" desc = "A high capacity HDD, for use in cluster storage solutions where capacity is more important than power efficiency." max_capacity = 512 - origin_tech = "programming=3;engineering=3" power_usage = 100 // High-capacity but uses lots of power, shortening battery life. Best used with APC link. icon_state = "harddisk_mini" w_class = WEIGHT_CLASS_SMALL @@ -148,7 +145,6 @@ name = "cluster hard disk drive" desc = "A large storage cluster consisting of multiple HDDs for usage in dedicated storage systems." power_usage = 500 - origin_tech = "programming=4;engineering=4" max_capacity = 2048 icon_state = "harddisk" w_class = WEIGHT_CLASS_NORMAL @@ -158,7 +154,6 @@ name = "solid state drive" desc = "An efficient SSD for portable devices." power_usage = 10 - origin_tech = "programming=2;engineering=2" max_capacity = 64 icon_state = "ssd_mini" w_class = WEIGHT_CLASS_TINY @@ -167,7 +162,6 @@ name = "micro solid state drive" desc = "A highly efficient SSD chip for portable devices." power_usage = 2 - origin_tech = "programming=1;engineering=1" max_capacity = 32 icon_state = "ssd_micro" w_class = WEIGHT_CLASS_TINY \ No newline at end of file diff --git a/code/modules/modular_computers/hardware/network_card.dm b/code/modules/modular_computers/hardware/network_card.dm index c6d507c4ed..216d55fbd8 100644 --- a/code/modules/modular_computers/hardware/network_card.dm +++ b/code/modules/modular_computers/hardware/network_card.dm @@ -2,7 +2,6 @@ name = "network card" desc = "A basic wireless network card for usage with standard NTNet frequencies." power_usage = 50 - origin_tech = "programming=2;engineering=1" icon_state = "radio_mini" var/identification_id = null // Identification ID. Technically MAC address of this device. Can't be changed by user. var/identification_string = "" // Identification string, technically nickname seen in the network. Can be set by user. @@ -65,7 +64,6 @@ name = "advanced network card" desc = "An advanced network card for usage with standard NTNet frequencies. Its transmitter is strong enough to connect even off-station." long_range = 1 - origin_tech = "programming=4;engineering=2" power_usage = 100 // Better range but higher power usage. icon_state = "radio" lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' @@ -76,7 +74,6 @@ name = "wired network card" desc = "An advanced network card for usage with standard NTNet frequencies. This one also supports wired connection." ethernet = 1 - origin_tech = "programming=5;engineering=3" power_usage = 100 // Better range but higher power usage. icon_state = "net_wired" w_class = WEIGHT_CLASS_NORMAL diff --git a/code/modules/modular_computers/hardware/portable_disk.dm b/code/modules/modular_computers/hardware/portable_disk.dm index 47430f80ac..d5aa404f58 100644 --- a/code/modules/modular_computers/hardware/portable_disk.dm +++ b/code/modules/modular_computers/hardware/portable_disk.dm @@ -6,7 +6,6 @@ w_class = WEIGHT_CLASS_TINY critical = 0 max_capacity = 16 - origin_tech = "programming=1" device_type = MC_SDD /obj/item/computer_hardware/hard_drive/portable/on_install(obj/item/device/modular_computer/M, mob/living/user = null) @@ -24,7 +23,6 @@ power_usage = 20 icon_state = "datadisk5" max_capacity = 64 - origin_tech = "programming=2" /obj/item/computer_hardware/hard_drive/portable/super name = "super data disk" @@ -32,4 +30,3 @@ power_usage = 40 icon_state = "datadisk3" max_capacity = 256 - origin_tech = "programming=4" diff --git a/code/modules/modular_computers/hardware/printer.dm b/code/modules/modular_computers/hardware/printer.dm index 27eb050655..b000c353b0 100644 --- a/code/modules/modular_computers/hardware/printer.dm +++ b/code/modules/modular_computers/hardware/printer.dm @@ -2,7 +2,6 @@ name = "printer" desc = "Computer-integrated printer with paper recycling module." power_usage = 100 - origin_tech = "programming=2;engineering=2" icon_state = "printer" w_class = WEIGHT_CLASS_NORMAL device_type = MC_PRINT diff --git a/code/modules/modular_computers/hardware/recharger.dm b/code/modules/modular_computers/hardware/recharger.dm index 7096233d3a..f1c7578aa7 100644 --- a/code/modules/modular_computers/hardware/recharger.dm +++ b/code/modules/modular_computers/hardware/recharger.dm @@ -28,7 +28,6 @@ desc = "A device that wirelessly recharges connected device from nearby APC." icon_state = "charger_APC" w_class = WEIGHT_CLASS_SMALL // Can't be installed into tablets/PDAs - origin_tech = "programming=2;engineering=2;powerstorage=3" /obj/item/computer_hardware/recharger/APC/use_power(amount, charging=0) if(ismachinery(holder.physical)) @@ -52,7 +51,6 @@ desc = "A power connector that recharges connected device from nearby power wire. Incompatible with portable computers." icon_state = "charger_wire" w_class = WEIGHT_CLASS_NORMAL - origin_tech = "engineering=2;powerstorage=1" /obj/item/computer_hardware/recharger/wired/can_install(obj/item/device/modular_computer/M, mob/living/user = null) if(ismachinery(M.physical) && M.physical.anchored) diff --git a/code/modules/ninja/ninja_event.dm b/code/modules/ninja/ninja_event.dm index 1656a43505..b26d01d880 100644 --- a/code/modules/ninja/ninja_event.dm +++ b/code/modules/ninja/ninja_event.dm @@ -95,7 +95,7 @@ Contents: var/datum/mind/Mind = new /datum/mind(key) Mind.assigned_role = "Space Ninja" Mind.special_role = "Space Ninja" - SSticker.mode.traitors |= Mind //Adds them to current traitor list. Which is really the extra antagonist list. + SSticker.mode.traitors |= Mind //Adds them to current traitor list. TODO : Remove this in admin tools refeactor. return Mind diff --git a/code/modules/ninja/suit/gloves.dm b/code/modules/ninja/suit/gloves.dm index 6cf03d1c10..c49ca072e8 100644 --- a/code/modules/ninja/suit/gloves.dm +++ b/code/modules/ninja/suit/gloves.dm @@ -63,9 +63,9 @@ if(isnum(.)) //Numerical values of drained handle their feedback here, Alpha values handle it themselves (Research hacking) if(.) - to_chat(H, "Gained [DisplayPower(.)] of power from [A].") + to_chat(H, "Gained [DisplayEnergy(.)] of energy from [A].") else - to_chat(H, "\The [A] has run dry of power, you must find another source!") + to_chat(H, "\The [A] has run dry of energy, you must find another source!") else . = 0 //as to not cancel attack_hand() diff --git a/code/modules/ninja/suit/ninjaDrainAct.dm b/code/modules/ninja/suit/ninjaDrainAct.dm index 4679b5ffbd..cdae56571f 100644 --- a/code/modules/ninja/suit/ninjaDrainAct.dm +++ b/code/modules/ninja/suit/ninjaDrainAct.dm @@ -10,7 +10,7 @@ They *could* go in their appropriate files, but this is supposed to be modular */ -//Needs to return the amount drained from the atom, if no drain on a power object, return 0, otherwise, return a define. +//Needs to return the amount drained from the atom, if no drain on a power object, return FALSE, otherwise, return a define. /atom/proc/ninjadrain_act() return INVALID_DRAIN @@ -130,26 +130,15 @@ They *could* go in their appropriate files, but this is supposed to be modular to_chat(H, "Hacking \the [src]...") AI_notify_hack() - if(files && files.known_tech.len) - for(var/datum/tech/current_data in S.stored_research) - to_chat(H, "Checking \the [current_data.name] database.") - if(do_after(H, S.s_delay, target = src) && G.candrain && src) - for(var/id in files.known_tech) - var/datum/tech/analyzing_data = files.known_tech[id] - if(current_data.id == analyzing_data.id) - if(analyzing_data.level > current_data.level) - to_chat(H, "Database: UPDATED.") - current_data.level = analyzing_data.level - . = DRAIN_RD_HACKED - break//Move on to next. - else - break//Otherwise, quit processing. - + if(stored_research) + to_chat(H, "Copying files...") + if(do_after(H, S.s_delay, target = src) && G.candrain && src) + stored_research.copy_research_to(S.stored_research) to_chat(H, "Data analyzed. Process finished.") //RD SERVER// //Shamelessly copypasted from above, since these two used to be the same proc, but with MANY colon operators -/obj/machinery/r_n_d/server/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/S, mob/living/carbon/human/H, obj/item/clothing/gloves/space_ninja/G) +/obj/machinery/rnd/server/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/S, mob/living/carbon/human/H, obj/item/clothing/gloves/space_ninja/G) if(!S || !H || !G) return INVALID_DRAIN @@ -158,21 +147,10 @@ They *could* go in their appropriate files, but this is supposed to be modular to_chat(H, "Hacking \the [src]...") AI_notify_hack() - if(files && files.known_tech.len) - for(var/datum/tech/current_data in S.stored_research) - to_chat(H, "Checking \the [current_data.name] database.") - if(do_after(H, S.s_delay, target = src) && G.candrain && src) - for(var/id in files.known_tech) - var/datum/tech/analyzing_data = files.known_tech[id] - if(current_data.id == analyzing_data.id) - if(analyzing_data.level > current_data.level) - to_chat(H, "Database: UPDATED.") - current_data.level = analyzing_data.level - . = DRAIN_RD_HACKED - break//Move on to next. - else - break//Otherwise, quit processing. - + if(stored_research) + to_chat(H, "Copying files...") + if(do_after(H, S.s_delay, target = src) && G.candrain && src) + stored_research.copy_research_to(S.stored_research) to_chat(H, "Data analyzed. Process finished.") diff --git a/code/modules/ninja/suit/suit.dm b/code/modules/ninja/suit/suit.dm index 1dcfed99c0..82c7dfa0bf 100644 --- a/code/modules/ninja/suit/suit.dm +++ b/code/modules/ninja/suit/suit.dm @@ -28,7 +28,7 @@ Contents: var/mob/living/carbon/human/affecting = null var/obj/item/stock_parts/cell/cell var/datum/effect_system/spark_spread/spark_system - var/list/stored_research = list()//For stealing station research. + var/datum/techweb/stored_research var/obj/item/disk/tech_disk/t_disk//To copy design onto disk. var/obj/item/energy_katana/energyKatana //For teleporting the katana back to the ninja (It's an ability) @@ -62,14 +62,12 @@ Contents: ..() //Spark Init - spark_system = new() + spark_system = new spark_system.set_up(5, 0, src) spark_system.attach(src) //Research Init stored_research = new() - for(var/T in subtypesof(/datum/tech))//Store up on research. - stored_research += new T(src) //Cell Init cell = new/obj/item/stock_parts/cell/high @@ -97,7 +95,7 @@ Contents: //This proc prevents the suit from being taken off. /obj/item/clothing/suit/space/space_ninja/proc/lock_suit(mob/living/carbon/human/H) if(!istype(H)) - return 0 + return FALSE if(!is_ninja(H)) to_chat(H, "fTaL RRoR: 382200-*#00CDE RED\nUNAU?HORIZED US DETC???eD\nCoMMNCING SUB-R0U?IN3 13...\nTRMInATING U-U-USR...") H.gib() @@ -152,7 +150,7 @@ Contents: ..() if(s_initialized) if(user == affecting) - to_chat(user, "All systems operational. Current energy capacity: [DisplayPower(cell.charge)].") + to_chat(user, "All systems operational. Current energy capacity: [DisplayEnergy(cell.charge)].") to_chat(user, "The CLOAK-tech device is [s_active?"active":"inactive"].") to_chat(user, "There are [s_bombs] smoke bomb\s remaining.") to_chat(user, "There are [a_boost] adrenaline booster\s remaining.") diff --git a/code/modules/ninja/suit/suit_attackby.dm b/code/modules/ninja/suit/suit_attackby.dm index ce75fd6ed3..d185d596a3 100644 --- a/code/modules/ninja/suit/suit_attackby.dm +++ b/code/modules/ninja/suit/suit_attackby.dm @@ -32,26 +32,12 @@ else if(istype(I, /obj/item/disk/tech_disk))//If it's a data disk, we want to copy the research on to the suit. var/obj/item/disk/tech_disk/TD = I - var/has_research = FALSE - for(var/V in TD.tech_stored) - if(V) - has_research = TRUE - break + var/has_research = 0 if(has_research)//If it has something on it. - to_chat(U, "Research information detected, processing...") + to_chat(U, "Research information detected, processing...") if(do_after(U,s_delay, target = src)) - for(var/V1 in 1 to TD.max_tech_stored) - var/datum/tech/new_data = TD.tech_stored[V1] - TD.tech_stored[V1] = null - if(!new_data) - continue - for(var/V2 in stored_research) - var/datum/tech/current_data = V2 - if(current_data.id == new_data.id) - current_data.level = max(current_data.level, new_data.level) - break + TD.stored_research.copy_research_to(stored_research) to_chat(U, "Data analyzed and updated. Disk erased.") - else to_chat(U, "ERROR: Procedure interrupted. Process terminated.") else diff --git a/code/modules/ninja/suit/suit_initialisation.dm b/code/modules/ninja/suit/suit_initialisation.dm index 0084ff1995..e19e67404d 100644 --- a/code/modules/ninja/suit/suit_initialisation.dm +++ b/code/modules/ninja/suit/suit_initialisation.dm @@ -42,7 +42,7 @@ addtimer(CALLBACK(src, .proc/ninitialize_six, delay, U), delay) /obj/item/clothing/suit/space/space_ninja/proc/ninitialize_six(delay, mob/living/carbon/human/U) - to_chat(U, "Primary system status: ONLINE.\nBackup system status: ONLINE.\nCurrent energy capacity: [DisplayPower(cell.charge)].") + to_chat(U, "Primary system status: ONLINE.\nBackup system status: ONLINE.\nCurrent energy capacity: [DisplayEnergy(cell.charge)].") addtimer(CALLBACK(src, .proc/ninitialize_seven, delay, U), delay) /obj/item/clothing/suit/space/space_ninja/proc/ninitialize_seven(delay, mob/living/carbon/human/U) diff --git a/code/modules/paperwork/clipboard.dm b/code/modules/paperwork/clipboard.dm index d9d220b0ef..e8487b3344 100644 --- a/code/modules/paperwork/clipboard.dm +++ b/code/modules/paperwork/clipboard.dm @@ -73,7 +73,7 @@ if(href_list["pen"]) if(haspen) - haspen.loc = usr.loc + haspen.forceMove(usr.loc) usr.put_in_hands(haspen) haspen = null @@ -96,7 +96,7 @@ if(href_list["remove"]) var/obj/item/P = locate(href_list["remove"]) if(istype(P) && P.loc == src) - P.loc = usr.loc + P.forceMove(usr.loc) usr.put_in_hands(P) if(P == toppaper) toppaper = null diff --git a/code/modules/paperwork/contract.dm b/code/modules/paperwork/contract.dm index a02e98ed2b..3f23b8ba22 100644 --- a/code/modules/paperwork/contract.dm +++ b/code/modules/paperwork/contract.dm @@ -45,11 +45,6 @@ to_chat(M, "You feel that your soul has returned to its rightful owner, Nanotrasen.") M.return_soul() else - if(ishuman(M)) - var/mob/living/carbon/human/N = M - if(!istype(N.head, /obj/item/clothing/head/helmet)) - N.adjustBrainLoss(10) - to_chat(N, "You feel dumber.") M.visible_message("[user] beats [M] over the head with [src]!", \ "[user] beats [M] over the head with [src]!") return ..() @@ -207,7 +202,7 @@ if(!user.mind.hasSoul) to_chat(user, "You do not possess a soul.") return 0 - if(prob(user.getBrainLoss())) + if(user.disabilities & DUMB) to_chat(user, "You quickly scrawl 'your name' on the contract.") signIncorrectly() return 0 @@ -307,11 +302,11 @@ if(istype(worn, /obj/item/device/pda)) var/obj/item/device/pda/PDA = worn PDA.id = id - id.loc = worn + id.forceMove(worn) else if(istype(worn, /obj/item/storage/wallet)) var/obj/item/storage/wallet/W = worn W.front_id = id - id.loc = worn + id.forceMove(worn) worn.update_icon() var/datum/round_event/ion_storm/add_law_only/ion = new() ion.announceEvent = -1 diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm index 21d157a33c..0d963d4be8 100644 --- a/code/modules/paperwork/filingcabinet.dm +++ b/code/modules/paperwork/filingcabinet.dm @@ -36,7 +36,7 @@ if(mapload) for(var/obj/item/I in loc) if(istype(I, /obj/item/paper) || istype(I, /obj/item/folder) || istype(I, /obj/item/photo)) - I.loc = src + I.forceMove(src) /obj/structure/filingcabinet/deconstruct(disassembled = TRUE) if(!(flags_1 & NODECONSTRUCT_1)) @@ -90,7 +90,7 @@ if(contents.len) if(prob(40 + contents.len * 5)) var/obj/item/I = pick(contents) - I.loc = loc + I.forceMove(loc) if(prob(25)) step_rand(I) to_chat(user, "You pull \a [I] out of [src] at random.") @@ -184,7 +184,8 @@ GLOBAL_LIST_EMPTY(employmentCabinets) icon_state = "employmentcabinet" var/virgin = 1 -/obj/structure/filingcabinet/employment/New() +/obj/structure/filingcabinet/employment/Initialize() + . = ..() GLOB.employmentCabinets += src return ..() diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm index 3221a2c8db..c81ab37591 100644 --- a/code/modules/paperwork/folders.dm +++ b/code/modules/paperwork/folders.dm @@ -62,7 +62,7 @@ if(href_list["remove"]) var/obj/item/I = locate(href_list["remove"]) if(istype(I) && I.loc == src) - I.loc = usr.loc + I.forceMove(usr.loc) usr.put_in_hands(I) if(href_list["read"]) diff --git a/code/modules/paperwork/paper_cutter.dm b/code/modules/paperwork/paper_cutter.dm index 4a85d03df7..fbf6e7b6e4 100644 --- a/code/modules/paperwork/paper_cutter.dm +++ b/code/modules/paperwork/paper_cutter.dm @@ -55,7 +55,7 @@ if(!user.transferItemToLoc(P, src)) return to_chat(user, "You replace [src]'s [P].") - P.loc = src + P.forceMove(src) storedcutter = P update_icon() return diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm index 962802aa6d..87dc0506f2 100644 --- a/code/modules/paperwork/paperbin.dm +++ b/code/modules/paperwork/paperbin.dm @@ -22,7 +22,7 @@ return var/obj/item/pen/P = locate(/obj/item/pen) in src.loc if(P && !bin_pen) - P.loc = src + P.forceMove(src) bin_pen = P update_icon() @@ -69,7 +69,7 @@ user.changeNext_move(CLICK_CD_MELEE) if(bin_pen) var/obj/item/pen/P = bin_pen - P.loc = user.loc + P.forceMove(user.loc) user.put_in_hands(P) to_chat(user, "You take [P] out of \the [src].") bin_pen = null @@ -90,7 +90,7 @@ P.rigged = 1 P.updateinfolinks() - P.loc = user.loc + P.forceMove(user.loc) user.put_in_hands(P) to_chat(user, "You take [P] out of \the [src].") else @@ -169,4 +169,4 @@ CHECK_TICK qdel(src) else - ..() \ No newline at end of file + ..() diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index 4b31ce7262..cde600186f 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -23,6 +23,7 @@ throw_range = 7 materials = list(MAT_METAL=10) pressure_resistance = 2 + grind_results = list("iron" = 2, "iodine" = 1) var/colour = "black" //what colour the ink is! var/traitor_unlock_degrees = 0 var/degrees = 0 @@ -99,19 +100,13 @@ if(deg && (deg > 0 && deg <= 360)) degrees = deg to_chat(user, "You rotate the top of the pen to [degrees] degrees.") + GET_COMPONENT(hidden_uplink, /datum/component/uplink) if(hidden_uplink && degrees == traitor_unlock_degrees) to_chat(user, "Your pen makes a clicking noise, before quickly rotating back to 0 degrees!") degrees = 0 + hidden_uplink.locked = FALSE hidden_uplink.interact(user) - -/obj/item/pen/attackby(obj/item/I, mob/user, params) - if(hidden_uplink) - return hidden_uplink.attackby(I, user, params) - else - return ..() - - /obj/item/pen/attack(mob/living/M, mob/user,stealth) if(!istype(M)) return @@ -167,8 +162,7 @@ * Sleepypens */ /obj/item/pen/sleepy - origin_tech = "engineering=4;syndicate=2" - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER /obj/item/pen/sleepy/attack(mob/living/M, mob/user) @@ -181,7 +175,8 @@ reagents.trans_to(M, reagents.total_volume) -/obj/item/pen/sleepy/New() +/obj/item/pen/sleepy/Initialize() + . = ..() create_reagents(45) reagents.add_reagent("chloralhydrate2", 20) reagents.add_reagent("mutetoxin", 15) @@ -192,7 +187,6 @@ * (Alan) Edaggers */ /obj/item/pen/edagger - origin_tech = "combat=3;syndicate=1" attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") //these wont show up if the pen is off var/on = FALSE diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 20038f5745..e065fd8c03 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -247,10 +247,10 @@ /obj/machinery/photocopier/proc/remove_photocopy(obj/item/O, mob/user) if(!issilicon(user)) //surprised this check didn't exist before, putting stuff in AI's hand is bad - O.loc = user.loc + O.forceMove(user.loc) user.put_in_hands(O) else - O.loc = src.loc + O.forceMove(drop_location()) to_chat(user, "You take [O] out of [src].") /obj/machinery/photocopier/attackby(obj/item/O, mob/user, params) @@ -338,16 +338,16 @@ else user.visible_message("[user] puts [target] onto the photocopier!", "You put [target] onto the photocopier.") - target.loc = get_turf(src) + target.forceMove(drop_location()) ass = target if(photocopy) - photocopy.loc = src.loc + photocopy.forceMove(drop_location()) visible_message("[photocopy] is shoved out of the way by [ass]!") photocopy = null else if(copy) - copy.loc = src.loc + copy.forceMove(drop_location()) visible_message("[copy] is shoved out of the way by [ass]!") copy = null updateUsrDialog() @@ -391,5 +391,6 @@ /obj/item/device/toner name = "toner cartridge" icon_state = "tonercartridge" + grind_results = list("iodine" = 40, "iron" = 10) var/charges = 5 var/max_charges = 5 diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index 48b045f680..6e908c0f6a 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -33,6 +33,7 @@ w_class = WEIGHT_CLASS_TINY resistance_flags = FLAMMABLE max_integrity = 50 + grind_results = list("iodine" = 4) var/icon/img //Big photo image var/scribble //Scribble on the back. var/blueprints = 0 //Does it include the blueprints? diff --git a/code/modules/power/antimatter/control.dm b/code/modules/power/antimatter/control.dm index a37344d635..f8b8cae22a 100644 --- a/code/modules/power/antimatter/control.dm +++ b/code/modules/power/antimatter/control.dm @@ -339,7 +339,7 @@ if(href_list["ejectjar"]) if(fueljar) - fueljar.loc = src.loc + fueljar.forceMove(drop_location()) fueljar = null //fueljar.control_unit = null currently it does not care where it is //update_icon() when we have the icon for it diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 815da3fbdb..548651f9c8 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -89,6 +89,7 @@ var/auto_name = 0 var/failure_timer = 0 var/force_update = 0 + var/emergency_lights = FALSE var/update_state = -1 var/update_overlay = -1 var/icon_update_needed = FALSE @@ -152,7 +153,7 @@ GLOB.apcs_list -= src if(malfai && operating) - malfai.malf_picker.processing_time = Clamp(malfai.malf_picker.processing_time - 10,0,1000) + malfai.malf_picker.processing_time = CLAMP(malfai.malf_picker.processing_time - 10,0,1000) area.power_light = FALSE area.power_equip = FALSE area.power_environ = FALSE @@ -760,6 +761,7 @@ "coverLocked" = coverlocked, "siliconUser" = user.has_unlimited_silicon_privilege || user.using_power_flow_console(), "malfStatus" = get_malf_status(user), + "emergencyLights" = !emergency_lights, "powerChannels" = list( list( @@ -899,6 +901,14 @@ failure_timer = 0 update_icon() update() + if("emergency_lighting") + emergency_lights = !emergency_lights + for(var/area/A in area.related) + for(var/obj/machinery/light/L in A) + if(!initial(L.no_emergency)) //If there was an override set on creation, keep that override + L.no_emergency = emergency_lights + INVOKE_ASYNC(L, /obj/machinery/light/.proc/update, FALSE) + CHECK_TICK return 1 /obj/machinery/power/apc/proc/toggle_breaker() @@ -962,7 +972,7 @@ else to_chat(occupier, "Primary core damaged, unable to return core processes.") if(forced) - occupier.loc = src.loc + occupier.forceMove(drop_location()) occupier.death() occupier.gib() for(var/obj/item/pinpointer/nuke/P in GLOB.pinpointer_list) @@ -1243,7 +1253,7 @@ /obj/machinery/power/apc/proc/set_broken() if(malfai && operating) - malfai.malf_picker.processing_time = Clamp(malfai.malf_picker.processing_time - 10,0,1000) + malfai.malf_picker.processing_time = CLAMP(malfai.malf_picker.processing_time - 10,0,1000) stat |= BROKEN operating = FALSE if(occupier) diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index dc63253681..ca424cb80d 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -427,10 +427,10 @@ By design, d1 is the smallest direction and d2 is the highest var/obj/O = P_list[1] // remove the cut cable from its turf and powernet, so that it doesn't get count in propagate_network worklist if(remove) - loc = null + moveToNullspace() powernet.remove_cable(src) //remove the cut cable from its powernet - addtimer(CALLBACK(src, .proc/auto_propogate_cut_cable, O), 0) //so we don't rebuild the network X times when singulo/explosion destroys a line of X cables + addtimer(CALLBACK(O, .proc/auto_propogate_cut_cable, O), 0) //so we don't rebuild the network X times when singulo/explosion destroys a line of X cables // Disconnect machines connected to nodes if(d1 == 0) // if we cut a node (O-X) cable @@ -472,6 +472,7 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai attack_verb = list("whipped", "lashed", "disciplined", "flogged") singular_name = "cable piece" full_w_class = WEIGHT_CLASS_SMALL + grind_results = list("copper" = 2) //2 copper per cable in the coil /obj/item/stack/cable_coil/cyborg is_cyborg = 1 diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index c8e58791e2..cd24dbb928 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -6,7 +6,6 @@ item_state = "cell" lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' - origin_tech = "powerstorage=1" force = 5 throwforce = 5 throw_speed = 2 @@ -15,6 +14,7 @@ var/charge = 0 // note %age conveted to actual charge in New var/maxcharge = 1000 materials = list(MAT_METAL=700, MAT_GLASS=50) + grind_results = list("lithium" = 15, "iron" = 5, "silicon" = 5) var/rigged = 0 // true if rigged to explode var/chargerate = 100 //how much power is given every tick in a recharger var/self_recharge = 0 //does it self recharge, over time, or not? @@ -24,12 +24,14 @@ /obj/item/stock_parts/cell/get_cell() return src -/obj/item/stock_parts/cell/New() +/obj/item/stock_parts/cell/Initialize(mapload, override_maxcharge) . = ..() START_PROCESSING(SSobj, src) + if (override_maxcharge) + maxcharge = override_maxcharge charge = maxcharge if(ratingdesc) - desc += " This one has a power rating of [DisplayPower(maxcharge)], and you should not swallow it." + desc += " This one has a rating of [DisplayEnergy(maxcharge)], and you should not swallow it." update_icon() /obj/item/stock_parts/cell/Destroy() @@ -106,6 +108,7 @@ to_chat(user, "You inject the solution into the power cell.") if(S.reagents.has_reagent("plasma", 5)) rigged = 1 + grind_results["plasma"] = 5 S.reagents.clear_reagents() @@ -154,7 +157,7 @@ /obj/item/stock_parts/cell/proc/get_electrocute_damage() if(charge >= 1000) - return Clamp(round(charge/10000), 10, 90) + rand(-5,5) + return CLAMP(round(charge/10000), 10, 90) + rand(-5,5) else return 0 @@ -185,7 +188,6 @@ /obj/item/stock_parts/cell/secborg name = "security borg rechargeable D battery" - origin_tech = null maxcharge = 600 //600 max charge / 100 charge per shot = six shots materials = list(MAT_GLASS=40) rating = 2.5 @@ -210,7 +212,6 @@ /obj/item/stock_parts/cell/high name = "high-capacity power cell" - origin_tech = "powerstorage=2" icon_state = "hcell" maxcharge = 10000 materials = list(MAT_GLASS=60) @@ -230,7 +231,6 @@ /obj/item/stock_parts/cell/super name = "super-capacity power cell" - origin_tech = "powerstorage=3;materials=3" icon_state = "scell" maxcharge = 20000 materials = list(MAT_GLASS=300) @@ -243,7 +243,6 @@ /obj/item/stock_parts/cell/hyper name = "hyper-capacity power cell" - origin_tech = "powerstorage=4;engineering=4;materials=4" icon_state = "hpcell" maxcharge = 30000 materials = list(MAT_GLASS=400) @@ -257,7 +256,6 @@ /obj/item/stock_parts/cell/bluespace name = "bluespace power cell" desc = "A rechargeable transdimensional power cell." - origin_tech = "powerstorage=5;bluespace=4;materials=4;engineering=4" icon_state = "bscell" maxcharge = 40000 materials = list(MAT_GLASS=600) @@ -271,7 +269,6 @@ /obj/item/stock_parts/cell/infinite name = "infinite-capacity power cell!" icon_state = "icell" - origin_tech = "powerstorage=7" maxcharge = 30000 materials = list(MAT_GLASS=1000) rating = 6 @@ -285,7 +282,6 @@ desc = "An alien power cell that produces energy seemingly out of nowhere." icon = 'icons/obj/abductor.dmi' icon_state = "cell" - origin_tech = "abductor=5;powerstorage=8;engineering=6" maxcharge = 50000 rating = 12 ratingdesc = FALSE @@ -299,7 +295,6 @@ desc = "A rechargeable starch based power cell." icon = 'icons/obj/hydroponics/harvest.dmi' icon_state = "potato" - origin_tech = "powerstorage=1;biotech=1" charge = 100 maxcharge = 300 materials = list() @@ -309,7 +304,6 @@ /obj/item/stock_parts/cell/high/slime name = "charged slime core" desc = "A yellow slime core infused with plasma, it crackles with power." - origin_tech = "powerstorage=5;biotech=4" icon = 'icons/mob/slimes.dmi' icon_state = "yellow slime extract" materials = list() @@ -342,4 +336,18 @@ return /obj/item/stock_parts/cell/beam_rifle/emp_act(severity) - charge = Clamp((charge-(10000/severity)),0,maxcharge) + charge = CLAMP((charge-(10000/severity)),0,maxcharge) + +/obj/item/stock_parts/cell/emergency_light + name = "miniature power cell" + desc = "A tiny power cell with a very low power capacity. Used in light fixtures to power them in the event of an outage." + maxcharge = 120 //Emergency lights use 0.2 W per tick, meaning ~10 minutes of emergency power from a cell + materials = list(MAT_GLASS = 20) + rating = 1 + w_class = WEIGHT_CLASS_TINY + +/obj/item/stock_parts/cell/emergency_light/Initialize() + . = ..() + var/area/A = get_area(src) + if(!A.lightswitch || !A.light_power) + charge = 0 //For naturally depowered areas, we start with no power diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 98fb2ed233..749dcb463e 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -2,7 +2,7 @@ // // consists of light fixtures (/obj/machinery/light) and light tube/bulb items (/obj/item/light) - +#define LIGHT_EMERGENCY_POWER_USE 0.2 //How much power emergency lights will consume per tick // status values shared between lighting fixtures and items #define LIGHT_OK 0 #define LIGHT_EMPTY 1 @@ -49,12 +49,22 @@ var/fixture_type = "tube" var/sheets_refunded = 2 var/obj/machinery/light/newlight = null + var/obj/item/stock_parts/cell/cell -/obj/structure/light_construct/New(loc, ndir, building) - ..() + var/cell_connectors = TRUE + +/obj/structure/light_construct/Initialize(mapload, ndir, building) + . = ..() if(building) setDir(ndir) +/obj/structure/light_construct/Destroy() + QDEL_NULL(cell) + return ..() + +/obj/structure/light_construct/get_cell() + return cell + /obj/structure/light_construct/examine(mob/user) ..() switch(src.stage) @@ -64,9 +74,38 @@ to_chat(user, "It's wired.") if(3) to_chat(user, "The casing is closed.") + if(cell_connectors) + if(cell) + to_chat(user, "You see [cell] inside the casing.") + else + to_chat(user, "The casing has no power cell for backup power.") + else + to_chat(user, "This casing doesn't support power cells for backup power.") + return /obj/structure/light_construct/attackby(obj/item/W, mob/user, params) add_fingerprint(user) + if(istype(W, /obj/item/stock_parts/cell)) + if(!cell_connectors) + to_chat(user, "This [name] can't support a power cell!") + return + if(W.flags_1 & NODROP_1) + to_chat(user, "[W] is stuck to your hand!") + return + user.dropItemToGround(W) + if(cell) + user.visible_message("[user] swaps [W] out for [src]'s cell.", \ + "You swap [src]'s power cells.") + cell.forceMove(drop_location()) + user.put_in_hands(cell) + else + user.visible_message("[user] hooks up [W] to [src].", \ + "You add [W] to [src].") + playsound(src, 'sound/machines/click.ogg', 50, TRUE) + W.forceMove(src) + cell = W + add_fingerprint(user) + return switch(stage) if(1) if(istype(W, /obj/item/wrench)) @@ -124,6 +163,10 @@ newlight = new /obj/machinery/light/small/built(loc) newlight.setDir(dir) transfer_fingerprints_to(newlight) + if(cell) + newlight.cell = cell + cell.forceMove(newlight) + cell = null qdel(src) return return ..() @@ -173,6 +216,11 @@ var/rigged = 0 // true if rigged to explode + var/obj/item/stock_parts/cell/cell + var/start_with_cell = TRUE // if true, this fixture generates a very weak cell at roundstart + var/emergency_mode = FALSE // if true, the light is in emergency mode + var/no_emergency = FALSE // if true, this light cannot ever have an emergency mode + // the smaller bulb light fixture /obj/machinery/light/small @@ -192,8 +240,10 @@ /obj/machinery/light/built icon_state = "tube-empty" + start_with_cell = FALSE -/obj/machinery/light/built/New() +/obj/machinery/light/built/Initialize() + . = ..() status = LIGHT_EMPTY update(0) ..() @@ -208,8 +258,10 @@ // create a new lighting fixture -/obj/machinery/light/New() - ..() +/obj/machinery/light/Initialize() + . = ..() + if(start_with_cell && !no_emergency) + cell = new/obj/item/stock_parts/cell/emergency_light(src) spawn(2) switch(fitting) if("tube") @@ -228,28 +280,30 @@ if(A) on = FALSE // A.update_lights() + QDEL_NULL(cell) return ..() /obj/machinery/light/update_icon() - switch(status) // set icon_states if(LIGHT_OK) - icon_state = "[base_state][on]" + if(emergency_mode) + icon_state = "[base_state]_emergency" + else + icon_state = "[base_state][on]" if(LIGHT_EMPTY) icon_state = "[base_state]-empty" - on = FALSE if(LIGHT_BURNED) icon_state = "[base_state]-burned" - on = FALSE if(LIGHT_BROKEN) icon_state = "[base_state]-broken" - on = FALSE return // update the icon_state and luminosity of the light depending on its state /obj/machinery/light/proc/update(trigger = 1) - - update_icon() + switch(status) + if(LIGHT_BROKEN,LIGHT_BURNED,LIGHT_EMPTY) + on = FALSE + emergency_mode = FALSE if(on) if(!light || light.light_range != brightness) switchcount++ @@ -261,10 +315,14 @@ burn_out() else use_power = ACTIVE_POWER_USE - set_light(brightness) + set_light(brightness, 1, "#FFFFFF") + else if(has_emergency_power(LIGHT_EMERGENCY_POWER_USE) && !turned_off()) + use_power = IDLE_POWER_USE + emergency_mode = TRUE else use_power = IDLE_POWER_USE set_light(0) + update_icon() active_power_usage = (brightness * 10) if(on != on_gs) @@ -276,6 +334,12 @@ removeStaticPower(static_power_used, STATIC_LIGHT) +/obj/machinery/light/process() + if(has_power() && cell) + cell.charge = min(cell.maxcharge, cell.charge + LIGHT_EMERGENCY_POWER_USE) //Recharge emergency power automatically while not using it + if(emergency_mode && !use_emergency_power(LIGHT_EMERGENCY_POWER_USE)) + update(FALSE) //Disables emergency mode and sets the color to normal + /obj/machinery/light/proc/burn_out() if(status == LIGHT_OK) status = LIGHT_BURNED @@ -289,6 +353,9 @@ on = (s && status == LIGHT_OK) update() +/obj/machinery/light/get_cell() + return cell + // examine verb /obj/machinery/light/examine(mob/user) ..() @@ -301,6 +368,8 @@ to_chat(user, "The [fitting] is burnt out.") if(LIGHT_BROKEN) to_chat(user, "The [fitting] has been smashed.") + if(cell) + to_chat(user, "Its backup power charge meter reads [(cell.charge / cell.maxcharge) * 100]%.") @@ -384,6 +453,10 @@ drop_light_tube() new /obj/item/stack/cable_coil(loc, 1, "red") transfer_fingerprints_to(newlight) + if(cell) + newlight.cell = cell + cell.forceMove(newlight) + cell = null qdel(src) /obj/machinery/light/attacked_by(obj/item/I, mob/living/user) @@ -415,6 +488,11 @@ if(BURN) playsound(src.loc, 'sound/items/welder.ogg', 100, 1) +// returns if the light has power /but/ is manually turned off +// if a light is turned off, it won't activate emergency power +/obj/machinery/light/proc/turned_off() + var/area/A = get_area(src) + return !A.lightswitch && A.power_light || !flickering // returns whether this light has power // true if area has power and lightswitch is on @@ -422,6 +500,27 @@ var/area/A = get_area(src) return A.lightswitch && A.power_light +// returns whether this light has emergency power +// can also return if it has access to a certain amount of that power +/obj/machinery/light/proc/has_emergency_power(pwr) + if(no_emergency || !cell) + return FALSE + if(pwr ? cell.charge >= pwr : cell.charge) + return status == LIGHT_OK + +// attempts to use power from the installed emergency cell, returns true if it does and false if it doesn't +/obj/machinery/light/proc/use_emergency_power(pwr = LIGHT_EMERGENCY_POWER_USE) + if(!has_emergency_power(pwr)) + return FALSE + if(cell.charge > 300) //it's meant to handle 120 W, ya doofus + visible_message("[src] short-circuits from too powerful of a power cell!") + burn_out() + return FALSE + cell.use(pwr) + set_light(brightness * 0.25, max(0.5, 0.75 * (cell.charge / cell.maxcharge)), "#FF3232") //RGB: 255, 50, 50 + return TRUE + + /obj/machinery/light/proc/flicker(var/amount = rand(10, 20)) set waitfor = 0 if(flickering) @@ -441,7 +540,9 @@ // ai attack - make lights flicker, because why not /obj/machinery/light/attack_ai(mob/user) - src.flicker(1) + no_emergency = !no_emergency + to_chat(user, "Emergency lights for this fixture have been [no_emergency ? "disabled" : "enabled"].") + update(FALSE) return // attack with hand - remove tube/bulb @@ -575,10 +676,11 @@ force = 2 throwforce = 5 w_class = WEIGHT_CLASS_TINY - var/status = 0 // LIGHT_OK, LIGHT_BURNED or LIGHT_BROKEN + var/status = LIGHT_OK // LIGHT_OK, LIGHT_BURNED or LIGHT_BROKEN var/base_state var/switchcount = 0 // number of times switched materials = list(MAT_GLASS=100) + grind_results = list("silicon" = 5, "nitrogen" = 10) //Nitrogen is used as a cheaper alternative to argon in incandescent lighbulbs var/rigged = 0 // true if rigged to explode var/brightness = 2 //how much light it gives off @@ -658,7 +760,7 @@ /obj/item/light/proc/shatter() if(status == LIGHT_OK || status == LIGHT_BURNED) - src.visible_message("[name] shatters.","You hear a small glass object shatter.") + visible_message("[name] shatters.","You hear a small glass object shatter.") status = LIGHT_BROKEN force = 5 playsound(src.loc, 'sound/effects/glasshit.ogg', 75, 1) diff --git a/code/modules/power/powernet.dm b/code/modules/power/powernet.dm index b6f61103ca..c34edc53f3 100644 --- a/code/modules/power/powernet.dm +++ b/code/modules/power/powernet.dm @@ -94,6 +94,6 @@ /datum/powernet/proc/get_electrocute_damage() if(avail >= 1000) - return Clamp(round(avail/10000), 10, 90) + rand(-5,5) + return CLAMP(round(avail/10000), 10, 90) + rand(-5,5) else return 0 \ No newline at end of file diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm index 0ede336ef6..a5e9db1fde 100644 --- a/code/modules/power/singularity/collector.dm +++ b/code/modules/power/singularity/collector.dm @@ -37,7 +37,7 @@ eject() else loaded_tank.air_contents.gases[/datum/gas/plasma][MOLES] -= 0.001*drainratio - ASSERT_GAS(/datum/gas/tritium,loaded_tank.air_contents) + loaded_tank.air_contents.assert_gas(/datum/gas/tritium) loaded_tank.air_contents.gases[/datum/gas/tritium][MOLES] += 0.001*drainratio loaded_tank.air_contents.garbage_collect() @@ -132,7 +132,7 @@ var/obj/item/tank/internals/plasma/Z = src.loaded_tank if (!Z) return - Z.loc = get_turf(src) + Z.forceMove(drop_location()) Z.layer = initial(Z.layer) Z.plane = initial(Z.plane) src.loaded_tank = null diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index 7596d890e0..1c5f0a3375 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -335,7 +335,7 @@ buckled_mob.pixel_x = 0 buckled_mob.pixel_y = 0 if(buckled_mob.client) - buckled_mob.client.change_view(world.view) + buckled_mob.client.change_view(CONFIG_GET(string/default_view)) auto.Remove(buckled_mob) . = ..() diff --git a/code/modules/power/singularity/field_generator.dm b/code/modules/power/singularity/field_generator.dm index 74aa140721..cdfbb35b34 100644 --- a/code/modules/power/singularity/field_generator.dm +++ b/code/modules/power/singularity/field_generator.dm @@ -285,9 +285,8 @@ field_generator power level display var/field_dir = get_dir(T,get_step(G.loc, NSEW)) T = get_step(T, NSEW) if(!locate(/obj/machinery/field/containment) in T) - var/obj/machinery/field/containment/CF = new/obj/machinery/field/containment() + var/obj/machinery/field/containment/CF = new(T) CF.set_master(src,G) - CF.loc = T CF.setDir(field_dir) fields += CF G.fields += CF diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm index 22712e970d..15b76d2641 100644 --- a/code/modules/power/singularity/narsie.dm +++ b/code/modules/power/singularity/narsie.dm @@ -47,8 +47,15 @@ /obj/singularity/narsie/large/cult/Initialize() . = ..() GLOB.cult_narsie = src - deltimer(GLOB.blood_target_reset_timer) - GLOB.blood_target = src + var/list/all_cults = list() + for(var/datum/antagonist/cult/C in GLOB.antagonists) + all_cults |= C.cult_team + for(var/datum/team/cult/T in all_cults) + deltimer(T.blood_target_reset_timer) + T.blood_target = src + var/datum/objective/eldergod/summon_objective = locate() in T.objectives + if(summon_objective) + summon_objective.summoned = TRUE for(var/datum/mind/cult_mind in SSticker.mode.cult) if(isliving(cult_mind.current)) var/mob/living/L = cult_mind.current diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index 70776b5c05..95b78ff0b5 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -227,7 +227,7 @@ /obj/machinery/power/smes/proc/chargedisplay() - return Clamp(round(5.5*charge/capacity),0,5) + return CLAMP(round(5.5*charge/capacity),0,5) /obj/machinery/power/smes/process() if(stat & BROKEN) @@ -382,7 +382,7 @@ target = text2num(target) . = TRUE if(.) - input_level = Clamp(target, 0, input_level_max) + input_level = CLAMP(target, 0, input_level_max) log_smes(usr.ckey) if("output") var/target = params["target"] @@ -404,7 +404,7 @@ target = text2num(target) . = TRUE if(.) - output_level = Clamp(target, 0, output_level_max) + output_level = CLAMP(target, 0, output_level_max) log_smes(usr.ckey) /obj/machinery/power/smes/proc/log_smes(user = "") diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index fb530f128f..af81b632d7 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -378,14 +378,14 @@ if("direction") var/adjust = text2num(params["adjust"]) if(adjust) - currentdir = Clamp((360 + adjust + currentdir) % 360, 0, 359) + currentdir = CLAMP((360 + adjust + currentdir) % 360, 0, 359) targetdir = currentdir set_panels(currentdir) . = TRUE if("rate") var/adjust = text2num(params["adjust"]) if(adjust) - trackrate = Clamp(trackrate + adjust, -7200, 7200) + trackrate = CLAMP(trackrate + adjust, -7200, 7200) if(trackrate) nexttime = world.time + 36000 / abs(trackrate) . = TRUE @@ -419,7 +419,7 @@ new /obj/item/shard( src.loc ) var/obj/item/circuitboard/computer/solar_control/M = new /obj/item/circuitboard/computer/solar_control( A ) for (var/obj/C in src) - C.loc = src.loc + C.forceMove(drop_location()) A.circuit = M A.state = 3 A.icon_state = "3" @@ -430,7 +430,7 @@ var/obj/structure/frame/computer/A = new /obj/structure/frame/computer( src.loc ) var/obj/item/circuitboard/computer/solar_control/M = new /obj/item/circuitboard/computer/solar_control( A ) for (var/obj/C in src) - C.loc = src.loc + C.forceMove(drop_location()) A.circuit = M A.state = 4 A.icon_state = "4" diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index de67f837f4..5f9f6042d3 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -258,7 +258,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) return //Yeah just stop. if(power) - soundloop.volume = min(50, (round(power, 50)/50)+1) // 5 +1 volume per 20 power. 2500 power is max + soundloop.volume = min(40, (round(power/100)/50)+1) // 5 +1 volume per 20 power. 2500 power is max //Ok, get the air from the turf var/datum/gas_mixture/env = T.return_air() @@ -317,10 +317,10 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) mole_heat_penalty = max(combined_gas / MOLE_HEAT_PENALTY, 0.25) if (combined_gas > POWERLOSS_INHIBITION_MOLE_THRESHOLD && co2comp > POWERLOSS_INHIBITION_GAS_THRESHOLD) - powerloss_dynamic_scaling = Clamp(powerloss_dynamic_scaling + Clamp(co2comp - powerloss_dynamic_scaling, -0.02, 0.02), 0, 1) + powerloss_dynamic_scaling = CLAMP(powerloss_dynamic_scaling + CLAMP(co2comp - powerloss_dynamic_scaling, -0.02, 0.02), 0, 1) else - powerloss_dynamic_scaling = Clamp(powerloss_dynamic_scaling - 0.05,0, 1) - powerloss_inhibitor = Clamp(1-(powerloss_dynamic_scaling * Clamp(combined_gas/POWERLOSS_INHIBITION_MOLE_BOOST_THRESHOLD,1 ,1.5)),0 ,1) + powerloss_dynamic_scaling = CLAMP(powerloss_dynamic_scaling - 0.05,0, 1) + powerloss_inhibitor = CLAMP(1-(powerloss_dynamic_scaling * CLAMP(combined_gas/POWERLOSS_INHIBITION_MOLE_BOOST_THRESHOLD,1 ,1.5)),0 ,1) if(matter_power) var/removed_matter = max(matter_power/MATTER_POWER_CONVERSION, 40) @@ -368,7 +368,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) if(!istype(l.glasses, /obj/item/clothing/glasses/meson)) var/D = sqrt(1 / max(1, get_dist(l, src))) l.hallucination += power * config_hallucination_power * D - l.hallucination = Clamp(0, 200, l.hallucination) + l.hallucination = CLAMP(0, 200, l.hallucination) for(var/mob/living/l in range(src, round((power / 100) ** 0.25))) var/rads = (power / 10) * sqrt( 1 / max(get_dist(l, src),1) ) @@ -386,7 +386,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard) supermatter_zap(src, 5, min(power*2, 20000)) else if (damage > damage_penalty_point && prob(20)) playsound(src.loc, 'sound/weapons/emitter2.ogg', 100, 1, extrarange = 10) - supermatter_zap(src, 5, Clamp(power*2, 4000, 20000)) + supermatter_zap(src, 5, CLAMP(power*2, 4000, 20000)) if(prob(15) && power > POWER_PENALTY_THRESHOLD) supermatter_pull(src, power/750) diff --git a/code/modules/power/tesla/coil.dm b/code/modules/power/tesla/coil.dm index 57ec453863..a0977d93e3 100644 --- a/code/modules/power/tesla/coil.dm +++ b/code/modules/power/tesla/coil.dm @@ -103,8 +103,6 @@ buckle_lying = FALSE buckle_requires_restraints = TRUE - circuit = /obj/item/circuitboard/machine/grounding_rod - /obj/machinery/power/grounding_rod/default_unfasten_wrench(mob/user, obj/item/wrench/W, time = 20) . = ..() if(. == SUCCESSFUL_UNFASTEN) diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index 4a26950217..51cb99a34f 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -62,7 +62,7 @@ pixel_x = -32 pixel_y = -32 for (var/ball in orbiting_balls) - var/range = rand(1, Clamp(orbiting_balls.len, 3, 7)) + var/range = rand(1, CLAMP(orbiting_balls.len, 3, 7)) tesla_zap(ball, range, TESLA_MINI_POWER/7*range, TRUE) else energy = 0 // ensure we dont have miniballs of miniballs @@ -268,7 +268,7 @@ closest_grounding_rod.tesla_act(power, explosive, stun_mobs) else if(closest_mob) - var/shock_damage = Clamp(round(power/400), 10, 90) + rand(-5, 5) + var/shock_damage = CLAMP(round(power/400), 10, 90) + rand(-5, 5) closest_mob.electrocute_act(shock_damage, source, 1, tesla_shock = 1, stun = stun_mobs) if(issilicon(closest_mob)) var/mob/living/silicon/S = closest_mob diff --git a/code/modules/power/tracker.dm b/code/modules/power/tracker.dm index 5e129acf8f..a46627b7ca 100644 --- a/code/modules/power/tracker.dm +++ b/code/modules/power/tracker.dm @@ -47,7 +47,7 @@ S.glass_type = /obj/item/stack/sheet/glass S.tracker = 1 S.anchored = TRUE - S.loc = src + S.forceMove(src) update_icon() //updates the tracker icon and the facing angle for the control computer @@ -94,4 +94,4 @@ // Tracker Electronic /obj/item/electronics/tracker - name = "tracker electronics" \ No newline at end of file + name = "tracker electronics" diff --git a/code/modules/power/turbine.dm b/code/modules/power/turbine.dm index ac664894de..5c463b4ee9 100644 --- a/code/modules/power/turbine.dm +++ b/code/modules/power/turbine.dm @@ -75,7 +75,6 @@ // The inlet of the compressor is the direction it faces gas_contained = new inturf = get_step(src, dir) - locate_machinery() if(!turbine) stat |= BROKEN @@ -344,10 +343,10 @@ /obj/machinery/computer/turbine_computer/ui_data(mob/user) var/list/data = list() - data["working"] = (compressor.starter && compressor && compressor.turbine && !compressor.stat && !compressor.turbine.stat) data["connected"] = (compressor && compressor.turbine) ? TRUE : FALSE - data["compressor_broke"] = (!compressor || compressor.stat) ? TRUE : FALSE - data["turbine_broke"] = (!compressor || compressor.turbine.stat) ? TRUE : FALSE + data["compressor_broke"] = (!compressor || (compressor.stat & BROKEN)) ? TRUE : FALSE + data["turbine_broke"] = (!compressor || !compressor.turbine || (compressor.turbine.stat & BROKEN)) ? TRUE : FALSE + data["broken"] = (data["compressor_broke"] || data["turbine_broke"]) data["online"] = compressor.starter data["power"] = DisplayPower(compressor.turbine.lastgen) @@ -360,9 +359,13 @@ if(..()) return switch(action) - if("power") + if("power-on") if(compressor && compressor.turbine) - compressor.starter = !compressor.starter + compressor.starter = TRUE + . = TRUE + if("power-off") + if(compressor && compressor.turbine) + compressor.starter = FALSE . = TRUE if("reconnect") locate_machinery() diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index 71befb50f1..4e341fa2a4 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -17,6 +17,7 @@ var/delay = 0 //Delay for energy weapons var/click_cooldown_override = 0 //Override this to make your gun have a faster fire rate, in tenths of a second. 4 is the default gun cooldown. var/firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect //the visual effect appearing when the ammo is fired. + var/heavy_metal = TRUE /obj/item/ammo_casing/New() @@ -58,3 +59,47 @@ to_chat(user, "You fail to collect anything!") else return ..() + +/obj/item/ammo_casing/throw_impact(atom/A) + if(heavy_metal) + bounce_away(FALSE, NONE) + . = ..() + +/obj/item/ammo_casing/proc/bounce_away(still_warm = FALSE, delay = 3) + SpinAnimation(10, 1) + update_icon() + var/turf/T = get_turf(src) + if(still_warm && T && (is_type_in_typecache(T, GLOB.bullet_bounce_away_sizzle))) + addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, src, 'sound/items/welder.ogg', 20, 1), delay) + else if(T && (!is_type_in_typecache(T, GLOB.bullet_bounce_away_blacklist))) + addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, src, 'sound/weapons/bulletremove.ogg', 60, 1), delay) + +GLOBAL_LIST_INIT(bullet_bounce_away_sizzle, typecacheof(list( + /turf/closed/indestructible/rock/snow, + /turf/closed/wall/ice, + /turf/closed/wall/mineral/snow, + /turf/open/floor/grass/snow, + /turf/open/floor/holofloor/snow, + /turf/open/floor/plating/asteroid/snow, + /turf/open/floor/plating/ice, + /turf/open/water))) + +GLOBAL_LIST_INIT(bullet_bounce_away_blacklist, typecacheof(list( + /turf/closed/indestructible/rock/snow, + /turf/closed/indestructible/splashscreen, + /turf/closed/wall/mineral/snow, + /turf/open/chasm, + /turf/open/floor/carpet, + /turf/open/floor/grass, + /turf/open/floor/holofloor/beach, + /turf/open/floor/holofloor/carpet, + /turf/open/floor/holofloor/grass, + /turf/open/floor/holofloor/hyperspace, + /turf/open/floor/holofloor/snow, + /turf/open/floor/plating/asteroid/snow, + /turf/open/floor/plating/beach, + /turf/open/indestructible/reebe_void, + /turf/open/lava, + /turf/open/space, + /turf/open/water, + /turf/template_noop))) diff --git a/code/modules/projectiles/ammunition/ammo_casings.dm b/code/modules/projectiles/ammunition/ammo_casings.dm index d51ea36e15..edd28e72a8 100644 --- a/code/modules/projectiles/ammunition/ammo_casings.dm +++ b/code/modules/projectiles/ammunition/ammo_casings.dm @@ -284,9 +284,9 @@ icon_state = "cshell" projectile_type = /obj/item/projectile/bullet/dart -/obj/item/ammo_casing/shotgun/dart/New() - ..() - container_type |= OPENCONTAINER_1 +/obj/item/ammo_casing/shotgun/dart/Initialize() + . = ..() + container_type |= OPENCONTAINER create_reagents(30) reagents.set_reacting(TRUE) @@ -302,4 +302,4 @@ reagents.add_reagent("spore", 6) reagents.add_reagent("mutetoxin", 6) //;HELP OPS IN MAINT reagents.add_reagent("coniine", 6) - reagents.add_reagent("sodium_thiopental", 6) \ No newline at end of file + reagents.add_reagent("sodium_thiopental", 6) diff --git a/code/modules/projectiles/ammunition/caseless.dm b/code/modules/projectiles/ammunition/caseless.dm index e5b905019d..b3439c86b2 100644 --- a/code/modules/projectiles/ammunition/caseless.dm +++ b/code/modules/projectiles/ammunition/caseless.dm @@ -4,10 +4,11 @@ /obj/item/ammo_casing/caseless desc = "A caseless bullet casing." firing_effect_type = null + heavy_metal = FALSE /obj/item/ammo_casing/caseless/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread) if (..()) //successfully firing - loc = null + moveToNullspace() return 1 else return 0 diff --git a/code/modules/projectiles/ammunition/energy.dm b/code/modules/projectiles/ammunition/energy.dm index dcd9d356ad..40c198ec4e 100644 --- a/code/modules/projectiles/ammunition/energy.dm +++ b/code/modules/projectiles/ammunition/energy.dm @@ -7,6 +7,7 @@ var/select_name = "energy" fire_sound = 'sound/weapons/laser.ogg' firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/energy + heavy_metal = FALSE /obj/item/ammo_casing/energy/chameleon projectile_type = /obj/item/projectile/energy/chameleon diff --git a/code/modules/projectiles/ammunition/special.dm b/code/modules/projectiles/ammunition/special.dm index 11fd12da70..de103b399e 100644 --- a/code/modules/projectiles/ammunition/special.dm +++ b/code/modules/projectiles/ammunition/special.dm @@ -3,6 +3,7 @@ desc = "I didn't even know magic needed ammo..." projectile_type = /obj/item/projectile/magic firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/magic + heavy_metal = FALSE /obj/item/ammo_casing/magic/change projectile_type = /obj/item/projectile/magic/change diff --git a/code/modules/projectiles/box_magazine.dm b/code/modules/projectiles/box_magazine.dm index 324470ede4..bf941108ff 100644 --- a/code/modules/projectiles/box_magazine.dm +++ b/code/modules/projectiles/box_magazine.dm @@ -87,7 +87,7 @@ if(num_loaded) if(!silent) to_chat(user, "You load [num_loaded] shell\s into \the [src]!") - playsound(user, 'sound/weapons/bulletinsert.ogg', 60, 1) + playsound(src, 'sound/weapons/bulletinsert.ogg', 60, 1) A.update_icon() update_icon() @@ -96,9 +96,10 @@ /obj/item/ammo_box/attack_self(mob/user) var/obj/item/ammo_casing/A = get_round() if(A) - user.put_in_hands(A) + if(!user.put_in_hands(A)) + A.bounce_away(FALSE, NONE) + playsound(src, 'sound/weapons/bulletinsert.ogg', 60, 1) to_chat(user, "You remove a round from \the [src]!") - playsound(user, 'sound/weapons/bulletremove.ogg', 60, 1) update_icon() /obj/item/ammo_box/update_icon() diff --git a/code/modules/projectiles/boxes_magazines/ammo_boxes.dm b/code/modules/projectiles/boxes_magazines/ammo_boxes.dm index 50769b926e..73f8379baf 100644 --- a/code/modules/projectiles/boxes_magazines/ammo_boxes.dm +++ b/code/modules/projectiles/boxes_magazines/ammo_boxes.dm @@ -17,21 +17,18 @@ /obj/item/ammo_box/c9mm name = "ammo box (9mm)" icon_state = "9mmbox" - origin_tech = "combat=2" ammo_type = /obj/item/ammo_casing/c9mm max_ammo = 30 /obj/item/ammo_box/c10mm name = "ammo box (10mm)" icon_state = "10mmbox" - origin_tech = "combat=2" ammo_type = /obj/item/ammo_casing/c10mm max_ammo = 20 /obj/item/ammo_box/c45 name = "ammo box (.45)" icon_state = "45box" - origin_tech = "combat=2" ammo_type = /obj/item/ammo_casing/c45 max_ammo = 20 @@ -53,7 +50,6 @@ /obj/item/ammo_box/n762 name = "ammo box (7.62x38mmR)" icon_state = "10mmbox" - origin_tech = "combat=2" ammo_type = /obj/item/ammo_casing/n762 max_ammo = 14 diff --git a/code/modules/projectiles/boxes_magazines/external_mag.dm b/code/modules/projectiles/boxes_magazines/external_mag.dm index f288482349..b7b3a3e286 100644 --- a/code/modules/projectiles/boxes_magazines/external_mag.dm +++ b/code/modules/projectiles/boxes_magazines/external_mag.dm @@ -5,7 +5,6 @@ name = "pistol magazine (10mm)" desc = "A gun magazine." icon_state = "9x19p" - origin_tech = "combat=2" ammo_type = /obj/item/ammo_casing/c10mm caliber = "10mm" max_ammo = 8 @@ -15,7 +14,6 @@ name = "rifle magazine (10mm)" desc = "A well-worn magazine fitted for the surplus rifle." icon_state = "75-8" - origin_tech = "combat=2" ammo_type = /obj/item/ammo_casing/c10mm caliber = "10mm" max_ammo = 10 @@ -129,7 +127,6 @@ /obj/item/ammo_box/magazine/smgm45 name = "SMG magazine (.45)" icon_state = "c20r45-24" - origin_tech = "combat=2" ammo_type = /obj/item/ammo_casing/c45/nostamina caliber = ".45" max_ammo = 24 @@ -148,7 +145,6 @@ /obj/item/ammo_box/magazine/m50 name = "handgun magazine (.50ae)" icon_state = "50ae" - origin_tech = "combat=2" ammo_type = /obj/item/ammo_casing/a50AE caliber = ".50" max_ammo = 7 @@ -165,7 +161,6 @@ /obj/item/ammo_box/magazine/m556 name = "toploader magazine (5.56mm)" icon_state = "5.56m" - origin_tech = "combat=5;syndicate=1" ammo_type = /obj/item/ammo_casing/a556 caliber = "a556" max_ammo = 30 @@ -176,13 +171,12 @@ desc = "A drum magazine." icon_state = "m12gs" ammo_type = /obj/item/ammo_casing/shotgun/stunslug - origin_tech = "combat=3;syndicate=1" caliber = "shotgun" max_ammo = 8 /obj/item/ammo_box/magazine/m12g/update_icon() ..() - icon_state = "[initial(icon_state)]-[Ceiling(ammo_count(0)/8)*8]" + icon_state = "[initial(icon_state)]-[CEILING(ammo_count(0)/8, 1)*8]" /obj/item/ammo_box/magazine/m12g/buckshot name = "shotgun magazine (12g buckshot slugs)" @@ -215,7 +209,6 @@ /obj/item/ammo_box/magazine/sniper_rounds name = "sniper rounds (.50)" icon_state = ".50mag" - origin_tech = "combat=6;syndicate=2" ammo_type = /obj/item/ammo_casing/p50 max_ammo = 6 caliber = ".50" @@ -230,7 +223,6 @@ name = "sniper rounds (Zzzzz)" desc = "Soporific sniper rounds, designed for happy days and dead quiet nights..." icon_state = "soporific" - origin_tech = "combat=6;syndicate=3" ammo_type = /obj/item/ammo_casing/p50/soporific max_ammo = 3 caliber = ".50" @@ -239,7 +231,6 @@ name = "sniper rounds (penetrator)" desc = "An extremely powerful round capable of passing straight through cover and anyone unfortunate enough to be behind it." ammo_type = /obj/item/ammo_casing/p50/penetrator - origin_tech = "combat=6;syndicate=3" max_ammo = 5 //// SAW MAGAZINES @@ -247,24 +238,20 @@ /obj/item/ammo_box/magazine/mm195x129 name = "box magazine (1.95x129mm)" icon_state = "a762-50" - origin_tech = "combat=2" ammo_type = /obj/item/ammo_casing/mm195x129 caliber = "mm195129" max_ammo = 50 /obj/item/ammo_box/magazine/mm195x129/hollow name = "box magazine (Hollow-Point 1.95x129mm)" - origin_tech = "combat=3" ammo_type = /obj/item/ammo_casing/mm195x129/hollow /obj/item/ammo_box/magazine/mm195x129/ap name = "box magazine (Armor Penetrating 1.95x129mm)" - origin_tech = "combat=4" ammo_type = /obj/item/ammo_casing/mm195x129/ap /obj/item/ammo_box/magazine/mm195x129/incen name = "box magazine (Incendiary 1.95x129mm)" - origin_tech = "combat=4" ammo_type = /obj/item/ammo_casing/mm195x129/incen /obj/item/ammo_box/magazine/mm195x129/update_icon() diff --git a/code/modules/projectiles/boxes_magazines/internal_mag.dm b/code/modules/projectiles/boxes_magazines/internal_mag.dm index 3a8b4e6f2f..f486be732d 100644 --- a/code/modules/projectiles/boxes_magazines/internal_mag.dm +++ b/code/modules/projectiles/boxes_magazines/internal_mag.dm @@ -51,10 +51,10 @@ var/obj/item/ammo_casing/bullet = stored_ammo[i] if(!bullet || !bullet.BB) // found a spent ammo stored_ammo[i] = R - R.loc = src + R.forceMove(src) if(bullet) - bullet.loc = get_turf(src.loc) + bullet.forceMove(drop_location()) return 1 return 0 diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 085c618c42..ff7ed7653e 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -15,9 +15,8 @@ throw_speed = 3 throw_range = 5 force = 5 - origin_tech = "combat=1" - needs_permit = 1 - unique_rename = 0 + needs_permit = TRUE + unique_rename = FALSE attack_verb = list("struck", "hit", "bashed") var/fire_sound = "gunshot" @@ -78,9 +77,8 @@ ..() var/obj/item/gun/G = locate(/obj/item/gun) in contents if(G) - G.loc = loc - qdel(G.pin) - G.pin = null + G.forceMove(loc) + QDEL_NULL(G.pin) visible_message("[G] can now fit a new pin, but the old one was destroyed in the process.", null, null, 3) qdel(src) @@ -109,7 +107,7 @@ /obj/item/gun/proc/shoot_with_empty_chamber(mob/living/user as mob|obj) to_chat(user, "*click*") - playsound(user, 'sound/weapons/empty.ogg', 100, 1) + playsound(src, "gun_dry_fire", 30, 1) /obj/item/gun/proc/shoot_live_shot(mob/living/user as mob|obj, pointblank = 0, mob/pbtarget = null, message = 1) @@ -500,7 +498,7 @@ user.client.pixel_x = world.icon_size*_x user.client.pixel_y = world.icon_size*_y else - user.client.change_view(world.view) + user.client.change_view(CONFIG_GET(string/default_view)) user.client.pixel_x = 0 user.client.pixel_y = 0 return zoomed diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index b7db29084a..680c86ff5c 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -2,7 +2,6 @@ desc = "Now comes in flavors like GUN. Uses 10mm ammo, for some reason." name = "projectile gun" icon_state = "pistol" - origin_tech = "combat=2;materials=2" w_class = WEIGHT_CLASS_NORMAL var/spawnwithmagazine = TRUE var/mag_type = /obj/item/ammo_box/magazine/m10mm //Removes the need for max_ammo and caliber info @@ -31,8 +30,8 @@ var/obj/item/ammo_casing/AC = chambered //Find chambered round if(istype(AC)) //there's a chambered round if(casing_ejector) - AC.forceMove(get_turf(src)) //Eject casing onto ground. - AC.SpinAnimation(10, 1) //next gen special effects + AC.forceMove(drop_location()) //Eject casing onto ground. + AC.bounce_away(TRUE) chambered = null else if(empty_chamber) chambered = null @@ -59,7 +58,13 @@ if(user.transferItemToLoc(AM, src)) magazine = AM to_chat(user, "You load a new magazine into \the [src].") - chamber_round() + if(magazine.ammo_count()) + playsound(src, "gun_insert_full_magazine", 70, 1) + if(!chambered) + chamber_round() + addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, src, 'sound/weapons/gun_chamber_round.ogg', 100, 1), 3) + else + playsound(src, "gun_insert_empty_magazine", 70, 1) A.update_icon() update_icon() return 1 @@ -108,16 +113,21 @@ /obj/item/gun/ballistic/attack_self(mob/living/user) var/obj/item/ammo_casing/AC = chambered //Find chambered round if(magazine) - magazine.loc = get_turf(src.loc) + magazine.forceMove(drop_location()) user.put_in_hands(magazine) magazine.update_icon() + if(magazine.ammo_count()) + playsound(src, "sound/weapons/gun_magazine_remove_full.ogg", 70, 1) + else + playsound(src, "gun_remove_empty_magazine", 70, 1) magazine = null to_chat(user, "You pull the magazine out of \the [src].") else if(chambered) - AC.loc = get_turf(src) - AC.SpinAnimation(10, 1) + AC.forceMove(drop_location()) + AC.bounce_away() chambered = null to_chat(user, "You unload the round from \the [src]'s chamber.") + playsound(src, "gun_slide_lock", 70, 1) else to_chat(user, "There's no magazine in \the [src].") update_icon() @@ -163,7 +173,7 @@ return(OXYLOSS) else user.visible_message("[user] is pretending to blow [user.p_their()] brain[user.p_s()] out with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(loc, 'sound/weapons/empty.ogg', 50, 1, -1) + playsound(src, "gun_dry_fire", 30, 1) return (OXYLOSS) #undef BRAINS_BLOWN_THROW_SPEED #undef BRAINS_BLOWN_THROW_RANGE @@ -217,4 +227,3 @@ desc = "A foreign knock-off suppressor, it feels flimsy, cheap, and brittle. Still fits all weapons." icon = 'icons/obj/guns/projectile.dmi' icon_state = "suppressor" - diff --git a/code/modules/projectiles/guns/ballistic/automatic.dm b/code/modules/projectiles/guns/ballistic/automatic.dm index 7fc37b8c56..9724f9be01 100644 --- a/code/modules/projectiles/guns/ballistic/automatic.dm +++ b/code/modules/projectiles/guns/ballistic/automatic.dm @@ -1,5 +1,4 @@ /obj/item/gun/ballistic/automatic - origin_tech = "combat=4;materials=2" w_class = WEIGHT_CLASS_NORMAL var/alarmed = 0 var/select = 1 @@ -89,7 +88,6 @@ desc = "A bullpup two-round burst .45 SMG, designated 'C-20r'. Has a 'Scarborough Arms - Per falcis, per pravitas' buttstamp." icon_state = "c20r" item_state = "c20r" - origin_tech = "combat=5;materials=2;syndicate=6" mag_type = /obj/item/ammo_box/magazine/smgm45 fire_sound = 'sound/weapons/gunshot_smg.ogg' fire_delay = 2 @@ -110,7 +108,7 @@ /obj/item/gun/ballistic/automatic/c20r/update_icon() ..() - icon_state = "c20r[magazine ? "-[Ceiling(get_ammo(0)/4)*4]" : ""][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" + icon_state = "c20r[magazine ? "-[CEILING(get_ammo(0)/4, 1)*4]" : ""][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" /obj/item/gun/ballistic/automatic/wt550 name = "security auto rifle" @@ -125,13 +123,12 @@ /obj/item/gun/ballistic/automatic/wt550/update_icon() ..() - icon_state = "wt550[magazine ? "-[Ceiling(get_ammo(0)/4)*4]" : ""]" + icon_state = "wt550[magazine ? "-[CEILING(get_ammo(0)/4, 1)*4]" : ""]" /obj/item/gun/ballistic/automatic/mini_uzi name = "\improper Type U3 Uzi" desc = "A lightweight, burst-fire submachine gun, for when you really want someone dead. Uses 9mm rounds." icon_state = "mini-uzi" - origin_tech = "combat=4;materials=2;syndicate=4" mag_type = /obj/item/ammo_box/magazine/uzim9mm burst_size = 2 @@ -140,7 +137,6 @@ desc = "A three-round burst 5.56 toploading carbine, designated 'M-90gl'. Has an attached underbarrel grenade launcher which can be toggled on and off." icon_state = "m90" item_state = "m90" - origin_tech = "combat=5;materials=2;syndicate=6" mag_type = /obj/item/ammo_box/magazine/m556 fire_sound = 'sound/weapons/gunshot_smg.ogg' can_suppress = FALSE @@ -214,7 +210,6 @@ item_state = "shotgun" w_class = WEIGHT_CLASS_HUGE slot_flags = 0 - origin_tech = "combat=5;materials=1;syndicate=3" mag_type = /obj/item/ammo_box/magazine/tommygunm45 fire_sound = 'sound/weapons/gunshot_smg.ogg' can_suppress = FALSE @@ -223,11 +218,10 @@ /obj/item/gun/ballistic/automatic/ar name = "\improper NT-ARG 'Boarder'" - desc = "A robust assault rile used by Nanotrasen fighting forces." + desc = "A robust assault rifle used by Nanotrasen fighting forces." icon_state = "arg" item_state = "arg" slot_flags = 0 - origin_tech = "combat=6;engineering=4" mag_type = /obj/item/ammo_box/magazine/m556 fire_sound = 'sound/weapons/gunshot_smg.ogg' can_suppress = FALSE @@ -243,7 +237,6 @@ item_state = "bulldog" w_class = WEIGHT_CLASS_NORMAL weapon_weight = WEAPON_MEDIUM - origin_tech = "combat=6;materials=4;syndicate=6" mag_type = /obj/item/ammo_box/magazine/m12g fire_sound = 'sound/weapons/gunshot.ogg' can_suppress = FALSE @@ -281,7 +274,6 @@ item_state = "l6closedmag" w_class = WEIGHT_CLASS_HUGE slot_flags = 0 - origin_tech = "combat=6;engineering=3;syndicate=6" mag_type = /obj/item/ammo_box/magazine/mm195x129 weapon_weight = WEAPON_HEAVY fire_sound = 'sound/weapons/gunshot_smg.ogg' @@ -312,7 +304,7 @@ /obj/item/gun/ballistic/automatic/l6_saw/update_icon() - icon_state = "l6[cover_open ? "open" : "closed"][magazine ? Ceiling(get_ammo(0)/12.5)*25 : "-empty"][suppressed ? "-suppressed" : ""]" + icon_state = "l6[cover_open ? "open" : "closed"][magazine ? CEILING(get_ammo(0)/12.5, 1)*25 : "-empty"][suppressed ? "-suppressed" : ""]" item_state = "l6[cover_open ? "openmag" : "closedmag"]" @@ -333,7 +325,7 @@ else if(cover_open && magazine) //drop the mag magazine.update_icon() - magazine.loc = get_turf(src.loc) + magazine.forceMove(drop_location()) user.put_in_hands(magazine) magazine = null update_icon() @@ -361,7 +353,6 @@ mag_type = /obj/item/ammo_box/magazine/sniper_rounds fire_delay = 40 burst_size = 1 - origin_tech = "combat=7" can_unsuppress = TRUE can_suppress = TRUE w_class = WEIGHT_CLASS_NORMAL @@ -382,14 +373,12 @@ name = "syndicate sniper rifle" desc = "An illegally modified .50 cal sniper rifle with suppression compatibility. Quickscoping still doesn't work." pin = /obj/item/device/firing_pin/implant/pindicate - origin_tech = "combat=7;syndicate=6" // Old Semi-Auto Rifle // /obj/item/gun/ballistic/automatic/surplus name = "Surplus Rifle" desc = "One of countless obsolete ballistic rifles that still sees use as a cheap deterrent. Uses 10mm ammo and its bulky frame prevents one-hand firing." - origin_tech = "combat=3;materials=2" icon_state = "surplus" item_state = "moistnugget" weapon_weight = WEAPON_HEAVY @@ -426,5 +415,5 @@ /obj/item/gun/ballistic/automatic/laser/update_icon() ..() - icon_state = "oldrifle[magazine ? "-[Ceiling(get_ammo(0)/4)*4]" : ""]" + icon_state = "oldrifle[magazine ? "-[CEILING(get_ammo(0)/4, 1)*4]" : ""]" return diff --git a/code/modules/projectiles/guns/ballistic/laser_gatling.dm b/code/modules/projectiles/guns/ballistic/laser_gatling.dm index f7b5b4cd61..2dc6dd9857 100644 --- a/code/modules/projectiles/guns/ballistic/laser_gatling.dm +++ b/code/modules/projectiles/guns/ballistic/laser_gatling.dm @@ -97,7 +97,6 @@ icon = 'icons/obj/guns/minigun.dmi' icon_state = "minigun_spin" item_state = "minigun" - origin_tech = "combat=6;powerstorage=5;magnets=4" flags_1 = CONDUCT_1 slowdown = 1 slot_flags = null diff --git a/code/modules/projectiles/guns/ballistic/launchers.dm b/code/modules/projectiles/guns/ballistic/launchers.dm index a32d78bb2e..01e323e1a7 100644 --- a/code/modules/projectiles/guns/ballistic/launchers.dm +++ b/code/modules/projectiles/guns/ballistic/launchers.dm @@ -35,7 +35,6 @@ desc = "A prototype pistol designed to fire self propelled rockets." icon_state = "gyropistol" fire_sound = 'sound/weapons/grenadelaunch.ogg' - origin_tech = "combat=5" mag_type = /obj/item/ammo_box/magazine/m75 burst_size = 1 fire_delay = 0 @@ -52,7 +51,6 @@ icon_state = "speargun" item_state = "speargun" w_class = WEIGHT_CLASS_BULKY - origin_tech = "combat=4;engineering=4" force = 10 can_suppress = FALSE mag_type = /obj/item/ammo_box/magazine/internal/speargun diff --git a/code/modules/projectiles/guns/ballistic/pistol.dm b/code/modules/projectiles/guns/ballistic/pistol.dm index 06bb452b0b..569040745f 100644 --- a/code/modules/projectiles/guns/ballistic/pistol.dm +++ b/code/modules/projectiles/guns/ballistic/pistol.dm @@ -3,7 +3,6 @@ desc = "A small, easily concealable 10mm handgun. Has a threaded barrel for suppressors." icon_state = "pistol" w_class = WEIGHT_CLASS_SMALL - origin_tech = "combat=3;materials=2;syndicate=4" mag_type = /obj/item/ammo_box/magazine/m10mm can_suppress = TRUE burst_size = 1 @@ -55,7 +54,6 @@ desc = "The original russian version of a widely used Syndicate sidearm. Uses 9mm ammo." icon_state = "aps" w_class = WEIGHT_CLASS_SMALL - origin_tech = "combat=3;materials=2;syndicate=3" mag_type = /obj/item/ammo_box/magazine/pistolm9mm can_suppress = FALSE burst_size = 3 @@ -66,7 +64,6 @@ name = "flat gun" desc = "A 2 dimensional gun.. what?" icon_state = "flatgun" - origin_tech = "combat=3;materials=2;abductor=3" /obj/item/gun/ballistic/automatic/pistol/stickman/pickup(mob/living/user) to_chat(user, "As you try to pick up [src], it slips out of your grip..") diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm index 584445a573..563b3d9ad5 100644 --- a/code/modules/projectiles/guns/ballistic/revolver.dm +++ b/code/modules/projectiles/guns/ballistic/revolver.dm @@ -3,7 +3,6 @@ desc = "A suspicious revolver. Uses .357 ammo." //usually used by syndicates icon_state = "revolver" mag_type = /obj/item/ammo_box/magazine/internal/cylinder - origin_tech = "combat=3;materials=2" casing_ejector = FALSE /obj/item/gun/ballistic/revolver/Initialize() @@ -40,13 +39,11 @@ var/obj/item/ammo_casing/CB CB = magazine.get_round(0) if(CB) - CB.loc = get_turf(src.loc) - CB.SpinAnimation(10, 1) - CB.update_icon() + CB.forceMove(drop_location()) + CB.bounce_away(FALSE, NONE) num_unloaded++ if (num_unloaded) to_chat(user, "You unload [num_unloaded] shell\s from [src].") - playsound(user, 'sound/weapons/bulletremove.ogg', 60, 1) else to_chat(user, "[src] is empty!") @@ -158,8 +155,8 @@ name = "nagant revolver" desc = "An old model of revolver that originated in Russia. Able to be suppressed. Uses 7.62x38mmR ammo." icon_state = "nagant" - origin_tech = "combat=3" can_suppress = TRUE + mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev762 @@ -169,7 +166,6 @@ /obj/item/gun/ballistic/revolver/russian name = "\improper russian revolver" desc = "A Russian-made revolver for drinking games. Uses .357 ammo, and has a mechanism requiring you to spin the chamber before each trigger pull." - origin_tech = "combat=2;materials=2" mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rus357 var/spun = FALSE @@ -231,7 +227,7 @@ return user.visible_message("*click*") - playsound(user, 'sound/weapons/empty.ogg', 100, 1) + playsound(src, "gun_dry_fire", 30, 1) /obj/item/gun/ballistic/revolver/russian/proc/shoot_self(mob/living/carbon/human/user, affecting = "head") user.apply_damage(300, BRUTE, affecting) @@ -291,7 +287,7 @@ var/obj/item/ammo_casing/CB CB = magazine.get_round(0) chambered = null - CB.loc = get_turf(src.loc) + CB.forceMove(drop_location()) CB.update_icon() num_unloaded++ if (num_unloaded) diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm index 105e170429..e702013233 100644 --- a/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -7,7 +7,6 @@ force = 10 flags_1 = CONDUCT_1 slot_flags = SLOT_BACK - origin_tech = "combat=4;materials=2" mag_type = /obj/item/ammo_box/magazine/internal/shot casing_ejector = FALSE var/recentpump = 0 // to prevent spammage @@ -57,8 +56,8 @@ /obj/item/gun/ballistic/shotgun/proc/pump_unload(mob/M) if(chambered)//We have a shell in the chamber - chambered.loc = get_turf(src)//Eject casing - chambered.SpinAnimation(5, 1) + chambered.forceMove(drop_location())//Eject casing + chambered.bounce_away() chambered = null /obj/item/gun/ballistic/shotgun/proc/pump_reload(mob/M) @@ -189,7 +188,6 @@ name = "combat shotgun" desc = "A semi automatic shotgun with tactical furniture and a six-shell capacity underneath." icon_state = "cshotgun" - origin_tech = "combat=6" mag_type = /obj/item/ammo_box/magazine/internal/shot/com w_class = WEIGHT_CLASS_HUGE @@ -197,7 +195,6 @@ name = "compact combat shotgun" desc = "A compact version of the semi automatic combat shotgun. For close encounters." icon_state = "cshotgunc" - origin_tech = "combat=4;materials=2" mag_type = /obj/item/ammo_box/magazine/internal/shot/com/compact w_class = WEIGHT_CLASS_BULKY @@ -207,7 +204,6 @@ name = "cycler shotgun" desc = "An advanced shotgun with two separate magazine tubes, allowing you to quickly toggle between ammo types." icon_state = "cycler" - origin_tech = "combat=4;materials=2" mag_type = /obj/item/ammo_box/magazine/internal/shot/tube w_class = WEIGHT_CLASS_HUGE var/toggled = FALSE diff --git a/code/modules/projectiles/guns/ballistic/toy.dm b/code/modules/projectiles/guns/ballistic/toy.dm index c251a791d0..a04d6f1b54 100644 --- a/code/modules/projectiles/guns/ballistic/toy.dm +++ b/code/modules/projectiles/guns/ballistic/toy.dm @@ -51,7 +51,6 @@ icon = 'icons/obj/guns/toy.dmi' force = 0 throwforce = 0 - origin_tech = null mag_type = /obj/item/ammo_box/magazine/internal/shot/toy clumsy_check = 0 needs_permit = 0 diff --git a/code/modules/projectiles/guns/beam_rifle.dm b/code/modules/projectiles/guns/beam_rifle.dm index a88e271056..ee8036bf44 100644 --- a/code/modules/projectiles/guns/beam_rifle.dm +++ b/code/modules/projectiles/guns/beam_rifle.dm @@ -23,7 +23,6 @@ slot_flags = SLOT_BACK force = 15 materials = list() - origin_tech = "" recoil = 4 ammo_x_offset = 3 ammo_y_offset = 3 @@ -179,7 +178,7 @@ zoom_animating = 0 animate(current_user.client, pixel_x = 0, pixel_y = 0, 0, FALSE, LINEAR_EASING, ANIMATION_END_NOW) zoom_current_view_increase = 0 - current_user.client.change_view(world.view) + current_user.client.change_view(CONFIG_GET(string/default_view)) zooming_angle = 0 current_zoom_x = 0 current_zoom_y = 0 @@ -358,15 +357,15 @@ if(lastfire > world.time + delay) return lastfire = world.time + . = ..() stop_aiming() - return ..() /obj/item/gun/energy/beam_rifle/proc/sync_ammo() for(var/obj/item/ammo_casing/energy/beam_rifle/AC in contents) AC.sync_stats() /obj/item/gun/energy/beam_rifle/proc/delay_penalty(amount) - aiming_time_left = Clamp(aiming_time_left + amount, 0, aiming_time) + aiming_time_left = CLAMP(aiming_time_left + amount, 0, aiming_time) /obj/item/ammo_casing/energy/beam_rifle name = "particle acceleration lens" @@ -417,11 +416,11 @@ HS_BB.stun = projectile_stun HS_BB.impact_structure_damage = impact_structure_damage HS_BB.aoe_mob_damage = aoe_mob_damage - HS_BB.aoe_mob_range = Clamp(aoe_mob_range, 0, 15) //Badmin safety lock + HS_BB.aoe_mob_range = CLAMP(aoe_mob_range, 0, 15) //Badmin safety lock HS_BB.aoe_fire_chance = aoe_fire_chance HS_BB.aoe_fire_range = aoe_fire_range HS_BB.aoe_structure_damage = aoe_structure_damage - HS_BB.aoe_structure_range = Clamp(aoe_structure_range, 0, 15) //Badmin safety lock + HS_BB.aoe_structure_range = CLAMP(aoe_structure_range, 0, 15) //Badmin safety lock HS_BB.wall_devastate = wall_devastate HS_BB.wall_pierce_amount = wall_pierce_amount HS_BB.structure_pierce_amount = structure_piercing @@ -503,11 +502,11 @@ if(!do_pierce) return FALSE if(pierced[target]) //we already pierced them go away - loc = get_turf(target) + forceMove(get_turf(target)) return TRUE if(isclosedturf(target)) if(wall_pierce++ < wall_pierce_amount) - loc = target + forceMove(target) if(prob(wall_devastate)) if(iswallturf(target)) var/turf/closed/wall/W = target @@ -523,7 +522,7 @@ var/obj/O = AM O.take_damage((impact_structure_damage + aoe_structure_damage) * structure_bleed_coeff * get_damage_coeff(AM), BURN, "energy", FALSE) pierced[AM] = TRUE - loc = get_turf(AM) + forceMove(AM.drop_location()) structure_pierce++ return TRUE return FALSE diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index aa5b137a5b..b52a56426b 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -130,7 +130,7 @@ ..() if(!automatic_charge_overlays) return - var/ratio = Ceiling((cell.charge / cell.maxcharge) * charge_sections) + var/ratio = CEILING((cell.charge / cell.maxcharge) * charge_sections, 1) var/obj/item/ammo_casing/energy/shot = ammo_type[select] var/iconState = "[icon_state]_charge" var/itemState = null @@ -175,7 +175,7 @@ return(OXYLOSS) else user.visible_message("[user] is pretending to blow [user.p_their()] brains out with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(loc, 'sound/weapons/empty.ogg', 50, 1, -1) + playsound(src, "gun_dry_fire", 30, 1) return (OXYLOSS) diff --git a/code/modules/projectiles/guns/energy/energy_gun.dm b/code/modules/projectiles/guns/energy/energy_gun.dm index c9ec6077aa..524f1e8f90 100644 --- a/code/modules/projectiles/guns/energy/energy_gun.dm +++ b/code/modules/projectiles/guns/energy/energy_gun.dm @@ -4,7 +4,6 @@ icon_state = "energy" item_state = null //so the human update icon uses the icon_state instead. ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/laser) - origin_tech = "combat=4;magnets=3" modifystate = 1 can_flashlight = 1 ammo_x_offset = 3 @@ -55,7 +54,6 @@ name = "\improper X-01 MultiPhase Energy Gun" desc = "This is an expensive, modern recreation of an antique laser gun. This gun has several unique firemodes, but lacks the ability to recharge over time." icon_state = "hoslaser" - origin_tech = null force = 10 ammo_type = list(/obj/item/ammo_casing/energy/electrode/hos, /obj/item/ammo_casing/energy/laser/hos, /obj/item/ammo_casing/energy/disabler) ammo_x_offset = 4 @@ -68,7 +66,6 @@ item_state = "dragnet" lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi' - origin_tech = "combat=4;magnets=3;bluespace=4" ammo_type = list(/obj/item/ammo_casing/energy/net, /obj/item/ammo_casing/energy/trap) can_flashlight = 0 ammo_x_offset = 1 @@ -96,7 +93,6 @@ desc = "An energy gun with an experimental miniaturized nuclear reactor that automatically charges the internal power cell." icon_state = "nucgun" item_state = "nucgun" - origin_tech = "combat=4;magnets=4;powerstorage=4" charge_delay = 5 pin = null can_charge = 0 diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index d2261fc6f8..3b93a960ca 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -7,7 +7,6 @@ cell_type = /obj/item/stock_parts/cell/emproof needs_permit = 0 unique_rename = 1 - origin_tech = "combat=3;powerstorage=3;engineering=3" weapon_weight = WEAPON_LIGHT can_flashlight = 1 flight_x_offset = 15 @@ -213,7 +212,6 @@ desc = "An upgrade for kinetic accelerators." icon = 'icons/obj/objects.dmi' icon_state = "modkit" - origin_tech = "programming=2;materials=2;magnets=4" w_class = WEIGHT_CLASS_SMALL require_module = 1 module_type = /obj/item/robot_module/miner diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index 6f916a5709..37bb252adc 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -5,7 +5,6 @@ item_state = "laser" w_class = WEIGHT_CLASS_NORMAL materials = list(MAT_METAL=2000) - origin_tech = "combat=4;magnets=2" ammo_type = list(/obj/item/ammo_casing/energy/lasergun) ammo_x_offset = 1 shaded_charge = 1 @@ -13,7 +12,6 @@ /obj/item/gun/energy/laser/practice name = "practice laser gun" desc = "A modified version of the basic laser gun, this one fires less concentrated energy bolts designed for target practice." - origin_tech = "combat=2;magnets=2" ammo_type = list(/obj/item/ammo_casing/energy/laser/practice) clumsy_check = 0 needs_permit = 0 @@ -37,7 +35,6 @@ item_state = "caplaser" desc = "This is an antique laser gun. All craftsmanship is of the highest quality. It is decorated with assistant leather and chrome. The object menaces with spikes of energy. On the item is an image of Space Station 13. The station is exploding." force = 10 - origin_tech = null ammo_x_offset = 3 selfcharge = 1 resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF @@ -47,13 +44,11 @@ icon_state = "lasercannon" item_state = "laser" desc = "An industrial-grade heavy-duty laser rifle with a modified laser lens to scatter its shot into multiple smaller lasers. The inner-core can self-charge for theoretically infinite use." - origin_tech = "combat=5;materials=4;powerstorage=4" ammo_type = list(/obj/item/ammo_casing/energy/laser/scatter, /obj/item/ammo_casing/energy/laser) /obj/item/gun/energy/laser/cyborg can_charge = 0 desc = "An energy-based laser gun that draws power from the cyborg's internal energy cell directly. So this is what freedom looks like?" - origin_tech = null use_cyborg_cell = 1 /obj/item/gun/energy/laser/cyborg/emp_act() @@ -85,7 +80,6 @@ force = 10 flags_1 = CONDUCT_1 slot_flags = SLOT_BACK - origin_tech = "combat=4;magnets=4;powerstorage=3" ammo_type = list(/obj/item/ammo_casing/energy/laser/accelerator) pin = null ammo_x_offset = 3 @@ -111,7 +105,6 @@ desc = "A high-power laser gun capable of expelling concentrated x-ray blasts that pass through multiple soft targets and heavier materials." icon_state = "xray" item_state = null - origin_tech = "combat=6;materials=4;magnets=4;syndicate=1" ammo_type = list(/obj/item/ammo_casing/energy/xray) pin = null ammo_x_offset = 3 @@ -123,7 +116,6 @@ icon_state = "bluetag" desc = "A retro laser gun modified to fire harmless blue beams of light. Sound effects included!" ammo_type = list(/obj/item/ammo_casing/energy/laser/bluetag) - origin_tech = "combat=2;magnets=2" clumsy_check = 0 needs_permit = 0 pin = /obj/item/device/firing_pin/tag/blue @@ -135,7 +127,6 @@ icon_state = "redtag" desc = "A retro laser gun modified to fire harmless beams red of light. Sound effects included!" ammo_type = list(/obj/item/ammo_casing/energy/laser/redtag) - origin_tech = "combat=2;magnets=2" clumsy_check = 0 needs_permit = 0 pin = /obj/item/device/firing_pin/tag/red diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index d7c54f193d..a4ae8cae13 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -3,7 +3,6 @@ desc = "A man-portable anti-armor weapon designed to disable mechanical threats at range." icon_state = "ionrifle" item_state = null //so the human update icon uses the icon_state instead. - origin_tech = "combat=4;magnets=4" can_flashlight = 1 w_class = WEIGHT_CLASS_HUGE flags_1 = CONDUCT_1 @@ -31,7 +30,6 @@ name = "biological demolecularisor" desc = "A gun that discharges high amounts of controlled radiation to slowly break a target into component elements." icon_state = "decloner" - origin_tech = "combat=4;materials=4;biotech=5;plasmatech=6" ammo_type = list(/obj/item/ammo_casing/energy/declone) pin = null ammo_x_offset = 1 @@ -48,7 +46,6 @@ icon_state = "flora" item_state = "gun" ammo_type = list(/obj/item/ammo_casing/energy/flora/yield, /obj/item/ammo_casing/energy/flora/mut) - origin_tech = "materials=2;biotech=4" modifystate = 1 ammo_x_offset = 1 selfcharge = 1 @@ -89,7 +86,6 @@ item_state = "crossbow" w_class = WEIGHT_CLASS_SMALL materials = list(MAT_METAL=2000) - origin_tech = "combat=4;magnets=4;syndicate=5" suppressed = TRUE ammo_type = list(/obj/item/ammo_casing/energy/bolt) weapon_weight = WEAPON_LIGHT @@ -114,7 +110,6 @@ icon_state = "crossbowlarge" w_class = WEIGHT_CLASS_NORMAL materials = list(MAT_METAL=4000) - origin_tech = "combat=4;magnets=4;syndicate=2" suppressed = null ammo_type = list(/obj/item/ammo_casing/energy/bolt/large) pin = null @@ -124,10 +119,8 @@ desc = "A mining tool capable of expelling concentrated plasma bursts. You could use it to cut limbs off xenos! Or, you know, mine stuff." icon_state = "plasmacutter" item_state = "plasmacutter" - origin_tech = "combat=1;materials=3;magnets=2;plasmatech=3;engineering=1" ammo_type = list(/obj/item/ammo_casing/energy/plasma) flags_1 = CONDUCT_1 - container_type = OPENCONTAINER_1 attack_verb = list("attacked", "slashed", "cut", "sliced") force = 12 sharpness = IS_SHARP @@ -159,7 +152,6 @@ /obj/item/gun/energy/plasmacutter/adv name = "advanced plasma cutter" icon_state = "adv_plasmacutter" - origin_tech = "combat=3;materials=4;magnets=3;plasmatech=4;engineering=2" force = 15 ammo_type = list(/obj/item/ammo_casing/energy/plasma/adv) @@ -169,7 +161,6 @@ ammo_type = list(/obj/item/ammo_casing/energy/wormhole, /obj/item/ammo_casing/energy/wormhole/orange) item_state = null icon_state = "wormhole_projector" - origin_tech = "combat=4;bluespace=6;plasmatech=4;engineering=4" var/obj/effect/portal/p_blue var/obj/effect/portal/p_orange @@ -243,7 +234,6 @@ name = "temperature gun" icon_state = "freezegun" desc = "A gun that changes temperatures." - origin_tech = "combat=4;materials=4;powerstorage=3;magnets=2" ammo_type = list(/obj/item/ammo_casing/energy/temp, /obj/item/ammo_casing/energy/temp/hot) cell_type = "/obj/item/stock_parts/cell/high" pin = null @@ -251,7 +241,6 @@ /obj/item/gun/energy/temperature/security name = "security temperature gun" desc = "A weapon that can only be used to its full potential by the truly robust." - origin_tech = "combat=2;materials=2;powerstorage=1;magnets=1" pin = /obj/item/device/firing_pin /obj/item/gun/energy/laser/instakill @@ -261,7 +250,6 @@ desc = "A specialized ASMD laser-rifle, capable of flat-out disintegrating most targets in a single hit." ammo_type = list(/obj/item/ammo_casing/energy/instakill) force = 60 - origin_tech = "combat=7;magnets=6" /obj/item/gun/energy/laser/instakill/red desc = "A specialized ASMD laser-rifle, capable of flat-out disintegrating most targets in a single hit. This one has a red design." @@ -282,7 +270,6 @@ name = "one-point bluespace-gravitational manipulator" desc = "An experimental, multi-mode device that fires bolts of Zero-Point Energy, causing local distortions in gravity." ammo_type = list(/obj/item/ammo_casing/energy/gravityrepulse, /obj/item/ammo_casing/energy/gravityattract, /obj/item/ammo_casing/energy/gravitychaos) - origin_tech = "combat=4;magnets=4;materials=6;powerstorage=4;bluespace=4" item_state = "gravity_gun" icon_state = "gravity_gun" var/power = 4 diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm index 1b9532c2af..69f6a47813 100644 --- a/code/modules/projectiles/guns/energy/stun.dm +++ b/code/modules/projectiles/guns/energy/stun.dm @@ -4,7 +4,6 @@ icon_state = "taser" item_state = null //so the human update icon uses the icon_state instead. ammo_type = list(/obj/item/ammo_casing/energy/electrode) - origin_tech = "combat=3" ammo_x_offset = 3 /obj/item/gun/energy/tesla_revolver @@ -13,7 +12,6 @@ icon_state = "tesla" item_state = "tesla" ammo_type = list(/obj/item/ammo_casing/energy/tesla_revolver) - origin_tech = "combat=4;materials=4;powerstorage=4" can_flashlight = 0 pin = null shaded_charge = 1 @@ -23,7 +21,6 @@ desc = "A dual-mode taser designed to fire both short-range high-power electrodes and long-range disabler beams." icon_state = "advtaser" ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/disabler) - origin_tech = "combat=4" ammo_x_offset = 2 /obj/item/gun/energy/e_gun/advtaser/cyborg @@ -38,7 +35,6 @@ desc = "A self-defense weapon that exhausts organic targets, weakening them until they collapse." icon_state = "disabler" item_state = null - origin_tech = "combat=3" ammo_type = list(/obj/item/ammo_casing/energy/disabler) ammo_x_offset = 3 diff --git a/code/modules/projectiles/guns/grenade_launcher.dm b/code/modules/projectiles/guns/grenade_launcher.dm index d87a657710..771c0091e3 100644 --- a/code/modules/projectiles/guns/grenade_launcher.dm +++ b/code/modules/projectiles/guns/grenade_launcher.dm @@ -42,7 +42,7 @@ "You fire the grenade launcher!") var/obj/item/grenade/F = grenades[1] //Now with less copypasta! grenades -= F - F.loc = user.loc + F.forceMove(user.loc) F.throw_at(target, 30, 2, user) message_admins("[key_name_admin(user)] fired a grenade ([F.name]) from a grenade launcher ([src.name]).") log_game("[key_name(user)] fired a grenade ([F.name]) from a grenade launcher ([src.name]).") diff --git a/code/modules/projectiles/guns/magic.dm b/code/modules/projectiles/guns/magic.dm index 21bc12bb1f..36dc4937c5 100644 --- a/code/modules/projectiles/guns/magic.dm +++ b/code/modules/projectiles/guns/magic.dm @@ -16,7 +16,6 @@ var/can_charge = 1 var/ammo_type var/no_den_usage - origin_tech = null clumsy_check = 0 trigger_guard = TRIGGER_GUARD_ALLOW_ALL // Has no trigger at all, uses magic instead pin = /obj/item/device/firing_pin/magic diff --git a/code/modules/projectiles/guns/magic/wand.dm b/code/modules/projectiles/guns/magic/wand.dm index 27fb040de4..bf3ade0748 100644 --- a/code/modules/projectiles/guns/magic/wand.dm +++ b/code/modules/projectiles/guns/magic/wand.dm @@ -12,9 +12,9 @@ /obj/item/gun/magic/wand/Initialize() if(prob(75) && variable_charges) //25% chance of listed max charges, 50% chance of 1/2 max charges, 25% chance of 1/3 max charges if(prob(33)) - max_charges = Ceiling(max_charges / 3) + max_charges = CEILING(max_charges / 3, 1) else - max_charges = Ceiling(max_charges / 2) + max_charges = CEILING(max_charges / 2, 1) return ..() /obj/item/gun/magic/wand/examine(mob/user) diff --git a/code/modules/projectiles/guns/syringe_gun.dm b/code/modules/projectiles/guns/syringe_gun.dm index 17d2ea7cbe..ac9f7daedf 100644 --- a/code/modules/projectiles/guns/syringe_gun.dm +++ b/code/modules/projectiles/guns/syringe_gun.dm @@ -8,7 +8,6 @@ throw_range = 7 force = 4 materials = list(MAT_METAL=2000) - origin_tech = "combat=2;biotech=3" clumsy_check = 0 fire_sound = 'sound/items/syringeproj.ogg' var/list/syringes = list() @@ -43,7 +42,7 @@ if(!S) return 0 - S.loc = user.loc + S.forceMove(user.loc) syringes.Remove(S) to_chat(user, "You unload [S] from \the [src].") @@ -75,7 +74,6 @@ icon_state = "syringe_pistol" item_state = "gun" //Smaller inhand w_class = WEIGHT_CLASS_SMALL - origin_tech = "combat=2;syndicate=2;biotech=3" force = 2 //Also very weak because it's smaller suppressed = TRUE //Softer fire sound can_unsuppress = FALSE //Permanently silenced @@ -83,7 +81,6 @@ /obj/item/gun/syringe/dna name = "modified syringe gun" desc = "A syringe gun that has been modified to fit DNA injectors instead of normal syringes." - origin_tech = "combat=2;syndicate=2;biotech=3" /obj/item/gun/syringe/dna/Initialize() . = ..() @@ -104,4 +101,4 @@ return TRUE else to_chat(user, "[src] cannot hold more syringes!") - return FALSE \ No newline at end of file + return FALSE diff --git a/code/modules/projectiles/pins.dm b/code/modules/projectiles/pins.dm index 75066540cf..faf7de9010 100644 --- a/code/modules/projectiles/pins.dm +++ b/code/modules/projectiles/pins.dm @@ -4,7 +4,6 @@ icon = 'icons/obj/device.dmi' icon_state = "firing_pin" item_state = "pen" - origin_tech = "materials=2;combat=4" flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_TINY attack_verb = list("poked") @@ -25,7 +24,7 @@ if(istype(target, /obj/item/gun)) var/obj/item/gun/G = target if(G.pin && (force_replace || G.pin.pin_removeable)) - G.pin.loc = get_turf(G) + G.pin.forceMove(get_turf(G)) G.pin.gun_remove(user) to_chat(user, "You remove [G]'s old pin.") @@ -79,7 +78,6 @@ desc = "This safety firing pin allows weapons to be fired within proximity to a firing range." fail_message = "TEST RANGE CHECK FAILED." pin_removeable = 1 - origin_tech = "combat=2;materials=2" /obj/item/device/firing_pin/test_range/pin_auth(mob/living/user) for(var/obj/machinery/magnetic_controller/M in range(user, 3)) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index a45b713b85..79e2fdf903 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -168,7 +168,7 @@ /obj/item/projectile/proc/vol_by_damage() if(src.damage) - return Clamp((src.damage) * 0.67, 30, 100)// Multiply projectile damage by 0.67, then clamp the value between 30 and 100 + return CLAMP((src.damage) * 0.67, 30, 100)// Multiply projectile damage by 0.67, then clamp the value between 30 and 100 else return 50 //if the projectile doesn't do damage, play its hitsound at 50% volume @@ -177,6 +177,7 @@ ricochets++ if(A.handle_ricochet(src)) ignore_source_check = TRUE + range = initial(range) return FALSE if(firer && !ignore_source_check) if(A == firer || (A == firer.loc && ismecha(A))) //cannot shoot yourself or your mech @@ -187,7 +188,7 @@ def_zone = ran_zone(def_zone, max(100-(7*distance), 5)) //Lower accurancy/longer range tradeoff. 7 is a balanced number to use. if(isturf(A) && hitsound_wall) - var/volume = Clamp(vol_by_damage() + 20, 0, 100) + var/volume = CLAMP(vol_by_damage() + 20, 0, 100) if(suppressed) volume = 5 playsound(loc, hitsound_wall, volume, 1, -1) @@ -258,7 +259,7 @@ return var/elapsed_time_deciseconds = (world.time - last_projectile_move) + time_offset time_offset = 0 - var/required_moves = speed > 0? Floor(elapsed_time_deciseconds / speed) : MOVES_HITSCAN //Would be better if a 0 speed made hitscan but everyone hates those so I can't make it a universal system :< + var/required_moves = speed > 0? FLOOR(elapsed_time_deciseconds / speed, 1) : MOVES_HITSCAN //Would be better if a 0 speed made hitscan but everyone hates those so I can't make it a universal system :< if(required_moves == MOVES_HITSCAN) required_moves = SSprojectiles.global_max_tick_moves else @@ -266,7 +267,7 @@ var/overrun = required_moves - SSprojectiles.global_max_tick_moves required_moves = SSprojectiles.global_max_tick_moves time_offset += overrun * speed - time_offset += Modulus(elapsed_time_deciseconds, speed) + time_offset += MODULUS(elapsed_time_deciseconds, speed) for(var/i in 1 to required_moves) pixel_move(required_moves) @@ -286,7 +287,7 @@ setAngle(Angle + ((rand() - 0.5) * spread)) if(isnull(Angle)) //Try to resolve through offsets if there's no angle set. var/turf/starting = get_turf(src) - var/turf/target = locate(Clamp(starting + xo, 1, world.maxx), Clamp(starting + yo, 1, world.maxy), starting.z) + var/turf/target = locate(CLAMP(starting + xo, 1, world.maxx), CLAMP(starting + yo, 1, world.maxy), starting.z) setAngle(Get_Angle(src, target)) if(!nondirectional_sprite) var/matrix/M = new @@ -358,8 +359,9 @@ forceMove(get_turf(source)) starting = get_turf(source) original = target - yo = targloc.y - curloc.y - xo = targloc.x - curloc.x + if(targloc || !params) + yo = targloc.y - curloc.y + xo = targloc.x - curloc.x if(isliving(source) && params) var/list/calculated = calculate_projectile_angle_and_pixel_offsets(source, params) @@ -395,11 +397,13 @@ var/y = text2num(screen_loc_Y[1]) * 32 + text2num(screen_loc_Y[2]) - 32 //Calculate the "resolution" of screen based on client's view and world's icon size. This will work if the user can view more tiles than average. - var/screenview = (user.client.view * 2 + 1) * world.icon_size //Refer to http://www.byond.com/docs/ref/info.html#/client/var/view for mad maths + var/list/screenview = getviewsize(user.client.view) + var/screenviewX = screenview[1] * world.icon_size + var/screenviewY = screenview[2] * world.icon_size - var/ox = round(screenview/2) - user.client.pixel_x //"origin" x - var/oy = round(screenview/2) - user.client.pixel_y //"origin" y - angle = Atan2(y - oy, x - ox) + var/ox = round(screenviewX/2) - user.client.pixel_x //"origin" x + var/oy = round(screenviewY/2) - user.client.pixel_y //"origin" y + angle = ATAN2(y - oy, x - ox) return list(angle, p_x, p_y) /obj/item/projectile/Crossed(atom/movable/AM) //A mob moving on a tile with a projectile is hit by it. diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index a10c264b9a..9b4842d644 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -285,7 +285,7 @@ to_chat(new_mob, poly_msg) M.transfer_observers_to(new_mob) - + qdel(M) return new_mob @@ -319,7 +319,7 @@ L.mind.transfer_to(S) if(owner) to_chat(S, "You are an animate statue. You cannot move when monitored, but are nearly invincible and deadly when unobserved! Do not harm [owner], your creator.") - P.loc = S + P.forceMove(S) return else var/obj/O = src diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index 5a650ff2c3..152cff6c74 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -100,7 +100,7 @@ /obj/item/projectile/meteor/Collide(atom/A) if(A == firer) - loc = A.loc + forceMove(A.loc) return A.ex_act(EXPLODE_HEAVY) playsound(src.loc, 'sound/effects/meteorimpact.ogg', 40, 1) @@ -612,4 +612,3 @@ knockdown = 0 nodamage = TRUE return ..() - diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 9c4bff72cb..94e8b465c1 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -59,6 +59,19 @@ if(my_atom && my_atom.reagents == src) my_atom.reagents = null + +// Used in attack logs for reagents in pills and such +/datum/reagents/proc/log_list() + if(!length(reagent_list)) + return "no reagents" + + var/list/data = list() + for(var/r in reagent_list) //no reagents will be left behind + var/datum/reagent/R = r + data += "[R.id] ([round(R.volume, 0.1)]u)" + //Using IDs because SOME chemicals (I'm looking at you, chlorhydrate-beer) have the same names as other chemicals. + return english_list(data) + /datum/reagents/proc/remove_any(amount = 1) var/list/cached_reagents = reagent_list var/total_transfered = 0 @@ -228,8 +241,7 @@ var/list/cached_reagents = reagent_list var/list/cached_addictions = addiction_list if(C) - chem_temp = C.bodytemperature - handle_reactions() + expose_temperature(C.bodytemperature, 0.25) var/need_mob_update = 0 for(var/reagent in cached_reagents) var/datum/reagent/R = reagent @@ -580,7 +592,7 @@ if (R.id == reagent) //clamp the removal amount to be between current reagent amount //and zero, to prevent removing more than the holder has stored - amount = Clamp(amount, 0, R.volume) + amount = CLAMP(amount, 0, R.volume) R.volume -= amount update_total() if(!safety)//So it does not handle reactions when it need not to @@ -731,6 +743,16 @@ out += "[taste_desc]" return english_list(out, "something indescribable") + + +/datum/reagents/proc/expose_temperature(var/temperature, var/coeff=0.02) + var/temp_delta = (temperature - chem_temp) * coeff + if(temp_delta > 0) + chem_temp = min(chem_temp + max(temp_delta, 1), temperature) + else + chem_temp = max(chem_temp + min(temp_delta, -1), temperature) + chem_temp = round(chem_temp) + handle_reactions() /////////////////////////////////////////////////////////////////////////////////// diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index 654b9e0e69..ac8f3bc656 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -59,6 +59,11 @@ recharge() dispensable_reagents = sortList(dispensable_reagents) +/obj/machinery/chem_dispenser/Destroy() + QDEL_NULL(beaker) + QDEL_NULL(cell) + return ..() + /obj/machinery/chem_dispenser/process() if(recharged < 0) @@ -179,7 +184,7 @@ if(default_unfasten_wrench(user, I)) return - if(istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER_1)) + if(istype(I, /obj/item/reagent_containers) && I.is_open_container()) var/obj/item/reagent_containers/B = I . = 1 //no afterattack if(beaker) @@ -206,7 +211,7 @@ /obj/machinery/chem_dispenser/emp_act(severity) var/list/datum/reagents/R = list() - var/total = min(rand(7,15), Floor(cell.charge*powerefficiency)) + var/total = min(rand(7,15), FLOOR(cell.charge*powerefficiency, 1)) var/datum/reagents/Q = new(total*10) if(beaker && beaker.reagents) R += beaker.reagents @@ -303,6 +308,7 @@ if(beaker) beaker.forceMove(drop_location()) beaker = null + return ..() /obj/machinery/chem_dispenser/drinks name = "soda dispenser" diff --git a/code/modules/reagents/chemistry/machinery/chem_heater.dm b/code/modules/reagents/chemistry/machinery/chem_heater.dm index f8d2a66247..96dabf8aaa 100644 --- a/code/modules/reagents/chemistry/machinery/chem_heater.dm +++ b/code/modules/reagents/chemistry/machinery/chem_heater.dm @@ -13,6 +13,28 @@ var/heater_coefficient = 0.1 var/on = FALSE +/obj/machinery/chem_heater/Destroy() + QDEL_NULL(beaker) + return ..() + +/obj/machinery/chem_heater/handle_atom_del(atom/A) + . = ..() + if(A == beaker) + beaker = null + update_icon() + +/obj/machinery/chem_heater/update_icon() + if(beaker) + icon_state = "mixer1b" + else + icon_state = "mixer0b" + +/obj/machinery/chem_heater/proc/eject_beaker() + if(beaker) + beaker.forceMove(drop_location()) + beaker = null + update_icon() + /obj/machinery/chem_heater/RefreshParts() heater_coefficient = 0.1 for(var/obj/item/stock_parts/micro_laser/M in component_parts) @@ -42,7 +64,7 @@ if(default_deconstruction_crowbar(I)) return - if(istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER_1)) + if(istype(I, /obj/item/reagent_containers) && I.is_open_container()) . = 1 //no afterattack if(beaker) to_chat(user, "A container is already loaded into [src]!") @@ -52,12 +74,13 @@ return beaker = I to_chat(user, "You add [I] to [src].") - icon_state = "mixer1b" + update_icon() return return ..() /obj/machinery/chem_heater/on_deconstruction() eject_beaker() + return ..() /obj/machinery/chem_heater/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) @@ -103,15 +126,8 @@ target = text2num(target) . = TRUE if(.) - target_temperature = Clamp(target, 0, 1000) + target_temperature = CLAMP(target, 0, 1000) if("eject") on = FALSE eject_beaker() . = TRUE - -/obj/machinery/chem_heater/proc/eject_beaker() - if(beaker) - beaker.forceMove(drop_location()) - beaker.reagents.handle_reactions() - beaker = null - icon_state = "mixer0b" diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm index 434996fb08..d463def8af 100644 --- a/code/modules/reagents/chemistry/machinery/chem_master.dm +++ b/code/modules/reagents/chemistry/machinery/chem_master.dm @@ -13,7 +13,7 @@ var/obj/item/reagent_containers/beaker = null var/obj/item/storage/pill_bottle/bottle = null var/mode = 1 - var/condi = 0 + var/condi = FALSE var/screen = "home" var/analyzeVars[0] var/useramount = 30 // Last used amount @@ -23,6 +23,11 @@ add_overlay("waitlight") . = ..() +/obj/machinery/chem_master/Destroy() + QDEL_NULL(beaker) + QDEL_NULL(bottle) + return ..() + /obj/machinery/chem_master/RefreshParts() reagents.maximum_volume = 0 for(var/obj/item/reagent_containers/glass/beaker/B in component_parts) @@ -44,10 +49,22 @@ if(A == beaker) beaker = null reagents.clear_reagents() - icon_state = "mixer0" + update_icon() else if(A == bottle) bottle = null +/obj/machinery/chem_master/update_icon() + if(beaker) + icon_state = "mixer1" + else + icon_state = "mixer0" + +/obj/machinery/chem_master/proc/eject_beaker() + if(beaker) + beaker.forceMove(drop_location()) + adjust_item_drop_location(beaker) + beaker = null + update_icon() /obj/machinery/chem_master/blob_act(obj/structure/blob/B) if (prob(50)) @@ -61,15 +78,6 @@ /obj/machinery/chem_master/attackby(obj/item/I, mob/user, params) if(default_deconstruction_screwdriver(user, "mixer0_nopower", "mixer0", I)) - if(beaker) - beaker.forceMove(drop_location()) - adjust_item_drop_location(beaker) - beaker = null - reagents.clear_reagents() - if(bottle) - bottle.forceMove(drop_location()) - adjust_item_drop_location(bottle) - bottle = null return else if(exchange_parts(user, I)) @@ -80,7 +88,7 @@ if(default_unfasten_wrench(user, I)) return - if(istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER_1)) + if(istype(I, /obj/item/reagent_containers) && I.is_open_container()) . = 1 // no afterattack if(panel_open) to_chat(user, "You can't use the [src.name] while its panel is opened!") @@ -94,7 +102,7 @@ beaker = I to_chat(user, "You add [I] to [src].") src.updateUsrDialog() - icon_state = "mixer1" + update_icon() else if(!condi && istype(I, /obj/item/storage/pill_bottle)) if(bottle) @@ -109,6 +117,13 @@ else return ..() +/obj/machinery/chem_master/on_deconstruction() + eject_beaker() + if(bottle) + bottle.forceMove(drop_location()) + adjust_item_drop_location(bottle) + bottle = null + return ..() /obj/machinery/chem_master/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) @@ -154,13 +169,8 @@ return switch(action) if("eject") - if(beaker) - beaker.forceMove(drop_location()) - adjust_item_drop_location(beaker) - beaker = null - reagents.clear_reagents() - icon_state = "mixer0" - . = TRUE + eject_beaker() + . = TRUE if("ejectp") if(bottle) @@ -205,7 +215,7 @@ var/amount = 1 var/vol_each = min(reagents.total_volume, 50) if(text2num(many)) - amount = Clamp(round(input(usr, "Max 10. Buffer content will be split evenly.", "How many pills?", amount) as num|null), 0, 10) + amount = CLAMP(round(input(usr, "Max 10. Buffer content will be split evenly.", "How many pills?", amount) as num|null), 0, 10) if(!amount) return vol_each = min(reagents.total_volume / amount, 50) @@ -241,7 +251,7 @@ var/amount = 1 var/vol_each = min(reagents.total_volume, 40) if(text2num(many)) - amount = Clamp(round(input(usr, "Max 10. Buffer content will be split evenly.", "How many patches?", amount) as num|null), 0, 10) + amount = CLAMP(round(input(usr, "Max 10. Buffer content will be split evenly.", "How many patches?", amount) as num|null), 0, 10) if(!amount) return vol_each = min(reagents.total_volume / amount, 40) @@ -348,7 +358,7 @@ #if DM_VERSION >= 513 #warning 512 is definitely stable now, remove the old code #endif - + #if DM_VERSION >= 512 . += hex2num(md5[i]) #else @@ -361,4 +371,4 @@ /obj/machinery/chem_master/condimaster name = "CondiMaster 3000" desc = "Used to create condiments and other cooking supplies." - condi = 1 + condi = TRUE diff --git a/code/modules/reagents/chemistry/machinery/pandemic.dm b/code/modules/reagents/chemistry/machinery/pandemic.dm index 466aa047ad..ef186d8a79 100644 --- a/code/modules/reagents/chemistry/machinery/pandemic.dm +++ b/code/modules/reagents/chemistry/machinery/pandemic.dm @@ -25,6 +25,12 @@ QDEL_NULL(beaker) return ..() +/obj/machinery/computer/pandemic/handle_atom_del(atom/A) + . = ..() + if(A == beaker) + beaker = null + update_icon() + /obj/machinery/computer/pandemic/proc/get_by_index(thing, index) if(!beaker || !beaker.reagents) return @@ -121,9 +127,10 @@ add_overlay("waitlight") /obj/machinery/computer/pandemic/proc/eject_beaker() - beaker.forceMove(drop_location()) - beaker = null - update_icon() + if(beaker) + beaker.forceMove(drop_location()) + beaker = null + update_icon() /obj/machinery/computer/pandemic/ui_interact(mob/user, ui_key = "main", datum/tgui/ui, force_open = FALSE, datum/tgui/master_ui, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) @@ -159,8 +166,7 @@ return switch(action) if("eject_beaker") - if(beaker) - eject_beaker() + eject_beaker() . = TRUE if("empty_beaker") if(beaker) @@ -219,7 +225,7 @@ /obj/machinery/computer/pandemic/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER_1)) + if(istype(I, /obj/item/reagent_containers) && I.is_open_container()) . = TRUE //no afterattack if(stat & (NOPOWER|BROKEN)) return @@ -236,7 +242,5 @@ return ..() /obj/machinery/computer/pandemic/on_deconstruction() - if(beaker) - beaker.forceMove(drop_location()) - beaker = null + eject_beaker() . = ..() diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index 77fcd50306..48dd5c2dc0 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -2,7 +2,7 @@ #define MILK_TO_BUTTER_COEFF 15 /obj/machinery/reagentgrinder - name = "All-In-One Grinder" + name = "\improper All-In-One Grinder" desc = "From BlenderTech. Will It Blend? Let's test it out!" icon = 'icons/obj/kitchen.dmi' icon_state = "juicer1" @@ -16,97 +16,6 @@ var/operating = FALSE var/obj/item/reagent_containers/beaker = null var/limit = 10 - - var/static/list/blend_items = list( - //Sheets - /obj/item/stack/sheet/mineral/plasma = list("plasma" = 20), - /obj/item/stack/sheet/metal = list("iron" = 20), - /obj/item/stack/sheet/plasteel = list("iron" = 20, "plasma" = 20), - /obj/item/stack/sheet/mineral/wood = list("carbon" = 20), - /obj/item/stack/sheet/glass = list("silicon" = 20), - /obj/item/stack/sheet/rglass = list("silicon" = 20, "iron" = 20), - /obj/item/stack/sheet/mineral/uranium = list("uranium" = 20), - /obj/item/stack/sheet/mineral/bananium = list("banana" = 20), - /obj/item/stack/sheet/mineral/silver = list("silver" = 20), - /obj/item/stack/sheet/mineral/gold = list("gold" = 20), - /obj/item/stack/sheet/bluespace_crystal = list("bluespace" = 20), - /obj/item/stack/cable_coil = list ("copper" = 5), - /obj/item/ore/bluespace_crystal = list("bluespace" = 20), - /obj/item/grown/nettle/basic = list("sacid" = 0), - /obj/item/grown/nettle/death = list("facid" = 0, "sacid" = 0), - /obj/item/grown/novaflower = list("capsaicin" = 0, "condensedcapsaicin" = 0), - //Blender Stuff - /obj/item/reagent_containers/food/snacks/donkpocket/warm = list("omnizine" = 3), - /obj/item/reagent_containers/food/snacks/grown/soybeans = list("soymilk" = 0), - /obj/item/reagent_containers/food/snacks/grown/tomato = list("ketchup" = 0), - /obj/item/reagent_containers/food/snacks/grown/wheat = list("flour" = -5), - /obj/item/reagent_containers/food/snacks/grown/oat = list("flour" = -5), - /obj/item/reagent_containers/food/snacks/grown/rice = list("rice" = -5), - /obj/item/reagent_containers/food/snacks/donut = list("sprinkles" = -2, "sugar" = 1), - /obj/item/reagent_containers/food/snacks/grown/cherries = list("cherryjelly" = 0), - /obj/item/reagent_containers/food/snacks/grown/bluecherries = list("bluecherryjelly" = 0), - /obj/item/reagent_containers/food/snacks/egg = list("eggyolk" = -5), - /obj/item/reagent_containers/food/snacks/deadmouse = list ("blood" = 20, "gibs" = 5), // You monster - //Grinder stuff, but only if dry - /obj/item/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0), - /obj/item/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0), - /obj/item/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0), - /obj/item/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0), - //Stuff that doesn't quite fit in the other categories - /obj/item/electronics = list ("iron" = 10, "silicon" = 10), - /obj/item/circuitboard = list ("silicon" = 20, "sacid" = 0.5), // Retrieving acid this way is extremely inefficient - /obj/item/match = list ("phosphorus" = 2), - /obj/item/device/toner = list ("iodine" = 40, "iron" = 10), - /obj/item/photo = list ("iodine" = 4), - /obj/item/pen = list ("iodine" = 2, "iron" = 1), - /obj/item/reagent_containers/food/drinks/soda_cans = list ("aluminium" = 10), - /obj/item/trash/can = list ("aluminium" = 10), - /obj/item/device/flashlight/flare = list ("sulfur" = 15), - /obj/item/device/flashlight/glowstick = list ("phenol" = 15, "hydrodgen" = 10, "oxygen" = 5), - /obj/item/stock_parts/cell = list ("lithium" = 15, "iron" = 5, "silicon" = 5), - /obj/item/soap = list ("lye" = 10), - /obj/item/device/analyzer = list ("mercury" = 5, "iron" = 5, "silicon" = 5), - /obj/item/lighter = list ("iron" = 1, "weldingfuel" = 5, "oil" = 5), - /obj/item/light = list ("silicon" = 5, "nitrogen" = 10), //Nitrogen is used as a cheaper alternative to argon in incandescent lighbulbs - /obj/item/cigbutt/ = list ("carbon" = 2), - /obj/item/trash/coal = list ("carbon" = 20), - /obj/item/stack/medical/bruise_pack = list ("styptic_powder" = 5), - /obj/item/stack/medical/ointment = list ("silver_sulfadiazine" = 5), - //All types that you can put into the grinder to transfer the reagents to the beaker. !Put all recipes above this.! - /obj/item/slime_extract = list(), - /obj/item/reagent_containers/pill = list(), - /obj/item/reagent_containers/food = list(), - /obj/item/reagent_containers/honeycomb = list(), - /obj/item/toy/crayon = list(), - /obj/item/clothing/mask/cigarette = list()) - - var/static/list/juice_items = list( - //Juicer Stuff - /obj/item/reagent_containers/food/snacks/grown/corn = list("corn_starch" = 0), - /obj/item/reagent_containers/food/snacks/grown/tomato = list("tomatojuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/carrot = list("carrotjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/berries = list("berryjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/banana = list("banana" = 0), - /obj/item/reagent_containers/food/snacks/grown/potato = list("potato" = 0), - /obj/item/reagent_containers/food/snacks/grown/citrus/lemon = list("lemonjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/citrus/orange = list("orangejuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/citrus/lime = list("limejuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/watermelon = list("watermelonjuice" = 0), - /obj/item/reagent_containers/food/snacks/watermelonslice = list("watermelonjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/berries/poison = list("poisonberryjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/pumpkin = list("pumpkinjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/blumpkin = list("blumpkinjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/apple = list("applejuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/grapes = list("grapejuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/grapes/green = list("grapejuice" = 0)) - - var/static/list/dried_items = list( - //Grinder stuff, but only if dry, - /obj/item/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0), - /obj/item/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0), - /obj/item/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0), - /obj/item/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0)) - var/list/holdingitems /obj/machinery/reagentgrinder/Initialize() @@ -153,11 +62,12 @@ if(default_unfasten_wrench(user, I)) return - if (istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER_1) ) + if (istype(I, /obj/item/reagent_containers) && I.is_open_container()) if (!beaker) if(!user.transferItemToLoc(I, src)) to_chat(user, "[I] is stuck to your hand!") return TRUE + to_chat(user, "You slide [I] into [src].") beaker = I update_icon() updateUsrDialog() @@ -165,15 +75,8 @@ to_chat(user, "There's already a container inside [src].") return TRUE //no afterattack - if(is_type_in_list(I, dried_items)) - if(istype(I, /obj/item/reagent_containers/food/snacks/grown)) - var/obj/item/reagent_containers/food/snacks/grown/G = I - if(!G.dry) - to_chat(user, "You must dry [G] first!") - return TRUE - - if(length(holdingitems) >= limit) - to_chat(user, "The machine cannot hold anymore items.") + if(holdingitems.len >= limit) + to_chat(user, "[src] is filled to capacity!") return TRUE //Fill machine with a bag! @@ -192,14 +95,18 @@ updateUsrDialog() return TRUE - if (!is_type_in_list(I, blend_items) && !is_type_in_list(I, juice_items)) + if(!I.grind_results && !I.juice_results) if(user.a_intent == INTENT_HARM) return ..() else - to_chat(user, "Cannot refine into a reagent!") + to_chat(user, "You cannot grind [I] into reagents!") return TRUE + if(!I.grind_requirements(src)) //Error messages should be in the objects' definitions + return + if(user.transferItemToLoc(I, src)) + to_chat(user, "You add [I] to [src].") holdingitems[I] = TRUE updateUsrDialog() return FALSE @@ -214,7 +121,7 @@ user.set_machine(src) interact(user) -/obj/machinery/reagentgrinder/interact(mob/user) // The microwave Menu +/obj/machinery/reagentgrinder/interact(mob/user) // The microwave Menu //I am reasonably certain that this is not a microwave var/is_chamber_empty = FALSE var/is_beaker_ready = FALSE var/processing_chamber = "" @@ -307,60 +214,10 @@ holdingitems -= O updateUsrDialog() -/obj/machinery/reagentgrinder/proc/get_allowed_by_obj(obj/item/O) - for (var/i in blend_items) - if (istype(O, i)) - return blend_items[i] - -/obj/machinery/reagentgrinder/proc/get_allowed_juice_by_obj(obj/item/reagent_containers/food/snacks/O) - for(var/i in juice_items) - if(istype(O, i)) - return juice_items[i] - -/obj/machinery/reagentgrinder/proc/get_grownweapon_amount(obj/item/grown/O) - if (!istype(O) || !O.seed) - return 5 - else if (O.seed.potency == -1) - return 5 - else - return round(O.seed.potency) - -/obj/machinery/reagentgrinder/proc/get_juice_amount(obj/item/reagent_containers/food/snacks/grown/O) - if (!istype(O) || !O.seed) - return 5 - else if (O.seed.potency == -1) - return 5 - else - return round(5*sqrt(O.seed.potency)) - /obj/machinery/reagentgrinder/proc/remove_object(obj/item/O) holdingitems -= O qdel(O) -/obj/machinery/reagentgrinder/proc/juice() - power_change() - if(!beaker || (beaker && (beaker.reagents.total_volume >= beaker.reagents.maximum_volume))) - return - operate_for(50, juicing = TRUE) - - //Snacks - for(var/obj/item/i in holdingitems) - var/obj/item/I = i - if(istype(I, /obj/item/reagent_containers/food/snacks)) - var/obj/item/reagent_containers/food/snacks/O = I - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - var/list/allowed = get_allowed_juice_by_obj(O) - if(isnull(allowed)) - break - for(var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = get_juice_amount(O) - beaker.reagents.add_reagent(r_id, min(amount, space)) - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - remove_object(O) - /obj/machinery/reagentgrinder/proc/shake_for(duration) var/offset = prob(50) ? -2 : 2 var/old_pixel_x = pixel_x @@ -386,8 +243,26 @@ operating = FALSE updateUsrDialog() -/obj/machinery/reagentgrinder/proc/grind() +/obj/machinery/reagentgrinder/proc/juice() + power_change() + if(!beaker || (beaker && (beaker.reagents.total_volume >= beaker.reagents.maximum_volume))) + return + operate_for(50, juicing = TRUE) + for(var/obj/item/i in holdingitems) + if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + var/obj/item/I = i + if(I.juice_results) + juice_item(I) +/obj/machinery/reagentgrinder/proc/juice_item(obj/item/I) //Juicing results can be found in respective object definitions + if(I.on_juice(src) == -1) + to_chat(usr, "[src] shorts out as it tries to juice up [I], and transfers it back to storage.") + return + beaker.reagents.add_reagent_list(I.juice_results) + remove_object(I) + +/obj/machinery/reagentgrinder/proc/grind() power_change() if(!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume)) return @@ -396,82 +271,17 @@ if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) break var/obj/item/I = i - //Snacks - if(istype(I, /obj/item/reagent_containers/food/snacks)) - var/obj/item/reagent_containers/food/snacks/O = I - var/list/allowed = get_allowed_by_obj(O) - if(isnull(allowed)) - continue - for(var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - if(amount <= 0) - if(amount == 0) - if (O.reagents != null && O.reagents.has_reagent("nutriment")) - beaker.reagents.add_reagent(r_id, min(O.reagents.get_reagent_amount("nutriment"), space)) - O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space)) - else - if (O.reagents != null && O.reagents.has_reagent("nutriment")) - beaker.reagents.add_reagent(r_id, min(round(O.reagents.get_reagent_amount("nutriment")*abs(amount)), space)) - O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space)) - else - O.reagents.trans_id_to(beaker, r_id, min(amount, space)) - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - if(O.reagents.reagent_list.len == 0) - remove_object(O) - //Sheets - else if(istype(I, /obj/item/stack/sheet)) - var/obj/item/stack/sheet/O = I - var/list/allowed = get_allowed_by_obj(O) - for(var/t in 1 to round(O.amount, 1)) - for(var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - beaker.reagents.add_reagent(r_id,min(amount, space)) - if (space < amount) - break - if(t == round(O.amount, 1)) - remove_object(O) - break - //Plants - else if(istype(I, /obj/item/grown)) - var/obj/item/grown/O = I - var/list/allowed = get_allowed_by_obj(O) - for (var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - if (amount == 0) - if (O.reagents != null && O.reagents.has_reagent(r_id)) - beaker.reagents.add_reagent(r_id,min(O.reagents.get_reagent_amount(r_id), space)) - else - beaker.reagents.add_reagent(r_id,min(amount, space)) - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - remove_object(O) - else if(istype(I, /obj/item/slime_extract)) - var/obj/item/slime_extract/O = I - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - if (O.reagents != null) - var/amount = O.reagents.total_volume - O.reagents.trans_to(beaker, min(amount, space)) - if (O.Uses > 0) - beaker.reagents.add_reagent("slimejelly",min(20, space)) - remove_object(O) - if(istype(I, /obj/item/reagent_containers)) - var/obj/item/reagent_containers/O = I - var/amount = O.reagents.total_volume - O.reagents.trans_to(beaker, amount) - if(!O.reagents.total_volume) - remove_object(O) - else if(istype(I, /obj/item/toy/crayon)) - var/obj/item/toy/crayon/O = I - for (var/r_id in O.reagent_contents) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - if(!space) - break - beaker.reagents.add_reagent(r_id, min(O.reagent_contents[r_id], space)) - remove_object(O) + if(I.grind_results) + grind_item(i) + +/obj/machinery/reagentgrinder/proc/grind_item(obj/item/I) //Grind results can be found in respective object definitions + if(I.on_grind(src) == -1) //Call on_grind() to change amount as needed, and stop grinding the item if it returns -1 + to_chat(usr, "[src] shorts out as it tries to grind up [I], and transfers it back to storage.") + return + beaker.reagents.add_reagent_list(I.grind_results) + if(I.reagents) + I.reagents.trans_to(beaker, I.reagents.total_volume) + remove_object(I) /obj/machinery/reagentgrinder/proc/mix(mob/user) //For butter and other things that would change upon shaking or mixing @@ -484,7 +294,7 @@ /obj/machinery/reagentgrinder/proc/mix_complete() if(beaker && beaker.reagents.total_volume) //Recipe to make Butter - var/butter_amt = Floor(beaker.reagents.get_reagent_amount("milk") / MILK_TO_BUTTER_COEFF) + var/butter_amt = FLOOR(beaker.reagents.get_reagent_amount("milk") / MILK_TO_BUTTER_COEFF, 1) beaker.reagents.remove_reagent("milk", MILK_TO_BUTTER_COEFF * butter_amt) for(var/i in 1 to butter_amt) new /obj/item/reagent_containers/food/snacks/butter(drop_location()) diff --git a/code/modules/reagents/chemistry/machinery/smoke_machine.dm b/code/modules/reagents/chemistry/machinery/smoke_machine.dm index dc92dd3b52..7941853a91 100644 --- a/code/modules/reagents/chemistry/machinery/smoke_machine.dm +++ b/code/modules/reagents/chemistry/machinery/smoke_machine.dm @@ -1,3 +1,5 @@ +#define REAGENTS_BASE_VOLUME 100 // actual volume is REAGENTS_BASE_VOLUME plus REAGENTS_BASE_VOLUME * rating for each matterbin + /obj/machinery/smoke_machine name = "smoke machine" desc = "A machine with a centrifuge installed into it. It produces smoke with any reagents you put into the machine." @@ -11,14 +13,13 @@ var/cooldown = 0 var/screen = "home" var/useramount = 30 // Last used amount - var/volume = 300 - var/setting = 3 - var/list/possible_settings = list(3,6,9) + var/setting = 1 // displayed range is 3 * setting + var/max_range = 3 // displayed max range is 3 * max range -/datum/effect_system/smoke_spread/chem/smoke_machine/set_up(datum/reagents/carry, setting = 3, efficiency = 10, loc) - amount = setting +/datum/effect_system/smoke_spread/chem/smoke_machine/set_up(datum/reagents/carry, setting=1, efficiency=10, loc) + amount = setting * 3 carry.copy_to(chemholder, 20) - carry.remove_any(setting * 16 / efficiency) + carry.remove_any(amount * 16 / efficiency) location = loc /datum/effect_system/smoke_spread/chem/smoke_machine @@ -28,10 +29,11 @@ opaque = FALSE alpha = 100 - /obj/machinery/smoke_machine/Initialize() . = ..() - create_reagents(volume) + create_reagents(REAGENTS_BASE_VOLUME) + for(var/obj/item/stock_parts/matter_bin/B in component_parts) + reagents.maximum_volume += REAGENTS_BASE_VOLUME * B.rating /obj/machinery/smoke_machine/update_icon() if((!is_operational()) || (!on) || (reagents.total_volume == 0)) @@ -41,13 +43,22 @@ . = ..() /obj/machinery/smoke_machine/RefreshParts() - efficiency = 6 + var/new_volume = REAGENTS_BASE_VOLUME for(var/obj/item/stock_parts/matter_bin/B in component_parts) - efficiency += B.rating + new_volume += REAGENTS_BASE_VOLUME * B.rating + if(!reagents) + create_reagents(new_volume) + reagents.maximum_volume = new_volume + if(new_volume < reagents.total_volume) + reagents.reaction(loc, TOUCH) // if someone manages to downgrade it without deconstructing + reagents.clear_reagents() + efficiency = 9 for(var/obj/item/stock_parts/capacitor/C in component_parts) efficiency += C.rating + max_range = 1 for(var/obj/item/stock_parts/manipulator/M in component_parts) - efficiency += M.rating + max_range += M.rating + max_range = max(3, max_range) /obj/machinery/smoke_machine/process() ..() @@ -78,6 +89,11 @@ return return ..() +/obj/machinery/smoke_machine/deconstruct() + reagents.reaction(loc, TOUCH) + reagents.clear_reagents() + return ..() + /obj/machinery/smoke_machine/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) @@ -99,6 +115,7 @@ data["active"] = on data["setting"] = setting data["screen"] = screen + data["maxSetting"] = max_range return data /obj/machinery/smoke_machine/ui_act(action, params) @@ -110,7 +127,7 @@ . = TRUE if("setting") var/amount = text2num(params["amount"]) - if (locate(amount) in possible_settings) + if(amount in 1 to max_range) setting = amount . = TRUE if("power") @@ -122,3 +139,5 @@ if("goScreen") screen = params["screen"] . = TRUE + +#undef REAGENTS_BASE_VOLUME diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index 5f76a87654..9f8e129420 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -41,7 +41,7 @@ return 0 if(method == VAPOR) //smoke, foam, spray if(M.reagents) - var/modifier = Clamp((1 - touch_protection), 0, 1) + var/modifier = CLAMP((1 - touch_protection), 0, 1) var/amount = round(reac_volume*modifier, 0.1) if(amount >= 0.5) M.reagents.add_reagent(id, amount) diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm index 9321c6b015..00fd7d56a3 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm @@ -109,7 +109,7 @@ All effects don't start immediately, but rather get worse over time; the rate is color = "#664300" // rgb: 102, 67, 0 boozepwr = 45 glass_icon_state = "kahluaglass" - glass_name = "glass of RR Coffee Liquor" + glass_name = "glass of RR coffee liquor" glass_desc = "DAMN, THIS THING LOOKS ROBUST!" shot_glass_icon_state = "shotglasscream" @@ -341,7 +341,7 @@ All effects don't start immediately, but rather get worse over time; the rate is boozepwr = 25 taste_description = "burning cinnamon" glass_icon_state = "goldschlagerglass" - glass_name = "glass of Goldschlager" + glass_name = "glass of goldschlager" glass_desc = "100% proof that teen girls will drink anything with gold in it." shot_glass_icon_state = "shotglassgold" @@ -396,7 +396,7 @@ All effects don't start immediately, but rather get worse over time; the rate is boozepwr = 70 taste_description = "cola" glass_icon_state = "whiskeycolaglass" - glass_name = "Whiskey Cola" + glass_name = "whiskey cola" glass_desc = "An innocent-looking mixture of cola and Whiskey. Delicious." /datum/reagent/consumable/ethanol/martini @@ -706,7 +706,7 @@ All effects don't start immediately, but rather get worse over time; the rate is boozepwr = 70 taste_description = "soda" glass_icon_state = "whiskeysodaglass2" - glass_name = "Whiskey Soda" + glass_name = "whiskey soda" glass_desc = "Ultimate refreshment." /datum/reagent/consumable/ethanol/antifreeze @@ -785,7 +785,7 @@ All effects don't start immediately, but rather get worse over time; the rate is boozepwr = 70 taste_description = "tart bitterness" glass_icon_state = "vodkatonicglass" - glass_name = "Vodka and Tonic" + glass_name = "vodka and tonic" glass_desc = "For when a gin and tonic isn't Russian enough." @@ -797,7 +797,7 @@ All effects don't start immediately, but rather get worse over time; the rate is boozepwr = 45 taste_description = "dry, tart lemons" glass_icon_state = "ginfizzglass" - glass_name = "Gin Fizz" + glass_name = "gin fizz" glass_desc = "Refreshingly lemony, deliciously dry." @@ -870,7 +870,7 @@ All effects don't start immediately, but rather get worse over time; the rate is boozepwr = 15 taste_description = "refreshingly cold" glass_icon_state = "iced_beerglass" - glass_name = "Iced Beer" + glass_name = "iced beer" glass_desc = "A beer so frosty, the air around it freezes." /datum/reagent/consumable/ethanol/iced_beer/on_mob_life(mob/living/M) @@ -961,7 +961,7 @@ All effects don't start immediately, but rather get worse over time; the rate is var/datum/antagonist/changeling/changeling = M.mind.has_antag_datum(/datum/antagonist/changeling) if(changeling) changeling.chem_charges += metabolization_rate - changeling.chem_charges = Clamp(changeling.chem_charges, 0, changeling.chem_storage) + changeling.chem_charges = CLAMP(changeling.chem_charges, 0, changeling.chem_storage) return ..() /datum/reagent/consumable/ethanol/irishcarbomb @@ -1069,7 +1069,7 @@ All effects don't start immediately, but rather get worse over time; the rate is boozepwr = 35 taste_description = "sour lemons" glass_icon_state = "whiskey_sour" - glass_name = "Whiskey Sour" + glass_name = "whiskey sour" glass_desc = "Lemon juice mixed with whiskey and a dash of sugar. Surprisingly satisfying." /datum/reagent/consumable/ethanol/hcider @@ -1081,7 +1081,7 @@ All effects don't start immediately, but rather get worse over time; the rate is boozepwr = 25 taste_description = "apples" glass_icon_state = "whiskeyglass" - glass_name = "Hard Cider" + glass_name = "hard cider" glass_desc = "Tastes like autumn." shot_glass_icon_state = "shotglassbrown" @@ -1279,5 +1279,5 @@ All effects don't start immediately, but rather get worse over time; the rate is boozepwr = 1 taste_description = "custard and alcohol" glass_icon_state = "glass_yellow" - glass_name = "Eggnog" + glass_name = "eggnog" glass_desc = "For enjoying the most wonderful time of the year." diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm index 308fd47a16..b62afb80c0 100644 --- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm @@ -148,7 +148,7 @@ description = "Absolutely nothing." taste_description = "nothing" glass_icon_state = "nothing" - glass_name = "Nothing" + glass_name = "nothing" glass_desc = "Absolutely nothing." shot_glass_icon_state = "shotglass" @@ -319,7 +319,7 @@ nutriment_factor = 0 taste_description = "bitter coldness" glass_icon_state = "icedcoffeeglass" - glass_name = "Iced Coffee" + glass_name = "iced coffee" glass_desc = "A drink to perk you up and refresh you!" /datum/reagent/consumable/icecoffee/on_mob_life(mob/living/M) @@ -340,7 +340,7 @@ nutriment_factor = 0 taste_description = "sweet tea" glass_icon_state = "icedteaglass" - glass_name = "Iced Tea" + glass_name = "iced tea" glass_desc = "All natural, antioxidant-rich flavour sensation." /datum/reagent/consumable/icetea/on_mob_life(mob/living/M) @@ -361,7 +361,7 @@ color = "#100800" // rgb: 16, 8, 0 taste_description = "cola" glass_icon_state = "glass_brown" - glass_name = "glass of space Cola" + glass_name = "glass of Space Cola" glass_desc = "A glass of refreshing Space Cola." /datum/reagent/consumable/space_cola/on_mob_life(mob/living/M) @@ -377,7 +377,7 @@ color = "#100800" // rgb: 16, 8, 0 taste_description = "the future" glass_icon_state = "nuka_colaglass" - glass_name = "Nuka Cola" + glass_name = "glass of Nuka Cola" glass_desc = "Don't cry, Don't raise your eye, It's only nuclear wasteland." /datum/reagent/consumable/nuka_cola/on_mob_life(mob/living/M) @@ -434,7 +434,7 @@ color = "#00FF00" // rgb: 0, 255, 0 taste_description = "cherry soda" glass_icon_state = "space-up_glass" - glass_name = "glass of Space-up" + glass_name = "glass of Space-Up" glass_desc = "Space-up. It helps you keep your cool." @@ -450,7 +450,7 @@ color = "#8CFF00" // rgb: 135, 255, 0 taste_description = "tangy lime and lemon soda" glass_icon_state = "glass_yellow" - glass_name = "glass of Lemon-Lime" + glass_name = "glass of lemon-lime" glass_desc = "You're pretty certain a real fruit has never actually touched this." @@ -481,7 +481,7 @@ color = "#f00060" // rgb: 94, 0, 38 taste_description = "carbonated metallic soda" glass_icon_state = "glass_red" - glass_name = "glass of Shambler's Juice" + glass_name = "glass of Shambler's juice" glass_desc = "Mmm mm, shambly." /datum/reagent/consumable/shamblers/on_mob_life(mob/living/M) @@ -495,7 +495,7 @@ color = "#619494" // rgb: 97, 148, 148 taste_description = "carbonated water" glass_icon_state = "glass_clear" - glass_name = "glass of Soda Water" + glass_name = "glass of soda water" glass_desc = "Soda water. Why not make a scotch and soda?" /datum/reagent/consumable/sodawater/on_mob_life(mob/living/M) @@ -512,7 +512,7 @@ color = "#0064C8" // rgb: 0, 100, 200 taste_description = "tart and fresh" glass_icon_state = "glass_clear" - glass_name = "glass of Tonic Water" + glass_name = "glass of tonic water" glass_desc = "Quinine tastes funny, but at least it'll keep that Space Malaria away." /datum/reagent/consumable/tonic/on_mob_life(mob/living/M) @@ -546,7 +546,7 @@ color = "#664300" // rgb: 102, 67, 0 taste_description = "creamy coffee" glass_icon_state = "soy_latte" - glass_name = "Soy Latte" + glass_name = "soy latte" glass_desc = "A nice and refreshing beverage while you're reading." /datum/reagent/consumable/soy_latte/on_mob_life(mob/living/M) @@ -568,7 +568,7 @@ color = "#664300" // rgb: 102, 67, 0 taste_description = "bitter cream" glass_icon_state = "cafe_latte" - glass_name = "Cafe Latte" + glass_name = "cafe latte" glass_desc = "A nice, strong and refreshing beverage while you're reading." /datum/reagent/consumable/cafe_latte/on_mob_life(mob/living/M) @@ -612,7 +612,7 @@ nutriment_factor = 4 * REAGENTS_METABOLISM taste_description = "sweet chocolate" glass_icon_state = "chocolatepudding" - glass_name = "Chocolate Pudding" + glass_name = "chocolate pudding" glass_desc = "Tasty." /datum/reagent/consumable/vanillapudding @@ -623,7 +623,7 @@ nutriment_factor = 4 * REAGENTS_METABOLISM taste_description = "sweet vanilla" glass_icon_state = "vanillapudding" - glass_name = "Vanilla Pudding" + glass_name = "vanilla pudding" glass_desc = "Tasty." /datum/reagent/consumable/cherryshake @@ -634,7 +634,7 @@ nutriment_factor = 4 * REAGENTS_METABOLISM taste_description = "creamy cherry" glass_icon_state = "cherryshake" - glass_name = "Cherry Shake" + glass_name = "cherry shake" glass_desc = "A cherry flavored milkshake." /datum/reagent/consumable/bluecherryshake @@ -645,7 +645,7 @@ nutriment_factor = 4 * REAGENTS_METABOLISM taste_description = "creamy blue cherry" glass_icon_state = "bluecherryshake" - glass_name = "Blue Cherry Shake" + glass_name = "blue cherry shake" glass_desc = "An exotic blue milkshake." /datum/reagent/consumable/pumpkin_latte @@ -656,7 +656,7 @@ nutriment_factor = 3 * REAGENTS_METABOLISM taste_description = "creamy pumpkin" glass_icon_state = "pumpkin_latte" - glass_name = "Pumpkin Latte" + glass_name = "pumpkin latte" glass_desc = "A mix of coffee and pumpkin juice." /datum/reagent/consumable/gibbfloats diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm index 60d1f64754..534cf515d9 100644 --- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm @@ -99,7 +99,7 @@ . = 1 /datum/reagent/drug/crank/addiction_act_stage4(mob/living/M) - M.adjustBrainLoss(5*REM) + M.adjustBrainLoss(3*REM) M.adjustToxLoss(5*REM, 0) M.adjustBruteLoss(5*REM, 0) ..() diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index 08db315b7d..a3c0d2c034 100644 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -628,7 +628,7 @@ . = 1 if(prob(20)) M.losebreath += 4 - M.adjustBrainLoss(2*REM) + M.adjustBrainLoss(2*REM, 150) M.adjustToxLoss(3*REM,0) M.adjustStaminaLoss(10*REM,0) M.blur_eyes(5) diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 7547a0834c..ddb08db032 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -59,6 +59,7 @@ M.confused = 0 M.SetSleeping(0, 0) M.jitteriness = 0 + M.cure_all_traumas(TRUE, TRUE) for(var/thing in M.viruses) var/datum/disease/D = thing if(D.severity == VIRUS_SEVERITY_POSITIVE) @@ -792,7 +793,13 @@ color = "#DCDCFF" /datum/reagent/medicine/mannitol/on_mob_life(mob/living/M) - M.adjustBrainLoss(-3*REM) + M.adjustBrainLoss(-2*REM) + if(iscarbon(M)) + var/mob/living/carbon/C = M + if(prob(30) && C.has_trauma_type(BRAIN_TRAUMA_SPECIAL)) + C.cure_trauma_type(BRAIN_TRAUMA_SPECIAL) + if(prob(10) && C.has_trauma_type(BRAIN_TRAUMA_MILD)) + C.cure_trauma_type(BRAIN_TRAUMA_MILD) ..() /datum/reagent/medicine/mutadone @@ -1016,7 +1023,7 @@ M.adjustFireLoss(-3 * REM, 0) M.adjustOxyLoss(-15 * REM, 0) M.adjustToxLoss(-3 * REM, 0) - M.adjustBrainLoss(2 * REM) //This does, after all, come from ambrosia, and the most powerful ambrosia in existence, at that! + M.adjustBrainLoss(2 * REM, 150) //This does, after all, come from ambrosia, and the most powerful ambrosia in existence, at that! M.adjustCloneLoss(-1 * REM, 0) M.adjustStaminaLoss(-30 * REM, 0) M.jitteriness = min(max(0, M.jitteriness + 3), 30) @@ -1047,7 +1054,7 @@ if (M.hallucination >= 5) M.hallucination -= 5 if(prob(20)) - M.adjustBrainLoss(1*REM) + M.adjustBrainLoss(1*REM, 50) M.adjustStaminaLoss(2.5*REM, 0) ..() . = 1 diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index aab8491249..219d9df8ef 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -117,7 +117,7 @@ taste_description = "water" var/cooling_temperature = 2 glass_icon_state = "glass_clear" - glass_name = "glass of Water" + glass_name = "glass of water" glass_desc = "The father of all refreshments." shot_glass_icon_state = "shotglassclear" @@ -188,7 +188,7 @@ description = "Water blessed by some deity." color = "#E0E8EF" // rgb: 224, 232, 239 glass_icon_state = "glass_clear" - glass_name = "glass of Holy Water" + glass_name = "glass of holy water" glass_desc = "A glass of holy water." /datum/reagent/water/holywater/reaction_mob(mob/living/M, method=TOUCH, reac_volume) @@ -261,7 +261,7 @@ M.adjustBruteLoss(-2, 0) M.adjustFireLoss(-2, 0) else - M.adjustBrainLoss(3) + M.adjustBrainLoss(3, 150) M.adjustToxLoss(1, 0) M.adjustFireLoss(2, 0) M.adjustOxyLoss(2, 0) @@ -280,7 +280,7 @@ M.IgniteMob() //Only problem with igniting people is currently the commonly availible fire suits make you immune to being on fire M.adjustToxLoss(1, 0) M.adjustFireLoss(1, 0) //Hence the other damages... ain't I a bastard? - M.adjustBrainLoss(5) + M.adjustBrainLoss(5, 150) holder.remove_reagent(src.id, 1) /datum/reagent/medicine/omnizine/godblood @@ -676,7 +676,7 @@ step(M, pick(GLOB.cardinals)) if(prob(5)) M.emote(pick("twitch","drool","moan")) - M.adjustBrainLoss(2) + M.adjustBrainLoss(1) ..() /datum/reagent/sulfur @@ -1029,7 +1029,7 @@ /datum/reagent/impedrezene/on_mob_life(mob/living/M) M.jitteriness = max(M.jitteriness-5,0) if(prob(80)) - M.adjustBrainLoss(1*REM) + M.adjustBrainLoss(2*REM) if(prob(50)) M.drowsyness = max(M.drowsyness, 3) if(prob(10)) diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index fd7d5750f1..7bee2ef958 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -455,13 +455,12 @@ toxpwr = 0 /datum/reagent/toxin/neurotoxin2/on_mob_life(mob/living/M) - if(M.brainloss + M.toxloss <= 60) - M.adjustBrainLoss(1*REM) + M.adjustBrainLoss(3*REM, 150) + . = 1 + if(M.toxloss <= 60) M.adjustToxLoss(1*REM, 0) - . = 1 if(current_cycle >= 18) M.Sleeping(40, 0) - . = 1 ..() /datum/reagent/toxin/cyanide @@ -851,9 +850,9 @@ /datum/reagent/toxin/peaceborg/confuse/on_mob_life(mob/living/M) if(M.confused < 6) - M.confused = Clamp(M.confused + 3, 0, 5) + M.confused = CLAMP(M.confused + 3, 0, 5) if(M.dizziness < 6) - M.dizziness = Clamp(M.dizziness + 3, 0, 5) + M.dizziness = CLAMP(M.dizziness + 3, 0, 5) if(prob(20)) to_chat(M, "You feel confused and disorientated.") ..() diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm index aa97dd3180..b77dcc435a 100644 --- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm +++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm @@ -139,7 +139,6 @@ /datum/chemical_reaction/reagent_explosion/methsplosion name = "Meth explosion" id = "methboom1" - results = list("methboom1" = 1) required_temp = 380 //slightly above the meth mix time. required_reagents = list("methamphetamine" = 1) strengthdiv = 6 @@ -154,9 +153,9 @@ ..() /datum/chemical_reaction/reagent_explosion/methsplosion/methboom2 + id = "methboom2" required_reagents = list("diethylamine" = 1, "iodine" = 1, "phosphorus" = 1, "hydrogen" = 1) //diethylamine is often left over from mixing the ephedrine. - required_temp = 300 //room temperature, chilling it even a little will prevent the explosion - results = list("methboom1" = 4) // this is ugly. Sorry goof. + required_temp = 300 //room temperature, chilling it even a little will prevent the explosion /datum/chemical_reaction/sorium name = "Sorium" @@ -169,7 +168,7 @@ return holder.remove_reagent("sorium", created_volume*4) var/turf/T = get_turf(holder.my_atom) - var/range = Clamp(sqrt(created_volume*4), 1, 6) + var/range = CLAMP(sqrt(created_volume*4), 1, 6) goonchem_vortex(T, 1, range) /datum/chemical_reaction/sorium_vortex @@ -180,7 +179,7 @@ /datum/chemical_reaction/sorium_vortex/on_reaction(datum/reagents/holder, created_volume) var/turf/T = get_turf(holder.my_atom) - var/range = Clamp(sqrt(created_volume), 1, 6) + var/range = CLAMP(sqrt(created_volume), 1, 6) goonchem_vortex(T, 1, range) /datum/chemical_reaction/liquid_dark_matter @@ -194,7 +193,7 @@ return holder.remove_reagent("liquid_dark_matter", created_volume*3) var/turf/T = get_turf(holder.my_atom) - var/range = Clamp(sqrt(created_volume*3), 1, 6) + var/range = CLAMP(sqrt(created_volume*3), 1, 6) goonchem_vortex(T, 0, range) /datum/chemical_reaction/ldm_vortex @@ -205,7 +204,7 @@ /datum/chemical_reaction/ldm_vortex/on_reaction(datum/reagents/holder, created_volume) var/turf/T = get_turf(holder.my_atom) - var/range = Clamp(sqrt(created_volume/2), 1, 6) + var/range = CLAMP(sqrt(created_volume/2), 1, 6) goonchem_vortex(T, 0, range) /datum/chemical_reaction/flash_powder @@ -382,7 +381,6 @@ name = "Teslium Destabilization" id = "teslium_lightning" required_reagents = list("teslium" = 1, "water" = 1) - results = list("destabilized_teslium" = 1) strengthdiv = 100 modifier = -100 mix_message = "The teslium starts to spark as electricity arcs away from it!" diff --git a/code/modules/reagents/chemistry/recipes/slime_extracts.dm b/code/modules/reagents/chemistry/recipes/slime_extracts.dm index f3143e1193..9b04eb1b0a 100644 --- a/code/modules/reagents/chemistry/recipes/slime_extracts.dm +++ b/code/modules/reagents/chemistry/recipes/slime_extracts.dm @@ -152,11 +152,10 @@ var/chosen = pick(borks) var/obj/B = new chosen(T) if(prob(5))//Fry it! - var/obj/item/reagent_containers/food/snacks/deepfryholder/D = new(T) - var/datum/reagents/reagents = new(25) - reagents.add_reagent("nutriment", 25) - D.fry(B, reagents) - B = D + var/obj/item/reagent_containers/food/snacks/deepfryholder/fried + fried = new(T, B) + fried.fry() // actually set the name and colour it + B = fried if(prob(50)) for(var/j in 1 to rand(1, 3)) step(B, pick(NORTH,SOUTH,EAST,WEST)) diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 8698c10b05..6fb21e847b 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -48,15 +48,6 @@ /obj/item/reagent_containers/afterattack(obj/target, mob/user , flag) return -/obj/item/reagent_containers/proc/reagentlist(obj/item/reagent_containers/snack) //Attack logs for regents in pills - var/data - if(snack.reagents.reagent_list && snack.reagents.reagent_list.len) //find a reagent list if there is and check if it has entries - for (var/datum/reagent/R in snack.reagents.reagent_list) //no reagents will be left behind - data += "[R.id]([R.volume] units); " //Using IDs because SOME chemicals(I'm looking at you, chlorhydrate-beer) have the same names as other chemicals. - return data - else - return "No reagents" - /obj/item/reagent_containers/proc/canconsume(mob/eater, mob/user) if(!iscarbon(eater)) return 0 @@ -80,8 +71,7 @@ ..() /obj/item/reagent_containers/fire_act(exposed_temperature, exposed_volume) - reagents.chem_temp += 30 - reagents.handle_reactions() + reagents.expose_temperature(exposed_temperature) ..() /obj/item/reagent_containers/throw_impact(atom/target) @@ -127,7 +117,8 @@ reagents.clear_reagents() /obj/item/reagent_containers/microwave_act(obj/machinery/microwave/M) - if(is_open_container()) - reagents.chem_temp = max(reagents.chem_temp, 1000) - reagents.handle_reactions() + reagents.expose_temperature(1000) ..() + +/obj/item/reagent_containers/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) + reagents.expose_temperature(exposed_temperature) diff --git a/code/modules/reagents/reagent_containers/blood_pack.dm b/code/modules/reagents/reagent_containers/blood_pack.dm index a4d766539f..bc92521b93 100644 --- a/code/modules/reagents/reagent_containers/blood_pack.dm +++ b/code/modules/reagents/reagent_containers/blood_pack.dm @@ -40,6 +40,9 @@ if(51 to INFINITY) icon_state = "full" +/obj/item/reagent_containers/blood/random + icon_state = "random_bloodpack" + /obj/item/reagent_containers/blood/random/Initialize() blood_type = pick("A+", "A-", "B+", "B-", "O+", "O-", "L") . = ..() diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm index 28a07d5862..0a99d9da6e 100644 --- a/code/modules/reagents/reagent_containers/borghydro.dm +++ b/code/modules/reagents/reagent_containers/borghydro.dm @@ -173,7 +173,7 @@ Borg Shaker if(!proximity) return - else if(target.is_open_container() && target.reagents) + else if(target.is_refillable()) var/datum/reagents/R = reagent_list[mode] if(!R.total_volume) to_chat(user, "[src] is currently out of this ingredient! Please allow some time for the synthesizer to produce more.") diff --git a/code/modules/reagents/reagent_containers/dropper.dm b/code/modules/reagents/reagent_containers/dropper.dm index 30aa67e91a..144db32a6c 100644 --- a/code/modules/reagents/reagent_containers/dropper.dm +++ b/code/modules/reagents/reagent_containers/dropper.dm @@ -6,7 +6,7 @@ amount_per_transfer_from_this = 5 possible_transfer_amounts = list(1, 2, 3, 4, 5) volume = 5 - container_type = TRANSPARENT_1 + container_type = TRANSPARENT /obj/item/reagent_containers/dropper/afterattack(obj/target, mob/user , proximity) if(!proximity) diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index c27e2e9ea5..06a242cca9 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -3,7 +3,7 @@ amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5, 10, 15, 20, 25, 30, 50) volume = 50 - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER spillable = TRUE resistance_flags = ACID_PROOF @@ -44,7 +44,7 @@ if(!reagents || !reagents.total_volume) return // The drink might be empty after the delay, such as by spam-feeding M.visible_message("[user] feeds something to [M].", "[user] feeds something to you.") - add_logs(user, M, "fed", reagentlist(src)) + add_logs(user, M, "fed", reagents.log_list()) else to_chat(user, "You swallow a gulp of [src].") var/fraction = min(5/reagents.total_volume, 1) @@ -56,32 +56,30 @@ if((!proximity) || !check_allowed_items(target,target_self=1)) return - else if(istype(target, /obj/structure/reagent_dispensers)) //A dispenser. Transfer FROM it TO us. - - if(target.reagents && !target.reagents.total_volume) - to_chat(user, "[target] is empty and can't be refilled!") - return - - if(reagents.total_volume >= reagents.maximum_volume) - to_chat(user, "[src] is full.") - return - - var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this) - to_chat(user, "You fill [src] with [trans] unit\s of the contents of [target].") - - else if(target.is_open_container() && target.reagents) //Something like a glass. Player probably wants to transfer TO it. + if(target.is_refillable()) //Something like a glass. Player probably wants to transfer TO it. if(!reagents.total_volume) to_chat(user, "[src] is empty!") return - if(target.reagents.total_volume >= target.reagents.maximum_volume) - to_chat(user, "[target] is full.") + if(target.reagents.holder_full()) + to_chat(user, "[target] is full.") return - var/trans = reagents.trans_to(target, amount_per_transfer_from_this) to_chat(user, "You transfer [trans] unit\s of the solution to [target].") + else if(target.is_drainable()) //A dispenser. Transfer FROM it TO us. + if(!target.reagents.total_volume) + to_chat(user, "[target] is empty and can't be refilled!") + return + + if(reagents.holder_full()) + to_chat(user, "[src] is full.") + return + + var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this) + to_chat(user, "You fill [src] with [trans] unit\s of the contents of [target].") + else if(reagents.total_volume) if(user.a_intent == INTENT_HARM) user.visible_message("[user] splashes the contents of [src] onto [target]!", \ @@ -91,15 +89,9 @@ /obj/item/reagent_containers/glass/attackby(obj/item/I, mob/user, params) var/hotness = I.is_hot() - if(hotness) - var/added_heat = (hotness / 100) //ishot returns a temperature - if(reagents) - if(reagents.chem_temp < hotness) //can't be heated to be hotter than the source - reagents.chem_temp += added_heat - to_chat(user, "You heat [src] with [I].") - reagents.handle_reactions() - else - to_chat(user, "[src] is already hotter than [I]!") + if(hotness && reagents) + reagents.expose_temperature(hotness) + to_chat(user, "You heat [name] with [I]!") if(istype(I, /obj/item/reagent_containers/food/snacks/egg)) //breaking eggs var/obj/item/reagent_containers/food/snacks/egg/E = I @@ -169,7 +161,6 @@ volume = 100 amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5,10,15,20,25,30,50,100) - flags_1 = OPENCONTAINER_1 /obj/item/reagent_containers/glass/beaker/noreact name = "cryostasis beaker" @@ -179,8 +170,6 @@ materials = list(MAT_METAL=3000) volume = 50 amount_per_transfer_from_this = 10 - origin_tech = "materials=2;engineering=3;plasmatech=3" - flags_1 = OPENCONTAINER_1 /obj/item/reagent_containers/glass/beaker/noreact/Initialize() . = ..() @@ -196,8 +185,6 @@ volume = 300 amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5,10,15,20,25,30,50,100,300) - flags_1 = OPENCONTAINER_1 - origin_tech = "bluespace=5;materials=4;plasmatech=4" /obj/item/reagent_containers/glass/beaker/cryoxadone list_reagents = list("cryoxadone" = 30) @@ -240,7 +227,6 @@ amount_per_transfer_from_this = 20 possible_transfer_amounts = list(10,15,20,25,30,50,70) volume = 70 - flags_1 = OPENCONTAINER_1 flags_inv = HIDEHAIR slot_flags = SLOT_HEAD resistance_flags = NONE @@ -298,7 +284,6 @@ materials = list(MAT_GLASS=0) volume = 50 amount_per_transfer_from_this = 10 - origin_tech = null /obj/item/reagent_containers/glass/beaker/waterbottle/empty list_reagents = list() @@ -412,4 +397,4 @@ /obj/item/reagent_containers/glass/beaker/large/bromine name = "bromine beaker" - list_reagents = list("bromine" = 50) \ No newline at end of file + list_reagents = list("bromine" = 50) diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index dff0869322..53e0c9bfb6 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -10,7 +10,7 @@ volume = 30 possible_transfer_amounts = list() resistance_flags = ACID_PROOF - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER slot_flags = SLOT_BELT var/ignore_flags = 0 var/infinite = FALSE @@ -88,7 +88,7 @@ amount_per_transfer_from_this = 10 volume = 10 ignore_flags = 1 //so you can medipen through hardsuits - container_type = DRAWABLE_1 + container_type = DRAWABLE flags_1 = null list_reagents = list("epinephrine" = 10) diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index 324623edbd..4908a55911 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -1,154 +1,160 @@ -/obj/item/reagent_containers/pill - name = "pill" - desc = "A tablet or capsule." - icon = 'icons/obj/chemical.dmi' - icon_state = "pill" - item_state = "pill" - lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' - possible_transfer_amounts = list() - volume = 50 - var/apply_type = INGEST - var/apply_method = "swallow" - var/roundstart = 0 - var/self_delay = 0 //pills are instant, this is because patches inheret their aplication from pills - -/obj/item/reagent_containers/pill/Initialize() - . = ..() - if(!icon_state) - icon_state = "pill[rand(1,20)]" - if(reagents.total_volume && roundstart) - name += " ([reagents.total_volume]u)" - - -/obj/item/reagent_containers/pill/attack_self(mob/user) - return - - -/obj/item/reagent_containers/pill/attack(mob/M, mob/user, def_zone) - if(!canconsume(M, user)) - return 0 - - if(M == user) - M.visible_message("[user] attempts to [apply_method] [src].") - if(self_delay) - if(!do_mob(user, M, self_delay)) - return 0 - to_chat(M, "You [apply_method] [src].") - - else - M.visible_message("[user] attempts to force [M] to [apply_method] [src].", \ - "[user] attempts to force [M] to [apply_method] [src].") - if(!do_mob(user, M)) - return 0 - M.visible_message("[user] forces [M] to [apply_method] [src].", \ - "[user] forces [M] to [apply_method] [src].") - - - add_logs(user, M, "fed", reagentlist(src)) - if(reagents.total_volume) - reagents.reaction(M, apply_type) - reagents.trans_to(M, reagents.total_volume) - qdel(src) - return 1 - - -/obj/item/reagent_containers/pill/afterattack(obj/target, mob/user , proximity) - if(!proximity) - return - if(target.is_open_container() != 0 && target.reagents) - if(!target.reagents.total_volume) - to_chat(user, "[target] is empty! There's nothing to dissolve [src] in.") - return - to_chat(user, "You dissolve [src] in [target].") - for(var/mob/O in viewers(2, user)) //viewers is necessary here because of the small radius - to_chat(O, "[user] slips something into [target]!") - reagents.trans_to(target, reagents.total_volume) - qdel(src) - -/obj/item/reagent_containers/pill/tox - name = "toxins pill" - desc = "Highly toxic." - icon_state = "pill5" - list_reagents = list("toxin" = 50) - roundstart = 1 -/obj/item/reagent_containers/pill/cyanide - name = "cyanide pill" - desc = "Don't swallow this." - icon_state = "pill5" - list_reagents = list("cyanide" = 50) - roundstart = 1 -/obj/item/reagent_containers/pill/adminordrazine - name = "adminordrazine pill" - desc = "It's magic. We don't have to explain it." - icon_state = "pill16" - list_reagents = list("adminordrazine" = 50) - roundstart = 1 -/obj/item/reagent_containers/pill/morphine - name = "morphine pill" - desc = "Commonly used to treat insomnia." - icon_state = "pill8" - list_reagents = list("morphine" = 30) - roundstart = 1 -/obj/item/reagent_containers/pill/stimulant - name = "stimulant pill" - desc = "Often taken by overworked employees, athletes, and the inebriated. You'll snap to attention immediately!" - icon_state = "pill19" - list_reagents = list("ephedrine" = 10, "antihol" = 10, "coffee" = 30) - roundstart = 1 -/obj/item/reagent_containers/pill/salbutamol - name = "salbutamol pill" - desc = "Used to treat oxygen deprivation." - icon_state = "pill16" - list_reagents = list("salbutamol" = 30) - roundstart = 1 -/obj/item/reagent_containers/pill/charcoal - name = "charcoal pill" - desc = "Neutralizes many common toxins." - icon_state = "pill17" - list_reagents = list("charcoal" = 10) - roundstart = 1 -/obj/item/reagent_containers/pill/epinephrine - name = "epinephrine pill" - desc = "Used to stabilize patients." - icon_state = "pill5" - list_reagents = list("epinephrine" = 15) - roundstart = 1 -/obj/item/reagent_containers/pill/mannitol - name = "mannitol pill" - desc = "Used to treat brain damage." - icon_state = "pill17" - list_reagents = list("mannitol" = 50) - roundstart = 1 -/obj/item/reagent_containers/pill/mutadone - name = "mutadone pill" - desc = "Used to treat genetic damage." - icon_state = "pill20" - list_reagents = list("mutadone" = 50) - roundstart = 1 -/obj/item/reagent_containers/pill/salicyclic - name = "salicylic acid pill" - desc = "Used to dull pain." - icon_state = "pill9" - list_reagents = list("sal_acid" = 24) - roundstart = 1 -/obj/item/reagent_containers/pill/oxandrolone - name = "oxandrolone pill" - desc = "Used to stimulate burn healing." - icon_state = "pill11" - list_reagents = list("oxandrolone" = 24) - roundstart = 1 - -/obj/item/reagent_containers/pill/insulin - name = "insulin pill" - desc = "Handles hyperglycaemic coma." - icon_state = "pill18" - list_reagents = list("insulin" = 50) - roundstart = 1 - -/obj/item/reagent_containers/pill/shadowtoxin - name = "black pill" - desc = "I wouldn't eat this if I were you." - icon_state = "pill9" - color = "#454545" - list_reagents = list("shadowmutationtoxin" = 1) +/obj/item/reagent_containers/pill + name = "pill" + desc = "A tablet or capsule." + icon = 'icons/obj/chemical.dmi' + icon_state = "pill" + item_state = "pill" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + possible_transfer_amounts = list() + volume = 50 + grind_results = list() + var/apply_type = INGEST + var/apply_method = "swallow" + var/roundstart = 0 + var/self_delay = 0 //pills are instant, this is because patches inheret their aplication from pills + +/obj/item/reagent_containers/pill/Initialize() + . = ..() + if(!icon_state) + icon_state = "pill[rand(1,20)]" + if(reagents.total_volume && roundstart) + name += " ([reagents.total_volume]u)" + + +/obj/item/reagent_containers/pill/attack_self(mob/user) + return + + +/obj/item/reagent_containers/pill/attack(mob/M, mob/user, def_zone) + if(!canconsume(M, user)) + return 0 + + if(M == user) + M.visible_message("[user] attempts to [apply_method] [src].") + if(self_delay) + if(!do_mob(user, M, self_delay)) + return 0 + to_chat(M, "You [apply_method] [src].") + + else + M.visible_message("[user] attempts to force [M] to [apply_method] [src].", \ + "[user] attempts to force [M] to [apply_method] [src].") + if(!do_mob(user, M)) + return 0 + M.visible_message("[user] forces [M] to [apply_method] [src].", \ + "[user] forces [M] to [apply_method] [src].") + + + add_logs(user, M, "fed", reagents.log_list()) + if(reagents.total_volume) + reagents.reaction(M, apply_type) + reagents.trans_to(M, reagents.total_volume) + qdel(src) + return 1 + + +/obj/item/reagent_containers/pill/afterattack(obj/target, mob/user , proximity) + if(!proximity) + return + if(target.is_refillable()) + if(target.is_drainable() && !target.reagents.total_volume) + to_chat(user, "[target] is empty! There's nothing to dissolve [src] in.") + return + + if(target.reagents.holder_full()) + to_chat(user, "[target] is full.") + return + + to_chat(user, "You dissolve [src] in [target].") + for(var/mob/O in viewers(2, user)) //viewers is necessary here because of the small radius + to_chat(O, "[user] slips something into [target]!") + reagents.trans_to(target, reagents.total_volume) + qdel(src) + +/obj/item/reagent_containers/pill/tox + name = "toxins pill" + desc = "Highly toxic." + icon_state = "pill5" + list_reagents = list("toxin" = 50) + roundstart = 1 +/obj/item/reagent_containers/pill/cyanide + name = "cyanide pill" + desc = "Don't swallow this." + icon_state = "pill5" + list_reagents = list("cyanide" = 50) + roundstart = 1 +/obj/item/reagent_containers/pill/adminordrazine + name = "adminordrazine pill" + desc = "It's magic. We don't have to explain it." + icon_state = "pill16" + list_reagents = list("adminordrazine" = 50) + roundstart = 1 +/obj/item/reagent_containers/pill/morphine + name = "morphine pill" + desc = "Commonly used to treat insomnia." + icon_state = "pill8" + list_reagents = list("morphine" = 30) + roundstart = 1 +/obj/item/reagent_containers/pill/stimulant + name = "stimulant pill" + desc = "Often taken by overworked employees, athletes, and the inebriated. You'll snap to attention immediately!" + icon_state = "pill19" + list_reagents = list("ephedrine" = 10, "antihol" = 10, "coffee" = 30) + roundstart = 1 +/obj/item/reagent_containers/pill/salbutamol + name = "salbutamol pill" + desc = "Used to treat oxygen deprivation." + icon_state = "pill16" + list_reagents = list("salbutamol" = 30) + roundstart = 1 +/obj/item/reagent_containers/pill/charcoal + name = "charcoal pill" + desc = "Neutralizes many common toxins." + icon_state = "pill17" + list_reagents = list("charcoal" = 10) + roundstart = 1 +/obj/item/reagent_containers/pill/epinephrine + name = "epinephrine pill" + desc = "Used to stabilize patients." + icon_state = "pill5" + list_reagents = list("epinephrine" = 15) + roundstart = 1 +/obj/item/reagent_containers/pill/mannitol + name = "mannitol pill" + desc = "Used to treat brain damage." + icon_state = "pill17" + list_reagents = list("mannitol" = 50) + roundstart = 1 +/obj/item/reagent_containers/pill/mutadone + name = "mutadone pill" + desc = "Used to treat genetic damage." + icon_state = "pill20" + list_reagents = list("mutadone" = 50) + roundstart = 1 +/obj/item/reagent_containers/pill/salicyclic + name = "salicylic acid pill" + desc = "Used to dull pain." + icon_state = "pill9" + list_reagents = list("sal_acid" = 24) + roundstart = 1 +/obj/item/reagent_containers/pill/oxandrolone + name = "oxandrolone pill" + desc = "Used to stimulate burn healing." + icon_state = "pill11" + list_reagents = list("oxandrolone" = 24) + roundstart = 1 + +/obj/item/reagent_containers/pill/insulin + name = "insulin pill" + desc = "Handles hyperglycaemic coma." + icon_state = "pill18" + list_reagents = list("insulin" = 50) + roundstart = 1 + +/obj/item/reagent_containers/pill/shadowtoxin + name = "black pill" + desc = "I wouldn't eat this if I were you." + icon_state = "pill9" + color = "#454545" + list_reagents = list("shadowmutationtoxin" = 1) diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 869076081e..2e34e39f8f 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -7,7 +7,7 @@ lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi' flags_1 = NOBLUDGEON_1 - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER slot_flags = SLOT_BELT throwforce = 0 w_class = WEIGHT_CLASS_SMALL @@ -23,17 +23,17 @@ possible_transfer_amounts = list(5,10,15,20,25,30,50,100) -/obj/item/reagent_containers/spray/afterattack(atom/A as mob|obj, mob/user) +/obj/item/reagent_containers/spray/afterattack(atom/A, mob/user) if(istype(A, /obj/structure/sink) || istype(A, /obj/structure/janitorialcart) || istype(A, /obj/machinery/hydroponics)) return - if(istype(A, /obj/structure/reagent_dispensers) && get_dist(src,A) <= 1) //this block copypasted from reagent_containers/glass, for lack of a better solution - if(!A.reagents.total_volume && A.reagents) - to_chat(user, "\The [A] is empty.") + if((A.is_drainable() && !A.is_refillable()) && get_dist(src,A) <= 1) + if(!A.reagents.total_volume) + to_chat(user, "[A] is empty.") return - if(reagents.total_volume >= reagents.maximum_volume) - to_chat(user, "\The [src] is full.") + if(reagents.holder_full()) + to_chat(user, "[src] is full.") return var/trans = A.reagents.trans_to(src, 50) //transfer 50u , using the spray's transfer amount would take too long to refill @@ -41,7 +41,7 @@ return if(reagents.total_volume < amount_per_transfer_from_this) - to_chat(user, "\The [src] is empty!") + to_chat(user, "[src] is empty!") return spray(A) @@ -123,6 +123,14 @@ current_range = spray_range to_chat(user, "You switch the nozzle setting to [stream_mode ? "\"stream\"":"\"spray\""]. You'll now use [amount_per_transfer_from_this] units per use.") +/obj/item/reagent_containers/spray/attackby(obj/item/I, mob/user, params) + var/hotness = I.is_hot() + if(hotness && reagents) + reagents.expose_temperature(hotness) + to_chat(user, "You heat [name] with [I]!") + return ..() + + /obj/item/reagent_containers/spray/verb/empty() set name = "Empty Spray Bottle" set category = "Object" @@ -214,7 +222,6 @@ stream_range = 7 amount_per_transfer_from_this = 10 volume = 600 - origin_tech = "combat=3;materials=3;engineering=3" /obj/item/reagent_containers/spray/chemsprayer/afterattack(atom/A as mob|obj, mob/user) // Make it so the bioterror spray doesn't spray yourself when you click your inventory items diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 9695caab02..3f38be95c9 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -13,7 +13,7 @@ var/busy = FALSE // needed for delayed drawing of blood var/proj_piercing = 0 //does it pierce through thick clothes when shot with syringe gun materials = list(MAT_METAL=10, MAT_GLASS=20) - container_type = TRANSPARENT_1 + container_type = TRANSPARENT /obj/item/reagent_containers/syringe/Initialize() . = ..() @@ -107,11 +107,8 @@ update_icon() if(SYRINGE_INJECT) - //Always log attemped injections for admins - var/list/rinject = list() - for(var/datum/reagent/R in reagents.reagent_list) - rinject += R.name - var/contained = english_list(rinject) + // Always log attemped injections for admins + var/contained = reagents.log_list() add_logs(user, L, "attemped to inject", src, addition="which had [contained]") if(!reagents.total_volume) @@ -157,7 +154,7 @@ /obj/item/reagent_containers/syringe/update_icon() - var/rounded_vol = Clamp(round((reagents.total_volume / volume * 15),5), 0, 15) + var/rounded_vol = CLAMP(round((reagents.total_volume / volume * 15),5), 0, 15) cut_overlays() if(ismob(loc)) var/injoverlay @@ -207,6 +204,11 @@ desc = "Contains calomel." list_reagents = list("calomel" = 15) +/obj/item/reagent_containers/syringe/plasma + name = "syringe (plasma)" + desc = "Contains plasma." + list_reagents = list("plasma" = 15) + /obj/item/reagent_containers/syringe/lethal name = "lethal injection syringe" desc = "A syringe used for lethal injections. It can hold up to 50 units." @@ -238,13 +240,11 @@ desc = "An advanced syringe that can hold 60 units of chemicals." amount_per_transfer_from_this = 20 volume = 60 - origin_tech = "bluespace=4;materials=4;biotech=4" /obj/item/reagent_containers/syringe/noreact name = "cryo syringe" desc = "An advanced syringe that stops reagents inside from reacting. It can hold up to 20 units." volume = 20 - origin_tech = "materials=3;engineering=3" /obj/item/reagent_containers/syringe/noreact/Initialize() . = ..() @@ -255,4 +255,3 @@ desc = "A diamond-tipped syringe that pierces armor when launched at high velocity. It can hold up to 10 units." volume = 10 proj_piercing = 1 - origin_tech = "combat=3;materials=4;engineering=5" diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index ea80f4c508..f0c0ecfb68 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -5,7 +5,7 @@ icon_state = "water" density = TRUE anchored = FALSE - container_type = DRAWABLE_1 + container_type = DRAINABLE | AMOUNT_VISIBLE pressure_resistance = 2*ONE_ATMOSPHERE max_integrity = 300 var/tank_volume = 1000 //In units, how much the dispenser can hold @@ -18,7 +18,7 @@ boom() /obj/structure/reagent_dispensers/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/reagent_containers)) + if(W.is_refillable()) return 0 //so we can refill them via their afterattack. else return ..() @@ -28,14 +28,6 @@ reagents.add_reagent(reagent_id, tank_volume) . = ..() -/obj/structure/reagent_dispensers/examine(mob/user) - ..() - if(reagents.total_volume) - to_chat(user, "It has [reagents.total_volume] unit\s left.") - else - to_chat(user, "It's empty.") - - /obj/structure/reagent_dispensers/proc/boom() visible_message("\The [src] ruptures!") chem_splash(loc, 5, list(reagents)) diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm index ed14ae63c1..62965f7ca1 100644 --- a/code/modules/recycling/disposal/bin.dm +++ b/code/modules/recycling/disposal/bin.dm @@ -29,7 +29,7 @@ if(make_from) setDir(make_from.dir) - make_from.loc = null + make_from.moveToNullspace() stored = make_from pressure_charging = FALSE // newly built disposal bins start with pump off else @@ -297,7 +297,7 @@ data["full_pressure"] = full_pressure data["pressure_charging"] = pressure_charging data["panel_open"] = panel_open - var/per = Clamp(100* air_contents.return_pressure() / (SEND_PRESSURE), 0, 100) + var/per = CLAMP(100* air_contents.return_pressure() / (SEND_PRESSURE), 0, 100) data["per"] = round(per, 1) data["isai"] = isAI(user) return data @@ -471,7 +471,7 @@ if(isobj(AM)) var/obj/O = AM - O.loc = src + O.forceMove(src) else if(ismob(AM)) var/mob/M = AM if(prob(2)) // to prevent mobs being stuck in infinite loops diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index 0bafcba54d..e7410685f7 100644 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -61,7 +61,7 @@ if(!user || user.stat != CONSCIOUS || user.loc != O || O.loc != src ) return to_chat(user, "You successfully removed [O]'s wrapping !") - O.loc = loc + O.forceMove(loc) playsound(src.loc, 'sound/items/poster_ripped.ogg', 50, 1) qdel(src) else diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm index ebeb869d9c..26fa304209 100644 --- a/code/modules/research/circuitprinter.dm +++ b/code/modules/research/circuitprinter.dm @@ -4,14 +4,18 @@ a /datum/desgin on the linked R&D console. You can then print them out in a fasi using metal and glass, it uses glass and reagents (usually sulfuric acis). */ -/obj/machinery/r_n_d/circuit_imprinter +/obj/machinery/rnd/circuit_imprinter name = "circuit imprinter" desc = "Manufactures circuit boards for the construction of machines." icon_state = "circuit_imprinter" - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER circuit = /obj/item/circuitboard/machine/circuit_imprinter var/efficiency_coeff + var/console_link = TRUE //can this link to a console? + var/requires_console = TRUE + + var/datum/component/material_container/materials //Store for hyper speed! var/list/categories = list( "AI Modules", @@ -27,14 +31,15 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). "Computer Parts" ) -/obj/machinery/r_n_d/circuit_imprinter/Initialize() - var/datum/component/material_container/materials = AddComponent(/datum/component/material_container, list(MAT_GLASS, MAT_GOLD, MAT_DIAMOND, MAT_METAL, MAT_BLUESPACE), - FALSE, list(/obj/item/stack, /obj/item/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready)) +/obj/machinery/rnd/circuit_imprinter/Initialize() + var/datum/component/material_container/materials + materials = AddComponent(/datum/component/material_container, list(MAT_GLASS, MAT_GOLD, MAT_DIAMOND, MAT_METAL, MAT_BLUESPACE), 0, + FALSE, list(/obj/item/stack, /obj/item/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready), CALLBACK(src, .proc/AfterMaterialInsert)) materials.precise_insertion = TRUE create_reagents(0) return ..() -/obj/machinery/r_n_d/circuit_imprinter/RefreshParts() +/obj/machinery/rnd/circuit_imprinter/RefreshParts() reagents.maximum_volume = 0 for(var/obj/item/reagent_containers/glass/G in component_parts) reagents.maximum_volume += G.volume @@ -50,11 +55,11 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). T += M.rating efficiency_coeff = 2 ** (T - 1) //Only 1 manipulator here, you're making runtimes Razharas -/obj/machinery/r_n_d/circuit_imprinter/blob_act(obj/structure/blob/B) +/obj/machinery/rnd/circuit_imprinter/blob_act(obj/structure/blob/B) if (prob(50)) qdel(src) -/obj/machinery/r_n_d/circuit_imprinter/proc/check_mat(datum/design/being_built, M) // now returns how many times the item can be built with the material +/obj/machinery/rnd/circuit_imprinter/proc/check_mat(datum/design/being_built, M) // now returns how many times the item can be built with the material var/list/all_materials = being_built.reagents_list + being_built.materials GET_COMPONENT(materials, /datum/component/material_container) @@ -65,7 +70,7 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). return round(A / max(1, (all_materials[M]/efficiency_coeff))) //we eject the materials upon deconstruction. -/obj/machinery/r_n_d/circuit_imprinter/on_deconstruction() +/obj/machinery/rnd/circuit_imprinter/on_deconstruction() for(var/obj/item/reagent_containers/glass/G in component_parts) reagents.trans_to(G, G.reagents.maximum_volume) GET_COMPONENT(materials, /datum/component/material_container) @@ -73,24 +78,52 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). ..() -/obj/machinery/r_n_d/circuit_imprinter/disconnect_console() +/obj/machinery/rnd/circuit_imprinter/disconnect_console() linked_console.linked_imprinter = null ..() -/obj/machinery/r_n_d/circuit_imprinter/ComponentActivated(datum/component/C) - ..() - if(istype(C, /datum/component/material_container)) - 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" - use_power(MINERAL_MATERIAL_AMOUNT / 10) - else - var/obj/item/stack/S = lit - stack_name = initial(S.name) - use_power(max(1000, (MINERAL_MATERIAL_AMOUNT * M.last_amount_inserted / 10))) - add_overlay("protolathe_[stack_name]") - addtimer(CALLBACK(src, /atom/proc/cut_overlay, "protolathe_[stack_name]"), 10) +/obj/machinery/rnd/circuit_imprinter/proc/user_try_print_id(id) + if((!linked_console && requires_console) || !id) + return FALSE + var/datum/design/D = (linked_console || requires_console)? linked_console.stored_research.researched_designs[id] : get_techweb_design_by_id(id) + if(!istype(D)) + return FALSE + + var/power = 1000 + for(var/M in D.materials) + power += round(D.materials[M] / 5) + power = max(4000, power) + use_power(power) + + var/list/efficient_mats = list() + for(var/MAT in D.materials) + efficient_mats[MAT] = D.materials[MAT]/efficiency_coeff + + if(!materials.has_materials(efficient_mats)) + say("Not enough materials to complete prototype.") + return FALSE + for(var/R in D.reagents_list) + if(!reagents.has_reagent(R, D.reagents_list[R]/efficiency_coeff)) + say("Not enough reagents to complete prototype.") + return FALSE + + busy = TRUE + flick("circuit_imprinter_ani", src) + materials.use_amount(efficient_mats) + for(var/R in D.reagents_list) + reagents.remove_reagent(R, D.reagents_list[R]/efficiency_coeff) + + var/P = D.build_path + addtimer(CALLBACK(src, .proc/reset_busy), 16) + addtimer(CALLBACK(src, .proc/do_print, P, efficient_mats, D.dangerous_construction), 16) + return TRUE + +/obj/machinery/rnd/circuit_imprinter/proc/do_print(path, list/matlist, notify_admins) + if(notify_admins) + if(usr) + usr.investigate_log("built [path] at a circuit imprinter.", INVESTIGATE_RESEARCH) + var/turf/T = get_turf(usr) + message_admins("[key_name(usr)][ADMIN_JMP(T)] has built [path] at a circuit imprinter at [COORD(usr)]") + var/obj/item/I = new path(get_turf(src)) + I.materials = matlist.Copy() + SSblackbox.record_feedback("nested_tally", "circuit_printed", 1, list("[type]", "[path]")) diff --git a/code/modules/research/departmental_circuit_imprinter.dm b/code/modules/research/departmental_circuit_imprinter.dm new file mode 100644 index 0000000000..7b06aaa839 --- /dev/null +++ b/code/modules/research/departmental_circuit_imprinter.dm @@ -0,0 +1,201 @@ +/obj/machinery/rnd/circuit_imprinter/department + name = "Department Circuit Imprinter" + desc = "A special circuit imprinter with a built in interface meant for departmental usage, with built in ExoSync recievers allowing it to print designs researched that match its ROM-encoded department type. Features a bluespace materials reciever for recieving materials without the hassle of running to mining!" + icon_state = "circuit_imprinter" + container_type = OPENCONTAINER + circuit = /obj/item/circuitboard/machine/circuit_imprinter/department + requires_console = FALSE + + var/list/datum/design/cached_designs + var/list/datum/design/matching_designs + var/department_tag = "Unidentified" //used for material distribution among other things. + var/datum/techweb/stored_research + var/datum/techweb/host_research + var/screen = DEPPRINTER_SCREEN_PRIMARY + +/obj/machinery/rnd/circuit_imprinter/department/science + allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_SCIENCE + department_tag = "Science" + +/obj/machinery/rnd/circuit_imprinter/department/Initialize() + . = ..() + stored_research = new + cached_designs = list() + host_research = SSresearch.science_tech + matching_designs = list() + update_research() + +/obj/machinery/rnd/circuit_imprinter/department/Destroy() + QDEL_NULL(stored_research) + return ..() + +/obj/machinery/rnd/circuit_imprinter/department/user_try_print_id(id, amount) + var/datum/design/D = get_techweb_design_by_id(id) + if(!D || !(D.departmental_flags & allowed_department_flags)) + say("Warning: Printing failed. Please update the research data with the on-screen button!") + return FALSE + . = ..() + +/obj/machinery/rnd/circuit_imprinter/department/attack_hand(mob/user) + if(..()) + return + interact(user) + +/obj/machinery/rnd/circuit_imprinter/department/interact(mob/user) + user.set_machine(src) + + var/datum/browser/popup = new(user, "rndconsole", name, 460, 550) + popup.set_content(generate_ui()) + popup.open() + +/obj/machinery/rnd/circuit_imprinter/department/proc/search(string) + matching_designs.Cut() + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] + if(!(D.build_type & IMPRINTER) || !(D.departmental_flags & allowed_department_flags)) + continue + if(findtext(D.name,string)) + matching_designs.Add(D) + +/obj/machinery/rnd/circuit_imprinter/department/proc/update_research() + host_research.copy_research_to(stored_research, TRUE) + update_designs() + +/obj/machinery/rnd/circuit_imprinter/department/proc/update_designs() + cached_designs.Cut() + for(var/i in stored_research.researched_designs) + var/datum/design/d = stored_research.researched_designs[i] + if((d.departmental_flags & allowed_department_flags) && (d.build_type & IMPRINTER)) + cached_designs |= d + +/obj/machinery/rnd/circuit_imprinter/department/proc/generate_ui() + var/list/ui = list() + ui += ui_header() + switch(screen) + if(DEPPRINTER_SCREEN_MATERIALS) + ui += ui_materials() + if(DEPPRINTER_SCREEN_CHEMICALS) + ui += ui_chemicals() + if(DEPPRINTER_SCREEN_SEARCH) + ui += ui_search() + else + ui += ui_department_imprinter() + for(var/i in 1 to length(ui)) + if(!findtextEx(ui[i], RDSCREEN_NOBREAK)) + ui[i] += "
    " + ui[i] = replacetextEx(ui[i], RDSCREEN_NOBREAK, "") + return ui.Join("") + +/obj/machinery/rnd/circuit_imprinter/department/proc/ui_search() //Legacy code + var/list/l = list() + l += "

    Search Results:

    " + l += "
    \ + \ + \ + \ + \ +

    " + var/coeff = efficiency_coeff + for(var/datum/design/D in matching_designs) + var/temp_materials + var/check_materials = TRUE + var/all_materials = D.materials + D.reagents_list + for(var/M in all_materials) + temp_materials += " | " + if (!check_mat(D, M)) + check_materials = FALSE + temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]" + else + temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]" + if (check_materials) + l += "[D.name][temp_materials]" + else + l += "[D.name][temp_materials]" + l += "
    " + return l + +/obj/machinery/rnd/circuit_imprinter/department/proc/ui_header() + var/list/l = list() + l += "

    Nanotrasen Department Circuit Imprinter: [department_tag]

    [RDSCREEN_NOBREAK]" + l += "
    Connected Technology database: [host_research == SSresearch.science_tech? "Nanotrasen" : "Third Party"]" + l += "Security protocols: [emagged? "Disabled" : "Enabled"]" + l += "Material Amount: [materials.total_amount] / [materials.max_amount]" + l += "Chemical volume: [reagents.total_volume] / [reagents.maximum_volume]" + l += "Synchronize Research" + l += "Main Screen
    [RDSCREEN_NOBREAK]" + return l + +/obj/machinery/rnd/circuit_imprinter/department/proc/ui_materials() + var/list/l = list() + l += "

    Material Storage:

    " + for(var/mat_id in materials.materials) + var/datum/material/M = materials.materials[mat_id] + l += "* [M.amount] of [M.name]: " + if(M.amount >= MINERAL_MATERIAL_AMOUNT) l += "Eject [RDSCREEN_NOBREAK]" + if(M.amount >= MINERAL_MATERIAL_AMOUNT*5) l += "5x [RDSCREEN_NOBREAK]" + if(M.amount >= MINERAL_MATERIAL_AMOUNT) l += "All[RDSCREEN_NOBREAK]" + l += "" + l += "
    [RDSCREEN_NOBREAK]" + return l + +/obj/machinery/rnd/circuit_imprinter/department/proc/ui_chemicals() + var/list/l = list() + l += "
    Disposal All Chemicals in Storage" + l += "

    Chemical Storage:

    " + for(var/datum/reagent/R in reagents.reagent_list) + l += "[R.name]: [R.volume]" + l += "Purge" + l += "
    " + return l + +/obj/machinery/rnd/circuit_imprinter/department/Topic(raw, ls) + if(..()) + return + add_fingerprint(usr) + usr.set_machine(src) + if(ls["switch_screen"]) + screen = text2num(ls["switch_screen"]) + if(ls["imprint"]) //Causes the circuit_imprinter to build something. + if(busy) + say("Warning: Fabricators busy!") + else + user_try_print_id(ls["imprint"]) + if(ls["search"]) //Search for designs with name matching pattern + search(ls["to_search"]) + screen = DEPPRINTER_SCREEN_SEARCH + if(ls["sync_research"]) + update_research() + say("Synchronizing research with host technology database.") + if(ls["dispose"]) //Causes the protolathe to dispose of a single reagent (all of it) + reagents.del_reagent(ls["dispose"]) + if(ls["disposeall"]) //Causes the protolathe to dispose of all it's reagents. + reagents.clear_reagents() + if(ls["ejectsheet"]) //Causes the protolathe to eject a sheet of material + materials.retrieve_sheets(text2num(ls["eject_amt"]), ls["ejectsheet"]) diff --git a/code/modules/research/departmental_lathe.dm b/code/modules/research/departmental_lathe.dm new file mode 100644 index 0000000000..4e8d33a3a3 --- /dev/null +++ b/code/modules/research/departmental_lathe.dm @@ -0,0 +1,245 @@ +/obj/machinery/rnd/protolathe/department + name = "department protolathe" + desc = "A special protolathe with a built in interface meant for departmental usage, with built in ExoSync recievers allowing it to print designs researched that match its ROM-encoded department type. Features a bluespace materials reciever for recieving materials without the hassle of running to mining!" + icon_state = "protolathe" + container_type = OPENCONTAINER + circuit = /obj/item/circuitboard/machine/protolathe/department + requires_console = FALSE + + var/list/datum/design/cached_designs + var/list/datum/design/matching_designs + var/department_tag = "Unidentified" //used for material distribution among other things. + var/datum/techweb/stored_research + var/datum/techweb/host_research + var/screen = DEPLATHE_SCREEN_PRIMARY + +/obj/machinery/rnd/protolathe/department/engineering + allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_ENGINEERING + department_tag = "Engineering" + circuit = /obj/item/circuitboard/machine/protolathe/department/engineering + +/obj/machinery/rnd/protolathe/department/service + allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_SERVICE + department_tag = "Service" + circuit = /obj/item/circuitboard/machine/protolathe/department/service + +/obj/machinery/rnd/protolathe/department/medical + allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_MEDICAL + department_tag = "Medical" + circuit = /obj/item/circuitboard/machine/protolathe/department/medical + +/obj/machinery/rnd/protolathe/department/cargo + allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_CARGO + department_tag = "Cargo" + circuit = /obj/item/circuitboard/machine/protolathe/department/cargo + +/obj/machinery/rnd/protolathe/department/science + allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_SCIENCE + department_tag = "Science" + circuit = /obj/item/circuitboard/machine/protolathe/department/science + +/obj/machinery/rnd/protolathe/department/security + allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_SECURITY + department_tag = "Security" + circuit = /obj/item/circuitboard/machine/protolathe/department/security + +/obj/machinery/rnd/protolathe/department/Initialize() + . = ..() + matching_designs = list() + cached_designs = list() + stored_research = new + host_research = SSresearch.science_tech + update_research() + +/obj/machinery/rnd/protolathe/department/Destroy() + QDEL_NULL(stored_research) + return ..() + +/obj/machinery/rnd/protolathe/department/user_try_print_id(id, amount) + var/datum/design/D = get_techweb_design_by_id(id) + if(!D || !(D.departmental_flags & allowed_department_flags)) + say("Warning: Printing failed. Please update the research data with the on-screen button!") + return FALSE + . = ..() + +/obj/machinery/rnd/protolathe/department/attack_hand(mob/user) + if(..()) + return + interact(user) + +/obj/machinery/rnd/protolathe/department/interact(mob/user) + user.set_machine(src) + var/datum/browser/popup = new(user, "rndconsole", name, 460, 550) + popup.set_content(generate_ui()) + popup.open() + +/obj/machinery/rnd/protolathe/department/proc/search(string) + matching_designs.Cut() + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] + if(!(D.build_type & PROTOLATHE) || !(D.departmental_flags & allowed_department_flags)) + continue + if(findtext(D.name,string)) + matching_designs.Add(D) + +/obj/machinery/rnd/protolathe/department/proc/update_research() + host_research.copy_research_to(stored_research, TRUE) + update_designs() + +/obj/machinery/rnd/protolathe/department/proc/update_designs() + cached_designs.Cut() + for(var/i in stored_research.researched_designs) + var/datum/design/d = stored_research.researched_designs[i] + if((d.departmental_flags & allowed_department_flags) && (d.build_type & PROTOLATHE)) + cached_designs |= d + +/obj/machinery/rnd/protolathe/department/proc/generate_ui() + var/list/ui = list() + ui += ui_header() + switch(screen) + if(DEPLATHE_SCREEN_MATERIALS) + ui += ui_materials() + if(DEPLATHE_SCREEN_CHEMICALS) + ui += ui_chemicals() + if(DEPLATHE_SCREEN_SEARCH) + ui += ui_search() + else + ui += ui_department_lathe() + for(var/i in 1 to length(ui)) + if(!findtextEx(ui[i], RDSCREEN_NOBREAK)) + ui[i] += "
    " + ui[i] = replacetextEx(ui[i], RDSCREEN_NOBREAK, "") + return ui.Join("") + +/obj/machinery/rnd/protolathe/department/proc/ui_search() //Legacy code + var/list/l = list() + var/coeff = efficiency_coeff + l += "

    Search Results:

    " + l += "
    \ + \ + \ + \ + \ +

    " + for(var/datum/design/D in matching_designs) + var/temp_material + var/c = 50 + var/t + var/all_materials = D.materials + D.reagents_list + for(var/M in all_materials) + t = check_mat(D, M) + temp_material += " | " + if (t < 1) + temp_material += "[all_materials[M]*coeff] [CallMaterialName(M)]" + else + temp_material += " [all_materials[M]*coeff] [CallMaterialName(M)]" + c = min(c,t) + + if (c >= 1) + l += "[D.name][RDSCREEN_NOBREAK]" + if(c >= 5) + l += "x5[RDSCREEN_NOBREAK]" + if(c >= 10) + l += "x10[RDSCREEN_NOBREAK]" + l += "[temp_material][RDSCREEN_NOBREAK]" + else + l += "[D.name][temp_material][RDSCREEN_NOBREAK]" + l += "" + l += "
    " + return l + +/obj/machinery/rnd/protolathe/department/proc/ui_department_lathe() + var/list/l = list() + var/coeff = efficiency_coeff + l += "
    \ + \ + \ + \ + \ +

    " + for(var/datum/design/D in cached_designs) + var/temp_material + var/c = 50 + var/t + var/all_materials = D.materials + D.reagents_list + for(var/M in all_materials) + t = check_mat(D, M) + temp_material += " | " + if (t < 1) + temp_material += "[all_materials[M]*coeff] [CallMaterialName(M)]" + else + temp_material += " [all_materials[M]*coeff] [CallMaterialName(M)]" + c = min(c,t) + + if (c >= 1) + l += "[D.name][RDSCREEN_NOBREAK]" + if(c >= 5) + l += "x5[RDSCREEN_NOBREAK]" + if(c >= 10) + l += "x10[RDSCREEN_NOBREAK]" + l += "[temp_material][RDSCREEN_NOBREAK]" + else + l += "[D.name][temp_material][RDSCREEN_NOBREAK]" + l += "" + l += "
    " + return l + +/obj/machinery/rnd/protolathe/department/proc/ui_header() + var/list/l = list() + l += "

    Nanotrasen Department Lathe: [department_tag]

    [RDSCREEN_NOBREAK]" + l += "
    Connected Technology database: [host_research == SSresearch.science_tech? "Nanotrasen" : "Third Party"]" + l += "Security protocols: [emagged? "Disabled" : "Enabled"]" + l += "Material Amount: [materials.total_amount] / [materials.max_amount]" + l += "Chemical volume: [reagents.total_volume] / [reagents.maximum_volume]" + l += "Synchronize Research" + l += "Main Screen
    [RDSCREEN_NOBREAK]" + return l + +/obj/machinery/rnd/protolathe/department/proc/ui_materials() + var/list/l = list() + l += "

    Material Storage:

    " + for(var/mat_id in materials.materials) + var/datum/material/M = materials.materials[mat_id] + l += "* [M.amount] of [M.name]: " + if(M.amount >= MINERAL_MATERIAL_AMOUNT) l += "Eject [RDSCREEN_NOBREAK]" + if(M.amount >= MINERAL_MATERIAL_AMOUNT*5) l += "5x [RDSCREEN_NOBREAK]" + if(M.amount >= MINERAL_MATERIAL_AMOUNT) l += "All[RDSCREEN_NOBREAK]" + l += "" + l += "
    [RDSCREEN_NOBREAK]" + return l + +/obj/machinery/rnd/protolathe/department/proc/ui_chemicals() + var/list/l = list() + l += "
    Disposal All Chemicals in Storage" + l += "

    Chemical Storage:

    " + for(var/datum/reagent/R in reagents.reagent_list) + l += "[R.name]: [R.volume]" + l += "Purge" + l += "
    " + return l + +/obj/machinery/rnd/protolathe/department/Topic(raw, ls) + if(..()) + return + add_fingerprint(usr) + usr.set_machine(src) + if(ls["switch_screen"]) + screen = text2num(ls["switch_screen"]) + if(ls["build"]) //Causes the Protolathe to build something. + if(busy) + say("Warning: Fabricators busy!") + else + user_try_print_id(ls["build"], ls["amount"]) + if(ls["search"]) //Search for designs with name matching pattern + search(ls["to_search"]) + screen = DEPLATHE_SCREEN_SEARCH + if(ls["sync_research"]) + update_research() + say("Synchronizing research with host technology database.") + if(ls["dispose"]) //Causes the protolathe to dispose of a single reagent (all of it) + reagents.del_reagent(ls["dispose"]) + if(ls["disposeall"]) //Causes the protolathe to dispose of all it's reagents. + reagents.clear_reagents() + if(ls["ejectsheet"]) //Causes the protolathe to eject a sheet of material + materials.retrieve_sheets(text2num(ls["eject_amt"]), ls["ejectsheet"]) + updateUsrDialog() diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index d2b587cc68..e16aadb7cd 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -26,11 +26,12 @@ other types of metals and chemistry for reagents). - Add the AUTOLATHE tag to */ +//DESIGNS ARE GLOBAL. DO NOT CREATE OR DESTROY THEM AT RUNTIME OUTSIDE OF INIT, JUST REFERENCE THEM TO WHATEVER YOU'RE DOING! + /datum/design //Datum for object designs, used in construction var/name = "Name" //Name of the created object. var/desc = "Desc" //Description of the created object. - var/id = "id" //ID of the created object for easy refernece. Alphanumeric, lower-case, no symbols - var/list/req_tech = list() //IDs of that techs the object originated from and the minimum level requirements. + var/id = DESIGN_ID_IGNORE //ID of the created object for easy refernece. Alphanumeric, lower-case, no symbols var/build_type = null //Flag as to what kind machine the design is built in. See defines. var/list/materials = list() //List of materials. Format: "id" = amount. var/construction_time //Amount of time required for building the object @@ -40,7 +41,12 @@ other types of metals and chemistry for reagents). var/list/reagents_list = list() //List of reagents. Format: "id" = amount. var/maxstack = 1 var/lathe_time_factor = 1 //How many times faster than normal is this to build on the protolathe + var/dangerous_construction = FALSE //notify and log for admin investigations if this is printed. + var/departmental_flags = ALL //bitflags for deplathes. +/datum/design/Destroy() + CRASH("DESIGN DATUMS SHOULD NOT EVER BE DESTROYED AS THEY ARE ONLY MEANT TO BE IN A GLOBAL LIST AND REFERENCED FOR US.") + return ..() //////////////////////////////////////// //Disks for transporting design datums// @@ -66,609 +72,3 @@ other types of metals and chemistry for reagents). desc = "A disk for storing device design data for construction in lathes. This one has extra storage space." materials = list(MAT_METAL=300, MAT_GLASS=100, MAT_SILVER = 50) max_blueprints = 5 - -/////////////////////////////////// -/////Non-Board Computer Stuff////// -/////////////////////////////////// - -/datum/design/intellicard - name = "Intellicard AI Transportation System" - desc = "Allows for the construction of an intellicard." - id = "intellicard" - req_tech = list("programming" = 3, "materials" = 3) - build_type = PROTOLATHE - materials = list(MAT_GLASS = 1000, MAT_GOLD = 200) - build_path = /obj/item/device/aicard - category = list("Electronics") - -/datum/design/paicard - name = "Personal Artificial Intelligence Card" - desc = "Allows for the construction of a pAI Card." - id = "paicard" - req_tech = list("programming" = 2) - build_type = PROTOLATHE - materials = list(MAT_GLASS = 500, MAT_METAL = 500) - build_path = /obj/item/device/paicard - category = list("Electronics") - -/datum/design/integrated_printer - name = "Integrated circuits printer" - desc = "This machine provides all neccesary things for circuitry." - id = "icprinter" - req_tech = list("programming" = 2,"materials" = 2, "engineering" = 3) - build_type = PROTOLATHE - materials = list(MAT_GLASS = 5000, MAT_METAL = 5000) - build_path = /obj/item/device/integrated_circuit_printer - category = list("Electronics") - -/datum/design/advupdisk - name = "Upgrade disk-advanced circuits" - desc = "Upgrade disk for integrated circuits printer.Allows advanced designs." - id = "udiskadv" - req_tech = list("programming" = 3, "engineering" = 3) - build_type = PROTOLATHE - materials = list(MAT_GLASS = 500, MAT_METAL = 500) - build_path = /obj/item/disk/integrated_circuit/upgrade/advanced - category = list("Electronics") - -/datum/design/cloneupisk - name = "Upgrade disk-assembly cloning" - desc = "Upgrade disk for integrated circuits printer.Allows assembly cloning." - id = "udiskclone" - req_tech = list("programming" = 4, "engineering" = 4) - build_type = PROTOLATHE - materials = list(MAT_GLASS = 500, MAT_METAL = 500) - build_path = /obj/item/disk/integrated_circuit/upgrade/clone - category = list("Electronics") - -//////////////////////////////////////// -//////////Disk Construction Disks/////// -//////////////////////////////////////// -/datum/design/design_disk - name = "Design Storage Disk" - desc = "Produce additional disks for storing device designs." - id = "design_disk" - req_tech = list("programming" = 1) - build_type = PROTOLATHE | AUTOLATHE - materials = list(MAT_METAL = 300, MAT_GLASS = 100) - build_path = /obj/item/disk/design_disk - category = list("Electronics") - -/datum/design/design_disk_adv - name = "Advanced Design Storage Disk" - desc = "Produce additional disks for storing device designs." - id = "design_disk_adv" - req_tech = list("programming" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 300, MAT_GLASS = 100, MAT_SILVER=50) - build_path = /obj/item/disk/design_disk/adv - category = list("Electronics") - -/datum/design/tech_disk - name = "Technology Data Storage Disk" - desc = "Produce additional disks for storing technology data." - id = "tech_disk" - req_tech = list("programming" = 1) - build_type = PROTOLATHE | AUTOLATHE - materials = list(MAT_METAL = 300, MAT_GLASS = 100) - build_path = /obj/item/disk/tech_disk - category = list("Electronics") - -/datum/design/tech_disk_adv - name = "Advanced Technology Data Storage Disk" - desc = "Produce disks with extra storage capacity for storing technology data." - id = "tech_disk_adv" - req_tech = list("programming" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 300, MAT_GLASS = 100, MAT_SILVER=50) - build_path = /obj/item/disk/tech_disk/adv - category = list("Electronics") - -/datum/design/tech_disk_super_adv - name = "Quantum Technology Data Storage Disk" - desc = "Produce disks with extremely large storage capacity for storing technology data." - id = "tech_disk_super_adv" - req_tech = list("programming" = 6) - build_type = PROTOLATHE - materials = list(MAT_METAL = 300, MAT_GLASS = 100, MAT_SILVER=100, MAT_GOLD=100, MAT_BLUESPACE = 100) - build_path = /obj/item/disk/tech_disk/super_adv - category = list("Electronics") - -///////////////////////////////////////// -/////////////////Mining////////////////// -///////////////////////////////////////// - -/datum/design/drill - name = "Mining Drill" - desc = "Yours is the drill that will pierce through the rock walls." - id = "drill" - req_tech = list("materials" = 2, "powerstorage" = 2, "engineering" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 6000, MAT_GLASS = 1000) //expensive, but no need for miners. - build_path = /obj/item/pickaxe/drill - category = list("Mining Designs") - -/datum/design/drill_diamond - name = "Diamond-Tipped Mining Drill" - desc = "Yours is the drill that will pierce the heavens!" - id = "drill_diamond" - req_tech = list("materials" = 6, "powerstorage" = 5, "engineering" = 5) - build_type = PROTOLATHE - materials = list(MAT_METAL = 6000, MAT_GLASS = 1000, MAT_DIAMOND = 2000) //Yes, a whole diamond is needed. - build_path = /obj/item/pickaxe/drill/diamonddrill - category = list("Mining Designs") - -/datum/design/plasmacutter - name = "Plasma Cutter" - desc = "You could use it to cut limbs off of xenos! Or, you know, mine stuff." - id = "plasmacutter" - req_tech = list("materials" = 3, "plasmatech" = 3, "magnets" = 2) - build_type = PROTOLATHE - materials = list(MAT_METAL = 1500, MAT_GLASS = 500, MAT_PLASMA = 400) - build_path = /obj/item/gun/energy/plasmacutter - category = list("Mining Designs") - -/datum/design/plasmacutter_adv - name = "Advanced Plasma Cutter" - desc = "It's an advanced plasma cutter, oh my god." - id = "plasmacutter_adv" - req_tech = list("materials" = 4, "plasmatech" = 4, "engineering" = 2, "combat" = 3, "magnets" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 3000, MAT_GLASS = 1000, MAT_PLASMA = 2000, MAT_GOLD = 500) - build_path = /obj/item/gun/energy/plasmacutter/adv - category = list("Mining Designs") - -/datum/design/jackhammer - name = "Sonic Jackhammer" - desc = "Essentially a handheld planet-cracker. Can drill through walls with ease as well." - id = "jackhammer" - req_tech = list("materials" = 7, "powerstorage" = 5, "engineering" = 6, "magnets" = 5) - build_type = PROTOLATHE - materials = list(MAT_METAL = 6000, MAT_GLASS = 2000, MAT_SILVER = 2000, MAT_DIAMOND = 6000) - build_path = /obj/item/pickaxe/drill/jackhammer - category = list("Mining Designs") - -/datum/design/superresonator - name = "Upgraded Resonator" - desc = "An upgraded version of the resonator that allows more fields to be active at once." - id = "superresonator" - req_tech = list("materials" = 4, "powerstorage" = 3, "engineering" = 3, "magnets" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 4000, MAT_GLASS = 1500, MAT_SILVER = 1000, MAT_URANIUM = 1000) - build_path = /obj/item/resonator/upgraded - category = list("Mining Designs") - -/datum/design/trigger_guard_mod - name = "Kinetic Accelerator Trigger Guard Mod" - desc = "A device which allows kinetic accelerators to be wielded by any organism." - id = "triggermod" - req_tech = list("materials" = 5, "powerstorage" = 4, "engineering" = 4, "magnets" = 4, "combat" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) - build_path = /obj/item/borg/upgrade/modkit/trigger_guard - category = list("Mining Designs") - -/datum/design/damage_mod - name = "Kinetic Accelerator Damage Mod" - desc = "A device which allows kinetic accelerators to deal more damage." - id = "damagemod" - req_tech = list("materials" = 5, "powerstorage" = 4, "engineering" = 4, "magnets" = 4, "combat" = 3) - build_type = PROTOLATHE | MECHFAB - materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) - build_path = /obj/item/borg/upgrade/modkit/damage - category = list("Mining Designs", "Cyborg Upgrade Modules") - -/datum/design/cooldown_mod - name = "Kinetic Accelerator Cooldown Mod" - desc = "A device which decreases the cooldown of a Kinetic Accelerator." - id = "cooldownmod" - req_tech = list("materials" = 5, "powerstorage" = 4, "engineering" = 4, "magnets" = 4, "combat" = 3) - build_type = PROTOLATHE | MECHFAB - materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) - build_path = /obj/item/borg/upgrade/modkit/cooldown - category = list("Mining Designs", "Cyborg Upgrade Modules") - -/datum/design/range_mod - name = "Kinetic Accelerator Range Mod" - desc = "A device which allows kinetic accelerators to fire at a further range." - id = "rangemod" - req_tech = list("materials" = 5, "powerstorage" = 4, "engineering" = 4, "magnets" = 4, "combat" = 3) - build_type = PROTOLATHE | MECHFAB - materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) - build_path = /obj/item/borg/upgrade/modkit/range - category = list("Mining Designs", "Cyborg Upgrade Modules") - -/datum/design/hyperaccelerator - name = "Kinetic Accelerator Mining AoE Mod" - desc = "A modification kit for Kinetic Accelerators which causes it to fire AoE blasts that destroy rock." - id = "hypermod" - req_tech = list("materials" = 7, "powerstorage" = 5, "engineering" = 5, "magnets" = 5, "combat" = 4) - build_type = PROTOLATHE | MECHFAB - materials = list(MAT_METAL = 8000, MAT_GLASS = 1500, MAT_SILVER = 2000, MAT_GOLD = 2000, MAT_DIAMOND = 2000) - build_path = /obj/item/borg/upgrade/modkit/aoe/turfs - category = list("Mining Designs", "Cyborg Upgrade Modules") - - -///////////////////////////////////////// -//////////////Blue Space///////////////// -///////////////////////////////////////// - -/datum/design/beacon - name = "Tracking Beacon" - desc = "A blue space tracking beacon." - id = "beacon" - req_tech = list("bluespace" = 1) - build_type = PROTOLATHE - materials = list(MAT_METAL = 150, MAT_GLASS = 100) - build_path = /obj/item/device/radio/beacon - category = list("Bluespace Designs") - -/datum/design/bag_holding - name = "Bag of Holding" - desc = "A backpack that opens into a localized pocket of bluespace." - id = "bag_holding" - req_tech = list("bluespace" = 7, "materials" = 5, "engineering" = 5, "plasmatech" = 6) - build_type = PROTOLATHE - materials = list(MAT_GOLD = 3000, MAT_DIAMOND = 1500, MAT_URANIUM = 250, MAT_BLUESPACE = 2000) - build_path = /obj/item/storage/backpack/holding - category = list("Bluespace Designs") - -/datum/design/bluespace_crystal - name = "Artificial Bluespace Crystal" - desc = "A small blue crystal with mystical properties." - id = "bluespace_crystal" - req_tech = list("bluespace" = 3, "materials" = 6, "plasmatech" = 4) - build_type = PROTOLATHE - materials = list(MAT_DIAMOND = 1500, MAT_PLASMA = 1500) - build_path = /obj/item/ore/bluespace_crystal/artificial - category = list("Bluespace Designs") - -/datum/design/telesci_gps - name = "GPS Device" - desc = "Little thingie that can track its position at all times." - id = "telesci_gps" - req_tech = list("materials" = 2, "bluespace" = 2) - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 1000) - build_path = /obj/item/device/gps - category = list("Bluespace Designs") - -/datum/design/miningsatchel_holding - name = "Mining Satchel of Holding" - desc = "A mining satchel that can hold an infinite amount of ores." - id = "minerbag_holding" - req_tech = list("bluespace" = 4, "materials" = 3, "engineering" = 4) - build_type = PROTOLATHE - materials = list(MAT_GOLD = 250, MAT_URANIUM = 500) //quite cheap, for more convenience - build_path = /obj/item/storage/bag/ore/holding - category = list("Bluespace Designs") - - -///////////////////////////////////////// -/////////////////HUDs//////////////////// -///////////////////////////////////////// - -/datum/design/health_hud - name = "Health Scanner HUD" - desc = "A heads-up display that scans the humans in view and provides accurate data about their health status." - id = "health_hud" - req_tech = list("biotech" = 2, "magnets" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500) - build_path = /obj/item/clothing/glasses/hud/health - category = list("Equipment") - -/datum/design/health_hud_night - name = "Night Vision Health Scanner HUD" - desc = "An advanced medical head-up display that allows doctors to find patients in complete darkness." - id = "health_hud_night" - req_tech = list("biotech" = 4, "magnets" = 5, "plasmatech" = 4, "engineering" = 6) - build_type = PROTOLATHE - materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_URANIUM = 1000, MAT_SILVER = 350) - build_path = /obj/item/clothing/glasses/hud/health/night - category = list("Equipment") - -/datum/design/security_hud - name = "Security HUD" - desc = "A heads-up display that scans the humans in view and provides accurate data about their ID status." - id = "security_hud" - req_tech = list("magnets" = 3, "combat" = 2) - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500) - build_path = /obj/item/clothing/glasses/hud/security - category = list("Equipment") - -/datum/design/security_hud_night - name = "Night Vision Security HUD" - desc = "A heads-up display which provides id data and vision in complete darkness." - id = "security_hud_night" - req_tech = list("combat" = 4, "magnets" = 5, "plasmatech" = 4, "engineering" = 6) - build_type = PROTOLATHE - materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_URANIUM = 1000, MAT_GOLD = 350) - build_path = /obj/item/clothing/glasses/hud/security/night - category = list("Equipment") - -/datum/design/diagnostic_hud - name = "Diagnostic HUD" - desc = "A HUD used to analyze and determine faults within robotic machinery." - id = "dianostic_hud" - req_tech = list("magnets" = 3, "engineering" = 2) - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500) - build_path = /obj/item/clothing/glasses/hud/diagnostic - category = list("Equipment") - -/datum/design/diagnostic_hud_night - name = "Night Vision Diagnostic HUD" - desc = "Upgraded version of the diagnostic HUD designed to function during a power failure." - id = "dianostic_hud_night" - req_tech = list("magnets" = 5, "plasmatech" = 4, "engineering" = 6, "powerstorage" = 4) - build_type = PROTOLATHE - materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_URANIUM = 1000, MAT_PLASMA = 300) - build_path = /obj/item/clothing/glasses/hud/diagnostic/night - category = list("Equipment") - -///////////////////////////////////////// -//////////////////Test/////////////////// -///////////////////////////////////////// - - /* test - name = "Test Design" - desc = "A design to test the new protolathe." - id = "protolathe_test" - build_type = PROTOLATHE - req_tech = list("materials" = 1) - materials = list(MAT_GOLD = 3000, "iron" = 15, "copper" = 10, MAT_SILVER = 2500) - build_path = /obj/item/banhammer" - category = list("Weapons") */ - -///////////////////////////////////////// -//////////////////Misc/////////////////// -///////////////////////////////////////// - -/datum/design/welding_mask - name = "Welding Gas Mask" - desc = "A gas mask with built in welding goggles and face shield. Looks like a skull, clearly designed by a nerd." - id = "weldingmask" - req_tech = list("materials" = 2, "engineering" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 3000, MAT_GLASS = 1000) - build_path = /obj/item/clothing/mask/gas/welding - category = list("Equipment") - -/datum/design/portaseeder - name = "Portable Seed Extractor" - desc = "For the enterprising botanist on the go. Less efficient than the stationary model, it creates one seed per plant." - build_type = PROTOLATHE - req_tech = list("biotech" = 3, "engineering" = 2) - materials = list(MAT_METAL = 1000, MAT_GLASS = 400) - build_path = /obj/item/storage/bag/plants/portaseeder - category = list("Equipment") - -/datum/design/air_horn - name = "Air Horn" - desc = "Damn son, where'd you find this?" - id = "air_horn" - req_tech = list("materials" = 4, "engineering" = 4) - build_type = PROTOLATHE - materials = list(MAT_METAL = 4000, MAT_BANANIUM = 1000) - build_path = /obj/item/bikehorn/airhorn - category = list("Equipment") - -/datum/design/mesons - name = "Optical Meson Scanners" - desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting condition." - id = "mesons" - req_tech = list("magnets" = 2, "engineering" = 2, "plasmatech" = 2) - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500) - build_path = /obj/item/clothing/glasses/meson - category = list("Equipment") - -/datum/design/engine_goggles - name = "Engineering Scanner Goggles" - desc = "Goggles used by engineers. The Meson Scanner mode lets you see basic structural and terrain layouts through walls, regardless of lighting condition. The T-ray Scanner mode lets you see underfloor objects such as cables and pipes." - id = "engine_goggles" - req_tech = list("materials" = 4, "magnets" = 3, "engineering" = 4, "plasmatech" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_PLASMA = 100) - build_path = /obj/item/clothing/glasses/meson/engine - category = list("Equipment") - -/datum/design/tray_goggles - name = "Optical T-Ray Scanners" - desc = "Used by engineering staff to see underfloor objects such as cables and pipes." - id = "tray_goggles" - req_tech = list("materials" = 3, "magnets" = 2, "engineering" = 2) - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500) - build_path = /obj/item/clothing/glasses/meson/engine/tray - category = list("Equipment") - -/datum/design/nvgmesons - name = "Night Vision Optical Meson Scanners" - desc = "Prototype meson scanners fitted with an extra sensor which amplifies the visible light spectrum and overlays it to the UHD display." - id = "nvgmesons" - req_tech = list("magnets" = 5, "plasmatech" = 5, "engineering" = 6) - build_type = PROTOLATHE - materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_PLASMA = 350, MAT_URANIUM = 1000) - build_path = /obj/item/clothing/glasses/meson/night - category = list("Equipment") - -/datum/design/night_vision_goggles - name = "Night Vision Goggles" - desc = "Goggles that let you see through darkness unhindered." - id = "night_visision_goggles" - req_tech = list("materials" = 4, "magnets" = 5, "plasmatech" = 4, "engineering" = 5) - build_type = PROTOLATHE - materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_PLASMA = 350, MAT_URANIUM = 1000) - build_path = /obj/item/clothing/glasses/night - category = list("Equipment") - -/datum/design/magboots - name = "Magnetic Boots" - desc = "Magnetic boots, often used during extravehicular activity to ensure the user remains safely attached to the vehicle." - id = "magboots" - req_tech = list("materials" = 4, "magnets" = 4, "engineering" = 5) - build_type = PROTOLATHE - materials = list(MAT_METAL = 4500, MAT_SILVER = 1500, MAT_GOLD = 2500) - build_path = /obj/item/clothing/shoes/magboots - category = list("Equipment") - -/datum/design/sci_goggles - name = "Science Goggles" - desc = "Goggles fitted with a portable analyzer capable of determining the research worth of an item or components of a machine." - id = "scigoggles" - req_tech = list("magnets" = 2) - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500) - build_path = /obj/item/clothing/glasses/science - category = list("Equipment") - -/datum/design/handdrill - name = "Hand Drill" - desc = "A small electric hand drill with an interchangeable screwdriver and bolt bit" - id = "handdrill" - req_tech = list("materials" = 4, "engineering" = 6) - build_type = PROTOLATHE - materials = list(MAT_METAL = 3500, MAT_SILVER = 1500, MAT_TITANIUM = 2500) - build_path = /obj/item/screwdriver/power - category = list("Equipment") - -/datum/design/jawsoflife - name = "Jaws of Life" - desc = "A small, compact Jaws of Life with an interchangeable pry jaws and cutting jaws" - id = "jawsoflife" - req_tech = list("materials" = 4, "engineering" = 6, "magnets" = 6) // added one more requirment since the Jaws of Life are a bit OP - build_path = /obj/item/crowbar/power - build_type = PROTOLATHE - materials = list(MAT_METAL = 4500, MAT_SILVER = 2500, MAT_TITANIUM = 3500) - category = list("Equipment") - -/datum/design/alienwrench - name = "Alien Wrench" - desc = "An advanced wrench obtained through Abductor technology." - id = "alien_wrench" - req_tech = list("engineering" = 5, "materials" = 5, "abductor" = 4) - build_path = /obj/item/wrench/abductor - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) - category = list("Equipment") - -/datum/design/alienwirecutters - name = "Alien Wirecutters" - desc = "Advanced wirecutters obtained through Abductor technology." - id = "alien_wirecutters" - req_tech = list("engineering" = 5, "materials" = 5, "abductor" = 4) - build_path = /obj/item/wirecutters/abductor - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) - category = list("Equipment") - -/datum/design/alienscrewdriver - name = "Alien Screwdriver" - desc = "An advanced screwdriver obtained through Abductor technology." - id = "alien_screwdriver" - req_tech = list("engineering" = 5, "materials" = 5, "abductor" = 4) - build_path = /obj/item/screwdriver/abductor - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) - category = list("Equipment") - -/datum/design/aliencrowbar - name = "Alien Crowbar" - desc = "An advanced crowbar obtained through Abductor technology." - id = "alien_crowbar" - req_tech = list("engineering" = 5, "materials" = 5, "abductor" = 4) - build_path = /obj/item/crowbar/abductor - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) - category = list("Equipment") - -/datum/design/alienwelder - name = "Alien Welding Tool" - desc = "An advanced welding tool obtained through Abductor technology." - id = "alien_welder" - req_tech = list("engineering" = 5, "plasmatech" = 5, "abductor" = 4) - build_path = /obj/item/weldingtool/abductor - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 5000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) - category = list("Equipment") - -/datum/design/alienmultitool - name = "Alien Multitool" - desc = "An advanced multitool obtained through Abductor technology." - id = "alien_multitool" - req_tech = list("engineering" = 5, "programming" = 5, "abductor" = 4) - build_path = /obj/item/device/multitool/abductor - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 5000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) - category = list("Equipment") - -/datum/design/diskplantgene - name = "Plant Data Disk" - desc = "A disk for storing plant genetic data." - id = "diskplantgene" - req_tech = list("programming" = 4, "biotech" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL=200, MAT_GLASS=100) - build_path = /obj/item/disk/plantgene - category = list("Electronics") - -///////////////////////////////////////// -////////////Janitor Designs////////////// -///////////////////////////////////////// - -/datum/design/advmop - name = "Advanced Mop" - desc = "An upgraded mop with a large internal capacity for holding water or other cleaning chemicals." - id = "advmop" - req_tech = list("materials" = 4, "engineering" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 2500, MAT_GLASS = 200) - build_path = /obj/item/mop/advanced - category = list("Equipment") - -/datum/design/blutrash - name = "Trashbag of Holding" - desc = "An advanced trash bag with bluespace properties; capable of holding a plethora of garbage." - id = "blutrash" - req_tech = list("materials" = 5, "bluespace" = 4, "engineering" = 4, "plasmatech" = 3) - build_type = PROTOLATHE - materials = list(MAT_GOLD = 1500, MAT_URANIUM = 250, MAT_PLASMA = 1500) - build_path = /obj/item/storage/bag/trash/bluespace - category = list("Equipment") - -/datum/design/buffer - name = "Floor Buffer Upgrade" - desc = "A floor buffer that can be attached to vehicular janicarts." - id = "buffer" - req_tech = list("materials" = 4, "engineering" = 4) - build_type = PROTOLATHE - materials = list(MAT_METAL = 3000, MAT_GLASS = 200) - build_path = /obj/item/janiupgrade - category = list("Equipment") - -/datum/design/holosign - name = "Holographic Sign Projector" - desc = "A holograpic projector used to project various warning signs." - id = "holosign" - req_tech = list("programming" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 2000, MAT_GLASS = 1000) - build_path = /obj/item/holosign_creator - category = list("Equipment") - -///////////////////////////////////////// -////////////Tools////////////// -///////////////////////////////////////// - -/datum/design/exwelder - name = "Experimental Welding Tool" - desc = "An experimental welder capable of self-fuel generation." - id = "exwelder" - req_tech = list("materials" = 4, "engineering" = 5, "bluespace" = 3, "plasmatech" = 4) - build_type = PROTOLATHE - materials = list(MAT_METAL = 1000, MAT_GLASS = 500, MAT_PLASMA = 1500, MAT_URANIUM = 200) - build_path = /obj/item/weldingtool/experimental - category = list("Equipment") diff --git a/code/modules/research/designs/AI_module_designs.dm b/code/modules/research/designs/AI_module_designs.dm index b56e2eb756..13ddd2582f 100644 --- a/code/modules/research/designs/AI_module_designs.dm +++ b/code/modules/research/designs/AI_module_designs.dm @@ -6,146 +6,142 @@ name = "AI Design (AI Core)" desc = "Allows for the construction of circuit boards used to build new AI cores." id = "aicore" - req_tech = list("programming" = 3) build_path = /obj/item/circuitboard/aicore category = list("AI Modules") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/safeguard_module name = "Module Design (Safeguard)" desc = "Allows for the construction of a Safeguard AI Module." id = "safeguard_module" - req_tech = list("programming" = 3, "materials" = 3) materials = list(MAT_GLASS = 1000, MAT_GOLD = 100) build_path = /obj/item/aiModule/supplied/safeguard category = list("AI Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/onehuman_module name = "Module Design (OneCrew)" desc = "Allows for the construction of a OneCrew AI Module." id = "onehuman_module" - req_tech = list("programming" = 6, "materials" = 4) materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100) build_path = /obj/item/aiModule/zeroth/oneHuman category = list("AI Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/protectstation_module name = "Module Design (ProtectStation)" desc = "Allows for the construction of a ProtectStation AI Module." id = "protectstation_module" - req_tech = list("programming" = 5, "materials" = 4) materials = list(MAT_GLASS = 1000, MAT_GOLD = 100) build_path = /obj/item/aiModule/supplied/protectStation category = list("AI Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/quarantine_module name = "Module Design (Quarantine)" desc = "Allows for the construction of a Quarantine AI Module." id = "quarantine_module" - req_tech = list("programming" = 3, "biotech" = 2, "materials" = 4) materials = list(MAT_GLASS = 1000, MAT_GOLD = 100) build_path = /obj/item/aiModule/supplied/quarantine category = list("AI Modules") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/oxygen_module name = "Module Design (OxygenIsToxicToHumans)" desc = "Allows for the construction of a Safeguard AI Module." id = "oxygen_module" - req_tech = list("programming" = 4, "biotech" = 2, "materials" = 4) materials = list(MAT_GLASS = 1000, MAT_GOLD = 100) build_path = /obj/item/aiModule/supplied/oxygen category = list("AI Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/freeform_module name = "Module Design (Freeform)" desc = "Allows for the construction of a Freeform AI Module." id = "freeform_module" - req_tech = list("programming" = 5, "materials" = 4) materials = list(MAT_GLASS = 1000, MAT_GOLD = 100) build_path = /obj/item/aiModule/supplied/freeform category = list("AI Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/reset_module name = "Module Design (Reset)" desc = "Allows for the construction of a Reset AI Module." id = "reset_module" - req_tech = list("programming" = 4, "materials" = 6) materials = list(MAT_GLASS = 1000, MAT_GOLD = 100) build_path = /obj/item/aiModule/reset category = list("AI Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/purge_module name = "Module Design (Purge)" desc = "Allows for the construction of a Purge AI Module." id = "purge_module" - req_tech = list("programming" = 5, "materials" = 6) materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100) build_path = /obj/item/aiModule/reset/purge category = list("AI Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/remove_module name = "Module Design (Law Removal)" desc = "Allows for the construction of a Law Removal AI Core Module." id = "remove_module" - req_tech = list("programming" = 5, "materials" = 5) materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100) build_path = /obj/item/aiModule/remove category = list("AI Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/freeformcore_module name = "AI Core Module (Freeform)" desc = "Allows for the construction of a Freeform AI Core Module." id = "freeformcore_module" - req_tech = list("programming" = 6, "materials" = 6) materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100) build_path = /obj/item/aiModule/core/freeformcore category = list("AI Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/asimov name = "Core Module Design (Asimov)" desc = "Allows for the construction of an Asimov AI Core Module." id = "asimov_module" - req_tech = list("programming" = 3, "materials" = 5) materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100) build_path = /obj/item/aiModule/core/full/asimov category = list("AI Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/paladin_module name = "Core Module Design (P.A.L.A.D.I.N.)" desc = "Allows for the construction of a P.A.L.A.D.I.N. AI Core Module." id = "paladin_module" - req_tech = list("programming" = 5, "materials" = 5) build_type = IMPRINTER materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100) build_path = /obj/item/aiModule/core/full/paladin category = list("AI Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/tyrant_module name = "Core Module Design (T.Y.R.A.N.T.)" desc = "Allows for the construction of a T.Y.R.A.N.T. AI Module." id = "tyrant_module" - req_tech = list("programming" = 5, "syndicate" = 2, "materials" = 5) materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100) build_path = /obj/item/aiModule/core/full/tyrant category = list("AI Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/corporate_module name = "Core Module Design (Corporate)" desc = "Allows for the construction of a Corporate AI Core Module." id = "corporate_module" - req_tech = list("programming" = 5, "materials" = 5) materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100) build_path = /obj/item/aiModule/core/full/corp category = list("AI Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/default_module name = "Core Module Design (Default)" desc = "Allows for the construction of a Default AI Core Module." id = "default_module" - req_tech = list("programming" = 5, "materials" = 5) materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100) build_path = /obj/item/aiModule/core/full/custom category = list("AI Modules") - - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm index 03424346e8..ff2ccc938f 100644 --- a/code/modules/research/designs/autolathe_designs.dm +++ b/code/modules/research/designs/autolathe_designs.dm @@ -681,7 +681,7 @@ category = list("hacked", "Security") /datum/design/a357 - name = "Ammo Box (.357)" + name = "Speed Loader (.357)" id = "a357" build_type = AUTOLATHE materials = list(MAT_METAL = 30000) @@ -799,3 +799,26 @@ materials = list(MAT_METAL = 300, MAT_GLASS = 200) build_path = /obj/item/device/slime_scanner category = list("initial", "Misc") + +/datum/design/pet_carrier + name = "Pet Carrier" + id = "pet_carrier" + build_type = AUTOLATHE + materials = list(MAT_METAL = 7500, MAT_GLASS = 100) + build_path = /obj/item/pet_carrier + +/datum/design/miniature_power_cell + name = "Light Fixture Battery" + id = "miniature_power_cell" + build_type = AUTOLATHE + materials = list(MAT_GLASS = 20) + build_path = /obj/item/stock_parts/cell/emergency_light + category = list("initial", "Electronics") + +/datum/design/holodisk + name = "Holodisk" + id = "holodisk" + build_type = AUTOLATHE + materials = list(MAT_METAL = 1000) + build_path = /obj/item/disk/holodisk + category = list("initial", "Misc") diff --git a/code/modules/research/designs/bluespace_designs.dm b/code/modules/research/designs/bluespace_designs.dm new file mode 100644 index 0000000000..0ec15ac037 --- /dev/null +++ b/code/modules/research/designs/bluespace_designs.dm @@ -0,0 +1,55 @@ + +///////////////////////////////////////// +//////////////Blue Space///////////////// +///////////////////////////////////////// + +/datum/design/beacon + name = "Tracking Beacon" + desc = "A blue space tracking beacon." + id = "beacon" + build_type = PROTOLATHE + materials = list(MAT_METAL = 150, MAT_GLASS = 100) + build_path = /obj/item/device/radio/beacon + category = list("Bluespace Designs") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_SECURITY + +/datum/design/bag_holding + name = "Bag of Holding" + desc = "A backpack that opens into a localized pocket of bluespace." + id = "bag_holding" + build_type = PROTOLATHE + materials = list(MAT_GOLD = 3000, MAT_DIAMOND = 1500, MAT_URANIUM = 250, MAT_BLUESPACE = 2000) + build_path = /obj/item/storage/backpack/holding + category = list("Bluespace Designs") + dangerous_construction = TRUE + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/bluespace_crystal + name = "Artificial Bluespace Crystal" + desc = "A small blue crystal with mystical properties." + id = "bluespace_crystal" + build_type = PROTOLATHE + materials = list(MAT_DIAMOND = 1500, MAT_PLASMA = 1500) + build_path = /obj/item/ore/bluespace_crystal/artificial + category = list("Bluespace Designs") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/telesci_gps + name = "GPS Device" + desc = "Little thingie that can track its position at all times." + id = "telesci_gps" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 1000) + build_path = /obj/item/device/gps + category = list("Bluespace Designs") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_CARGO + +/datum/design/miningsatchel_holding + name = "Mining Satchel of Holding" + desc = "A mining satchel that can hold an infinite amount of ores." + id = "minerbag_holding" + build_type = PROTOLATHE + materials = list(MAT_GOLD = 250, MAT_URANIUM = 500) //quite cheap, for more convenience + build_path = /obj/item/storage/bag/ore/holding + category = list("Bluespace Designs") + departmental_flags = DEPARTMENTAL_FLAG_CARGO diff --git a/code/modules/research/designs/comp_board_designs.dm b/code/modules/research/designs/comp_board_designs.dm index be5d0aeaee..7e743a396b 100644 --- a/code/modules/research/designs/comp_board_designs.dm +++ b/code/modules/research/designs/comp_board_designs.dm @@ -1,30 +1,32 @@ ///////////////////Computer Boards/////////////////////////////////// /datum/design/board - name = "Computer Design (Battle Arcade Machine)" - desc = "Allows for the construction of circuit boards used to build a new arcade machine." - id = "arcade_battle" - req_tech = list("programming" = 1) + name = "Computer Design ( NULL ENTRY )" + desc = "I promise this doesn't give you syndicate goodies!" build_type = IMPRINTER materials = list(MAT_GLASS = 1000) reagents_list = list("sacid" = 20) + +/datum/design/board/arcade_battle + name = "Computer Design (Battle Arcade Machine)" + desc = "Allows for the construction of circuit boards used to build a new arcade machine." + id = "arcade_battle" build_path = /obj/item/circuitboard/computer/arcade/battle category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING /datum/design/board/orion_trail name = "Computer Design (Orion Trail Arcade Machine)" desc = "Allows for the construction of circuit boards used to build a new Orion Trail machine." id = "arcade_orion" - req_tech = list("programming" = 1) build_path = /obj/item/circuitboard/computer/arcade/orion_trail category = list("Computer Boards") - + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING /datum/design/board/seccamera name = "Computer Design (Security Camera)" desc = "Allows for the construction of circuit boards used to build security camera computers." id = "seccamera" - req_tech = list("programming" = 2, "combat" = 2) build_path = /obj/item/circuitboard/computer/security category = list("Computer Boards") @@ -32,15 +34,14 @@ name = "Computer Design (Xenobiology Console)" desc = "Allows for the construction of circuit boards used to build xenobiology camera computers." id = "xenobioconsole" - req_tech = list("programming" = 3, "biotech" = 3) build_path = /obj/item/circuitboard/computer/xenobiology category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/aiupload name = "Computer Design (AI Upload)" desc = "Allows for the construction of circuit boards used to build an AI Upload Console." id = "aiupload" - req_tech = list("programming" = 5, "engineering" = 4) build_path = /obj/item/circuitboard/computer/aiupload category = list("Computer Boards") @@ -48,7 +49,6 @@ name = "Computer Design (Cyborg Upload)" desc = "Allows for the construction of circuit boards used to build a Cyborg Upload Console." id = "borgupload" - req_tech = list("programming" = 5, "engineering" = 4) build_path = /obj/item/circuitboard/computer/borgupload category = list("Computer Boards") @@ -56,7 +56,6 @@ name = "Computer Design (Medical Records)" desc = "Allows for the construction of circuit boards used to build a medical records console." id = "med_data" - req_tech = list("programming" = 2, "biotech" = 2) build_path = /obj/item/circuitboard/computer/med_data category = list("Computer Boards") @@ -64,7 +63,6 @@ name = "Computer Design (Operating Computer)" desc = "Allows for the construction of circuit boards used to build an operating computer console." id = "operating" - req_tech = list("programming" = 2, "biotech" = 3) build_path = /obj/item/circuitboard/computer/operating category = list("Computer Boards") @@ -72,7 +70,6 @@ name = "Computer Design (PanD.E.M.I.C. 2200)" desc = "Allows for the construction of circuit boards used to build a PanD.E.M.I.C. 2200 console." id = "pandemic" - req_tech = list("programming" = 3, "biotech" = 3) build_path = /obj/item/circuitboard/computer/pandemic category = list("Computer Boards") @@ -80,7 +77,6 @@ name = "Computer Design (DNA Machine)" desc = "Allows for the construction of circuit boards used to build a new DNA scanning console." id = "scan_console" - req_tech = list("programming" = 2, "biotech" = 2) build_path = /obj/item/circuitboard/computer/scan_consolenew category = list("Computer Boards") @@ -88,7 +84,6 @@ name = "Computer Design (Communications)" desc = "Allows for the construction of circuit boards used to build a communications console." id = "comconsole" - req_tech = list("programming" = 3, "magnets" = 3) build_path = /obj/item/circuitboard/computer/communications category = list("Computer Boards") @@ -96,7 +91,6 @@ name = "Computer Design (ID Console)" desc = "Allows for the construction of circuit boards used to build an ID computer." id = "idcardconsole" - req_tech = list("programming" = 3) build_path = /obj/item/circuitboard/computer/card category = list("Computer Boards") @@ -104,7 +98,6 @@ name = "Computer Design (Crew monitoring computer)" desc = "Allows for the construction of circuit boards used to build a Crew monitoring computer." id = "crewconsole" - req_tech = list("programming" = 3, "magnets" = 2, "biotech" = 2) build_path = /obj/item/circuitboard/computer/crew category = list("Computer Boards") @@ -112,7 +105,6 @@ name = "Computer Design (Security Records Console)" desc = "Allows for the construction of circuit boards used to build a security records console." id = "secdata" - req_tech = list("programming" = 2, "combat" = 2) build_path = /obj/item/circuitboard/computer/secure_data category = list("Computer Boards") @@ -120,7 +112,6 @@ name = "Computer Design (Atmosphere Alert)" desc = "Allows for the construction of circuit boards used to build an atmosphere alert console." id = "atmosalerts" - req_tech = list("programming" = 2) build_path = /obj/item/circuitboard/computer/atmos_alert category = list("Computer Boards") @@ -128,7 +119,6 @@ name = "Computer Design (Atmospheric Monitor)" desc = "Allows for the construction of circuit boards used to build an Atmospheric Monitor." id = "atmos_control" - req_tech = list("programming" = 2) build_path = /obj/item/circuitboard/computer/atmos_control category = list("Computer Boards") @@ -136,7 +126,6 @@ name = "Computer Design (Robotics Control Console)" desc = "Allows for the construction of circuit boards used to build a Robotics Control console." id = "robocontrol" - req_tech = list("programming" = 4) build_path = /obj/item/circuitboard/computer/robotics category = list("Computer Boards") @@ -144,7 +133,6 @@ name = "Computer Design (Slot Machine)" desc = "Allows for the construction of circuit boards used to build a new slot machine." id = "slotmachine" - req_tech = list("programming" = 1) build_path = /obj/item/circuitboard/computer/slot_machine category = list("Computer Boards") @@ -152,7 +140,6 @@ name = "Computer Design (Power Monitor)" desc = "Allows for the construction of circuit boards used to build a new power monitor." id = "powermonitor" - req_tech = list("programming" = 2, "powerstorage" = 2) build_path = /obj/item/circuitboard/computer/powermonitor category = list("Computer Boards") @@ -160,7 +147,6 @@ name = "Computer Design (Solar Control)" desc = "Allows for the construction of circuit boards used to build a solar control console." id = "solarcontrol" - req_tech = list("programming" = 2, "powerstorage" = 2) build_path = /obj/item/circuitboard/computer/solar_control category = list("Computer Boards") @@ -168,7 +154,6 @@ name = "Computer Design (Prisoner Management Console)" desc = "Allows for the construction of circuit boards used to build a prisoner management console." id = "prisonmanage" - req_tech = list("programming" = 2) build_path = /obj/item/circuitboard/computer/prisoner category = list("Computer Boards") @@ -176,31 +161,30 @@ name = "Computer Design (Exosuit Control Console)" desc = "Allows for the construction of circuit boards used to build an exosuit control console." id = "mechacontrol" - req_tech = list("programming" = 3) build_path = /obj/item/circuitboard/computer/mecha_control category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/mechapower name = "Computer Design (Mech Bay Power Control Console)" desc = "Allows for the construction of circuit boards used to build a mech bay power control console." id = "mechapower" - req_tech = list("programming" = 3, "powerstorage" = 3) build_path = /obj/item/circuitboard/computer/mech_bay_power_console category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/rdconsole name = "Computer Design (R&D Console)" desc = "Allows for the construction of circuit boards used to build a new R&D console." id = "rdconsole" - req_tech = list("programming" = 4) build_path = /obj/item/circuitboard/computer/rdconsole category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/cargo name = "Computer Design (Supply Console)" desc = "Allows for the construction of circuit boards used to build a Supply Console." id = "cargo" - req_tech = list("programming" = 3) build_path = /obj/item/circuitboard/computer/cargo category = list("Computer Boards") @@ -208,7 +192,6 @@ name = "Computer Design (Supply Request Console)" desc = "Allows for the construction of circuit boards used to build a Supply Request Console." id = "cargorequest" - req_tech = list("programming" = 2) build_path = /obj/item/circuitboard/computer/cargo/request category = list("Computer Boards") @@ -216,7 +199,6 @@ name = "Computer Design (Stock Exchange Console)" desc = "Allows for the construction of circuit boards used to build a Stock Exchange Console." id = "stockexchange" - req_tech = list("programming" = 3) build_path = /obj/item/circuitboard/computer/stockexchange category = list("Computer Boards") @@ -224,7 +206,6 @@ name = "Computer Design (Outpost Status Display)" desc = "Allows for the construction of circuit boards used to build an outpost status display console." id = "mining" - req_tech = list("programming" = 2) build_path = /obj/item/circuitboard/computer/mining category = list("Computer Boards") @@ -232,7 +213,6 @@ name = "Computer Design (Telecommunications Monitoring Console)" desc = "Allows for the construction of circuit boards used to build a telecommunications monitor." id = "comm_monitor" - req_tech = list("programming" = 3, "magnets" = 3, "bluespace" = 2) build_path = /obj/item/circuitboard/computer/comm_monitor category = list("Computer Boards") @@ -240,7 +220,6 @@ name = "Computer Design (Telecommunications Server Monitoring Console)" desc = "Allows for the construction of circuit boards used to build a telecommunication server browser and monitor." id = "comm_server" - req_tech = list("programming" = 3, "magnets" = 3, "bluespace" = 2) build_path = /obj/item/circuitboard/computer/comm_server category = list("Computer Boards") @@ -248,7 +227,6 @@ name = "Computer Design (Messaging Monitor Console)" desc = "Allows for the construction of circuit boards used to build a messaging monitor console." id = "message_monitor" - req_tech = list("programming" = 5) build_path = /obj/item/circuitboard/computer/message_monitor category = list("Computer Boards") @@ -256,15 +234,14 @@ name = "Computer Design (AI Integrity Restorer)" desc = "Allows for the construction of circuit boards used to build an AI Integrity Restorer." id = "aifixer" - req_tech = list("programming" = 4, "magnets" = 3) build_path = /obj/item/circuitboard/computer/aifixer category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/libraryconsole name = "Computer Design (Library Console)" desc = "Allows for the construction of circuit boards used to build a new library console." id = "libraryconsole" - req_tech = list("programming" = 1) build_path = /obj/item/circuitboard/computer/libraryconsole category = list("Computer Boards") @@ -272,6 +249,5 @@ name = "Computer Design (APC Control)" desc = "Allows for the construction of circuit boards used to build a new APC control console." id = "apc_control" - req_tech = list("programming" = 4, "engineering" = 4, "powerstorage" = 5) build_path = /obj/item/circuitboard/computer/apc_control category = list("Computer Boards") diff --git a/code/modules/research/designs/computer_part_designs.dm b/code/modules/research/designs/computer_part_designs.dm index 318070c084..15c37a117e 100644 --- a/code/modules/research/designs/computer_part_designs.dm +++ b/code/modules/research/designs/computer_part_designs.dm @@ -5,257 +5,251 @@ /datum/design/disk/normal name = "Hard Disk Drive" id = "hdd_basic" - req_tech = list("programming" = 1, "engineering" = 1) build_type = PROTOLATHE materials = list(MAT_METAL = 400, MAT_GLASS = 100) build_path = /obj/item/computer_hardware/hard_drive category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/disk/advanced name = "Advanced Hard Disk Drive" id = "hdd_advanced" - req_tech = list("programming" = 2, "engineering" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 800, MAT_GLASS = 200) build_path = /obj/item/computer_hardware/hard_drive/advanced category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/disk/super name = "Super Hard Disk Drive" id = "hdd_super" - req_tech = list("programming" = 3, "engineering" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 1600, MAT_GLASS = 400) build_path = /obj/item/computer_hardware/hard_drive/super category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/disk/cluster name = "Cluster Hard Disk Drive" id = "hdd_cluster" - req_tech = list("programming" = 4, "engineering" = 4) build_type = PROTOLATHE materials = list(MAT_METAL = 3200, MAT_GLASS = 800) build_path = /obj/item/computer_hardware/hard_drive/cluster category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/disk/small name = "Solid State Drive" id = "ssd_small" - req_tech = list("programming" = 2, "engineering" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 800, MAT_GLASS = 200) build_path = /obj/item/computer_hardware/hard_drive/small category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/disk/micro name = "Micro Solid State Drive" id = "ssd_micro" - req_tech = list("programming" = 1, "engineering" = 1) build_type = PROTOLATHE materials = list(MAT_METAL = 400, MAT_GLASS = 100) build_path = /obj/item/computer_hardware/hard_drive/micro category = list("Computer Parts") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING // Network cards /datum/design/netcard/basic name = "Network Card" id = "netcard_basic" - req_tech = list("programming" = 2, "engineering" = 1) build_type = IMPRINTER materials = list(MAT_METAL = 250, MAT_GLASS = 100) reagents_list = list("sacid" = 20) build_path = /obj/item/computer_hardware/network_card category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/netcard/advanced name = "Advanced Network Card" id = "netcard_advanced" - req_tech = list("programming" = 4, "engineering" = 2) build_type = IMPRINTER materials = list(MAT_METAL = 500, MAT_GLASS = 200) reagents_list = list("sacid" = 20) build_path = /obj/item/computer_hardware/network_card/advanced category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/netcard/wired name = "Wired Network Card" id = "netcard_wired" - req_tech = list("programming" = 5, "engineering" = 3) build_type = IMPRINTER materials = list(MAT_METAL = 2500, MAT_GLASS = 400) reagents_list = list("sacid" = 20) build_path = /obj/item/computer_hardware/network_card/wired category = list("Computer Parts") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING // Data disks /datum/design/portabledrive/basic name = "Data Disk" id = "portadrive_basic" - req_tech = list("programming" = 1) build_type = IMPRINTER materials = list(MAT_GLASS = 800) reagents_list = list("sacid" = 20) build_path = /obj/item/computer_hardware/hard_drive/portable category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/portabledrive/advanced name = "Advanced Data Disk" id = "portadrive_advanced" - req_tech = list("programming" = 2) build_type = IMPRINTER materials = list(MAT_GLASS = 1600) reagents_list = list("sacid" = 20) build_path = /obj/item/computer_hardware/hard_drive/portable/advanced category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/portabledrive/super name = "Super Data Disk" id = "portadrive_super" - req_tech = list("programming" = 4) build_type = IMPRINTER materials = list(MAT_GLASS = 3200) reagents_list = list("sacid" = 20) build_path = /obj/item/computer_hardware/hard_drive/portable/super category = list("Computer Parts") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING // Card slot /datum/design/cardslot name = "ID Card Slot" id = "cardslot" - req_tech = list("programming" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 600) build_path = /obj/item/computer_hardware/card_slot category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING // Intellicard slot /datum/design/aislot name = "Intellicard Slot" id = "aislot" - req_tech = list("programming" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 600) build_path = /obj/item/computer_hardware/ai_slot category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING // Mini printer /datum/design/miniprinter name = "Miniprinter" id = "miniprinter" - req_tech = list("programming" = 2, "engineering" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 600) build_path = /obj/item/computer_hardware/printer/mini category = list("Computer Parts") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING // APC Link /datum/design/APClink name = "Area Power Connector" id = "APClink" - req_tech = list("programming" = 2, "powerstorage" = 3, "engineering" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 2000) build_path = /obj/item/computer_hardware/recharger/APC category = list("Computer Parts") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING // Batteries /datum/design/battery/controller name = "Power Cell Controller" id = "bat_control" - req_tech = list("powerstorage" = 1, "engineering" = 1) build_type = PROTOLATHE materials = list(MAT_METAL = 400) build_path = /obj/item/computer_hardware/battery category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/battery/normal name = "Battery Module" id = "bat_normal" - req_tech = list("powerstorage" = 1, "engineering" = 1) build_type = PROTOLATHE materials = list(MAT_METAL = 400) build_path = /obj/item/stock_parts/cell/computer category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/battery/advanced name = "Advanced Battery Module" id = "bat_advanced" - req_tech = list("powerstorage" = 2, "engineering" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 800) build_path = /obj/item/stock_parts/cell/computer/advanced category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/battery/super name = "Super Battery Module" id = "bat_super" - req_tech = list("powerstorage" = 3, "engineering" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 1600) build_path = /obj/item/stock_parts/cell/computer/super category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/battery/nano name = "Nano Battery Module" id = "bat_nano" - req_tech = list("powerstorage" = 1, "engineering" = 1) build_type = PROTOLATHE materials = list(MAT_METAL = 200) build_path = /obj/item/stock_parts/cell/computer/nano category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/battery/micro name = "Micro Battery Module" id = "bat_micro" - req_tech = list("powerstorage" = 2, "engineering" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 400) build_path = /obj/item/stock_parts/cell/computer/micro category = list("Computer Parts") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING // Processor unit /datum/design/cpu name = "Processor Board" id = "cpu_normal" - req_tech = list("programming" = 3, "engineering" = 2) build_type = IMPRINTER materials = list(MAT_GLASS = 1600) reagents_list = list("sacid" = 20) build_path = /obj/item/computer_hardware/processor_unit category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/cpu/small name = "Microprocessor" id = "cpu_small" - req_tech = list("programming" = 2, "engineering" = 2) build_type = IMPRINTER materials = list(MAT_GLASS = 800) reagents_list = list("sacid" = 20) build_path = /obj/item/computer_hardware/processor_unit/small category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/cpu/photonic name = "Photonic Processor Board" id = "pcpu_normal" - req_tech = list("programming" = 5, "engineering" = 4) build_type = IMPRINTER materials = list(MAT_GLASS= 6400, MAT_GOLD = 2000) reagents_list = list("sacid" = 40) build_path = /obj/item/computer_hardware/processor_unit/photonic category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/cpu/photonic/small name = "Photonic Microprocessor" id = "pcpu_small" - req_tech = list("programming" = 4, "engineering" = 3) build_type = IMPRINTER materials = list(MAT_GLASS = 3200, MAT_GOLD = 1000) reagents_list = list("sacid" = 20) build_path = /obj/item/computer_hardware/processor_unit/photonic/small - category = list("Computer Parts") \ No newline at end of file + category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING diff --git a/code/modules/research/designs/electronics_designs.dm b/code/modules/research/designs/electronics_designs.dm new file mode 100644 index 0000000000..bbc8e18c63 --- /dev/null +++ b/code/modules/research/designs/electronics_designs.dm @@ -0,0 +1,87 @@ + +/////////////////////////////////// +/////Non-Board Computer Stuff////// +/////////////////////////////////// + +/datum/design/intellicard + name = "Intellicard AI Transportation System" + desc = "Allows for the construction of an intellicard." + id = "intellicard" + build_type = PROTOLATHE + materials = list(MAT_GLASS = 1000, MAT_GOLD = 200) + build_path = /obj/item/device/aicard + category = list("Electronics") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/paicard + name = "Personal Artificial Intelligence Card" + desc = "Allows for the construction of a pAI Card." + id = "paicard" + build_type = PROTOLATHE + materials = list(MAT_GLASS = 500, MAT_METAL = 500) + build_path = /obj/item/device/paicard + category = list("Electronics") + departmental_flags = DEPARTMENTAL_FLAG_ALL + +//////////////////////////////////////// +//////////Disk Construction Disks/////// +//////////////////////////////////////// +/datum/design/design_disk + name = "Design Storage Disk" + desc = "Produce additional disks for storing device designs." + id = "design_disk" + build_type = PROTOLATHE | AUTOLATHE + materials = list(MAT_METAL = 300, MAT_GLASS = 100) + build_path = /obj/item/disk/design_disk + category = list("Electronics") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/design_disk_adv + name = "Advanced Design Storage Disk" + desc = "Produce additional disks for storing device designs." + id = "design_disk_adv" + build_type = PROTOLATHE + materials = list(MAT_METAL = 300, MAT_GLASS = 100, MAT_SILVER=50) + build_path = /obj/item/disk/design_disk/adv + category = list("Electronics") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/tech_disk + name = "Technology Data Storage Disk" + desc = "Produce additional disks for storing technology data." + id = "tech_disk" + build_type = PROTOLATHE | AUTOLATHE + materials = list(MAT_METAL = 300, MAT_GLASS = 100) + build_path = /obj/item/disk/tech_disk + category = list("Electronics") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/integrated_printer + name = "Integrated circuits printer" + desc = "This machine provides all neccesary things for circuitry." + id = "icprinter" + build_type = PROTOLATHE + materials = list(MAT_GLASS = 5000, MAT_METAL = 5000) + build_path = /obj/item/device/integrated_circuit_printer + category = list("Electronics") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/IC_printer_upgrade_advanced + name = "Integrated Circuits printer upgrade: Advanced Designs" + desc = "This disk allows for integrated circuit printers to print advanced circuitry designs." + id = "icupgadv" + build_type = PROTOLATHE + materials = list(MAT_GLASS = 10000, MAT_METAL = 10000) + build_path = /obj/item/disk/integrated_circuit/upgrade/advanced + category = list("Electronics") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/IC_printer_upgrade_clone + name = "Integrated Circuits printer upgrade: Clone Ability" + desc = "This disk allows for integrated circuit printers to clone designs." + id = "icupgclo" + build_type = PROTOLATHE + materials = list(MAT_GLASS = 10000, MAT_METAL = 10000) + build_path = /obj/item/disk/integrated_circuit/upgrade/clone + category = list("Electronics") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE diff --git a/code/modules/research/designs/equipment_designs.dm b/code/modules/research/designs/equipment_designs.dm new file mode 100644 index 0000000000..e369dfa724 --- /dev/null +++ b/code/modules/research/designs/equipment_designs.dm @@ -0,0 +1,32 @@ +/datum/design/flightsuit + name = "Flight Suit" + desc = "A specialized hardsuit that is able to attach a flightpack and accessories.." + id = "flightsuit" + build_type = PROTOLATHE + build_path = /obj/item/clothing/suit/space/hardsuit/flightsuit + materials = list(MAT_METAL=16000, MAT_GLASS = 8000, MAT_DIAMOND = 200, MAT_GOLD = 3000, MAT_SILVER = 3000, MAT_TITANIUM = 16000) //This expensive enough for you? + construction_time = 250 + category = list("Misc") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/flightpack + name = "Flight Pack" + desc = "An advanced back-worn system that has dual ion engines powerful enough to grant a humanoid flight. Contains an internal self-recharging high-current capacitor for short, powerful boosts." + id = "flightpack" + build_type = PROTOLATHE + build_path = /obj/item/device/flightpack + materials = list(MAT_METAL=16000, MAT_GLASS = 8000, MAT_DIAMOND = 4000, MAT_GOLD = 12000, MAT_SILVER = 12000, MAT_URANIUM = 20000, MAT_PLASMA = 16000, MAT_TITANIUM = 16000) //This expensive enough for you? + construction_time = 250 + category = list("Misc") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/flightshoes + name = "Flight Shoes" + desc = "Flight shoes, attachable to a flight suit to provide additional functions." + id = "flightshoes" + build_type = PROTOLATHE + build_path = /obj/item/clothing/shoes/flightshoes + materials = list(MAT_METAL = 5000, MAT_GLASS = 5000, MAT_GOLD = 1500, MAT_SILVER = 1500, MAT_PLASMA = 2000, MAT_TITANIUM = 2000) + construction_time = 100 + category = list("Misc") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index 14346ee13b..2343bd8814 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -6,7 +6,6 @@ name = "Machine Design (SMES Board)" desc = "The circuit board for a SMES." id = "smes" - req_tech = list("programming" = 4, "powerstorage" = 5, "engineering" = 4) build_path = /obj/item/circuitboard/machine/smes category = list ("Engineering Machinery") @@ -14,7 +13,6 @@ name = "Machine Design (Automated Announcement System Board)" desc = "The circuit board for an automated announcement system." id = "automated_announcement" - req_tech = list("programming" = 3, "bluespace" = 3, "magnets" = 2) build_path = /obj/item/circuitboard/machine/announcement_system category = list("Subspace Telecomms") @@ -22,7 +20,6 @@ name = "Computer Design (Power Turbine Console Board)" desc = "The circuit board for a power turbine console." id = "power_turbine_console" - req_tech = list("programming" = 4, "powerstorage" = 5, "engineering" = 4) build_path = /obj/item/circuitboard/computer/turbine_computer category = list ("Engineering Machinery") @@ -30,7 +27,6 @@ name = "Machine Design (Emitter Board)" desc = "The circuit board for an emitter." id = "emitter" - req_tech = list("programming" = 3, "powerstorage" = 5, "engineering" = 4) build_path = /obj/item/circuitboard/machine/emitter category = list ("Engineering Machinery") @@ -38,7 +34,6 @@ name = "Machine Design (Power Compressor Board)" desc = "The circuit board for a power compressor." id = "power_compressor" - req_tech = list("programming" = 4, "powerstorage" = 5, "engineering" = 4) build_path = /obj/item/circuitboard/machine/power_compressor category = list ("Engineering Machinery") @@ -46,7 +41,6 @@ name = "Machine Design (Power Turbine Board)" desc = "The circuit board for a power turbine." id = "power_turbine" - req_tech = list("programming" = 4, "powerstorage" = 4, "engineering" = 5) build_path = /obj/item/circuitboard/machine/power_turbine category = list ("Engineering Machinery") @@ -54,7 +48,6 @@ name = "Machine Design (Freezer/Heater Board)" desc = "The circuit board for a freezer/heater." id = "thermomachine" - req_tech = list("programming" = 3, "plasmatech" = 3) build_path = /obj/item/circuitboard/machine/thermomachine category = list ("Engineering Machinery") @@ -62,7 +55,6 @@ name = "Machine Design (Space Heater Board)" desc = "The circuit board for a space heater." id = "space_heater" - req_tech = list("programming" = 2, "engineering" = 2, "plasmatech" = 2) build_path = /obj/item/circuitboard/machine/space_heater category = list ("Engineering Machinery") @@ -70,55 +62,54 @@ name = "Machine Design (Teleportation Station Board)" desc = "The circuit board for a teleportation station." id = "tele_station" - req_tech = list("programming" = 5, "bluespace" = 4, "engineering" = 4, "plasmatech" = 4) build_path = /obj/item/circuitboard/machine/teleporter_station category = list ("Teleportation Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/teleport_hub name = "Machine Design (Teleportation Hub Board)" desc = "The circuit board for a teleportation hub." id = "tele_hub" - req_tech = list("programming" = 3, "bluespace" = 5, "materials" = 4, "engineering" = 5) build_path = /obj/item/circuitboard/machine/teleporter_hub category = list ("Teleportation Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/quantumpad name = "Machine Design (Quantum Pad Board)" desc = "The circuit board for a quantum telepad." id = "quantumpad" - req_tech = list("programming" = 4, "bluespace" = 4, "plasmatech" = 3, "engineering" = 4) build_path = /obj/item/circuitboard/machine/quantumpad category = list ("Teleportation Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/launchpad name = "Machine Design (Bluespace Launchpad Board)" desc = "The circuit board for a bluespace Launchpad." id = "launchpad" - req_tech = list("programming" = 3, "bluespace" = 3, "plasmatech" = 2, "engineering" = 3) build_path = /obj/item/circuitboard/machine/launchpad category = list ("Teleportation Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/launchpad_console name = "Machine Design (Bluespace Launchpad Console Board)" desc = "The circuit board for a bluespace launchpad Console." id = "launchpad_console" - req_tech = list("programming" = 4, "bluespace" = 3, "plasmatech" = 3) build_path = /obj/item/circuitboard/computer/launchpad_console category = list ("Teleportation Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/teleconsole name = "Computer Design (Teleporter Console)" desc = "Allows for the construction of circuit boards used to build a teleporter control console." id = "teleconsole" - req_tech = list("programming" = 3, "bluespace" = 3, "plasmatech" = 4) build_path = /obj/item/circuitboard/computer/teleporter category = list("Teleportation Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/sleeper name = "Machine Design (Sleeper Board)" desc = "The circuit board for a sleeper." id = "sleeper" - req_tech = list("programming" = 3, "biotech" = 2, "engineering" = 3) build_path = /obj/item/circuitboard/machine/sleeper category = list ("Medical Machinery") @@ -126,7 +117,6 @@ name = "Machine Design (Cryotube Board)" desc = "The circuit board for a cryotube." id = "cryotube" - req_tech = list("programming" = 5, "biotech" = 3, "engineering" = 4, "plasmatech" = 3) build_path = /obj/item/circuitboard/machine/cryo_tube category = list ("Medical Machinery") @@ -134,7 +124,6 @@ name = "Machine Design (Portable Chem Dispenser Board)" desc = "The circuit board for a portable chem dispenser." id = "chem_dispenser" - req_tech = list("programming" = 5, "biotech" = 3, "materials" = 4, "plasmatech" = 4) build_path = /obj/item/circuitboard/machine/chem_dispenser category = list ("Medical Machinery") @@ -142,7 +131,6 @@ name = "Machine Design (Chem Master Board)" desc = "The circuit board for a Chem Master 3000." id = "chem_master" - req_tech = list("biotech" = 3, "materials" = 3, "programming" = 2) build_path = /obj/item/circuitboard/machine/chem_master category = list ("Medical Machinery") @@ -150,7 +138,6 @@ name = "Machine Design (Chemical Heater Board)" desc = "The circuit board for a chemical heater." id = "chem_heater" - req_tech = list("engineering" = 2, "biotech" = 2, "programming" = 2) build_path = /obj/item/circuitboard/machine/chem_heater category = list ("Medical Machinery") @@ -158,7 +145,6 @@ name = "Machine Design (Smoke Machine)" desc = "The circuit board for a smoke machine." id = "smoke_machine" - req_tech = list("materials" = 4, "biotech" = 3, "engineering" = 3) build_path = /obj/item/circuitboard/machine/smoke_machine category = list ("Medical Machinery") @@ -166,7 +152,6 @@ name = "Computer Design (Cloning Machine Console)" desc = "Allows for the construction of circuit boards used to build a new Cloning Machine console." id = "clonecontrol" - req_tech = list("programming" = 4, "biotech" = 3) build_path = /obj/item/circuitboard/computer/cloning category = list("Medical Machinery") @@ -174,7 +159,6 @@ name = "Machine Design (Clone Pod)" desc = "Allows for the construction of circuit boards used to build a Cloning Pod." id = "clonepod" - req_tech = list("programming" = 4, "biotech" = 3) build_path = /obj/item/circuitboard/machine/clonepod category = list("Medical Machinery") @@ -182,7 +166,6 @@ name = "Machine Design (Cloning Scanner)" desc = "Allows for the construction of circuit boards used to build a Cloning Scanner." id = "clonescanner" - req_tech = list("programming" = 4, "biotech" = 3) build_path = /obj/item/circuitboard/machine/clonescanner category = list("Medical Machinery") @@ -190,7 +173,6 @@ name = "Machine Design (Biogenerator Board)" desc = "The circuit board for a biogenerator." id = "biogenerator" - req_tech = list("programming" = 2, "biotech" = 3, "materials" = 3) build_path = /obj/item/circuitboard/machine/biogenerator category = list ("Hydroponics Machinery") @@ -198,7 +180,6 @@ name = "Machine Design (Hydroponics Tray Board)" desc = "The circuit board for a hydroponics tray." id = "hydro_tray" - req_tech = list("biotech" = 2) build_path = /obj/item/circuitboard/machine/hydroponics category = list ("Hydroponics Machinery") @@ -206,23 +187,22 @@ name = "Machine Design (Destructive Analyzer Board)" desc = "The circuit board for a destructive analyzer." id = "destructive_analyzer" - req_tech = list("programming" = 2, "magnets" = 2, "engineering" = 2) build_path = /obj/item/circuitboard/machine/destructive_analyzer category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/experimentor name = "Machine Design (E.X.P.E.R.I-MENTOR Board)" desc = "The circuit board for an E.X.P.E.R.I-MENTOR." id = "experimentor" - req_tech = list("programming" = 2, "magnets" = 2, "engineering" = 2, "bluespace" = 2) build_path = /obj/item/circuitboard/machine/experimentor category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/protolathe name = "Machine Design (Protolathe Board)" desc = "The circuit board for a protolathe." id = "protolathe" - req_tech = list("programming" = 2, "engineering" = 2) build_path = /obj/item/circuitboard/machine/protolathe category = list("Research Machinery") @@ -230,7 +210,6 @@ name = "Machine Design (Circuit Imprinter Board)" desc = "The circuit board for a circuit imprinter." id = "circuit_imprinter" - req_tech = list("programming" = 2, "engineering" = 2) build_path = /obj/item/circuitboard/machine/circuit_imprinter category = list("Research Machinery") @@ -238,47 +217,46 @@ name = "Computer Design (R&D Server Control Console Board)" desc = "The circuit board for an R&D Server Control Console." id = "rdservercontrol" - req_tech = list("programming" = 3) build_path = /obj/item/circuitboard/computer/rdservercontrol category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/rdserver name = "Machine Design (R&D Server Board)" desc = "The circuit board for an R&D Server." id = "rdserver" - req_tech = list("programming" = 3) build_path = /obj/item/circuitboard/machine/rdserver category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/mechfab name = "Machine Design (Exosuit Fabricator Board)" desc = "The circuit board for an Exosuit Fabricator." id = "mechfab" - req_tech = list("programming" = 3, "engineering" = 3) build_path = /obj/item/circuitboard/machine/mechfab category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/cyborgrecharger name = "Machine Design (Cyborg Recharger Board)" desc = "The circuit board for a Cyborg Recharger." id = "cyborgrecharger" - req_tech = list("powerstorage" = 3, "engineering" = 3) build_path = /obj/item/circuitboard/machine/cyborgrecharger category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/mech_recharger name = "Machine Design (Mechbay Recharger Board)" desc = "The circuit board for a Mechbay Recharger." id = "mech_recharger" - req_tech = list("programming" = 3, "powerstorage" = 4, "engineering" = 3) build_path = /obj/item/circuitboard/machine/mech_recharger category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/microwave name = "Machine Design (Microwave Board)" desc = "The circuit board for a microwave." id = "microwave" - req_tech = list("programming" = 2, "magnets" = 2) build_path = /obj/item/circuitboard/machine/microwave category = list ("Misc. Machinery") @@ -286,7 +264,6 @@ name = "Machine Design (Gibber Board)" desc = "The circuit board for a gibber." id = "gibber" - req_tech = list("programming" = 2, "engineering" = 2) build_path = /obj/item/circuitboard/machine/gibber category = list ("Misc. Machinery") @@ -294,7 +271,6 @@ name = "Machine Design (Smartfridge Board)" desc = "The circuit board for a smartfridge." id = "smartfridge" - req_tech = list("programming" = 1) build_path = /obj/item/circuitboard/machine/smartfridge category = list ("Misc. Machinery") @@ -302,7 +278,6 @@ name = "Machine Design (Monkey Recycler Board)" desc = "The circuit board for a monkey recycler." id = "monkey_recycler" - req_tech = list("programming" = 1) build_path = /obj/item/circuitboard/machine/monkey_recycler category = list ("Misc. Machinery") @@ -310,7 +285,6 @@ name = "Machine Design (Seed Extractor Board)" desc = "The circuit board for a seed extractor." id = "seed_extractor" - req_tech = list("programming" = 1) build_path = /obj/item/circuitboard/machine/seed_extractor category = list ("Misc. Machinery") @@ -318,7 +292,6 @@ name = "Machine Design (Food Processor Board)" desc = "The circuit board for a food processor." id = "processor" - req_tech = list("programming" = 1) build_path = /obj/item/circuitboard/machine/processor category = list ("Misc. Machinery") @@ -326,7 +299,6 @@ name = "Machine Design (Slime Processor Board)" desc = "The circuit board for a slime processor." id = "slimeprocessor" - req_tech = list("programming" = 1, "plasmatech" = 1) build_path = /obj/item/circuitboard/machine/processor/slime category = list ("Misc. Machinery") @@ -334,7 +306,6 @@ name = "Machine Design (Recycler Board)" desc = "The circuit board for a recycler." id = "recycler" - req_tech = list("programming" = 2, "engineering" = 2) build_path = /obj/item/circuitboard/machine/recycler category = list ("Misc. Machinery") @@ -342,15 +313,14 @@ name = "Machine Design (AI Holopad Board)" desc = "The circuit board for a holopad." id = "holopad" - req_tech = list("programming" = 1) build_path = /obj/item/circuitboard/machine/holopad category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ALL /datum/design/board/autolathe name = "Machine Design (Autolathe Board)" desc = "The circuit board for an autolathe." id = "autolathe" - req_tech = list("programming" = 3, "engineering" = 3) build_path = /obj/item/circuitboard/machine/autolathe category = list ("Misc. Machinery") @@ -358,7 +328,6 @@ name = "Machine Design (Weapon Recharger Board)" desc = "The circuit board for a Weapon Recharger." id = "recharger" - req_tech = list("powerstorage" = 4, "engineering" = 3, "materials" = 4) materials = list(MAT_GLASS = 1000, MAT_GOLD = 100) build_path = /obj/item/circuitboard/machine/recharger category = list("Misc. Machinery") @@ -367,7 +336,6 @@ name = "Machine Design (Vendor Board)" desc = "The circuit board for a Vendor." id = "vendor" - req_tech = list("programming" = 1) build_path = /obj/item/circuitboard/machine/vendor category = list ("Misc. Machinery") @@ -375,23 +343,22 @@ name = "Machine Design (Ore Redemption Board)" desc = "The circuit board for an Ore Redemption machine." id = "ore_redemption" - req_tech = list("programming" = 2, "engineering" = 2, "plasmatech" = 3) build_path = /obj/item/circuitboard/machine/ore_redemption category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/mining_equipment_vendor name = "Machine Design (Mining Rewards Vender Board)" desc = "The circuit board for a Mining Rewards Vender." id = "mining_equipment_vendor" - req_tech = list("engineering" = 3) build_path = /obj/item/circuitboard/machine/mining_equipment_vendor category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/tesla_coil name = "Machine Design (Tesla Coil Board)" desc = "The circuit board for a tesla coil." id = "tesla_coil" - req_tech = list("programming" = 3, "powerstorage" = 3, "magnets" = 3) build_path = /obj/item/circuitboard/machine/tesla_coil category = list ("Misc. Machinery") @@ -399,7 +366,6 @@ name = "Machine Design (Grounding Rod Board)" desc = "The circuit board for a grounding rod." id = "grounding_rod" - req_tech = list("programming" = 3, "powerstorage" = 3, "magnets" = 3, "plasmatech" = 2) build_path = /obj/item/circuitboard/machine/grounding_rod category = list ("Misc. Machinery") @@ -407,7 +373,6 @@ name = "Machine Design (Plant DNA Manipulator Board)" desc = "The circuit board for a plant DNA manipulator." id = "plantgenes" - req_tech = list("programming" = 4, "biotech" = 3) build_path = /obj/item/circuitboard/machine/plantgenes category = list ("Misc. Machinery") @@ -415,15 +380,14 @@ name = "Machine Design (NTNet Relay Board)" desc = "The circuit board for a wireless network relay." id = "ntnet_relay" - req_tech = list("programming" = 2, "engineering" = 2, "bluespace" = 2) build_path = /obj/item/circuitboard/machine/ntnet_relay category = list("Subspace Telecomms") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/limbgrower name = "Machine Design (Limb Grower Board)" desc = "The circuit board for a limb grower." id = "limbgrower" - req_tech = list("programming" = 3, "biotech" = 2) build_path = /obj/item/circuitboard/machine/limbgrower category = list("Medical Machinery") @@ -431,7 +395,6 @@ name = "Machine Design (Deep Fryer)" desc = "The circuit board for a Deep Fryer." id = "deepfryer" - req_tech = list("programming" = 1) build_path = /obj/item/circuitboard/machine/deep_fryer category = list ("Misc. Machinery") @@ -439,6 +402,5 @@ name = "Machine Design (Donksoft Toy Vendor Board)" desc = "The circuit board for a Donksoft Toy Vendor." id = "donksofttoyvendor" - req_tech = list("programming" = 1, "syndicate" = 2) build_path = /obj/item/circuitboard/machine/vending/donksofttoyvendor category = list ("Misc. Machinery") diff --git a/code/modules/research/designs/mecha_designs.dm b/code/modules/research/designs/mecha_designs.dm index 8dbc118a0b..cee0dc7413 100644 --- a/code/modules/research/designs/mecha_designs.dm +++ b/code/modules/research/designs/mecha_designs.dm @@ -6,137 +6,132 @@ name = "APLU \"Ripley\" Central Control module" desc = "Allows for the construction of a \"Ripley\" Central Control module." id = "ripley_main" - req_tech = list("programming" = 2) build_path = /obj/item/circuitboard/mecha/ripley/main category = list("Exosuit Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/ripley_peri name = "APLU \"Ripley\" Peripherals Control module" desc = "Allows for the construction of a \"Ripley\" Peripheral Control module." id = "ripley_peri" - req_tech = list("programming" = 2) build_path = /obj/item/circuitboard/mecha/ripley/peripherals category = list("Exosuit Modules") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/odysseus_main name = "\"Odysseus\" Central Control module" desc = "Allows for the construction of a \"Odysseus\" Central Control module." id = "odysseus_main" - req_tech = list("programming" = 3,"biotech" = 3, "engineering" = 3) build_path = /obj/item/circuitboard/mecha/odysseus/main category = list("Exosuit Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/odysseus_peri name = "\"Odysseus\" Peripherals Control module" desc = "Allows for the construction of a \"Odysseus\" Peripheral Control module." id = "odysseus_peri" - req_tech = list("programming" = 3,"biotech" = 3, "engineering" = 3) build_path = /obj/item/circuitboard/mecha/odysseus/peripherals category = list("Exosuit Modules") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/gygax_main name = "\"Gygax\" Central Control module" desc = "Allows for the construction of a \"Gygax\" Central Control module." id = "gygax_main" - req_tech = list("programming" = 4, "combat" = 3, "engineering" = 4) build_path = /obj/item/circuitboard/mecha/gygax/main category = list("Exosuit Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/gygax_peri name = "\"Gygax\" Peripherals Control module" desc = "Allows for the construction of a \"Gygax\" Peripheral Control module." id = "gygax_peri" - req_tech = list("programming" = 4, "combat" = 3, "engineering" = 4) build_path = /obj/item/circuitboard/mecha/gygax/peripherals category = list("Exosuit Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/gygax_targ name = "\"Gygax\" Weapons & Targeting Control module" desc = "Allows for the construction of a \"Gygax\" Weapons & Targeting Control module." id = "gygax_targ" - req_tech = list("programming" = 4, "combat" = 4, "engineering" = 4) build_path = /obj/item/circuitboard/mecha/gygax/targeting category = list("Exosuit Modules") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/durand_main name = "\"Durand\" Central Control module" desc = "Allows for the construction of a \"Durand\" Central Control module." id = "durand_main" - req_tech = list("programming" = 4, "combat" = 4, "engineering" = 4) build_path = /obj/item/circuitboard/mecha/durand/main category = list("Exosuit Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/durand_peri name = "\"Durand\" Peripherals Control module" desc = "Allows for the construction of a \"Durand\" Peripheral Control module." id = "durand_peri" - req_tech = list("programming" = 4, "combat" = 4, "engineering" = 4) build_path = /obj/item/circuitboard/mecha/durand/peripherals category = list("Exosuit Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/durand_targ name = "\"Durand\" Weapons & Targeting Control module" desc = "Allows for the construction of a \"Durand\" Weapons & Targeting Control module." id = "durand_targ" - req_tech = list("programming" = 5, "combat" = 4, "engineering" = 4) build_path = /obj/item/circuitboard/mecha/durand/targeting category = list("Exosuit Modules") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/honker_main name = "\"H.O.N.K\" Central Control module" desc = "Allows for the construction of a \"H.O.N.K\" Central Control module." id = "honker_main" - req_tech = list("programming" = 3, "engineering" = 3) build_path = /obj/item/circuitboard/mecha/honker/main category = list("Exosuit Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/honker_peri name = "\"H.O.N.K\" Peripherals Control module" desc = "Allows for the construction of a \"H.O.N.K\" Peripheral Control module." id = "honker_peri" - req_tech = list("programming" = 3, "engineering" = 3) build_path = /obj/item/circuitboard/mecha/honker/peripherals category = list("Exosuit Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/honker_targ name = "\"H.O.N.K\" Weapons & Targeting Control module" desc = "Allows for the construction of a \"H.O.N.K\" Weapons & Targeting Control module." id = "honker_targ" - req_tech = list("programming" = 3, "engineering" = 3) build_path = /obj/item/circuitboard/mecha/honker/targeting category = list("Exosuit Modules") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/phazon_main name = "\"Phazon\" Central Control module" desc = "Allows for the construction of a \"Phazon\" Central Control module." id = "phazon_main" materials = list(MAT_GLASS = 1000, MAT_BLUESPACE = 100) - req_tech = list("programming" = 6, "materials" = 6, "plasmatech" = 5) build_path = /obj/item/circuitboard/mecha/phazon/main category = list("Exosuit Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/phazon_peri name = "\"Phazon\" Peripherals Control module" desc = "Allows for the construction of a \"Phazon\" Peripheral Control module." id = "phazon_peri" materials = list(MAT_GLASS = 1000, MAT_BLUESPACE = 100) - req_tech = list("programming" = 6, "bluespace" = 5, "plasmatech" = 5) build_path = /obj/item/circuitboard/mecha/phazon/peripherals category = list("Exosuit Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/phazon_targ name = "\"Phazon\" Weapons & Targeting Control module" desc = "Allows for the construction of a \"Phazon\" Weapons & Targeting Control module." id = "phazon_targ" materials = list(MAT_GLASS = 1000, MAT_BLUESPACE = 100) - req_tech = list("programming" = 6, "magnets" = 5, "plasmatech" = 5) build_path = /obj/item/circuitboard/mecha/phazon/targeting category = list("Exosuit Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE //////////////////////////////////////// /////////// Mecha Equpment ///////////// @@ -147,7 +142,6 @@ desc = "Allows for the construction of LBX AC 10." id = "mech_scattershot" build_type = MECHFAB - req_tech = list("combat" = 4) build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot materials = list(MAT_METAL=10000) construction_time = 100 @@ -158,7 +152,6 @@ desc = "Allows for the construction of FNX-99 \"Hades\" Carbine." id = "mech_carbine" build_type = MECHFAB - req_tech = list("combat" = 5, "materials" = 4) build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/carbine materials = list(MAT_METAL=10000) construction_time = 100 @@ -169,7 +162,6 @@ desc = "Allows for the construction of MKIV Ion Heavy Cannon." id = "mech_ion" build_type = MECHFAB - req_tech = list("combat" = 6, "magnets" = 5, "materials" = 5) build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/ion materials = list(MAT_METAL=20000,MAT_SILVER=6000,MAT_URANIUM=2000) construction_time = 100 @@ -180,7 +172,6 @@ desc = "Allows for the construction of MKI Tesla Cannon." id = "mech_tesla" build_type = MECHFAB - req_tech = list("combat" = 6, "magnets" = 5, "materials" = 5) build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/tesla materials = list(MAT_METAL=20000,MAT_SILVER=8000) construction_time = 100 @@ -191,7 +182,6 @@ desc = "Allows for the construction of CH-PS Laser." id = "mech_laser" build_type = MECHFAB - req_tech = list("combat" = 3, "magnets" = 3, "engineering" = 3) build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser materials = list(MAT_METAL=10000) construction_time = 100 @@ -202,7 +192,6 @@ desc = "Allows for the construction of CH-LC Laser Cannon." id = "mech_laser_heavy" build_type = MECHFAB - req_tech = list("combat" = 4, "magnets" = 4, "engineering" = 4) build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy materials = list(MAT_METAL=10000) construction_time = 100 @@ -213,7 +202,6 @@ desc = "Allows for the construction of SGL-6 Grenade Launcher." id = "mech_grenade_launcher" build_type = MECHFAB - req_tech = list("combat" = 4, "engineering" = 4) build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang materials = list(MAT_METAL=22000,MAT_GOLD=6000,MAT_SILVER=8000) construction_time = 100 @@ -224,7 +212,6 @@ desc = "Allows for the construction of SRM-8 Missile Rack." id = "mech_missile_rack" build_type = MECHFAB - req_tech = list("combat" = 6, "materials" = 5, "engineering" = 5) build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack materials = list(MAT_METAL=22000,MAT_GOLD=6000,MAT_SILVER=8000) construction_time = 100 @@ -235,7 +222,6 @@ desc = "A weapon that violates the Geneva Convention at 3 rounds per minute" id = "clusterbang_launcher" build_type = MECHFAB - req_tech = list("combat"= 5, "materials" = 5, "syndicate" = 3) build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/clusterbang materials = list(MAT_METAL=20000,MAT_GOLD=10000,MAT_URANIUM=10000) construction_time = 100 @@ -246,7 +232,6 @@ desc = "An exosuit module that allows generating of small quasi-stable wormholes." id = "mech_wormhole_gen" build_type = MECHFAB - req_tech = list("bluespace" = 4, "magnets" = 4, "plasmatech" = 3) build_path = /obj/item/mecha_parts/mecha_equipment/wormhole_generator materials = list(MAT_METAL=10000) construction_time = 100 @@ -257,7 +242,6 @@ desc = "An exosuit module that allows exosuits to teleport to any position in view." id = "mech_teleporter" build_type = MECHFAB - req_tech = list("bluespace" = 8, "magnets" = 5) build_path = /obj/item/mecha_parts/mecha_equipment/teleporter materials = list(MAT_METAL=10000,MAT_DIAMOND=10000) construction_time = 100 @@ -268,7 +252,6 @@ desc = "An exosuit-mounted Rapid Construction Device." id = "mech_rcd" build_type = MECHFAB - req_tech = list("materials" = 5, "bluespace" = 3, "magnets" = 4, "powerstorage"=4, "engineering" = 5) build_path = /obj/item/mecha_parts/mecha_equipment/rcd materials = list(MAT_METAL=30000,MAT_GOLD=20000,MAT_PLASMA=25000,MAT_SILVER=20000) construction_time = 1200 @@ -279,7 +262,6 @@ desc = "An exosuit mounted Gravitational Catapult." id = "mech_gravcatapult" build_type = MECHFAB - req_tech = list("bluespace" = 4, "magnets" = 3, "engineering" = 4) build_path = /obj/item/mecha_parts/mecha_equipment/gravcatapult materials = list(MAT_METAL=10000) construction_time = 100 @@ -290,7 +272,6 @@ desc = "Automated Repair Droid. BEEP BOOP" id = "mech_repair_droid" build_type = MECHFAB - req_tech = list("magnets" = 3, "programming" = 3, "engineering" = 5) build_path = /obj/item/mecha_parts/mecha_equipment/repair_droid materials = list(MAT_METAL=10000,MAT_GLASS=5000,MAT_GOLD=1000,MAT_SILVER=2000) construction_time = 100 @@ -301,7 +282,6 @@ desc = "Tesla Energy Relay" id = "mech_energy_relay" build_type = MECHFAB - req_tech = list("magnets" = 4, "powerstorage" = 5, "engineering" = 4) build_path = /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay materials = list(MAT_METAL=10000,MAT_GLASS=2000,MAT_GOLD=2000,MAT_SILVER=3000) construction_time = 100 @@ -312,7 +292,6 @@ desc = "Exosuit-mounted armor booster." id = "mech_ccw_armor" build_type = MECHFAB - req_tech = list("materials" = 5, "combat" = 4) build_path = /obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster materials = list(MAT_METAL=20000,MAT_SILVER=5000) construction_time = 100 @@ -323,7 +302,6 @@ desc = "Exosuit-mounted armor booster." id = "mech_proj_armor" build_type = MECHFAB - req_tech = list("materials" = 5, "combat" = 5, "engineering"=3) build_path = /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster materials = list(MAT_METAL=20000,MAT_GOLD=5000) construction_time = 100 @@ -334,7 +312,6 @@ desc = "An upgraded version of the standard drill." id = "mech_diamond_drill" build_type = MECHFAB - req_tech = list("materials" = 5, "engineering" = 4) build_path = /obj/item/mecha_parts/mecha_equipment/drill/diamonddrill materials = list(MAT_METAL=10000,MAT_DIAMOND=6500) construction_time = 100 @@ -345,7 +322,6 @@ desc = "Compact nuclear reactor module." id = "mech_generator_nuclear" build_type = MECHFAB - req_tech = list("powerstorage"= 5, "engineering" = 4, "materials" = 3) build_path = /obj/item/mecha_parts/mecha_equipment/generator/nuclear materials = list(MAT_METAL=10000,MAT_GLASS=1000,MAT_SILVER=500) construction_time = 100 @@ -356,7 +332,6 @@ desc = "A device that shoots resonant plasma bursts at extreme velocity. The blasts are capable of crushing rock and demolishing solid obstacles." id = "mech_plasma_cutter" build_type = MECHFAB - req_tech = list("engineering" = 3, "materials" = 3, "plasmatech" = 4) build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma materials = list(MAT_METAL = 8000, MAT_GLASS = 1000, MAT_PLASMA = 2000) construction_time = 100 @@ -367,7 +342,6 @@ desc = "A weapon for combat exosuits. Shoots non-lethal stunning electrodes." id = "mech_taser" build_type = MECHFAB - req_tech = list("combat" = 3) build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/taser materials = list(MAT_METAL=10000) construction_time = 100 @@ -378,7 +352,6 @@ desc = "A weapon for combat exosuits. Shoots a rapid, three shot burst." id = "mech_lmg" build_type = MECHFAB - req_tech = list("combat" = 4) build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg materials = list(MAT_METAL=10000) construction_time = 100 @@ -389,7 +362,6 @@ desc = "Equipment for medical exosuits. A mounted sleeper that stabilizes patients and can inject reagents in the exosuit's reserves." id = "mech_sleeper" build_type = MECHFAB - req_tech = list("biotech" = 3, "engineering" = 3, "plasmatech" = 2) build_path = /obj/item/mecha_parts/mecha_equipment/medical/sleeper materials = list(MAT_METAL=5000,MAT_GLASS=10000) construction_time = 100 @@ -400,7 +372,6 @@ desc = "Equipment for medical exosuits. A chem synthesizer with syringe gun. Reagents inside are held in stasis, so no reactions will occur." id = "mech_syringe_gun" build_type = MECHFAB - req_tech = list("magnets" = 4,"biotech" = 4, "combat" = 3, "materials" = 4) build_path = /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun materials = list(MAT_METAL=3000,MAT_GLASS=2000) construction_time = 200 @@ -410,7 +381,6 @@ name = "Exosuit Medical Equipment (Medical Beamgun)" desc = "Equipment for medical exosuits. A mounted medical nanite projector which will treat patients with a focused beam." id = "mech_medi_beam" - req_tech = list("engineering" = 6, "materials" = 7, "powerstorage" = 5, "biotech" = 6) build_type = MECHFAB materials = list(MAT_METAL = 15000, MAT_GLASS = 8000, MAT_PLASMA = 3000, MAT_GOLD = 8000, MAT_DIAMOND = 2000) construction_time = 250 diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index 6d0c32fcb1..74cd8805ab 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -593,7 +593,6 @@ id = "borg_upgrade_vtec" build_type = MECHFAB build_path = /obj/item/borg/upgrade/vtec - req_tech = list("engineering" = 4, "materials" = 5, "programming" = 4) materials = list(MAT_METAL=80000 , MAT_GLASS=6000 , MAT_URANIUM= 5000) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -603,7 +602,6 @@ id = "borg_upgrade_thrusters" build_type = MECHFAB build_path = /obj/item/borg/upgrade/thrusters - req_tech = list("engineering" = 4, "powerstorage" = 4) materials = list(MAT_METAL=10000, MAT_PLASMA=5000, MAT_URANIUM = 6000) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -613,7 +611,6 @@ id = "borg_upgrade_disablercooler" build_type = MECHFAB build_path = /obj/item/borg/upgrade/disablercooler - req_tech = list("combat" = 5, "powerstorage" = 4, "engineering" = 4) materials = list(MAT_METAL=80000 , MAT_GLASS=6000 , MAT_GOLD= 2000, MAT_DIAMOND = 500) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -623,7 +620,6 @@ id = "borg_upgrade_diamonddrill" build_type = MECHFAB build_path = /obj/item/borg/upgrade/ddrill - req_tech = list("engineering" = 5, "materials" = 6) materials = list(MAT_METAL=10000, MAT_DIAMOND=2000) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -633,7 +629,6 @@ id = "borg_upgrade_holding" build_type = MECHFAB build_path = /obj/item/borg/upgrade/soh - req_tech = list("engineering" = 4, "materials" = 4, "bluespace" = 4) materials = list(MAT_METAL = 10000, MAT_GOLD = 250, MAT_URANIUM = 500) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -643,7 +638,6 @@ id = "borg_upgrade_lavaproof" build_type = MECHFAB build_path = /obj/item/borg/upgrade/lavaproof - req_tech = list("plasmatech" = 4, "materials" = 4, "engineering" = 4) materials = list(MAT_METAL = 10000, MAT_PLASMA = 4000, MAT_TITANIUM = 5000) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -652,7 +646,6 @@ name = "Cyborg Upgrade (Illegal Modules)" id = "borg_syndicate_module" build_type = MECHFAB - req_tech = list("combat" = 4, "syndicate" = 2) build_path = /obj/item/borg/upgrade/syndicate materials = list(MAT_METAL=10000,MAT_GLASS=15000,MAT_DIAMOND = 10000) construction_time = 120 @@ -663,7 +656,6 @@ id = "borg_upgrade_selfrepair" build_type = MECHFAB build_path = /obj/item/borg/upgrade/selfrepair - req_tech = list("materials" = 4, "engineering" = 4) materials = list(MAT_METAL=15000, MAT_GLASS=15000) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -673,7 +665,6 @@ id = "borg_upgrade_expandedsynthesiser" build_type = MECHFAB build_path = /obj/item/borg/upgrade/hypospray/expanded - req_tech = list("programming" = 5, "engineering" = 4, "biotech" = 5) materials = list(MAT_METAL=15000, MAT_GLASS=15000, MAT_PLASMA=5000) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -683,7 +674,6 @@ id = "borg_upgrade_highstrengthsynthesiser" build_type = MECHFAB build_path = /obj/item/borg/upgrade/hypospray/high_strength - req_tech = list("programming" = 5, "engineering" = 5, "biotech" = 6) materials = list(MAT_METAL=15000, MAT_GLASS=15000, MAT_PLASMA=10000, MAT_URANIUM=5000) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -693,7 +683,6 @@ id = "borg_upgrade_piercinghypospray" build_type = MECHFAB build_path = /obj/item/borg/upgrade/piercing_hypospray - req_tech = list("materials" = 5, "engineering" = 7, "combat" = 3) materials = list(MAT_METAL=15000, MAT_GLASS=15000, MAT_TITANIUM=10000, MAT_DIAMOND=5000) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -703,7 +692,6 @@ id = "borg_upgrade_defibrillator" build_type = MECHFAB build_path = /obj/item/borg/upgrade/defib - req_tech = list("programming" = 4, "engineering" = 5, "materials" = 5, "powerstorage" = 5, "biotech" = 5) materials = list(MAT_METAL=15000, MAT_GLASS=15000, MAT_SILVER=10000, MAT_GOLD=10000, MAT_TITANIUM=5000, MAT_DIAMOND=5000) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -714,7 +702,6 @@ build_type = MECHFAB build_path = /obj/item/borg/upgrade/ai materials = list(MAT_METAL = 1200, MAT_GLASS = 1500, MAT_GOLD = 200) - req_tech = list("programming" = 4, "magnets" = 4, "engineering" = 4) construction_time = 50 category = list("Misc") @@ -734,7 +721,6 @@ build_type = MECHFAB build_path = /obj/item/mecha_parts/mecha_tracking/ai_control materials = list(MAT_METAL = 1000, MAT_GLASS = 500, MAT_SILVER = 200) - req_tech = list("programming" = 3, "magnets" = 2, "engineering" = 2) construction_time = 50 category = list("Misc") @@ -742,12 +728,12 @@ name = "Drone Shell" desc = "A shell of a maintenance drone, an expendable robot built to perform station repairs." id = "drone_shell" - req_tech = list("programming" = 2, "biotech" = 4) build_type = MECHFAB | PROTOLATHE materials = list(MAT_METAL = 800, MAT_GLASS = 350) construction_time=150 build_path = /obj/item/drone_shell category = list("Misc") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING /datum/design/synthetic_flash name = "Flash" @@ -758,36 +744,3 @@ construction_time = 100 build_path = /obj/item/device/assembly/flash/handheld category = list("Misc") - -/datum/design/flightsuit //Multi step build process/redo WIP - name = "Flight Suit" - desc = "A specialized hardsuit that is able to attach a flightpack and accessories.." - id = "flightsuit" - build_type = MECHFAB - build_path = /obj/item/clothing/suit/space/hardsuit/flightsuit - materials = list(MAT_METAL=16000, MAT_GLASS = 8000, MAT_DIAMOND = 200, MAT_GOLD = 3000, MAT_SILVER = 3000, MAT_TITANIUM = 16000) //This expensive enough for you? - construction_time = 250 - category = list("Misc") - req_tech = list("magnets" = 2, "combat" = 2, "plasmatech" = 2, "materials" = 4, "engineering" = 3, "powerstorage" = 2) - -/datum/design/flightpack - name = "Flight Pack" - desc = "An advanced back-worn system that has dual ion engines powerful enough to grant a humanoid flight. Contains an internal self-recharging high-current capacitor for short, powerful boosts." - id = "flightpack" - build_type = MECHFAB - build_path = /obj/item/device/flightpack - materials = list(MAT_METAL=16000, MAT_GLASS = 8000, MAT_DIAMOND = 4000, MAT_GOLD = 12000, MAT_SILVER = 12000, MAT_URANIUM = 20000, MAT_PLASMA = 16000, MAT_TITANIUM = 16000) //This expensive enough for you? - construction_time = 250 - category = list("Misc") - req_tech = list("magnets" = 4, "combat" = 3, "plasmatech" = 4, "materials" = 5, "engineering" = 4, "powerstorage" = 4) - -/datum/design/flightshoes - name = "Flight Shoes" - desc = "Flight shoes, attachable to a flight suit to provide additional functions." - id = "flightshoes" - build_type = MECHFAB - build_path = /obj/item/clothing/shoes/flightshoes - materials = list(MAT_METAL = 5000, MAT_GLASS = 5000, MAT_GOLD = 1500, MAT_SILVER = 1500, MAT_PLASMA = 2000, MAT_TITANIUM = 2000) - construction_time = 100 - category = list("Misc") - req_tech = list("magnets" = 2, "combat" = 2, "plasmatech" = 3, "materials" = 3, "engineering" = 2, "powerstorage" = 2) diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 89767a1c55..c1405ad55c 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -2,178 +2,157 @@ ////////////Medical Tools//////////////// ///////////////////////////////////////// - -/datum/design/mass_spectrometer - name = "Mass-Spectrometer" - desc = "A device for analyzing chemicals in the blood." - id = "mass_spectrometer" - req_tech = list("magnets" = 2, "plasmatech" = 2) - build_type = PROTOLATHE - materials = list(MAT_METAL = 300, MAT_GLASS = 100) - build_path = /obj/item/device/mass_spectrometer - category = list("Medical Designs") - -/datum/design/adv_mass_spectrometer - name = "Advanced Mass-Spectrometer" - desc = "A device for analyzing chemicals in the blood and their quantities." - id = "adv_mass_spectrometer" - req_tech = list("biotech" = 3, "magnets" = 4, "plasmatech" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 200) - build_path = /obj/item/device/mass_spectrometer/adv - category = list("Medical Designs") - /datum/design/mmi name = "Man-Machine Interface" desc = "The Warrior's bland acronym, MMI, obscures the true horror of this monstrosity." id = "mmi" - req_tech = list("programming" = 3, "biotech" = 2, "engineering" = 2) build_type = PROTOLATHE | MECHFAB materials = list(MAT_METAL = 1000, MAT_GLASS = 500) construction_time = 75 build_path = /obj/item/device/mmi category = list("Misc","Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE /datum/design/posibrain name = "Positronic Brain" desc = "The latest in Artificial Intelligences." id = "mmi_posi" - req_tech = list("programming" = 5, "biotech" = 4, "plasmatech" = 3) build_type = PROTOLATHE | MECHFAB materials = list(MAT_METAL = 1700, MAT_GLASS = 1350, MAT_GOLD = 500) //Gold, because SWAG. construction_time = 75 build_path = /obj/item/device/mmi/posibrain category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE /datum/design/bluespacebeaker name = "Bluespace Beaker" desc = "A bluespace beaker, powered by experimental bluespace technology and Element Cuban combined with the Compound Pete. Can hold up to 300 units." id = "bluespacebeaker" - req_tech = list("bluespace" = 6, "materials" = 5, "plasmatech" = 4) build_type = PROTOLATHE materials = list(MAT_GLASS = 3000, MAT_PLASMA = 3000, MAT_DIAMOND = 250, MAT_BLUESPACE = 250) build_path = /obj/item/reagent_containers/glass/beaker/bluespace category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE /datum/design/noreactbeaker name = "Cryostasis Beaker" desc = "A cryostasis beaker that allows for chemical storage without reactions. Can hold up to 50 units." id = "splitbeaker" - req_tech = list("materials" = 3, "engineering" = 3, "plasmatech" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 3000) build_path = /obj/item/reagent_containers/glass/beaker/noreact category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/bluespacesyringe name = "Bluespace Syringe" desc = "An advanced syringe that can hold 60 units of chemicals" id = "bluespacesyringe" - req_tech = list("bluespace" = 5, "materials" = 4, "biotech" = 4) build_type = PROTOLATHE materials = list(MAT_GLASS = 2000, MAT_PLASMA = 1000, MAT_DIAMOND = 1000, MAT_BLUESPACE = 500) build_path = /obj/item/reagent_containers/syringe/bluespace category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE /datum/design/noreactsyringe name = "Cryo Syringe" desc = "An advanced syringe that stops reagents inside from reacting. It can hold up to 20 units." id = "noreactsyringe" - req_tech = list("materials" = 3, "engineering" = 3) build_type = PROTOLATHE materials = list(MAT_GLASS = 2000, MAT_GOLD = 1000) build_path = /obj/item/reagent_containers/syringe/noreact category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/piercesyringe name = "Piercing Syringe" desc = "A diamond-tipped syringe that pierces armor when launched at high velocity. It can hold up to 10 units." id = "piercesyringe" - req_tech = list("materials" = 7, "combat" = 3, "engineering" = 5) build_type = PROTOLATHE materials = list(MAT_GLASS = 2000, MAT_DIAMOND = 1000) build_path = /obj/item/reagent_containers/syringe/piercing category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/bluespacebodybag name = "Bluespace Body Bag" desc = "A bluespace body bag, powered by experimental bluespace technology. It can hold loads of bodies and the largest of creatures." id = "bluespacebodybag" - req_tech = list("bluespace" = 5, "materials" = 4, "plasmatech" = 4) build_type = PROTOLATHE materials = list(MAT_METAL = 3000, MAT_PLASMA = 2000, MAT_DIAMOND = 500, MAT_BLUESPACE = 500) build_path = /obj/item/bodybag/bluespace category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE /datum/design/plasmarefiller name = "Plasma-Man Jumpsuit Refill" desc = "A refill pack for the auto-extinguisher on Plasma-man suits." - id = "plasmarefiller" - req_tech = list("materials" = 2, "plasmatech" = 3) //Why did this have no plasmatech + id = "plasmarefiller" //Why did this have no plasmatech build_type = PROTOLATHE materials = list(MAT_METAL = 4000, MAT_PLASMA = 1000) build_path = /obj/item/device/extinguisher_refill category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_ALL /datum/design/alienscalpel name = "Alien Scalpel" desc = "An advanced scalpel obtained through Abductor technology." id = "alien_scalpel" - req_tech = list("biotech" = 4, "materials" = 4, "abductor" = 3) build_path = /obj/item/scalpel/alien build_type = PROTOLATHE materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/alienhemostat name = "Alien Hemostat" desc = "An advanced hemostat obtained through Abductor technology." id = "alien_hemostat" - req_tech = list("biotech" = 4, "materials" = 4, "abductor" = 3) build_path = /obj/item/hemostat/alien build_type = PROTOLATHE materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/alienretractor name = "Alien Retractor" desc = "An advanced retractor obtained through Abductor technology." id = "alien_retractor" - req_tech = list("biotech" = 4, "materials" = 4, "abductor" = 3) build_path = /obj/item/retractor/alien build_type = PROTOLATHE materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/aliensaw name = "Alien Circular Saw" desc = "An advanced surgical saw obtained through Abductor technology." id = "alien_saw" - req_tech = list("biotech" = 4, "materials" = 4, "abductor" = 3) build_path = /obj/item/circular_saw/alien build_type = PROTOLATHE materials = list(MAT_METAL = 10000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 1500) category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/aliendrill name = "Alien Drill" desc = "An advanced drill obtained through Abductor technology." id = "alien_drill" - req_tech = list("biotech" = 4, "materials" = 4, "abductor" = 3) build_path = /obj/item/surgicaldrill/alien build_type = PROTOLATHE materials = list(MAT_METAL = 10000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 1500) category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/aliencautery name = "Alien Cautery" desc = "An advanced cautery obtained through Abductor technology." id = "alien_cautery" - req_tech = list("biotech" = 4, "materials" = 4, "abductor" = 3) build_path = /obj/item/cautery/alien build_type = PROTOLATHE materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL ///////////////////////////////////////// //////////Cybernetic Implants//////////// @@ -183,167 +162,166 @@ name = "Welding Shield Eyes" desc = "These reactive micro-shields will protect you from welders and flashes without obscuring your vision." id = "ci-welding" - req_tech = list("materials" = 4, "biotech" = 4, "engineering" = 5, "plasmatech" = 4) build_type = PROTOLATHE | MECHFAB construction_time = 40 materials = list(MAT_METAL = 600, MAT_GLASS = 400) build_path = /obj/item/organ/eyes/robotic/shield category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_gloweyes name = "Luminescent Eyes" desc = "A pair of cybernetic eyes that can emit multicolored light" id = "ci-gloweyes" - req_tech = list("materials" = 3, "biotech" = 3, "engineering" = 4) build_type = PROTOLATHE | MECHFAB construction_time = 40 materials = list(MAT_METAL = 600, MAT_GLASS = 1000) build_path = /obj/item/organ/eyes/robotic/glow category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_breather name = "Breathing Tube Implant" desc = "This simple implant adds an internals connector to your back, allowing you to use internals without a mask and protecting you from being choked." id = "ci-breather" - req_tech = list("materials" = 2, "biotech" = 3) build_type = PROTOLATHE | MECHFAB construction_time = 35 materials = list(MAT_METAL = 600, MAT_GLASS = 250) build_path = /obj/item/organ/cyberimp/mouth/breathing_tube category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_surgical - name = "Surgical Arm Implant" - desc = "A set of surgical tools hidden behind a concealed panel on the user's arm." - id = "ci-surgery" - req_tech = list("materials" = 3, "engineering" = 3, "biotech" = 3, "programming" = 2, "magnets" = 3) - build_type = PROTOLATHE | MECHFAB - materials = list (MAT_METAL = 2500, MAT_GLASS = 1500, MAT_SILVER = 1500) - construction_time = 200 - build_path = /obj/item/organ/cyberimp/arm/surgery - category = list("Misc", "Medical Designs") + name = "Surgical Arm Implant" + desc = "A set of surgical tools hidden behind a concealed panel on the user's arm." + id = "ci-surgery" + build_type = PROTOLATHE | MECHFAB + materials = list (MAT_METAL = 2500, MAT_GLASS = 1500, MAT_SILVER = 1500) + construction_time = 200 + build_path = /obj/item/organ/cyberimp/arm/surgery + category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_toolset name = "Toolset Arm Implant" desc = "A stripped-down version of engineering cyborg toolset, designed to be installed on subject's arm." id = "ci-toolset" - req_tech = list("materials" = 3, "engineering" = 4, "biotech" = 4, "powerstorage" = 4) build_type = PROTOLATHE | MECHFAB materials = list (MAT_METAL = 2500, MAT_GLASS = 1500, MAT_SILVER = 1500) construction_time = 200 build_path = /obj/item/organ/cyberimp/arm/toolset category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_medical_hud name = "Medical HUD Implant" desc = "These cybernetic eyes will display a medical HUD over everything you see. Wiggle eyes to control." id = "ci-medhud" - req_tech = list("materials" = 5, "programming" = 4, "biotech" = 4) build_type = PROTOLATHE | MECHFAB construction_time = 50 materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_SILVER = 500, MAT_GOLD = 500) build_path = /obj/item/organ/cyberimp/eyes/hud/medical category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_security_hud name = "Security HUD Implant" desc = "These cybernetic eyes will display a security HUD over everything you see. Wiggle eyes to control." id = "ci-sechud" - req_tech = list("materials" = 5, "programming" = 4, "biotech" = 4, "combat" = 3) build_type = PROTOLATHE | MECHFAB construction_time = 50 materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_SILVER = 750, MAT_GOLD = 750) build_path = /obj/item/organ/cyberimp/eyes/hud/security category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_xray name = "X-Ray Eyes" desc = "These cybernetic eyes will give you X-ray vision. Blinking is futile." id = "ci-xray" - req_tech = list("materials" = 7, "programming" = 5, "biotech" = 7, "magnets" = 5,"plasmatech" = 6) build_type = PROTOLATHE | MECHFAB construction_time = 60 materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_SILVER = 600, MAT_GOLD = 600, MAT_PLASMA = 1000, MAT_URANIUM = 1000, MAT_DIAMOND = 1000, MAT_BLUESPACE = 1000) build_path = /obj/item/organ/eyes/robotic/xray category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_thermals name = "Thermal Eyes" desc = "These cybernetic eyes will give you Thermal vision. Vertical slit pupil included." id = "ci-thermals" - req_tech = list("materials" = 6, "programming" = 4, "biotech" = 7, "magnets" = 5,"plasmatech" = 4) build_type = PROTOLATHE | MECHFAB construction_time = 60 materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_SILVER = 600, MAT_GOLD = 600, MAT_PLASMA = 1000, MAT_DIAMOND = 2000) build_path = /obj/item/organ/eyes/robotic/thermals category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_antidrop name = "Anti-Drop Implant" desc = "This cybernetic brain implant will allow you to force your hand muscles to contract, preventing item dropping. Twitch ear to toggle." id = "ci-antidrop" - req_tech = list("materials" = 5, "programming" = 6, "biotech" = 5) build_type = PROTOLATHE | MECHFAB construction_time = 60 materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_SILVER = 400, MAT_GOLD = 400) build_path = /obj/item/organ/cyberimp/brain/anti_drop category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_antistun name = "CNS Rebooter Implant" desc = "This implant will automatically give you back control over your central nervous system, reducing downtime when stunned." id = "ci-antistun" - req_tech = list("materials" = 6, "programming" = 5, "biotech" = 6) build_type = PROTOLATHE | MECHFAB construction_time = 60 materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_SILVER = 500, MAT_GOLD = 1000) build_path = /obj/item/organ/cyberimp/brain/anti_stun category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_nutriment name = "Nutriment Pump Implant" desc = "This implant with synthesize and pump into your bloodstream a small amount of nutriment when you are starving." id = "ci-nutriment" - req_tech = list("materials" = 3, "powerstorage" = 4, "biotech" = 3) build_type = PROTOLATHE | MECHFAB construction_time = 40 materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_GOLD = 500) build_path = /obj/item/organ/cyberimp/chest/nutriment category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_nutriment_plus name = "Nutriment Pump Implant PLUS" desc = "This implant with synthesize and pump into your bloodstream a small amount of nutriment when you are hungry." id = "ci-nutrimentplus" - req_tech = list("materials" = 5, "powerstorage" = 4, "biotech" = 4) build_type = PROTOLATHE | MECHFAB construction_time = 50 materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_GOLD = 500, MAT_URANIUM = 750) build_path = /obj/item/organ/cyberimp/chest/nutriment/plus category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_reviver name = "Reviver Implant" desc = "This implant will attempt to revive you if you lose consciousness. For the faint of heart!" id = "ci-reviver" - req_tech = list("materials" = 5, "programming" = 4, "biotech" = 5) build_type = PROTOLATHE | MECHFAB construction_time = 60 materials = list(MAT_METAL = 800, MAT_GLASS = 800, MAT_GOLD = 300, MAT_URANIUM = 500) build_path = /obj/item/organ/cyberimp/chest/reviver category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_thrusters name = "Thrusters Set Implant" desc = "This implant will allow you to use gas from environment or your internals for propulsion in zero-gravity areas." id = "ci-thrusters" - req_tech = list("materials" = 5, "biotech" = 5, "magnets" = 4, "engineering" = 7) build_type = PROTOLATHE | MECHFAB construction_time = 80 materials = list(MAT_METAL = 4000, MAT_GLASS = 2000, MAT_SILVER = 1000, MAT_DIAMOND = 1000) build_path = /obj/item/organ/cyberimp/chest/thrusters category = list("Misc", "Medical Designs") - + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL ///////////////////////////////////////// ////////////Regular Implants///////////// @@ -353,51 +331,51 @@ name = "Implanter" desc = "A sterile automatic implant injector." id = "implanter" - req_tech = list("materials" = 2, "biotech" = 3, "programming" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 600, MAT_GLASS = 200) build_path = /obj/item/implanter category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL /datum/design/implantcase name = "Implant Case" desc = "A glass case for containing an implant." id = "implantcase" - req_tech = list("biotech" = 2) build_type = PROTOLATHE materials = list(MAT_GLASS = 500) build_path = /obj/item/implantcase category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL /datum/design/implant_sadtrombone name = "Sad Trombone Implant Case" desc = "Makes death amusing." id = "implant_trombone" - req_tech = list("materials" = 2, "biotech" = 3, "programming" = 2) build_type = PROTOLATHE materials = list(MAT_GLASS = 500, MAT_BANANIUM = 500) build_path = /obj/item/implantcase/sad_trombone category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_ALL //if you get bananium you get the sad trombones. /datum/design/implant_chem name = "Chemical Implant Case" desc = "A glass case containing an implant." id = "implant_chem" - req_tech = list("materials" = 3, "biotech" = 5,) build_type = PROTOLATHE materials = list(MAT_GLASS = 700) build_path = /obj/item/implantcase/chem category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL /datum/design/implant_tracking name = "Tracking Implant Case" desc = "A glass case containing an implant." id = "implant_tracking" - req_tech = list("materials" = 2, "biotech" = 3, "magnets" = 3, "programming" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 500, MAT_GLASS = 500) build_path = /obj/item/implantcase/track category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL //Cybernetic organs @@ -405,48 +383,48 @@ name = "Cybernetic Liver" desc = "A cybernetic liver" id = "cybernetic_liver" - req_tech = list("biotech" = 4, "materials" = 4) build_type = PROTOLATHE materials = list(MAT_METAL = 500, MAT_GLASS = 500) build_path = /obj/item/organ/liver/cybernetic category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cybernetic_heart name = "Cybernetic Heart" desc = "A cybernetic heart" id = "cybernetic_heart" - req_tech = list("biotech" = 4, "materials" = 4) build_type = PROTOLATHE materials = list(MAT_METAL = 500, MAT_GLASS = 500) build_path = /obj/item/organ/heart/cybernetic category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cybernetic_liver_u name = "Upgraded Cybernetic Liver" desc = "An upgraded cybernetic liver" id = "cybernetic_liver_u" - req_tech = list("biotech" = 5, "materials" = 5, "plasmatech" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 500, MAT_GLASS = 500) build_path = /obj/item/organ/liver/cybernetic/upgraded category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cybernetic_lungs name = "Cybernetic Lungs" desc = "A pair of cybernetic lungs." id = "cybernetic_lungs" - req_tech = list("biotech" = 4, "materials" = 4) build_type = PROTOLATHE materials = list(MAT_METAL = 500, MAT_GLASS = 500) build_path = /obj/item/organ/lungs/cybernetic category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cybernetic_lungs_u name = "Upgraded Cybernetic Lungs" desc = "A pair of upgraded cybernetic lungs." id = "cybernetic_lungs_u" - req_tech = list("biotech" = 5, "materials" = 5, "engineering" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 500) build_path = /obj/item/organ/lungs/cybernetic/upgraded - category = list("Medical Designs") \ No newline at end of file + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL diff --git a/code/modules/research/designs/mining_designs.dm b/code/modules/research/designs/mining_designs.dm new file mode 100644 index 0000000000..8b193577e0 --- /dev/null +++ b/code/modules/research/designs/mining_designs.dm @@ -0,0 +1,114 @@ + +///////////////////////////////////////// +/////////////////Mining////////////////// +///////////////////////////////////////// + +/datum/design/drill + name = "Mining Drill" + desc = "Yours is the drill that will pierce through the rock walls." + id = "drill" + build_type = PROTOLATHE + materials = list(MAT_METAL = 6000, MAT_GLASS = 1000) //expensive, but no need for miners. + build_path = /obj/item/pickaxe/drill + category = list("Mining Designs") + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/drill_diamond + name = "Diamond-Tipped Mining Drill" + desc = "Yours is the drill that will pierce the heavens!" + id = "drill_diamond" + build_type = PROTOLATHE + materials = list(MAT_METAL = 6000, MAT_GLASS = 1000, MAT_DIAMOND = 2000) //Yes, a whole diamond is needed. + build_path = /obj/item/pickaxe/drill/diamonddrill + category = list("Mining Designs") + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/plasmacutter + name = "Plasma Cutter" + desc = "You could use it to cut limbs off of xenos! Or, you know, mine stuff." + id = "plasmacutter" + build_type = PROTOLATHE + materials = list(MAT_METAL = 1500, MAT_GLASS = 500, MAT_PLASMA = 400) + build_path = /obj/item/gun/energy/plasmacutter + category = list("Mining Designs") + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/plasmacutter_adv + name = "Advanced Plasma Cutter" + desc = "It's an advanced plasma cutter, oh my god." + id = "plasmacutter_adv" + build_type = PROTOLATHE + materials = list(MAT_METAL = 3000, MAT_GLASS = 1000, MAT_PLASMA = 2000, MAT_GOLD = 500) + build_path = /obj/item/gun/energy/plasmacutter/adv + category = list("Mining Designs") + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/jackhammer + name = "Sonic Jackhammer" + desc = "Essentially a handheld planet-cracker. Can drill through walls with ease as well." + id = "jackhammer" + build_type = PROTOLATHE + materials = list(MAT_METAL = 6000, MAT_GLASS = 2000, MAT_SILVER = 2000, MAT_DIAMOND = 6000) + build_path = /obj/item/pickaxe/drill/jackhammer + category = list("Mining Designs") + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/superresonator + name = "Upgraded Resonator" + desc = "An upgraded version of the resonator that allows more fields to be active at once." + id = "superresonator" + build_type = PROTOLATHE + materials = list(MAT_METAL = 4000, MAT_GLASS = 1500, MAT_SILVER = 1000, MAT_URANIUM = 1000) + build_path = /obj/item/resonator/upgraded + category = list("Mining Designs") + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/trigger_guard_mod + name = "Kinetic Accelerator Trigger Guard Mod" + desc = "A device which allows kinetic accelerators to be wielded by any organism." + id = "triggermod" + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) + build_path = /obj/item/borg/upgrade/modkit/trigger_guard + category = list("Mining Designs") + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/damage_mod + name = "Kinetic Accelerator Damage Mod" + desc = "A device which allows kinetic accelerators to deal more damage." + id = "damagemod" + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) + build_path = /obj/item/borg/upgrade/modkit/damage + category = list("Mining Designs", "Cyborg Upgrade Modules") + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/cooldown_mod + name = "Kinetic Accelerator Cooldown Mod" + desc = "A device which decreases the cooldown of a Kinetic Accelerator." + id = "cooldownmod" + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) + build_path = /obj/item/borg/upgrade/modkit/cooldown + category = list("Mining Designs", "Cyborg Upgrade Modules") + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/range_mod + name = "Kinetic Accelerator Range Mod" + desc = "A device which allows kinetic accelerators to fire at a further range." + id = "rangemod" + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) + build_path = /obj/item/borg/upgrade/modkit/range + category = list("Mining Designs", "Cyborg Upgrade Modules") + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/hyperaccelerator + name = "Kinetic Accelerator Mining AoE Mod" + desc = "A modification kit for Kinetic Accelerators which causes it to fire AoE blasts that destroy rock." + id = "hypermod" + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 8000, MAT_GLASS = 1500, MAT_SILVER = 2000, MAT_GOLD = 2000, MAT_DIAMOND = 2000) + build_path = /obj/item/borg/upgrade/modkit/aoe/turfs + category = list("Mining Designs", "Cyborg Upgrade Modules") + departmental_flags = DEPARTMENTAL_FLAG_CARGO diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm new file mode 100644 index 0000000000..189c06dd36 --- /dev/null +++ b/code/modules/research/designs/misc_designs.dm @@ -0,0 +1,316 @@ + +///////////////////////////////////////// +/////////////////HUDs//////////////////// +///////////////////////////////////////// + +/datum/design/health_hud + name = "Health Scanner HUD" + desc = "A heads-up display that scans the humans in view and provides accurate data about their health status." + id = "health_hud" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/clothing/glasses/hud/health + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/health_hud_night + name = "Night Vision Health Scanner HUD" + desc = "An advanced medical head-up display that allows doctors to find patients in complete darkness." + id = "health_hud_night" + build_type = PROTOLATHE + materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_URANIUM = 1000, MAT_SILVER = 350) + build_path = /obj/item/clothing/glasses/hud/health/night + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/security_hud + name = "Security HUD" + desc = "A heads-up display that scans the humans in view and provides accurate data about their ID status." + id = "security_hud" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/clothing/glasses/hud/security + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/security_hud_night + name = "Night Vision Security HUD" + desc = "A heads-up display which provides id data and vision in complete darkness." + id = "security_hud_night" + build_type = PROTOLATHE + materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_URANIUM = 1000, MAT_GOLD = 350) + build_path = /obj/item/clothing/glasses/hud/security/night + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/diagnostic_hud + name = "Diagnostic HUD" + desc = "A HUD used to analyze and determine faults within robotic machinery." + id = "diagnostic_hud" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/clothing/glasses/hud/diagnostic + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/diagnostic_hud_night + name = "Night Vision Diagnostic HUD" + desc = "Upgraded version of the diagnostic HUD designed to function during a power failure." + id = "diagnostic_hud_night" + build_type = PROTOLATHE + materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_URANIUM = 1000, MAT_PLASMA = 300) + build_path = /obj/item/clothing/glasses/hud/diagnostic/night + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +///////////////////////////////////////// +//////////////////Misc/////////////////// +///////////////////////////////////////// + +/datum/design/welding_mask + name = "Welding Gas Mask" + desc = "A gas mask with built in welding goggles and face shield. Looks like a skull, clearly designed by a nerd." + id = "weldingmask" + build_type = PROTOLATHE + materials = list(MAT_METAL = 3000, MAT_GLASS = 1000) + build_path = /obj/item/clothing/mask/gas/welding + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/portaseeder + name = "Portable Seed Extractor" + desc = "For the enterprising botanist on the go. Less efficient than the stationary model, it creates one seed per plant." + id = "portaseeder" + build_type = PROTOLATHE + materials = list(MAT_METAL = 1000, MAT_GLASS = 400) + build_path = /obj/item/storage/bag/plants/portaseeder + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +/datum/design/air_horn + name = "Air Horn" + desc = "Damn son, where'd you find this?" + id = "air_horn" + build_type = PROTOLATHE + materials = list(MAT_METAL = 4000, MAT_BANANIUM = 1000) + build_path = /obj/item/bikehorn/airhorn + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ALL //HONK! + +/datum/design/mesons + name = "Optical Meson Scanners" + desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting condition." + id = "mesons" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/clothing/glasses/meson + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/engine_goggles + name = "Engineering Scanner Goggles" + desc = "Goggles used by engineers. The Meson Scanner mode lets you see basic structural and terrain layouts through walls, regardless of lighting condition. The T-ray Scanner mode lets you see underfloor objects such as cables and pipes." + id = "engine_goggles" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_PLASMA = 100) + build_path = /obj/item/clothing/glasses/meson/engine + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/tray_goggles + name = "Optical T-Ray Scanners" + desc = "Used by engineering staff to see underfloor objects such as cables and pipes." + id = "tray_goggles" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/clothing/glasses/meson/engine/tray + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/nvgmesons + name = "Night Vision Optical Meson Scanners" + desc = "Prototype meson scanners fitted with an extra sensor which amplifies the visible light spectrum and overlays it to the UHD display." + id = "nvgmesons" + build_type = PROTOLATHE + materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_PLASMA = 350, MAT_URANIUM = 1000) + build_path = /obj/item/clothing/glasses/meson/night + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_CARGO + +/datum/design/night_vision_goggles + name = "Night Vision Goggles" + desc = "Goggles that let you see through darkness unhindered." + id = "night_visision_goggles" + build_type = PROTOLATHE + materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_PLASMA = 350, MAT_URANIUM = 1000) + build_path = /obj/item/clothing/glasses/night + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_SECURITY + +/datum/design/magboots + name = "Magnetic Boots" + desc = "Magnetic boots, often used during extravehicular activity to ensure the user remains safely attached to the vehicle." + id = "magboots" + build_type = PROTOLATHE + materials = list(MAT_METAL = 4500, MAT_SILVER = 1500, MAT_GOLD = 2500) + build_path = /obj/item/clothing/shoes/magboots + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/sci_goggles + name = "Science Goggles" + desc = "Goggles fitted with a portable analyzer capable of determining the research worth of an item or components of a machine." + id = "scigoggles" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/clothing/glasses/science + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/handdrill + name = "Hand Drill" + desc = "A small electric hand drill with an interchangeable screwdriver and bolt bit" + id = "handdrill" + build_type = PROTOLATHE + materials = list(MAT_METAL = 3500, MAT_SILVER = 1500, MAT_TITANIUM = 2500) + build_path = /obj/item/screwdriver/power + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/jawsoflife + name = "Jaws of Life" + desc = "A small, compact Jaws of Life with an interchangeable pry jaws and cutting jaws" + id = "jawsoflife" // added one more requirment since the Jaws of Life are a bit OP + build_path = /obj/item/crowbar/power + build_type = PROTOLATHE + materials = list(MAT_METAL = 4500, MAT_SILVER = 2500, MAT_TITANIUM = 3500) + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/alienwrench + name = "Alien Wrench" + desc = "An advanced wrench obtained through Abductor technology." + id = "alien_wrench" + build_path = /obj/item/wrench/abductor + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/alienwirecutters + name = "Alien Wirecutters" + desc = "Advanced wirecutters obtained through Abductor technology." + id = "alien_wirecutters" + build_path = /obj/item/wirecutters/abductor + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/alienscrewdriver + name = "Alien Screwdriver" + desc = "An advanced screwdriver obtained through Abductor technology." + id = "alien_screwdriver" + build_path = /obj/item/screwdriver/abductor + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/aliencrowbar + name = "Alien Crowbar" + desc = "An advanced crowbar obtained through Abductor technology." + id = "alien_crowbar" + build_path = /obj/item/crowbar/abductor + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/alienwelder + name = "Alien Welding Tool" + desc = "An advanced welding tool obtained through Abductor technology." + id = "alien_welder" + build_path = /obj/item/weldingtool/abductor + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 5000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/alienmultitool + name = "Alien Multitool" + desc = "An advanced multitool obtained through Abductor technology." + id = "alien_multitool" + build_path = /obj/item/device/multitool/abductor + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 5000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/diskplantgene + name = "Plant Data Disk" + desc = "A disk for storing plant genetic data." + id = "diskplantgene" + build_type = PROTOLATHE + materials = list(MAT_METAL=200, MAT_GLASS=100) + build_path = /obj/item/disk/plantgene + category = list("Electronics") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +///////////////////////////////////////// +////////////Janitor Designs////////////// +///////////////////////////////////////// + +/datum/design/advmop + name = "Advanced Mop" + desc = "An upgraded mop with a large internal capacity for holding water or other cleaning chemicals." + id = "advmop" + build_type = PROTOLATHE + materials = list(MAT_METAL = 2500, MAT_GLASS = 200) + build_path = /obj/item/mop/advanced + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +/datum/design/blutrash + name = "Trashbag of Holding" + desc = "An advanced trash bag with bluespace properties; capable of holding a plethora of garbage." + id = "blutrash" + build_type = PROTOLATHE + materials = list(MAT_GOLD = 1500, MAT_URANIUM = 250, MAT_PLASMA = 1500) + build_path = /obj/item/storage/bag/trash/bluespace + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +/datum/design/buffer + name = "Floor Buffer Upgrade" + desc = "A floor buffer that can be attached to vehicular janicarts." + id = "buffer" + build_type = PROTOLATHE + materials = list(MAT_METAL = 3000, MAT_GLASS = 200) + build_path = /obj/item/janiupgrade + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +/datum/design/holosign + name = "Holographic Sign Projector" + desc = "A holograpic projector used to project various warning signs." + id = "holosign" + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_GLASS = 1000) + build_path = /obj/item/holosign_creator + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +///////////////////////////////////////// +////////////Tools////////////// +///////////////////////////////////////// + +/datum/design/exwelder + name = "Experimental Welding Tool" + desc = "An experimental welder capable of self-fuel generation." + id = "exwelder" + build_type = PROTOLATHE + materials = list(MAT_METAL = 1000, MAT_GLASS = 500, MAT_PLASMA = 1500, MAT_URANIUM = 200) + build_path = /obj/item/weldingtool/experimental + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING diff --git a/code/modules/research/designs/power_designs.dm b/code/modules/research/designs/power_designs.dm index d5526e9509..e8d9478174 100644 --- a/code/modules/research/designs/power_designs.dm +++ b/code/modules/research/designs/power_designs.dm @@ -4,98 +4,97 @@ /datum/design/basic_cell name = "Basic Power Cell" - desc = "A basic power cell that holds 1 kW of power." + desc = "A basic power cell that holds 1 MJ of energy." id = "basic_cell" - req_tech = list("powerstorage" = 1) build_type = PROTOLATHE | AUTOLATHE |MECHFAB materials = list(MAT_METAL = 700, MAT_GLASS = 50) construction_time=100 build_path = /obj/item/stock_parts/cell category = list("Misc","Power Designs","Machinery","initial") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/high_cell name = "High-Capacity Power Cell" - desc = "A power cell that holds 10 kW of power." + desc = "A power cell that holds 10 MJ of energy." id = "high_cell" - req_tech = list("powerstorage" = 2) build_type = PROTOLATHE | AUTOLATHE | MECHFAB materials = list(MAT_METAL = 700, MAT_GLASS = 60) construction_time=100 build_path = /obj/item/stock_parts/cell/high category = list("Misc","Power Designs") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/super_cell name = "Super-Capacity Power Cell" - desc = "A power cell that holds 20 kW of power." + desc = "A power cell that holds 20 MJ of energy." id = "super_cell" - req_tech = list("powerstorage" = 3, "materials" = 3) build_type = PROTOLATHE | MECHFAB materials = list(MAT_METAL = 700, MAT_GLASS = 70) construction_time=100 build_path = /obj/item/stock_parts/cell/super category = list("Misc","Power Designs") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/hyper_cell name = "Hyper-Capacity Power Cell" - desc = "A power cell that holds 30 kW of power." + desc = "A power cell that holds 30 MJ of energy." id = "hyper_cell" - req_tech = list("powerstorage" = 5, "materials" = 5, "engineering" = 5) build_type = PROTOLATHE | MECHFAB materials = list(MAT_METAL = 700, MAT_GOLD = 150, MAT_SILVER = 150, MAT_GLASS = 80) construction_time=100 build_path = /obj/item/stock_parts/cell/hyper category = list("Misc","Power Designs") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/bluespace_cell name = "Bluespace Power Cell" - desc = "A power cell that holds 40 kW of power." + desc = "A power cell that holds 40 MJ of energy." id = "bluespace_cell" - req_tech = list("powerstorage" = 6, "materials" = 5, "engineering" = 5, "bluespace" = 5) build_type = PROTOLATHE | MECHFAB materials = list(MAT_METAL = 800, MAT_GOLD = 120, MAT_GLASS = 160, MAT_DIAMOND = 160, MAT_TITANIUM = 300, MAT_BLUESPACE = 100) construction_time=100 build_path = /obj/item/stock_parts/cell/bluespace category = list("Misc","Power Designs") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/light_replacer name = "Light Replacer" desc = "A device to automatically replace lights. Refill with working lightbulbs." id = "light_replacer" - req_tech = list("magnets" = 3, "engineering" = 4) build_type = PROTOLATHE materials = list(MAT_METAL = 1500, MAT_SILVER = 150, MAT_GLASS = 3000) build_path = /obj/item/device/lightreplacer category = list("Power Designs") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE /datum/design/inducer name = "Inducer" desc = "The NT-75 Electromagnetic Power Inducer can wirelessly induce electric charge in an object, allowing you to recharge power cells without having to remove them." id = "inducer" - req_tech = list("powerstorage" = 4, "engineering" = 4, "magnets" = 4) build_type = PROTOLATHE materials = list(MAT_METAL = 3000, MAT_GLASS = 1000) build_path = /obj/item/inducer/sci category = list("Power Designs") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/board/pacman name = "Machine Design (PACMAN-type Generator Board)" desc = "The circuit board that for a PACMAN-type portable generator." id = "pacman" - req_tech = list("programming" = 2, "plasmatech" = 3, "powerstorage" = 3, "engineering" = 3) build_path = /obj/item/circuitboard/machine/pacman category = list("Engineering Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING /datum/design/board/pacman/super name = "Machine Design (SUPERPACMAN-type Generator Board)" desc = "The circuit board that for a SUPERPACMAN-type portable generator." id = "superpacman" - req_tech = list("programming" = 3, "powerstorage" = 4, "engineering" = 4) build_path = /obj/item/circuitboard/machine/pacman/super + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING /datum/design/board/pacman/mrs name = "Machine Design (MRSPACMAN-type Generator Board)" desc = "The circuit board that for a MRSPACMAN-type portable generator." id = "mrspacman" - req_tech = list("programming" = 3, "powerstorage" = 5, "engineering" = 5, "plasmatech" = 4) build_path = /obj/item/circuitboard/machine/pacman/mrs + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING diff --git a/code/modules/research/designs/smelting_designs.dm b/code/modules/research/designs/smelting_designs.dm index 7668f7b734..0a2fdbd83e 100644 --- a/code/modules/research/designs/smelting_designs.dm +++ b/code/modules/research/designs/smelting_designs.dm @@ -29,8 +29,8 @@ name = "Alien Alloy" desc = "A sheet of reverse-engineered alien alloy." id = "alienalloy" - req_tech = list("abductor" = 1, "materials" = 7, "plasmatech" = 2) build_type = PROTOLATHE | SMELTER materials = list(MAT_METAL = 4000, MAT_PLASMA = 4000) build_path = /obj/item/stack/sheet/mineral/abductor category = list("Stock Parts") + departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_SCIENCE diff --git a/code/modules/research/designs/stock_parts_designs.dm b/code/modules/research/designs/stock_parts_designs.dm index 799c400d08..257d63ce40 100644 --- a/code/modules/research/designs/stock_parts_designs.dm +++ b/code/modules/research/designs/stock_parts_designs.dm @@ -6,272 +6,271 @@ name = "Rapid Part Exchange Device" desc = "Special mechanical module made to store, sort, and apply standard machine parts." id = "rped" - req_tech = list("engineering" = 1) build_type = PROTOLATHE materials = list(MAT_METAL = 10000, MAT_GLASS = 5000) //hardcore build_path = /obj/item/storage/part_replacer category = list("Stock Parts") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/BS_RPED name = "Bluespace RPED" desc = "Powered by bluespace technology, this RPED variant can upgrade buildings from a distance, without needing to remove the panel first." id = "bs_rped" - req_tech = list("engineering" = 4, "bluespace" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 15000, MAT_GLASS = 5000, MAT_SILVER = 2500) //hardcore build_path = /obj/item/storage/part_replacer/bluespace category = list("Stock Parts") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE //Capacitors /datum/design/basic_capacitor name = "Basic Capacitor" desc = "A stock part used in the construction of various devices." id = "basic_capacitor" - req_tech = list("powerstorage" = 1) build_type = PROTOLATHE | AUTOLATHE materials = list(MAT_METAL = 100, MAT_GLASS = 100) build_path = /obj/item/stock_parts/capacitor category = list("Stock Parts","Machinery","initial") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/adv_capacitor name = "Advanced Capacitor" desc = "A stock part used in the construction of various devices." id = "adv_capacitor" - req_tech = list("powerstorage" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 150, MAT_GLASS = 150) build_path = /obj/item/stock_parts/capacitor/adv category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/super_capacitor name = "Super Capacitor" desc = "A stock part used in the construction of various devices." id = "super_capacitor" - req_tech = list("powerstorage" = 5, "engineering" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_GOLD = 100) build_path = /obj/item/stock_parts/capacitor/super category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/quadratic_capacitor name = "Quadratic Capacitor" desc = "A stock part used in the construction of various devices." id = "quadratic_capacitor" - req_tech = list("powerstorage" = 6, "engineering" = 5, "materials" = 5, "bluespace" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_GOLD = 100, MAT_DIAMOND = 100) build_path = /obj/item/stock_parts/capacitor/quadratic category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE //Scanning modules /datum/design/basic_scanning name = "Basic Scanning Module" desc = "A stock part used in the construction of various devices." id = "basic_scanning" - req_tech = list("magnets" = 1) build_type = PROTOLATHE | AUTOLATHE materials = list(MAT_METAL = 100, MAT_GLASS = 50) build_path = /obj/item/stock_parts/scanning_module category = list("Stock Parts","Machinery","initial") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/adv_scanning name = "Advanced Scanning Module" desc = "A stock part used in the construction of various devices." id = "adv_scanning" - req_tech = list("magnets" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 150, MAT_GLASS = 100) build_path = /obj/item/stock_parts/scanning_module/adv category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/phasic_scanning name = "Phasic Scanning Module" desc = "A stock part used in the construction of various devices." id = "phasic_scanning" - req_tech = list("magnets" = 5, "engineering" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 200, MAT_GLASS = 150, MAT_SILVER = 60) build_path = /obj/item/stock_parts/scanning_module/phasic category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/triphasic_scanning name = "Triphasic Scanning Module" desc = "A stock part used in the construction of various devices." id = "triphasic_scanning" - req_tech = list("magnets" = 6, "materials" = 5, "engineering" = 5, "bluespace" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_DIAMOND = 30, MAT_BLUESPACE = 30) build_path = /obj/item/stock_parts/scanning_module/triphasic category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE //Maipulators /datum/design/micro_mani name = "Micro Manipulator" desc = "A stock part used in the construction of various devices." id = "micro_mani" - req_tech = list("materials" = 1) build_type = PROTOLATHE | AUTOLATHE materials = list(MAT_METAL = 100) build_path = /obj/item/stock_parts/manipulator category = list("Stock Parts","Machinery","initial") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/nano_mani name = "Nano Manipulator" desc = "A stock part used in the construction of various devices." id = "nano_mani" - req_tech = list("materials" = 3, "programming" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 150) build_path = /obj/item/stock_parts/manipulator/nano category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/pico_mani name = "Pico Manipulator" desc = "A stock part used in the construction of various devices." id = "pico_mani" - req_tech = list("materials" = 5, "programming" = 4, "engineering" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 200) build_path = /obj/item/stock_parts/manipulator/pico category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/femto_mani name = "Femto Manipulator" desc = "A stock part used in the construction of various devices." id = "femto_mani" - req_tech = list("materials" = 7, "programming" = 5, "engineering" = 5, "bluespace" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 200, MAT_DIAMOND = 30, MAT_TITANIUM = 30) build_path = /obj/item/stock_parts/manipulator/femto category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE //Micro-lasers /datum/design/basic_micro_laser name = "Basic Micro-Laser" desc = "A stock part used in the construction of various devices." id = "basic_micro_laser" - req_tech = list("magnets" = 1) build_type = PROTOLATHE | AUTOLATHE materials = list(MAT_METAL = 100, MAT_GLASS = 50) build_path = /obj/item/stock_parts/micro_laser category = list("Stock Parts","Machinery","initial") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/high_micro_laser name = "High-Power Micro-Laser" desc = "A stock part used in the construction of various devices." id = "high_micro_laser" - req_tech = list("magnets" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 150, MAT_GLASS = 100) build_path = /obj/item/stock_parts/micro_laser/high category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/ultra_micro_laser name = "Ultra-High-Power Micro-Laser" desc = "A stock part used in the construction of various devices." id = "ultra_micro_laser" - req_tech = list("magnets" = 5, "engineering" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 200, MAT_GLASS = 150, MAT_URANIUM = 60) build_path = /obj/item/stock_parts/micro_laser/ultra category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/quadultra_micro_laser name = "Quad-Ultra Micro-Laser" desc = "A stock part used in the construction of various devices." id = "quadultra_micro_laser" - req_tech = list("magnets" = 6, "materials" = 5, "engineering" = 5, "bluespace" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_URANIUM = 100, MAT_DIAMOND = 60) build_path = /obj/item/stock_parts/micro_laser/quadultra category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/basic_matter_bin name = "Basic Matter Bin" desc = "A stock part used in the construction of various devices." id = "basic_matter_bin" - req_tech = list("materials" = 1) build_type = PROTOLATHE | AUTOLATHE materials = list(MAT_METAL = 100) build_path = /obj/item/stock_parts/matter_bin category = list("Stock Parts","Machinery","initial") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/adv_matter_bin name = "Advanced Matter Bin" desc = "A stock part used in the construction of various devices." id = "adv_matter_bin" - req_tech = list("materials" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 150) build_path = /obj/item/stock_parts/matter_bin/adv category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/super_matter_bin name = "Super Matter Bin" desc = "A stock part used in the construction of various devices." id = "super_matter_bin" - req_tech = list("materials" = 5, "engineering" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 200) build_path = /obj/item/stock_parts/matter_bin/super category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/bluespace_matter_bin name = "Bluespace Matter Bin" desc = "A stock part used in the construction of various devices." id = "bluespace_matter_bin" - req_tech = list("materials" = 7, "engineering" = 5, "bluespace" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 250, MAT_DIAMOND = 100, MAT_BLUESPACE = 100) build_path = /obj/item/stock_parts/matter_bin/bluespace category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE //T-Comms devices /datum/design/subspace_ansible name = "Subspace Ansible" desc = "A compact module capable of sensing extradimensional activity." id = "s-ansible" - req_tech = list("programming" = 2, "magnets" = 2, "materials" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 100, MAT_SILVER = 100) build_path = /obj/item/stock_parts/subspace/ansible category = list("Stock Parts") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/hyperwave_filter name = "Hyperwave Filter" desc = "A tiny device capable of filtering and converting super-intense radiowaves." id = "s-filter" - req_tech = list("programming" = 3, "magnets" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 100, MAT_SILVER = 100) build_path = /obj/item/stock_parts/subspace/filter category = list("Stock Parts") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/subspace_amplifier name = "Subspace Amplifier" desc = "A compact micro-machine capable of amplifying weak subspace transmissions." id = "s-amplifier" - req_tech = list("programming" = 3, "magnets" = 4, "materials" = 3, "bluespace" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 100, MAT_GOLD = 100, MAT_URANIUM = 100) build_path = /obj/item/stock_parts/subspace/amplifier @@ -281,38 +280,38 @@ name = "Subspace Treatment Disk" desc = "A compact micro-machine capable of stretching out hyper-compressed radio waves." id = "s-treatment" - req_tech = list("programming" = 2, "magnets" = 3, "materials" = 2, "bluespace" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 100, MAT_SILVER = 200) build_path = /obj/item/stock_parts/subspace/treatment category = list("Stock Parts") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/subspace_analyzer name = "Subspace Analyzer" desc = "A sophisticated analyzer capable of analyzing cryptic subspace wavelengths." id = "s-analyzer" - req_tech = list("programming" = 3, "magnets" = 4, "materials" = 2, "bluespace" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 100, MAT_GOLD = 100) build_path = /obj/item/stock_parts/subspace/analyzer category = list("Stock Parts") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/subspace_crystal name = "Ansible Crystal" desc = "A sophisticated analyzer capable of analyzing cryptic subspace wavelengths." id = "s-crystal" - req_tech = list("magnets" = 2, "materials" = 2, "bluespace" = 3, "plasmatech" = 3) build_type = PROTOLATHE materials = list(MAT_GLASS = 800, MAT_SILVER = 100, MAT_GOLD = 100) build_path = /obj/item/stock_parts/subspace/crystal category = list("Stock Parts") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/subspace_transmitter name = "Subspace Transmitter" desc = "A large piece of equipment used to open a window into the subspace dimension." id = "s-transmitter" - req_tech = list("magnets" = 3, "materials" = 4, "bluespace" = 4) build_type = PROTOLATHE materials = list(MAT_GLASS = 100, MAT_SILVER = 100, MAT_URANIUM = 100) build_path = /obj/item/stock_parts/subspace/transmitter category = list("Stock Parts") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE diff --git a/code/modules/research/designs/telecomms_designs.dm b/code/modules/research/designs/telecomms_designs.dm index 5822c5b808..09d02c3ccc 100644 --- a/code/modules/research/designs/telecomms_designs.dm +++ b/code/modules/research/designs/telecomms_designs.dm @@ -6,7 +6,6 @@ name = "Machine Design (Subspace Receiver)" desc = "Allows for the construction of Subspace Receiver equipment." id = "s-receiver" - req_tech = list("programming" = 2, "engineering" = 2, "bluespace" = 1) build_path = /obj/item/circuitboard/machine/telecomms/receiver category = list("Subspace Telecomms") @@ -14,7 +13,6 @@ name = "Machine Design (Bus Mainframe)" desc = "Allows for the construction of Telecommunications Bus Mainframes." id = "s-bus" - req_tech = list("programming" = 2, "engineering" = 2) build_path = /obj/item/circuitboard/machine/telecomms/bus category = list("Subspace Telecomms") @@ -22,7 +20,6 @@ name = "Machine Design (Hub Mainframe)" desc = "Allows for the construction of Telecommunications Hub Mainframes." id = "s-hub" - req_tech = list("programming" = 2, "engineering" = 2) build_path = /obj/item/circuitboard/machine/telecomms/hub category = list("Subspace Telecomms") @@ -30,7 +27,6 @@ name = "Machine Design (Relay Mainframe)" desc = "Allows for the construction of Telecommunications Relay Mainframes." id = "s-relay" - req_tech = list("programming" = 2, "engineering" = 2, "bluespace" = 2) build_path = /obj/item/circuitboard/machine/telecomms/relay category = list("Subspace Telecomms") @@ -38,7 +34,6 @@ name = "Machine Design (Processor Unit)" desc = "Allows for the construction of Telecommunications Processor equipment." id = "s-processor" - req_tech = list("programming" = 2, "engineering" = 2) build_path = /obj/item/circuitboard/machine/telecomms/processor category = list("Subspace Telecomms") @@ -46,7 +41,6 @@ name = "Machine Design (Server Mainframe)" desc = "Allows for the construction of Telecommunications Servers." id = "s-server" - req_tech = list("programming" = 2, "engineering" = 2) build_path = /obj/item/circuitboard/machine/telecomms/server category = list("Subspace Telecomms") @@ -54,6 +48,5 @@ name = "Machine Design (Subspace Broadcaster)" desc = "Allows for the construction of Subspace Broadcasting equipment." id = "s-broadcaster" - req_tech = list("programming" = 2, "engineering" = 2) build_path = /obj/item/circuitboard/machine/telecomms/broadcaster category = list("Subspace Telecomms") diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm index 5cd10ca50d..66fb69a8a3 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -6,163 +6,173 @@ name = "Test-Range Firing Pin" desc = "This safety firing pin allows firearms to be operated within proximity to a firing range." id = "pin_testing" - req_tech = list("combat" = 2, "materials" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 500, MAT_GLASS = 300) build_path = /obj/item/device/firing_pin/test_range category = list("Firing Pins") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/pin_mindshield name = "Mindshield Firing Pin" desc = "This is a security firing pin which only authorizes users who are mindshield-implanted." id = "pin_loyalty" - req_tech = list("combat" = 5, "materials" = 6) build_type = PROTOLATHE materials = list(MAT_SILVER = 600, MAT_DIAMOND = 600, MAT_URANIUM = 200) build_path = /obj/item/device/firing_pin/implant/mindshield category = list("Firing Pins") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/stunrevolver name = "Tesla Revolver" desc = "A high-tech revolver that fires internal, reusable shock cartridges in a revolving cylinder. The cartridges can be recharged using conventional rechargers." id = "stunrevolver" - req_tech = list("combat" = 4, "materials" = 4, "powerstorage" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 10000, MAT_GLASS = 10000, MAT_SILVER = 10000) build_path = /obj/item/gun/energy/tesla_revolver category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/nuclear_gun name = "Advanced Energy Gun" desc = "An energy gun with an experimental miniaturized reactor." id = "nuclear_gun" - req_tech = list("combat" = 5, "magnets" = 5, "powerstorage" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 10000, MAT_GLASS = 2000, MAT_URANIUM = 3000, MAT_TITANIUM = 1000) build_path = /obj/item/gun/energy/e_gun/nuclear category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/tele_shield name = "Telescopic Riot Shield" desc = "An advanced riot shield made of lightweight materials that collapses for easy storage." id = "tele_shield" - req_tech = list("combat" = 4, "materials" = 3, "engineering" = 4) build_type = PROTOLATHE materials = list(MAT_METAL = 4000, MAT_GLASS = 4000, MAT_SILVER = 300, MAT_TITANIUM = 200) build_path = /obj/item/shield/riot/tele category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/beamrifle name = "Beam Marksman Rifle" desc = "A powerful long ranged anti-material rifle that fires charged particle beams to obliterate targets." id = "beamrifle" - req_tech = list("combat" = 7, "magnets" = 5, "powerstorage" = 5, "materials" = 7, "programming" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 10000, MAT_GLASS = 5000, MAT_DIAMOND = 5000, MAT_URANIUM = 8000, MAT_SILVER = 4500, MAT_GOLD = 5000) build_path = /obj/item/gun/energy/beam_rifle category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/decloner name = "Decloner" desc = "Your opponent will bubble into a messy pile of goop." id = "decloner" - req_tech = list("combat" = 5, "materials" = 5, "biotech" = 6, "plasmatech" = 7) build_type = PROTOLATHE materials = list(MAT_GOLD = 5000,MAT_URANIUM = 10000) reagents_list = list("mutagen" = 40) build_path = /obj/item/gun/energy/decloner category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/rapidsyringe name = "Rapid Syringe Gun" desc = "A gun that fires many syringes." id = "rapidsyringe" - req_tech = list("combat" = 2, "biotech" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 5000, MAT_GLASS = 1000) build_path = /obj/item/gun/syringe/rapidsyringe category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL //uwu /datum/design/temp_gun name = "Temperature Gun" desc = "A gun that shoots temperature bullet energythings to change temperature."//Change it if you want id = "temp_gun" - req_tech = list("combat" = 4, "materials" = 4, "powerstorage" = 3, "magnets" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 5000, MAT_GLASS = 500, MAT_SILVER = 3000) build_path = /obj/item/gun/energy/temperature category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/flora_gun name = "Floral Somatoray" desc = "A tool that discharges controlled radiation which induces mutation in plant cells. Harmless to other organic life." id = "flora_gun" - req_tech = list("materials" = 2, "biotech" = 4) build_type = PROTOLATHE materials = list(MAT_METAL = 2000, MAT_GLASS = 500) reagents_list = list("radium" = 20) build_path = /obj/item/gun/energy/floragun category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE /datum/design/large_grenade name = "Large Grenade" desc = "A grenade that affects a larger area and use larger containers." id = "large_Grenade" - req_tech = list("combat" = 3, "engineering" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 3000) build_path = /obj/item/grenade/chem_grenade/large category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL /datum/design/pyro_grenade name = "Pyro Grenade" desc = "An advanced grenade that is able to self ignite its mixture." id = "pyro_Grenade" - req_tech = list("combat" = 4, "engineering" = 4) build_type = PROTOLATHE materials = list(MAT_METAL = 2000, MAT_PLASMA = 500) build_path = /obj/item/grenade/chem_grenade/pyro category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/cryo_grenade + name = "Cryo Grenade" + desc = "An advanced grenade that rapidly cools its contents upon detonation." + id = "cryo_Grenade" + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_SILVER = 500) + build_path = /obj/item/grenade/chem_grenade/cryo + category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL /datum/design/adv_grenade name = "Advanced Release Grenade" desc = "An advanced grenade that can be detonated several times, best used with a repeating igniter." id = "adv_Grenade" - req_tech = list("combat" = 3, "engineering" = 4) build_type = PROTOLATHE materials = list(MAT_METAL = 3000, MAT_GLASS = 500) build_path = /obj/item/grenade/chem_grenade/adv_release category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL /datum/design/xray name = "Xray Laser Gun" desc = "Not quite as menacing as it sounds" - id = "xray" - req_tech = list("combat" = 7, "magnets" = 5, "biotech" = 5, "powerstorage" = 4) + id = "xray_laser" build_type = PROTOLATHE materials = list(MAT_GOLD = 5000, MAT_URANIUM = 4000, MAT_METAL = 5000, MAT_TITANIUM = 2000, MAT_BLUESPACE = 2000) build_path = /obj/item/gun/energy/xray category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/ioncarbine name = "Ion Carbine" desc = "How to dismantle a cyborg : The gun." id = "ioncarbine" - req_tech = list("combat" = 5, "magnets" = 4) build_type = PROTOLATHE materials = list(MAT_SILVER = 6000, MAT_METAL = 8000, MAT_URANIUM = 2000) build_path = /obj/item/gun/energy/ionrifle/carbine category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/wormhole_projector name = "Bluespace Wormhole Projector" desc = "A projector that emits high density quantum-coupled bluespace beams." id = "wormholeprojector" - req_tech = list("combat" = 5, "engineering" = 5, "bluespace" = 7, "plasmatech" = 6) build_type = PROTOLATHE materials = list(MAT_SILVER = 2000, MAT_METAL = 5000, MAT_DIAMOND = 2000, MAT_BLUESPACE = 3000) build_path = /obj/item/gun/energy/wormhole_projector category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE //WT550 Mags @@ -170,11 +180,11 @@ name = "WT-550 Auto Gun Magazine (4.6x30mm)" desc = "A 20 round magazine for the out of date security WT-550 Auto Rifle" id = "mag_oldsmg" - req_tech = list("combat" = 1, "materials" = 1) build_type = PROTOLATHE materials = list(MAT_METAL = 4000) build_path = /obj/item/ammo_box/magazine/wt550m9 category = list("Ammo") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/mag_oldsmg/ap_mag name = "WT-550 Auto Gun Armour Piercing Magazine (4.6x30mm AP)" @@ -189,53 +199,54 @@ id = "mag_oldsmg_ic" materials = list(MAT_METAL = 6000, MAT_SILVER = 600, MAT_GLASS = 1000) build_path = /obj/item/ammo_box/magazine/wt550m9/wtic + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/stunshell name = "Stun Shell" desc = "A stunning shell for a shotgun." id = "stunshell" - req_tech = list("combat" = 3, "materials" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 200) build_path = /obj/item/ammo_casing/shotgun/stunslug category = list("Ammo") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/techshell name = "Unloaded Technological Shotshell" desc = "A high-tech shotgun shell which can be loaded with materials to produce unique effects." id = "techshotshell" - req_tech = list("combat" = 3, "materials" = 3, "powerstorage" = 4, "magnets" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 1000, MAT_GLASS = 200) build_path = /obj/item/ammo_casing/shotgun/techshell category = list("Ammo") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE /datum/design/suppressor name = "Universal Suppressor" desc = "A reverse-engineered universal suppressor that fits on most small arms with threaded barrels." id = "suppressor" - req_tech = list("combat" = 6, "engineering" = 5, "syndicate" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 2000, MAT_SILVER = 500) build_path = /obj/item/suppressor category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/gravitygun name = "One-point Bluespace-gravitational Manipulator" desc = "A multi-mode device that blasts one-point bluespace-gravitational bolts that locally distort gravity." id = "gravitygun" - req_tech = list("combat" = 4, "materials" = 5, "bluespace" = 4, "powerstorage" = 4, "magnets" = 5) build_type = PROTOLATHE materials = list(MAT_SILVER = 8000, MAT_URANIUM = 8000, MAT_GLASS = 12000, MAT_METAL = 12000, MAT_DIAMOND = 3000, MAT_BLUESPACE = 3000) build_path = /obj/item/gun/energy/gravity_gun category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/largecrossbow name = "Energy Crossbow" desc = "A reverse-engineered energy crossbow favored by syndicate infiltration teams and carp hunters." id = "largecrossbow" - req_tech = list("combat" = 5, "engineering" = 3, "magnets" = 5, "syndicate" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 5000, MAT_GLASS = 1500, MAT_URANIUM = 1500, MAT_SILVER = 1500) build_path = /obj/item/gun/energy/kinetic_accelerator/crossbow/large category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY diff --git a/code/modules/research/destructive_analyzer.dm b/code/modules/research/destructive_analyzer.dm index 790cba0889..e3caef247c 100644 --- a/code/modules/research/destructive_analyzer.dm +++ b/code/modules/research/destructive_analyzer.dm @@ -7,42 +7,35 @@ It is used to destroy hand-held objects and advance technological research. Cont Note: Must be placed within 3 tiles of the R&D Console */ -/obj/machinery/r_n_d/destructive_analyzer +/obj/machinery/rnd/destructive_analyzer name = "destructive analyzer" desc = "Learn science by destroying things!" icon_state = "d_analyzer" circuit = /obj/item/circuitboard/machine/destructive_analyzer var/decon_mod = 0 -/obj/machinery/r_n_d/destructive_analyzer/RefreshParts() +/obj/machinery/rnd/destructive_analyzer/RefreshParts() var/T = 0 for(var/obj/item/stock_parts/S in component_parts) T += S.rating decon_mod = T -/obj/machinery/r_n_d/destructive_analyzer/proc/ConvertReqString2List(list/source_list) +/obj/machinery/rnd/destructive_analyzer/proc/ConvertReqString2List(list/source_list) var/list/temp_list = params2list(source_list) for(var/O in temp_list) temp_list[O] = text2num(temp_list[O]) return temp_list -/obj/machinery/r_n_d/destructive_analyzer/disconnect_console() +/obj/machinery/rnd/destructive_analyzer/disconnect_console() linked_console.linked_destroy = null ..() -/obj/machinery/r_n_d/destructive_analyzer/Insert_Item(obj/item/O, mob/user) +/obj/machinery/rnd/destructive_analyzer/Insert_Item(obj/item/O, mob/user) if(user.a_intent != INTENT_HARM) . = 1 if(!is_insertion_ready(user)) return - if(!O.origin_tech) - to_chat(user, "This doesn't seem to have a tech origin!") - return - var/list/temp_tech = ConvertReqString2List(O.origin_tech) - if (temp_tech.len == 0) - to_chat(user, "You cannot deconstruct this item!") - return if(!user.transferItemToLoc(O, src)) to_chat(user, "\The [O] is stuck to your hand, you cannot put it in the [src.name]!") return @@ -52,9 +45,92 @@ Note: Must be placed within 3 tiles of the R&D Console flick("d_analyzer_la", src) addtimer(CALLBACK(src, .proc/finish_loading), 10) -/obj/machinery/r_n_d/destructive_analyzer/proc/finish_loading() +/obj/machinery/rnd/destructive_analyzer/proc/finish_loading() update_icon() - busy = FALSE + reset_busy() -/obj/machinery/r_n_d/destructive_analyzer/update_icon() - icon_state = "d_analyzer_l" +/obj/machinery/rnd/destructive_analyzer/update_icon() + if(loaded_item) + icon_state = "d_analyzer_l" + else + icon_state = initial(icon_state) + +/obj/machinery/rnd/destructive_analyzer/proc/reclaim_materials_from(obj/item/thing) + . = 0 + if(linked_console && linked_console.linked_lathe) //Also sends salvaged materials to a linked protolathe, if any. + for(var/material in thing.materials) + var/can_insert = min((linked_console.linked_lathe.materials.max_amount - linked_console.linked_lathe.materials.total_amount), (max(thing.materials[material]*(decon_mod/10), thing.materials[material]))) + linked_console.linked_lathe.materials.insert_amount(can_insert, material) + . += can_insert + +/obj/machinery/rnd/destructive_analyzer/proc/destroy_item(obj/item/thing, innermode = FALSE) + if(QDELETED(thing) || QDELETED(src) || QDELETED(linked_console)) + return FALSE + if(!innermode) + flick("d_analyzer_process", src) + busy = TRUE + addtimer(CALLBACK(src, .proc/reset_busy), 24) + use_power(250) + if(thing == loaded_item) + loaded_item = null + update_icon() + var/list/food = thing.GetDeconstructableContents() + for(var/obj/item/innerthing in food) + destroy_item(innerthing, TRUE) + reclaim_materials_from(thing) + for(var/mob/M in thing) + M.death() + if(istype(thing, /obj/item/stack/sheet)) + var/obj/item/stack/sheet/S = thing + if(S.amount > 1 && !innermode) + S.amount-- + else + qdel(S) + else + qdel(thing) + return TRUE + +/obj/machinery/rnd/destructive_analyzer/proc/user_try_decon_id(id, mob/user) + if(!istype(loaded_item) || !istype(linked_console)) + return FALSE + if(id && !(id == RESEARCH_MATERIAL_RECLAMATION_ID)) + var/datum/techweb_node/TN = get_techweb_node_by_id(id) + if(!istype(TN)) + return FALSE + var/list/pos1 = techweb_item_boost_check(loaded_item) + if(isnull(pos1[id])) + return FALSE + var/dpath = loaded_item.type + if(isnull(TN.boost_item_paths[dpath])) + return FALSE + var/dboost = TN.boost_item_paths[dpath] + var/choice = input("Are you sure you want to destroy [loaded_item.name] for a boost of [dboost? 0 : dboost] in node [TN.display_name]") in list("Proceed", "Cancel") + if(choice == "Cancel") + return FALSE + if(QDELETED(loaded_item) || QDELETED(linked_console) || !user.Adjacent(linked_console) || QDELETED(src)) + return FALSE + SSblackbox.record_feedback("nested_tally", "item_deconstructed", 1, list("[TN.id]", "[loaded_item.type]")) + if(destroy_item(loaded_item)) + linked_console.stored_research.boost_with_path(SSresearch.techweb_nodes[TN.id], dpath) + else + var/point_value = techweb_item_point_check(loaded_item) + if(linked_console.stored_research.deconstructed_items[loaded_item.type]) + point_value = 0 + var/choice = input("Are you sure you want to destroy [loaded_item.name] for [point_value? "[point_value] points" : "material reclaimation"]?") in list("Proceed", "Cancel") + if(choice == "Cancel") + return FALSE + if(QDELETED(loaded_item) || QDELETED(linked_console) || !user.Adjacent(linked_console) || QDELETED(src)) + return FALSE + var/loaded_type = loaded_item.type + if(destroy_item(loaded_item)) + linked_console.stored_research.research_points += point_value + linked_console.stored_research.deconstructed_items[loaded_type] = point_value + + return TRUE + +/obj/machinery/rnd/destructive_analyzer/proc/unload_item() + if(!loaded_item) + return FALSE + loaded_item.forceMove(get_turf(src)) + loaded_item = null + return TRUE diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index 57ca602774..bad8f1e5aa 100644 --- a/code/modules/research/experimentor.dm +++ b/code/modules/research/experimentor.dm @@ -17,7 +17,7 @@ #define EFFECT_PROB_VERYHIGH 95 #define FAIL 8 -/obj/machinery/r_n_d/experimentor +/obj/machinery/rnd/experimentor name = "\improper E.X.P.E.R.I-MENTOR" desc = "A \"replacement\" for the deconstructive analyzer with a slight tendency to catastrophically fail." icon = 'icons/obj/machines/heavy_lathe.dmi' @@ -37,13 +37,14 @@ var/list/valid_items = list() //valid items for special reactions like transforming var/list/critical_items = list() //items that can cause critical reactions -/obj/machinery/r_n_d/experimentor/proc/ConvertReqString2List(list/source_list) +/obj/machinery/rnd/experimentor/proc/ConvertReqString2List(list/source_list) var/list/temp_list = params2list(source_list) for(var/O in temp_list) temp_list[O] = text2num(temp_list[O]) return temp_list -/obj/machinery/r_n_d/experimentor/proc/SetTypeReactions() + +/obj/machinery/rnd/experimentor/proc/SetTypeReactions() var/probWeight = 0 for(var/I in typesof(/obj/item)) if(istype(I, /obj/item/relic)) @@ -69,14 +70,14 @@ critical_items += I -/obj/machinery/r_n_d/experimentor/Initialize() +/obj/machinery/rnd/experimentor/Initialize() . = ..() trackedIan = locate(/mob/living/simple_animal/pet/dog/corgi/Ian) in GLOB.mob_living_list trackedRuntime = locate(/mob/living/simple_animal/pet/cat/Runtime) in GLOB.mob_living_list SetTypeReactions() -/obj/machinery/r_n_d/experimentor/RefreshParts() +/obj/machinery/rnd/experimentor/RefreshParts() for(var/obj/item/stock_parts/manipulator/M in component_parts) if(resetTime > 0 && (resetTime - M.rating) >= 1) resetTime -= M.rating @@ -85,7 +86,7 @@ for(var/obj/item/stock_parts/micro_laser/M in component_parts) badThingCoeff += M.rating -/obj/machinery/r_n_d/experimentor/proc/checkCircumstances(obj/item/O) +/obj/machinery/rnd/experimentor/proc/checkCircumstances(obj/item/O) //snowflake check to only take "made" bombs if(istype(O, /obj/item/device/transfer_valve)) var/obj/item/device/transfer_valve/T = O @@ -93,65 +94,106 @@ return FALSE return TRUE -/obj/machinery/r_n_d/experimentor/Insert_Item(obj/item/O, mob/user) +/obj/machinery/rnd/experimentor/Insert_Item(obj/item/O, mob/user) if(user.a_intent != INTENT_HARM) . = 1 if(!is_insertion_ready(user)) return - if(!checkCircumstances(O)) - to_chat(user, "[O] is not yet valid for [src] and must be completed!") - return - if(!O.origin_tech) - to_chat(user, "This doesn't seem to have a tech origin!") - return - var/list/temp_tech = ConvertReqString2List(O.origin_tech) - if (temp_tech.len == 0) - to_chat(user, "You cannot experiment on this item!") - return if(!user.transferItemToLoc(O, src)) return loaded_item = O to_chat(user, "You add [O] to the machine.") flick("h_lathe_load", src) - - -/obj/machinery/r_n_d/experimentor/default_deconstruction_crowbar(obj/item/O) +/obj/machinery/rnd/experimentor/default_deconstruction_crowbar(obj/item/O) ejectItem() - ..(O) + . = ..(O) -/obj/machinery/r_n_d/experimentor/attack_hand(mob/user) +/obj/machinery/rnd/experimentor/attack_hand(mob/user) user.set_machine(src) - var/dat = "
    " + var/list/dat = list("
    ") if(!linked_console) - dat += "Scan for R&D Console
    " + dat += "Scan for R&D Console" if(loaded_item) - dat += "Loaded Item: [loaded_item]
    " - dat += "Technology:
    " - var/list/D = ConvertReqString2List(loaded_item.origin_tech) - for(var/T in D) - dat += "[T]
    " - dat += "

    Available tests:" - dat += "
    Poke" - dat += "
    Irradiate" - dat += "
    Gas" - dat += "
    Burn" - dat += "
    Freeze" - dat += "
    Destroy
    " - if(istype(loaded_item, /obj/item/relic)) - dat += "
    Discover
    " - dat += "
    Eject" + dat += "Loaded Item: [loaded_item]" + + dat += "
    Available tests:" + dat += "Poke" + dat += "Irradiate" + dat += "Gas" + dat += "Burn" + dat += "Freeze" + dat += "Destroy
    " + if(istype(loaded_item,/obj/item/relic)) + dat += "Discover" + dat += "Eject" + var/list/listin = techweb_item_boost_check(src) + if(listin) + var/list/output = list("Research Boost Data:") + var/list/res = list("Already researched:") + var/list/boosted = list("Already boosted:") + for(var/node_id in listin) + var/datum/techweb_node/N = get_techweb_node_by_id(node_id) + var/str = "[N.display_name]: [listin[N]] points." + if(SSresearch.science_tech.researched_nodes[N]) + res += str + else if(SSresearch.science_tech.boosted_nodes[N]) + boosted += str + if(SSresearch.science_tech.visible_nodes[N]) //JOY OF DISCOVERY! + output += str + output += boosted + res + dat += output else dat += "Nothing loaded." - dat += "
    Refresh
    " - dat += "
    Close
    " + dat += "Refresh" + dat += "Close
    " var/datum/browser/popup = new(user, "experimentor","Experimentor", 700, 400, src) - popup.set_content(dat) + popup.set_content(dat.Join("
    ")) popup.open() onclose(user, "experimentor") +/obj/machinery/rnd/experimentor/Topic(href, href_list) + if(..()) + return + usr.set_machine(src) -/obj/machinery/r_n_d/experimentor/proc/matchReaction(matching,reaction) + var/scantype = href_list["function"] + var/obj/item/process = locate(href_list["item"]) in src + + if(href_list["close"]) + usr << browse(null, "window=experimentor") + return + if(scantype == "search") + var/obj/machinery/computer/rdconsole/D = locate(/obj/machinery/computer/rdconsole) in oview(3,src) + if(D) + linked_console = D + else if(scantype == "eject") + ejectItem() + else if(scantype == "refresh") + updateUsrDialog() + else + if(recentlyExperimented) + to_chat(usr, "[src] has been used too recently!") + else if(!loaded_item) + to_chat(usr, "[src] is not currently loaded!") + else if(!process || process != loaded_item) //Interface exploit protection (such as hrefs or swapping items with interface set to old item) + to_chat(usr, "Interface failure detected in [src]. Please try again.") + else + var/dotype + if(text2num(scantype) == SCANTYPE_DISCOVER) + dotype = SCANTYPE_DISCOVER + else + dotype = matchReaction(process,scantype) + experiment(dotype,process) + use_power(750) + if(dotype != FAIL) + var/list/datum/techweb_node/nodes = techweb_item_boost_check(process) + var/picked = pickweight(nodes) //This should work. + if(linked_console) + linked_console.stored_research.boost_with_path(picked, process.type) + updateUsrDialog() + +/obj/machinery/rnd/experimentor/proc/matchReaction(matching,reaction) var/obj/item/D = matching if(D) if(item_reactions.Find("[D.type]")) @@ -165,7 +207,7 @@ else return FAIL -/obj/machinery/r_n_d/experimentor/proc/ejectItem(delete=FALSE) +/obj/machinery/rnd/experimentor/proc/ejectItem(delete=FALSE) if(loaded_item) if(cloneMode && cloneCount > 0) visible_message("A duplicate [loaded_item] pops out!") @@ -177,18 +219,18 @@ return var/turf/dropturf = get_turf(pick(view(1,src))) if(!dropturf) //Failsafe to prevent the object being lost in the void forever. - dropturf = get_turf(src) - loaded_item.loc = dropturf + dropturf = drop_location() + loaded_item.forceMove(dropturf) if(delete) qdel(loaded_item) loaded_item = null -/obj/machinery/r_n_d/experimentor/proc/throwSmoke(turf/where) +/obj/machinery/rnd/experimentor/proc/throwSmoke(turf/where) var/datum/effect_system/smoke_spread/smoke = new smoke.set_up(0, where) smoke.start() -/obj/machinery/r_n_d/experimentor/proc/pickWeighted(list/from) +/obj/machinery/rnd/experimentor/proc/pickWeighted(list/from) var/result = FALSE var/counter = 1 while(!result) @@ -201,7 +243,7 @@ else counter = 1 -/obj/machinery/r_n_d/experimentor/proc/experiment(exp,obj/item/exp_on) +/obj/machinery/rnd/experimentor/proc/experiment(exp,obj/item/exp_on) recentlyExperimented = 1 icon_state = "h_lathe_wloop" var/chosenchem @@ -468,7 +510,7 @@ throwSmoke(loc) if(trackedRuntime) throwSmoke(trackedRuntime.loc) - trackedRuntime.loc = loc + trackedRuntime.forceMove(drop_location()) investigate_log("Experimentor has stolen Runtime!", INVESTIGATE_EXPERIMENTOR) else new /mob/living/simple_animal/pet/cat(loc) @@ -481,62 +523,15 @@ addtimer(CALLBACK(src, .proc/reset_exp), resetTime) -/obj/machinery/r_n_d/experimentor/proc/reset_exp() +/obj/machinery/rnd/experimentor/proc/reset_exp() update_icon() recentlyExperimented = FALSE -/obj/machinery/r_n_d/experimentor/update_icon() +/obj/machinery/rnd/experimentor/update_icon() icon_state = "h_lathe" -/obj/machinery/r_n_d/experimentor/Topic(href, href_list) - if(..()) - return - usr.set_machine(src) - - var/scantype = href_list["function"] - var/obj/item/process = locate(href_list["item"]) in src - - if(href_list["close"]) - usr << browse(null, "window=experimentor") - return - else if(scantype == "search") - var/obj/machinery/computer/rdconsole/D = locate(/obj/machinery/computer/rdconsole) in oview(3,src) - if(D) - linked_console = D - else if(scantype == "eject") - ejectItem() - else if(scantype == "refresh") - updateUsrDialog() - else - if(recentlyExperimented) - to_chat(usr, "[src] has been used too recently!") - return - else if(!loaded_item) - updateUsrDialog() //Set the interface to unloaded mode - to_chat(usr, "[src] is not currently loaded!") - return - else if(!process || process != loaded_item) //Interface exploit protection (such as hrefs or swapping items with interface set to old item) - updateUsrDialog() //Refresh interface to update interface hrefs - to_chat(usr, "Interface failure detected in [src]. Please try again.") - return - var/dotype - if(text2num(scantype) == SCANTYPE_DISCOVER) - dotype = SCANTYPE_DISCOVER - else - dotype = matchReaction(process,scantype) - experiment(dotype,process) - use_power(750) - if(dotype != FAIL) - if(process && process.origin_tech) - var/list/temp_tech = ConvertReqString2List(process.origin_tech) - for(var/T in temp_tech) - linked_console.files.UpdateTech(T, temp_tech[T]) - updateUsrDialog() - return - -//~~~~~~~~Admin logging proc, aka the Powergamer Alarm~~~~~~~~ -/obj/machinery/r_n_d/experimentor/proc/warn_admins(mob/user, ReactionName) - var/turf/T = get_turf(src) +/obj/machinery/rnd/experimentor/proc/warn_admins(user, ReactionName) + var/turf/T = get_turf(user) message_admins("Experimentor reaction: [ReactionName] generated by [ADMIN_LOOKUPFLW(user)] at [ADMIN_COORDJMP(T)]",0,1) log_game("Experimentor reaction: [ReactionName] generated by [key_name(user)] in ([T.x],[T.y],[T.z])") @@ -563,7 +558,6 @@ name = "strange object" desc = "What mysteries could this hold?" icon = 'icons/obj/assemblies.dmi' - origin_tech = "combat=1;plasmatech=1;powerstorage=1;materials=1" var/realName = "defined object" var/revealed = FALSE var/realProc @@ -583,7 +577,6 @@ name = realName cooldownMax = rand(60,300) realProc = pick("teleport","explode","rapidDupe","petSpray","flash","clean","corgicannon") - origin_tech = pick("engineering=[rand(2,5)]","magnets=[rand(2,5)]","plasmatech=[rand(2,5)]","programming=[rand(2,5)]","powerstorage=[rand(2,5)]") /obj/item/relic/attack_self(mob/user) if(revealed) diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm index 9df4946ed2..cbd0fa9f27 100644 --- a/code/modules/research/protolathe.dm +++ b/code/modules/research/protolathe.dm @@ -7,15 +7,16 @@ it creates. All the menus and other manipulation commands are in the R&D console Note: Must be placed west/left of and R&D console to function. */ -/obj/machinery/r_n_d/protolathe +/obj/machinery/rnd/protolathe name = "protolathe" desc = "Converts raw materials into useful objects." icon_state = "protolathe" - container_type = OPENCONTAINER_1 + container_type = OPENCONTAINER circuit = /obj/item/circuitboard/machine/protolathe var/efficiency_coeff - + var/console_link = TRUE //allow console link. + var/requires_console = TRUE var/list/categories = list( "Power Designs", "Medical Designs", @@ -30,16 +31,17 @@ Note: Must be placed west/left of and R&D console to function. "Computer Parts" ) + var/datum/component/material_container/materials -/obj/machinery/r_n_d/protolathe/Initialize() +/obj/machinery/rnd/protolathe/Initialize() create_reagents(0) - var/datum/component/material_container/materials = AddComponent(/datum/component/material_container, - list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE), - FALSE, list(/obj/item/stack, /obj/item/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready)) + materials = AddComponent(/datum/component/material_container, + list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE), 0, + FALSE, list(/obj/item/stack, /obj/item/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready), CALLBACK(src, .proc/AfterMaterialInsert)) materials.precise_insertion = TRUE return ..() -/obj/machinery/r_n_d/protolathe/RefreshParts() +/obj/machinery/rnd/protolathe/RefreshParts() reagents.maximum_volume = 0 for(var/obj/item/reagent_containers/glass/G in component_parts) reagents.maximum_volume += G.volume @@ -55,7 +57,7 @@ Note: Must be placed west/left of and R&D console to function. T -= M.rating/10 efficiency_coeff = min(max(0, T), 1) -/obj/machinery/r_n_d/protolathe/proc/check_mat(datum/design/being_built, M) // now returns how many times the item can be built with the material +/obj/machinery/rnd/protolathe/proc/check_mat(datum/design/being_built, M) // now returns how many times the item can be built with the material var/list/all_materials = being_built.reagents_list + being_built.materials GET_COMPONENT(materials, /datum/component/material_container) @@ -66,32 +68,69 @@ Note: Must be placed west/left of and R&D console to function. return round(A / max(1, (all_materials[M]*efficiency_coeff))) //we eject the materials upon deconstruction. -/obj/machinery/r_n_d/protolathe/on_deconstruction() +/obj/machinery/rnd/protolathe/on_deconstruction() for(var/obj/item/reagent_containers/glass/G in component_parts) reagents.trans_to(G, G.reagents.maximum_volume) GET_COMPONENT(materials, /datum/component/material_container) materials.retrieve_all() ..() - -/obj/machinery/r_n_d/protolathe/disconnect_console() +/obj/machinery/rnd/protolathe/disconnect_console() linked_console.linked_lathe = null ..() -/obj/machinery/r_n_d/protolathe/ComponentActivated(datum/component/C) - ..() - if(istype(C, /datum/component/material_container)) - 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" - use_power(MINERAL_MATERIAL_AMOUNT / 10) - else - var/obj/item/stack/S = lit - stack_name = initial(S.name) - use_power(max(1000, (MINERAL_MATERIAL_AMOUNT * M.last_amount_inserted / 10))) - add_overlay("protolathe_[stack_name]") - addtimer(CALLBACK(src, /atom/proc/cut_overlay, "protolathe_[stack_name]"), 10) +/obj/machinery/rnd/protolathe/proc/user_try_print_id(id, amount) + if((!istype(linked_console) && requires_console) || !id) + return FALSE + if(istext(amount)) + amount = text2num(amount) + if(isnull(amount)) + amount = 1 + var/datum/design/D = (linked_console || requires_console)? linked_console.stored_research.researched_designs[id] : get_techweb_design_by_id(id) + if(!istype(D)) + return FALSE + if(D.make_reagents.len) + return FALSE + + var/power = 1000 + amount = CLAMP(amount, 1, 10) + for(var/M in D.materials) + power += round(D.materials[M] * amount / 5) + power = max(3000, power) + use_power(power) + + var/list/efficient_mats = list() + for(var/MAT in D.materials) + efficient_mats[MAT] = D.materials[MAT]*efficiency_coeff + + if(!materials.has_materials(efficient_mats, amount)) + say("Not enough materials to complete prototype[amount > 1? "s" : ""].") + return FALSE + for(var/R in D.reagents_list) + if(!reagents.has_reagent(R, D.reagents_list[R]*efficiency_coeff)) + say("Not enough reagents to complete prototype[amount > 1? "s" : ""].") + return FALSE + + materials.use_amount(efficient_mats, amount) + for(var/R in D.reagents_list) + reagents.remove_reagent(R, D.reagents_list[R]*efficiency_coeff) + + busy = TRUE + flick("protolathe_n", src) + var/timecoeff = efficiency_coeff * D.lathe_time_factor + + addtimer(CALLBACK(src, .proc/reset_busy), (32 * timecoeff * amount) ** 0.8) + addtimer(CALLBACK(src, .proc/do_print, D.build_path, amount, efficient_mats, D.dangerous_construction), (32 * timecoeff * amount) ** 0.8) + return TRUE + +/obj/machinery/rnd/protolathe/proc/do_print(path, amount, list/matlist, notify_admins) + if(notify_admins) + if(usr) + usr.investigate_log("built [amount] of [path] at a protolathe.", INVESTIGATE_RESEARCH) + var/turf/T = get_turf(usr) + message_admins("[key_name(usr)][ADMIN_JMP(T)] has built [amount] of [path] at a protolathe at [COORD(usr)]") + for(var/i in 1 to amount) + var/obj/item/I = new path(get_turf(src)) + if(!istype(I, /obj/item/stack/sheet) && !istype(I, /obj/item/ore/bluespace_crystal)) + I.materials = matlist.Copy() + SSblackbox.record_feedback("nested_tally", "item_printed", amount, list("[type]", "[path]")) \ No newline at end of file diff --git a/code/modules/research/rd-readme.dm b/code/modules/research/rd-readme.dm deleted file mode 100644 index 9dc47247c3..0000000000 --- a/code/modules/research/rd-readme.dm +++ /dev/null @@ -1,239 +0,0 @@ -/* -Research and Development System. (Designed specifically for the /tg/station 13 (Space Station 13) open source project) - -///////////////Overview/////////////////// -This system is a "tech tree" research and development system designed for SS13. It allows a "researcher" job (this document assumes -the "scientist" job is given this role) the tools necessiary to research new and better technologies. In general, the system works -by breaking existing technology and using what you learn from to advance your knowledge of SCIENCE! As your knowledge progresses, -you can build newer (and better?) devices (which you can also, eventually, deconstruct to advance your knowledge). - -A brief overview is below. For more details, see the related files. - -////////////Game Use///////////// -The major research and development is performed using a combination of four machines: -- R&D Console: A computer console that allows you to manipulate the other devices that are linked to it and view/manipulate the -technologies you have researched so far. -- Protolathe: Used to make new hand-held devices and parts for larger devices. All metals and reagents as raw materials. -- Destructive Analyzer: You can put hand-held objects into it and it'll analyze them for technological advancements but it destroys -them in the process. Destroyed items will send their raw materials to a linked Protolathe (if any) -- Circuit Imprinter: Similar to the Protolathe, it allows for the construction of circuit boards. Uses glass and acid as the raw -materials. - -While researching you are dealing with two different types of information: Technology Paths and Device Designs. Technology Paths -are the "Tech Trees" of the game. You start out with a number of them at the game start and they are improved by using the -Destructive Analyzer. By themselves, they don't do a whole lot. However, they unlock Device Designs. This is the information used -by the circuit imprinter and the protolathe to produce objects. - -//EXISTING TECH -Each tech path should have at LEAST one item at every level (levels 1 - 20). This is to allow for a more fluid progression of the -researching. Existing tech (ie, anything you can find on the station or get from the quartermaster) shouldn't go higher then -level 5 or 7. Everything past that should be stuff you research. - -Below is a checklist to make sure every tree is filled. As new items get added to R&D, add them here if there is an empty slot. -When thinking about new stuff, check here to see if there are any slots unfilled. - -//MATERIALS -1 | Metal -2 | Solid Plasma -3 | Silver -4 | Gold, Super Capacitor -5 | Uranium, Nuclear Gun, SUPERPACMAN -6 | Diamond, MRSPACMAN -7 | -8 | -9 | -10 | -11 | -12 | -13 | -14 | -15 | -16 | -17 | -18 | -19 | -20 | - -//PLASMA TECH -1 | -2 | Solid Plasma -3 | Pacman Generator -4 | -5 | -6 | -7 | -8 | -9 | -10 | -11 | -12 | -13 | -14 | -15 | -16 | -17 | -18 | -19 | -20 | - -//POWER TECH -1 | Basic Capacitor, Basic Cell -2 | High-Capacity Cell (10,000) -3 | Super-Capacity Cell (20,000), Powersink, PACMAN -4 | SUPERPACMAN -5 | MRSPACMAN, Super Capacitor -6 | Hyper-Capacity Cell (30,000) -7 | -8 | -9 | -10 | -11 | -12 | -13 | -14 | -15 | -16 | -17 | -18 | -19 | -20 | - -//BLUE SPACE -1 | -2 | Teleporter Console Board -3 | Teleport Gun, Hand Tele -4 | Teleportation Scroll -5 | -6 | -7 | -8 | -9 | -10 | -11 | -12 | -13 | -14 | -15 | -16 | -17 | -18 | -19 | -20 | - -//BIOTECH -1 | Bruise Pack, Scalple -2 | PANDEMIC Board, Mass Spectrometer -3 | AI Core, Brains (MMI) -4 | MMI+Radio -5 | -6 | -7 | -8 | -9 | -10 | -11 | -12 | -13 | -14 | -15 | -16 | -17 | -18 | -19 | -20 | - -//MAGNETS -1 | Basic Sensor -2 | Comm Console Board -3 | Adv Sensor -4 | Adv Mass Spectrometer, Chameleon Projector -5 | Phasic Sensor -6 | -7 | -8 | -9 | -10 | -11 | -12 | -13 | -14 | -15 | -16 | -17 | -18 | -19 | -20 | - -//PROGRAMMING -1 | Arcade Board -2 | Sec Camera -3 | Cloning Machine Console Board -4 | AI Core, Intellicard -5 | Pico-Manipulator, Ultra-Micro-Laser -6 | -7 | -8 | -9 | -10 | -11 | -12 | -13 | -14 | -15 | -16 | -17 | -18 | -19 | -20 | - -//SYNDICATE -1 | Sleepypen -2 | TYRANT Module, Emag -3 | Power Sink -4 | -5 | -6 | -7 | -8 | -9 | -10 | -11 | -12 | -13 | -14 | -15 | -16 | -17 | -18 | -19 | -20 | - -//COMBAT -1 | Flashbang, Mousetrap, Nettle -2 | Stun Baton -3 | Power Axe, Death Nettle, Nuclear Gun -4 | -5 | -6 | -7 | -8 | -9 | -10 | -11 | -12 | -13 | -14 | -15 | -16 | -17 | -18 | -19 | -20 | - - - - - - - -*/ \ No newline at end of file diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index b98a75e6fd..0c468b184a 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -1,8 +1,9 @@ + /* Research and Development (R&D) Console This is the main work horse of the R&D system. It contains the menus/controls for the Destructive Analyzer, Protolathe, and Circuit -imprinter. It also contains the /datum/research holder with all the known/possible technology paths and device designs. +imprinter. Basic use: When it first is created, it will attempt to link up to related devices within 3 squares. It'll only link up if they aren't already linked to another console. Any consoles it cannot link up with (either because all of a certain type are already @@ -14,50 +15,41 @@ on a menu, nothing is to stop the person from using the options on that menu (al one). You can also lock the console on the settings menu if you're feeling paranoid and you don't want anyone messing with it who doesn't have toxins access. -When a R&D console is destroyed or even partially disassembled, you lose all research data on it. However, there are two ways around -this dire fate: -- The easiest way is to go to the settings menu and select "Sync Database with Network." That causes it to upload (but not download) -it's data to every other device in the game. Each console has a "disconnect from network" option that'll will cause data base sync -operations to skip that console. This is useful if you want to make a "public" R&D console or, for example, give the engineers -a circuit imprinter with certain designs on it and don't want it accidentally updating. The downside of this method is that you have -to have physical access to the other console to send data back. Note: An R&D console is on CentCom so if a random griffan happens to -cause a ton of data to be lost, an admin can go send it back. -- The second method is with Technology Disks and Design Disks. Each of these disks can hold technology or design datums in -their entirety. You can then take the disk to any R&D console and upload it's data to it. This method is a lot more secure (since it -won't update every console in existence) but it's more of a hassle to do. Also, the disks can be stolen. - - */ /obj/machinery/computer/rdconsole name = "R&D Console" + desc = "A console used to interface with R&D tools." icon_screen = "rdcomp" icon_keyboard = "rd_key" + var/datum/techweb/stored_research //Reference to global science techweb. + var/obj/item/disk/tech_disk/t_disk //Stores the technology disk. + var/obj/item/disk/design_disk/d_disk //Stores the design disk. circuit = /obj/item/circuitboard/computer/rdconsole - var/datum/research/files //Stores all the collected research data. - var/obj/item/disk/tech_disk/t_disk = null //Stores the technology disk. - var/obj/item/disk/design_disk/d_disk = null //Stores the design disk. - var/obj/machinery/r_n_d/destructive_analyzer/linked_destroy = null //Linked Destructive Analyzer - var/obj/machinery/r_n_d/protolathe/linked_lathe = null //Linked Protolathe - var/obj/machinery/r_n_d/circuit_imprinter/linked_imprinter = null //Linked Circuit Imprinter + var/obj/machinery/rnd/destructive_analyzer/linked_destroy //Linked Destructive Analyzer + var/obj/machinery/rnd/protolathe/linked_lathe //Linked Protolathe + var/obj/machinery/rnd/circuit_imprinter/linked_imprinter //Linked Circuit Imprinter - var/screen = 1.0 //Which screen is currently showing. - var/id = 0 //ID of the computer (for server restrictions). - var/sync = 1 //If sync = 0, it doesn't show up on Server Control Console - var/first_use = 1 //If first_use = 1, it will try to auto-connect with nearby devices - - req_access = list(ACCESS_TOX) //DATA AND SETTING MANIPULATION REQUIRES SCIENTIST ACCESS. + req_access = list(ACCESS_TOX) //lA AND SETTING MANIPULATION REQUIRES SCIENTIST ACCESS. + //UI VARS + var/screen = RDSCREEN_MENU + var/back = RDSCREEN_MENU + var/locked = FALSE + var/tdisk_uple = FALSE + var/ddisk_uple = FALSE + var/datum/techweb_node/selected_node + var/datum/design/selected_design var/selected_category - var/list/datum/design/matching_designs = list() //for the search function - var/disk_slot_selected = 0 + var/list/datum/design/matching_designs + var/disk_slot_selected + var/searchstring = "" + var/searchtype = "" + var/research_control = TRUE -/proc/CallTechName(ID) //A simple helper proc to find the name of a tech with a given ID. - if(GLOB.tech_list[ID]) - var/datum/tech/tech = GLOB.tech_list[ID] - return tech.name - return "ERROR: Report This" +/obj/machinery/computer/rdconsole/production + research_control = FALSE /proc/CallMaterialName(ID) if (copytext(ID, 1, 2) == "$" && GLOB.materials_list[ID]) @@ -70,69 +62,120 @@ won't update every console in existence) but it's more of a hassle to do. Also, return "ERROR: Report This" /obj/machinery/computer/rdconsole/proc/SyncRDevices() //Makes sure it is properly sync'ed up with the devices attached to it (if any). - for(var/obj/machinery/r_n_d/D in oview(3,src)) + for(var/obj/machinery/rnd/D in oview(3,src)) if(D.linked_console != null || D.disabled || D.panel_open) continue - if(istype(D, /obj/machinery/r_n_d/destructive_analyzer)) + if(istype(D, /obj/machinery/rnd/destructive_analyzer)) if(linked_destroy == null) linked_destroy = D D.linked_console = src - else if(istype(D, /obj/machinery/r_n_d/protolathe)) + else if(istype(D, /obj/machinery/rnd/protolathe)) if(linked_lathe == null) + var/obj/machinery/rnd/protolathe/P = D + if(!P.console_link) + continue linked_lathe = D D.linked_console = src - else if(istype(D, /obj/machinery/r_n_d/circuit_imprinter)) + else if(istype(D, /obj/machinery/rnd/circuit_imprinter)) if(linked_imprinter == null) + var/obj/machinery/rnd/circuit_imprinter/C = D + if(!C.console_link) + continue linked_imprinter = D D.linked_console = src - first_use = 0 - -//Have it automatically push research to the centcom server so wild griffins can't fuck up R&D's work --NEO -/obj/machinery/computer/rdconsole/proc/griefProtection() - for(var/obj/machinery/r_n_d/server/centcom/C in GLOB.machines) - for(var/v in files.known_tech) - var/datum/tech/T = files.known_tech[v] - C.files.AddTech2Known(T) - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] - C.files.AddDesign2Known(D) - C.files.RefreshResearch() - /obj/machinery/computer/rdconsole/Initialize() . = ..() - files = new /datum/research(src) //Setup the research data holder. + stored_research = SSresearch.science_tech + stored_research.consoles_accessing[src] = TRUE matching_designs = list() - if(!id) - fix_noid_research_servers() + SyncRDevices() -/* Instead of calling this every tick, it is only being called when needed -/obj/machinery/computer/rdconsole/process() - griefProtection() -*/ +/obj/machinery/computer/rdconsole/Destroy() + if(stored_research) + stored_research.consoles_accessing -= src + if(linked_destroy) + linked_destroy.linked_console = null + linked_destroy = null + if(linked_lathe) + linked_lathe.linked_console = null + linked_lathe = null + if(linked_imprinter) + linked_imprinter.linked_console = null + linked_imprinter = null + if(t_disk) + t_disk.forceMove(get_turf(src)) + t_disk = null + if(d_disk) + d_disk.forceMove(get_turf(src)) + d_disk = null + matching_designs = null + selected_node = null + selected_design = null + return ..() /obj/machinery/computer/rdconsole/attackby(obj/item/D, mob/user, params) - //Loading a disk into it. if(istype(D, /obj/item/disk)) - if(t_disk || d_disk) - to_chat(user, "A disk is already loaded into the machine.") - return - if(istype(D, /obj/item/disk/tech_disk)) + if(t_disk) + to_chat(user, "A technology disk is already loaded!") + return + if(!user.transferItemToLoc(D, src)) + to_chat(user, "[D] is stuck to your hand!") + return t_disk = D else if (istype(D, /obj/item/disk/design_disk)) + if(d_disk) + to_chat(user, "A design disk is already loaded!") + return + if(!user.transferItemToLoc(D, src)) + to_chat(user, "[D] is stuck to your hand!") + return d_disk = D else to_chat(user, "Machine cannot accept disks in that format.") return - if(!user.transferItemToLoc(D, src)) - return - to_chat(user, "You add the disk to the machine!") + to_chat(user, "You insert [D] into \the [src]!") else if(!(linked_destroy && linked_destroy.busy) && !(linked_lathe && linked_lathe.busy) && !(linked_imprinter && linked_imprinter.busy)) . = ..() - updateUsrDialog() +/obj/machinery/computer/rdconsole/proc/research_node(id, mob/user) + if(!stored_research.available_nodes[id] || stored_research.researched_nodes[id]) + say("Node unlock failed: Either already researched or not available!") + return FALSE + var/datum/techweb_node/TN = SSresearch.techweb_nodes[id] + if(!istype(TN)) + say("Node unlock failed: Unknown error.") + return FALSE + var/price = TN.get_price(stored_research) + if(stored_research.research_points >= price) + investigate_log("[key_name(user)] researched [id]([price]) on techweb id [stored_research.id].", INVESTIGATE_RESEARCH) + if(stored_research == SSresearch.science_tech) + SSblackbox.record_feedback("associative", "science_techweb_unlock", 1, list("id" = "[id]", "price" = "[price]", "time" = "[SQLtime()]")) + if(stored_research.research_node(SSresearch.techweb_nodes[id])) + say("Sucessfully researched [TN.display_name].") + var/logname = "Unknown" + if(isAI(user)) + logname = "AI: [user.name]" + if(iscarbon(user)) + var/obj/item/card/id/idcard = user.get_active_held_item() + if(istype(idcard)) + logname = "User: [idcard.registered_name]" + if(ishuman(user)) + var/mob/living/carbon/human/H = user + var/obj/item/I = H.wear_id + if(istype(I)) + var/obj/item/card/id/ID = I.GetID() + if(istype(ID)) + logname = "User: [ID.registered_name]" + stored_research.research_logs += "[logname] researched node id [id] for [price] points." + return TRUE + else + say("Failed to research node: Internal database error!") + return FALSE + say("Not enough research points...") + return FALSE /obj/machinery/computer/rdconsole/on_deconstruction() if(linked_destroy) @@ -146,423 +189,567 @@ won't update every console in existence) but it's more of a hassle to do. Also, linked_imprinter = null ..() - /obj/machinery/computer/rdconsole/emag_act(mob/user) - if(emagged) - return - playsound(src, "sparks", 75, 1) - emagged = TRUE - to_chat(user, "You disable the security protocols") + if(!emagged) + to_chat(user, "You disable the security protocols") + playsound(src, "sparks", 75, 1) + emagged = TRUE + return ..() -/obj/machinery/computer/rdconsole/Topic(href, href_list) +/obj/machinery/computer/rdconsole/proc/list_categories(list/categories, menu_num as num) + if(!categories) + return + + var/line_length = 1 + var/list/l = "" + + for(var/C in categories) + if(line_length > 2) + l += "" + line_length = 1 + + l += "" + line_length++ + + l += "
    [C]
    " + return l + +/obj/machinery/computer/rdconsole/proc/ui_header() + var/list/l = list() + l += "

    Nanotrasen Research and Development

    [RDSCREEN_NOBREAK]" + l += "
    Connected Technology database: [stored_research == SSresearch.science_tech? "Nanotrasen" : "Third Party"]" + l += "Available Points: [stored_research.research_points]" + l += "Security protocols: [emagged? "Disabled" : "Enabled"]" + l += "Design Disk: [d_disk? "Loaded" : "Not Loaded"] | \ + Technology Disk: [t_disk? "Loaded" : "Not Loaded"]" + l += "Main Menu | Back
    [RDSCREEN_NOBREAK]" + return l + +/obj/machinery/computer/rdconsole/proc/ui_main_menu() + var/list/l = list() + if(research_control) + l += "

    Technology" + if(d_disk) + l += "
    Design Disk" + if(t_disk) + l += "
    Tech Disk" + if(linked_destroy) + l += "
    Deconstructive Analyzer" + if(linked_lathe) + l += "
    Protolathe" + if(linked_imprinter) + l += "
    Circuit Imprinter" + l += "
    Settings

    " + return l + +/obj/machinery/computer/rdconsole/proc/ui_locked() + return list("

    SYSTEM LOCKED


    ") + +/obj/machinery/computer/rdconsole/proc/ui_settings() + var/list/l = list() + l += "

    R&D Console Settings:

    " + l += "Device Linkage Menu" + l += "Lock Console
    " + return l + +/obj/machinery/computer/rdconsole/proc/ui_device_linking() + var/list/l = list() + l += "Settings Menu
    " + l += "

    R&D Console Device Linkage Menu:

    " + l += "Re-sync with Nearby Devices" + l += "

    Linked Devices:

    " + l += linked_destroy? "* Destructive Analyzer Disconnect" : "* No Destructive Analyzer Linked" + l += linked_lathe? "* Protolathe Disconnect" : "* No Protolathe Linked" + l += linked_imprinter? "* Circuit Imprinter Disconnect" : "* No Circuit Imprinter Linked" + l += "
    " + return l + +/obj/machinery/computer/rdconsole/proc/ui_protolathe_header() + var/list/l = list() + l += "" + return l + +/obj/machinery/computer/rdconsole/proc/ui_protolathe_category_view() //Legacy code + RDSCREEN_UI_LATHE_CHECK + var/list/l = list() + l += ui_protolathe_header() + l += "

    Browsing [selected_category]:

    " + var/coeff = linked_lathe.efficiency_coeff + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] + if(!(selected_category in D.category)|| !(D.build_type & PROTOLATHE)) + continue + if(!(D.departmental_flags & linked_lathe.allowed_department_flags)) + continue + var/temp_material + var/c = 50 + var/t + + var/all_materials = D.materials + D.reagents_list + for(var/M in all_materials) + t = linked_lathe.check_mat(D, M) + temp_material += " | " + if (t < 1) + temp_material += "[all_materials[M]*coeff] [CallMaterialName(M)]" + else + temp_material += " [all_materials[M]*coeff] [CallMaterialName(M)]" + c = min(c,t) + + if (c >= 1) + l += "[D.name][RDSCREEN_NOBREAK]" + if(c >= 5) + l += "x5[RDSCREEN_NOBREAK]" + if(c >= 10) + l += "x10[RDSCREEN_NOBREAK]" + l += "[temp_material][RDSCREEN_NOBREAK]" + else + l += "[D.name][temp_material][RDSCREEN_NOBREAK]" + l += "" + l += "
    " + return l + +/obj/machinery/computer/rdconsole/proc/ui_protolathe() //Legacy code + RDSCREEN_UI_LATHE_CHECK + var/list/l = list() + l += ui_protolathe_header() + + l += "
    \ + \ + \ + \ + \ + \ +

    " + + l += list_categories(linked_lathe.categories, RDSCREEN_PROTOLATHE_CATEGORY_VIEW) + + return l + +/obj/machinery/computer/rdconsole/proc/ui_protolathe_search() //Legacy code + RDSCREEN_UI_LATHE_CHECK + var/list/l = list() + l += ui_protolathe_header() + var/coeff = linked_lathe.efficiency_coeff + for(var/datum/design/D in matching_designs) + if(!(D.departmental_flags & linked_lathe.allowed_department_flags)) + continue + var/temp_material + var/c = 50 + var/t + var/all_materials = D.materials + D.reagents_list + for(var/M in all_materials) + t = linked_lathe.check_mat(D, M) + temp_material += " | " + if (t < 1) + temp_material += "[all_materials[M]*coeff] [CallMaterialName(M)]" + else + temp_material += " [all_materials[M]*coeff] [CallMaterialName(M)]" + c = min(c,t) + + if (c >= 1) + l += "[D.name][RDSCREEN_NOBREAK]" + if(c >= 5) + l += "x5[RDSCREEN_NOBREAK]" + if(c >= 10) + l += "x10[RDSCREEN_NOBREAK]" + l += "[temp_material][RDSCREEN_NOBREAK]" + else + l += "[D.name][temp_material][RDSCREEN_NOBREAK]" + l += "" + l += "
    " + return l + +/obj/machinery/computer/rdconsole/proc/ui_protolathe_materials() //Legacy code + RDSCREEN_UI_LATHE_CHECK + var/list/l = list() + l += ui_protolathe_header() + l += "

    Material Storage:

    " + for(var/mat_id in linked_lathe.materials.materials) + var/datum/material/M = linked_lathe.materials.materials[mat_id] + l += "* [M.amount] of [M.name]: " + if(M.amount >= MINERAL_MATERIAL_AMOUNT) l += "Eject [RDSCREEN_NOBREAK]" + if(M.amount >= MINERAL_MATERIAL_AMOUNT*5) l += "5x [RDSCREEN_NOBREAK]" + if(M.amount >= MINERAL_MATERIAL_AMOUNT) l += "All[RDSCREEN_NOBREAK]" + l += "" + l += "
    [RDSCREEN_NOBREAK]" + return l + +/obj/machinery/computer/rdconsole/proc/ui_protolathe_chemicals() //Legacy code + RDSCREEN_UI_LATHE_CHECK + var/list/l = list() + l += ui_protolathe_header() + l += "
    Disposal All Chemicals in Storage" + l += "

    Chemical Storage:

    " + for(var/datum/reagent/R in linked_lathe.reagents.reagent_list) + l += "[R.name]: [R.volume]" + l += "Purge" + l += "
    " + return l + +/obj/machinery/computer/rdconsole/proc/ui_circuit_header() //Legacy Code + var/list/l = list() + l += "" + return l + +/obj/machinery/computer/rdconsole/proc/ui_circuit() //Legacy code + RDSCREEN_UI_IMPRINTER_CHECK + var/list/l = list() + l += ui_circuit_header() + l += "

    Circuit Imprinter Menu:

    " + + l += "
    \ + \ + \ + \ + \ + \ +

    " + + l += list_categories(linked_imprinter.categories, RDSCREEN_IMPRINTER_CATEGORY_VIEW) + return l + +/obj/machinery/computer/rdconsole/proc/ui_circuit_category_view() //Legacy code + RDSCREEN_UI_IMPRINTER_CHECK + var/list/l = list() + l += ui_circuit_header() + l += "

    Browsing [selected_category]:

    " + + var/coeff = linked_imprinter.efficiency_coeff + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] + if(!(selected_category in D.category) || !(D.build_type & IMPRINTER)) + continue + if(!(D.departmental_flags & linked_imprinter.allowed_department_flags)) + continue + var/temp_materials + var/check_materials = TRUE + + var/all_materials = D.materials + D.reagents_list + + for(var/M in all_materials) + temp_materials += " | " + if (!linked_imprinter.check_mat(D, M)) + check_materials = FALSE + temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]" + else + temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]" + if (check_materials) + l += "[D.name][temp_materials]" + else + l += "[D.name][temp_materials]" + l += "
    " + return l + +/obj/machinery/computer/rdconsole/proc/ui_circuit_search() //Legacy code + RDSCREEN_UI_IMPRINTER_CHECK + var/list/l = list() + l += ui_circuit_header() + l += "

    Search results:

    " + + var/coeff = linked_imprinter.efficiency_coeff + for(var/datum/design/D in matching_designs) + if(!(D.departmental_flags & linked_imprinter.allowed_department_flags)) + continue + var/temp_materials + var/check_materials = TRUE + var/all_materials = D.materials + D.reagents_list + for(var/M in all_materials) + temp_materials += " | " + if (!linked_imprinter.check_mat(D, M)) + check_materials = FALSE + temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]" + else + temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]" + if (check_materials) + l += "[D.name][temp_materials]" + else + l += "[D.name][temp_materials]" + l += "
    " + return l + +/obj/machinery/computer/rdconsole/proc/ui_circuit_chemicals() //legacy code + RDSCREEN_UI_IMPRINTER_CHECK + var/list/l = list() + l += ui_circuit_header() + l += "Disposal All Chemicals in Storage
    " + l += "

    Chemical Storage:

    " + for(var/datum/reagent/R in linked_imprinter.reagents.reagent_list) + l += "[R.name]: [R.volume]" + l += "Purge" + return l + +/obj/machinery/computer/rdconsole/proc/ui_circuit_materials() //Legacy code! + RDSCREEN_UI_IMPRINTER_CHECK + var/list/l = list() + l += ui_circuit_header() + l += "

    Material Storage:

    " + for(var/mat_id in linked_imprinter.materials.materials) + var/datum/material/M = linked_imprinter.materials.materials[mat_id] + l += "* [M.amount] of [M.name]: " + if(M.amount >= MINERAL_MATERIAL_AMOUNT) l += "Eject [RDSCREEN_NOBREAK]" + if(M.amount >= MINERAL_MATERIAL_AMOUNT*5) l += "5x [RDSCREEN_NOBREAK]" + if(M.amount >= MINERAL_MATERIAL_AMOUNT) l += "All[RDSCREEN_NOBREAK]
    " + return l + +/obj/machinery/computer/rdconsole/proc/ui_techdisk() //Legacy code + RDSCREEN_UI_TDISK_CHECK + var/list/l = list() + l += "
    Disk Operations: Clear Disk" + l += "Eject Disk" + l += "Upload All" + l += "Load Technology to Disk
    " + l += "

    Stored Technology Nodes:

    " + for(var/i in t_disk.stored_research.researched_nodes) + var/datum/techweb_node/N = t_disk.stored_research.researched_nodes[i] + l += "[N.display_name]" + l += "
    " + return l + +/obj/machinery/computer/rdconsole/proc/ui_designdisk() //Legacy code + RDSCREEN_UI_DDISK_CHECK + var/list/l = list() + l += "Disk Operations: Clear DiskUpload AllEject Disk" + for(var/i in 1 to d_disk.max_blueprints) + l += "
    " + if(d_disk.blueprints[i]) + var/datum/design/D = d_disk.blueprints[i] + l += "[D.name]" + l += "Operations: Upload to database Clear Slot" + else + l += "Empty Slot Operations: Load Design to Slot" + l += "
    " + return l + +/obj/machinery/computer/rdconsole/proc/ui_designdisk_upload() //Legacy code + RDSCREEN_UI_DDISK_CHECK + var/list/l = list() + l += "Return to Disk Operations
    " + l += "

    Load Design to Disk:

    " + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] + l += "[D.name] " + l += "Copy to Disk" + l += "
    " + return l + +/obj/machinery/computer/rdconsole/proc/ui_deconstruct() //Legacy code + RDSCREEN_UI_DECONSTRUCT_CHECK + var/list/l = list() + if(!linked_destroy.loaded_item) + l += "
    No Item Loaded. Standing-by...
    " + else + l += "

    Deconstruction Menu

    " + l += "Eject Item" + l += "Name: [linked_destroy.loaded_item.name]" + l += "Select a node to boost by deconstructing this item." + l += "This item is able to boost:" + var/list/listin = techweb_item_boost_check(linked_destroy.loaded_item) + for(var/node_id in listin) + var/datum/techweb_node/N = get_techweb_node_by_id(node_id) + var/worth = listin[N.id] + if(!stored_research.researched_nodes[N.id] && !stored_research.boosted_nodes[N.id]) + l += "[N.display_name]: [worth] points" + else + l += "Generic Point Deconstruction - [point_value] points" + l += "Material Reclaimation Deconstruction" + l += "
    " + return l + +/obj/machinery/computer/rdconsole/proc/ui_techweb() //Legacy code. + var/list/l = list() + var/list/avail = list() //This could probably be optimized a bit later. + var/list/unavail = list() + var/list/res = list() + for(var/v in stored_research.researched_nodes) + res += stored_research.researched_nodes[v] + for(var/v in stored_research.available_nodes) + if(stored_research.researched_nodes[v]) + continue + avail += stored_research.available_nodes[v] + for(var/v in stored_research.visible_nodes) + if(stored_research.available_nodes[v]) + continue + unavail += stored_research.visible_nodes[v] + l += "

    Technology Nodes:

    [RDSCREEN_NOBREAK]" + l += "

    Available for Research:

    " + for(var/datum/techweb_node/N in avail) + var/not_unlocked = (stored_research.available_nodes[N.id] && !stored_research.researched_nodes[N.id]) + var/has_points = (stored_research.research_points >= N.get_price(stored_research)) + var/research_href = not_unlocked? (has_points? "Research" : "Not Enough Points") : null + l += "[N.display_name][research_href]" + l += "

    Locked Nodes:

    " + for(var/datum/techweb_node/N in unavail) + l += "[N.display_name]" + l += "

    Researched Nodes:

    " + for(var/datum/techweb_node/N in res) + l += "[N.display_name]" + l += "
    [RDSCREEN_NOBREAK]" + return l + +/obj/machinery/computer/rdconsole/proc/ui_techweb_nodeview() //Legacy code + RDSCREEN_UI_SNODE_CHECK + var/list/l = list() + if(stored_research.hidden_nodes[selected_node.id]) + l += "

    ERROR: RESEARCH NODE UNKNOWN.

    " + l += "

    [selected_node.display_name]

    " + l += "Description: [selected_node.description]" + l += "Status: [stored_research.researched_nodes[selected_node.id]? "Researched" : "Locked"]" + l += "Point Cost: [selected_node.get_price(stored_research)].
    [RDSCREEN_NOBREAK]" + if(stored_research.researched_nodes[selected_node.id]) + l += "

    Already Researched

    [RDSCREEN_NOBREAK]" + else if(stored_research.available_nodes[selected_node.id]) + if(stored_research.research_points >= selected_node.get_price(stored_research)) + l += "

    Research

    [RDSCREEN_NOBREAK]" + else + l += "

    Not Enough Points

    [RDSCREEN_NOBREAK]" + else if(stored_research.visible_nodes[selected_node.id]) + l += "

    Prerequisites not met!

    [RDSCREEN_NOBREAK]" + else + l += "

    ERROR

    [RDSCREEN_NOBREAK]" + l += "

    Designs:

    [RDSCREEN_NOBREAK]" + for(var/i in selected_node.designs) + var/datum/design/D = selected_node.designs[i] + l += "[D.name]" + l += "

    Prerequisites:

    [RDSCREEN_NOBREAK]" + for(var/i in selected_node.prerequisites) + var/datum/techweb_node/prereq = selected_node.prerequisites[i] + var/sc = stored_research.researched_nodes[prereq.id] + var/begin + var/end + if(sc) + begin = "" + end = "" + else + begin = "" + end = "" + l += "[begin][prereq.display_name][end]" + l += "

    Unlocks:

    [RDSCREEN_NOBREAK]" + for(var/i in selected_node.unlocks) + var/datum/techweb_node/unlock = selected_node.unlocks[i] + l += "[unlock.display_name]" + + l += "
    [RDSCREEN_NOBREAK]" + return l + +/obj/machinery/computer/rdconsole/proc/ui_techweb_designview() //Legacy code + RDSCREEN_UI_SDESIGN_CHECK + var/list/l = list() + var/datum/design/D = selected_design + l += "
    Name: [D.name]" + if(D.build_type) + l += "Lathe Types:" + if(D.build_type & IMPRINTER) l += "Circuit Imprinter" + if(D.build_type & PROTOLATHE) l += "Protolathe" + if(D.build_type & AUTOLATHE) l += "Autolathe" + if(D.build_type & MECHFAB) l += "Exosuit Fabricator" + if(D.build_type & BIOGENERATOR) l += "Biogenerator" + if(D.build_type & LIMBGROWER) l += "Limbgrower" + if(D.build_type & SMELTER) l += "Smelter" + l += "Required Materials:" + var/all_mats = D.materials + D.reagents_list + for(var/M in all_mats) + l += "* [CallMaterialName(M)] x [all_mats[M]]" + l += "[RDSCREEN_NOBREAK]
    " + return l + +//Fuck TGUI. +/obj/machinery/computer/rdconsole/proc/generate_ui() + var/list/ui = list() + ui += ui_header() + if(locked) + ui += ui_locked() + else + switch(screen) + if(RDSCREEN_MENU) + ui += ui_main_menu() + if(RDSCREEN_TECHWEB) + ui += ui_techweb() + if(RDSCREEN_TECHWEB_NODEVIEW) + ui += ui_techweb_nodeview() + if(RDSCREEN_TECHWEB_DESIGNVIEW) + ui += ui_techweb_designview() + if(RDSCREEN_DESIGNDISK) + ui += ui_designdisk() + if(RDSCREEN_DESIGNDISK_UPLOAD) + ui += ui_designdisk_upload() + if(RDSCREEN_TECHDISK) + ui += ui_techdisk() + if(RDSCREEN_DECONSTRUCT) + ui += ui_deconstruct() + if(RDSCREEN_PROTOLATHE) + ui += ui_protolathe() + if(RDSCREEN_PROTOLATHE_CATEGORY_VIEW) + ui += ui_protolathe_category_view() + if(RDSCREEN_PROTOLATHE_MATERIALS) + ui += ui_protolathe_materials() + if(RDSCREEN_PROTOLATHE_CHEMICALS) + ui += ui_protolathe_chemicals() + if(RDSCREEN_PROTOLATHE_SEARCH) + ui += ui_protolathe_search() + if(RDSCREEN_IMPRINTER) + ui += ui_circuit() + if(RDSCREEN_IMPRINTER_CATEGORY_VIEW) + ui += ui_circuit_category_view() + if(RDSCREEN_IMPRINTER_MATERIALS) + ui += ui_circuit_materials() + if(RDSCREEN_IMPRINTER_CHEMICALS) + ui += ui_circuit_chemicals() + if(RDSCREEN_IMPRINTER_SEARCH) + ui += ui_circuit_search() + if(RDSCREEN_SETTINGS) + ui += ui_settings() + if(RDSCREEN_DEVICE_LINKING) + ui += ui_device_linking() + for(var/i in 1 to length(ui)) + if(!findtextEx(ui[i], RDSCREEN_NOBREAK)) + ui[i] += "
    " + ui[i] = replacetextEx(ui[i], RDSCREEN_NOBREAK, "") + return ui.Join("") + +/obj/machinery/computer/rdconsole/Topic(raw, ls) if(..()) return - add_fingerprint(usr) - usr.set_machine(src) - if(href_list["disk_slot"]) - disk_slot_selected = text2num(href_list["disk_slot"]) - - if(href_list["menu"]) //Switches menu screens. Converts a sent text string into a number. Saves a LOT of code. - var/temp_screen = text2num(href_list["menu"]) - screen = temp_screen - - - var/datum/component/material_container/linked_materials - if(linked_lathe) - linked_materials = linked_lathe.GetComponent(/datum/component/material_container) - - var/datum/component/material_container/imprinter_materials - if(linked_imprinter) - imprinter_materials = linked_imprinter.GetComponent(/datum/component/material_container) - - if(href_list["category"]) - selected_category = href_list["category"] - - else if(href_list["updt_tech"]) //Update the research holder with information from the technology disk. - var/n = text2num(href_list["updt_tech"]) - screen = 0.0 - var/wait = 50 - if(!n) - wait = 0 - for(var/D in t_disk.tech_stored) - if(D) - wait += 50 - spawn(wait) - screen = 1.2 - if(t_disk) - if(!n) - for(var/tech in t_disk.tech_stored) - files.AddTech2Known(tech) - else - files.AddTech2Known(t_disk.tech_stored[n]) - updateUsrDialog() - griefProtection() //Update centcom too - - else if(href_list["clear_tech"]) //Erase data on the technology disk. - if(t_disk) - var/n = text2num(href_list["clear_tech"]) - if(!n) - for(var/i in 1 to t_disk.max_tech_stored) - t_disk.tech_stored[i] = null - else - t_disk.tech_stored[n] = null - - else if(href_list["eject_tech"]) //Eject the technology disk. - if(t_disk) - t_disk.loc = src.loc - t_disk = null - screen = 1.0 - - else if(href_list["copy_tech"]) //Copy some technology data from the research holder to the disk. - var/slot = text2num(href_list["copy_tech"]) - var/datum/tech/T = files.known_tech[href_list["copy_tech_ID"]] - if(T) - t_disk.tech_stored[slot] = T.copy() - screen = 1.2 - - else if(href_list["updt_design"]) //Updates the research holder with design data from the design disk. - var/n = text2num(href_list["updt_design"]) - screen = 0.0 - var/wait = 50 - if(!n) - wait = 0 - for(var/D in d_disk.blueprints) - if(D) - wait += 50 - spawn(wait) - screen = 1.4 - if(d_disk) - if(!n) - for(var/D in d_disk.blueprints) - if(D) - files.AddDesign2Known(D) - else - files.AddDesign2Known(d_disk.blueprints[n]) - updateUsrDialog() - griefProtection() //Update centcom too - - else if(href_list["clear_design"]) //Erases data on the design disk. - if(d_disk) - var/n = text2num(href_list["clear_design"]) - if(!n) - for(var/i in 1 to d_disk.max_blueprints) - d_disk.blueprints[i] = null - else - d_disk.blueprints[n] = null - - else if(href_list["eject_design"]) //Eject the design disk. - if(d_disk) - d_disk.loc = src.loc - d_disk = null - screen = 1.0 - - else if(href_list["copy_design"]) //Copy design data from the research holder to the design disk. - var/slot = text2num(href_list["copy_design"]) - var/datum/design/D = files.known_designs[href_list["copy_design_ID"]] - if(D) - var/autolathe_friendly = 1 - if(D.reagents_list.len) - autolathe_friendly = 0 - D.category -= "Imported" - else - for(var/x in D.materials) - if( !(x in list(MAT_METAL, MAT_GLASS))) - autolathe_friendly = 0 - D.category -= "Imported" - - if(D.build_type & (AUTOLATHE|PROTOLATHE|CRAFTLATHE)) // Specifically excludes circuit imprinter and mechfab - D.build_type = autolathe_friendly ? (D.build_type | AUTOLATHE) : D.build_type - D.category |= "Imported" - d_disk.blueprints[slot] = D - screen = 1.4 - - else if(href_list["eject_item"]) //Eject the item inside the destructive analyzer. - if(linked_destroy) - if(linked_destroy.busy) - to_chat(usr, "The destructive analyzer is busy at the moment.") - - else if(linked_destroy.loaded_item) - linked_destroy.loaded_item.forceMove(linked_destroy.loc) - linked_destroy.loaded_item = null - linked_destroy.icon_state = "d_analyzer" - screen = 1.0 - - else if(href_list["deconstruct"]) //Deconstruct the item in the destructive analyzer and update the research holder. - if(!linked_destroy || linked_destroy.busy || !linked_destroy.loaded_item) - updateUsrDialog() - return - - var/list/temp_tech = linked_destroy.ConvertReqString2List(linked_destroy.loaded_item.origin_tech) - var/cancontinue = FALSE - for(var/T in temp_tech) - if(files.IsTechHigher(T, temp_tech[T])) - cancontinue = TRUE - break - if(!cancontinue) - var/choice = input("This item does not raise tech levels. Proceed destroying loaded item anyway?") in list("Proceed", "Cancel") - if(choice == "Cancel" || !linked_destroy || !linked_destroy.loaded_item) - return - linked_destroy.busy = TRUE - screen = 0.1 - updateUsrDialog() - flick("d_analyzer_process", linked_destroy) - spawn(24) - if(linked_destroy) - linked_destroy.busy = FALSE - if(!linked_destroy.loaded_item) - screen = 1.0 - return - - for(var/T in temp_tech) - files.UpdateTech(T, temp_tech[T]) - - if(linked_lathe) //Also sends salvaged materials to a linked protolathe, if any. - for(var/material in linked_destroy.loaded_item.materials) - linked_materials.insert_amount(min((linked_materials.max_amount - linked_materials.total_amount), (min(linked_destroy.loaded_item.materials[material]*(linked_destroy.decon_mod/10), linked_destroy.loaded_item.materials[material]))), material) - SSblackbox.record_feedback("tally", "item_deconstructed", 1, linked_destroy.loaded_item.type) - linked_destroy.loaded_item = null - for(var/obj/I in linked_destroy.contents) - for(var/mob/M in I.contents) - M.death() - if(istype(I, /obj/item/stack/sheet))//Only deconsturcts one sheet at a time instead of the entire stack - var/obj/item/stack/sheet/S = I - if(S.amount > 1) - S.amount-- - linked_destroy.loaded_item = S - else - qdel(S) - linked_destroy.icon_state = "d_analyzer" - else - if(!(I in linked_destroy.component_parts)) - qdel(I) - linked_destroy.icon_state = "d_analyzer" - screen = 1.0 - use_power(250) - updateUsrDialog() - - else if(href_list["lock"]) //Lock the console from use by anyone without tox access. - if(src.allowed(usr)) - screen = text2num(href_list["lock"]) + if(ls["switch_screen"]) + back = screen + screen = text2num(ls["switch_screen"]) + if(ls["lock_console"]) + if(allowed(usr)) + lock_console(usr) else - to_chat(usr, "Unauthorized Access.") - - else if(href_list["sync"]) //Sync the research holder with all the R&D consoles in the game that aren't sync protected. - screen = 0.0 - if(!sync) - to_chat(usr, "You must connect to the network first!") + to_chat(usr, "Unauthorized Access.") + if(ls["unlock_console"]) + if(allowed(usr)) + unlock_console(usr) else - griefProtection() //Putting this here because I dont trust the sync process - spawn(30) - if(src) - for(var/obj/machinery/r_n_d/server/S in GLOB.machines) - var/server_processed = 0 - if(S.disabled) - continue - if((id in S.id_with_upload) || istype(S, /obj/machinery/r_n_d/server/centcom)) - for(var/v in files.known_tech) - var/datum/tech/T = files.known_tech[v] - S.files.AddTech2Known(T) - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] - S.files.AddDesign2Known(D) - S.files.RefreshResearch() - server_processed = 1 - if(((id in S.id_with_download) && !istype(S, /obj/machinery/r_n_d/server/centcom)) || S.hacked) - for(var/v in S.files.known_tech) - var/datum/tech/T = S.files.known_tech[v] - files.AddTech2Known(T) - for(var/v in S.files.known_designs) - var/datum/design/D = S.files.known_designs[v] - files.AddDesign2Known(D) - files.RefreshResearch() - server_processed = 1 - if(!istype(S, /obj/machinery/r_n_d/server/centcom) && server_processed) - S.produce_heat(100) - screen = 1.6 - updateUsrDialog() - - else if(href_list["togglesync"]) //Prevents the console from being synced by other consoles. Can still send data. - sync = !sync - - else if(href_list["build"]) //Causes the Protolathe to build something. - var/datum/design/being_built = files.known_designs[href_list["build"]] - var/amount = text2num(href_list["amount"]) - - if(being_built.make_reagents.len) - return 0 - - if(!linked_lathe || !being_built || !amount) - updateUsrDialog() - return - + to_chat(usr, "Unauthorized Access.") + if(ls["find_device"]) + SyncRDevices() + say("Resynced with nearby devices.") + if(ls["back_screen"]) + back = text2num(ls["back_screen"]) + if(ls["build"]) //Causes the Protolathe to build something. if(linked_lathe.busy) - to_chat(usr, "Protolathe is busy at the moment.") - return - - var/coeff = linked_lathe.efficiency_coeff - var/power = 1000 - var/old_screen = screen - - amount = max(1, min(10, amount)) - for(var/M in being_built.materials) - power += round(being_built.materials[M] * amount / 5) - power = max(3000, power) - screen = 0.3 - var/key = usr.key //so we don't lose the info during the spawn delay - if (!(being_built.build_type & PROTOLATHE)) - message_admins("Protolathe exploit attempted by [key_name(usr, usr.client)]!") - updateUsrDialog() - return - - var/g2g = 1 - var/enough_materials = 1 - linked_lathe.busy = TRUE - flick("protolathe_n",linked_lathe) - use_power(power) - - var/list/efficient_mats = list() - for(var/MAT in being_built.materials) - efficient_mats[MAT] = being_built.materials[MAT]*coeff - - if(!linked_materials.has_materials(efficient_mats, amount)) - linked_lathe.say("Not enough materials to complete prototype.") - enough_materials = 0 - g2g = 0 + say("Warning: Protolathe busy!") else - for(var/R in being_built.reagents_list) - if(!linked_lathe.reagents.has_reagent(R, being_built.reagents_list[R]*coeff)) - linked_lathe.say("Not enough reagents to complete prototype.") - enough_materials = 0 - g2g = 0 - - if(enough_materials) - linked_materials.use_amount(efficient_mats, amount) - for(var/R in being_built.reagents_list) - linked_lathe.reagents.remove_reagent(R, being_built.reagents_list[R]*coeff) - - var/P = being_built.build_path //lets save these values before the spawn() just in case. Nobody likes runtimes. - - coeff *= being_built.lathe_time_factor - - spawn(32*coeff*amount**0.8) - if(linked_lathe) - if(g2g) //And if we only fail the material requirements, we still spend time and power - var/already_logged = 0 - for(var/i = 0, iCircuit Imprinter is busy at the moment.") - updateUsrDialog() - return - - var/coeff = linked_imprinter.efficiency_coeff - - var/power = 1000 - var/old_screen = screen - for(var/M in being_built.materials) - power += round(being_built.materials[M] / 5) - power = max(4000, power) - screen = 0.4 - if (!(being_built.build_type & IMPRINTER)) - message_admins("Circuit imprinter exploit attempted by [key_name(usr, usr.client)]!") - updateUsrDialog() - return - - var/g2g = 1 - var/enough_materials = 1 - linked_imprinter.busy = TRUE - flick("circuit_imprinter_ani", linked_imprinter) - use_power(power) - - var/list/efficient_mats = list() - for(var/MAT in being_built.materials) - efficient_mats[MAT] = being_built.materials[MAT]/coeff - - if(!imprinter_materials.has_materials(efficient_mats)) - linked_imprinter.say("Not enough materials to complete prototype.") - enough_materials = 0 - g2g = 0 + say("Warning: Imprinter busy!") else - for(var/R in being_built.reagents_list) - if(!linked_imprinter.reagents.has_reagent(R, being_built.reagents_list[R]/coeff)) - linked_imprinter.say("Not enough reagents to complete prototype.") - enough_materials = 0 - g2g = 0 - - if(enough_materials) - imprinter_materials.use_amount(efficient_mats) - for(var/R in being_built.reagents_list) - linked_imprinter.reagents.remove_reagent(R, being_built.reagents_list[R]/coeff) - - var/P = being_built.build_path //lets save these values before the spawn() just in case. Nobody likes runtimes. - spawn(16) - if(linked_imprinter) - if(g2g) - var/obj/item/new_item = new P(src) - new_item.loc = linked_imprinter.loc - new_item.materials = efficient_mats.Copy() - SSblackbox.record_feedback("tally", "circuit_printed", 1, new_item.type) - screen = old_screen - linked_imprinter.busy = FALSE - else - say("Circuit Imprinter connection failed. Production halted.") - screen = 1.0 - updateUsrDialog() - - //Protolathe Materials - else if(href_list["disposeP"] && linked_lathe) //Causes the protolathe to dispose of a single reagent (all of it) - linked_lathe.reagents.del_reagent(href_list["disposeP"]) - - else if(href_list["disposeallP"] && linked_lathe) //Causes the protolathe to dispose of all it's reagents. - linked_lathe.reagents.clear_reagents() - - else if(href_list["ejectsheet"] && linked_lathe) //Causes the protolathe to eject a sheet of material - linked_materials.retrieve_sheets(text2num(href_list["eject_amt"]), href_list["ejectsheet"]) - - //Circuit Imprinter Materials - else if(href_list["disposeI"] && linked_imprinter) //Causes the circuit imprinter to dispose of a single reagent (all of it) - linked_imprinter.reagents.del_reagent(href_list["disposeI"]) - - else if(href_list["disposeallI"] && linked_imprinter) //Causes the circuit imprinter to dispose of all it's reagents. - linked_imprinter.reagents.clear_reagents() - - else if(href_list["imprinter_ejectsheet"] && linked_imprinter) //Causes the imprinter to eject a sheet of material - imprinter_materials.retrieve_sheets(text2num(href_list["eject_amt"]), href_list["imprinter_ejectsheet"]) - - - else if(href_list["find_device"]) //The R&D console looks for devices nearby to link up with. - screen = 0.0 - spawn(20) - SyncRDevices() - screen = 1.7 - updateUsrDialog() - - else if(href_list["disconnect"]) //The R&D console disconnects with a specific device. - switch(href_list["disconnect"]) + linked_imprinter.user_try_print_id(ls["imprint"]) + if(ls["category"]) + selected_category = ls["category"] + if(ls["disconnect"]) //The R&D console disconnects with a specific device. + switch(ls["disconnect"]) if("destroy") linked_destroy.linked_console = null linked_destroy = null @@ -572,42 +759,112 @@ won't update every console in existence) but it's more of a hassle to do. Also, if("imprinter") linked_imprinter.linked_console = null linked_imprinter = null - - else if(href_list["reset"]) //Reset the R&D console's database. - griefProtection() - var/choice = alert("R&D Console Database Reset", "Are you sure you want to reset the R&D console's database? Data lost cannot be recovered.", "Continue", "Cancel") - if(choice == "Continue" && usr.canUseTopic(src)) - message_admins("[key_name_admin(usr)] reset \the [src.name]'s database") - log_game("[key_name_admin(usr)] reset \the [src.name]'s database") - screen = 0.0 - qdel(files) - files = new /datum/research(src) - spawn(20) - screen = 1.6 - updateUsrDialog() - - else if(href_list["search"]) //Search for designs with name matching pattern - var/compare - - matching_designs.Cut() - - if(href_list["type"] == "proto") - compare = PROTOLATHE - screen = 3.17 + if(ls["eject_design"]) //Eject the design disk. + eject_disk("design") + screen = RDSCREEN_MENU + say("Ejecting Design Disk") + if(ls["eject_tech"]) //Eject the technology disk. + eject_disk("tech") + screen = RDSCREEN_MENU + say("Ejecting Technology Disk") + if(ls["deconstruct"]) + linked_destroy.user_try_decon_id(ls["deconstruct"], usr) + //Protolathe Materials + if(ls["disposeP"] && linked_lathe) //Causes the protolathe to dispose of a single reagent (all of it) + linked_lathe.reagents.del_reagent(ls["disposeP"]) + if(ls["disposeallP"] && linked_lathe) //Causes the protolathe to dispose of all it's reagents. + linked_lathe.reagents.clear_reagents() + if(ls["ejectsheet"] && linked_lathe) //Causes the protolathe to eject a sheet of material + linked_lathe.materials.retrieve_sheets(text2num(ls["eject_amt"]), ls["ejectsheet"]) + //Circuit Imprinter Materials + if(ls["disposeI"] && linked_imprinter) //Causes the circuit imprinter to dispose of a single reagent (all of it) + linked_imprinter.reagents.del_reagent(ls["disposeI"]) + if(ls["disposeallI"] && linked_imprinter) //Causes the circuit imprinter to dispose of all it's reagents. + linked_imprinter.reagents.clear_reagents() + if(ls["imprinter_ejectsheet"] && linked_imprinter) //Causes the imprinter to eject a sheet of material + linked_imprinter.materials.retrieve_sheets(text2num(ls["eject_amt"]), ls["imprinter_ejectsheet"]) + if(ls["disk_slot"]) + disk_slot_selected = text2num(ls["disk_slot"]) + if(ls["research_node"]) + if(!research_control) + return //honestly should call them out for href exploiting :^) + if(!SSresearch.science_tech.available_nodes[ls["research_node"]]) + return //Nope! + research_node(ls["research_node"]) + if(ls["clear_tech"]) //Erase la on the technology disk. + if(t_disk) + qdel(t_disk.stored_research) + t_disk.stored_research = new + say("Wiping technology disk.") + if(ls["copy_tech"]) //Copy some technology la from the research holder to the disk. + stored_research.copy_research_to(t_disk.stored_research) + screen = RDSCREEN_TECHDISK + say("Downloading to technology disk.") + if(ls["clear_design"]) //Erases la on the design disk. + if(d_disk) + var/n = text2num(ls["clear_design"]) + if(!n) + for(var/i in 1 to d_disk.max_blueprints) + d_disk.blueprints[i] = null + say("Wiping design disk.") + else + var/datum/design/D = d_disk.blueprints[n] + say("Wiping design [D.name] from design disk.") + d_disk.blueprints[n] = null + if(ls["search"]) //Search for designs with name matching pattern + searchstring = ls["to_search"] + searchtype = ls["type"] + rescan_views() + if(searchtype == "proto") + screen = RDSCREEN_PROTOLATHE_SEARCH else - compare = IMPRINTER - screen = 4.17 + screen = RDSCREEN_IMPRINTER_SEARCH + if(ls["updt_tech"]) //Uple the research holder with information from the technology disk. + say("Uploading Technology Disk.") + if(t_disk) + t_disk.stored_research.copy_research_to(stored_research) + if(ls["copy_design"]) //Copy design la from the research holder to the design disk. + var/slot = text2num(ls["copy_design"]) + var/datum/design/D = stored_research.researched_designs[ls["copy_design_ID"]] + if(D) + var/autolathe_friendly = TRUE + if(D.reagents_list.len) + autolathe_friendly = FALSE + D.category -= "Imported" + else + for(var/x in D.materials) + if( !(x in list(MAT_METAL, MAT_GLASS))) + autolathe_friendly = FALSE + D.category -= "Imported" - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] - if(!(D.build_type & compare)) - continue - if(findtext(D.name,href_list["to_search"])) - matching_designs.Add(D) + if(D.build_type & (AUTOLATHE|PROTOLATHE|CRAFTLATHE)) // Specifically excludes circuit imprinter and mechfab + D.build_type = autolathe_friendly ? (D.build_type | AUTOLATHE) : D.build_type + D.category |= "Imported" + d_disk.blueprints[slot] = D + screen = RDSCREEN_DESIGNDISK + if(ls["eject_item"]) //Eject the item inside the destructive analyzer. + if(linked_destroy && linked_destroy.busy) + to_chat(usr, "The destructive analyzer is busy at the moment.") + else if(linked_destroy.loaded_item) + linked_destroy.unload_item() + screen = RDSCREEN_MENU + if(ls["view_node"]) + selected_node = SSresearch.techweb_nodes[ls["view_node"]] + screen = RDSCREEN_TECHWEB_NODEVIEW + if(ls["view_design"]) + selected_design = SSresearch.techweb_designs[ls["view_design"]] + screen = RDSCREEN_TECHWEB_DESIGNVIEW + if(ls["updt_design"]) //Uples the research holder with design la from the design disk. + if(d_disk) + var/n = text2num(ls["updt_design"]) + if(!n) + for(var/D in d_disk.blueprints) + if(D) + stored_research.add_design(D) + else + stored_research.add_design(d_disk.blueprints[n]) updateUsrDialog() - return - /obj/machinery/computer/rdconsole/attack_hand(mob/user) if(..()) @@ -616,483 +873,68 @@ won't update every console in existence) but it's more of a hassle to do. Also, /obj/machinery/computer/rdconsole/interact(mob/user) user.set_machine(src) - - if(first_use) - SyncRDevices() - - var/dat = "" - files.RefreshResearch() - switch(screen) //A quick check to make sure you get the right screen when a device is disconnected. - if(2 to 2.9) - if(screen == 2.3) - ; - else if(linked_destroy == null) - screen = 2.0 - else if(linked_destroy.loaded_item == null) - screen = 2.1 - else - screen = 2.2 - if(3 to 3.9) - if(linked_lathe == null) - screen = 3.0 - if(4 to 4.9) - if(linked_imprinter == null) - screen = 4.0 - - - var/datum/component/material_container/linked_materials - if(linked_lathe) - linked_materials = linked_lathe.GetComponent(/datum/component/material_container) - - var/datum/component/material_container/imprinter_materials - if(linked_imprinter) - imprinter_materials = linked_imprinter.GetComponent(/datum/component/material_container) - switch(screen) - - //////////////////////R&D CONSOLE SCREENS////////////////// - if(0.0) - dat += "
    Updating Database....
    " - - if(0.1) - dat += "
    Processing and Updating Database...
    " - - if(RD_CONSOLE_LOCKED_SCREEN) - dat += "
    SYSTEM LOCKED
    " - dat += "Unlock" - - if(0.3) - dat += "
    Constructing Prototype. Please Wait...
    " - - if(0.4) - dat += "
    Imprinting Circuit. Please Wait...
    " - - if(1.0) //Main Menu - dat += "
    " - dat += "

    Main Menu:


    " - dat += "Current Research Levels
    " - if(t_disk) - dat += "Disk Operations
    " - else if(d_disk) - dat += "Disk Operations
    " - else - dat += "Disk Operations
    " - if(linked_destroy) - dat += "Destructive Analyzer Menu
    " - else - dat += "Destructive Analyzer Menu
    " - if(linked_lathe) - dat += "Protolathe Construction Menu
    " - else - dat += "Protolathe Construction Menu
    " - if(linked_imprinter) - dat += "Circuit Construction Menu
    " - else - dat += "Circuit Construction Menu
    " - dat += "Settings" - dat += "
    " - - if(1.1) //Research viewer - dat += "Main Menu" - dat += "

    Current Research Levels:


    " - for(var/v in files.known_tech) - var/datum/tech/T = files.known_tech[v] - if(T.level <= 0) - continue - dat += "[T.name]
    " - dat += "* Level: [T.level]
    " - dat += "* Summary: [T.desc]
    " - dat += "
    " - - if(1.2) //Technology Disk Menu - dat += "Main Menu
    " - dat += "Disk Operations: Clear DiskUpload AllEject Disk" - for(var/i in 1 to t_disk.max_tech_stored) - dat += "
    " - if(t_disk.tech_stored[i]) - var/datum/tech/tech = t_disk.tech_stored[i] - dat += "Name: [tech.name]
    " - dat += "Level: [tech.level]
    " - dat += "Description: [tech.desc]
    " - dat += "Operations: Upload to DatabaseClear Slot" - else - dat += "Empty Slot
    Operations: Load Tech to Slot" - dat += "
    " - if(1.3) //Technology Disk submenu - dat += "Main Menu" - dat += "Return to Disk Operations
    " - dat += "

    Load Technology to Disk:


    " - for(var/v in files.known_tech) - var/datum/tech/T = files.known_tech[v] - if(T.level <= 0) - continue - dat += "[T.name]" - dat += "Copy to Disk
    " - dat += "
    " - - if(1.4) //Design Disk menu. - dat += "Main Menu
    " - dat += "Disk Operations: Clear DiskUpload AllEject Disk" - for(var/i in 1 to d_disk.max_blueprints) - dat += "
    " - if(d_disk.blueprints[i]) - var/datum/design/D = d_disk.blueprints[i] - dat += "Name: [D.name]
    " - if(D.build_type) - dat += "Lathe Types:
    " - if(D.build_type & IMPRINTER) - dat += "Circuit Imprinter
    " - if(D.build_type & PROTOLATHE) - dat += "Protolathe
    " - if(D.build_type & AUTOLATHE) - dat += "Autolathe
    " - if(D.build_type & MECHFAB) - dat += "Exosuit Fabricator
    " - if(D.build_type & BIOGENERATOR) - dat += "Biogenerator
    " - if(D.build_type & LIMBGROWER) - dat += "Limbgrower
    " - if(D.build_type & SMELTER) - dat += "Smelter
    " - dat += "Required Materials:
    " - var/all_mats = D.materials + D.reagents_list - for(var/M in all_mats) - dat += "* [CallMaterialName(M)] x [all_mats[M]]
    " - dat += "Operations: Upload to Database Clear Slot" - else - dat += "Empty Slot
    Operations: Load Design to Slot" - dat += "
    " - if(1.5) //Design disk submenu - dat += "Main Menu" - dat += "Return to Disk Operations
    " - dat += "

    Load Design to Disk:


    " - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] - dat += "[D.name] " - dat += "Copy to Disk
    " - dat += "
    " - - if(1.6) //R&D console settings - dat += "Main Menu
    " - dat += "

    R&D Console Setting:


    " - if(sync) - dat += "Sync Database with Network
    " - dat += "Connect to Research Network
    " - dat += "Disconnect from Research Network
    " - else - dat += "Sync Database with Network
    " - dat += "Connect to Research Network
    " - dat += "Disconnect from Research Network
    " - dat += "Device Linkage Menu
    " - dat += "Lock Console
    " - dat += "Reset R&D Database
    " - - if(1.7) //R&D device linkage - dat += "Main Menu" - dat += "Settings Menu
    " - dat += "

    R&D Console Device Linkage Menu:


    " - dat += "Re-sync with Nearby Devices

    " - dat += "

    Linked Devices:


    " - if(linked_destroy) - dat += "* Destructive Analyzer Disconnect
    " - else - dat += "* No Destructive Analyzer Linked
    " - if(linked_lathe) - dat += "* Protolathe Disconnect
    " - else - dat += "* No Protolathe Linked
    " - if(linked_imprinter) - dat += "* Circuit Imprinter Disconnect
    " - else - dat += "* No Circuit Imprinter Linked
    " - dat += "
    " - - ////////////////////DESTRUCTIVE ANALYZER SCREENS//////////////////////////// - if(2.0) - dat += "Main Menu" - dat += "
    NO DESTRUCTIVE ANALYZER LINKED TO CONSOLE
    " - - if(2.1) - dat += "Main Menu" - dat += "
    No Item Loaded. Standing-by...
    " - - if(2.2) - dat += "Main Menu
    " - dat += "

    Deconstruction Menu


    " - dat += "Name: [linked_destroy.loaded_item.name]
    " - dat += "Origin Tech:
    " - var/list/temp_tech = linked_destroy.ConvertReqString2List(linked_destroy.loaded_item.origin_tech) - for(var/T in temp_tech) - dat += "* [CallTechName(T)] [temp_tech[T]]" - var/datum/tech/F = files.known_tech[T] - if(F) - dat += " (Current: [F.level])" - - dat += "
    " - dat += "
    Options: " - dat += "Deconstruct Item" - dat += "Eject Item" - if(2.3) - dat += "Main Menu" - dat += "
    Item is neither reliable enough or broken enough to learn from.
    " - - /////////////////////PROTOLATHE SCREENS///////////////////////// - if(3.0) - dat += "Main Menu
    " - dat += "
    NO PROTOLATHE LINKED TO CONSOLE
    " - - if(3.1) - dat += "Main Menu " - dat += "Material Storage" - dat += "Chemical Storage
    " - dat += "

    Protolathe Menu:


    " - dat += "Material Amount: [linked_materials.total_amount] / [linked_materials.max_amount]
    " - dat += "Chemical Volume: [linked_lathe.reagents.total_volume] / [linked_lathe.reagents.maximum_volume]
    " - - dat += "
    \ - \ - \ - \ - \ - \ -

    " - - dat += list_categories(linked_lathe.categories, 3.15) - - //Grouping designs by categories, to improve readability - if(3.15) - dat += "Main Menu" - dat += "Protolathe Menu" - dat += "

    Browsing [selected_category]:


    " - dat += "Material Amount: [linked_materials.total_amount] / [linked_materials.max_amount]
    " - dat += "Chemical Volume: [linked_lathe.reagents.total_volume] / [linked_lathe.reagents.maximum_volume]
    " - - var/coeff = linked_lathe.efficiency_coeff - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] - if(!(selected_category in D.category)|| !(D.build_type & PROTOLATHE)) - continue - var/temp_material - var/c = 50 - var/t - - var/all_materials = D.materials + D.reagents_list - for(var/M in all_materials) - t = linked_lathe.check_mat(D, M) - temp_material += " | " - if (t < 1) - temp_material += "[all_materials[M]*coeff] [CallMaterialName(M)]" - else - temp_material += " [all_materials[M]*coeff] [CallMaterialName(M)]" - c = min(c,t) - - if (c >= 1) - dat += "[D.name]" - if(c >= 5) - dat += "x5" - if(c >= 10) - dat += "x10" - dat += "[temp_material]" - else - dat += "[D.name][temp_material]" - dat += "
    " - dat += "
    " - - if(3.17) //Display search result - dat += "Main Menu" - dat += "Protolathe Menu" - dat += "

    Search results:


    " - dat += "Material Amount: [linked_materials.total_amount] / [linked_materials.max_amount]
    " - dat += "Chemical Volume: [linked_lathe.reagents.total_volume] / [linked_lathe.reagents.maximum_volume]
    " - - var/coeff = linked_lathe.efficiency_coeff - for(var/datum/design/D in matching_designs) - var/temp_material - var/c = 50 - var/t - var/all_materials = D.materials + D.reagents_list - for(var/M in all_materials) - t = linked_lathe.check_mat(D, M) - temp_material += " | " - if (t < 1) - temp_material += "[all_materials[M]*coeff] [CallMaterialName(M)]" - else - temp_material += " [all_materials[M]*coeff] [CallMaterialName(M)]" - c = min(c,t) - - if (c >= 1) - dat += "[D.name]" - if(c >= 5) - dat += "x5" - if(c >= 10) - dat += "x10" - dat += "[temp_material]" - else - dat += "[D.name][temp_material]" - dat += "
    " - dat += "
    " - - if(3.2) //Protolathe Material Storage Sub-menu - dat += "Main Menu" - dat += "Protolathe Menu
    " - dat += "

    Material Storage:



    " - if(!linked_lathe) - dat += "ERROR: Protolathe connection failed." - else - for(var/mat_id in linked_materials.materials) - var/datum/material/M = linked_materials.materials[mat_id] - dat += "* [M.amount] of [M.name]: " - if(M.amount >= MINERAL_MATERIAL_AMOUNT) - dat += "Eject " - if(M.amount >= MINERAL_MATERIAL_AMOUNT*5) - dat += "5x " - if(M.amount >= MINERAL_MATERIAL_AMOUNT) - dat += "All" - dat += "
    " - dat += "
    " - - if(3.3) - dat += "Main Menu" - dat += "Protolathe Menu" - dat += "Disposal All Chemicals in Storage
    " - dat += "

    Chemical Storage:



    " - for(var/datum/reagent/R in linked_lathe.reagents.reagent_list) - dat += "[R.name]: [R.volume]" - dat += "Purge
    " - - ///////////////////CIRCUIT IMPRINTER SCREENS//////////////////// - if(4.0) - dat += "Main Menu
    " - dat += "
    NO CIRCUIT IMPRINTER LINKED TO CONSOLE
    " - - if(4.1) - dat += "Main Menu" - dat += "Material Storage" - dat += "Chemical Storage
    " - dat += "

    Circuit Imprinter Menu:


    " - dat += "Material Amount: [imprinter_materials.total_amount]
    " - dat += "Chemical Volume: [linked_imprinter.reagents.total_volume]
    " - - dat += "
    \ - \ - \ - \ - \ - \ -

    " - - dat += list_categories(linked_imprinter.categories, 4.15) - - if(4.15) - dat += "Main Menu" - dat += "Circuit Imprinter Menu" - dat += "

    Browsing [selected_category]:


    " - dat += "Material Amount: [imprinter_materials.total_amount]
    " - dat += "Chemical Volume: [linked_imprinter.reagents.total_volume]
    " - - var/coeff = linked_imprinter.efficiency_coeff - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] - if(!(selected_category in D.category) || !(D.build_type & IMPRINTER)) - continue - var/temp_materials - var/check_materials = 1 - - var/all_materials = D.materials + D.reagents_list - - for(var/M in all_materials) - temp_materials += " | " - if (!linked_imprinter.check_mat(D, M)) - check_materials = 0 - temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]" - else - temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]" - if (check_materials) - dat += "[D.name][temp_materials]
    " - else - dat += "[D.name][temp_materials]
    " - dat += "
    " - - if(4.17) - dat += "Main Menu" - dat += "Circuit Imprinter Menu" - dat += "

    Search results:


    " - dat += "Material Amount: [imprinter_materials.total_amount]
    " - dat += "Chemical Volume: [linked_imprinter.reagents.total_volume]
    " - - var/coeff = linked_imprinter.efficiency_coeff - for(var/datum/design/D in matching_designs) - var/temp_materials - var/check_materials = 1 - var/all_materials = D.materials + D.reagents_list - for(var/M in all_materials) - temp_materials += " | " - if (!linked_imprinter.check_mat(D, M)) - check_materials = 0 - temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]" - else - temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]" - if (check_materials) - dat += "[D.name][temp_materials]
    " - else - dat += "[D.name][temp_materials]
    " - dat += "
    " - - if(4.2) //Circuit Imprinter Material Storage Sub-menu - dat += "Main Menu" - dat += "Circuit Imprinter Menu" - dat += "Disposal All Chemicals in Storage
    " - dat += "

    Chemical Storage:



    " - for(var/datum/reagent/R in linked_imprinter.reagents.reagent_list) - dat += "[R.name]: [R.volume]" - dat += "Purge
    " - - if(4.3) - dat += "Main Menu" - dat += "Circuit Imprinter Menu
    " - dat += "

    Material Storage:



    " - if(!linked_imprinter) - dat += "ERROR: Protolathe connection failed." - else - for(var/mat_id in imprinter_materials.materials) - var/datum/material/M = imprinter_materials.materials[mat_id] - dat += "* [M.amount] of [M.name]: " - if(M.amount >= MINERAL_MATERIAL_AMOUNT) - dat += "Eject " - if(M.amount >= MINERAL_MATERIAL_AMOUNT*5) - dat += "5x " - if(M.amount >= MINERAL_MATERIAL_AMOUNT) - dat += "All" - dat += "
    " - dat += "
    " - var/datum/browser/popup = new(user, "rndconsole", name, 460, 550) - popup.set_content(dat) + popup.set_content(generate_ui()) popup.open() - return -//helper proc, which return a table containing categories -/obj/machinery/computer/rdconsole/proc/list_categories(list/categories, menu_num as num) - if(!categories) - return +/obj/machinery/computer/rdconsole/proc/tdisk_uple_complete() + tdisk_uple = FALSE + updateUsrDialog() - var/line_length = 1 - var/dat = "" +/obj/machinery/computer/rdconsole/proc/ddisk_uple_complete() + ddisk_uple = FALSE + updateUsrDialog() - for(var/C in categories) - if(line_length > 2) - dat += "" - line_length = 1 +/obj/machinery/computer/rdconsole/proc/eject_disk(type) + if(type == "design") + d_disk.forceMove(get_turf(src)) + d_disk = null + if(type == "tech") + t_disk.forceMove(get_turf(src)) + t_disk = null - dat += "" - line_length++ +/obj/machinery/computer/rdconsole/proc/rescan_views() + var/compare + matching_designs.Cut() + if(searchtype == "proto") + compare = PROTOLATHE + else if(searchtype == "imprint") + compare = IMPRINTER + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] + if(!(D.build_type & compare)) + continue + if(findtext(D.name,searchstring)) + matching_designs.Add(D) - dat += "
    [C]
    " - return dat +/obj/machinery/computer/rdconsole/proc/check_canprint(datum/design/D, buildtype) + var/amount = 50 + if(buildtype == IMPRINTER) + if(!linked_imprinter) + return FALSE + for(var/M in D.materials + D.reagents_list) + amount = min(amount, linked_imprinter.check_mat(D, M)) + if(amount < 1) + return FALSE + else if(buildtype == PROTOLATHE) + if(!linked_lathe) + return FALSE + for(var/M in D.materials + D.reagents_list) + amount = min(amount, linked_lathe.check_mat(D, M)) + if(amount < 1) + return FALSE + else + return FALSE + return amount + +/obj/machinery/computer/rdconsole/proc/lock_console(mob/user) + locked = TRUE + +/obj/machinery/computer/rdconsole/proc/unlock_console(mob/user) + locked = FALSE /obj/machinery/computer/rdconsole/robotics name = "Robotics R&D Console" - desc = "A console used to interface with R&D tools." - id = 2 req_access = null req_access_txt = "29" @@ -1104,10 +946,6 @@ won't update every console in existence) but it's more of a hassle to do. Also, /obj/machinery/computer/rdconsole/core name = "Core R&D Console" - desc = "A console used to interface with R&D tools." - id = 1 /obj/machinery/computer/rdconsole/experiment name = "E.X.P.E.R.I-MENTOR R&D Console" - desc = "A console used to interface with R&D tools." - id = 3 diff --git a/code/modules/research/rdmachines.dm b/code/modules/research/rdmachines.dm index 973a496254..663d3fc806 100644 --- a/code/modules/research/rdmachines.dm +++ b/code/modules/research/rdmachines.dm @@ -3,7 +3,7 @@ //All devices that link into the R&D console fall into thise type for easy identification and some shared procs. -/obj/machinery/r_n_d +/obj/machinery/rnd name = "R&D Device" icon = 'icons/obj/machines/research.dmi' density = TRUE @@ -11,31 +11,35 @@ use_power = IDLE_POWER_USE var/busy = FALSE var/hacked = FALSE - var/disabled = 0 + var/disabled = FALSE var/shocked = FALSE var/obj/machinery/computer/rdconsole/linked_console var/obj/item/loaded_item = null //the item loaded inside the machine (currently only used by experimentor and destructive analyzer) + var/allowed_department_flags = ALL + +/obj/machinery/rnd/proc/reset_busy() + busy = FALSE -/obj/machinery/r_n_d/Initialize() +/obj/machinery/rnd/Initialize() . = ..() - wires = new /datum/wires/r_n_d(src) + wires = new /datum/wires/rnd(src) -/obj/machinery/r_n_d/Destroy() +/obj/machinery/rnd/Destroy() QDEL_NULL(wires) return ..() -/obj/machinery/r_n_d/proc/shock(mob/user, prb) +/obj/machinery/rnd/proc/shock(mob/user, prb) if(stat & (BROKEN|NOPOWER)) // unpowered, no shock - return 0 + return FALSE if(!prob(prb)) - return 0 + return FALSE do_sparks(5, TRUE, src) if (electrocute_mob(user, get_area(src), src, 0.7, TRUE)) - return 1 + return TRUE else - return 0 + return FALSE -/obj/machinery/r_n_d/attack_hand(mob/user) +/obj/machinery/rnd/attack_hand(mob/user) if(shocked) if(shock(user,50)) return @@ -44,10 +48,10 @@ -/obj/machinery/r_n_d/attackby(obj/item/O, mob/user, params) +/obj/machinery/rnd/attackby(obj/item/O, mob/user, params) if (shocked) if(shock(user,50)) - return 1 + return TRUE if (default_deconstruction_screwdriver(user, "[initial(icon_state)]_t", initial(icon_state), O)) if(linked_console) disconnect_console() @@ -56,33 +60,29 @@ return if(default_deconstruction_crowbar(O)) return - if(is_open_container() && O.is_open_container()) - return 0 //inserting reagents into the machine + if(is_refillable() && O.is_drainable()) + return FALSE //inserting reagents into the machine if(Insert_Item(O, user)) - return 1 + return TRUE else return ..() //to disconnect the machine from the r&d console it's linked to -/obj/machinery/r_n_d/proc/disconnect_console() +/obj/machinery/rnd/proc/disconnect_console() linked_console = null -//proc used to handle inserting items or reagents into r_n_d machines -/obj/machinery/r_n_d/proc/Insert_Item(obj/item/I, mob/user) +//proc used to handle inserting items or reagents into rnd machines +/obj/machinery/rnd/proc/Insert_Item(obj/item/I, mob/user) return //whether the machine can have an item inserted in its current state. -/obj/machinery/r_n_d/proc/is_insertion_ready(mob/user) +/obj/machinery/rnd/proc/is_insertion_ready(mob/user) if(panel_open) to_chat(user, "You can't load [src] while it's opened!") return if (disabled) return if (!linked_console) // Try to auto-connect to new RnD consoles nearby. - for(var/obj/machinery/computer/rdconsole/console in oview(3, src)) - if(console.first_use) - console.SyncRDevices() - if(!linked_console) to_chat(user, "[src] must be linked to an R&D console first!") return @@ -98,11 +98,23 @@ if(loaded_item) to_chat(user, "[src] is already loaded.") return - return 1 + return TRUE //we eject the loaded item when deconstructing the machine -/obj/machinery/r_n_d/on_deconstruction() +/obj/machinery/rnd/on_deconstruction() if(loaded_item) loaded_item.forceMove(loc) ..() + +/obj/machinery/rnd/proc/AfterMaterialInsert(type_inserted, id_inserted, amount_inserted) + var/stack_name + if(ispath(type_inserted, /obj/item/ore/bluespace_crystal)) + stack_name = "bluespace" + use_power(MINERAL_MATERIAL_AMOUNT / 10) + else + var/obj/item/stack/S = type_inserted + stack_name = initial(S.name) + use_power(max(1000, (MINERAL_MATERIAL_AMOUNT * amount_inserted / 10))) + add_overlay("protolathe_[stack_name]") + addtimer(CALLBACK(src, /atom/proc/cut_overlay, "protolathe_[stack_name]"), 10) diff --git a/code/modules/research/research.dm b/code/modules/research/research.dm deleted file mode 100644 index 284e9d42e7..0000000000 --- a/code/modules/research/research.dm +++ /dev/null @@ -1,371 +0,0 @@ -/* -General Explination: -The research datum is the "folder" where all the research information is stored in a R&D console. It's also a holder for all the -various procs used to manipulate it. It has four variables and seven procs: - -Variables: -- possible_tech is a list of all the /datum/tech that can potentially be researched by the player. The RefreshResearch() proc -(explained later) only goes through those when refreshing what you know. Generally, possible_tech contains ALL of the existing tech -but it is possible to add tech to the game that DON'T start in it (example: Xeno tech). Generally speaking, you don't want to mess -with these since they should be the default version of the datums. They're actually stored in a list rather then using typesof to -refer to them since it makes it a bit easier to search through them for specific information. -- know_tech is the companion list to possible_tech. It's the tech you can actually research and improve. Until it's added to this -list, it can't be improved. All the tech in this list are visible to the player. -- possible_designs is functionally identical to possbile_tech except it's for /datum/design. -- known_designs is functionally identical to known_tech except it's for /datum/design - -Procs: -- TechHasReqs: Used by other procs (specifically RefreshResearch) to see whether all of a tech's requirements are currently in -known_tech and at a high enough level. -- DesignHasReqs: Same as TechHasReqs but for /datum/design and known_design. -- AddTech2Known: Adds a /datum/tech to known_tech. It checks to see whether it already has that tech (if so, it just replaces it). If -it doesn't have it, it adds it. Note: It does NOT check possible_tech at all. So if you want to add something strange to it (like -a player made tech?) you can. -- AddDesign2Known: Same as AddTech2Known except for /datum/design and known_designs. -- RefreshResearch: This is the workhorse of the R&D system. It updates the /datum/research holder and adds any unlocked tech paths -and designs you have reached the requirements for. It only checks through possible_tech and possible_designs, however, so it won't -accidentally add "secret" tech to it. -- UpdateTech is used as part of the actual researching process. It takes an ID and finds techs with that same ID in known_tech. When -it finds it, it checks to see whether it can improve it at all. If the known_tech's level is less then or equal to -the inputted level, it increases the known tech's level to the inputted level -1 or know tech's level +1 (whichever is higher). - -The tech datums are the actual "tech trees" that you improve through researching. Each one has five variables: -- Name: Pretty obvious. This is often viewable to the players. -- Desc: Pretty obvious. Also player viewable. -- ID: This is the unique ID of the tech that is used by the various procs to find and/or maniuplate it. -- Level: This is the current level of the tech. All techs start at 1 and have a max of 20. Devices and some techs require a certain -level in specific techs before you can produce them. -- Req_tech: This is a list of the techs required to unlock this tech path. If left blank, it'll automatically be loaded into the -research holder datum. - -*/ -/*************************************************************** -** Master Types ** -** Includes all the helper procs and basic tech processing. ** -***************************************************************/ - -/datum/research //Holder for all the existing, archived, and known tech. Individual to console. - - //Datum/tech go here. - var/list/possible_tech = list() //List of all tech in the game that players have access to (barring special events). - var/list/known_tech = list() //List of locally known tech. - var/list/possible_designs = list() //List of all designs. - var/list/known_designs = list() //List of available designs. - -/datum/research/New() //Insert techs into possible_tech here. Known_tech automatically updated. - for(var/T in subtypesof(/datum/tech)) - possible_tech += new T(src) - for(var/D in subtypesof(/datum/design)) - possible_designs += new D(src) - RefreshResearch() - -//Checks to see if tech has all the required pre-reqs. -//Input: datum/tech; Output: 0/1 (false/true) -/datum/research/proc/TechHasReqs(datum/tech/T) - if(T.req_tech.len == 0) - return TRUE - for(var/req in T.req_tech) - var/datum/tech/known = known_tech[req] - if(!known || known.level < T.req_tech[req]) - return FALSE - return TRUE - -//Checks to see if design has all the required pre-reqs. -//Input: datum/design; Output: 0/1 (false/true) -/datum/research/proc/DesignHasReqs(datum/design/D)//Heavily optimized -Sieve - if(D.req_tech.len == 0) - return TRUE - for(var/req in D.req_tech) - var/datum/tech/known = known_tech[req] - if(!known || known.level < D.req_tech[req]) - return FALSE - return TRUE - -//Adds a tech to known_tech list. Checks to make sure there aren't duplicates and updates existing tech's levels if needed. -//Input: datum/tech; Output: Null -/datum/research/proc/AddTech2Known(datum/tech/T) - if(!T) - return - if(known_tech[T.id]) - var/datum/tech/known = known_tech[T.id] - if(T.level > known.level) - known.level = T.level - return - known_tech[T.id] = T.copy() - -/datum/research/proc/AddDesign2Known(datum/design/D) - if(known_designs[D.id]) - return - known_designs[D.id] = D - -//Refreshes known_tech and known_designs list. -//Input/Output: n/a -/datum/research/proc/RefreshResearch() - for(var/datum/tech/PT in possible_tech) - if(TechHasReqs(PT)) - AddTech2Known(PT) - - for(var/datum/design/PD in possible_designs) - if(DesignHasReqs(PD)) - AddDesign2Known(PD) - - for(var/v in known_tech) - var/datum/tech/T = known_tech[v] - T.level = Clamp(T.level, 0, 20) - return - -//Refreshes the levels of a given tech. -//Input: Tech's ID and Level; Output: null -/datum/research/proc/UpdateTech(ID, level) - var/datum/tech/KT = known_tech[ID] - if(KT && KT.level <= level) - KT.level = max(KT.level + 1, level) - SSblackbox.log_research(KT.name, level) - -//Checks if the origin level can raise current tech levels -//Input: Tech's ID and Level; Output: TRUE for yes, FALSE for no -/datum/research/proc/IsTechHigher(ID, level) - var/datum/tech/KT = known_tech[ID] - if(KT) - if(KT.level <= level) - return TRUE - else - return FALSE - -/datum/research/proc/FindDesignByID(id) - return known_designs[id] - -/datum/research/proc/LowerTech(tech_id,value) - var/datum/tech/T = known_tech[tech_id] - T.level = max(initial(T.level),T.level - value) - known_designs.Cut() - RefreshResearch() - - -//Autolathe files -/datum/research/autolathe/New() - for(var/T in (subtypesof(/datum/tech))) - possible_tech += new T(src) - for(var/path in subtypesof(/datum/design)) - var/datum/design/D = new path(src) - possible_designs += D - if((D.build_type & AUTOLATHE) && ("initial" in D.category)) //autolathe starts without hacked designs - AddDesign2Known(D) - -//Limb Grower files -/datum/research/limbgrower/New() - for(var/T in (subtypesof(/datum/tech))) - possible_tech += new T(src) - for(var/path in subtypesof(/datum/design)) - var/datum/design/D = new path(src) - possible_designs += D - if((D.build_type & LIMBGROWER) && ("initial" in D.category)) - AddDesign2Known(D) - -/datum/research/autolathe/AddDesign2Known(datum/design/D) - if(!(D.build_type & AUTOLATHE)) - return - ..() - -//Biogenerator files -/datum/research/biogenerator/New() - for(var/T in (subtypesof(/datum/tech))) - possible_tech += new T(src) - for(var/path in subtypesof(/datum/design)) - var/datum/design/D = new path(src) - possible_designs += D - if((D.build_type & BIOGENERATOR) && ("initial" in D.category)) - AddDesign2Known(D) - -/datum/research/biogenerator/AddDesign2Known(datum/design/D) - if(!(D.build_type & BIOGENERATOR)) - return - ..() - -//Smelter files -/datum/research/smelter/New() - for(var/T in (subtypesof(/datum/tech))) - possible_tech += new T(src) - for(var/path in subtypesof(/datum/design)) - var/datum/design/D = new path(src) - possible_designs += D - if((D.build_type & SMELTER) && ("initial" in D.category)) - AddDesign2Known(D) - -/datum/research/smelter/AddDesign2Known(datum/design/D) - if(!(D.build_type & SMELTER)) - return - ..() - - -/*************************************************************** -** Technology Datums ** -** Includes all the various technoliges and what they make. ** -***************************************************************/ - -/datum/tech //Datum of individual technologies. - var/name = "name" //Name of the technology. - var/desc = "description" //General description of what it does and what it makes. - var/id = "id" //An easily referenced ID. Must be alphanumeric, lower-case, and no symbols. - var/level = 1 //A simple number scale of the research level. Level 0 = Secret tech. - var/rare = 1 //How much CentCom wants to get that tech. Used in supply shuttle tech cost calculation. - var/list/req_tech = list() //List of ids associated values of techs required to research this tech. "id" = # - - -//Trunk Technologies (don't require any other techs and you start knowning them). - -/datum/tech/materials - name = "Materials Research" - desc = "Development of new and improved materials." - id = "materials" - -/datum/tech/engineering - name = "Engineering Research" - desc = "Development of new and improved engineering parts and tools." - id = "engineering" - -/datum/tech/plasmatech - name = "Plasma Research" - desc = "Research into the mysterious substance colloquially known as \"plasma\"." - id = "plasmatech" - rare = 3 - -/datum/tech/powerstorage - name = "Power Manipulation Technology" - desc = "The various technologies behind the storage and generation of electricity." - id = "powerstorage" - -/datum/tech/bluespace - name = "\"Blue-space\" Research" - desc = "Research into the sub-reality known as \"blue-space\"." - id = "bluespace" - rare = 2 - -/datum/tech/biotech - name = "Biological Technology" - desc = "Research into the deeper mysteries of life and organic substances." - id = "biotech" - -/datum/tech/combat - name = "Combat Systems Research" - desc = "The development of offensive and defensive systems." - id = "combat" - -/datum/tech/magnets - name = "Electromagnetic Spectrum Research" - desc = "Research into the electromagnetic spectrum. No clue how they actually work, though." - id = "magnets" - -/datum/tech/programming - name = "Data Theory Research" - desc = "The development of new computer and artificial intelligence and data storage systems." - id = "programming" - -/datum/tech/syndicate - name = "Illegal Technologies Research" - desc = "The study of technologies that violate Nanotrasen regulations." - id = "syndicate" - rare = 4 - - -//Secret Technologies (hidden by default, require rare items to reveal) - -/datum/tech/abductor - name = "Alien Technologies Research" - desc = "The study of technologies used by the advanced alien race known as Abductors." - id = "abductor" - rare = 5 - level = 0 - -/datum/tech/arcane - name = "Arcane Research" - desc = "When sufficiently analyzed, any magic becomes indistinguishable from technology." - id = "arcane" - rare = 5 - level = 0 - -/* -//Branch Techs -/datum/tech/explosives - name = "Explosives Research" - desc = "The creation and application of explosive materials." - id = "explosives" - req_tech = list("materials" = 3) - -/datum/tech/generators - name = "Power Generation Technology" - desc = "Research into more powerful and more reliable sources." - id = "generators" - req_tech = list("powerstorage" = 2) - -/datum/tech/robotics - name = "Robotics Technology" - desc = "The development of advanced automated, autonomous machines." - id = "robotics" - req_tech = list("materials" = 3, "programming" = 3) -*/ - - -/datum/tech/proc/getCost(var/current_level = null) - // Calculates tech disk's supply points sell cost - if(!current_level) - current_level = initial(level) - - if(current_level >= level) - return 0 - - var/cost = 0 - for(var/i=current_level+1, i<=level, i++) - if(i == initial(level)) - continue - cost += i*rare - - return cost - -/datum/tech/proc/copy() - var/datum/tech/T = new type() - T.level = level - return T - -/obj/item/disk/tech_disk - name = "technology disk" - desc = "A disk for storing technology data for further research." - icon_state = "datadisk0" - materials = list(MAT_METAL=300, MAT_GLASS=100) - var/list/tech_stored = list() - var/max_tech_stored = 1 - -/obj/item/disk/tech_disk/Initialize() - . = ..() - pixel_x = rand(-5, 5) - pixel_y = rand(-5, 5) - for(var/i in 1 to max_tech_stored) - tech_stored += null - - -/obj/item/disk/tech_disk/adv - name = "advanced technology disk" - desc = "A disk for storing technology data for further research. This one has extra storage space." - materials = list(MAT_METAL=300, MAT_GLASS=100, MAT_SILVER=50) - max_tech_stored = 5 - -/obj/item/disk/tech_disk/super_adv - name = "quantum technology disk" - desc = "A disk for storing technology data for further research. This one has extremely large storage space." - materials = list(MAT_METAL=300, MAT_GLASS=100, MAT_SILVER=100, MAT_GOLD=100) - max_tech_stored = 10 - -/obj/item/disk/tech_disk/debug - name = "\improper CentCom technology disk" - desc = "A debug item for research." - materials = list() - max_tech_stored = 0 - -/obj/item/disk/tech_disk/debug/Initialize() - . = ..() - var/list/techs = subtypesof(/datum/tech) - max_tech_stored = techs.len - for(var/V in techs) - var/datum/tech/T = new V() - tech_stored += T - T.level = 8 diff --git a/code/modules/research/research_disk.dm b/code/modules/research/research_disk.dm new file mode 100644 index 0000000000..ac06bbdbd5 --- /dev/null +++ b/code/modules/research/research_disk.dm @@ -0,0 +1,22 @@ + +/obj/item/disk/tech_disk + name = "technology disk" + desc = "A disk for storing technology data for further research." + icon_state = "datadisk0" + materials = list(MAT_METAL=300, MAT_GLASS=100) + var/datum/techweb/stored_research + +/obj/item/disk/tech_disk/Initialize() + . = ..() + pixel_x = rand(-5, 5) + pixel_y = rand(-5, 5) + stored_research = new /datum/techweb + +/obj/item/disk/tech_disk/debug + name = "centcomm technology disk" + desc = "A debug item for research" + materials = list() + +/obj/item/disk/tech_disk/debug/Initialize() + . = ..() + stored_research = new /datum/techweb/admin diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm index 9a59e63e18..8a244bcea1 100644 --- a/code/modules/research/server.dm +++ b/code/modules/research/server.dm @@ -1,99 +1,65 @@ -/obj/machinery/r_n_d/server +/obj/machinery/rnd/server name = "\improper R&D Server" desc = "A computer system running a deep neural network that processes arbitrary information to produce data useable in the development of new technologies. In layman's terms, it makes research points." icon = 'icons/obj/machines/research.dmi' icon_state = "server" - var/datum/research/files + var/datum/techweb/stored_research var/heat_health = 100 - var/list/id_with_upload = list() //List of R&D consoles with upload to server access. - var/list/id_with_download = list() //List of R&D consoles with download from server access. - var/id_with_upload_string = "" //String versions for easy editing in map editor. - var/id_with_download_string = "" + //Code for point mining here. + var/working = TRUE //temperature should break it. var/server_id = 0 + var/base_mining_income = 2 var/heat_gen = 100 var/heating_power = 40000 - var/delay = 10 + var/delay = 5 + var/temp_tolerance_low = 0 + var/temp_tolerance_high = T20C + var/temp_penalty_coefficient = 0.5 //1 = -1 points per degree above high tolerance. 0.5 = -0.5 points per degree above high tolerance. req_access = list(ACCESS_RD) //ONLY THE R&D CAN CHANGE SERVER SETTINGS. -/obj/machinery/r_n_d/server/Initialize() +/obj/machinery/rnd/server/Initialize() . = ..() + SSresearch.servers |= src + stored_research = SSresearch.science_tech var/obj/item/circuitboard/machine/B = new /obj/item/circuitboard/machine/rdserver(null) B.apply_default_parts(src) -/obj/machinery/r_n_d/server/Destroy() - griefProtection() +/obj/machinery/rnd/server/Destroy() + SSresearch.servers -= src return ..() -/obj/machinery/r_n_d/server/RefreshParts() +/obj/machinery/rnd/server/RefreshParts() var/tot_rating = 0 for(var/obj/item/stock_parts/SP in src) tot_rating += SP.rating heat_gen /= max(1, tot_rating) -/obj/machinery/r_n_d/server/Initialize(mapload) - . = ..() - if(!files) - files = new /datum/research(src) - var/list/temp_list - if(!id_with_upload.len) - temp_list = list() - temp_list = splittext(id_with_upload_string, ";") - for(var/N in temp_list) - id_with_upload += text2num(N) - if(!id_with_download.len) - temp_list = list() - temp_list = splittext(id_with_download_string, ";") - for(var/N in temp_list) - id_with_download += text2num(N) - -/obj/machinery/r_n_d/server/process() - var/datum/gas_mixture/environment = loc.return_air() - switch(environment.temperature) - if(0 to T0C) - heat_health = min(100, heat_health + 1) - if(T0C to (T20C + 20)) - heat_health = Clamp(heat_health, 0, 100) - if((T20C + 20) to (T0C + 70)) - heat_health = max(0, heat_health - 1) - if(heat_health <= 0) - /*griefProtection() This seems to get called twice before running any code that deletes/damages the server or it's files anwyay. - refreshParts and the hasReq procs that get called by this are laggy and do not need to be called by every server on the map every tick */ - var/updateRD = 0 - files.known_designs = list() - for(var/v in files.known_tech) - var/datum/tech/T = files.known_tech[v] - if(prob(1)) - updateRD++ - T.level-- - if(updateRD) - files.RefreshResearch() - if(delay) - delay-- +/obj/machinery/rnd/server/proc/refresh_working() + if(stat & EMPED) + working = FALSE else - produce_heat(heat_gen) - delay = initial(delay) + working = TRUE +/obj/machinery/rnd/server/emp_act() + stat |= EMPED + addtimer(CALLBACK(src, .proc/unemp), 600) + refresh_working() + return ..() -/obj/machinery/r_n_d/server/emp_act(severity) - griefProtection() - ..() +/obj/machinery/rnd/server/proc/unemp() + stat &= ~EMPED + refresh_working() -/obj/machinery/r_n_d/server/ex_act(severity, target) - griefProtection() - ..() +/obj/machinery/rnd/server/proc/mine() + . = base_mining_income + var/penalty = max((get_env_temp() - temp_tolerance_low), 0) / temp_penalty_coefficient + . = max(. - penalty, 0) -//Backup files to centcom to help admins recover data after greifer attacks -/obj/machinery/r_n_d/server/proc/griefProtection() - for(var/obj/machinery/r_n_d/server/centcom/C in GLOB.machines) - for(var/v in files.known_tech) - var/datum/tech/T = files.known_tech[v] - C.files.AddTech2Known(T) - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] - C.files.AddDesign2Known(D) - C.files.RefreshResearch() +/obj/machinery/rnd/server/proc/get_env_temp() + var/datum/gas_mixture/environment = loc.return_air() + return environment.temperature -/obj/machinery/r_n_d/server/proc/produce_heat(heat_amt) +/obj/machinery/rnd/server/proc/produce_heat(heat_amt) if(!(stat & (NOPOWER|BROKEN))) //Blatently stolen from space heater. var/turf/L = loc if(istype(L)) @@ -114,30 +80,17 @@ env.merge(removed) air_update_turf() -//called when the server is deconstructed. -/obj/machinery/r_n_d/server/on_deconstruction() - griefProtection() - ..() - -/obj/machinery/r_n_d/server/attack_hand(mob/user as mob) // I guess only exists to stop ninjas or hell does it even work I dunno. See also ninja gloves. +/obj/machinery/rnd/server/attack_hand(mob/user as mob) // I guess only exists to stop ninjas or hell does it even work I dunno. See also ninja gloves. if (disabled) return if (shocked) shock(user,50) return -/obj/machinery/r_n_d/server/centcom - name = "CentCom Central R&D Database" - server_id = -1 - -/obj/machinery/r_n_d/server/centcom/Initialize() - . = ..() - fix_noid_research_servers() - /proc/fix_noid_research_servers() var/list/no_id_servers = list() var/list/server_ids = list() - for(var/obj/machinery/r_n_d/server/S in GLOB.machines) + for(var/obj/machinery/rnd/server/S in GLOB.machines) switch(S.server_id) if(-1) continue @@ -146,7 +99,7 @@ else server_ids += S.server_id - for(var/obj/machinery/r_n_d/server/S in no_id_servers) + for(var/obj/machinery/rnd/server/S in no_id_servers) var/num = 1 while(!S.server_id) if(num in server_ids) @@ -156,9 +109,6 @@ server_ids += num no_id_servers -= S -/obj/machinery/r_n_d/server/centcom/process() - return PROCESS_KILL //don't need process() - /obj/machinery/computer/rdservercontrol name = "R&D Server Controller" @@ -166,7 +116,7 @@ icon_screen = "rdcomp" icon_keyboard = "rd_key" var/screen = 0 - var/obj/machinery/r_n_d/server/temp_server + var/obj/machinery/rnd/server/temp_server var/list/servers = list() var/list/consoles = list() var/badmin = 0 @@ -185,58 +135,6 @@ if(href_list["main"]) screen = 0 - else if(href_list["access"] || href_list["data"] || href_list["transfer"]) - temp_server = null - consoles = list() - servers = list() - for(var/obj/machinery/r_n_d/server/S in GLOB.machines) - if(S.server_id == text2num(href_list["access"]) || S.server_id == text2num(href_list["data"]) || S.server_id == text2num(href_list["transfer"])) - temp_server = S - break - if(href_list["access"]) - screen = 1 - for(var/obj/machinery/computer/rdconsole/C in GLOB.machines) - if(C.sync) - consoles += C - else if(href_list["data"]) - screen = 2 - else if(href_list["transfer"]) - screen = 3 - for(var/obj/machinery/r_n_d/server/S in GLOB.machines) - if(S == src) - continue - servers += S - - else if(href_list["upload_toggle"]) - var/num = text2num(href_list["upload_toggle"]) - if(num in temp_server.id_with_upload) - temp_server.id_with_upload -= num - else - temp_server.id_with_upload += num - - else if(href_list["download_toggle"]) - var/num = text2num(href_list["download_toggle"]) - if(num in temp_server.id_with_download) - temp_server.id_with_download -= num - else - temp_server.id_with_download += num - - else if(href_list["reset_tech"]) - var/choice = alert("Technology Data Reset", "Are you sure you want to reset this technology to its default data? Data lost cannot be recovered.", "Continue", "Cancel") - if(choice == "Continue" && usr.canUseTopic(src)) - var/datum/tech/T = temp_server.files.known_tech[href_list["reset_tech"]] - if(T) - T.level = 1 - temp_server.files.RefreshResearch() - - else if(href_list["reset_design"]) - var/choice = alert("Design Data Deletion", "Are you sure you want to delete this design? Data lost cannot be recovered.", "Continue", "Cancel") - if(choice == "Continue" && usr.canUseTopic(src)) - var/datum/design/D = temp_server.files.known_designs[href_list["reset_design"]] - if(D) - temp_server.files.known_designs -= D.id - temp_server.files.RefreshResearch() - updateUsrDialog() return @@ -250,58 +148,12 @@ if(0) //Main Menu dat += "Connected Servers:

    " - for(var/obj/machinery/r_n_d/server/S in GLOB.machines) - if(istype(S, /obj/machinery/r_n_d/server/centcom) && !badmin) - continue + for(var/obj/machinery/rnd/server/S in GLOB.machines) dat += "[S.name] || " - dat += "Access Rights | " - dat += "Data Management" - if(badmin) - dat += " | Server-to-Server Transfer" dat += "
    " - if(1) //Access rights menu - dat += "[temp_server.name] Access Rights

    " - dat += "Consoles with Upload Access
    " - for(var/obj/machinery/computer/rdconsole/C in consoles) - var/turf/console_turf = get_turf(C) - dat += "* [console_turf.loc]" //FYI, these are all numeric ids, eventually. - if(C.id in temp_server.id_with_upload) - dat += " (Remove)
    " - else - dat += " (Add)
    " - dat += "Consoles with Download Access
    " - for(var/obj/machinery/computer/rdconsole/C in consoles) - var/turf/console_turf = get_turf(C) - dat += "* [console_turf.loc]" - if(C.id in temp_server.id_with_download) - dat += " (Remove)
    " - else - dat += " (Add)
    " - dat += "
    Main Menu" + //Mining status here - if(2) //Data Management menu - dat += "[temp_server.name] Data ManagementP

    " - dat += "Known Technologies
    " - for(var/v in temp_server.files.known_tech) - var/datum/tech/T = temp_server.files.known_tech[v] - if(T.level <= 0) - continue - dat += "* [T.name] " - dat += "(Reset)
    " //FYI, these are all strings. - dat += "Known Designs
    " - for(var/v in temp_server.files.known_designs) - var/datum/design/D = temp_server.files.known_designs[v] - dat += "* [D.name] " - dat += "(Delete)
    " - dat += "
    Main Menu" - - if(3) //Server Data Transfer - dat += "[temp_server.name] Server to Server Transfer

    " - dat += "Send Data to what server?
    " - for(var/obj/machinery/r_n_d/server/S in servers) - dat += "[S.name] (Transfer)
    " - dat += "
    Main Menu" user << browse("R&D Server Control
    [dat]", "window=server_control;size=575x400") onclose(user, "server_control") return @@ -317,15 +169,3 @@ emagged = TRUE to_chat(user, "You you disable the security protocols.") -/obj/machinery/r_n_d/server/robotics - name = "Robotics R&D Server" - id_with_upload_string = "1;2" - id_with_download_string = "1;2" - server_id = 2 - - -/obj/machinery/r_n_d/server/core - name = "Core R&D Server" - id_with_upload_string = "1" - id_with_download_string = "1" - server_id = 1 diff --git a/code/modules/research/stock_parts.dm b/code/modules/research/stock_parts.dm index 794c975b46..af1dc853d8 100644 --- a/code/modules/research/stock_parts.dm +++ b/code/modules/research/stock_parts.dm @@ -82,39 +82,35 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi //Rating 1 + /obj/item/stock_parts/capacitor name = "capacitor" desc = "A basic capacitor used in the construction of a variety of devices." icon_state = "capacitor" - origin_tech = "powerstorage=1" materials = list(MAT_METAL=50, MAT_GLASS=50) /obj/item/stock_parts/scanning_module name = "scanning module" desc = "A compact, high resolution scanning module used in the construction of certain devices." icon_state = "scan_module" - origin_tech = "magnets=1" materials = list(MAT_METAL=50, MAT_GLASS=20) /obj/item/stock_parts/manipulator name = "micro-manipulator" desc = "A tiny little manipulator used in the construction of certain devices." icon_state = "micro_mani" - origin_tech = "materials=1;programming=1" materials = list(MAT_METAL=30) /obj/item/stock_parts/micro_laser name = "micro-laser" desc = "A tiny laser used in certain devices." icon_state = "micro_laser" - origin_tech = "magnets=1" materials = list(MAT_METAL=10, MAT_GLASS=20) /obj/item/stock_parts/matter_bin name = "matter bin" desc = "A container designed to hold compressed matter awaiting reconstruction." icon_state = "matter_bin" - origin_tech = "materials=1" materials = list(MAT_METAL=80) //Rating 2 @@ -123,7 +119,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "advanced capacitor" desc = "An advanced capacitor used in the construction of a variety of devices." icon_state = "adv_capacitor" - origin_tech = "powerstorage=3" rating = 2 materials = list(MAT_METAL=50, MAT_GLASS=50) @@ -131,7 +126,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "advanced scanning module" desc = "A compact, high resolution scanning module used in the construction of certain devices." icon_state = "adv_scan_module" - origin_tech = "magnets=3" rating = 2 materials = list(MAT_METAL=50, MAT_GLASS=20) @@ -139,7 +133,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "nano-manipulator" desc = "A tiny little manipulator used in the construction of certain devices." icon_state = "nano_mani" - origin_tech = "materials=3;programming=2" rating = 2 materials = list(MAT_METAL=30) @@ -147,7 +140,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "high-power micro-laser" desc = "A tiny laser used in certain devices." icon_state = "high_micro_laser" - origin_tech = "magnets=3" rating = 2 materials = list(MAT_METAL=10, MAT_GLASS=20) @@ -155,7 +147,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "advanced matter bin" desc = "A container designed to hold compressed matter awaiting reconstruction." icon_state = "advanced_matter_bin" - origin_tech = "materials=3" rating = 2 materials = list(MAT_METAL=80) @@ -165,7 +156,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "super capacitor" desc = "A super-high capacity capacitor used in the construction of a variety of devices." icon_state = "super_capacitor" - origin_tech = "powerstorage=4;engineering=4" rating = 3 materials = list(MAT_METAL=50, MAT_GLASS=50) @@ -173,7 +163,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "phasic scanning module" desc = "A compact, high resolution phasic scanning module used in the construction of certain devices." icon_state = "super_scan_module" - origin_tech = "magnets=4;engineering=4" rating = 3 materials = list(MAT_METAL=50, MAT_GLASS=20) @@ -181,7 +170,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "pico-manipulator" desc = "A tiny little manipulator used in the construction of certain devices." icon_state = "pico_mani" - origin_tech = "materials=4;programming=4;engineering=4" rating = 3 materials = list(MAT_METAL=30) @@ -189,7 +177,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "ultra-high-power micro-laser" icon_state = "ultra_high_micro_laser" desc = "A tiny laser used in certain devices." - origin_tech = "magnets=4;engineering=4" rating = 3 materials = list(MAT_METAL=10, MAT_GLASS=20) @@ -197,7 +184,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "super matter bin" desc = "A container designed to hold compressed matter awaiting reconstruction." icon_state = "super_matter_bin" - origin_tech = "materials=4;engineering=4" rating = 3 materials = list(MAT_METAL=80) @@ -207,7 +193,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "quadratic capacitor" desc = "An capacity capacitor used in the construction of a variety of devices." icon_state = "quadratic_capacitor" - origin_tech = "powerstorage=5;materials=4;engineering=4" rating = 4 materials = list(MAT_METAL=50, MAT_GLASS=50) @@ -215,7 +200,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "triphasic scanning module" desc = "A compact, ultra resolution triphasic scanning module used in the construction of certain devices." icon_state = "triphasic_scan_module" - origin_tech = "magnets=5;materials=4;engineering=4" rating = 4 materials = list(MAT_METAL=50, MAT_GLASS=20) @@ -223,7 +207,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "femto-manipulator" desc = "A tiny little manipulator used in the construction of certain devices." icon_state = "femto_mani" - origin_tech = "materials=6;programming=4;engineering=4" rating = 4 materials = list(MAT_METAL=30) @@ -231,7 +214,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "quad-ultra micro-laser" icon_state = "quadultra_micro_laser" desc = "A tiny laser used in certain devices." - origin_tech = "magnets=5;materials=4;engineering=4" rating = 4 materials = list(MAT_METAL=10, MAT_GLASS=20) @@ -239,7 +221,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "bluespace matter bin" desc = "A container designed to hold compressed matter awaiting reconstruction." icon_state = "bluespace_matter_bin" - origin_tech = "materials=6;programming=4;engineering=4" rating = 4 materials = list(MAT_METAL=80) @@ -249,49 +230,42 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "subspace ansible" icon_state = "subspace_ansible" desc = "A compact module capable of sensing extradimensional activity." - origin_tech = "programming=2;magnets=2;materials=2;bluespace=1" materials = list(MAT_METAL=30, MAT_GLASS=10) /obj/item/stock_parts/subspace/filter name = "hyperwave filter" icon_state = "hyperwave_filter" desc = "A tiny device capable of filtering and converting super-intense radiowaves." - origin_tech = "programming=2;magnets=2" materials = list(MAT_METAL=30, MAT_GLASS=10) /obj/item/stock_parts/subspace/amplifier name = "subspace amplifier" icon_state = "subspace_amplifier" desc = "A compact micro-machine capable of amplifying weak subspace transmissions." - origin_tech = "programming=2;magnets=2;materials=2;bluespace=2" materials = list(MAT_METAL=30, MAT_GLASS=10) /obj/item/stock_parts/subspace/treatment name = "subspace treatment disk" icon_state = "treatment_disk" desc = "A compact micro-machine capable of stretching out hyper-compressed radio waves." - origin_tech = "programming=2;magnets=2;materials=2;bluespace=2" materials = list(MAT_METAL=30, MAT_GLASS=10) /obj/item/stock_parts/subspace/analyzer name = "subspace wavelength analyzer" icon_state = "wavelength_analyzer" desc = "A sophisticated analyzer capable of analyzing cryptic subspace wavelengths." - origin_tech = "programming=2;magnets=2;materials=2;bluespace=2" materials = list(MAT_METAL=30, MAT_GLASS=10) /obj/item/stock_parts/subspace/crystal name = "ansible crystal" icon_state = "ansible_crystal" desc = "A crystal made from pure glass used to transmit laser databursts to subspace." - origin_tech = "magnets=2;materials=2;bluespace=2;plasmatech=2" materials = list(MAT_GLASS=50) /obj/item/stock_parts/subspace/transmitter name = "subspace transmitter" icon_state = "subspace_transmitter" desc = "A large piece of equipment used to open a window into the subspace dimension." - origin_tech = "magnets=2;materials=2;bluespace=2" materials = list(MAT_METAL=50) /obj/item/research//Makes testing much less of a pain -Sieve @@ -299,4 +273,3 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi icon = 'icons/obj/stock_parts.dmi' icon_state = "capacitor" desc = "A debug item for research." - origin_tech = "materials=8;programming=8;magnets=8;powerstorage=8;bluespace=8;combat=8;biotech=8;syndicate=8;engineering=8;plasmatech=8;abductor=8" diff --git a/code/modules/research/techweb/__techweb_helpers.dm b/code/modules/research/techweb/__techweb_helpers.dm new file mode 100644 index 0000000000..adfa5c78d0 --- /dev/null +++ b/code/modules/research/techweb/__techweb_helpers.dm @@ -0,0 +1,178 @@ + +/proc/initialize_all_techweb_nodes(clearall = FALSE) + if(islist(SSresearch.techweb_nodes) && clearall) + QDEL_LIST(SSresearch.techweb_nodes) + if(islist(SSresearch.techweb_nodes_starting && clearall)) + QDEL_LIST(SSresearch.techweb_nodes_starting) + var/list/returned = list() + for(var/path in subtypesof(/datum/techweb_node)) + var/datum/techweb_node/TN = path + if(isnull(initial(TN.id))) + continue + TN = new path + if(returned[initial(TN.id)]) + stack_trace("WARNING: Techweb node ID clash with ID [initial(TN.id)] detected!") + SSresearch.errored_datums[TN] = initial(TN.id) + continue + returned[initial(TN.id)] = TN + if(TN.starting_node) + SSresearch.techweb_nodes_starting[TN.id] = TN + SSresearch.techweb_nodes = returned + verify_techweb_nodes() //Verify all nodes have ids and such. + calculate_techweb_nodes() + calculate_techweb_boost_list() + verify_techweb_nodes() //Verify nodes and designs have been crosslinked properly. + +/proc/initialize_all_techweb_designs(clearall = FALSE) + if(islist(SSresearch.techweb_designs) && clearall) + QDEL_LIST(SSresearch.techweb_designs) + var/list/returned = list() + for(var/path in subtypesof(/datum/design)) + var/datum/design/DN = path + if(isnull(initial(DN.id))) + stack_trace("WARNING: Design with null ID detected. Build path: [initial(DN.build_path)]") + continue + else if(initial(DN.id) == DESIGN_ID_IGNORE) + continue + DN = new path + if(returned[initial(DN.id)]) + stack_trace("WARNING: Design ID clash with ID [initial(DN.id)] detected!") + SSresearch.errored_datums[DN] = initial(DN.id) + continue + returned[initial(DN.id)] = DN + SSresearch.techweb_designs = returned + verify_techweb_designs() + +/proc/count_unique_techweb_nodes() + var/static/list/L = typesof(/datum/techweb_node) + return L.len + +/proc/count_unique_techweb_designs() + var/static/list/L = typesof(/datum/design) + return L.len + +/proc/get_techweb_node_by_id(id) + if(SSresearch.techweb_nodes[id]) + return SSresearch.techweb_nodes[id] + +/proc/get_techweb_design_by_id(id) + if(SSresearch.techweb_designs[id]) + return SSresearch.techweb_designs[id] + +/proc/research_node_id_error(id) + if(SSresearch.invalid_node_ids[id]) + SSresearch.invalid_node_ids[id]++ + else + SSresearch.invalid_node_ids[id] = 1 + +/proc/design_id_error(id) + if(SSresearch.invalid_design_ids[id]) + SSresearch.invalid_design_ids[id]++ + else + SSresearch.invalid_design_ids[id] = 1 + +/proc/node_boost_error(id, message) + SSresearch.invalid_node_boost[id] = message + +/proc/verify_techweb_nodes() + for(var/n in SSresearch.techweb_nodes) + var/datum/techweb_node/N = SSresearch.techweb_nodes[n] + if(!istype(N)) + stack_trace("WARNING: Invalid research node with ID [n] detected and removed.") + SSresearch.techweb_nodes -= n + research_node_id_error(n) + for(var/p in N.prereq_ids) + var/datum/techweb_node/P = SSresearch.techweb_nodes[p] + if(!istype(P)) + stack_trace("WARNING: Invalid research prerequisite node with ID [p] detected in node [N.display_name]\[[N.id]\] removed.") + N.prereq_ids -= p + research_node_id_error(p) + for(var/d in N.design_ids) + var/datum/design/D = SSresearch.techweb_designs[d] + if(!istype(D)) + stack_trace("WARNING: Invalid research design with ID [d] detected in node [N.display_name]\[[N.id]\] removed.") + N.designs -= d + design_id_error(d) + for(var/p in N.prerequisites) + var/datum/techweb_node/P = N.prerequisites[p] + if(!istype(P)) + stack_trace("WARNING: Invalid research prerequisite node with ID [p] detected in node [N.display_name]\[[N.id]\] removed.") + N.prerequisites -= p + research_node_id_error(p) + for(var/u in N.unlocks) + var/datum/techweb_node/U = N.unlocks[u] + if(!istype(U)) + stack_trace("WARNING: Invalid research unlock node with ID [u] detected in node [N.display_name]\[[N.id]\] removed.") + N.unlocks -= u + research_node_id_error(u) + for(var/d in N.designs) + var/datum/design/D = N.designs[d] + if(!istype(D)) + stack_trace("WARNING: Invalid research design with ID [d] detected in node [N.display_name]\[[N.id]\] removed.") + N.designs -= d + design_id_error(d) + for(var/p in N.boost_item_paths) + if(!ispath(p)) + N.boost_item_paths -= p + node_boost_error(N.id, "[p] is not a valid path.") + var/num = N.boost_item_paths[p] + if(!isnum(num)) + N.boost_item_paths -= p + node_boost_error(N.id, "[num] is not a valid number.") + CHECK_TICK + +/proc/verify_techweb_designs() + for(var/d in SSresearch.techweb_designs) + var/datum/design/D = SSresearch.techweb_designs[d] + if(!istype(D)) + stack_trace("WARNING: Invalid research design with ID [d] detected and removed.") + SSresearch.techweb_designs -= d + CHECK_TICK + +/proc/calculate_techweb_nodes() + for(var/node_id in SSresearch.techweb_nodes) + var/datum/techweb_node/node = SSresearch.techweb_nodes[node_id] + node.prerequisites = list() + node.unlocks = list() + node.designs = list() + for(var/i in node.prereq_ids) + node.prerequisites[i] = SSresearch.techweb_nodes[i] + for(var/i in node.design_ids) + node.designs[i] = SSresearch.techweb_designs[i] + if(node.hidden) + SSresearch.techweb_nodes_hidden[node.id] = node + CHECK_TICK + generate_techweb_unlock_linking() + +/proc/generate_techweb_unlock_linking() + for(var/node_id in SSresearch.techweb_nodes) //Clear all unlock links to avoid duplication. + var/datum/techweb_node/node = SSresearch.techweb_nodes[node_id] + node.unlocks = list() + for(var/node_id in SSresearch.techweb_nodes) + var/datum/techweb_node/node = SSresearch.techweb_nodes[node_id] + for(var/prereq_id in node.prerequisites) + var/datum/techweb_node/prereq_node = node.prerequisites[prereq_id] + prereq_node.unlocks[node.id] = node + +/proc/calculate_techweb_boost_list(clearall = FALSE) + if(clearall) + SSresearch.techweb_boost_items = list() + for(var/node_id in SSresearch.techweb_nodes) + var/datum/techweb_node/node = SSresearch.techweb_nodes[node_id] + for(var/path in node.boost_item_paths) + if(!ispath(path)) + continue + if(length(SSresearch.techweb_boost_items[path])) + SSresearch.techweb_boost_items[path] += list(node.id = node.boost_item_paths[path]) + else + SSresearch.techweb_boost_items[path] = list(node.id = node.boost_item_paths[path]) + CHECK_TICK + +/proc/techweb_item_boost_check(obj/item/I) //Returns an associative list of techweb node datums with values of the boost it gives. var/list/returned = list() + if(SSresearch.techweb_boost_items[I.type]) + return SSresearch.techweb_boost_items[I.type] //It should already be formatted in node datum = value. + +/proc/techweb_item_point_check(obj/item/I) + if(SSresearch.techweb_point_items[I.type]) + return SSresearch.techweb_point_items[I.type] + return 0 diff --git a/code/modules/research/techweb/_techweb.dm b/code/modules/research/techweb/_techweb.dm new file mode 100644 index 0000000000..74ace7e4c2 --- /dev/null +++ b/code/modules/research/techweb/_techweb.dm @@ -0,0 +1,273 @@ + +//Used \n[\s]*origin_tech[\s]*=[\s]*"[\S]+" to delete all origin techs. +//Or \n[\s]*origin_tech[\s]*=[\s]list\([A-Z_\s=0-9,]*\) +//Used \n[\s]*req_tech[\s]*=[\s]*list\(["a-z\s=0-9,]*\) to delete all req_techs. + +//Techweb datums are meant to store unlocked research, being able to be stored on research consoles, servers, and disks. They are NOT global. +/datum/techweb + var/list/datum/techweb_node/researched_nodes = list() //Already unlocked and all designs are now available. Assoc list, id = datum + var/list/datum/techweb_node/visible_nodes = list() //Visible nodes, doesn't mean it can be researched. Assoc list, id = datum + var/list/datum/techweb_node/available_nodes = list() //Nodes that can immediately be researched, all reqs met. assoc list, id = datum + var/list/datum/design/researched_designs = list() //Designs that are available for use. Assoc list, id = datum + var/list/datum/techweb_node/boosted_nodes = list() //Already boosted nodes that can't be boosted again. node datum = path of boost object. + var/list/datum/techweb_node/hidden_nodes = list() //Hidden nodes. id = datum. Used for unhiding nodes when requirements are met by removing the entry of the node. + var/list/deconstructed_items = list() //items already deconstructed for a generic point boost + var/research_points = 0 //Available research points. + var/list/obj/machinery/computer/rdconsole/consoles_accessing = list() + var/id = "generic" + var/list/research_logs = list() //IC logs. + var/max_bomb_value = 0 + +/datum/techweb/New() + for(var/i in SSresearch.techweb_nodes_starting) + var/datum/techweb_node/DN = SSresearch.techweb_nodes_starting[i] + research_node(DN, TRUE, FALSE) + hidden_nodes = SSresearch.techweb_nodes_hidden + return ..() + +/datum/techweb/admin + research_points = INFINITY //KEKKLES. + id = "ADMIN" + +/datum/techweb/admin/New() //All unlocked. + . = ..() + for(var/i in SSresearch.techweb_nodes) + var/datum/techweb_node/TN = SSresearch.techweb_nodes[i] + research_node(TN, TRUE) + hidden_nodes = list() + +/datum/techweb/science //Global science techweb for RND consoles. + id = "SCIENCE" + +/datum/techweb/Destroy() + researched_nodes = null + researched_designs = null + available_nodes = null + visible_nodes = null + return ..() + +/datum/techweb/proc/recalculate_nodes(recalculate_designs = FALSE) + var/list/datum/techweb_node/processing = list() + for(var/i in researched_nodes) + processing[i] = researched_nodes[i] + for(var/i in visible_nodes) + processing[i] = visible_nodes[i] + for(var/i in available_nodes) + processing[i] = available_nodes[i] + for(var/i in processing) + update_node_status(processing[i]) + if(recalculate_designs) //Wipes custom added designs like from design disks or anything like that! + researched_designs = list() + for(var/i in processing) + var/datum/techweb_node/TN = processing[i] + update_node_status(TN, FALSE) + CHECK_TICK + for(var/v in consoles_accessing) + var/obj/machinery/computer/rdconsole/V = v + V.rescan_views() + V.updateUsrDialog() + +/datum/techweb/proc/copy_research_to(datum/techweb/reciever, unlock_hidden = TRUE) //Adds any missing research to theirs. + for(var/i in researched_nodes) + CHECK_TICK + reciever.research_node_id(i, TRUE, FALSE) + for(var/i in researched_designs) + CHECK_TICK + reciever.add_design_by_id(i) + if(unlock_hidden) + for(var/i in reciever.hidden_nodes) + CHECK_TICK + if(!hidden_nodes[i]) + reciever.hidden_nodes -= i //We can see it so let them see it too. + reciever.recalculate_nodes() + +/datum/techweb/proc/copy() + var/datum/techweb/returned = new() + returned.researched_nodes = researched_nodes.Copy() + returned.visible_nodes = visible_nodes.Copy() + returned.available_nodes = available_nodes.Copy() + returned.researched_designs = researched_designs.Copy() + returned.hidden_nodes = hidden_nodes.Copy() + return returned + +/datum/techweb/proc/get_visible_nodes() //The way this is set up is shit but whatever. + return visible_nodes - hidden_nodes + +/datum/techweb/proc/get_available_nodes() + return available_nodes - hidden_nodes + +/datum/techweb/proc/get_researched_nodes() + return researched_nodes - hidden_nodes + +/datum/techweb/proc/add_design_by_id(id) + return add_design(get_techweb_design_by_id(id)) + +/datum/techweb/proc/add_design(datum/design/design) + if(!istype(design)) + return FALSE + researched_designs[design.id] = design + return TRUE + +/datum/techweb/proc/remove_design_by_id(id) + return remove_design(get_techweb_design_by_id(id)) + +/datum/techweb/proc/remove_design(datum/design/design) + if(!istype(design)) + return FALSE + researched_designs -= design.id + return TRUE + +/datum/techweb/proc/research_node_id(id, force, auto_update_points) + return research_node(get_techweb_node_by_id(id), force, auto_update_points) + +/datum/techweb/proc/research_node(datum/techweb_node/node, force = FALSE, auto_adjust_cost = TRUE) + if(!istype(node)) + return FALSE + update_node_status(node) + if(!force) + if(!available_nodes[node.id] || (auto_adjust_cost && (research_points < node.get_price(src)))) + return FALSE + if(auto_adjust_cost) + research_points -= node.get_price(src) + researched_nodes[node.id] = node //Add to our researched list + for(var/i in node.unlocks) + visible_nodes[i] = node.unlocks[i] + update_node_status(node.unlocks[i]) + for(var/i in node.designs) + add_design(node.designs[i]) + update_node_status(node) + return TRUE + +/datum/techweb/proc/unresearch_node_id(id) + return unresearch_node(get_techweb_node_by_id(id)) + +/datum/techweb/proc/unresearch_node(datum/techweb_node/node) + if(!istype(node)) + return FALSE + researched_nodes -= node.id + recalculate_nodes(TRUE) //Fully rebuild the tree. + +/datum/techweb/proc/boost_with_path(datum/techweb_node/N, itempath) + if(!istype(N)||!ispath(itempath)) + return FALSE + var/boost = N.boost_item_paths[itempath] + if(!boosted_nodes[N]) + boosted_nodes[N] = boost + if(N.autounlock_by_boost) + hidden_nodes -= N.id + return TRUE + +/datum/techweb/proc/update_node_status(datum/techweb_node/node, autoupdate_consoles = TRUE) + var/researched = FALSE + var/available = FALSE + var/visible = FALSE + if(researched_nodes[node.id]) + researched = TRUE + var/needed = node.prereq_ids.len + for(var/i in node.prereq_ids) + if(researched_nodes[i]) + visible = TRUE + needed-- + if(!needed) + available = TRUE + researched_nodes -= node.id + available_nodes -= node.id + visible_nodes -= node.id + if(hidden_nodes[node.id]) //Hidden. + return + if(researched) + researched_nodes[node.id] = node + for(var/i in node.designs) + add_design(node.designs[i]) + else + if(available) + available_nodes[node.id] = node + else + if(visible) + visible_nodes[node.id] = node + if(autoupdate_consoles) + for(var/v in consoles_accessing) + var/obj/machinery/computer/rdconsole/V = v + V.rescan_views() + V.updateUsrDialog() + +//Laggy procs to do specific checks, just in case. Don't use them if you can just use the vars that already store all this! +/datum/techweb/proc/designHasReqs(datum/design/D) + for(var/i in researched_nodes) + var/datum/techweb_node/N = researched_nodes[i] + for(var/I in N.designs) + if(D == N.designs[I]) + return TRUE + return FALSE + +/datum/techweb/proc/isDesignResearched(datum/design/D) + return isDesignResearchedID(D.id) + +/datum/techweb/proc/isDesignResearchedID(id) + return researched_designs[id] + +/datum/techweb/proc/isNodeResearched(datum/techweb_node/N) + return isNodeResearchedID(N.id) + +/datum/techweb/proc/isNodeResearchedID(id) + return researched_nodes[id] + +/datum/techweb/proc/isNodeVisible(datum/techweb_node/N) + return isNodeResearchedID(N.id) + +/datum/techweb/proc/isNodeVisibleID(id) + return visible_nodes[id] + +/datum/techweb/proc/isNodeAvailable(datum/techweb_node/N) + return isNodeAvailableID(N.id) + +/datum/techweb/proc/isNodeAvailableID(id) + return available_nodes[id] + +/datum/techweb/specialized + var/allowed_buildtypes = ALL + +/datum/techweb/specialized/add_design(datum/design/D) + if(!(D.build_type & allowed_buildtypes)) + return FALSE + return ..() + +/datum/techweb/specialized/autounlocking + var/design_autounlock_buildtypes = NONE + var/design_autounlock_categories = list("initial") //if a design has a buildtype that matches the abovea and either has a category in this or this is null, unlock it. + var/node_autounlock_ids = list() //autounlock nodes of this type. + +/datum/techweb/specialized/autounlocking/New() + ..() + autounlock() + +/datum/techweb/specialized/autounlocking/proc/autounlock() + for(var/id in node_autounlock_ids) + research_node_id(id, TRUE, FALSE) + for(var/id in SSresearch.techweb_designs) + var/datum/design/D = SSresearch.techweb_designs[id] + if(D.build_type & design_autounlock_buildtypes) + for(var/i in D.category) + if(i in design_autounlock_categories) + add_design(D) + break + +/datum/techweb/specialized/autounlocking/autolathe + design_autounlock_buildtypes = AUTOLATHE + allowed_buildtypes = AUTOLATHE + +/datum/techweb/specialized/autounlocking/limbgrower + design_autounlock_buildtypes = LIMBGROWER + allowed_buildtypes = LIMBGROWER + +/datum/techweb/specialized/autounlocking/biogenerator + design_autounlock_buildtypes = BIOGENERATOR + allowed_buildtypes = BIOGENERATOR + +/datum/techweb/specialized/autounlocking/smelter + design_autounlock_buildtypes = SMELTER + allowed_buildtypes = SMELTER + +/datum/techweb/specialized/autounlocking/exofab + node_autounlock_ids = list("robotics", "mmi", "cyborg", "mecha_odysseus", "mech_gygax", "mech_durand", "mecha_phazon", "mecha", "mech_tools", "clown") + allowed_buildtypes = MECHFAB diff --git a/code/modules/research/techweb/_techweb_node.dm b/code/modules/research/techweb/_techweb_node.dm new file mode 100644 index 0000000000..75faf07bf1 --- /dev/null +++ b/code/modules/research/techweb/_techweb_node.dm @@ -0,0 +1,30 @@ + +//Techweb nodes are GLOBAL, there should only be one instance of them in the game. Persistant changes should never be made to them in-game. + +/datum/techweb_node + var/id + var/display_name = "Errored Node" + var/description = "Why are you seeing this?" + var/hidden = FALSE //Whether it starts off hidden. + var/starting_node = FALSE //Whether it's available without any research. + var/list/prereq_ids = list() + var/list/design_ids = list() + var/list/datum/techweb_node/prerequisites = list() //Assoc list id = datum + var/list/datum/techweb_node/unlocks = list() //CALCULATED FROM OTHER NODE'S PREREQUISITES. Assoc list id = datum. + var/list/datum/design/designs = list() //Assoc list id = datum + var/list/boost_item_paths = list() //Associative list, path = point_value. + var/autounlock_by_boost = TRUE //boosting this will autounlock this node. + var/export_price = 0 //Cargo export price. + var/research_cost = 0 //Point cost to research. + var/actual_cost = 0 + var/category = "Misc" //Category + +/datum/techweb_node/New() + actual_cost = research_cost + +/datum/techweb_node/proc/get_price(datum/techweb/host) + if(!host) + return actual_cost + var/discount = boost_item_paths[host.boosted_nodes[src]] + actual_cost = research_cost - discount + return actual_cost diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm new file mode 100644 index 0000000000..96b252854b --- /dev/null +++ b/code/modules/research/techweb/all_nodes.dm @@ -0,0 +1,860 @@ + +//Current rate: 132500 research points in 90 minutes +//Current cargo price: 250000 points for fullmaxed R&D. + +//Base Node +/datum/techweb_node/base + id = "base" + starting_node = TRUE + display_name = "Basic Research Technology" + description = "NT default research technologies." + design_ids = list("basic_matter_bin", "basic_cell", "basic_scanning", "basic_capacitor", "basic_micro_laser", "micro_mani", + "destructive_analyzer", "protolathe", "circuit_imprinter", "experimentor", "rdconsole", "design_disk", "tech_disk", "rdserver", "rdservercontrol", "mechfab", + "space_heater") //Default research tech, prevents bricking + +/////////////////////////Biotech///////////////////////// +/datum/techweb_node/biotech + id = "biotech" + display_name = "Biological Technology" + description = "What makes us tick." //the MC, silly! + prereq_ids = list("base") + design_ids = list("mass_spectrometer", "chem_heater", "chem_master", "chem_dispenser", "sleeper", "pandemic") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/adv_biotech + id = "adv_biotech" + display_name = "Advanced Biotechnology" + description = "Advanced Biotechnology" + prereq_ids = list("biotech") + design_ids = list("piercesyringe", "adv_mass_spectrometer", "plasmarefiller", "limbgrower") + research_cost = 2500 + export_price = 10000 + +/////////////////////////data theory tech///////////////////////// +/datum/techweb_node/datatheory //Computer science + id = "datatheory" + display_name = "Data Theory" + description = "Big Data, in space!" + prereq_ids = list("base") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/adv_datatheory + id = "adv_datatheory" + display_name = "Advanced Data Theory" + description = "Better insight into programming and data." + prereq_ids = list("datatheory") + design_ids = list("icprinter", "icupgadv", "icupgclo") + research_cost = 2500 + export_price = 10000 + +/////////////////////////engineering tech///////////////////////// +/datum/techweb_node/engineering + id = "engineering" + description = "Modern Engineering Technology." + display_name = "Industrial Engineering" + prereq_ids = list("base") + design_ids = list("solarcontrol", "recharger", "powermonitor", "rped", "pacman", "adv_capacitor", "adv_scanning", "emitter", "high_cell", "adv_matter_bin", + "atmosalerts", "atmos_control", "recycler", "autolathe", "high_micro_laser", "nano_mani", "weldingmask", "mesons", "thermomachine", "tesla_coil", "grounding_rod", "apc_control") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/adv_engi + id = "adv_engi" + description = "Advanced Engineering research" + display_name = "Advanced Engineering" + prereq_ids = list("engineering", "emp_basic") + design_ids = list("engine_goggles", "diagnostic_hud", "magboots") + research_cost = 2500 + export_price = 10000 + +/////////////////////////Bluespace tech///////////////////////// +/datum/techweb_node/bluespace_basic //Bluespace-memery + id = "bluespace_basic" + display_name = "Basic Bluespace Theory" + description = "Basic studies into the mysterious alternate dimension known as bluespace." + prereq_ids = list("base") + design_ids = list("beacon", "xenobioconsole") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/adv_bluespace + id = "adv_bluespace" + display_name = "Advanced Bluespace Research" + description = "Deeper understanding of how the Bluespace dimension works" + prereq_ids = list("practical_bluespace", "high_efficiency") + design_ids = list("bluespace_matter_bin", "femto_mani", "triphasic_scanning", "tele_station", "tele_hub", "quantumpad", "launchpad", "launchpad_console", + "teleconsole", "bag_holding", "bluespace_crystal", "wormholeprojector") + research_cost = 2500 + export_price = 10000 + +/////////////////////////plasma tech///////////////////////// +/datum/techweb_node/basic_plasma + id = "basic_plasma" + display_name = "Basic Plasma Research" + description = "Research into the mysterious and dangerous substance, plasma." + prereq_ids = list("engineering") + design_ids = list("mech_generator") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/adv_plasma + id = "adv_plasma" + display_name = "Advanced Plasma Research" + description = "Research on how to fully exploit the power of plasma." + prereq_ids = list("basic_plasma") + design_ids = list("mech_plasma_cutter") + research_cost = 2500 + export_price = 10000 + +/////////////////////////robotics tech///////////////////////// +/datum/techweb_node/robotics + id = "robotics" + display_name = "Basic Robotics Research" + description = "Programmable machines that make our lives lazier." + prereq_ids = list("base") + design_ids = list("paicard", "drone_shell") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/adv_robotics + id = "adv_robotics" + display_name = "Advanced Robotics Research" + description = "It can even do the dishes!" + prereq_ids = list("robotics") + design_ids = list("borg_upgrade_diamonddrill") + research_cost = 2500 + export_price = 10000 + +/////////////////////////EMP tech///////////////////////// +/datum/techweb_node/emp_basic //EMP tech for some reason + id = "emp_basic" + display_name = "Electromagnetic Theory" + description = "Study into usage of frequencies in the electromagnetic spectrum." + prereq_ids = list("base") + design_ids = list("holosign", "inducer", "tray_goggles", "holopad") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/emp_adv + id = "emp_adv" + display_name = "Advanced Electromagnetic Theory" + prereq_ids = list("emp_basic") + design_ids = list("ultra_micro_laser") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/emp_super + id = "emp_super" + display_name = "Quantum Electromagnetic Technology" //bs + description = "Even better electromagnetic technology" + prereq_ids = list("emp_adv") + design_ids = list("quadultra_micro_laser") + research_cost = 2500 + export_price = 10000 + +/////////////////////////Clown tech///////////////////////// +/datum/techweb_node/clown + id = "clown" + display_name = "Clown Technology" + description = "Honk?!" + prereq_ids = list("base") + design_ids = list("air_horn", "honker_main", "honker_peri", "honker_targ", "honk_chassis", "honk_head", "honk_torso", "honk_left_arm", "honk_right_arm", + "honk_left_leg", "honk_right_leg", "mech_banana_mortar", "mech_mousetrap_mortar", "mech_honker", "mech_punching_face", "implant_trombone") + research_cost = 2500 + export_price = 10000 + +////////////////////////Computer tech//////////////////////// +/datum/techweb_node/comptech + id = "comptech" + display_name = "Computer Consoles" + description = "Computers and how they work." + prereq_ids = list("datatheory") + design_ids = list("cargo", "cargorequest", "stockexchange", "libraryconsole", "aifixer", "mining", "crewconsole", "comconsole", "idcardconsole", "operating", "seccamera") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/computer_hardware_basic //Modular computers are shitty and nearly useless so until someone makes them actually useful this can be easy to get. + id = "computer_hardware_basic" + display_name = "Computer Hardware" + description = "How computer hardware are made." + prereq_ids = list("comptech") + research_cost = 2500 + export_price = 10000 + design_ids = list("hdd_basic", "hdd_advanced", "hdd_super", "hdd_cluster", "ssd_small", "ssd_micro", "netcard_basic", "netcard_advanced", "netcard_wired", + "portadrive_basic", "portadrive_advanced", "portadrive_super", "cardslot", "aislot", "miniprinter", "APClink", "bat_control", "bat_normal", "bat_advanced", + "bat_super", "bat_micro", "bat_nano", "cpu_normal", "pcpu_normal", "cpu_small", "pcpu_small") + +/datum/techweb_node/computer_board_gaming + id = "computer_board_gaming" + display_name = "Arcade Games" + description = "For the slackers on the station." + prereq_ids = list("comptech") + design_ids = list("arcade_battle", "arcade_orion", "slotmachine") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/comp_recordkeeping + id = "comp_recordkeeping" + display_name = "Computerized Recordkeeping" + description = "Organized record databases and how they're used." + prereq_ids = list("comptech") + design_ids = list("secdata", "med_data", "prisonmanage", "vendor", "automated_announcement") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/telecomms + id = "telecomms" + display_name = "Telecommunications Technology" + description = "Subspace transmission technology for near-instant communications devices." + prereq_ids = list("comptech", "bluespace_basic") + research_cost = 2500 + export_price = 10000 + design_ids = list("s-receiver", "s-bus", "s-broadcaster", "s-processor", "s-hub", "s-server", "s-relay", "comm_monitor", "comm_server", + "s-ansible", "s-filter", "s-amplifier", "ntnet_relay", "s-treatment", "s-analyzer", "s-crystal", "s-transmitter") + +/datum/techweb_node/integrated_HUDs + id = "integrated_HUDs" + display_name = "Integrated HUDs" + description = "The usefulness of computerized records, projected straight onto your eyepiece!" + prereq_ids = list("comp_recordkeeping", "emp_basic") + design_ids = list("health_hud", "security_hud", "diagnostic_hud", "scigoggles") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/NVGtech + id = "NVGtech" + display_name = "Night Vision Technology" + description = "Allows seeing in the dark without actual light!" + prereq_ids = list("integrated_HUDs", "adv_engi", "emp_adv") + design_ids = list("health_hud_night", "security_hud_night", "diagnostic_hud_night", "night_visision_goggles", "nvgmesons") + research_cost = 2500 + export_price = 10000 + +////////////////////////AI & Cyborg tech//////////////////////// +/datum/techweb_node/neural_programming + id = "neural_programming" + display_name = "Neural Programming" + description = "Study into networks of processing units that mimic our brains." + prereq_ids = list("biotech", "datatheory") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mmi + id = "mmi" + display_name = "Man Machine Interface" + description = "A slightly Frankensteinian device that allows human brains to interface natively with software APIs." + prereq_ids = list("biotech", "neural_programming") + design_ids = list("mmi") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/posibrain + id = "posibrain" + display_name = "Positronic Brain" + description = "Applied usage of neural technology allowing for autonomous AI units based on special metallic cubes with conductive and processing circuits." + prereq_ids = list("mmi", "neural_programming") + design_ids = list("mmi_posi") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/cyborg + id = "cyborg" + display_name = "Cyborg Construction" + description = "Sapient robots with preloaded tool modules and programmable laws." + prereq_ids = list("mmi", "robotics") + research_cost = 2500 + export_price = 10000 + design_ids = list("robocontrol", "sflash", "borg_suit", "borg_head", "borg_chest", "borg_r_arm", "borg_l_arm", "borg_r_leg", "borg_l_leg", "borgupload", + "cyborgrecharger", "borg_upgrade_restart", "borg_upgrade_rename") + +/datum/techweb_node/cyborg_upg_util + id = "cyborg_upg_util" + display_name = "Cyborg Upgrades: Utility" + description = "Utility upgrades for cybogs." + prereq_ids = list("engineering", "cyborg") + design_ids = list("borg_upgrade_holding", "borg_upgrade_lavaproof", "borg_upgrade_thrusters", "borg_upgrade_selfrepair") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/cyborg_upg_med + id = "cyborg_upg_med" + display_name = "Cyborg Upgrades: Medical" + description = "Medical upgrades for cyborgs" + prereq_ids = list("adv_biotech", "cyborg") + design_ids = list("borg_upgrade_defibrillator", "borg_upgrade_piercinghypospray", "borg_upgrade_highstrengthsynthesiser", "borg_upgrade_expandedsynthesiser") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/cyborg_upg_combat + id = "cyborg_upg_combat" + display_name = "Cyborg Upgrades: Combat" + description = "Military grade upgrades for cyborgs." + prereq_ids = list("adv_robotics", "adv_engi") + design_ids = list("borg_upgrade_vtec", "borg_upgrade_disablercooler") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/ai + id = "ai" + display_name = "Artificial Intelligence" + description = "AI unit research." + prereq_ids = list("robotics", "neural_programming") + design_ids = list("aicore", "safeguard_module", "onehuman_module", "protectstation_module", "quarantine_module", "oxygen_module", "freeform_module", + "reset_module", "purge_module", "remove_module", "freeformcore_module", "asimov_module", "paladin_module", "tyrant_module", "corporate_module", + "default_module", "borg_ai_control", "mecha_tracking_ai_control", "aiupload", "intellicard") + research_cost = 2500 + export_price = 10000 + +////////////////////////Medical//////////////////////// +/datum/techweb_node/cloning + id = "cloning" + display_name = "Genetic Engineering" + description = "We have the technology to make him." + prereq_ids = list("biotech") + design_ids = list("clonecontrol", "clonepod", "clonescanner", "scan_console") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/cryotech + id = "cryotech" + display_name = "Cryostasis Technology" + description = "Smart freezing of objects to preserve them!" + prereq_ids = list("adv_engi", "emp_basic", "biotech") + design_ids = list("splitbeaker", "noreactsyringe", "cryotube", "cryo_Grenade") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/subdermal_implants + id = "subdermal_implants" + display_name = "Subdermal Implants" + description = "Electronic implants buried beneath the skin." + prereq_ids = list("biotech") + design_ids = list("implanter", "implantcase", "implant_chem", "implant_tracking") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/cyber_organs + id = "cyber_organs" + display_name = "Cybernetic Organs" + description = "We have the technology to rebuild him." + prereq_ids = list("adv_biotech", "cyborg") + design_ids = list("cybernetic_heart", "cybernetic_liver", "cybernetic_liver_u", "cybernetic_lungs") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/cyber_implants + id = "cyber_implants" + display_name = "Cybernetic Implants" + description = "Electronic implants that improve humans." + prereq_ids = list("adv_biotech", "cyborg", "adv_datatheory") + design_ids = list("ci-nutriment", "ci-nutrimentplus", "ci-breather", "ci-gloweyes", "ci-welding", "ci-medhud", "ci-sechud") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/adv_cyber_implants + id = "adv_cyber_implants" + display_name = "Advanced Cybernetic Implants" + description = "Upgraded and more powerful cybernetic implants." + prereq_ids = list("neural_programming", "cyber_implants") + design_ids = list("ci-toolset", "ci-surgery", "ci-reviver") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/combat_cyber_implants + id = "combat_cyber_implants" + display_name = "Combat Cybernetic Implants" + description = "Military grade combat implants to improve performance." + prereq_ids = list("adv_cyber_implants") //Needs way more reqs. + design_ids = list("ci-xray", "ci-thermals", "ci-antidrop", "ci-antistun", "ci-thrusters") + research_cost = 2500 + export_price = 10000 + +////////////////////////generic biotech//////////////////////// +/datum/techweb_node/bio_process + id = "bio_process" + display_name = "Biological Processing" + description = "From slimes to kitchens." + prereq_ids = list("biotech") + design_ids = list("smartfridge", "gibber", "deepfryer", "monkey_recycler", "processor", "gibber", "microwave") + research_cost = 2500 + export_price = 10000 + +////////////////////////generic engineering//////////////////////// +/datum/techweb_node/high_efficiency + id = "high_efficiency" + display_name = "High Efficiency Parts" + description = "High Efficiency Parts" + prereq_ids = list("engineering", "datatheory") + design_ids = list("pico_mani", "super_matter_bin") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/adv_power + id = "adv_power" + display_name = "Advanced Power Manipulation" + description = "How to get more zap." + prereq_ids = list("engineering") + design_ids = list("smes", "super_cell", "hyper_cell", "super_capacitor", "superpacman", "mrspacman", "power_turbine", "power_turbine_console", "power_compressor") + research_cost = 2500 + export_price = 10000 + +////////////////////////Tools//////////////////////// +/datum/techweb_node/basic_mining + id = "basic_mining" + display_name = "Mining Technology" + description = "Better than Efficiency V." + prereq_ids = list("engineering") + design_ids = list("drill", "superresonator", "triggermod", "damagemod", "cooldownmod", "rangemod", "ore_redemption", "mining_equipment_vendor") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/adv_mining + id = "adv_mining" + display_name = "Advanced Mining Technology" + description = "Efficiency Level 127" //dumb mc references + prereq_ids = list("basic_mining", "adv_engi", "adv_power", "adv_plasma") + design_ids = list("drill_diamond", "jackhammer", "hypermod", "plasmacutter", "plasmacutter_adv") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/practical_bluespace + id = "practical_bluespace" + display_name = "Applied Bluespace Research" + description = "Using bluespace to make things faster and better." + prereq_ids = list("bluespace_basic", "engineering") + design_ids = list("bs_rped","minerbag_holding", "telesci_gps", "bluespacebeaker", "bluespacesyringe", "bluespacebodybag", "phasic_scanning") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/janitor + id = "janitor" + display_name = "Advanced Sanitation Technology" + description = "Clean things better, faster, stronger, and harder!" + prereq_ids = list("adv_engi") + design_ids = list("advmop", "buffer", "blutrash", "light_replacer") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/botany + id = "botany" + display_name = "Botanical Engineering" + description = "Botanical tools" + prereq_ids = list("adv_engi", "biotech") + design_ids = list("diskplantgene", "portaseeder", "plantgenes", "flora_gun", "hydro_tray", "biogenerator", "seed_extractor") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/exp_tools + id = "exp_tools" + display_name = "Experimental Tools" + description = "Highly advanced construction tools." + design_ids = list("exwelder", "jawsoflife", "handdrill") + prereq_ids = list("adv_engi") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/exp_equipment + id = "exp_equipment" + display_name = "Experimental Flight Equipment" + description = "Highly advanced construction tools." + design_ids = list("flightshoes", "flightpack", "flightsuit") + prereq_ids = list("adv_engi") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/bluespace_power + id = "bluespace_power" + display_name = "Bluespace Power Technology" + description = "Even more powerful.. power!" + prereq_ids = list("adv_power", "adv_bluespace") + design_ids = list("bluespace_cell", "quadratic_capacitor") + research_cost = 2500 + export_price = 10000 + +/////////////////////////weaponry tech///////////////////////// +/datum/techweb_node/weaponry + id = "weaponry" + display_name = "Weapon Development Technology" + description = "Our researchers have found new to weaponize just about everything now." + prereq_ids = list("engineering") + design_ids = list("pin_testing") + research_cost = 10000 + export_price = 10000 + +/datum/techweb_node/adv_weaponry + id = "adv_weaponry" + display_name = "Advanced Weapon Development Technology" + description = "Our weapons are breaking the rules of reality by now." + prereq_ids = list("adv_engi", "weaponry") + design_ids = list("pin_loyalty") + research_cost = 10000 + export_price = 10000 + +/datum/techweb_node/electric_weapons + id = "electronic_weapons" + display_name = "Electric Weapons" + description = "Weapons using electric technology" + prereq_ids = list("weaponry", "adv_power") + design_ids = list("stunrevolver", "stunshell", "tele_shield") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/radioactive_weapons + id = "radioactive_weapons" + display_name = "Radioactive Weaponry" + description = "Weapons using radioactive technology." + prereq_ids = list("adv_engi", "adv_weaponry") + design_ids = list("nuclear_gun", "decloner") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/medical_weapons + id = "medical_weapons" + display_name = "Medical Weaponry" + description = "Weapons using medical technology." + prereq_ids = list("adv_biotech", "adv_weaponry") + design_ids = list("rapidsyringe") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/beam_weapons + id = "beam_weapons" + display_name = "Beam Weaponry" + description = "Various basic beam weapons" + prereq_ids = list("adv_weaponry") + design_ids = list("beamrifle", "ioncarbine") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/adv_beam_weapons + id = "adv_beam_weapons" + display_name = "Advanced Beam Weaponry" + description = "Various advanced beam weapons" + prereq_ids = list("beam_weapons") + design_ids = list("xray_laser") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/explosive_weapons + id = "explosive_weapons" + display_name = "Explosive & Pyrotechnical Weaponry" + description = "If the light stuff just won't do it." + prereq_ids = list("adv_weaponry") + design_ids = list("temp_gun", "large_Grenade", "pyro_Grenade", "adv_Grenade") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/ballistic_weapons + id = "ballistic_weapons" + display_name = "Ballistic Weaponry" + description = "This isn't research.. This is reverse-engineering!" + prereq_ids = list("weaponry") + design_ids = list("mag_oldsmg", "mag_oldsmg_ap", "mag_oldsmg_ic") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/tech_shell + id = "tech_shell" + display_name = "Technological Shells" + description = "They're more technological than regular shot." + prereq_ids = list("adv_weaponry") + design_ids = list("techshotshell") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/gravity_gun + id = "gravity_gun" + display_name = "One-point Bluespace-gravitational Manipulator" + description = "Fancy wording for gravity gun" + prereq_ids = list("adv_weaponry", "adv_bluespace") + design_ids = list("gravitygun") + research_cost = 2500 + export_price = 10000 + +////////////////////////mech technology//////////////////////// +/datum/techweb_node/mech + id = "mecha" + display_name = "Mechanical Exosuits" + description = "Mechanized exosuits that are several magnitudes stronger and more powerful than the average human." + prereq_ids = list("robotics", "adv_engi") + design_ids = list("mecha_tracking", "mechacontrol", "mechapower", "mech_recharger", "ripley_chassis", "firefighter_chassis", "ripley_torso", "ripley_left_arm", "ripley_right_arm", "ripley_left_leg", "ripley_right_leg", + "ripley_main", "ripley_peri", "mech_hydraulic_clamp") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/adv_mecha + id = "adv_mecha" + display_name = "Mechanical Exosuits" + description = "Mechanized exosuits that are several magnitudes stronger and more powerful than the average human." + prereq_ids = list("adv_robotics", "mecha") + design_ids = list("mech_repair_droid") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/odysseus + id = "mecha_odysseus" + display_name = "EXOSUIT: Odysseus" + description = "Odysseus exosuit designs" + prereq_ids = list("mecha") + design_ids = list("odysseus_chassis", "odysseus_torso", "odysseus_head", "odysseus_left_arm", "odysseus_right_arm" ,"odysseus_left_leg", "odysseus_right_leg", + "odysseus_main", "odysseus_peri") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/gygax + id = "mech_gygax" + display_name = "EXOSUIT: Gygax" + description = "Gygax exosuit designs" + prereq_ids = list("adv_mecha", "weaponry") + design_ids = list("gygax_chassis", "gygax_torso", "gygax_head", "gygax_left_arm", "gygax_right_arm", "gygax_left_leg", "gygax_right_leg", "gygax_main", + "gygax_peri", "gygax_targ", "gygax_armor") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/durand + id = "mech_durand" + display_name = "EXOSUIT: Durand" + description = "Durand exosuit designs" + prereq_ids = list("adv_mecha", "adv_weaponry") + design_ids = list("durand_chassis", "durand_torso", "durand_head", "durand_left_arm", "durand_right_arm", "durand_left_leg", "durand_right_leg", "durand_main", + "durand_peri", "durand_targ", "durand_armor") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/phazon + id = "mecha_phazon" + display_name = "EXOSUIT: Phazon" + description = "Phazon exosuit designs" + prereq_ids = list("adv_mecha", "weaponry") + design_ids = list("phazon_chassis", "phazon_torso", "phazon_head", "phazon_left_arm", "phazon_right_arm", "phazon_left_leg", "phazon_right_leg", "phazon_main", + "phazon_peri", "phazon_targ", "phazon_armor") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_tools + id = "mech_tools" + display_name = "Basic Exosuit Equipment" + description = "Various tools fit for basic mech units" + prereq_ids = list("mecha", "engineering") + design_ids = list("mech_drill", "mech_mscanner", "mech_extinguisher", "mech_cable_layer") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/adv_mecha_tools + id = "adv_mecha_tools" + display_name = "Advanced Exosuit Equipment" + description = "Tools for high level mech suits" + prereq_ids = list("adv_mecha", "mech_tools", "adv_engi") + design_ids = list("mech_rcd") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/med_mech_tools + id = "med_mech_tools" + display_name = "Medical Exosuit Equipment" + description = "Tools for high level mech suits" + prereq_ids = list("mecha", "adv_biotech", "mech_tools") + design_ids = list("mech_sleeper", "mech_syringe_gun", "mech_medi_beam") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_modules + id = "adv_mecha_modules" + display_name = "Basic Exosuit Modules" + description = "An advanced piece of mech weaponry" + prereq_ids = list("adv_mecha", "adv_power") + design_ids = list("mech_energy_relay", "mech_ccw_armor", "mech_proj_armor", "mech_generator_nuclear") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_scattershot + id = "mecha_tools" + display_name = "Exosuit Weapon (LBX AC 10 \"Scattershot\")" + description = "An advanced piece of mech weaponry" + prereq_ids = list("mecha", "adv_weaponry", "ballistic_weapons") + design_ids = list("mech_scattershot") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_carbine + id = "mech_carbine" + display_name = "Exosuit Weapon (FNX-99 \"Hades\" Carbine)" + description = "An advanced piece of mech weaponry" + prereq_ids = list("mecha", "adv_weaponry", "ballistic_weapons") + design_ids = list("mech_carbine") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_ion + id = "mmech_ion" + display_name = "Exosuit Weapon (MKIV Ion Heavy Cannon)" + description = "An advanced piece of mech weaponry" + prereq_ids = list("mecha", "adv_weaponry", "emp_adv") + design_ids = list("mech_ion") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_tesla + id = "mech_tesla" + display_name = "Exosuit Weapon (MKI Tesla Cannon)" + description = "An advanced piece of mech weaponry" + prereq_ids = list("mecha", "weaponry", "adv_power") + design_ids = list("mech_tesla") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_laser + id = "mech_laser" + display_name = "Exosuit Weapon (CH-PS \"Immolator\" Laser)" + description = "A basic piece of mech weaponry" + prereq_ids = list("mecha", "beam_weapons") + design_ids = list("mech_laser") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_laser_heavy + id = "mech_laser_heavy" + display_name = "Exosuit Weapon (CH-LC \"Solaris\" Laser Cannon)" + description = "An advanced piece of mech weaponry" + prereq_ids = list("mecha", "adv_weaponry", "adv_beam_weapons") + design_ids = list("mech_laser_heavy") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_grenade_launcher + id = "mech_grenade_launcher" + display_name = "Exosuit Weapon (SGL-6 Grenade Launcher)" + description = "An advanced piece of mech weaponry" + prereq_ids = list("mecha", "explosive_weapons") + design_ids = list("mech_grenade_launcher") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_missile_rack + id = "mech_missile_rack" + display_name = "Exosuit Weapon (SRM-8 Missile Rack)" + description = "An advanced piece of mech weaponry" + prereq_ids = list("mecha", "explosive_weapons") + design_ids = list("mech_missile_rack") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/clusterbang_launcher + id = "clusterbang_launcher" + display_name = "Exosuit Module (SOB-3 Clusterbang Launcher)" + description = "An advanced piece of mech weaponry" + prereq_ids = list("mecha", "weaponry") + design_ids = list("clusterbang_launcher") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_teleporter + id = "mech_teleporter" + display_name = "Exosuit Module (Teleporter Module)" + description = "An advanced piece of mech Equipment" + prereq_ids = list("mecha", "mech_tools", "adv_bluespace") + design_ids = list("mech_teleporter") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_wormhole_gen + id = "mech_wormhole_gen" + display_name = "Exosuit Module (Localized Wormhole Generator)" + description = "An advanced piece of mech weaponry" + prereq_ids = list("mecha", "mech_tools", "adv_bluespace") + design_ids = list("mech_wormhole_gen") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_taser + id = "mech_taser" + display_name = "Exosuit Weapon (PBT \"Pacifier\" Mounted Taser)" + description = "A basic piece of mech weaponry" + prereq_ids = list("mecha", "adv_weaponry") + design_ids = list("mech_taser") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_lmg + id = "mech_lmg" + display_name = "Exosuit Weapon (PBT \"Pacifier\" Mounted Taser)" + description = "An advanced piece of mech weaponry" + prereq_ids = list("adv_mecha", "adv_weaponry", "ballistic_weapons") + design_ids = list("mech_lmg") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_diamond_drill + id = "mech_diamond_drill" + display_name = "Exosuit Diamond Drill" + description = "A diamond drill fit for a large exosuit" + prereq_ids = list("mecha", "adv_mining") + design_ids = list("mech_diamond_drill") + research_cost = 2500 + export_price = 10000 + +////////////////////////Alien technology//////////////////////// +/datum/techweb_node/alientech //AYYYYYYYYLMAOO tech + id = "alientech" + display_name = "Alien Technology" + description = "Things used by the greys." + prereq_ids = list("base") + boost_item_paths = list(/obj/item/gun/energy/alien = 0, /obj/item/scalpel/alien = 0, /obj/item/hemostat/alien = 0, /obj/item/retractor/alien = 0, /obj/item/circular_saw/alien = 0, + /obj/item/cautery/alien = 0, /obj/item/surgicaldrill/alien = 0, /obj/item/screwdriver/abductor = 0, /obj/item/wrench/abductor = 0, /obj/item/crowbar/abductor = 0, /obj/item/device/multitool/abductor = 0, + /obj/item/weldingtool/abductor = 0, /obj/item/wirecutters/abductor = 0, /obj/item/circuitboard/machine/abductor = 0, /obj/item/abductor_baton = 0, /obj/item/device/abductor = 0) + research_cost = 2500 + export_price = 10000 + hidden = TRUE + design_ids = list("alienalloy") + +/datum/techweb_node/alien_bio + id = "alien_bio" + display_name = "Alien Biological Tools" + description = "Advanced biological tools." + prereq_ids = list("alientech", "biotech") + design_ids = list("alien_scalpel", "alien_hemostat", "alien_retractor", "alien_saw", "alien_drill", "alien_cautery") + boost_item_paths = list(/obj/item/gun/energy/alien = 0, /obj/item/scalpel/alien = 0, /obj/item/hemostat/alien = 0, /obj/item/retractor/alien = 0, /obj/item/circular_saw/alien = 0, + /obj/item/cautery/alien = 0, /obj/item/surgicaldrill/alien = 0, /obj/item/screwdriver/abductor = 0, /obj/item/wrench/abductor = 0, /obj/item/crowbar/abductor = 0, /obj/item/device/multitool/abductor = 0, + /obj/item/weldingtool/abductor = 0, /obj/item/wirecutters/abductor = 0, /obj/item/circuitboard/machine/abductor = 0, /obj/item/abductor_baton = 0, /obj/item/device/abductor = 0) + research_cost = 2500 + export_price = 10000 + hidden = TRUE + +/datum/techweb_node/alien_engi + id = "alien_engi" + display_name = "Alien Engineering" + description = "Alien engineering tools" + prereq_ids = list("alientech", "adv_engi") + boost_item_paths = list(/obj/item/screwdriver/abductor = 0, /obj/item/wrench/abductor = 0, /obj/item/crowbar/abductor = 0, /obj/item/device/multitool/abductor = 0, + /obj/item/weldingtool/abductor = 0, /obj/item/wirecutters/abductor = 0, /obj/item/circuitboard/machine/abductor = 0, /obj/item/abductor_baton = 0, /obj/item/device/abductor = 0) + design_ids = list("alien_wrench", "alien_wirecutters", "alien_screwdriver", "alien_crowbar", "alien_welder", "alien_multitool") + research_cost = 2500 + export_price = 10000 + hidden = TRUE + +/proc/total_techweb_points() + var/list/datum/techweb_node/processing = list() + for(var/i in subtypesof(/datum/techweb_node)) + processing += new i + . = 0 + for(var/i in processing) + var/datum/techweb_node/TN = i + . += TN.research_cost + +/* +/datum/design/borg_syndicate_module + name = "Cyborg Upgrade (Illegal Modules)" + id = "borg_syndicate_module" + construction_time = 120 + +/datum/design/suppressor + name = "Universal Suppressor" + id = "suppressor" + +/datum/design/largecrossbow + name = "Energy Crossbow" + id = "largecrossbow" + build_path = /obj/item/gun/energy/kinetic_accelerator/crossbow/large +*/ \ No newline at end of file diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm index 02180b273f..ca929e5e9a 100644 --- a/code/modules/research/xenobiology/xenobio_camera.dm +++ b/code/modules/research/xenobiology/xenobio_camera.dm @@ -12,7 +12,7 @@ /mob/camera/aiEye/remote/xenobio/setLoc(var/t) var/area/new_area = get_area(t) - if(new_area && new_area.name == allowed_area || istype(new_area, /area/science/xenobiology )) + if(new_area && new_area.name == allowed_area || new_area && new_area.xenobiology_compatible) return ..() else return @@ -99,7 +99,7 @@ if(GLOB.cameranet.checkTurfVis(remote_eye.loc)) for(var/mob/living/simple_animal/slime/S in X.stored_slimes) - S.loc = remote_eye.loc + S.forceMove(remote_eye.loc) S.visible_message("[S] warps in!") X.stored_slimes -= S else @@ -125,7 +125,7 @@ if(S.buckled) S.Feedstop(silent=1) S.visible_message("[S] vanishes in a flash of light!") - S.loc = X + S.forceMove(X) X.stored_slimes += S else to_chat(owner, "Target is not near a camera. Cannot proceed.") diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index 83957a7285..061bb0bdda 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -11,8 +11,8 @@ throwforce = 0 throw_speed = 3 throw_range = 6 - origin_tech = "biotech=3" - container_type = INJECTABLE_1 + container_type = INJECTABLE | DRAWABLE + grind_results = list() var/Uses = 1 // uses before it goes inert var/qdel_timer = null // deletion timer, for delayed reactions @@ -30,6 +30,10 @@ . = ..() create_reagents(100) +/obj/item/slime_extract/on_grind() + if(Uses) + grind_results["slimejelly"] = 20 + /obj/item/slime_extract/grey name = "grey slime extract" icon_state = "grey slime extract" @@ -124,7 +128,6 @@ name = "slime potion" desc = "A hard yet gelatinous capsule excreted by a slime, containing mysterious substances." w_class = WEIGHT_CLASS_TINY - origin_tech = "biotech=4" /obj/item/slimepotion/afterattack(obj/item/reagent_containers/target, mob/user , proximity) if (istype(target)) @@ -162,7 +165,6 @@ desc = "A miraculous chemical mix that grants human like intelligence to living beings." icon = 'icons/obj/chemical.dmi' icon_state = "potpink" - origin_tech = "biotech=6" var/list/not_interested = list() var/being_used = 0 var/sentience_type = SENTIENCE_ORGANIC @@ -208,7 +210,6 @@ desc = "A strange slime-based chemical that, when used, allows the user to transfer their consciousness to a lesser being." icon = 'icons/obj/chemical.dmi' icon_state = "potorange" - origin_tech = "biotech=6" var/prompted = 0 var/animal_type = SENTIENCE_ORGANIC @@ -294,7 +295,7 @@ return ..() to_chat(user, "You feed the slime the stabilizer. It is now less likely to mutate.") - M.mutation_chance = Clamp(M.mutation_chance-15,0,100) + M.mutation_chance = CLAMP(M.mutation_chance-15,0,100) qdel(src) /obj/item/slimepotion/mutator @@ -318,7 +319,7 @@ return ..() to_chat(user, "You feed the slime the mutator. It is now more likely to mutate.") - M.mutation_chance = Clamp(M.mutation_chance+12,0,100) + M.mutation_chance = CLAMP(M.mutation_chance+12,0,100) M.mutator_used = TRUE qdel(src) @@ -327,7 +328,6 @@ desc = "A potent chemical mix that will remove the slowdown from any item." icon = 'icons/obj/chemical.dmi' icon_state = "potyellow" - origin_tech = "biotech=5" /obj/item/slimepotion/speed/afterattack(obj/C, mob/user) ..() @@ -343,8 +343,8 @@ if(istype(C, /obj/vehicle)) var/obj/vehicle/V = C - var/datum/riding/R = V.riding_datum - if(V.riding_datum) + var/datum/component/riding/R = V.GetComponent(/datum/component/riding) + if(R) if(R.vehicle_move_delay <= 0 ) to_chat(user, "The [C] can't be made any faster!") return ..() @@ -355,13 +355,11 @@ C.add_atom_colour("#FF0000", FIXED_COLOUR_PRIORITY) qdel(src) - /obj/item/slimepotion/fireproof name = "slime chill potion" desc = "A potent chemical mix that will fireproof any article of clothing. Has three uses." icon = 'icons/obj/chemical.dmi' icon_state = "potblue" - origin_tech = "biotech=5" var/uses = 3 /obj/item/slimepotion/fireproof/afterattack(obj/item/clothing/C, mob/user) @@ -509,14 +507,14 @@ /obj/item/areaeditor/blueprints/slime name = "cerulean prints" - desc = "A one use yet of blueprints made of jelly like organic material. Renaming an area to 'Xenobiology Lab' will extend the reach of the management console." + desc = "A one use yet of blueprints made of jelly like organic material. Extends the reach of the management console." color = "#2956B2" /obj/item/areaeditor/blueprints/slime/edit_area() - var/success = ..() + ..() var/area/A = get_area(src) - if(success) - for(var/turf/T in A) - T.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) - T.add_atom_colour("#2956B2", FIXED_COLOUR_PRIORITY) - qdel(src) + for(var/turf/T in A) + T.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) + T.add_atom_colour("#2956B2", FIXED_COLOUR_PRIORITY) + A.xenobiology_compatible = TRUE + qdel(src) diff --git a/code/modules/ruins/lavaland_ruin_code.dm b/code/modules/ruins/lavaland_ruin_code.dm index 67edf8dc9b..126cff9713 100644 --- a/code/modules/ruins/lavaland_ruin_code.dm +++ b/code/modules/ruins/lavaland_ruin_code.dm @@ -33,7 +33,6 @@ name = "Golem Shell Construction" desc = "Allows for the construction of a Golem Shell." id = "golem" - req_tech = list("materials" = 12) build_type = AUTOLATHE materials = list(MAT_METAL = 40000) build_path = /obj/item/golem_shell @@ -97,7 +96,7 @@ name = "Syndicate Bioweapon Scientist" roundstart = FALSE death = FALSE - icon = 'icons/obj/Cryogenic2.dmi' + icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper_s" flavour_text = "You are a syndicate agent, employed in a top secret research facility developing biological weapons. Unfortunately, your hated enemy, Nanotrasen, has begun mining in this sector. Continue your research as best you can, and try to keep a low profile. DON'T abandon the base without good cause. The base is rigged with explosives should the worst happen, do not let the base fall into enemy hands!
    " id_access_list = list(ACCESS_SYNDICATE) 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 7f301bf8b9..f98162266a 100644 --- a/code/modules/ruins/objects_and_mobs/ash_walker_den.dm +++ b/code/modules/ruins/objects_and_mobs/ash_walker_den.dm @@ -9,7 +9,7 @@ faction = list("ashwalker") health = 200 maxHealth = 200 - loot = list(/obj/effect/collapse) + loot = null var/meat_counter = 6 /mob/living/simple_animal/hostile/spawner/lavaland/ash_walker/death() diff --git a/code/modules/server_tools/st_commands.dm b/code/modules/server_tools/st_commands.dm index 9ec87a595c..1e071550e0 100644 --- a/code/modules/server_tools/st_commands.dm +++ b/code/modules/server_tools/st_commands.dm @@ -51,7 +51,7 @@ /* The MIT License -Copyright (c) 2011 Dominic Tarr +Copyright (c) 2017 Jordan Brown Permission is hereby granted, free of charge, to any person obtaining a copy of this software and diff --git a/code/modules/server_tools/st_interface.dm b/code/modules/server_tools/st_interface.dm index 39bebbbb3d..b0b1b0a43c 100644 --- a/code/modules/server_tools/st_interface.dm +++ b/code/modules/server_tools/st_interface.dm @@ -30,7 +30,10 @@ SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(server_tools_api_compatible, FALSE) 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 + var/instance = params[SERVICE_INSTANCE_PARAM] + if(!instance) + instance = "TG Station Server" //maybe just upgraded + call(SERVICE_INTERFACE_DLL, SERVICE_INTERFACE_FUNCTION)(instance, command) //trust no retval return TRUE /world/proc/ChatBroadcast(message) @@ -72,7 +75,7 @@ SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(server_tools_api_compatible, FALSE) switch(command) if(SERVICE_CMD_API_COMPATIBLE) SERVER_TOOLS_WRITE_GLOBAL(server_tools_api_compatible, TRUE) - return "SUCCESS" + return SERVICE_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) @@ -88,7 +91,7 @@ SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(server_tools_api_compatible, FALSE) if(!istext(msg) || !msg) return "No message set!" SERVER_TOOLS_WORLD_ANNOUNCE(msg) - return "SUCCESS" + return SERVICE_RETURN_SUCCESS if(SERVICE_CMD_PLAYER_COUNT) return "[SERVER_TOOLS_CLIENT_COUNT]" if(SERVICE_CMD_LIST_CUSTOM) @@ -96,13 +99,13 @@ SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(server_tools_api_compatible, 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 istext(custom_command_result) ? custom_command_result : SERVICE_RETURN_SUCCESS return "Unknown command: [command]" /* The MIT License -Copyright (c) 2011 Dominic Tarr +Copyright (c) 2017 Jordan Brown Permission is hereby granted, free of charge, to any person obtaining a copy of this software and diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index d573f9ce13..c4eb16305a 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -473,7 +473,7 @@ turfs -= T T = pick(turfs) else - src.loc = T + forceMove(T) break //Pod suits/pickaxes diff --git a/code/modules/shuttle/navigation_computer.dm b/code/modules/shuttle/navigation_computer.dm index 27ef7eec33..de1b0022f6 100644 --- a/code/modules/shuttle/navigation_computer.dm +++ b/code/modules/shuttle/navigation_computer.dm @@ -14,6 +14,17 @@ var/x_offset = 0 var/y_offset = 0 var/space_turfs_only = TRUE + var/see_hidden = FALSE + var/designate_time = 0 + var/turf/designating_target_loc + +/obj/machinery/computer/camera_advanced/shuttle_docker/Initialize() + . = ..() + GLOB.navigation_computers += src + +/obj/machinery/computer/camera_advanced/shuttle_docker/Destroy() + . = ..() + GLOB.navigation_computers -= src /obj/machinery/computer/camera_advanced/shuttle_docker/GrantActions(mob/living/user) if(jumpto_ports.len) @@ -47,63 +58,98 @@ if(T.z != origin.z) continue var/image/I = image('icons/effects/alphacolors.dmi', origin, "red") + var/x_off = T.x - origin.x + var/y_off = T.y - origin.y + I.loc = locate(origin.x + x_off, origin.y + y_off, origin.z) //we have to set this after creating the image because it might be null, and images created in nullspace are immutable. I.layer = ABOVE_NORMAL_TURF_LAYER I.plane = 0 I.mouse_opacity = 0 - var/x_off = T.x - origin.x - var/y_off = T.y - origin.y - I.pixel_x = x_off * 32 - I.pixel_y = y_off * 32 the_eye.placement_images[I] = list(x_off, y_off) /obj/machinery/computer/camera_advanced/shuttle_docker/give_eye_control(mob/user) ..() if(!QDELETED(user) && user.client) var/mob/camera/aiEye/remote/shuttle_docker/the_eye = eyeobj - user.client.images += the_eye.placement_images - user.client.images += the_eye.placed_images + var/list/to_add = list() + to_add += the_eye.placement_images + to_add += the_eye.placed_images + if(!see_hidden) + to_add += SSshuttle.hidden_shuttle_turf_images + + user.client.images += to_add user.client.change_view(view_range) /obj/machinery/computer/camera_advanced/shuttle_docker/remove_eye_control(mob/living/user) ..() if(!QDELETED(user) && user.client) var/mob/camera/aiEye/remote/shuttle_docker/the_eye = eyeobj - user.client.images -= the_eye.placement_images - user.client.images -= the_eye.placed_images - user.client.change_view(world.view) + var/list/to_remove = list() + to_remove += the_eye.placement_images + to_remove += the_eye.placed_images + if(!see_hidden) + to_remove += SSshuttle.hidden_shuttle_turf_images + + user.client.images -= to_remove + user.client.change_view(CONFIG_GET(string/default_view)) /obj/machinery/computer/camera_advanced/shuttle_docker/proc/placeLandingSpot() - if(!checkLandingSpot()) - return FALSE + if(designating_target_loc || !current_user) + return + var/mob/camera/aiEye/remote/shuttle_docker/the_eye = eyeobj + var/landing_clear = checkLandingSpot() + if(designate_time && (landing_clear != SHUTTLE_DOCKER_BLOCKED)) + to_chat(current_user, "Targeting transit location, please wait [designate_time/10] seconds...") + designating_target_loc = the_eye.loc + var/wait_completed = do_after(current_user, designate_time, FALSE, designating_target_loc, TRUE, CALLBACK(src, /obj/machinery/computer/camera_advanced/shuttle_docker/proc/canDesignateTarget)) + designating_target_loc = null + if(!current_user) + return + if(!wait_completed) + to_chat(current_user, "Operation aborted.") + return + landing_clear = checkLandingSpot() + + if(landing_clear != SHUTTLE_DOCKER_LANDING_CLEAR) + switch(landing_clear) + if(SHUTTLE_DOCKER_BLOCKED) + to_chat(current_user, "Invalid transit location") + if(SHUTTLE_DOCKER_BLOCKED_BY_HIDDEN_PORT) + to_chat(current_user, "Unknown object detected in landing zone. Please designate another location.") + return + if(!my_port) - my_port = new /obj/docking_port/stationary() + my_port = new(locate(eyeobj.x - x_offset, eyeobj.y - y_offset, eyeobj.z)) my_port.name = shuttlePortName my_port.id = shuttlePortId - var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId) - my_port.height = M.height - my_port.width = M.width - my_port.dheight = M.dheight - my_port.dwidth = M.dwidth + my_port.height = shuttle_port.height + my_port.width = shuttle_port.width + my_port.dheight = shuttle_port.dheight + my_port.dwidth = shuttle_port.dwidth + my_port.hidden = shuttle_port.hidden my_port.dir = the_eye.dir - my_port.loc = locate(eyeobj.x - x_offset, eyeobj.y - y_offset, eyeobj.z) - if(current_user && current_user.client) + if(current_user.client) current_user.client.images -= the_eye.placed_images - for(var/V in the_eye.placed_images) - qdel(V) - the_eye.placed_images = list() + QDEL_LIST(the_eye.placed_images) for(var/V in the_eye.placement_images) - var/turf/T = locate(eyeobj.x + the_eye.placement_images[V][1], eyeobj.y + the_eye.placement_images[V][2], eyeobj.z) - var/image/I = image('icons/effects/alphacolors.dmi', T, "blue") - I.layer = ABOVE_OPEN_TURF_LAYER - I.plane = 0 - I.mouse_opacity = 0 - the_eye.placed_images += I + var/image/I = V + var/image/newI = image('icons/effects/alphacolors.dmi', the_eye.loc, "blue") + newI.loc = I.loc //It is highly unlikely that any landing spot including a null tile will get this far, but better safe than sorry. + newI.layer = ABOVE_OPEN_TURF_LAYER + newI.plane = 0 + newI.mouse_opacity = 0 + the_eye.placed_images += newI - if(current_user && current_user.client) + if(current_user.client) current_user.client.images += the_eye.placed_images + to_chat(current_user, "Transit location designated") + return + +/obj/machinery/computer/camera_advanced/shuttle_docker/proc/canDesignateTarget() + if(!designating_target_loc || !current_user || (eyeobj.loc != designating_target_loc) || (stat & (NOPOWER|BROKEN)) ) + return FALSE return TRUE /obj/machinery/computer/camera_advanced/shuttle_docker/proc/rotateLandingSpot() @@ -116,8 +162,7 @@ var/Tmp = coords[1] coords[1] = coords[2] coords[2] = -Tmp - pic.pixel_x = coords[1] * 32 - pic.pixel_y = coords[2] * 32 + pic.loc = locate(the_eye.x + coords[1], the_eye.y + coords[2], the_eye.z) var/Tmp = x_offset x_offset = y_offset y_offset = -Tmp @@ -128,41 +173,65 @@ var/turf/eyeturf = get_turf(the_eye) if(!eyeturf) return + . = SHUTTLE_DOCKER_LANDING_CLEAR var/list/bounds = shuttle_port.return_coords(the_eye.x - x_offset, the_eye.y - y_offset, the_eye.dir) var/list/overlappers = SSshuttle.get_dock_overlap(bounds[1], bounds[2], bounds[3], bounds[4], the_eye.z) - . = TRUE var/list/image_cache = the_eye.placement_images for(var/i in 1 to image_cache.len) var/image/I = image_cache[i] - I.loc = eyeturf var/list/coords = image_cache[I] var/turf/T = locate(eyeturf.x + coords[1], eyeturf.y + coords[2], eyeturf.z) - if(checkLandingTurf(T, overlappers)) - I.icon_state = "green" - else - I.icon_state = "red" - . = FALSE + I.loc = T + switch(checkLandingTurf(T, overlappers)) + if(SHUTTLE_DOCKER_LANDING_CLEAR) + I.icon_state = "green" + if(SHUTTLE_DOCKER_BLOCKED_BY_HIDDEN_PORT) + I.icon_state = "green" + if(. == SHUTTLE_DOCKER_LANDING_CLEAR) + . = SHUTTLE_DOCKER_BLOCKED_BY_HIDDEN_PORT + else + I.icon_state = "red" + . = SHUTTLE_DOCKER_BLOCKED + +/obj/machinery/computer/camera_advanced/shuttle_docker/proc/checkLandingTurf(turf/T, list/overlappers) + // Too close to the map edge is never allowed + if(!T || T.x == 1 || T.y == 1 || T.x == world.maxx || T.y == world.maxy) + return SHUTTLE_DOCKER_BLOCKED + // If it's one of our shuttle areas assume it's ok to be there + if(shuttle_port.shuttle_areas[T.loc]) + return SHUTTLE_DOCKER_LANDING_CLEAR + . = SHUTTLE_DOCKER_LANDING_CLEAR + // See if the turf is hidden from us + var/list/hidden_turf_info + if(!see_hidden) + hidden_turf_info = SSshuttle.hidden_shuttle_turfs[T] + if(hidden_turf_info) + . = SHUTTLE_DOCKER_BLOCKED_BY_HIDDEN_PORT + + if(space_turfs_only) + var/turf_type = hidden_turf_info ? hidden_turf_info[2] : T.type + if(!ispath(turf_type, /turf/open/space)) + return SHUTTLE_DOCKER_BLOCKED -/obj/machinery/computer/camera_advanced/shuttle_docker/proc/checkLandingTurf(turf/T, list/overlappers) - // Too close to the map edge is never allowed - if(!T || T.x == 1 || T.y == 1 || T.x == world.maxx || T.y == world.maxy) - return FALSE - // If it's one of our shuttle areas assume it's ok to be there - if(shuttle_port.shuttle_areas[T.loc]) - return TRUE // Checking for overlapping dock boundaries for(var/i in 1 to overlappers.len) var/obj/docking_port/port = overlappers[i] if(port == my_port) continue + var/port_hidden = !see_hidden && port.hidden var/list/overlap = overlappers[port] var/list/xs = overlap[1] var/list/ys = overlap[2] if(xs["[T.x]"] && ys["[T.y]"]) - return FALSE - if(space_turfs_only && !isspaceturf(T)) - return FALSE - return TRUE + if(port_hidden) + . = SHUTTLE_DOCKER_BLOCKED_BY_HIDDEN_PORT + else + return SHUTTLE_DOCKER_BLOCKED + +/obj/machinery/computer/camera_advanced/shuttle_docker/proc/update_hidden_docking_ports(list/remove_images, list/add_images) + if(!see_hidden && current_user && current_user.client) + current_user.client.images -= remove_images + current_user.client.images += add_images /mob/camera/aiEye/remote/shuttle_docker visible_icon = FALSE @@ -205,10 +274,7 @@ var/mob/living/C = target var/mob/camera/aiEye/remote/remote_eye = C.remote_control var/obj/machinery/computer/camera_advanced/shuttle_docker/origin = remote_eye.origin - if(origin.placeLandingSpot()) - to_chat(target, "Transit location designated") - else - to_chat(target, "Invalid transit location") + origin.placeLandingSpot(target) /datum/action/innate/camera_jump/shuttle_docker name = "Jump to Location" diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index 51c62029e0..c7a77f9457 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -89,15 +89,23 @@ All ShuttleMove procs go here return loc = newT + return TRUE // Called on atoms after everything has been moved -/atom/movable/proc/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) +/atom/movable/proc/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) + + var/turf/newT = get_turf(src) + if (newT.z != oldT.z) + onTransitZ(oldT.z, newT.z) + if(light) update_light() if(rotation) shuttleRotate(rotation) + + update_parallax_contents() return TRUE @@ -148,7 +156,7 @@ All ShuttleMove procs go here A.air_tight = TRUE INVOKE_ASYNC(A, /obj/machinery/door/.proc/close) -/obj/machinery/door/airlock/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) +/obj/machinery/door/airlock/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() shuttledocked = 1 for(var/obj/machinery/door/airlock/A in range(1, src)) @@ -160,24 +168,24 @@ All ShuttleMove procs go here . |= MOVE_CONTENTS GLOB.cameranet.removeCamera(src) -/obj/machinery/camera/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) +/obj/machinery/camera/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() GLOB.cameranet.addCamera(src) -/obj/machinery/telecomms/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) +/obj/machinery/telecomms/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() listening_level = z // Update listening Z, just in case you have telecomm relay on a shuttle -/obj/machinery/mech_bay_recharge_port/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir) +/obj/machinery/mech_bay_recharge_port/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir) . = ..() recharging_turf = get_step(loc, dir) -/obj/machinery/atmospherics/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) +/obj/machinery/atmospherics/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() if(pipe_vision_img) pipe_vision_img.loc = loc -/obj/machinery/computer/auxillary_base/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) +/obj/machinery/computer/auxillary_base/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() if(z == ZLEVEL_MINING) //Avoids double logging and landing on other Z-levels due to badminnery SSblackbox.record_feedback("associative", "colonies_dropped", 1, list("x" = x, "y" = y, "z" = z)) @@ -187,7 +195,7 @@ All ShuttleMove procs go here on = FALSE update_list() -/obj/machinery/gravity_generator/main/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) +/obj/machinery/gravity_generator/main/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() if(charge_count != 0 && charging_state != POWER_UP) on = TRUE @@ -198,7 +206,7 @@ All ShuttleMove procs go here if(. & MOVE_AREA) . |= MOVE_CONTENTS -/obj/machinery/atmospherics/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) +/obj/machinery/atmospherics/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() var/missing_nodes = FALSE for(DEVICE_TYPE_LOOP) @@ -227,7 +235,7 @@ All ShuttleMove procs go here // atmosinit() calls update_icon(), so we don't need to call it update_icon() -/obj/machinery/atmospherics/pipe/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) +/obj/machinery/atmospherics/pipe/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() var/turf/T = loc hide(T.intact) @@ -237,7 +245,7 @@ All ShuttleMove procs go here GLOB.navbeacons["[z]"] -= src GLOB.deliverybeacons -= src -/obj/machinery/navbeacon/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) +/obj/machinery/navbeacon/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() var/turf/T = loc hide(T.intact) @@ -249,7 +257,7 @@ All ShuttleMove procs go here GLOB.deliverybeacons += src GLOB.deliverybeacontags += location -/obj/machinery/power/terminal/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) +/obj/machinery/power/terminal/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() var/turf/T = src.loc if(level==1) @@ -257,7 +265,7 @@ All ShuttleMove procs go here /************************************Item move procs************************************/ -/obj/item/storage/pod/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) +/obj/item/storage/pod/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() unlocked = TRUE // If the pod was launched, the storage will always open. @@ -269,7 +277,7 @@ All ShuttleMove procs go here return . = ..() -/mob/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) +/mob/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) if(!move_on_shuttle) return . = ..() @@ -279,7 +287,7 @@ All ShuttleMove procs go here shake_force *= 0.25 shake_camera(src, shake_force, 1) -/mob/living/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) +/mob/living/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() if(movement_force && !buckled) if(movement_force["THROW"]) @@ -307,11 +315,11 @@ All ShuttleMove procs go here if(. & MOVE_AREA) . |= MOVE_CONTENTS -/obj/structure/disposalpipe/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) +/obj/structure/disposalpipe/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() update() -/obj/structure/cable/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) +/obj/structure/cable/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() var/turf/T = loc if(level==1) @@ -328,9 +336,6 @@ All ShuttleMove procs go here /atom/movable/lighting_object/onShuttleMove() return FALSE -/atom/movable/light/onShuttleMove() - return FALSE - /obj/docking_port/stationary/onShuttleMove(turf/newT, turf/oldT, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock) if(!moving_dock.can_move_docking_ports || old_dock == src) return FALSE diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 2f0fb711bd..3811fa0e4a 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -24,6 +24,7 @@ var/area_type var/turf_type var/baseturf_type + var/hidden = FALSE //are we invisible to shuttle navigation computers? //these objects are indestructible /obj/docking_port/Destroy(force) @@ -84,15 +85,7 @@ //returns turfs within our projected rectangle in a specific order. //this ensures that turfs are copied over in the same order, regardless of any rotation -/obj/docking_port/proc/return_ordered_turfs(_x, _y, _z, _dir, area_type) - if(!_dir) - _dir = dir - if(!_x) - _x = x - if(!_y) - _y = y - if(!_z) - _z = z +/obj/docking_port/proc/return_ordered_turfs(_x, _y, _z, _dir) var/cos = 1 var/sin = 0 switch(_dir) @@ -108,52 +101,14 @@ . = list() - var/xi - var/yi - for(var/dx=0, dx 0) change_per_engine = (1 - ENGINE_COEFF_MIN) / initial_engines // or however many it had - return Clamp(1 - delta * change_per_engine,ENGINE_COEFF_MIN,ENGINE_COEFF_MAX) + return CLAMP(1 - delta * change_per_engine,ENGINE_COEFF_MIN,ENGINE_COEFF_MAX) if(new_value < initial_engines) var/delta = initial_engines - new_value var/change_per_engine = 1 //doesn't really matter should not be happening for 0 engine shuttles if(initial_engines > 0) change_per_engine = (ENGINE_COEFF_MAX - 1) / initial_engines //just linear drop to max delay - return Clamp(1 + delta * change_per_engine,ENGINE_COEFF_MIN,ENGINE_COEFF_MAX) + return CLAMP(1 + delta * change_per_engine,ENGINE_COEFF_MIN,ENGINE_COEFF_MAX) /obj/docking_port/mobile/proc/in_flight() diff --git a/code/modules/shuttle/shuttle_rotate.dm b/code/modules/shuttle/shuttle_rotate.dm index d322f2cd32..49c7396dba 100644 --- a/code/modules/shuttle/shuttle_rotate.dm +++ b/code/modules/shuttle/shuttle_rotate.dm @@ -48,10 +48,6 @@ If ever any of these procs are useful for non-shuttles, rename it to proc/rotate /************************************Structure rotate procs************************************/ -/obj/structure/door_assembly/door_assembly_pod/shuttleRotate(rotation, params) - . = ..() - expected_dir = angle2dir(rotation+dir2angle(dir)) - /obj/structure/cable/shuttleRotate(rotation, params) params &= ~ROTATE_DIR . = ..() @@ -105,10 +101,6 @@ If ever any of these procs are useful for non-shuttles, rename it to proc/rotate params = NONE return ..() -/obj/machinery/door/airlock/survival_pod/shuttleRotate(rotation, params) - expected_dir = angle2dir(rotation+dir2angle(dir)) - return ..() - //prevents shuttles attempting to rotate this since it messes up sprites /obj/machinery/gravity_generator/shuttleRotate(rotation, params) params = NONE diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index b73cfb05e2..579397cc4b 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -17,7 +17,7 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list( /obj/effect/clockwork/spatial_gateway, /obj/structure/destructible/clockwork/powered/clockwork_obelisk, /obj/item/device/warp_cube, - /obj/machinery/r_n_d/protolathe, //print tracking beacons, send shuttle + /obj/machinery/rnd/protolathe, //print tracking beacons, send shuttle /obj/machinery/autolathe, //same /obj/item/projectile/beam/wormhole, /obj/effect/portal, diff --git a/code/modules/shuttle/syndicate.dm b/code/modules/shuttle/syndicate.dm index 4574e62bd1..283ac0f35c 100644 --- a/code/modules/shuttle/syndicate.dm +++ b/code/modules/shuttle/syndicate.dm @@ -58,5 +58,6 @@ view_range = 13 x_offset = -4 y_offset = -2 + see_hidden = TRUE #undef SYNDICATE_CHALLENGE_TIMER \ No newline at end of file diff --git a/code/modules/shuttle/white_ship.dm b/code/modules/shuttle/white_ship.dm index b6775fea82..46aa4b6576 100644 --- a/code/modules/shuttle/white_ship.dm +++ b/code/modules/shuttle/white_ship.dm @@ -1,18 +1,19 @@ -/obj/machinery/computer/shuttle/white_ship - name = "White Ship Console" - desc = "Used to control the White Ship." - circuit = /obj/item/circuitboard/computer/white_ship - shuttleId = "whiteship" - possible_destinations = "whiteship_away;whiteship_home;whiteship_z4;whiteship_lavaland;whiteship_custom" - -/obj/machinery/computer/camera_advanced/shuttle_docker/whiteship - name = "White Ship Navigation Computer" - desc = "Used to designate a precise transit location for the White Ship." - shuttleId = "whiteship" - station_lock_override = TRUE - shuttlePortId = "whiteship_custom" - shuttlePortName = "Custom Location" - jumpto_ports = list("whiteship_away" = 1, "whiteship_home" = 1, "whiteship_z4" = 1) - view_range = 20 - x_offset = -6 - y_offset = -10 +/obj/machinery/computer/shuttle/white_ship + name = "White Ship Console" + desc = "Used to control the White Ship." + circuit = /obj/item/circuitboard/computer/white_ship + shuttleId = "whiteship" + possible_destinations = "whiteship_away;whiteship_home;whiteship_z4;whiteship_lavaland;whiteship_custom" + +/obj/machinery/computer/camera_advanced/shuttle_docker/whiteship + name = "White Ship Navigation Computer" + desc = "Used to designate a precise transit location for the White Ship." + shuttleId = "whiteship" + station_lock_override = TRUE + shuttlePortId = "whiteship_custom" + shuttlePortName = "Custom Location" + jumpto_ports = list("whiteship_away" = 1, "whiteship_home" = 1, "whiteship_z4" = 1) + view_range = 18 + x_offset = -6 + y_offset = -10 + designate_time = 100 diff --git a/code/modules/space_transition/space_transition.dm b/code/modules/space_transition/space_transition.dm index e1a4c743bf..2a8be8a761 100644 --- a/code/modules/space_transition/space_transition.dm +++ b/code/modules/space_transition/space_transition.dm @@ -1,10 +1,5 @@ //This is a simple 3 by 3 grid working off the corpse of the space torus. The donut is dead, cube has been avenged! -#define Z_LEVEL_NORTH "1" -#define Z_LEVEL_SOUTH "2" -#define Z_LEVEL_EAST "4" -#define Z_LEVEL_WEST "8" - GLOBAL_LIST_EMPTY(z_levels_list) /datum/space_level @@ -19,7 +14,7 @@ GLOBAL_LIST_EMPTY(z_levels_list) linked = transition_type if(linked == SELFLOOPING) neigbours = list() - var/list/L = list(Z_LEVEL_NORTH,Z_LEVEL_SOUTH,Z_LEVEL_EAST,Z_LEVEL_WEST) + var/list/L = list(TEXT_NORTH,TEXT_SOUTH,TEXT_EAST,TEXT_WEST) for(var/A in L) neigbours[A] = src @@ -27,18 +22,18 @@ GLOBAL_LIST_EMPTY(z_levels_list) for(var/datum/point/P in L) if(P.x == xi) if(P.y == yi+1) - neigbours[Z_LEVEL_NORTH] = P.spl - P.spl.neigbours[Z_LEVEL_SOUTH] = src + neigbours[TEXT_NORTH] = P.spl + P.spl.neigbours[TEXT_SOUTH] = src else if(P.y == yi-1) - neigbours[Z_LEVEL_SOUTH] = P.spl - P.spl.neigbours[Z_LEVEL_NORTH] = src + neigbours[TEXT_SOUTH] = P.spl + P.spl.neigbours[TEXT_NORTH] = src else if(P.y == yi) if(P.x == xi+1) - neigbours[Z_LEVEL_EAST] = P.spl - P.spl.neigbours[Z_LEVEL_WEST] = src + neigbours[TEXT_EAST] = P.spl + P.spl.neigbours[TEXT_WEST] = src else if(P.x == xi-1) - neigbours[Z_LEVEL_WEST] = P.spl - P.spl.neigbours[Z_LEVEL_EAST] = src + neigbours[TEXT_WEST] = P.spl + P.spl.neigbours[TEXT_EAST] = src /datum/point //this is explicitly utilitarian datum type made specially for the space map generation and are absolutely unusable for anything else var/list/neigbours = list() @@ -157,8 +152,3 @@ GLOBAL_LIST_EMPTY(z_levels_list) for(var/A in grid) GLOB.z_levels_list[A] = grid[A] - -#undef Z_LEVEL_NORTH -#undef Z_LEVEL_SOUTH -#undef Z_LEVEL_EAST -#undef Z_LEVEL_WEST diff --git a/code/modules/spells/spell_types/conjure.dm b/code/modules/spells/spell_types/conjure.dm index 87c1b8de44..306c3fcef6 100644 --- a/code/modules/spells/spell_types/conjure.dm +++ b/code/modules/spells/spell_types/conjure.dm @@ -56,6 +56,18 @@ range = 3 newVars = list("emagged" = 2, "remote_disabled" = 1,"shoot_sound" = 'sound/weapons/laser.ogg',"projectile" = /obj/item/projectile/beam/laser, "declare_arrests" = 0,"name" = "Wizard's Justicebot") +/obj/effect/proc_holder/spell/aoe_turf/conjure/linkWorlds + name = "Link Worlds" + desc = "A whole new dimension for you to play with! They won't be happy about it, though." + invocation = "WTF" + clothes_req = FALSE + charge_max = 600 + cooldown_min = 200 + summon_type = list(/mob/living/simple_animal/hostile/spawner/nether) + summon_amt = 1 + range = 1 + cast_sound = 'sound/weapons/marauder.ogg' + /obj/effect/proc_holder/spell/targeted/conjure_item name = "Summon weapon" desc = "A generic spell that should not exist. This summons an instance of a specific type of item, or if one already exists, un-summons it. Summons into hand if possible." diff --git a/code/modules/spells/spell_types/rightandwrong.dm b/code/modules/spells/spell_types/rightandwrong.dm index b992871004..7ab3121a3a 100644 --- a/code/modules/spells/spell_types/rightandwrong.dm +++ b/code/modules/spells/spell_types/rightandwrong.dm @@ -22,12 +22,14 @@ guns.owner = H.mind H.mind.objectives += guns H.mind.special_role = "survivalist" + H.mind.add_antag_datum(/datum/antagonist/auto_custom) to_chat(H, "You are the survivalist! Your own safety matters above all else, and the only way to ensure your safety is to stockpile weapons! Grab as many guns as possible, by any means necessary. Kill anyone who gets in your way.") else var/datum/objective/steal_five_of_type/summon_magic/magic = new magic.owner = H.mind H.mind.objectives += magic H.mind.special_role = "amateur magician" + H.mind.add_antag_datum(/datum/antagonist/auto_custom) to_chat(H, "You are the amateur magician! Grow your newfound talent! Grab as many magical artefacts as possible, by any means necessary. Kill anyone who gets in your way.") var/datum/objective/survive/survive = new survive.owner = H.mind diff --git a/code/modules/spells/spell_types/voice_of_god.dm b/code/modules/spells/spell_types/voice_of_god.dm index a5b44b8e0f..eb8950086c 100644 --- a/code/modules/spells/spell_types/voice_of_god.dm +++ b/code/modules/spells/spell_types/voice_of_god.dm @@ -31,9 +31,8 @@ ..() /obj/effect/proc_holder/spell/voice_of_god/cast(list/targets, mob/user = usr) - user.say(uppertext(command), spans = spans, sanitize = FALSE) playsound(get_turf(user), speech_sound, 300, 1, 5) - var/cooldown = voice_of_god(command, user, spans, base_multiplier = power_mod) + var/cooldown = voice_of_god(uppertext(command), user, spans, base_multiplier = power_mod) charge_max = (cooldown * cooldown_mod) /obj/effect/proc_holder/spell/voice_of_god/clown diff --git a/code/modules/spells/spell_types/wizard.dm b/code/modules/spells/spell_types/wizard.dm index 9b120c2e7f..b36dfc885d 100644 --- a/code/modules/spells/spell_types/wizard.dm +++ b/code/modules/spells/spell_types/wizard.dm @@ -209,7 +209,7 @@ summon_amt = 10 range = 3 - summon_type = list(/mob/living/simple_animal/hostile/creature) + summon_type = list(/mob/living/simple_animal/hostile/netherworld) cast_sound = 'sound/magic/summonitems_generic.ogg' /obj/effect/proc_holder/spell/targeted/trigger/blind @@ -289,7 +289,7 @@ var/mob/living/M = AM M.Knockdown(stun_amt) to_chat(M, "You're thrown back by [user]!") - AM.throw_at(throwtarget, ((Clamp((maxthrow - (Clamp(distfromcaster - 2, 0, distfromcaster))), 3, maxthrow))), 1,user)//So stuff gets tossed around at the same time. + AM.throw_at(throwtarget, ((CLAMP((maxthrow - (CLAMP(distfromcaster - 2, 0, distfromcaster))), 3, maxthrow))), 1,user)//So stuff gets tossed around at the same time. /obj/effect/proc_holder/spell/aoe_turf/repulse/xeno //i fixed conflicts only to find out that this is in the WIZARD file instead of the xeno file?! name = "Tail Sweep" diff --git a/code/modules/station_goals/station_goal.dm b/code/modules/station_goals/station_goal.dm index 98ec01f641..88377455c6 100644 --- a/code/modules/station_goals/station_goal.dm +++ b/code/modules/station_goals/station_goal.dm @@ -26,11 +26,11 @@ /datum/station_goal/proc/check_completion() return completed -/datum/station_goal/proc/print_result() +/datum/station_goal/proc/get_result() if(check_completion()) - to_chat(world, "Station Goal : [name] : Completed!") + return "
  • [name] : Completed!
  • " else - to_chat(world, "Station Goal : [name] : Failed!") + return "
  • [name] : Failed!
  • " /datum/station_goal/Destroy() SSticker.mode.station_goals -= src diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index 9784dd115c..63b955a571 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -18,7 +18,7 @@ return 0 var/obj/item/bodypart/affecting = C.get_bodypart("chest") - affecting.receive_damage(Clamp(brute_dam/2, 15, 50), Clamp(burn_dam/2, 0, 50)) //Damage the chest based on limb's existing damage + affecting.receive_damage(CLAMP(brute_dam/2, 15, 50), CLAMP(burn_dam/2, 0, 50)) //Damage the chest based on limb's existing damage C.visible_message("[C]'s [src.name] has been violently dismembered!") C.emote("scream") drop_limb() @@ -102,7 +102,7 @@ for(var/obj/item/I in embedded_objects) embedded_objects -= I - I.loc = src + I.forceMove(src) if(!C.has_embedded_objects()) C.clear_alert("embeddedobject") @@ -142,16 +142,16 @@ //when a limb is dropped, the internal organs are removed from the mob and put into the limb /obj/item/organ/proc/transfer_to_limb(obj/item/bodypart/LB, mob/living/carbon/C) Remove(C) - loc = LB + forceMove(LB) /obj/item/organ/brain/transfer_to_limb(obj/item/bodypart/head/LB, mob/living/carbon/human/C) Remove(C) //Changeling brain concerns are now handled in Remove - loc = LB + forceMove(LB) LB.brain = src if(brainmob) LB.brainmob = brainmob brainmob = null - LB.brainmob.loc = LB + LB.brainmob.forceMove(LB) LB.brainmob.container = LB LB.brainmob.stat = DEAD @@ -167,7 +167,7 @@ ..() if(C && !special) if(C.handcuffed) - C.handcuffed.loc = C.loc + C.handcuffed.forceMove(C.loc) C.handcuffed.dropped(C) C.handcuffed = null C.update_handcuffed() @@ -185,7 +185,7 @@ ..() if(C && !special) if(C.handcuffed) - C.handcuffed.loc = C.loc + C.handcuffed.forceMove(C.loc) C.handcuffed.dropped(C) C.handcuffed = null C.update_handcuffed() @@ -201,7 +201,7 @@ /obj/item/bodypart/r_leg/drop_limb(special) if(owner && !special) if(owner.legcuffed) - owner.legcuffed.loc = owner.loc + owner.legcuffed.forceMove(owner.loc) owner.legcuffed.dropped(owner) owner.legcuffed = null owner.update_inv_legcuffed() @@ -212,7 +212,7 @@ /obj/item/bodypart/l_leg/drop_limb(special) //copypasta if(owner && !special) if(owner.legcuffed) - owner.legcuffed.loc = owner.loc + owner.legcuffed.forceMove(owner.loc) owner.legcuffed.dropped(owner) owner.legcuffed = null owner.update_inv_legcuffed() @@ -236,6 +236,11 @@ if(pill) pill.forceMove(src) + //Make sure de-zombification happens before organ removal instead of during it + var/obj/item/organ/zombie_infection/ooze = owner.getorganslot(ORGAN_SLOT_ZOMBIE) + if(istype(ooze)) + ooze.transfer_to_limb(src, owner) + name = "[owner.real_name]'s head" ..() @@ -265,7 +270,7 @@ attach_limb(C, special) /obj/item/bodypart/proc/attach_limb(mob/living/carbon/C, special) - loc = null + moveToNullspace() owner = C C.bodyparts += src if(held_index) @@ -306,7 +311,7 @@ if(brain) if(brainmob) brainmob.container = null //Reset brainmob head var. - brainmob.loc = brain //Throw mob into brain. + brainmob.forceMove(brain) //Throw mob into brain. brain.brainmob = brainmob //Set the brain to use the brainmob brainmob = null //Set head brainmob var to null brain.Insert(C) //Now insert the brain proper diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm index a4d317ad2a..f631400bee 100644 --- a/code/modules/surgery/bodyparts/head.dm +++ b/code/modules/surgery/bodyparts/head.dm @@ -41,10 +41,10 @@ user.visible_message("[user] saws [src] open and pulls out a brain!", "You saw [src] open and pull out a brain.") if(brainmob) brainmob.container = null - brainmob.loc = brain + brainmob.forceMove(brain) brain.brainmob = brainmob brainmob = null - brain.loc = T + brain.forceMove(T) brain = null update_icon_dropped() else diff --git a/code/modules/surgery/bodyparts/helpers.dm b/code/modules/surgery/bodyparts/helpers.dm index e460a8c97f..7ac387b4d8 100644 --- a/code/modules/surgery/bodyparts/helpers.dm +++ b/code/modules/surgery/bodyparts/helpers.dm @@ -118,7 +118,7 @@ var/obj/item/bodypart/L = X for(var/obj/item/I in L.embedded_objects) L.embedded_objects -= I - I.loc = T + I.forceMove(T) clear_alert("embeddedobject") diff --git a/code/modules/surgery/brain_surgery.dm b/code/modules/surgery/brain_surgery.dm new file mode 100644 index 0000000000..b22b45efce --- /dev/null +++ b/code/modules/surgery/brain_surgery.dm @@ -0,0 +1,42 @@ +/datum/surgery/brain_surgery + name = "brain surgery" + steps = list( + /datum/surgery_step/incise, + /datum/surgery_step/retract_skin, + /datum/surgery_step/saw, + /datum/surgery_step/clamp_bleeders, + /datum/surgery_step/fix_brain, + /datum/surgery_step/close) + + species = list(/mob/living/carbon/human, /mob/living/carbon/monkey) + possible_locs = list("head") + requires_bodypart_type = 0 + +/datum/surgery_step/fix_brain + name = "fix brain" + implements = list(/obj/item/hemostat = 85, /obj/item/screwdriver = 35, /obj/item/pen = 15) //don't worry, pouring some alcohol on their open brain will get that chance to 100 + time = 120 //long and complicated + +/datum/surgery/brain_surgery/can_start(mob/user, mob/living/carbon/target) + var/obj/item/organ/brain/B = target.getorganslot(ORGAN_SLOT_BRAIN) + if(!B) + to_chat(user, "It's hard to do surgery on someone's brain when they don't have one.") + return FALSE + return TRUE + +/datum/surgery_step/fix_brain/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + user.visible_message("[user] begins to fix [target]'s brain.", "You begin to fix [target]'s brain...") + +/datum/surgery_step/fix_brain/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + user.visible_message("[user] successfully fixes [target]'s brain!", "You succeed in fixing [target]'s brain.") + target.adjustBrainLoss(-60) + target.cure_all_traumas() + return TRUE + +/datum/surgery_step/fix_brain/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + if(target.getorganslot(ORGAN_SLOT_BRAIN)) + user.visible_message("[user] screws up, causing more damage!", "You screw up, causing more damage!") + target.adjustBrainLoss(80) + else + user.visible_message("[user] suddenly notices that the brain [user.p_they()] [user.p_were()] working on is not there anymore.", "You suddenly notice that the brain you were working on is not there anymore.") + return FALSE \ No newline at end of file diff --git a/code/modules/surgery/eye_surgery.dm b/code/modules/surgery/eye_surgery.dm index 6c340b61f5..c8a47d2096 100644 --- a/code/modules/surgery/eye_surgery.dm +++ b/code/modules/surgery/eye_surgery.dm @@ -16,6 +16,7 @@ if(!E) to_chat(user, "It's hard to do surgery on someone's eyes when they don't have any.") return FALSE + return TRUE /datum/surgery_step/fix_eyes/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) user.visible_message("[user] begins to fix [target]'s eyes.", "You begin to fix [target]'s eyes...") @@ -32,7 +33,7 @@ /datum/surgery_step/fix_eyes/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) if(target.getorgan(/obj/item/organ/brain)) user.visible_message("[user] accidentally stabs [target] right in the brain!", "You accidentally stab [target] right in the brain!") - target.adjustBrainLoss(100) + target.adjustBrainLoss(70) else user.visible_message("[user] accidentally stabs [target] right in the brain! Or would have, if [target] had a brain.", "You accidentally stab [target] right in the brain! Or would have, if [target] had a brain.") return FALSE \ No newline at end of file diff --git a/code/modules/surgery/organ_manipulation.dm b/code/modules/surgery/organ_manipulation.dm index f477535dab..dc8b3543fa 100644 --- a/code/modules/surgery/organ_manipulation.dm +++ b/code/modules/surgery/organ_manipulation.dm @@ -176,7 +176,7 @@ "You successfully extract [I] from [target]'s [parse_zone(target_zone)].") add_logs(user, target, "surgically removed [I.name] from", addition="INTENT: [uppertext(user.a_intent)]") I.Remove(target) - I.loc = get_turf(target) + I.forceMove(get_turf(target)) else user.visible_message("[user] can't seem to extract anything from [target]'s [parse_zone(target_zone)]!", "You can't extract anything from [target]'s [parse_zone(target_zone)]!") diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm index aa1ea10cd0..a90923e58f 100644 --- a/code/modules/surgery/organs/augments_arms.dm +++ b/code/modules/surgery/organs/augments_arms.dm @@ -61,7 +61,7 @@ /obj/item/organ/cyberimp/arm/emag_act() return 0 -/obj/item/organ/cyberimp/arm/gun/emp_act(severity) +/obj/item/organ/cyberimp/arm/emp_act(severity) if(prob(15/severity) && owner) to_chat(owner, "[src] is hit by EMP!") // give the owner an idea about why his implant is glitching @@ -161,7 +161,6 @@ name = "arm-mounted laser implant" desc = "A variant of the arm cannon implant that fires lethal laser beams. The cannon emerges from the subject's arm and remains inside when not in use." icon_state = "arm_laser" - origin_tech = "materials=4;combat=4;biotech=4;powerstorage=4;syndicate=3" contents = newlist(/obj/item/gun/energy/laser/mounted) /obj/item/organ/cyberimp/arm/gun/laser/l @@ -172,7 +171,6 @@ name = "arm-mounted taser implant" desc = "A variant of the arm cannon implant that fires electrodes and disabler shots. The cannon emerges from the subject's arm and remains inside when not in use." icon_state = "arm_taser" - origin_tech = "materials=5;combat=5;biotech=4;powerstorage=4" contents = newlist(/obj/item/gun/energy/e_gun/advtaser/mounted) /obj/item/organ/cyberimp/arm/gun/taser/l @@ -182,7 +180,6 @@ /obj/item/organ/cyberimp/arm/toolset name = "integrated toolset implant" desc = "A stripped-down version of the engineering cyborg toolset, designed to be installed on subject's arm. Contains all necessary tools." - origin_tech = "materials=3;engineering=4;biotech=3;powerstorage=4" contents = newlist(/obj/item/screwdriver/cyborg, /obj/item/wrench/cyborg, /obj/item/weldingtool/largetank/cyborg, /obj/item/crowbar/cyborg, /obj/item/wirecutters/cyborg, /obj/item/device/multitool/cyborg) @@ -200,19 +197,17 @@ name = "arm-mounted energy blade" desc = "An illegal and highly dangerous cybernetic implant that can project a deadly blade of concentrated energy." contents = newlist(/obj/item/melee/transforming/energy/blade/hardlight) - origin_tech = "materials=4;combat=5;biotech=3;powerstorage=2;syndicate=5" /obj/item/organ/cyberimp/arm/medibeam name = "integrated medical beamgun" desc = "A cybernetic implant that allows the user to project a healing beam from their hand." contents = newlist(/obj/item/gun/medbeam) - origin_tech = "materials=5;combat=2;biotech=5;powerstorage=4;syndicate=1" + /obj/item/organ/cyberimp/arm/flash name = "integrated high-intensity photon projector" //Why not desc = "An integrated projector mounted onto a user's arm that is able to be used as a powerful flash." contents = newlist(/obj/item/device/assembly/flash/armimplant) - origin_tech = "materials=4;combat=3;biotech=4;magnets=4;powerstorage=3" /obj/item/organ/cyberimp/arm/flash/Initialize() . = ..() @@ -224,13 +219,11 @@ name = "arm electrification implant" desc = "An illegal combat implant that allows the user to administer disabling shocks from their arm." contents = newlist(/obj/item/borg/stun) - origin_tech = "materials=3;combat=5;biotech=4;powerstorage=4;syndicate=3" /obj/item/organ/cyberimp/arm/combat name = "combat cybernetics implant" desc = "A powerful cybernetic implant that contains combat modules built into the user's arm." contents = newlist(/obj/item/melee/transforming/energy/blade/hardlight, /obj/item/gun/medbeam, /obj/item/borg/stun, /obj/item/device/assembly/flash/armimplant) - origin_tech = "materials=5;combat=7;biotech=5;powerstorage=5;syndicate=6;programming=5" /obj/item/organ/cyberimp/arm/combat/Initialize() . = ..() @@ -242,4 +235,3 @@ name = "surgical toolset implant" desc = "A set of surgical tools hidden behind a concealed panel on the user's arm." contents = newlist(/obj/item/retractor/augment, /obj/item/hemostat/augment, /obj/item/cautery/augment, /obj/item/surgicaldrill/augment, /obj/item/scalpel/augment, /obj/item/circular_saw/augment, /obj/item/surgical_drapes) - origin_tech = "materials=3;engineering=3;biotech=3;programming=2;magnets=3" diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm index 1e93c4df4a..a6635ed78d 100644 --- a/code/modules/surgery/organs/augments_chest.dm +++ b/code/modules/surgery/organs/augments_chest.dm @@ -14,7 +14,6 @@ var/synthesizing = 0 var/poison_amount = 5 slot = ORGAN_SLOT_STOMACH - origin_tech = "materials=2;powerstorage=2;biotech=2" /obj/item/organ/cyberimp/chest/nutriment/on_life() if(synthesizing) @@ -43,14 +42,12 @@ implant_color = "#006607" hunger_threshold = NUTRITION_LEVEL_HUNGRY poison_amount = 10 - origin_tech = "materials=4;powerstorage=3;biotech=3" /obj/item/organ/cyberimp/chest/reviver name = "Reviver implant" desc = "This implant will attempt to revive you if you lose consciousness. For the faint of heart!" icon_state = "chest_implant" implant_color = "#AD0000" - origin_tech = "materials=5;programming=4;biotech=4" slot = ORGAN_SLOT_HEART_AID var/revive_cost = 0 var/reviving = 0 @@ -122,7 +119,6 @@ Unlike regular jetpack, this device has no stabilization system." slot = ORGAN_SLOT_THRUSTERS icon_state = "imp_jetpack" - origin_tech = "materials=4;magnets=4;biotech=4;engineering=5" implant_overlay = null implant_color = null actions_types = list(/datum/action/item_action/organ_action/toggle) diff --git a/code/modules/surgery/organs/augments_eyes.dm b/code/modules/surgery/organs/augments_eyes.dm index 29fc6f1ac2..37cbb9e022 100644 --- a/code/modules/surgery/organs/augments_eyes.dm +++ b/code/modules/surgery/organs/augments_eyes.dm @@ -29,13 +29,11 @@ /obj/item/organ/cyberimp/eyes/hud/medical name = "Medical HUD implant" desc = "These cybernetic eye implants will display a medical HUD over everything you see." - origin_tech = "materials=4;programming=4;biotech=4" HUD_type = DATA_HUD_MEDICAL_ADVANCED /obj/item/organ/cyberimp/eyes/hud/security name = "Security HUD implant" desc = "These cybernetic eye implants will display a security HUD over everything you see." - origin_tech = "materials=4;programming=4;biotech=3;combat=3" HUD_type = DATA_HUD_SECURITY_ADVANCED /obj/item/organ/cyberimp/eyes/hud/security/syndicate diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm index a6c1517faa..7e209a1de0 100644 --- a/code/modules/surgery/organs/augments_internal.dm +++ b/code/modules/surgery/organs/augments_internal.dm @@ -45,7 +45,6 @@ var/list/stored_items = list() implant_color = "#DE7E00" slot = ORGAN_SLOT_BRAIN_ANTIDROP - origin_tech = "materials=4;programming=5;biotech=4" actions_types = list(/datum/action/item_action/organ_action/toggle) /obj/item/organ/cyberimp/brain/anti_drop/ui_action_click() @@ -102,7 +101,6 @@ desc = "This implant will automatically give you back control over your central nervous system, reducing downtime when stunned." implant_color = "#FFFF00" slot = ORGAN_SLOT_BRAIN_ANTISTUN - origin_tech = "materials=5;programming=4;biotech=5" /obj/item/organ/cyberimp/brain/anti_stun/on_life() ..() @@ -135,7 +133,6 @@ icon_state = "implant_mask" slot = ORGAN_SLOT_BREATHING_TUBE w_class = WEIGHT_CLASS_TINY - origin_tech = "materials=2;biotech=3" /obj/item/organ/cyberimp/mouth/breathing_tube/emp_act(severity) if(prob(60/severity)) diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index 75d4aa0bcc..f8f57c650f 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -103,7 +103,6 @@ name = "thermal eyes" desc = "These cybernetic eye implants will give you thermal vision. Vertical slit pupil included." eye_color = "FC0" - origin_tech = "materials=5;programming=4;biotech=4;magnets=4;syndicate=1" sight_flags = SEE_MOBS lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE flash_protect = -1 @@ -141,7 +140,6 @@ /obj/item/organ/eyes/robotic/shield name = "shielded robotic eyes" desc = "These reactive micro-shields will protect you from welders and flashes without obscuring your vision." - origin_tech = "materials=4;biotech=3;engineering=4;plasmatech=3" flash_protect = 2 /obj/item/organ/eyes/robotic/shield/emp_act(severity) @@ -152,7 +150,6 @@ /obj/item/organ/eyes/robotic/glow name = "High Luminosity Eyes" desc = "Special glowing eyes, used by snowflakes who want to be special." - origin_tech = "materials=3;biotech=3;engineering=3;magnets=4" eye_color = "000" actions_types = list(/datum/action/item_action/organ_action/use, /datum/action/item_action/organ_action/toggle) var/current_color_string = "#ffffff" @@ -202,7 +199,7 @@ return var/range = input(user, "Enter range (0 - [max_light_beam_distance])", "Range Select", 0) as null|num - set_distance(Clamp(range, 0, max_light_beam_distance)) + set_distance(CLAMP(range, 0, max_light_beam_distance)) assume_rgb(C) /obj/item/organ/eyes/robotic/glow/proc/assume_rgb(newcolor) diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm index 30825f46bb..21d15fb609 100644 --- a/code/modules/surgery/organs/heart.dm +++ b/code/modules/surgery/organs/heart.dm @@ -4,7 +4,6 @@ icon_state = "heart-on" zone = "chest" slot = ORGAN_SLOT_HEART - origin_tech = "biotech=5" // Heart attack code is in code/modules/mob/living/carbon/human/life.dm var/beating = 1 var/icon_base = "heart" @@ -54,7 +53,7 @@ var/sound/slowbeat = sound('sound/health/slowbeat.ogg', repeat = TRUE) var/sound/fastbeat = sound('sound/health/fastbeat.ogg', repeat = TRUE) var/mob/living/carbon/H = owner - + if(H.health <= HEALTH_THRESHOLD_CRIT && beat != BEAT_SLOW) beat = BEAT_SLOW H.playsound_local(get_turf(H), slowbeat,40,0, channel = CHANNEL_HEARTBEAT) @@ -63,16 +62,19 @@ H.stop_sound_channel(CHANNEL_HEARTBEAT) beat = BEAT_NONE - if(H.jitteriness && H.health > HEALTH_THRESHOLD_FULLCRIT && (!beat || beat == BEAT_SLOW)) - H.playsound_local(get_turf(H),fastbeat,40,0, channel = CHANNEL_HEARTBEAT) - beat = BEAT_FAST + if(H.jitteriness) + if(H.health > HEALTH_THRESHOLD_FULLCRIT && (!beat || beat == BEAT_SLOW)) + H.playsound_local(get_turf(H),fastbeat,40,0, channel = CHANNEL_HEARTBEAT) + beat = BEAT_FAST + else if(beat == BEAT_FAST) + H.stop_sound_channel(CHANNEL_HEARTBEAT) + beat = BEAT_NONE /obj/item/organ/heart/cursed name = "cursed heart" desc = "A heart that, when inserted, will force you to pump it manually." icon_state = "cursedheart-off" icon_base = "cursedheart" - origin_tech = "biotech=6" actions_types = list(/datum/action/item_action/organ_action/cursed_heart) var/last_pump = 0 var/add_colour = TRUE //So we're not constantly recreating colour datums @@ -147,7 +149,6 @@ name = "cybernetic heart" desc = "An electronic device designed to mimic the functions of an organic human heart. Offers no benefit over an organic heart other than being easy to make." icon_state = "heart-c" - origin_tech = "biotech=5" /obj/item/organ/heart/cybernetic/emp_act() Stop() diff --git a/code/modules/surgery/organs/liver.dm b/code/modules/surgery/organs/liver.dm index 352958d9b8..d2de50ce3e 100755 --- a/code/modules/surgery/organs/liver.dm +++ b/code/modules/surgery/organs/liver.dm @@ -5,7 +5,6 @@ /obj/item/organ/liver name = "liver" icon_state = "liver" - origin_tech = "biotech=3" w_class = WEIGHT_CLASS_NORMAL zone = "chest" slot = ORGAN_SLOT_LIVER @@ -68,13 +67,11 @@ name = "cybernetic liver" icon_state = "liver-c" desc = "An electronic device designed to mimic the functions of a human liver. It has no benefits over an organic liver, but is easy to produce." - origin_tech = "biotech=4" /obj/item/organ/liver/cybernetic/upgraded name = "upgraded cybernetic liver" icon_state = "liver-c-u" desc = "An upgraded version of the cybernetic liver, designed to improve upon organic livers. It is resistant to alcohol poisoning and is very robust at filtering toxins." - origin_tech = "biotech=6" alcohol_tolerance = 0.001 maxHealth = 200 //double the health of a normal liver toxTolerance = 15 //can shrug off up to 15u of toxins diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index 2ed2c2107e..102ac9720f 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -28,7 +28,8 @@ var/safe_toxins_max = 0.05 var/SA_para_min = 1 //Sleeping agent var/SA_sleep_min = 5 //Sleeping agent - var/BZ_trip_balls_min = 1 //BZ gas. + var/BZ_trip_balls_min = 1 //BZ gas + var/gas_stimulation_min = 0.002 //Nitryl and Stimulum var/oxy_breath_dam_min = MIN_TOXIC_GAS_DAMAGE var/oxy_breath_dam_max = MAX_TOXIC_GAS_DAMAGE @@ -110,7 +111,7 @@ if(safe_oxygen_max) if(O2_pp > safe_oxygen_max) var/ratio = (breath_gases[/datum/gas/oxygen][MOLES]/safe_oxygen_max) * 10 - H.apply_damage_type(Clamp(ratio, oxy_breath_dam_min, oxy_breath_dam_max), oxy_damage_type) + H.apply_damage_type(CLAMP(ratio, oxy_breath_dam_min, oxy_breath_dam_max), oxy_damage_type) H.throw_alert("too_much_oxy", /obj/screen/alert/too_much_oxy) else H.clear_alert("too_much_oxy") @@ -138,7 +139,7 @@ if(safe_nitro_max) if(N2_pp > safe_nitro_max) var/ratio = (breath_gases[/datum/gas/nitrogen][MOLES]/safe_nitro_max) * 10 - H.apply_damage_type(Clamp(ratio, nitro_breath_dam_min, nitro_breath_dam_max), nitro_damage_type) + H.apply_damage_type(CLAMP(ratio, nitro_breath_dam_min, nitro_breath_dam_max), nitro_damage_type) H.throw_alert("too_much_nitro", /obj/screen/alert/too_much_nitro) else H.clear_alert("too_much_nitro") @@ -204,7 +205,7 @@ if(safe_toxins_max) if(Toxins_pp > safe_toxins_max) var/ratio = (breath_gases[/datum/gas/plasma][MOLES]/safe_toxins_max) * 10 - H.apply_damage_type(Clamp(ratio, tox_breath_dam_min, tox_breath_dam_max), tox_damage_type) + H.apply_damage_type(CLAMP(ratio, tox_breath_dam_min, tox_breath_dam_max), tox_damage_type) H.throw_alert("too_much_tox", /obj/screen/alert/too_much_tox) else H.clear_alert("too_much_tox") @@ -249,7 +250,7 @@ if(bz_pp > BZ_trip_balls_min) H.hallucination += 20 if(prob(33)) - H.adjustBrainLoss(3) + H.adjustBrainLoss(3, 150) else if(bz_pp > 0.01) H.hallucination += 5//Removed at 2 per tick so this will slowly build up @@ -274,14 +275,14 @@ else H.adjustFireLoss(nitryl_pp/4) gas_breathed = breath_gases[/datum/gas/nitryl][MOLES] - if (gas_breathed > GAS_STIM_MINIMUM) + if (gas_breathed > gas_stimulation_min) H.reagents.add_reagent("nitryl_gas",1) breath_gases[/datum/gas/nitryl][MOLES]-=gas_breathed gas_breathed = 0 // Stimulum gas_breathed = breath_gases[/datum/gas/stimulum][MOLES] - if (gas_breathed > GAS_STIM_MINIMUM) + if (gas_breathed > gas_stimulation_min) H.reagents.add_reagent("stimulum",1) breath_gases[/datum/gas/stimulum][MOLES]-=gas_breathed handle_breath_temperature(breath, H) @@ -355,7 +356,6 @@ name = "cybernetic lungs" desc = "A cybernetic version of the lungs found in traditional humanoid entities. It functions the same as an organic lung and is merely meant as a replacement." icon_state = "lungs-c" - origin_tech = "biotech=4" /obj/item/organ/lungs/cybernetic/emp_act() owner.losebreath = 20 @@ -365,8 +365,6 @@ name = "upgraded cybernetic lungs" desc = "A more advanced version of the stock cybernetic lungs. They are capable of filtering out lower levels of toxins and carbon dioxide." icon_state = "lungs-c-u" - origin_tech = "biotech=5" - safe_toxins_max = 20 safe_co2_max = 20 diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index 4097f3fb47..a384845281 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -3,7 +3,6 @@ icon = 'icons/obj/surgery.dmi' var/mob/living/carbon/owner = null var/status = ORGAN_ORGANIC - origin_tech = "biotech=3" w_class = WEIGHT_CLASS_SMALL throwforce = 0 var/zone = "chest" @@ -29,7 +28,7 @@ owner = M M.internal_organs |= src M.internal_organs_slot[slot] = src - loc = null + moveToNullspace() for(var/X in actions) var/datum/action/A = X A.Grant(M) @@ -66,7 +65,6 @@ S.desc = desc S.icon = icon S.icon_state = icon_state - S.origin_tech = origin_tech S.w_class = w_class return S diff --git a/code/modules/surgery/organs/stomach.dm b/code/modules/surgery/organs/stomach.dm index 2bf34334f4..1422c20c7b 100755 --- a/code/modules/surgery/organs/stomach.dm +++ b/code/modules/surgery/organs/stomach.dm @@ -1,7 +1,6 @@ /obj/item/organ/stomach name = "stomach" icon_state = "stomach" - origin_tech = "biotech=4" w_class = WEIGHT_CLASS_NORMAL zone = "chest" slot = ORGAN_SLOT_STOMACH diff --git a/code/modules/surgery/organs/tongue.dm b/code/modules/surgery/organs/tongue.dm index a8d6e7840a..ba988f450d 100644 --- a/code/modules/surgery/organs/tongue.dm +++ b/code/modules/surgery/organs/tongue.dm @@ -15,7 +15,8 @@ /datum/language/monkey, /datum/language/narsie, /datum/language/beachbum, - /datum/language/ratvar + /datum/language/ratvar, + /datum/language/aphasia )) /obj/item/organ/tongue/Initialize(mapload) diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/vocal_cords.dm index 755d35435d..cc0324ab6a 100644 --- a/code/modules/surgery/organs/vocal_cords.dm +++ b/code/modules/surgery/organs/vocal_cords.dm @@ -108,19 +108,18 @@ return TRUE /obj/item/organ/vocal_cords/colossus/handle_speech(message) - owner.say(uppertext(message), spans = spans, sanitize = FALSE) playsound(get_turf(owner), 'sound/magic/clockwork/invoke_general.ogg', 300, 1, 5) return //voice of god speaks for us /obj/item/organ/vocal_cords/colossus/speak_with(message) - var/cooldown = voice_of_god(message, owner, spans, base_multiplier) + var/cooldown = voice_of_god(uppertext(message), owner, spans, base_multiplier) next_command = world.time + (cooldown * cooldown_mod) ////////////////////////////////////// ///////////VOICE OF GOD/////////////// ////////////////////////////////////// -/proc/voice_of_god(message, mob/living/user, list/span_list, base_multiplier = 1) +/proc/voice_of_god(message, mob/living/user, list/span_list, base_multiplier = 1, include_speaker = FALSE, message_admins = TRUE) var/cooldown = 0 if(!user || !user.can_speak() || user.stat) @@ -135,10 +134,14 @@ else span_list = list() + user.say(message, spans = span_list, sanitize = FALSE) + message = lowertext(message) var/mob/living/list/listeners = list() for(var/mob/living/L in get_hearers_in_view(8, user)) - if(L.can_hear() && !L.null_rod_check() && L != user && L.stat != DEAD) + if(L.can_hear() && !L.null_rod_check() && L.stat != DEAD) + if(L == user && !include_speaker) + continue if(ishuman(L)) var/mob/living/carbon/human/H = L if(istype(H.ears, /obj/item/clothing/ears/earmuffs)) @@ -208,12 +211,12 @@ var/static/regex/stun_words = regex("stop|wait|stand still|hold on|halt") var/static/regex/knockdown_words = regex("drop|fall|trip|knockdown") var/static/regex/sleep_words = regex("sleep|slumber|rest") - var/static/regex/vomit_words = regex("vomit|throw up") - var/static/regex/silence_words = regex("shut up|silence|ssh|quiet|hush") + var/static/regex/vomit_words = regex("vomit|throw up|sick") + var/static/regex/silence_words = regex("shut up|silence|be silent|ssh|quiet|hush") var/static/regex/hallucinate_words = regex("see the truth|hallucinate") var/static/regex/wakeup_words = regex("wake up|awaken") - var/static/regex/heal_words = regex("live|heal|survive|mend|heroes never die") - var/static/regex/hurt_words = regex("die|suffer|hurt|pain") + var/static/regex/heal_words = regex("live|heal|survive|mend|life|heroes never die") + var/static/regex/hurt_words = regex("die|suffer|hurt|pain|death") var/static/regex/bleed_words = regex("bleed|there will be blood") var/static/regex/burn_words = regex("burn|ignite") var/static/regex/hot_words = regex("heat|hot|hell") @@ -565,7 +568,8 @@ else cooldown = COOLDOWN_NONE - message_admins("[key_name_admin(user)] has said '[log_message]' with a Voice of God, affecting [english_list(listeners)], with a power multiplier of [power_multiplier].") + if(message_admins) + message_admins("[key_name_admin(user)] has said '[log_message]' with a Voice of God, affecting [english_list(listeners)], with a power multiplier of [power_multiplier].") log_game("[key_name(user)] has said '[log_message]' with a Voice of God, affecting [english_list(listeners)], with a power multiplier of [power_multiplier].") SSblackbox.record_feedback("tally", "voice_of_god", 1, log_message) diff --git a/code/modules/surgery/remove_embedded_object.dm b/code/modules/surgery/remove_embedded_object.dm index e116c23303..577541e6c4 100644 --- a/code/modules/surgery/remove_embedded_object.dm +++ b/code/modules/surgery/remove_embedded_object.dm @@ -26,7 +26,7 @@ var/objects = 0 for(var/obj/item/I in L.embedded_objects) objects++ - I.loc = get_turf(H) + I.forceMove(get_turf(H)) L.embedded_objects -= I if(!H.has_embedded_objects()) H.clear_alert("embeddedobject") @@ -39,4 +39,4 @@ else to_chat(user, "You can't find [target]'s [parse_zone(user.zone_selected)], let alone any objects embedded in it!") - return 1 \ No newline at end of file + return 1 diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index 084ed3f81d..310513326a 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -6,7 +6,6 @@ materials = list(MAT_METAL=6000, MAT_GLASS=3000) flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_TINY - origin_tech = "materials=1;biotech=1" /obj/item/retractor/augment @@ -17,7 +16,6 @@ materials = list(MAT_METAL=6000, MAT_GLASS=3000) flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_TINY - origin_tech = "materials=1;biotech=1" toolspeed = 0.5 @@ -29,7 +27,6 @@ materials = list(MAT_METAL=5000, MAT_GLASS=2500) flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_TINY - origin_tech = "materials=1;biotech=1" attack_verb = list("attacked", "pinched") @@ -41,7 +38,6 @@ materials = list(MAT_METAL=5000, MAT_GLASS=2500) flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_TINY - origin_tech = "materials=1;biotech=1" toolspeed = 0.5 attack_verb = list("attacked", "pinched") @@ -54,7 +50,6 @@ materials = list(MAT_METAL=2500, MAT_GLASS=750) flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_TINY - origin_tech = "materials=1;biotech=1" attack_verb = list("burnt") @@ -66,7 +61,6 @@ materials = list(MAT_METAL=2500, MAT_GLASS=750) flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_TINY - origin_tech = "materials=1;biotech=1" toolspeed = 0.5 attack_verb = list("burnt") @@ -83,7 +77,6 @@ flags_1 = CONDUCT_1 force = 15 w_class = WEIGHT_CLASS_NORMAL - origin_tech = "materials=1;biotech=1" attack_verb = list("drilled") @@ -97,7 +90,6 @@ flags_1 = CONDUCT_1 force = 10 w_class = WEIGHT_CLASS_SMALL - origin_tech = "materials=1;biotech=1" toolspeed = 0.5 attack_verb = list("drilled") @@ -116,7 +108,6 @@ throw_speed = 3 throw_range = 5 materials = list(MAT_METAL=4000, MAT_GLASS=1000) - origin_tech = "materials=1;biotech=1" attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") hitsound = 'sound/weapons/bladeslice.ogg' sharpness = IS_SHARP_ACCURATE @@ -133,7 +124,6 @@ throw_speed = 3 throw_range = 5 materials = list(MAT_METAL=4000, MAT_GLASS=1000) - origin_tech = "materials=1;biotech=1" attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") toolspeed = 0.5 hitsound = 'sound/weapons/bladeslice.ogg' @@ -160,7 +150,6 @@ throw_speed = 2 throw_range = 5 materials = list(MAT_METAL=10000, MAT_GLASS=6000) - origin_tech = "biotech=1;combat=1" attack_verb = list("attacked", "slashed", "sawed", "cut") sharpness = IS_SHARP @@ -178,7 +167,6 @@ throw_speed = 2 throw_range = 5 materials = list(MAT_METAL=10000, MAT_GLASS=6000) - origin_tech = "biotech=1;combat=1" toolspeed = 0.5 attack_verb = list("attacked", "slashed", "sawed", "cut") sharpness = IS_SHARP @@ -189,7 +177,6 @@ icon = 'icons/obj/surgery.dmi' icon_state = "surgical_drapes" w_class = WEIGHT_CLASS_TINY - origin_tech = "biotech=1" attack_verb = list("slapped") /obj/item/surgical_drapes/attack(mob/living/M, mob/user) @@ -225,7 +212,7 @@ add_overlay(img) add_overlay("evidence") desc = "An organ storage container holding [I]." - I.loc = src + I.forceMove(src) w_class = I.w_class /obj/item/organ_storage/attack_self(mob/user) diff --git a/code/modules/telesci/telepad.dm b/code/modules/telesci/telepad.dm index 32a2acf9c6..d712b773d3 100644 --- a/code/modules/telesci/telepad.dm +++ b/code/modules/telesci/telepad.dm @@ -18,7 +18,6 @@ /obj/item/circuitboard/machine/telesci_pad name = "Telepad (Machine Board)" build_path = /obj/machinery/telepad - origin_tech = "programming=4;engineering=3;plasmatech=4;bluespace=4" req_components = list( /obj/item/ore/bluespace_crystal = 2, /obj/item/stock_parts/capacitor = 1, @@ -104,7 +103,6 @@ icon = 'icons/obj/radio.dmi' icon_state = "beacon" item_state = "beacon" - origin_tech = "bluespace=3" /obj/item/device/telepad_beacon/attack_self(mob/user) if(user) diff --git a/code/modules/tgui/states.dm b/code/modules/tgui/states.dm index c3e7d9b0c9..831f829154 100644 --- a/code/modules/tgui/states.dm +++ b/code/modules/tgui/states.dm @@ -26,7 +26,8 @@ . = max(., UI_INTERACTIVE) // Regular ghosts can always at least view if in range. - if(get_dist(src_object, user) < user.client.view) + var/clientviewlist = getviewsize(user.client.view) + if(get_dist(src_object, user) < max(clientviewlist[1],clientviewlist[2])) . = max(., UI_UPDATE) // Check if the state allows interaction diff --git a/code/modules/tgui/states/default.dm b/code/modules/tgui/states/default.dm index 3ae48c7bc7..0e4844dced 100644 --- a/code/modules/tgui/states/default.dm +++ b/code/modules/tgui/states/default.dm @@ -23,9 +23,6 @@ GLOBAL_DATUM_INIT(default_state, /datum/ui_state/default, new) . = shared_ui_interaction(src_object) if(. > UI_CLOSE) . = min(., shared_living_ui_distance(src_object)) // Check the distance... - // Derp a bit if we have brain loss. - if(prob(getBrainLoss())) - return UI_UPDATE /mob/living/silicon/robot/default_can_use_topic(src_object) . = shared_ui_interaction(src_object) @@ -33,7 +30,8 @@ GLOBAL_DATUM_INIT(default_state, /datum/ui_state/default, new) return // Robots can interact with anything they can see. - if(get_dist(src, src_object) <= client.view) + var/list/clientviewlist = getviewsize(client.view) + if(get_dist(src, src_object) <= min(clientviewlist[1],clientviewlist[2])) return UI_INTERACTIVE return UI_DISABLED // Otherwise they can keep the UI open. diff --git a/code/modules/tooltip/tooltip.dm b/code/modules/tooltip/tooltip.dm index afafbbdf66..5110b98e8e 100644 --- a/code/modules/tooltip/tooltip.dm +++ b/code/modules/tooltip/tooltip.dm @@ -41,21 +41,21 @@ Notes: /datum/tooltip/New(client/C) if (C) - src.owner = C - src.owner << browse(file2text('code/modules/tooltip/tooltip.html'), "window=[src.control]") + owner = C + owner << browse(file2text('code/modules/tooltip/tooltip.html'), "window=[control]") ..() /datum/tooltip/proc/show(atom/movable/thing, params = null, title = null, content = null, theme = "default", special = "none") - if (!thing || !params || (!title && !content) || !src.owner || !isnum(world.icon_size)) + if (!thing || !params || (!title && !content) || !owner || !isnum(world.icon_size)) return 0 - if (!src.init) + if (!init) //Initialize some vars - src.init = 1 - src.owner << output(list2params(list(world.icon_size, src.control)), "[src.control]:tooltip.init") + init = 1 + owner << output(list2params(list(world.icon_size, control)), "[control]:tooltip.init") - src.showing = 1 + showing = 1 if (title && content) title = "

    [title]

    " @@ -73,18 +73,19 @@ Notes: params = {"{ "cursor": "[params]", "screenLoc": "[thing.screen_loc]" }"} //Send stuff to the tooltip - src.owner << output(list2params(list(params, src.owner.view, "[title][content]", theme, special)), "[src.control]:tooltip.update") + var/view_size = getviewsize(owner.view) + owner << output(list2params(list(params, view_size[1] , view_size[2], "[title][content]", theme, special)), "[control]:tooltip.update") //If a hide() was hit while we were showing, run hide() again to avoid stuck tooltips - src.showing = 0 - if (src.queueHide) - src.hide() + showing = 0 + if (queueHide) + hide() return 1 /datum/tooltip/proc/hide() - if (src.queueHide) + if (queueHide) addtimer(CALLBACK(src, .proc/do_hide), 1) else do_hide() diff --git a/code/modules/tooltip/tooltip.html b/code/modules/tooltip/tooltip.html index 859ee3134d..67fb8a77f1 100644 --- a/code/modules/tooltip/tooltip.html +++ b/code/modules/tooltip/tooltip.html @@ -99,7 +99,8 @@ 'tileSize': 32, 'control': '', 'params': {}, - 'clientView': 0, + 'client_view_w': 0, + 'client_view_h': 0, 'text': '', 'theme': '', 'padding': 2, @@ -121,7 +122,7 @@ //Get the real icon size according to the client view var mapWidth = map['view-size'].x, mapHeight = map['view-size'].y, - tilesShown = (tooltip.clientView * 2) + 1, + tilesShown = tooltip.client_view_w realIconSize = mapWidth / tilesShown, resizeRatio = realIconSize / tooltip.tileSize, //Calculate letterboxing offsets @@ -230,10 +231,11 @@ tooltip.hide(); }); }, - update: function(params, clientView, text, theme, special) { + update: function(params, client_vw , clien_vh , text, theme, special) { //Assign our global object tooltip.params = $.parseJSON(params); - tooltip.clientView = parseInt(clientView); + tooltip.client_view_w = parseInt(client_vw); + tooltip.client_view_h = parseInt(clien_vh); tooltip.text = text; tooltip.theme = theme; tooltip.special = special; diff --git a/code/modules/uplink/uplink.dm b/code/modules/uplink/uplink.dm index 6b53ed5920..175ac9469c 100644 --- a/code/modules/uplink/uplink.dm +++ b/code/modules/uplink/uplink.dm @@ -1,162 +1,204 @@ -GLOBAL_LIST_EMPTY(uplinks) - -/** - * Uplinks - * - * All /obj/item(s) have a hidden_uplink var. By default it's null. Give the item one with 'new(src') (it must be in it's contents). Then add 'uses.' - * Use whatever conditionals you want to check that the user has an uplink, and then call interact() on their uplink. - * You might also want the uplink menu to open if active. Check if the uplink is 'active' and then interact() with it. -**/ -/obj/item/device/uplink - name = "syndicate uplink" - desc = "There is something wrong if you're examining this." - var/active = FALSE - var/lockable = TRUE - var/telecrystals = 20 - var/selected_cat = null - var/owner = null - var/datum/game_mode/gamemode = null - var/spent_telecrystals = 0 - var/purchase_log = "" - var/list/uplink_items - var/hidden_crystals = 0 - -/obj/item/device/uplink/Initialize() - . = ..() - GLOB.uplinks += src - uplink_items = get_uplink_items(gamemode) - -/obj/item/device/uplink/proc/set_gamemode(gamemode) - src.gamemode = gamemode - uplink_items = get_uplink_items(gamemode) - -/obj/item/device/uplink/Destroy() - GLOB.uplinks -= src - return ..() - -/obj/item/device/uplink/attackby(obj/item/I, mob/user, params) - for(var/item in subtypesof(/datum/uplink_item)) - var/datum/uplink_item/UI = item - var/path = null - if(initial(UI.refund_path)) - path = initial(UI.refund_path) - else - path = initial(UI.item) - var/cost = 0 - if(initial(UI.refund_amount)) - cost = initial(UI.refund_amount) - else - cost = initial(UI.cost) - var/refundable = initial(UI.refundable) - if(I.type == path && refundable && I.check_uplink_validity()) - telecrystals += cost - spent_telecrystals -= cost - to_chat(user, "[I] refunded.") - qdel(I) - return - ..() - -/obj/item/device/uplink/interact(mob/user) - active = TRUE - if(user) - ui_interact(user) - -/obj/item/device/uplink/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ - datum/tgui/master_ui = null, datum/ui_state/state = GLOB.inventory_state) - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "uplink", name, 450, 750, master_ui, state) - ui.set_autoupdate(FALSE) // This UI is only ever opened by one person, and never is updated outside of user input. - ui.set_style("syndicate") - ui.open() - -/obj/item/device/uplink/ui_data(mob/user) - if(!user.mind) - return - var/list/data = list() - data["telecrystals"] = telecrystals - data["lockable"] = lockable - - data["categories"] = list() - for(var/category in uplink_items) - var/list/cat = list( - "name" = category, - "items" = (category == selected_cat ? list() : null)) - if(category == selected_cat) - for(var/item in uplink_items[category]) - var/datum/uplink_item/I = uplink_items[category][item] - if(I.limited_stock == 0) - continue - if(I.restricted_roles.len) - var/is_inaccessible = 1 - for(var/R in I.restricted_roles) - if(R == user.mind.assigned_role) - is_inaccessible = 0 - if(is_inaccessible) - continue - cat["items"] += list(list( - "name" = I.name, - "cost" = I.cost, - "desc" = I.desc, - )) - data["categories"] += list(cat) - return data - - -/obj/item/device/uplink/ui_act(action, params) - if(!active) - return - - switch(action) - if("buy") - var/item = params["item"] - - var/list/buyable_items = list() - for(var/category in uplink_items) - buyable_items += uplink_items[category] - - if(item in buyable_items) - var/datum/uplink_item/I = buyable_items[item] - I.buy(usr, src) - . = TRUE - if("lock") - active = FALSE - telecrystals += hidden_crystals - hidden_crystals = 0 - SStgui.close_uis(src) - if("select") - selected_cat = params["category"] - return 1 - - -/obj/item/device/uplink/ui_host() - return loc - -// Refund certain items by hitting the uplink with it. -/obj/item/device/radio/uplink/attackby(obj/item/I, mob/user, params) - return hidden_uplink.attackby(I, user, params) - -// A collection of pre-set uplinks, for admin spawns. -/obj/item/device/radio/uplink/Initialize() - . = ..() - icon_state = "radio" - lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' - righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' - hidden_uplink = new(src) - hidden_uplink.active = TRUE - hidden_uplink.lockable = FALSE - -/obj/item/device/radio/uplink/nuclear/Initialize() - . = ..() - hidden_uplink.set_gamemode(/datum/game_mode/nuclear) - -/obj/item/device/multitool/uplink/Initialize() - . = ..() - hidden_uplink = new(src) - hidden_uplink.active = TRUE - hidden_uplink.lockable = FALSE - -/obj/item/pen/uplink/Initialize() - . = ..() - hidden_uplink = new(src) - traitor_unlock_degrees = 360 +GLOBAL_LIST_EMPTY(uplinks) + +/** + * Uplinks + * + * All /obj/item(s) have a hidden_uplink var. By default it's null. Give the item one with 'new(src') (it must be in it's contents). Then add 'uses.' + * Use whatever conditionals you want to check that the user has an uplink, and then call interact() on their uplink. + * You might also want the uplink menu to open if active. Check if the uplink is 'active' and then interact() with it. +**/ +/datum/component/uplink + dupe_mode = COMPONENT_DUPE_UNIQUE + var/name = "syndicate uplink" + var/active = FALSE + var/lockable = TRUE + var/locked = TRUE + var/telecrystals + var/selected_cat + var/owner = null + var/datum/game_mode/gamemode + var/spent_telecrystals = 0 + var/datum/uplink_purchase_log/purchase_log + var/list/uplink_items + var/hidden_crystals = 0 + +/datum/component/uplink/Initialize(_owner, _lockable = TRUE, _enabled = FALSE, datum/game_mode/_gamemode, starting_tc = 20) + if(!isitem(parent)) + return COMPONENT_INCOMPATIBLE + GLOB.uplinks += src + uplink_items = get_uplink_items(gamemode) + RegisterSignal(COMSIG_PARENT_ATTACKBY, .proc/OnAttackBy) + RegisterSignal(COMSIG_ITEM_ATTACK_SELF, .proc/interact) + owner = _owner + if(owner) + LAZYINITLIST(GLOB.uplink_purchase_logs_by_key) + if(GLOB.uplink_purchase_logs_by_key[owner]) + purchase_log = GLOB.uplink_purchase_logs_by_key[owner] + else + purchase_log = new(owner, src) + lockable = _lockable + active = _enabled + gamemode = _gamemode + telecrystals = starting_tc + if(!lockable) + active = TRUE + locked = FALSE + +/datum/component/uplink/InheritComponent(datum/component/uplink/U) + lockable |= U.lockable + active |= U.active + if(!gamemode) + gamemode = U.gamemode + telecrystals += U.telecrystals + if(purchase_log && U.purchase_log) + purchase_log.MergeWithAndDel(U.purchase_log) + +/datum/component/uplink/Destroy() + GLOB.uplinks -= src + gamemode = null + return ..() + +/datum/component/uplink/proc/LoadTC(mob/user, obj/item/stack/telecrystal/TC, silent = FALSE) + if(!silent) + to_chat(user, "You slot [TC] into [parent] and charge its internal uplink.") + var/amt = TC.amount + telecrystals += amt + TC.use(amt) + +/datum/component/uplink/proc/set_gamemode(_gamemode) + gamemode = _gamemode + uplink_items = get_uplink_items(gamemode) + +/datum/component/uplink/proc/OnAttackBy(obj/item/I, mob/user) + if(!active) + return //no hitting everyone/everything just to try to slot tcs in! + if(istype(I, /obj/item/stack/telecrystal)) + LoadTC(user, I) + for(var/item in subtypesof(/datum/uplink_item)) + var/datum/uplink_item/UI = item + var/path = null + if(initial(UI.refund_path)) + path = initial(UI.refund_path) + else + path = initial(UI.item) + var/cost = 0 + if(initial(UI.refund_amount)) + cost = initial(UI.refund_amount) + else + cost = initial(UI.cost) + var/refundable = initial(UI.refundable) + if(I.type == path && refundable && I.check_uplink_validity()) + telecrystals += cost + spent_telecrystals -= cost + to_chat(user, "[I] refunded.") + qdel(I) + return + +/datum/component/uplink/proc/interact(mob/user) + if(locked) + return + active = TRUE + if(user) + ui_interact(user) + +/datum/component/uplink/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ + datum/tgui/master_ui = null, datum/ui_state/state = GLOB.inventory_state) + active = TRUE + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "uplink", name, 450, 750, master_ui, state) + ui.set_autoupdate(FALSE) // This UI is only ever opened by one person, and never is updated outside of user input. + ui.set_style("syndicate") + ui.open() + +/datum/component/uplink/ui_data(mob/user) + if(!user.mind) + return + var/list/data = list() + data["telecrystals"] = telecrystals + data["lockable"] = lockable + + data["categories"] = list() + for(var/category in uplink_items) + var/list/cat = list( + "name" = category, + "items" = (category == selected_cat ? list() : null)) + if(category == selected_cat) + for(var/item in uplink_items[category]) + var/datum/uplink_item/I = uplink_items[category][item] + if(I.limited_stock == 0) + continue + if(I.restricted_roles.len) + var/is_inaccessible = 1 + for(var/R in I.restricted_roles) + if(R == user.mind.assigned_role) + is_inaccessible = 0 + if(is_inaccessible) + continue + cat["items"] += list(list( + "name" = I.name, + "cost" = I.cost, + "desc" = I.desc, + )) + data["categories"] += list(cat) + return data + +/datum/component/uplink/ui_act(action, params) + if(!active) + return + + switch(action) + if("buy") + var/item = params["item"] + + var/list/buyable_items = list() + for(var/category in uplink_items) + buyable_items += uplink_items[category] + + if(item in buyable_items) + var/datum/uplink_item/I = buyable_items[item] + MakePurchase(usr, I) + . = TRUE + if("lock") + active = FALSE + locked = TRUE + telecrystals += hidden_crystals + hidden_crystals = 0 + SStgui.close_uis(src) + if("select") + selected_cat = params["category"] + return TRUE + +/datum/component/uplink/proc/MakePurchase(mob/user, datum/uplink_item/U) + if(!istype(U)) + return + if (!user || user.incapacitated()) + return + + if(telecrystals < U.cost || U.limited_stock == 0) + return + telecrystals -= U.cost + + var/atom/A = U.spawn_item(get_turf(user), src, user) + if(U.purchase_log_vis && purchase_log) + var/obj/item/storage/box/B = A + var/list/atom/logging = list() + if(istype(B) && B.contents.len > 0) + logging |= list(B) + else + logging |= A + for(var/atom/_logging in logging) + purchase_log.LogPurchase(_logging, U.cost) + + if(U.limited_stock > 0) + U.limited_stock -= 1 + + SSblackbox.record_feedback("nested tally", "traitor_uplink_items_bought", 1, list("[initial(U.name)]", "[U.cost]")) + if(ishuman(user) && istype(A, /obj/item)) + var/mob/living/carbon/human/H = user + if(H.put_in_hands(A)) + to_chat(H, "[A] materializes into your hands!") + else + to_chat(H, "\The [A] materializes onto the floor.") + return TRUE + diff --git a/code/modules/uplink/uplink_devices.dm b/code/modules/uplink/uplink_devices.dm new file mode 100644 index 0000000000..737f92a9ef --- /dev/null +++ b/code/modules/uplink/uplink_devices.dm @@ -0,0 +1,31 @@ + +// A collection of pre-set uplinks, for admin spawns. +/obj/item/device/radio/uplink/Initialize(mapload, _owner, _tc_amount = 20) + . = ..() + icon_state = "radio" + lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' + righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' + AddComponent(/datum/component/uplink, _owner, FALSE, TRUE, null, _tc_amount) + +/obj/item/device/radio/uplink/nuclear/Initialize() + . = ..() + GET_COMPONENT(hidden_uplink, /datum/component/uplink) + hidden_uplink.set_gamemode(/datum/game_mode/nuclear) + +/obj/item/device/multitool/uplink/Initialize(mapload, _owner, _tc_amount = 20) + . = ..() + AddComponent(/datum/component/uplink, _owner, FALSE, TRUE, null, _tc_amount) + +/obj/item/pen/uplink/Initialize(mapload, _owner, _tc_amount = 20) + . = ..() + AddComponent(/datum/component/uplink) + traitor_unlock_degrees = 360 + +/obj/item/device/radio/uplink/old + name = "dusty radio" + desc = "A dusty looking radio." + +/obj/item/device/radio/uplink/old/Initialize(mapload, _owner, _tc_amount = 10) + . = ..() + GET_COMPONENT(hidden_uplink, /datum/component/uplink) + hidden_uplink.name = "dusty radio" diff --git a/code/modules/uplink/uplink_item.dm b/code/modules/uplink/uplink_items.dm similarity index 97% rename from code/modules/uplink/uplink_item.dm rename to code/modules/uplink/uplink_items.dm index 884e3f9426..ebff0fdbeb 100644 --- a/code/modules/uplink/uplink_item.dm +++ b/code/modules/uplink/uplink_items.dm @@ -89,43 +89,11 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once. /datum/uplink_item/proc/get_discount() return pick(4;0.75,2;0.5,1;0.25) -/datum/uplink_item/proc/spawn_item(turf/loc, obj/item/device/uplink/U) +/datum/uplink_item/proc/spawn_item(turf/loc, datum/component/uplink/U, mob/user) if(item) SSblackbox.record_feedback("nested tally", "traitor_uplink_items_bought", 1, list("[initial(name)]", "[cost]")) return new item(loc) -/datum/uplink_item/proc/buy(mob/user, obj/item/device/uplink/U) - if(!istype(U)) - return - if (!user || user.incapacitated()) - return - - if(U.telecrystals < cost || limited_stock == 0) - return - else - U.telecrystals -= cost - U.spent_telecrystals += cost - - var/atom/A = spawn_item(get_turf(user), U) - var/obj/item/storage/box/B = A - if(istype(B) && B.contents.len > 0) - for(var/obj/item/I in B) - U.purchase_log += "[icon2base64html(I)]" - else - if(purchase_log_vis) - U.purchase_log += "[icon2base64html(A)]" - - if(limited_stock > 0) - limited_stock -= 1 - - if(ishuman(user) && istype(A, /obj/item)) - var/mob/living/carbon/human/H = user - if(H.put_in_hands(A)) - to_chat(H, "[A] materializes into your hands!") - else - to_chat(H, "\The [A] materializes onto the floor.") - return 1 - /datum/uplink_item/Destroy() if(src in GLOB.uplink_items) GLOB.uplink_items -= src //Take us out instead of leaving a null! @@ -368,7 +336,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once. cost = 12 surplus = 35 include_modes = list(/datum/game_mode/nuclear) - + /datum/uplink_item/dangerous/guardian name = "Holoparasites" desc = "Though capable of near sorcerous feats via use of hardlight holograms and nanomachines, they require an \ @@ -977,8 +945,8 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once. item = /obj/item/briefcase_launchpad cost = 6 -/datum/uplink_item/device_tools/briefcase_launchpad/buy(mob/user, obj/item/device/uplink/U) - var/obj/item/device/launchpad_remote/L = new(get_turf(user)) //free remote +/datum/uplink_item/device_tools/briefcase_launchpad/spawn_item(turf/loc, datum/component/uplink/U, mob/user) + var/obj/item/device/launchpad_remote/L = new(loc) //free remote if(ishuman(user)) var/mob/living/carbon/human/H = user if(H.put_in_hands(L)) @@ -1128,16 +1096,9 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once. /datum/uplink_item/device_tools/codespeak_manual name = "Codespeak Manual" - desc = "Syndicate agents can be trained to use a series of codewords to convey complex information, which sounds like random concepts and drinks to anyone listening. This manual teaches you this Codespeak. You can also hit someone else with the manual in order to teach them. One use." - item = /obj/item/codespeak_manual - cost = 2 - exclude_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/device_tools/codespeak_manual_deluxe - name = "Deluxe Codespeak Manual" - desc = "Syndicate agents can be trained to use a series of codewords to convey complex information, which sounds like random concepts and drinks to anyone listening. This manual teaches you this Codespeak. You can also hit someone else with the manual in order to teach them. This is the deluxe edition, which has unlimited uses." - cost = 8 - include_modes = list(/datum/game_mode/nuclear) + desc = "Syndicate agents can be trained to use a series of codewords to convey complex information, which sounds like random concepts and drinks to anyone listening. This manual teaches you this Codespeak. You can also hit someone else with the manual in order to teach them. This is the deluxe edition, which has unlimited used." + item = /obj/item/codespeak_manual/unlimited + cost = 3 // Implants /datum/uplink_item/implants @@ -1381,7 +1342,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once. exclude_modes = list(/datum/game_mode/nuclear) cant_discount = TRUE -/datum/uplink_item/badass/surplus/spawn_item(turf/loc, obj/item/device/uplink/U) +/datum/uplink_item/badass/surplus/spawn_item(turf/loc, datum/component/uplink/U) var/list/uplink_items = get_uplink_items(SSticker && SSticker.mode? SSticker.mode : null) var/crate_value = 50 @@ -1397,7 +1358,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once. continue crate_value -= I.cost var/obj/goods = new I.item(C) - U.purchase_log += "[icon2base64html(goods)]" + U.purchase_log.LogPurchase(goods, I.cost) SSblackbox.record_feedback("nested tally", "traitor_uplink_items_bought", 1, list("[initial(name)]", "[cost]")) return C @@ -1409,7 +1370,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once. cost = 0 cant_discount = TRUE -/datum/uplink_item/badass/random/spawn_item(turf/loc, obj/item/device/uplink/U) +/datum/uplink_item/badass/random/spawn_item(turf/loc, datum/component/uplink/U) var/list/uplink_items = get_uplink_items(SSticker && SSticker.mode? SSticker.mode : null) var/list/possible_items = list() for(var/category in uplink_items) diff --git a/code/modules/uplink/uplink_purchase_log.dm b/code/modules/uplink/uplink_purchase_log.dm new file mode 100644 index 0000000000..5ec462d237 --- /dev/null +++ b/code/modules/uplink/uplink_purchase_log.dm @@ -0,0 +1,64 @@ +GLOBAL_LIST(uplink_purchase_logs_by_key) //assoc key = /datum/uplink_purchase_log + +/datum/uplink_purchase_log + var/owner + var/list/purchase_log //assoc path-of-item = /datum/uplink_purchase_entry + var/datum/component/uplink/parent + var/total_spent = 0 + +/datum/uplink_purchase_log/New(_owner, datum/component/uplink/_parent) + owner = _owner + parent = _parent + LAZYINITLIST(GLOB.uplink_purchase_logs_by_key) + if(owner) + if(GLOB.uplink_purchase_logs_by_key[owner]) + stack_trace("WARNING: DUPLICATE PURCHASE LOGS DETECTED. [_owner] [_parent] [_parent.type]") + MergeWithAndDel(GLOB.uplink_purchase_logs_by_key[owner]) + GLOB.uplink_purchase_logs_by_key[owner] = src + purchase_log = list() + +/datum/uplink_purchase_log/Destroy() + purchase_log = null + parent = null + return ..() + +/datum/uplink_purchase_log/proc/MergeWithAndDel(datum/uplink_purchase_log/other) + if(!istype(other)) + return + . = owner == other.owner + if(!.) + return + for(var/path in other.purchase_log) + if(!purchase_log[path]) + purchase_log[path] = other.purchase_log[path] + else + var/datum/uplink_purchase_entry/UPE = purchase_log[path] + var/datum/uplink_purchase_entry/UPE_O = other.purchase_log[path] + UPE.amount_purchased += UPE_O.amount_purchased + qdel(other) + +/datum/uplink_purchase_log/proc/TotalTelecrystalsSpent() + . = total_spent + +/datum/uplink_purchase_log/proc/generate_render(show_key = TRUE) + . = "" + for(var/path in purchase_log) + var/datum/uplink_purchase_entry/UPE = purchase_log[path] + . += "\[[UPE.icon_b64][show_key?"([owner])":""]\]" + +/datum/uplink_purchase_log/proc/LogPurchase(atom/A, cost) + var/datum/uplink_purchase_entry/UPE + if(purchase_log[A.type]) + UPE = purchase_log[A.type] + else + UPE = new + purchase_log[A.type] = UPE + UPE.path = A.type + UPE.icon_b64 = "[icon2base64html(A)]" + UPE.amount_purchased++ + total_spent += cost + +/datum/uplink_purchase_entry + var/amount_purchased = 0 + var/path + var/icon_b64 diff --git a/code/modules/vehicles/_vehicle.dm b/code/modules/vehicles/_vehicle.dm new file mode 100644 index 0000000000..4cedfdf3e3 --- /dev/null +++ b/code/modules/vehicles/_vehicle.dm @@ -0,0 +1,140 @@ +#define VEHICLE_CONTROL_PERMISSION 1 +#define VEHICLE_CONTROL_DRIVE 2 + +/obj/vehicle + name = "generic vehicle" + desc = "Yell at coderbus." + icon = 'icons/obj/vehicles.dmi' + icon_state = "fuckyou" + max_integrity = 300 + armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 60) + density = TRUE + anchored = FALSE + var/list/mob/occupants //mob = bitflags of their control level. + var/max_occupants = 1 + var/max_drivers = 1 + var/movedelay = 2 + var/lastmove = 0 + var/key_type + var/obj/item/key/inserted_key + var/key_type_exact = TRUE //can subtypes work + var/canmove = TRUE + var/emulate_door_bumps = TRUE //when bumping a door try to make occupants bump them to open them. + var/default_driver_move = TRUE //handle driver movement instead of letting something else do it like riding datums. + var/list/autogrant_actions_passenger //plain list of typepaths + var/list/autogrant_actions_controller //assoc list "[bitflag]" = list(typepaths) + var/list/mob/occupant_actions //assoc list mob = list(type = action datum assigned to mob) + +/obj/vehicle/Initialize(mapload) + . = ..() + occupants = list() + autogrant_actions_passenger = list() + autogrant_actions_controller = list() + occupant_actions = list() + generate_actions() + +/obj/vehicle/proc/is_key(obj/item/I) + return I? (key_type_exact? (I.type == key_type) : istype(I, key_type)) : FALSE + +/obj/vehicle/proc/return_occupants() + return occupants + +/obj/vehicle/proc/occupant_amount() + return length(occupants) + +/obj/vehicle/proc/return_amount_of_controllers_with_flag(flag) + . = 0 + for(var/i in occupants) + if(occupants[i] & flag) + .++ + +/obj/vehicle/proc/return_controllers_with_flag(flag) + . = list() + for(var/i in occupants) + if(occupants[i] & flag) + . += i + +/obj/vehicle/proc/return_drivers() + return return_controllers_with_flag(VEHICLE_CONTROL_DRIVE) + +/obj/vehicle/proc/driver_amount() + return return_amount_of_controllers_with_flag(VEHICLE_CONTROL_DRIVE) + +/obj/vehicle/proc/is_driver(mob/M) + return is_occupant(M) && occupants[M] & VEHICLE_CONTROL_DRIVE + +/obj/vehicle/proc/is_occupant(mob/M) + return !isnull(occupants[M]) + +/obj/vehicle/proc/add_occupant(mob/M, control_flags) + if(!istype(M) || occupants[M]) + return FALSE + occupants[M] = NONE + add_control_flags(M, control_flags) + grant_passenger_actions(M) + after_add_occupant(M) + return TRUE + +/obj/vehicle/proc/after_add_occupant(mob/M) + auto_assign_occupant_flags(M) + +/obj/vehicle/proc/auto_assign_occupant_flags(mob/M) //override for each type that needs it. Default is assign driver if drivers is not at max. + if(driver_amount() < max_drivers) + add_control_flags(M, VEHICLE_CONTROL_DRIVE|VEHICLE_CONTROL_PERMISSION) + +/obj/vehicle/proc/remove_occupant(mob/M) + if(!istype(M)) + return FALSE + remove_control_flags(M, ALL) + occupants -= M + remove_passenger_actions(M) + cleanup_actions_for_mob(M) + after_remove_occupant(M) + return TRUE + +/obj/vehicle/proc/after_remove_occupant(mob/M) + +/obj/vehicle/relaymove(mob/user, direction) + if(is_driver(user)) + return driver_move(user, direction) + return FALSE + +/obj/vehicle/proc/driver_move(mob/user, direction) + if(key_type && !is_key(inserted_key)) + to_chat(user, "[src] has no key inserted!") + return FALSE + if(!default_driver_move) + return + vehicle_move(direction) + +/obj/vehicle/proc/vehicle_move(direction) + if(lastmove + movedelay > world.time) + return FALSE + lastmove = world.time + return step(src, direction) + +/obj/vehicle/proc/add_control_flags(mob/controller, flags) + if(!istype(controller) || !flags) + return FALSE + occupants[controller] |= flags + for(var/i in GLOB.bitflags) + if(flags & i) + grant_controller_actions_by_flag(controller, i) + return TRUE + +/obj/vehicle/proc/remove_control_flags(mob/controller, flags) + if(!istype(controller) || !flags) + return FALSE + occupants[controller] &= ~flags + for(var/i in GLOB.bitflags) + if(flags & i) + remove_controller_actions_by_flag(controller, i) + return TRUE + +/obj/vehicle/Collide(atom/movable/M) + . = ..() + if(emulate_door_bumps) + if(istype(M, /obj/machinery/door) && has_buckled_mobs()) + for(var/m in occupants) + M.CollidedWith(m) + diff --git a/code/modules/vehicles/atv.dm b/code/modules/vehicles/atv.dm index 504e4753df..ac5be5b51c 100644 --- a/code/modules/vehicles/atv.dm +++ b/code/modules/vehicles/atv.dm @@ -1,45 +1,63 @@ -/obj/vehicle/atv +/obj/vehicle/ridden/atv name = "all-terrain vehicle" desc = "An all-terrain vehicle built for traversing rough terrain with ease. One of the few old-Earth technologies that are still relevant on most planet-bound outposts." icon_state = "atv" + key_type = /obj/item/key var/static/mutable_appearance/atvcover -/obj/vehicle/atv/buckle_mob(mob/living/buckled_mob, force = 0, check_loc = 1) +/obj/vehicle/ridden/atv/Initialize() . = ..() - riding_datum = new/datum/riding/atv + var/datum/component/riding/D = LoadComponent(/datum/component/riding) + D.vehicle_move_delay = 1 + D.set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 4), TEXT_SOUTH = list(0, 4), TEXT_EAST = list(0, 4), TEXT_WEST = list( 0, 4))) + D.set_vehicle_dir_layer(SOUTH, ABOVE_MOB_LAYER) + D.set_vehicle_dir_layer(NORTH, OBJ_LAYER) + D.set_vehicle_dir_layer(EAST, OBJ_LAYER) + D.set_vehicle_dir_layer(WEST, OBJ_LAYER) -/obj/vehicle/atv/Initialize() - . = ..() - atvcover = atvcover || mutable_appearance(icon, "atvcover", ABOVE_MOB_LAYER) +/obj/vehicle/ridden/atv/post_buckle_mob(mob/living/M) + add_overlay(atvcover) + return ..() - -/obj/vehicle/atv/post_buckle_mob(mob/living/M) - if(has_buckled_mobs()) - add_overlay(atvcover) - else +/obj/vehicle/ridden/atv/post_unbuckle_mob(mob/living/M) + if(!has_buckled_mobs()) cut_overlay(atvcover) - - + return ..() //TURRETS! -/obj/vehicle/atv/turret +/obj/vehicle/ridden/atv/turret var/obj/machinery/porta_turret/syndicate/vehicle_turret/turret = null - /obj/machinery/porta_turret/syndicate/vehicle_turret name = "mounted turret" scan_range = 7 emp_vunerable = 1 density = FALSE - -/obj/vehicle/atv/turret/Initialize() +/obj/vehicle/ridden/atv/turret/Initialize() . = ..() turret = new(loc) turret.base = src -/obj/vehicle/atv/turret/buckle_mob(mob/living/buckled_mob, force = 0, check_loc = 1) +/obj/vehicle/ridden/atv/turret/Moved() . = ..() - riding_datum = new/datum/riding/atv/turret - + if(turret) + turret.forceMove(get_turf(src)) + switch(dir) + if(NORTH) + turret.pixel_x = 0 + turret.pixel_y = 4 + turret.layer = ABOVE_MOB_LAYER + if(EAST) + turret.pixel_x = -12 + turret.pixel_y = 4 + turret.layer = OBJ_LAYER + if(SOUTH) + turret.pixel_x = 0 + turret.pixel_y = 4 + turret.layer = OBJ_LAYER + if(WEST) + turret.pixel_x = 12 + turret.pixel_y = 4 + turret.layer = OBJ_LAYER diff --git a/code/modules/vehicles/bicycle.dm b/code/modules/vehicles/bicycle.dm index cd93196b69..a6818d8bf3 100644 --- a/code/modules/vehicles/bicycle.dm +++ b/code/modules/vehicles/bicycle.dm @@ -7,9 +7,12 @@ var/static/list/bike_music = list('sound/misc/bike1.mid', 'sound/misc/bike2.mid', 'sound/misc/bike3.mid') + /obj/vehicle/bicycle/Initialize() . = ..() - riding_datum = new/datum/riding/bicycle + var/datum/component/riding/D = LoadComponent(/datum/component/riding) + D.set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 4), TEXT_SOUTH = list(0, 4), TEXT_EAST = list(0, 4), TEXT_WEST = list( 0, 4))) + D.vehicle_move_delay = 0 /obj/vehicle/bicycle/buckle_mob(mob/living/M, force = 0, check_loc = 1) if(prob(easter_egg_chance) || (SSevents.holidays && SSevents.holidays[APRIL_FOOLS])) @@ -24,7 +27,7 @@ /obj/vehicle/bicycle/tesla_act() // :::^^^))) name = "fried bicycle" desc = "Well spent." - riding_datum = null color = rgb(63, 23, 4) + can_buckle = FALSE for(var/m in buckled_mobs) unbuckle_mob(m,1) diff --git a/code/modules/vehicles/entered.dm b/code/modules/vehicles/entered.dm new file mode 100644 index 0000000000..d0fb93f7f0 --- /dev/null +++ b/code/modules/vehicles/entered.dm @@ -0,0 +1,56 @@ +/obj/vehicle/sealed + var/enter_delay = 20 + +/obj/vehicle/sealed/generate_actions() + . = ..() + initialize_passenger_action_type(/datum/action/vehicle/sealed/climb_out) + +/obj/vehicle/sealed/generate_action_type() + var/datum/action/vehicle/sealed/E = ..() + . = E + if(istype(E)) + E.vehicle_entered_target = src + +/obj/vehicle/sealed/MouseDrop_T(atom/dropping, mob/M) + if(!istype(dropping) || !istype(M)) + return ..() + if(M == dropping) + mob_try_enter(M) + return ..() + +/obj/vehicle/sealed/proc/mob_try_enter(mob/M) + if(!istype(M)) + return FALSE + if(occupant_amount() >= max_occupants) + return FALSE + if(do_after(M, get_enter_delay(M), FALSE, src, TRUE)) + mob_enter(M) + return TRUE + return FALSE + +/obj/vehicle/sealed/proc/get_enter_delay(mob/M) + return enter_delay + +/obj/vehicle/sealed/proc/mob_enter(mob/M, silent = FALSE) + if(!istype(M)) + return FALSE + if(!silent) + M.visible_message("[M] climbs into \the [src]!") + M.forceMove(src) + add_occupant(M) + return TRUE + +/obj/vehicle/sealed/proc/mob_try_exit(mob/M, mob/user, silent = FALSE) + mob_exit(M, silent) + +/obj/vehicle/sealed/proc/mob_exit(mob/M, silent = FALSE) + if(!istype(M)) + return FALSE + remove_occupant(M) + M.forceMove(exit_location(M)) + if(!silent) + M.visible_message("[M] drops out of \the [src]!") + return TRUE + +/obj/vehicle/sealed/proc/exit_location(M) + return drop_location() diff --git a/code/modules/vehicles/pimpin_ride.dm b/code/modules/vehicles/pimpin_ride.dm index f8f80819dd..3925b863ff 100644 --- a/code/modules/vehicles/pimpin_ride.dm +++ b/code/modules/vehicles/pimpin_ride.dm @@ -1,48 +1,36 @@ //PIMP-CART -/obj/vehicle/janicart +/obj/vehicle/ridden/janicart name = "janicart (pimpin' ride)" desc = "A brave janitor cyborg gave its life to produce such an amazing combination of speed and utility." icon_state = "pussywagon" - + key_type = /obj/item/key/janitor var/obj/item/storage/bag/trash/mybag = null var/floorbuffer = FALSE -/obj/vehicle/janicart/Initialize(mapload) +/obj/vehicle/ridden/janicart/Initialize(mapload) . = ..() update_icon() + var/datum/component/riding/D = LoadComponent(/datum/component/riding) + D.set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 4), TEXT_SOUTH = list(0, 7), TEXT_EAST = list(-12, 7), TEXT_WEST = list( 12, 7))) -/obj/vehicle/janicart/Destroy() +/obj/vehicle/ridden/janicart/Destroy() if(mybag) qdel(mybag) mybag = null . = ..() -/obj/vehicle/janicart/buckle_mob(mob/living/buckled_mob, force = 0, check_loc = 0) - . = ..() - riding_datum = new/datum/riding/janicart - - - -/obj/item/key/janitor - desc = "A keyring with a small steel key, and a pink fob reading \"Pussy Wagon\"." - icon_state = "keyjanitor" - - /obj/item/janiupgrade name = "floor buffer upgrade" desc = "An upgrade for mobile janicarts." icon = 'icons/obj/vehicles.dmi' icon_state = "upgrade" - origin_tech = "materials=3;engineering=4" - -/obj/vehicle/janicart/examine(mob/user) +/obj/vehicle/ridden/janicart/examine(mob/user) ..() if(floorbuffer) to_chat(user, "It has been upgraded with a floor buffer.") - -/obj/vehicle/janicart/attackby(obj/item/I, mob/user, params) +/obj/vehicle/ridden/janicart/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/storage/bag/trash)) if(mybag) to_chat(user, "[src] already has a trashbag hooked!") @@ -64,16 +52,14 @@ else return ..() - -/obj/vehicle/janicart/update_icon() +/obj/vehicle/ridden/janicart/update_icon() cut_overlays() if(mybag) add_overlay("cart_garbage") if(floorbuffer) add_overlay("cart_buffer") - -/obj/vehicle/janicart/attack_hand(mob/user) +/obj/vehicle/ridden/janicart/attack_hand(mob/user) if(..()) return 1 else if(mybag) @@ -82,5 +68,5 @@ mybag = null update_icon() -/obj/vehicle/janicart/upgraded +/obj/vehicle/ridden/janicart/upgraded floorbuffer = TRUE diff --git a/code/modules/vehicles/ridden.dm b/code/modules/vehicles/ridden.dm new file mode 100644 index 0000000000..32975e1e0f --- /dev/null +++ b/code/modules/vehicles/ridden.dm @@ -0,0 +1,76 @@ +/obj/vehicle/ridden + name = "ridden vehicle" + can_buckle = TRUE + max_buckled_mobs = 1 + buckle_lying = FALSE + default_driver_move = FALSE + var/legs_required = 2 + var/arms_requires = 0 //why not? + +/obj/vehicle/ridden/Initialize() + . = ..() + LoadComponent(/datum/component/riding) + +/obj/vehicle/ridden/examine(mob/user) + . = ..() + to_chat(user, "Put a key inside it by clicking it with the key. If there's a key inside, you can remove it via Alt-Click!") + +/obj/vehicle/ridden/generate_action_type(actiontype) + var/datum/action/vehicle/ridden/A = ..() + . = A + if(istype(A)) + A.vehicle_ridden_target = src + +/obj/vehicle/ridden/post_unbuckle_mob(mob/living/M) + remove_occupant(M) + return ..() + +/obj/vehicle/ridden/post_buckle_mob(mob/living/M) + add_occupant(M) + return ..() + +/obj/vehicle/ridden/attackby(obj/item/I, mob/user, params) + if(key_type && !is_key(inserted_key) && is_key(I)) + if(user.transferItemToLoc(I, src)) + to_chat(user, "You insert \the [I] into \the [src].") + if(inserted_key) //just in case there's an invalid key + inserted_key.forceMove(drop_location()) + inserted_key = I + else + to_chat(user, "[I] seems to be stuck to your hand!") + return + return ..() + +/obj/vehicle/ridden/AltClick(mob/user) + if(user.Adjacent(src) && inserted_key) + if(!is_occupant(user)) + to_chat(user, "You must be riding the [src] to remove [src]'s key!") + return + to_chat(user, "You remove \the [inserted_key] from \the [src].") + inserted_key.forceMove(drop_location()) + user.put_in_hands(inserted_key) + inserted_key = null + return ..() + +/obj/vehicle/ridden/driver_move(mob/user, direction) + if(key_type && !is_key(inserted_key)) + to_chat(user, "[src] has no key inserted!") + return FALSE + var/datum/component/riding/R = GetComponent(/datum/component/riding) + R.handle_ride(user, direction) + return ..() + +/obj/vehicle/ridden/user_buckle_mob(mob/living/M, mob/user, check_loc = TRUE) + if(user.incapacitated()) + return + for(var/atom/movable/A in get_turf(src)) + if(A.density) + if(A != src && A != M) + return + M.forceMove(get_turf(src)) + . = ..() + +/obj/vehicle/ridden/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE) + if(!force && occupant_amount() >= max_occupants) + return FALSE + return ..() diff --git a/code/modules/vehicles/scooter.dm b/code/modules/vehicles/scooter.dm index 24cfd9ab92..66ae84f559 100644 --- a/code/modules/vehicles/scooter.dm +++ b/code/modules/vehicles/scooter.dm @@ -1,14 +1,20 @@ -/obj/vehicle/scooter +/obj/vehicle/ridden/scooter name = "scooter" desc = "A fun way to get around." icon_state = "scooter" -/obj/vehicle/scooter/attackby(obj/item/I, mob/user, params) +/obj/vehicle/ridden/scooter/Initialize() + . = ..() + var/datum/component/riding/D = LoadComponent(/datum/component/riding) + D.set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0), TEXT_SOUTH = list(-2), TEXT_EAST = list(0), TEXT_WEST = list( 2))) + + +/obj/vehicle/ridden/scooter/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/wrench)) to_chat(user, "You begin to remove the handlebars...") playsound(get_turf(user), 'sound/items/ratchet.ogg', 50, 1) if(do_after(user, 40*I.toolspeed, target = src)) - var/obj/vehicle/scooter/skateboard/S = new /obj/vehicle/scooter/skateboard(get_turf(src)) + var/obj/vehicle/ridden/scooter/skateboard/S = new(loc) new /obj/item/stack/rods(get_turf(src),2) to_chat(user, "You remove the handlebars from [src].") if(has_buckled_mobs()) @@ -17,9 +23,16 @@ S.buckle_mob(H) qdel(src) +/obj/vehicle/ridden/scooter/Moved() + . = ..() + for(var/m in buckled_mobs) + var/mob/living/buckled_mob = m + if(buckled_mob.get_num_legs() > 0) + buckled_mob.pixel_y = 5 + else + buckled_mob.pixel_y = -4 -/obj/vehicle/scooter/buckle_mob(mob/living/M, force = 0, check_loc = 1) - riding_datum = new/datum/riding/scooter +/obj/vehicle/ridden/scooter/buckle_mob(mob/living/M, force = 0, check_loc = 1) if(!istype(M)) return 0 if(M.get_num_legs() < 2 && M.get_num_arms() <= 0) @@ -27,29 +40,32 @@ return 0 . = ..() -/obj/vehicle/scooter/post_buckle_mob(mob/living/M) - riding_datum.account_limbs(M) - -/obj/vehicle/scooter/skateboard +/obj/vehicle/ridden/scooter/skateboard name = "skateboard" desc = "An unfinished scooter which can only barely be called a skateboard. It's still rideable, but probably unsafe. Looks like you'll need to add a few rods to make handlebars." icon_state = "skateboard" - density = FALSE -/obj/vehicle/scooter/skateboard/buckle_mob(mob/living/M, force = 0, check_loc = 1) +/obj/vehicle/ridden/scooter/skateboard/Initialize() . = ..() - riding_datum = new/datum/riding/scooter/skateboard + var/datum/component/riding/D = LoadComponent(/datum/component/riding) + D.vehicle_move_delay = 0 + D.set_vehicle_dir_layer(SOUTH, ABOVE_MOB_LAYER) + D.set_vehicle_dir_layer(NORTH, OBJ_LAYER) + D.set_vehicle_dir_layer(EAST, OBJ_LAYER) + D.set_vehicle_dir_layer(WEST, OBJ_LAYER) -/obj/vehicle/scooter/skateboard/post_buckle_mob(mob/living/M)//allows skateboards to be non-dense but still allows 2 skateboarders to collide with each other - if(has_buckled_mobs()) - density = TRUE - else +/obj/vehicle/ridden/scooter/skateboard/post_buckle_mob(mob/living/M)//allows skateboards to be non-dense but still allows 2 skateboarders to collide with each other + density = TRUE + return ..() + +/obj/vehicle/ridden/scooter/skateboard/post_unbuckle_mob(mob/living/M) + if(!has_buckled_mobs()) density = FALSE - ..() + return ..() -/obj/vehicle/scooter/skateboard/Collide(atom/A) - ..() +/obj/vehicle/ridden/scooter/skateboard/Collide(atom/A) + . = ..() if(A.density && has_buckled_mobs()) var/mob/living/carbon/H = buckled_mobs[1] var/atom/throw_target = get_edge_target_turf(H, pick(GLOB.cardinals)) @@ -63,7 +79,7 @@ visible_message("[src] crashes into [A], sending [H] flying!") playsound(src, 'sound/effects/bang.ogg', 50, 1) -/obj/vehicle/scooter/skateboard/MouseDrop(atom/over_object) +/obj/vehicle/ridden/scooter/skateboard/MouseDrop(atom/over_object) var/mob/living/carbon/M = usr if(!istype(M) || M.incapacitated() || !Adjacent(M)) return @@ -102,10 +118,10 @@ return M.use(5) to_chat(user, "You finish making wheels for [src].") - new /obj/vehicle/scooter/skateboard(user.loc) + new /obj/vehicle/ridden/scooter/skateboard(user.loc) qdel(src) -/obj/vehicle/scooter/skateboard/attackby(obj/item/I, mob/user, params) +/obj/vehicle/ridden/scooter/skateboard/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/screwdriver)) to_chat(user, "You begin to deconstruct and remove the wheels on [src]...") playsound(get_turf(user), I.usesound, 50, 1) @@ -129,7 +145,7 @@ return to_chat(user, "You add the rods to [src], creating handlebars.") C.use(2) - var/obj/vehicle/scooter/S = new/obj/vehicle/scooter(get_turf(src)) + var/obj/vehicle/ridden/scooter/S = new(loc) if(has_buckled_mobs()) var/mob/living/carbon/H = buckled_mobs[1] unbuckle_mob(H) diff --git a/code/modules/vehicles/secway.dm b/code/modules/vehicles/secway.dm index c85088ec8d..33f0d794c8 100644 --- a/code/modules/vehicles/secway.dm +++ b/code/modules/vehicles/secway.dm @@ -1,13 +1,12 @@ -/obj/vehicle/secway +/obj/vehicle/ridden/secway name = "secway" desc = "A brave security cyborg gave its life to help you look like a complete tool." icon_state = "secway" + key_type = /obj/item/key/security -/obj/item/key/security - desc = "A keyring with a small steel key, and a rubber stun baton accessory." - icon_state = "keysec" - -/obj/vehicle/secway/buckle_mob(mob/living/buckled_mob, force = 0, check_loc = 1) +/obj/vehicle/ridden/secway/Initialize() . = ..() - riding_datum = new/datum/riding/secway \ No newline at end of file + var/datum/component/riding/D = LoadComponent(/datum/component/riding) + D.vehicle_move_delay = 1 + D.set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 4), TEXT_SOUTH = list(0, 4), TEXT_EAST = list(0, 4), TEXT_WEST = list( 0, 4))) diff --git a/code/modules/vehicles/speedbike.dm b/code/modules/vehicles/speedbike.dm index 9200a3d696..e05504b0dc 100644 --- a/code/modules/vehicles/speedbike.dm +++ b/code/modules/vehicles/speedbike.dm @@ -1,44 +1,68 @@ -/obj/vehicle/space/speedbike + +/obj/vehicle/ridden/space + name = "Generic Space Vehicle!" + +/obj/vehicle/ridden/space/Initialize() + . = ..() + var/datum/component/riding/D = LoadComponent(/datum/component/riding) + D.override_allow_spacemove = TRUE + +/obj/vehicle/ridden/space/speedbike name = "Speedbike" icon = 'icons/obj/bike.dmi' icon_state = "speedbike_blue" layer = LYING_MOB_LAYER var/overlay_state = "cover_blue" - var/static/mutable_appearance/overlay + var/mutable_appearance/overlay -/obj/vehicle/space/speedbike/buckle_mob(mob/living/M, force = 0, check_loc = 1) +/obj/vehicle/ridden/space/speedbike/Initialize() . = ..() - riding_datum = new/datum/riding/space/speedbike - -/obj/vehicle/space/speedbike/New() - . = ..() - overlay = overlay || mutable_appearance(icon, overlay_state, ABOVE_MOB_LAYER) + overlay = mutable_appearance(icon, overlay_state, ABOVE_MOB_LAYER) add_overlay(overlay) + var/datum/component/riding/D = LoadComponent(/datum/component/riding) + D.set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, -8), TEXT_SOUTH = list(0, 4), TEXT_EAST = list(-10, 5), TEXT_WEST = list( 10, 5))) + D.vehicle_move_delay = 0 + D.set_vehicle_dir_offsets(NORTH, -16, -16) + D.set_vehicle_dir_offsets(SOUTH, -16, -16) + D.set_vehicle_dir_offsets(EAST, -18, 0) + D.set_vehicle_dir_offsets(WEST, -18, 0) -/obj/vehicle/space/speedbike/Move(newloc,move_dir) +/obj/vehicle/ridden/space/speedbike/Move(newloc,move_dir) if(has_buckled_mobs()) new /obj/effect/temp_visual/dir_setting/speedbike_trail(loc,move_dir) . = ..() -/obj/vehicle/space/speedbike/red +/obj/vehicle/ridden/space/speedbike/red icon_state = "speedbike_red" overlay_state = "cover_red" //BM SPEEDWAGON -/obj/vehicle/space/speedbike/speedwagon +/obj/vehicle/ridden/space/speedwagon name = "BM Speedwagon" desc = "Push it to the limit, walk along the razor's edge." icon = 'icons/obj/car.dmi' icon_state = "speedwagon" layer = LYING_MOB_LAYER - overlay_state = "speedwagon_cover" + var/static/mutable_appearance/overlay = mutable_appearance(icon, "speedwagon_cover", ABOVE_MOB_LAYER) max_buckled_mobs = 4 var/crash_all = FALSE //CHAOS pixel_y = -48 //to fix the offset when Initialized() pixel_x = -48 -/obj/vehicle/space/speedbike/speedwagon/Collide(atom/movable/A) +/obj/vehicle/ridden/space/speedwagon/Initialize() + . = ..() + add_overlay(overlay) + var/datum/component/riding/D = LoadComponent(/datum/component/riding) + D.vehicle_move_delay = 0 + D.set_riding_offsets(1, list(TEXT_NORTH = list(-10, -4), TEXT_SOUTH = list(16, 3), TEXT_EAST = list(-4, 30), TEXT_WEST = list(4, -3))) + D.set_riding_offsets(2, list(TEXT_NORTH = list(19, -5, 4), TEXT_SOUTH = list(-13, 3, 4), TEXT_EAST = list(-4, -3, 4.1), TEXT_WEST = list(4, 28, 3.9))) + D.set_riding_offsets(3, list(TEXT_NORTH = list(-10, -18, 4.2), TEXT_SOUTH = list(16, 25, 3.9), TEXT_EAST = list(-22, 30), TEXT_WEST = list(22, -3, 4.1))) + D.set_riding_offsets(4, list(TEXT_NORTH = list(19, -18, 4.2), TEXT_SOUTH = list(-13, 25, 3.9), TEXT_EAST = list(-22, 3, 3.9), TEXT_WEST = list(22, 28))) + for(var/i in GLOB.cardinals) + D.set_vehicle_dir_layer(i, BELOW_MOB_LAYER) + +/obj/vehicle/ridden/space/speedwagon/Collide(atom/movable/A) . = ..() if(A.density && has_buckled_mobs()) var/atom/throw_target = get_edge_target_turf(A, dir) @@ -56,11 +80,7 @@ visible_message("[src] crashes into [H]!") playsound(src, 'sound/effects/bang.ogg', 50, 1) -/obj/vehicle/space/speedbike/speedwagon/buckle_mob(mob/living/M, force = 0, check_loc = 1) - . = ..() - riding_datum = new/datum/riding/space/speedwagon - -/obj/vehicle/space/speedbike/speedwagon/Moved() +/obj/vehicle/ridden/space/speedwagon/Moved() . = ..() if(has_buckled_mobs()) for(var/atom/A in range(2, src)) diff --git a/code/modules/vehicles/vehicle.dm b/code/modules/vehicles/vehicle.dm deleted file mode 100644 index e538599754..0000000000 --- a/code/modules/vehicles/vehicle.dm +++ /dev/null @@ -1,108 +0,0 @@ - -/obj/vehicle - name = "vehicle" - desc = "A basic vehicle, vroom." - icon = 'icons/obj/vehicles.dmi' - icon_state = "fuckyou" - density = TRUE - anchored = FALSE - can_buckle = 1 - buckle_lying = 0 - max_integrity = 300 - armor = list(melee = 30, bullet = 30, laser = 30, energy = 0, bomb = 30, bio = 0, rad = 0, fire = 60, acid = 60) - var/auto_door_open = TRUE - var/view_range = 7 - var/datum/riding/riding_datum = null - -/obj/vehicle/Destroy() - QDEL_NULL(riding_datum) - return ..() - -/obj/vehicle/update_icon() - return - -/obj/item/key - name = "key" - desc = "A small grey key." - icon = 'icons/obj/vehicles.dmi' - icon_state = "key" - w_class = WEIGHT_CLASS_TINY - -//BUCKLE HOOKS -/obj/vehicle/unbuckle_mob(mob/living/buckled_mob,force = 0) - if(riding_datum) - riding_datum.restore_position(buckled_mob) - . = ..() - - -/obj/vehicle/user_buckle_mob(mob/living/M, mob/living/user) - if(!istype(user) || user.incapacitated()) - return - for(var/atom/movable/A in get_turf(src)) - if(A.density) - if(A != src && A != M) - return - M.forceMove(get_turf(src)) - ..() - if(user.client) - user.client.change_view(view_range) - if(riding_datum) - riding_datum.ridden = src - riding_datum.handle_vehicle_offsets() - -//MOVEMENT -/obj/vehicle/relaymove(mob/user, direction) - if(riding_datum) - riding_datum.handle_ride(user, direction) - - -/obj/vehicle/Moved() - . = ..() - if(riding_datum) - riding_datum.handle_vehicle_layer() - riding_datum.handle_vehicle_offsets() - - -/obj/vehicle/Collide(atom/movable/M) - . = ..() - if(auto_door_open) - if(istype(M, /obj/machinery/door) && has_buckled_mobs()) - for(var/m in buckled_mobs) - M.CollidedWith(m) - - -/obj/vehicle/Process_Spacemove(direction) - if(has_gravity()) - return 1 - - if(pulledby && (pulledby.loc != loc)) - return 1 - - return 0 - -/obj/vehicle/space - pressure_resistance = INFINITY - - -/obj/vehicle/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) - if(damage_flag == "melee" && damage_amount < 20) - return 0 - . = ..() - -/obj/vehicle/deconstruct(disassembled = TRUE) - new /obj/item/stack/sheet/metal (loc, 5) - qdel(src) - -/obj/vehicle/examine(mob/user) - ..() - if(!(resistance_flags & INDESTRUCTIBLE)) - if(resistance_flags & ON_FIRE) - to_chat(user, "It's on fire!") - var/healthpercent = (obj_integrity/max_integrity) * 100 - switch(healthpercent) - if(50 to 99) - to_chat(user, "It looks slightly damaged.") - if(25 to 50) - to_chat(user, "It appears heavily damaged.") - if(0 to 25) - to_chat(user, "It's falling apart!") \ No newline at end of file diff --git a/code/modules/vehicles/vehicle_actions.dm b/code/modules/vehicles/vehicle_actions.dm new file mode 100644 index 0000000000..865834495f --- /dev/null +++ b/code/modules/vehicles/vehicle_actions.dm @@ -0,0 +1,112 @@ +//VEHICLE DEFAULT HANDLING +/obj/vehicle/proc/generate_actions() + return + +/obj/vehicle/proc/generate_action_type(actiontype) + var/datum/action/vehicle/A = new actiontype + if(!istype(A)) + return + A.vehicle_target = src + return A + +/obj/vehicle/proc/initialize_passenger_action_type(actiontype) + autogrant_actions_passenger += actiontype + for(var/i in occupants) + grant_passenger_actions(i) //refresh + +/obj/vehicle/proc/initialize_controller_action_type(actiontype, control_flag) + LAZYINITLIST(autogrant_actions_controller["[control_flag]"]) + autogrant_actions_controller["[control_flag]"] += actiontype + for(var/i in occupants) + grant_controller_actions(i) //refresh + +/obj/vehicle/proc/grant_action_type_to_mob(actiontype, mob/m) + if(!occupants[m] || !actiontype) + return FALSE + LAZYINITLIST(occupant_actions[m]) + if(occupant_actions[m][actiontype]) + return TRUE + var/datum/action/action = generate_action_type(actiontype) + action.Grant(m) + occupant_actions[m][action.type] = action + return TRUE + +/obj/vehicle/proc/remove_action_type_from_mob(actiontype, mob/m) + if(!occupants[m] || !actiontype) + return FALSE + LAZYINITLIST(occupant_actions[m]) + if(occupant_actions[m][actiontype]) + var/datum/action/action = occupant_actions[m][actiontype] + action.Remove(m) + occupant_actions[m] -= actiontype + return TRUE + +/obj/vehicle/proc/grant_passenger_actions(mob/M) + for(var/v in autogrant_actions_passenger) + grant_action_type_to_mob(v, M) + +/obj/vehicle/proc/remove_passenger_actions(mob/M) + for(var/v in autogrant_actions_passenger) + remove_action_type_from_mob(v, M) + +/obj/vehicle/proc/grant_controller_actions(mob/M) + if(!istype(M) || !occupants[M]) + return FALSE + for(var/i in GLOB.bitflags) + if(occupants[M] & i) + grant_controller_actions_by_flag(M, i) + return TRUE + +/obj/vehicle/proc/remove_controller_actions(mob/M) + if(!istype(M) || !occupants[M]) + return FALSE + for(var/i in GLOB.bitflags) + remove_controller_actions_by_flag(M, i) + return TRUE + +/obj/vehicle/proc/grant_controller_actions_by_flag(mob/M, flag) + if(!istype(M) || !autogrant_actions_controller["[flag]"]) + return FALSE + for(var/v in autogrant_actions_controller["[flag]"]) + grant_action_type_to_mob(v, M) + return TRUE + +/obj/vehicle/proc/remove_controller_actions_by_flag(mob/M, flag) + if(!istype(M) || autogrant_actions_controller["[flag]"]) + return FALSE + for(var/v in autogrant_actions_controller["[flag]"]) + remove_action_type_from_mob(v, M) + return TRUE + +/obj/vehicle/proc/cleanup_actions_for_mob(mob/M) + if(!istype(M)) + return FALSE + LAZYINITLIST(occupant_actions[M]) + for(var/path in occupant_actions[M]) + stack_trace("Leftover action type [path] in vehicle type [type] for mob type [M.type] - THIS SHOULD NOT BE HAPPENING!") + var/datum/action/action = occupant_actions[M] + action.Remove(M) + occupant_actions -= M + return TRUE + +//ACTION DATUMS + +/datum/action/vehicle + check_flags = AB_CHECK_RESTRAINED | AB_CHECK_STUN | AB_CHECK_CONSCIOUS + icon_icon = 'icons/mob/actions/actions_vehicle.dmi' + button_icon_state = "vehicle_eject" + var/obj/vehicle/vehicle_target + +/datum/action/vehicle/sealed + var/obj/vehicle/sealed/vehicle_entered_target + +/datum/action/vehicle/sealed/climb_out + name = "Climb Out" + desc = "Climb out of your vehicle!" + +/datum/action/vehicle/sealed/climb_out/Trigger() + if(..() && istype(vehicle_entered_target)) + vehicle_entered_target.mob_try_exit(owner, owner) + +/datum/action/vehicle/ridden + var/obj/vehicle/ridden/vehicle_ridden_target diff --git a/code/modules/vehicles/vehicle_key.dm b/code/modules/vehicles/vehicle_key.dm new file mode 100644 index 0000000000..e34ad9253d --- /dev/null +++ b/code/modules/vehicles/vehicle_key.dm @@ -0,0 +1,15 @@ +/obj/item/key + name = "key" + desc = "A small grey key." + icon = 'icons/obj/vehicles.dmi' + icon_state = "key" + w_class = WEIGHT_CLASS_TINY + +/obj/item/key/security + desc = "A keyring with a small steel key, and a rubber stun baton accessory." + icon_state = "keysec" + +/obj/item/key/janitor + desc = "A keyring with a small steel key, and a pink fob reading \"Pussy Wagon\"." + icon_state = "keyjanitor" + diff --git a/code/modules/vore/resizing/sizegun_vr.dm b/code/modules/vore/resizing/sizegun_vr.dm index de6e0eb7f0..51b6e24736 100644 --- a/code/modules/vore/resizing/sizegun_vr.dm +++ b/code/modules/vore/resizing/sizegun_vr.dm @@ -11,7 +11,6 @@ fire_sound = 'sound/weapons/wave.ogg' charge_cost = 100 projectile_type = /obj/item/projectile/beam/shrinklaser - origin_tech = "redspace=1;bluespace=4" modifystate = "sizegun-shrink" selfcharge = 1 firemodes = list( @@ -88,7 +87,6 @@ datum/design/sizeray name = "Size Ray" desc = "Abuse bluespace tech to alter living matter scale." id = "sizeray" - req_tech = list("combat" = 5, "materials" = 4, "engineering" = 5, "bluespace" = 4) build_type = PROTOLATHE materials = list(MAT_METAL = 1000, MAT_GLASS = 1000, MAT_DIAMOND = 2500, MAT_URANIUM = 2500, MAT_TITANIUM = 1000) build_path = /obj/item/gun/energy/laser/sizeray @@ -155,7 +153,6 @@ datum/design/sizeray desc = "Size manipulator using bluespace breakthroughs." item_state = null //so the human update icon uses the icon_state instead. ammo_type = list(/obj/item/ammo_casing/energy/laser/shrinkray, /obj/item/ammo_casing/energy/laser/growthray) - origin_tech = "combat=1;magnets=2" selfcharge = 1 charge_delay = 5 ammo_x_offset = 2 diff --git a/code/modules/zombie/organs.dm b/code/modules/zombie/organs.dm index d55059960f..07e3648417 100644 --- a/code/modules/zombie/organs.dm +++ b/code/modules/zombie/organs.dm @@ -4,7 +4,6 @@ zone = "head" slot = ORGAN_SLOT_ZOMBIE icon_state = "blacktumor" - origin_tech = "biotech=5" var/datum/species/old_species = /datum/species/human var/living_transformation_time = 30 var/converts_living = FALSE diff --git a/config/admin_ranks.txt b/config/admin_ranks.txt index 96737c5484..3cf5cbfb72 100644 --- a/config/admin_ranks.txt +++ b/config/admin_ranks.txt @@ -27,17 +27,19 @@ # +RIGHTS (or +PERMISSIONS) = allows you to promote and/or demote people. # +SOUND (or +SOUNDS) = allows you to upload and play sounds # +SPAWN (or +CREATE) = mob transformations, spawning of most atoms including mobs (high-risk atoms, e.g. blackholes, will require the +FUN flag too) +# +AUTOLOGIN = admin gains powers upon connect. This defaults to on, you can use -AUTOLOGIN to make a role require using the readmin verb to gain powers. (this does not effect the admin's ability to walk past bans or other on-connect limitations like panic bunker or pop limit.) # +EVERYTHING (or +HOST or +ALL) = Simply gives you everything without having to type every flag # END_KEYWORDS -Admin Observer +Admin Observer = -AUTOLOGIN Moderator = +ADMIN Admin Candidate = +@ Trial Admin = +@ +SPAWN +REJUV +VAREDIT +BAN Badmin = +@ +POSSESS +BUILDMODE +SERVER +FUN Game Admin = +@ +STEALTH +SOUNDS +DEBUG Game Master = +EVERYTHING +Lazy Master = +EVERYTHING -AUTOLOGIN Host = +EVERYTHING -Coder = +DEBUG +VAREDIT +SERVER +SPAWN \ No newline at end of file +Coder = +DEBUG +VAREDIT +SERVER +SPAWN -AUTOLOGIN diff --git a/config/admins.txt b/config/admins.txt index b7d8cf0e6b..0f5684b465 100644 --- a/config/admins.txt +++ b/config/admins.txt @@ -15,7 +15,7 @@ Optimumtact = Host NewSta = Game Master Expletives = Game Master kingofkosmos = Game Master -MrStonedOne = Game Master +MrStonedOne = Lazy Master microscopics = Game Master Gun Hog = Game Master KorPhaeron = Game Master diff --git a/config/config.txt b/config/config.txt index a05e463f45..e43b38b568 100644 --- a/config/config.txt +++ b/config/config.txt @@ -1,3 +1,9 @@ +# You can use the "$include" directive to split your configs however you want + +$include game_options.txt +$include dbconfig.txt +$include comms.txt + # You can use the @ character at the beginning of a config option to lock it from being edited in-game # Example usage: # @SERVERNAME tgstation @@ -386,3 +392,10 @@ DISABLE_HIGH_POP_MC_MODE_AMOUNT 60 ## Uncomment to set the number of /world/Reboot()s before the DreamDaemon restarts itself. 0 means restart every round. Requires tgstation server tools. #ROUNDS_UNTIL_HARD_RESTART 10 + + +##Default screen resolution, in tiles. +## By default, this is 15x15, which gets simplified to 7 by BYOND, as it is a 1:1 screen ratio. +## For reference, Goonstation uses a resolution of 21x15 for it's widescreen mode. +## Do note that changing this value will affect the title screen. The title screen will have to be updated manually if this is changed. +DEFAULT_VIEW 15x15 diff --git a/config/unbuyableshuttles.txt b/config/unbuyableshuttles.txt index 30c887b39b..b563c6c0e6 100644 --- a/config/unbuyableshuttles.txt +++ b/config/unbuyableshuttles.txt @@ -27,3 +27,4 @@ #_maps/shuttles/emergency_scrapheap.dmm #_maps/shuttles/emergency_supermatter.dmm #_maps/shuttles/emergency_wabbajack.dmm +#_maps/shuttles/emergency_discoinferno.dmm diff --git a/html/browser/roundend.css b/html/browser/roundend.css new file mode 100644 index 0000000000..82235f1273 --- /dev/null +++ b/html/browser/roundend.css @@ -0,0 +1,67 @@ +.greentext { + color: #90ee90; + font-weight: bold; +} + +.greentext_alt { + color: green; +} +.redtext { + color: #ef2f3c; + font-weight: bold; +} +.neutraltext { + font-weight: bold; /* If you feel these should have some color feel free to change */ +} + +.marooned { + color: rgb(109, 109, 255); font-weight: bold; +} + +.header { + font-size: 24px; font-weight: bold; +} + +.big { + font-size: 24px; +} + +.medaltext { + color: #add8e6; +} + +.codephrase { + color : #ef2f3c; +} + +.redborder { + border-bottom: 2px solid #ef2f3c; +} + +.greenborder { + border-bottom: 2px solid #90ee90; +} + +.clockborder { + border-bottom: 2px solid #B18B25; +} + +.stationborder { + border-bottom: 2px solid #add8e6; +} + +li { + margin-bottom: 0.2rem; +} + +.panel { + background-color: #313131; + padding: 10px; + border-radius: 10px; + margin-bottom: 5px; +} + +body { + background-color: #272727; + color: #efefef; +} \ No newline at end of file diff --git a/html/changelog.css b/html/changelog.css index 031c1e42c0..2bfa3fa495 100644 --- a/html/changelog.css +++ b/html/changelog.css @@ -1,41 +1,41 @@ -.top{font-family:Tahoma,sans-serif;font-size:12px;} -h2{font-family:Tahoma,sans-serif;} -a img {border:none;} -.bgimages16 li { - padding:2px 10px 2px 30px; - background-position:6px center; - background-repeat:no-repeat; - border:1px solid #ddd; - border-left:4px solid #999; - margin-bottom:2px; -} -.bugfix {background-image:url(bug-minus.png)} -.wip {background-image:url(hard-hat-exclamation.png)} -.tweak {background-image:url(wrench-screwdriver.png)} -.soundadd {background-image:url(music-plus.png)} -.sounddel {background-image:url(music-minus.png)} -.rscdel {background-image:url(cross-circle.png)} -.rscadd {background-image:url(tick-circle.png)} -.imageadd {background-image:url(image-plus.png)} -.imagedel {background-image:url(image-minus.png)} -.spellcheck {background-image:url(spell-check.png)} -.experiment {background-image:url(burn-exclamation.png)} -.refactor {background-image:url(burn-exclamation.png)} -.code_imp {background-image:url(coding.png)} -.config {background-image:url(chrome_wrench.png)} -.admin {background-image:url(ban.png)} -.server {background-image:url(hard-hat-exclamation.png)} -.balance {background-image:url(scales.png)} -.sansserif {font-family:Tahoma,sans-serif;font-size:12px;} -.commit {margin-bottom:20px;font-size:100%;font-weight:normal;} -.changes {list-style:none;margin:5px 0;padding:0 0 0 25px;font-size:0.8em;} -.date {margin:10px 0;color:blue;border-bottom:2px solid #00f;width:60%;padding:2px 0;font-size:1em;font-weight:bold;} -.author {padding-left:10px;margin:0;font-weight:bold;font-size:0.9em;} -.drop {cursor:pointer;border:1px solid #999;display:inline;font-size:0.9em;padding:1px 20px 1px 5px;line-height:16px;} -.hidden {display:none;} -.indrop {margin:2px 0 0 0;clear:both;background:#fff;border:1px solid #ddd;padding:5px 10px;} -.indrop p {margin:0;font-size:0.8em;line-height:16px;margin:1px 0;} -.indrop img {margin-right:5px;vertical-align:middle;} -.closed {background:url(chevron-expand.png) right center no-repeat;} -.open {background:url(chevron.png) right center no-repeat;} -.lic {font-size:9px;} \ No newline at end of file +.top{font-family:Tahoma,sans-serif;font-size:12px;} +h2{font-family:Tahoma,sans-serif;} +a img {border:none;} +.bgimages16 li { + padding:2px 10px 2px 30px; + background-position:6px center; + background-repeat:no-repeat; + border:1px solid #ddd; + border-left:4px solid #999; + margin-bottom:2px; +} +.bugfix {background-image:url(bug-minus.png)} +.wip {background-image:url(hard-hat-exclamation.png)} +.tweak {background-image:url(wrench-screwdriver.png)} +.soundadd {background-image:url(music-plus.png)} +.sounddel {background-image:url(music-minus.png)} +.rscdel {background-image:url(cross-circle.png)} +.rscadd {background-image:url(tick-circle.png)} +.imageadd {background-image:url(image-plus.png)} +.imagedel {background-image:url(image-minus.png)} +.spellcheck {background-image:url(spell-check.png)} +.experiment {background-image:url(burn-exclamation.png)} +.refactor {background-image:url(burn-exclamation.png)} +.code_imp {background-image:url(coding.png)} +.config {background-image:url(chrome-wrench.png)} +.admin {background-image:url(ban.png)} +.server {background-image:url(hard-hat-exclamation.png)} +.balance {background-image:url(scales.png)} +.sansserif {font-family:Tahoma,sans-serif;font-size:12px;} +.commit {margin-bottom:20px;font-size:100%;font-weight:normal;} +.changes {list-style:none;margin:5px 0;padding:0 0 0 25px;font-size:0.8em;} +.date {margin:10px 0;color:blue;border-bottom:2px solid #00f;width:60%;padding:2px 0;font-size:1em;font-weight:bold;} +.author {padding-left:10px;margin:0;font-weight:bold;font-size:0.9em;} +.drop {cursor:pointer;border:1px solid #999;display:inline;font-size:0.9em;padding:1px 20px 1px 5px;line-height:16px;} +.hidden {display:none;} +.indrop {margin:2px 0 0 0;clear:both;background:#fff;border:1px solid #ddd;padding:5px 10px;} +.indrop p {margin:0;font-size:0.8em;line-height:16px;margin:1px 0;} +.indrop img {margin-right:5px;vertical-align:middle;} +.closed {background:url(chevron-expand.png) right center no-repeat;} +.open {background:url(chevron.png) right center no-repeat;} +.lic {font-size:9px;} diff --git a/html/changelog.html b/html/changelog.html index 45dfe57b20..d73ebdcd62 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -1279,3 +1279,1492 @@ + + + + /tg/ Station 13 Changelog + + + + + + + +
    + + + + +
    +
    Traditional Games Space Station 13
    + +

    + Visit our IRC channel: #tgstation13 on irc.rizon.net +
    + + + + + +
    + Current Project Maintainers: -Click Here-
    + Currently Active GitHub contributor list: -Click Here-
    + Coders: TLE, NEO, Errorage, muskets, veryinky, Skie, Noise, Numbers, Agouri, Noka, Urist McDorf, Uhangi, Darem, Mport, rastaf0, Doohl, Superxpdude, Rockdtben, ConstantA, Petethegoat, Kor, Polymorph, Carn, Nodrak, Donkie, Sieve, Giacom, Ikarrus, trubble_bass, Aranclanos, Cael_Aislinn, Cheridan, Intigracy, Malkevin, SuperSayu, DumpDavidson, Tastyfish, Yvar, Elo001, Fleure, ManeaterMildred, Miauw, MrPerson
    + Spriters: Agouri, Cheridan, Cruazy Guest, Deeaych, Deuryn, Matty406, Microwave, ShiftyEyesShady, Skie, Uhangi, Veyveyr, Petethegoat, Kor, Ricotez, Ausops, TankNut, Pewtershmitz, Firecage, Nienhaus2
    + Sounds: Skie, Lasty/Vinyl
    + Main Testers: Tenebrosity, Anyone who has submitted a bug to the issue tracker
    + Thanks to: Baystation 12, /vg/station, NTstation, CDK Station devs, FacepunchStation, GoonStation devs, the original SpaceStation developers and Invisty for the title image.
    Also a thanks to anybody who has contributed who is not listed here :( Ask to be added here on irc.
    +
    Have a bug to report?
    Visit our Issue Tracker.
    + Please ensure that the bug has not already been reported and use the template provided here. +
    + + +
    +

    16 December 2017

    +

    Armhulen and lagnas2000 (+his team of amazing spriters) updated:

    +
      +
    • Mi-go have entered your realm!
    • +
    +

    Robustin updated:

    +
      +
    • Marauder shields now take twice as long to regenerate and only recharge one charge at a time.
    • +
    • Marauders now have 120hp down from 150hp.
    • +
    • The wizard event "race swap" should now stick to "safer" species.
    • +
    • Zombies are now properly stunned for a maximum of 2 seconds instead of 2/10ths of a second.
    • +
    • Zombie slowdown adjusted from -2 to -1.6.
    • +
    +

    SpaceManiac updated:

    +
      +
    • The shuttle will no longer be autocalled if the round has already ended.
    • +
    +

    Xhuis updated:

    +
      +
    • Vitality matrices don't have visible messages when someone crosses them anymore.
    • +
    + +

    15 December 2017

    +

    AverageJoe82 updated:

    +
      +
    • drones now have night vision
    • +
    • drones no longer have lights
    • +
    +

    Cruix updated:

    +
      +
    • Shuttles now place hyperspace ripples where they are about to land again.
    • +
    +

    Cyberboss updated:

    +
      +
    • Added "$include" directives to config files. These are recursive. Only config.txt will be default loaded if they are specified inside it
    • +
    • Added multi string list entry CROSS_SERVER. e.g. CROSS_SERVER Server+Name byond://server.net:1337
    • +
    • CROSS_SERVER_ADDRESS removed
    • +
    +

    Epoc updated:

    +
      +
    • Adds Cybernetic Lungs to the Cyber Organs research node
    • +
    +

    JStheguy updated:

    +
      +
    • Added 10 new assembly designs to the integrated circuit printer, the difference from current designs is purely aesthetics.
    • +
    • Added the icons for said new assembly designs to electronic_setups.dmi, changed the current electronic mechanism and electronic machine sprites.
    • +
    +

    MrStonedOne updated:

    +
      +
    • Added new admin flag, AUTOLOGIN, to control if admins start with admin powers. this defaults to on, and can be removed with -AUTOLOGIN
    • +
    • Admins with +PERMISSION may now deadmin or readmin other admins via the permission panel.
    • +
    +

    Naksu updated:

    +
      +
    • Preliminary work on tracking cliented living mobs across Z-levels to facilitate mob AI changes later
    • +
    • Tidied up some loc assignments
    • +
    • fixes the remaining loc assignments
    • +
    +

    ShizCalev updated:

    +
      +
    • Revamped gun dry-firing sounds.
    • +
    • Everyone around you will now hear when your gun goes click. You don't want to hear click when you want to hear bang!
    • +
    +

    SpaceManiac updated:

    +
      +
    • Remote signaler and other non-telecomms radio code has been cleaned up.
    • +
    +

    Xhuis updated:

    +
      +
    • Grinding runed metal and brass now produces iron/blood and iron/teslium, respectively.
    • +
    • As part of some code-side improvements, the amount of reagents you get from grinding some objects might be slightly different.
    • +
    • Some grinding recipes that didn't work, like dead mice and glowsticks, now do.
    • +
    • All-In-One grinders now correctly grind up everything, instead of one thing at a time.
    • +
    +

    nicbn updated:

    +
      +
    • Closet sprites changed.
    • +
    + +

    13 December 2017

    +

    Naksu updated:

    +
      +
    • glass shards and bananium floors no longer make a sound when "walked" over by a camera or a ghost
    • +
    +

    SpaceManiac updated:

    +
      +
    • Nonstandard power cells found in MULEbots, cyborgs, and elsewhere now have the correct description.
    • +
    +

    deathride58 updated:

    +
      +
    • Genetics will no longer have a random block completely disappear each round
    • +
    + +

    12 December 2017

    +

    Mark9013100 updated:

    +
      +
    • Medical Wardrobes now contain an additional standard and EMT labcoat.
    • +
    +

    Robustin updated:

    +
      +
    • The blood cult revive rune will now replace the souls of braindead or inactive cultists/constructs when properly invoked. These "revivals" will not count toward the revive limit.
    • +
    • The clock cult healing rune will now replace the souls of braindead or inactive cultists/constructs when left atop the rune. These "revivals" will not drain the rune's energy.
    • +
    +

    Swindly updated:

    +
      +
    • Swarmers can no longer deconstruct objects with living things in them.
    • +
    +

    kevinz000 updated:

    +
      +
    • You can now print telecomms equipment again.
    • +
    + +

    11 December 2017

    +

    Anonmare updated:

    +
      +
    • Booze-o-mats have beer
    • +
    +

    Cruix updated:

    +
      +
    • The white ship navigation computer now takes 10 seconds to designate a landing spot, and users can no longer see the syndicate shuttle or its custom landing location. If the white ship landing location would intersect the syndicate shuttle or its landing location, it will fail after the 10 seconds have elapsed.
    • +
    +

    Frozenguy5 updated:

    +
      +
    • Some hardsuits have had their melee, fire and rad armor ratings tweaked.
    • +
    +

    Improvedname updated:

    +
      +
    • cats now drop their ears and tail when butchered.
    • +
    +

    Robustin updated:

    +
      +
    • Modes not in rotation have had their "false report" weights for the Command Report standardized
    • +
    +

    SpaceManiac updated:

    +
      +
    • The MULEbots that the station starts with now show their ID numbers.
    • +
    • The dependency by Advanced Cybernetic Implants and Experimental Flight Equipment on Integrated HUDs has been restored.
    • +
    +

    kevinz000 updated:

    +
      +
    • flightsuits should no longer disappear when you take them off involuntarily
    • +
    • beam rifles actually fire striaght now
    • +
    • click catchers now actually work
    • +
    • you no longer see space in areas you normally can't see, instead of black. in reality you can still see space but it's faint enough that you can't tell so I'll say I fixed it.
    • +
    +

    uraniummeltdown updated:

    +
      +
    • Added MANY new types of airlock assembly that can be built with metal. Use metal in hand to see the new airlock assembly recipes.
    • +
    • Added new airlock types to the RCD and airlock painter
    • +
    • Vault door assemblies can be built with 8 plasteel, high security assemblies with 6 plasteel
    • +
    • Glass mineral airlocks are finally constructible. Use glass and mineral sheets on an airlock assembly in any order to make them.
    • +
    • Glass and mineral sheets are now able to be welded out of door assemblies rather than having to deconstruct the whole thing
    • +
    • Airlock painter no longer works on airlock assemblies (still works on airlocks)
    • +
    • Titanium airlocks no longer have any missing overlays
    • +
    + +

    10 December 2017

    +

    SpaceManiac updated:

    +
      +
    • External airlocks of the mining base and gulag are now cycle-linked.
    • +
    • The pAI software interface is now accessible via an action button.
    • +
    +

    Swindly updated:

    +
      +
    • You can kill yourself with a few more items.
    • +
    +

    XDTM updated:

    +
      +
    • Instead of activating randomly on speech, Godwoken Syndrome randomly grants inspiration, causing the next message to be a Voice of God.
    • +
    +

    Xhuis updated:

    +
      +
    • Flickering lights will now actually flicker and not go between emergency lights and normal lighting.
    • +
    • Emergency lights no longer stay on forever in some cases.
    • +
    +

    kevinz000 updated:

    +
      +
    • Nanotrasen would like to remind crewmembers and especially medical personnel to stand clear of cadeavers before applying a defibrillator shock. (You get shocked if you're pulling/grabbing someone being defibbed.)
    • +
    • defib shock/charge sounds upped from 50% to 75%.
    • +
    + +

    08 December 2017

    +

    Dax Dupont updated:

    +
      +
    • Fixed observer chat flavor of silicon chat.
    • +
    • Grilles now no longer revert to a pre-broken icon state when you hit them after they broke.
    • +
    +

    Dorsisdwarf updated:

    +
      +
    • Minor fixes to some techweb nodes
    • +
    • Made flight suits, combat implants, and combat modules require more nodes
    • +
    +

    Fox McCloud updated:

    +
      +
    • Slime blueprints can now make an area compatible with Xenobio consoles, regardless of the name of the new area
    • +
    +

    MrDoomBringer updated:

    +
      +
    • All stations have been outfitted with brand new Smoke Machines! They have nicer sprites now!
    • +
    +

    Shadowlight213 updated:

    +
      +
    • You now can get a medal for wasting hours talking to the secret debug tile.
    • +
    • Fixed runtime for the tile when poly's speech file doesn't exist.
    • +
    +

    Xhuis updated:

    +
      +
    • You can now make pet carriers from the autolathe, to carry around chef meat and other small animals without having to drag them. The HoP, captain, and CMO also start with carriers in their lockers for their pets.
    • +
    +

    YPOQ updated:

    +
      +
    • Fixed the camera failure, race swap, cursed items, and imposter wizard random events
    • +
    • The cursed items event no longer nullspaces items
    • +
    +

    jammer312 updated:

    +
      +
    • Action buttons now remember positions where you locked.
    • +
    • Now locking action buttons prevents them from being reset.
    • +
    + +

    07 December 2017

    +

    ShizCalev updated:

    +
      +
    • Games vending machines can now properly be rebuilt.
    • +
    • Games vending machines can now be refilled via supply crates.
    • +
    • Games Supply Crates have been added to the cargo console.
    • +
    +

    SpaceManiac updated:

    +
      +
    • Radio frequency 148.9 is once again serviced by the telecomms system.
    • +
    +

    Xhuis updated:

    +
      +
    • Added the Eminence role to clockcult! Players can elect themselves or ghosts as the Eminence from the eminence spire structure on Reebe.
    • +
    • The Eminence is incorporeal and invisible, and directs the entire cult. Anything they say is heard over the Hierophant network, and they can issue commands by middle-clicking themselves or different turfs.
    • +
    • The Eminence also has a single-use mass recall that warps all servants to the Ark chamber.
    • +
    • Added traps, triggers, and brass filaments to link them. They can all be constructed from brass sheets, and do different things and trigger in different ways. Current traps include the brass skewer and steam vent, and triggers include the pressure sensor, lever, and repeater.
    • +
    • The Eminence can activate trap triggers by clicking on them!
    • +
    • Servants can deconstruct traps instantly with a wrench.
    • +
    • Mending Mantra has been removed.
    • +
    • Clockwork scriptures have been recolored and sorted based on their functions; yellow scriptures are for construction, red for offense, blue for defense, and purple for niche.
    • +
    • Servants now spawn with a PDA and black shoes to make disguise more feasible.
    • +
    • The Eminence can superheat up to 20 clockwork walls at a time. Superheated walls are immune to hulk and mech punches, but can still be broken conventionally.
    • +
    • Clockwork walls are slightly faster to build before the Ark activates, taking an extra second less.
    • +
    • Poly no longer continually undergoes binary fission when Ratvar is in range.
    • +
    • The global records alert for servants will no longer display info that doesn't affect them since the rework.
    • +
    +

    coiax updated:

    +
      +
    • The drone dispenser on Box Station has been moved from the Testing Lab to the Morgue/Robotics maintenance tunnel.
    • +
    +

    deathride58 updated:

    +
      +
    • The default view range can now be defined in the config. The default is 15x15, which is simplified to 7 by BYOND. For reference, Goonstation's widescreen range is 21x15. Do note that changing this value will affect the title screen. The title screen images and the title screen area on the Centcom z-level will have to be updated if the default view range is changed.
    • +
    + +

    06 December 2017

    +

    Dax Dupont & Alek2ander updated:

    +
      +
    • Binary chat messages been made more visible.
    • +
    +

    Revenant Defile ability updated:

    +
      +
    • Revenant's Defile now removes salt piles
    • +
    +

    XDTM updated:

    +
      +
    • Brain damage has been completely reworked! remove: Brain damage now no longer simply makes you dumb. Although most of its effects have been shifted into a brain trauma.
    • +
    • Every time you take brain damage, there's a chance you'll suffer a brain trauma. There are many variations of brain traumas, split in mild, severe, and special.
    • +
    • Mild brain traumas are the easiest to get, can be lightly to moderately annoying, and can be cured with mannitol and time.
    • +
    • Severe brain traumas are much rarer and require extensive brain damage before you have a chance to get them; they are usually very debilitating. Unlike mild traumas, they require surgery to cure. A new surgery procedure has been added for this, the aptly named Brain Surgery. It can also heal minor traumas.
    • +
    • Special brain traumas are rarely gained in place of Severe traumas: they are either complex or beneficial. However, they are also even easier to cure than mild traumas, which means that keeping these will usually mean keeping a mild trauma along with it.
    • +
    • Mobs can only naturally have one mild trauma and one severe or special trauma.
    • +
    • Brain damage will now kill and ruin the brain if it goes above 200. If it somehow goes above 400, the brain will melt and be destroyed completely.
    • +
    • Many brain-damaging effects have been given a damage cap, making them non-lethal.
    • +
    • The Unintelligible mutation has been removed and made into a brain trauma.
    • +
    • Brain damage no longer makes using machines a living hell.
    • +
    • Abductors give minor traumas to people they experiment on.
    • +
    +

    coiax updated:

    +
      +
    • The drone dispenser on Metastation has been moved to the maintenance by Robotics.
    • +
    + +

    05 December 2017

    +

    Cyberboss updated:

    +
      +
    • Reduced the volume of showers
    • +
    +

    Dax Dupont updated:

    +
      +
    • Nanotrasen is happy to announce the pinnacle in plasma research! The Disco Inferno shuttle design is the result of decades of plasma research. Burn, baby, burn!
    • +
    +

    MrPerson & ninjanomnom updated:

    +
      +
    • Completely changed how keyboard input is read.
    • +
    • Holding two directions at the same time will now move you diagonally. This works with the arrow keys, wasd, and the numpad.
    • +
    • Moving diagonally takes twice as long as moving a cardinal direction.
    • +
    • You can use control to turn using wasd and the numpad instead of just the arrow keys.
    • +
    • Some old non-hotkey mode behaviors, especially in relation to chatbox interaction, can't be kept with the new system. Of key note: You can't type while walking. This is due to limitations of byond and the work necessary to overcome it is better done as another overhaul allowing custom controls.
    • +
    +

    Robustin updated:

    +
      +
    • Reverted changes in 3d sound system that tripled the distance that sound would carry.
    • +
    +

    SpaceManiac updated:

    +
      +
    • Energy values are now measured in joules. What was previously 1 unit is now 1 kJ.
    • +
    • Syndicate uplink implants now work again.
    • +
    +

    Xhuis updated:

    +
      +
    • Stethoscopes now inform the user if the target can be defibrillated; the user will hear a "faint, fluttery pulse."
    • +
    +

    coiax updated:

    +
      +
    • Quiet areas of libraries on station have now been equipped with a vending machine containing suitable recreational activities.
    • +
    + +

    04 December 2017

    +

    AnturK updated:

    +
      +
    • You can now record and replay holopad messages using holodisks.
    • +
    • Holodisks are printable in autolathes.
    • +
    +

    Xhuis updated:

    +
      +
    • You now need fuel in your welder to repair mechs.
    • +
    + +

    03 December 2017

    +

    ExcessiveUseOfCobblestone updated:

    +
      +
    • You can now lay (buckle!) yourself to a bed to avoid being burnt to a crisp during "the floor is lava" event.
    • +
    +

    Robustin updated:

    +
      +
    • Igniting plasma statues no longer ignores ignition temperature and only creates as much plasma as was used in its creation.
    • +
    +

    Xhuis updated:

    +
      +
    • Light fixtures now turn an ominous, dim red color when they lose power, and draw from an internal power cell to maintain it until either the cell dies (usually after 10 minutes) or power is restored.
    • +
    • You can override emergency light functionality from an APC. You can also click on individual lights as a cyborg or AI to override them individually. Traitor AIs also have a new ability that disables emergency lights across the entire station.
    • +
    +

    zennerx updated:

    +
      +
    • fixed some typos in the weapon firing mechanism description
    • +
    + +

    02 December 2017

    +

    BeeSting12 updated:

    +
      +
    • Occupand ---> Occupant on opened cryogenic pods.
    • +
    • Cyrogenic ---> Cryogenic on opened cryogenic pods.
    • +
    +

    CosmicScientist updated:

    +
      +
    • You can make plushies kiss one another!
    • +
    +

    Frozenguy5 updated:

    +
      +
    • The Particle Accelerator's wires can no longer be EMP'd
    • +
    +

    Naksu updated:

    +
      +
    • Cleans up some loc assignments
    • +
    +

    Robustin updated:

    +
      +
    • Damage examinations now include a "moderate" classification. Before minor was <30 and severe was anything 30 or above. Now minor is <25, moderate is 25 to <50, and severe is 50+.
    • +
    • Clockwork magicks will now prevent Bags of Holding from being combined on Reebe.
    • +
    • Flashes will now burn out AFTER flashing when they fail instead of being a ticking time bomb that waits to screw you over on your next attempt.
    • +
    +

    SpaceManiac updated:

    +
      +
    • The R&D Console has been given a much prettier interface.
    • +
    • Research scanner goggles now show materials and technology prospects in a nicer way.
    • +
    +

    uraniummeltdown updated:

    +
      +
    • Construct shells have a new animated sprite
    • +
    + +

    30 November 2017

    +

    ninjanomnom updated:

    +
      +
    • Reduced the max volume of sm by 1/5th and made the upper bounds only play mid delamination.
    • +
    +

    psykzz updated:

    +
      +
    • Fixing the broken turbine computer
    • +
    + +

    29 November 2017

    +

    MrStonedOne updated:

    +
      +
    • The sloth no longer suspiciously moves fast when gliding between tiles.
    • +
    • The sloth's movespeed when inhabited by a player has been lowered from once every 1/5 of a second to once every second.
    • +
    +

    SpaceManiac updated:

    +
      +
    • The techweb node for mech LMGs no longer claims to be for mech tasers.
    • +
    + +

    28 November 2017

    +

    ACCount updated:

    +
      +
    • "Machine prototype" is removed from the game.
    • +
    • Mass-spectrometers are removed. Would anyone notice if not for this changelog entry?
    • +
    +

    Cruix updated:

    +
      +
    • AI and observer diagnostic huds will now show the astar path of all bots, and Pai bots will be given a visible path to follow when called by the AI.
    • +
    +

    JJRcop updated:

    +
      +
    • Fixed the Make space ninja verb.
    • +
    +

    Naksu updated:

    +
      +
    • rejiggered botcode a little bit
    • +
    +

    SpaceManiac updated:

    +
      +
    • Admin-added "download research" objectives are now consistent with automatic ones.
    • +
    +

    improvedname updated:

    +
      +
    • toolbelts can now carry geiger counters
    • +
    +

    uraniummeltdown updated:

    +
      +
    • You can make many different types of office and comfy chairs with metal
    • +
    • Stack menus use /datum/browser
    • +
    + +

    27 November 2017

    +

    ACCount updated:

    +
      +
    • New integrated circuit components: list constructors/deconstructors. Useful for building lists and taking them apart.
    • +
    • Fixed multiple bugs in integrated circuits UIs, improved overall usability.
    • +
    +

    More Robust Than You updated:

    +
      +
    • Fixed cult leaders being de-culted upon election if they had a mindshield implant
    • +
    +

    Naksu updated:

    +
      +
    • Hopefully fixed mesons granting the ability to hear people through walls.
    • +
    +

    Okand37 updated:

    +
      +
    • Re-organized Delta's departmental protolathes for all departments.
    • +
    • Re-organized Delta's ORM placement by connecting it to the mining office, which now has a desk for over handing materials to the outside.
    • +
    • Added a second Nanomed to Deltastation's medical bay.
    • +
    • Nanotrasen has decided to add proper caution signs to most docking ports on Deltastation, warning individuals to be cautious around these areas.
    • +
    • Two health sensors are now placed in Deltastation's robotics area for medibots.
    • +
    • Atmospheric Technicians at Deltastation can now open up their gas storage in the supermatter power area as intended.
    • +
    +

    WJohnston updated:

    +
      +
    • Fixed a case where items would sometimes be placed underneath racks.
    • +
    +

    XDTM updated:

    +
      +
    • Viruses' healing symptoms have been reworked!
    • +
    • All existing healing symptoms have been removed in favour of new ones.
    • +
    • Weight Even and Weight Gain have been removed, so hunger can be used for balancing in symptoms.
    • +
    • Starlight Condensation heals toxin damage if you're in space using starlight as a catalyst. Being up to two tiles away also works, as long as you can still see it, but slower.
    • +
    • Toxolysis (level 7) rapidly cleanses all chemicals from the body, with no exception.
    • +
    • Cellular Molding heals brute damage depending on your body temperature: the higher the temperature, the faster the healing. Requires above-average temperature to activate, and the speed heavily increases while on fire.
    • +
    • Regenerative Coma (level 8) causes the virus to send you into a deep coma when you are heavily damaged (>70 brute+burn damage). While you are unconscious, either from the virus or from other sources, the virus will heal both brute and burn damage fairly quickly. Sleeping also works, but at reduced speed.
    • +
    • Tissue Hydration heals burn damage if you are wet (negative fire stacks) or if you have water in your bloodstream.
    • +
    • Plasma Fixation (level 8) stabilizes temperature and heals burns while plasma is in your body or while standing in a plasma cloud. Does not protect from the poisoning effects of plasma.
    • +
    • Radioactive Resonance gives a mild constant brute and burn healing while irradiated. The healing becomes more intense if you reach higher levels of radiation, but is still less than the alternatives.
    • +
    • Metabolic Boost (level 7) doubles the rate at which you process chemicals, good and bad, but also increases hunger tenfold.
    • +
    +

    kevinz000 updated:

    +
      +
    • Cryo cells can now be properly rotated with a wrench.
    • +
    +

    ninjanomnom updated:

    +
      +
    • You can now make a new tasty traditional treat: butterdogs. Watch out, they're slippery.
    • +
    + +

    25 November 2017

    +

    CosmicScientist updated:

    +
      +
    • bolas are back in tablecrafting!
    • +
    +

    Dorsisdwarf updated:

    +
      +
    • Catpeople are now distracted instead of debilitated
    • +
    • Normal cats now go for laser pointers
    • +
    +

    SpaceManiac updated:

    +
      +
    • You can no longer buckle people to roller beds from inside of a locker.
    • +
    +

    YPOQ updated:

    +
      +
    • AIs and cyborgs can interact with unscrewed airlocks and APCs.
    • +
    +

    ninjanomnom updated:

    +
      +
    • Fixes thermite burning hotter than the boiling point of stone
    • +
    +

    zennerx updated:

    +
      +
    • Zombies don't reanimate with no head!
    • +
    + +

    24 November 2017

    +

    ACCount updated:

    +
      +
    • Removed "console screen" stock part. Just use glass sheets instead.
    • +
    +

    More Robust Than You updated:

    +
      +
    • Spessmen are now smart enough to realize you don't need to turn around to pull cigarette butts
    • +
    +

    SpaceManiac updated:

    +
      +
    • Fix water misters being inappropriately glued to hands in some cases.
    • +
    • Some misplaced decals in the Hotel brig have been corrected.
    • +
    +

    ninjanomnom updated:

    +
      +
    • Custom shuttle dockers can no longer place docking regions inside other custom docker regions.
    • +
    + +

    23 November 2017

    +

    GupGup updated:

    +
      +
    • Fixes hostile mobs attacking surrounding tiles when trying to attack someone
    • +
    +

    MrStonedOne and Jordie updated:

    +
      +
    • As a late note, serverops be advise that mysql is no longer supported. existing mysql databases will need to be converted to mariadb
    • +
    +

    Robustin updated:

    +
      +
    • RND consoles will no longer display options for machines or disks that are not connected/inserted.
    • +
    +

    ShizCalev updated:

    +
      +
    • Aliens in soft-crit will now use the correct sprite.
    • +
    +

    XDTM updated:

    +
      +
    • Added two new symptoms: one allows viruses to still work while dead, and allows infection of undead species, and one allows infection of inorganic species (such as plasmapeople or golems).
    • +
    + +

    22 November 2017

    +

    ACCount updated:

    +
      +
    • Old integrated circuit save file format is ditched in favor of JSON. Readability, both of save files and save code, is improved greatly.
    • +
    • Integrated circuit panels now open with screwdriver instead of crowbar, to match every single other thing on this server.
    • +
    • Integrated circuit printer now stores up to 25 metal sheets.
    • +
    • Fixed integrated circuit rechargers not recharging guns properly and not updating icons.
    • +
    • Fixed multiple bugs in integrated circuits UIs, improved overall usability.
    • +
    +

    Anonmare updated:

    +
      +
    • Laserpoitners now incapcitate catpeople
    • +
    +

    AutomaticFrenzy updated:

    +
      +
    • cell chargers weren't animating properly
    • +
    • disable_warning wasn't getting checked and the chat was being spammed
    • +
    +

    Code by Pyko, Ported by Frozenguy5 updated:

    +
      +
    • Rat Kebabs and Double Rat Kebabs have been added!
    • +
    +

    Cyberboss updated:

    +
      +
    • Server tools API changed to version 3.2.0.1
    • +
    • "ahelp" chat command can now accept a ticket number as opposed to a ckey
    • +
    +

    DaxDupont updated:

    +
      +
    • CentCom has issued a firmware updated for the operating computers. It is no longer needed to manually refresh the procedure and patient status.
    • +
    • Proximity sensors no longer beep when unarmed.
    • +
    • Plant trays will now properly process fluorine and adjust toxins and water contents.
    • +
    +

    Francinum updated:

    +
      +
    • The shuttle build plate is now better sized for all stations.
    • +
    +

    Iamgoofball updated:

    +
      +
    • fixes grammar on logic gate descriptions
    • +
    • fixes grammar on list circuits
    • +
    • fixes grammar on trig circuits
    • +
    • fixed grammar on output circuits
    • +
    +

    JJRcop updated:

    +
      +
    • Fixes changeling eggs not putting the changeling in control if the brainslug is destroyed before hatching.
    • +
    • The silicon airlock menu looks a little more like it used to.
    • +
    +

    Kor updated:

    +
      +
    • Blobbernauts will no longer spawn if a player is not selected to control it, preventing AI blobbernauts from running off the blob and to their deaths.
    • +
    • Following complaints that cargo has been selling all the materials they receive rather than distributing them, mineral exporting has been removed.
    • +
    +

    MMMiracles updated:

    +
      +
    • Power regen on the regular tesla relay has been reduced to 50, from 150.
    • +
    +

    Naksu updated:

    +
      +
    • Sped up saycode to remove free lag from highpop
    • +
    • Using a chameleon projector will now dismount you from any vehicles you are riding, in order to prevent wacky space glitches and being sent to a realm outside space and time.
    • +
    +

    Shadowlight213 updated:

    +
      +
    • Added round id to the status world topic
    • +
    +

    ShizCalev updated:

    +
      +
    • Chameleon goggles will no longer go invisible when selecting Optical Tray scanners.
    • +
    • Engineering and Atmos scanner goggles will now have correctly colored inhand sprites.
    • +
    • The computers on all maps have have been updated for the latest directional sprite changes. Please report any computers facing in strange directions to your nearest mapper.
    • +
    • MetaStation - The consoles in medbay have had their directions corrected.
    • +
    • The Nanotrasen logo on modular computers has been fixed, rejoice!
    • +
    • PubbyStation - Unpowered air injectors in various locations have been fixed.
    • +
    • MetaStation - Air injector leading out of the incinerator has been fixed
    • +
    • MetaStation - Corrected a couple maintenance airlocks being powered by the wrong areas.
    • +
    • Computers will no longer rotate incorrectly when being deconstructed.
    • +
    • You can now rotate computer frames during construction.
    • +
    • Chairs, PA parts, infrared emitters, and doppler arrays will now rotate clockwise.
    • +
    • Throwing drinking glasses and cartons will now consistently cause them to break!
    • +
    • Humans missing legs or are legcuffed will no longer move slower in areas without gravity.
    • +
    • The structures external to stations are now properly lit. Make sure you bring a flashlight.
    • +
    • Computers will no longer delete themselves when being built, whoops!
    • +
    • Space cats will no longer have a smashed helmet when they lay down.
    • +
    +

    Skylar Lineman, your local R&D moonlighter updated:

    +
      +
    • Research has been completely overhauled into the techweb system! No more levels, the station now unlocks research "nodes" with research points passively generated when there is atleast one research server properly cooled, powered, and online.
    • +
    • R&D lab has been replaced by the departmental lathe system on the three major maps. Each department gets a lathe and possibly a circuit imprinter that only have designs assigned by that department.
    • +
    • The ore redemption machine has been moved into cargo bay on maps with decentralized research to prevent the hallways from becoming a free for all. Honk!
    • +
    • You shouldn't expect balance as this is the initial merge. Please put all feedback and concerns on the forum so we can revise the system over the days, weeks, and months, to make this enjoyable for everyone. Heavily wanted are ideas of how to add more ways of generating points.
    • +
    • You can get techweb points by setting off bombs with an active science doppler array listening. The bombs have to have a theoretical radius far above maxcap to make a difference. You can only go up, not down, in radius, so you can't get 6 times the points with 6 TTVs. The algorithm is exponentially/logarithmically scaled to prevent "world destroyer" bombs from instantly finishing research.
    • +
    +

    SpaceManiac updated:

    +
      +
    • HUDs from mechs and helmets no longer conflict with HUD glasses and no longer inappropriately remove implanted HUDs.
    • +
    • Chasm code has been refactored to be more sane.
    • +
    • Building lattices over chasms no longer sometimes deletes the chasm.
    • +
    • Ladders have been refactored and should be far less buggy.
    • +
    • Jacob's ladder actually works again.
    • +
    • Pizza box stacking works again.
    • +
    • Fix some permanent-on and permanent-off bugs caused by the HUD stacking change.
    • +
    +

    WJohnston updated:

    +
      +
    • A bunch of new turf decals for mappers to play with, coming in yellow, white, and red varieties!
    • +
    • Green banded default airlocks now have extended click area like all other airlocks.
    • +
    +

    Y0SH1 M4S73R updated:

    +
      +
    • The R&D Server's name is now improper.
    • +
    • The R&D Server now has an explanation of what it does.
    • +
    +

    arsserpentarium updated:

    +
      +
    • now lists should work properly
    • +
    +

    duncathan updated:

    +
      +
    • The RPD has a shiny new UI!
    • +
    • The RPD can now paint pipes as it lays them, for quicker piping projects.
    • +
    • Atmos scrubbers (vent and portable) can now filter any and all gases.
    • +
    +

    ike709 updated:

    +
      +
    • Added new vent and scrubber sprites by Partheo.
    • +
    • Fixed some computers facing the wrong direction.
    • +
    +

    jammer312 updated:

    +
      +
    • fixed conjuration spells forgetting about conjured items
    • +
    +

    kevinz000 updated:

    +
      +
    • purple bartender suit and apron added to clothesmates!
    • +
    • long hair 3 added, check it out. both have sprites from okand!
    • +
    +

    nicbn updated:

    +
      +
    • Now rolling beds and office chairs have a sound!
    • +
    +

    oranges updated:

    +
      +
    • Removed the shocker circuit
    • +
    +

    psykzz updated:

    +
      +
    • Grilles have new damaged and default sprites
    • +
    • Added TGUI for Turbine computer
    • +
    +

    tserpas1289 updated:

    +
      +
    • Any suit that could hold emergency oxygen tanks can now also hold plasma man internals
    • +
    • Hydroponics winter coats now can hold emergency oxygen tanks just like the other winter coats.
    • +
    • Plasma men jumpsuits can now hold accessories like pocket protectors and medals.
    • +
    +

    zennerx updated:

    +
      +
    • fixed a bug that made you try and scream while unconscious due to a fire
    • +
    • Skateboard crashes now give slight brain damage!
    • +
    • Using a helmet prevents brain damage from the skateboard!
    • +
    + +

    15 November 2017

    +

    Fury updated:

    +
      +
    • Added new sprites for the Heirophant Relay (clock cultist telecomms equipment).
    • +
    +

    Naksu updated:

    +
      +
    • Removed fire-related free lag. change: fire alarms and cameras no longer work after being ripped off a wall by a singulo
    • +
    • Minor speedups to movement processing. change: Fat mobs no longer gain temperature by running.
    • +
    +

    Robustin updated:

    +
      +
    • Cult population scaling no longer operates on arbitrary breakpoints. Each additional player between the between the breakpoints will add to the "chance" that an additional cultist will spawn.
    • +
    • On average you will see less roundstart cultists in lowpop and more roundstart cultists in highpop.
    • +
    • Damage examinations now include a "moderate" classification. Before minor was <30 and severe was anything 30 or above. Now minor is <25, moderate is 25 to <50, and severe is 50+.
    • +
    • The tesla will now move toward power beacons at a significantly slower rate.
    • +
    +

    SpaceManiac updated:

    +
      +
    • The post-round station integrity report is now functional again.
    • +
    +

    ninjanomnom updated:

    +
      +
    • Gas overlays no longer block clicks, on 512
    • +
    + +

    14 November 2017

    +

    ike709 updated:

    +
      +
    • Added directional computer sprites. Maps haven't been changed yet.
    • +
    +

    psykzz updated:

    +
      +
    • AI Airlock UI to use TGUI
    • +
    • Allow AI to swap between electrified door states without having to un-electrify first.
    • +
    +

    selea/arsserpentarium updated:

    +
      +
    • Integrated circuits have been added to Research!
    • +
    • You can use these to create devices with very complex behaviors.
    • +
    • Research the Integrated circuits printer to get started.
    • +
    + +

    13 November 2017

    +

    Cobby updated:

    +
      +
    • The Xray now only hits the first mob it comes into contact with instead of being outright removed from the game.
    • +
    +

    Floyd / Qustinnus updated:

    +
      +
    • Reebe now has ambience sounds
    • +
    +

    Floyd / Qustinnus: updated:

    +
      +
    • Adds a few sound_loop datums to machinery.
    • +
    +

    Frozenguy5 updated:

    +
      +
    • Broken cable cuffs no longer has an invisible sprite.
    • +
    +

    PKPenguin321 updated:

    +
      +
    • Welders must now be screwdrivered open to reveal their fuel tank.
    • +
    • You can empty welders into open containers (like beakers or glasses) when they're screwdrivered open.
    • +
    • You can now insert any chemical into a welder, but all most will do is clog the fuel. Welding fuel will refuel it as usual. Plasma in welders tends to explode.
    • +
    +

    Qbopper and JJRcop updated:

    +
      +
    • The default internet sound volume was changed from 100 to 25. Stop complaining in OOC about your ears!
    • +
    +

    SpaceManiac updated:

    +
      +
    • Posters may no longer be placed on diagonal wall corners.
    • +
    +

    WJohnston updated:

    +
      +
    • Removes stationary docking ports for syndicate infiltrator ships on all maps. Use the docking navigator computer instead! This gives the white ship and syndicate infiltrator more room to navigate and place custom locations that are otherwise occupied by fixed shuttle landing zones that are rarely used.
    • +
    +

    Xhuis updated:

    +
      +
    • Deep fryers now have sound.
    • +
    • Deep fryers now use cooking oil, a specialized reagent that becomes highly damaging at high temperatures. You can get it from grinding soybeans and meat.
    • +
    • Deep fryers now become more efficient with higher-level micro lasers, using less oil and frying faster.
    • +
    • Deep fryers now slowly use oil as it fries objects, instead of all at once.
    • +
    • You can now correctly refill deep fryers with syringes and pills.
    • +
    +

    nicn updated:

    +
      +
    • Damage from low pressure has been doubled.
    • +
    +

    ninjanomnom updated:

    +
      +
    • You can now select a nearby area to expand when using a blueprint instead of making a new area.
    • +
    • New shuttle areas can be created using blueprints. This is currently not useful but will be used later for shuttle construction.
    • +
    • Blueprints can modify existing areas on station.
    • +
    • Blueprint functionality has been added to the debug tab as a verb.
    • +
    + +

    12 November 2017

    +

    Cyberboss updated:

    +
      +
    • Clockwork slabs no longer refer to components
    • +
    + +

    11 November 2017

    +

    DaxDupont updated:

    +
      +
    • Medbots can inject from one tile away again.
    • +
    +

    SpaceManiac updated:

    +
      +
    • The detective and heads of staff are no longer attacked by portable turrets.
    • +
    +

    deathride58 updated:

    +
      +
    • You can no longer delete girders, lattices, or catwalks with the RPD
    • +
    • Fixes runtimes that occur when clicking girders, lattices, catwalks, or disposal pipes with the RPD in paint mode
    • +
    +

    ninjanomnom updated:

    +
      +
    • Fixes ruin cable spawning and probably some other bugs
    • +
    + +

    10 November 2017

    +

    Anonmare updated:

    +
      +
    • Adds an organ storage bag to the syndicate medborg.
    • +
    +

    AnturK updated:

    +
      +
    • Dying in shapeshifted form reverts you to the original one. (You're still dead)
    • +
    +

    Floyd / Qustinnus updated:

    +
      +
    • Redtexting as a traitor now plays a depressing tune to you
    • +
    +

    Floyd / Qustinnus (And all the sounds by Kayozz11 from Yogstation) updated:

    +
      +
    • Adds about 30 new ambience sounds
    • +
    • added new defines for ambience lists.
    • +
    +

    Iamgoofball updated:

    +
      +
    • Cooldown on the Ripley's mining drills has been halved.
    • +
    • The frequency of the Ripley's ore pulse has been doubled.
    • +
    +

    Jalleo updated:

    +
      +
    • Removed a variable to state which RCD's can deconstruct reinforced walls
    • +
    • Made combat (ERT ones) and admin RCDs able to deconstruct r walls alongside borg ones
    • +
    +

    Kor updated:

    +
      +
    • Cult mode will once again print out names at round end.
    • +
    +

    Mark9013100 updated:

    +
      +
    • Deltastation now has a Whiteship.
    • +
    • Charcoal bottles have been renamed, and have been given a more informative description.
    • +
    +

    Mercenaryblue updated:

    +
      +
    • spellchecked the hotel staff.
    • +
    • Added frog masks. Reeeeeeeeee!!
    • +
    +

    More Robust Than You updated:

    +
      +
    • Blobbernauts and spores are no longer killed by blob victory
    • +
    • New blob overminds off the station Z level are moved to the station
    • +
    • You can now use banhammers as a weapon
    • +
    • Monkeys can no longer transmit diseases through hardsuits
    • +
    • Xenobio blobbernauts can no longer walk on blob tiles
    • +
    +

    Naksu updated:

    +
      +
    • Added deterministic output slots to the slime processor
    • +
    • Fixed some interactions with ghosts and items
    • +
    • Nonhumans such as monkeys can now be scanned for chemicals with the health analyzer.
    • +
    +

    Okand37 (DeltaStation Updates) updated:

    +
      +
    • Tweaked Atmospherics
    • +
    • Fixed the Incinerator air injector
    • +
    • Tweaked Engineering
    • +
    • Added logs to the Chaplain's closet for gimmicks (bonfires)
    • +
    • Tweaked Security
    • +
    • Fixed medical morgue maintenance not providing radiation shielding and exterior chemistry windoor
    • +
    • Bar now has a door from the backroom to the theatre stage
    • +
    • Tweaked Locker Room/Dormitories
    • +
    +

    ShizCalev updated:

    +
      +
    • You can now -actually- load pie cannons.
    • +
    • The captain's winter coat can now hold a flashlight.
    • +
    • The captain's and security winter coats can now hold internals tanks.
    • +
    • All winter coats can now hold toys, lighters, and cigarettes.
    • +
    • The captain's hardsuit can now hold pepperspray.
    • +
    • Updated the Test Map debugging verb to report more issues regarding APCs. DELTASTATION
    • +
    • Reverted Okand37's morgue changes which broke power in the area.
    • +
    • Corrected wrong area on the Southern airlock leading into electrical maintenance. ALL STATIONS
    • +
    • Corrected numerous duplicate APCs in areas which led to power issues.
    • +
    +

    SpaceManiac updated:

    +
      +
    • Ghosts can no longer create sparks from the hand teleporter's portals.
    • +
    • Digging on Lavaland no longer shows two progress bars.
    • +
    • The holodeck now has an "Offline" option.
    • +
    • Injury and crit overlays are now scaled properly for zoomed-out views.
    • +
    • Already-downloaded software is now hidden from the NTNet software downloader.
    • +
    • The crafting, language, and building buttons are now positioned correctly in zoomed-out views.
    • +
    • Bluespace shelter walls no longer smooth with non-shelter walls and windows.
    • +
    +

    Swindly updated:

    +
      +
    • Organ storage bags can be used to perform limb augmentation.
    • +
    • You can now cancel a cavity implant during the implanting/removing step by using drapes while holding the appropriate tool in your inactive hand. Cyborgs can cancel the surgery by using drapes alone.
    • +
    • Fixed hot items and fire heating reagents to temperatures higher than their heat source.
    • +
    • Sprays can now be heated with hot items.
    • +
    • The heating of reagents by hot items, fire, and microwaves now scales linearly with the difference between the reagent holder's temperature and the heat source's temperature instead of constantly.
    • +
    • The body temperature of a mob with reagents is affected by the temperature of the mob's reagents.
    • +
    • Reagent containers can now be heated by hot air.
    • +
    +

    Thefastfoodguy updated:

    +
      +
    • Spamming runes / battlecries / etc will no longer trigger spam prevention
    • +
    +

    WJohnston updated:

    +
      +
    • Ancient station lighting fixed on beta side (medical and atmos remains)
    • +
    +

    XDTM updated:

    +
      +
    • Ghosts now have a Toggle Health Scan verb, which allows them to health scan mobs they click on.
    • +
    +

    Xhuis updated:

    +
      +
    • Ratvar and Nar-Sie plushes now have a unique interaction.
    • +
    • Clockwork marauders are now on harm intent.
    • +
    • The Clockwork Marauder scripture now takes five seconds longer to invoke per marauder summoned in the last 20 seconds, capping at 30 extra seconds.
    • +
    • Clockwork marauders no longer gain a health bonus when war is declared.
    • +
    • Moved the BoxStation deep fryers up one tile.
    • +
    • Microwaves have new sounds!
    • +
    +

    YPOQ updated:

    +
      +
    • EMPs can pulse multiple wires
    • +
    +

    as334 updated:

    +
      +
    • Pluoxium can now be formed by irradiating tiles with CO2 in the air.
    • +
    • Rad collectors now steadily form Tritium at a slow pace.
    • +
    • Nerfs fusion by making it slower, and produce radioactivity.
    • +
    • Noblium formation now requires significantly more energy input.
    • +
    • Tanks now melt if their temperature is above 1 Million Kelvin.
    • +
    +

    deathride58 updated:

    +
      +
    • Directional character icon previews now function properly. Other things relying on getflaticon probably work with directional icons again, as well.
    • +
    +

    nicbn updated:

    +
      +
    • Canister sprites for the new gases
    • +
    +

    ninjanomnom updated:

    +
      +
    • Shuttle parallax has been fixed once more
    • +
    • You can no longer set up the auxiliary base's shuttle beacon overlapping with the edge of the map
    • +
    +

    uraniummeltdown updated:

    +
      +
    • Replica fabricatoring airlocks and windoors keeps the old name
    • +
    • Narsie and Ratvar converting airlocks and windoors keeps the old name
    • +
    + +

    02 November 2017

    +

    ACCount updated:

    +
      +
    • "Tail removal" and "tail attachment" surgeries are merged with "organ manipulation".
    • +
    • New sprites for reflectors. They finally look like something.
    • +
    • You can lock reflector's rotation by using a screwdriver. Use the screwdriver again to unlock it.
    • +
    • Reflector examine now shows the current angle and rotation lock status.
    • +
    • You can now use a welder to repair damaged reflectors.
    • +
    • Multiple reflector bugs are fixed.
    • +
    +

    Improvedname updated:

    +
      +
    • Removes statues from gold slime pool
    • +
    +

    Mercenaryblue updated:

    +
      +
    • Updated Clown Box sprite to match the others.
    • +
    +

    More Robust Than You updated:

    +
      +
    • ONLY ADMINS CAN ACTIVATE THE ARK NOW
    • +
    • The Ark's time measurements are now a bit more readable
    • +
    +

    MrStonedOne updated:

    +
      +
    • Meteor events will not happen before 25 minutes, the worst versions before 35 and 45 minutes.
    • +
    • Meteor events are now player gated to 15, 20, and 25 players respectively
    • +
    • The more destructive versions of meteor events now have a slightly higher chance of triggering, to offset the decrease in how often it is that they will even qualify.
    • +
    • Fixed the changelog generator.
    • +
    +

    Naksu updated:

    +
      +
    • Smartfridges and chem/condimasters now output items in a deterministic 3x3 grid rather than in a huge pile in the middle of the tile.
    • +
    +

    SpaceManiac updated:

    +
      +
    • Admins can once again spawn nuke teams on demand.
    • +
    +

    Xhuis updated:

    +
      +
    • Admins can now create sound emitters (/obj/effect/sound_emitter) that can be customized to play sounds to different people, at different volumes, and at different locations such as by z-level. They're much more versatile for events than the Play Sound commands!
    • +
    • You can now add grenades to plushies! You'll need to cut out the stuffing first.
    • +
    • Clockwork cult tips of the round have been updated to match the rework.
    • +
    • Abscond and Reebe rifts now place servants directly at the Ark instead of below the "base" area.
    • +
    +

    nicbn updated:

    +
      +
    • Brown gas renamed to nitryl.
    • +
    +

    ninjanomnom updated:

    +
      +
    • Fixes decals not rotating correctly with the turf.
    • +
    • Fixes a runtime causing some turfs to be left behind by removed shuttles.
    • +
    • Shuttles should be roughly 40-50% smoother.
    • +
    • Fixes the cargo shuttle occasionally breaking if a mob got on at exactly the right time.
    • +
    + +

    30 October 2017

    +

    PKPenguin321 updated:

    +
      +
    • You can now use beakers/cups/etc that have welding fuel in them on welders to refuel them.
    • +
    +

    bgobandit updated:

    +
      +
    • Due to cuts to Nanotrasen's Occupational Safety and Health Administration (NO-SHA) budget, station fixtures no longer undergo as much safety testing. (Translation for rank and file staff: More objects on the station will hurt you.)
    • +
    + +

    29 October 2017

    +

    Armhulen updated:

    +
      +
    • Frost Spiders now use Frost OIL!
    • +
    +

    Mercenaryblue updated:

    +
      +
    • Skeletons can now have their own spectral instruments
    • +
    • \[Dooting Intensifies\]
    • +
    • the variable "too_spooky" defines if it will spawn new instruments, by default TRUE.
    • +
    +

    Naksu updated:

    +
      +
    • Removed meteor-related free lag
    • +
    • Cleaned up dangling mob references from alerts
    • +
    +

    Xhuis updated:

    +
      +
    • You can no longer become an enhanced clockwork golem with mutation toxin.
    • +
    • Normal clockwork golems now have 20% armor, down from 40%.
    • +
    +

    as334 updated:

    +
      +
    • This changelog has been updated and so read it again if you are interested in doing assmos.
    • +
    • Atmospherics has been massively expanded including new gases.
    • +
    • These new gases include Brown Gas, Pluoxium, Stimulum, Hyper-Noblium and Tritium.
    • +
    • Brown Gas is acidic to breath, but mildly stimulation.
    • +
    • Stimulum is more stimulating and much safer.
    • +
    • Pluoxium is a non-reactive form of oxygen that delivers more oxygen into the bloodstream.
    • +
    • Hyper-Noblium is an extremely noble gas, and stops gases from reacting.
    • +
    • Tritium is radioactive and flammable.
    • +
    • New reactions have also been added to create these gases.
    • +
    • Tritium formation: Heat large amounts of oxygen with plasma. Make sure you have a filter ready and setup!
    • +
    • Fusion has been reintroduced. Plasma will fuse when heated to a high thermal energy with Tritium as a catalyst. Make sure to manage the waste products.
    • +
    • Brown Gas formation: Heat Oxygen and Nitrogen.
    • +
    • BZ fixation: Heat Tritium and Plasma.
    • +
    • Stimulum formation: Heated Tritium, Plasma, BZ and Brown Gas.
    • +
    • Hyper-Noblium condensation: Needs Nitrogen and Tritium at a super high heat. Cools rapidly.
    • +
    • Pluoxium is unable to be formed.
    • +
    • Freon has been removed. Use cold nitrogen for your SME problems now.
    • +
    • Water vapor now freezes the tile it is on when it is cooled heavily.
    • +
    +

    naltronix updated:

    +
      +
    • fixes that table that wasnt accessible in Metastation
    • +
    + +

    28 October 2017

    +

    Mark9013100 updated:

    +
      +
    • The Medical Cloning manual has been updated.
    • +
    + +

    27 October 2017

    +

    Anonmare updated:

    +
      +
    • Adds new grindables
    • +
    +

    JamieH updated:

    +
      +
    • Buildmode map generators will now show you a preview of the area you're changing
    • +
    • Buildmode map generators will now ask before nuking the map
    • +
    • Buildmode map generator corners can now only be set by left clicking
    • +
    +

    Kor updated:

    +
      +
    • Cloth golems will be available as a roundstart race during Halloween.
    • +
    +

    MrStonedOne updated:

    +
      +
    • Created a system to profile code on a line by line basis and return detailed info about how much time was spent (in milliseconds) on each line(s).
    • +
    +

    Xhuis updated:

    +
      +
    • Servants can no longer teleport into the gravity generator, EVA, or telecomms.
    • +
    +

    ninjanomnom updated:

    +
      +
    • Hardsuit helmets work like geiger counters for the user.
    • +
    • Radiation should perform a little better in places.
    • +
    • Various radiation symptom thresholds have been tweaked.
    • +
    • Contamination strengths at different ranges have been tweaked.
    • +
    • Contaminated objects have less range for their radiation.
    • +
    • Hitting something with a contaminated object reduces its strength faster.
    • +
    • Contaminated objects decay faster.
    • +
    • Both radiation healing medicines have been buffed a bit.
    • +
    • Passive radiation loss for mobs is nerfed.
    • +
    • There is a soft cap for mob radiation now.
    • +
    • Projectiles, ammo casings, and implants are disallowed from becoming contaminated.
    • +
    • Suit storage units can completely cleanse contamination from stored objects
    • +
    • The first time an object is contaminated enough to spread more contamination admins will be warned. This is also added to stat tracking.
    • +
    • Thermite works on floors and can be ignited by sufficiently hot fires now
    • +
    • Thermite has been made into a component
    • +
    • Thermite no longer removes existing overlays on turfs
    • +
    + +

    26 October 2017

    +

    Kor and JJRcop updated:

    +
      +
    • Added vampires. They will be available as a roundstart race during the Halloween holiday event.
    • +
    +

    ShizCalev updated:

    +
      +
    • Reflectors will no longer drop more materials than they took to make when deconstructed.
    • +
    • You will no longer be prompted to reenter your body while being defibbed if you can't actually be revived.
    • +
    • You can no longer teleport past the ticket stands of the Luxury Emergency Shuttle.
    • +
    • Lightgeists can now -actually- be spawned with gold slime cores.
    • +
    • The Staff of Change will now randomly assign a cyborg module when transforming a mob into a cyborg.
    • +
    +

    Xhuis updated:

    +
      +
    • Clockwork marauders now move more slowly below 40% health.
    • +
    • Instead of a 40% chance (or more) chance to block projectiles, clockwork marauders now have three fixed 100% blocks; after using those three, they cannot block anymore without avoiding projectiles for ten seconds. This number increases to four if war is declared.
    • +
    • Projectiles that deal no damage DO reduce marauders' shield health. Use disabler shots to open them up, then use lasers to go for the kill!
    • +
    • Cogscarab shells and marauder armor now appear in the spawners menu.
    • +
    • You can no longer stack infinitely many stargazers on one tile.
    • +
    +

    nicbn updated:

    +
      +
    • Chemical heater and smoke machine resprited.
    • +
    +

    ninjanomnom updated:

    +
      +
    • Portable generators have a sound while active.
    • +
    • The supermatter has a sound that scales with stored energy.
    • +
    +

    ninjanomnom & Wjohn updated:

    +
      +
    • Cable cuffs now inherit the color of the cables used to make them.
    • +
    • Split cable stacks keep their color.
    • +
    • The blue cable color is now a better blue.
    • +
    + +

    25 October 2017

    +

    Cruix updated:

    +
      +
    • Shuttle navigation computers can now place new transit locations over the shuttle's current position.
    • +
    +

    JJRcop updated:

    +
      +
    • The heart of darkness revives you as a shadowperson if you aren't one already.
    • +
    +

    ShizCalev updated:

    +
      +
    • Shades will no longer always hear a heartbeat.
    • +
    • Golem abilities will now be start on cooldown when they are made.
    • +
    + +

    24 October 2017

    +

    Armhulen updated:

    +
      +
    • Wizards may now shapeshift into viper spiders.
    • +
    +

    Improvedname updated:

    +
      +
    • Blacklists holoparasite's from surplus crates
    • +
    +

    Kor updated:

    +
      +
    • Added dullahans, which will be available from the character set up menu during the Halloween event.
    • +
    • Severed heads will no longer appear bald.
    • +
    +

    More Robust Than You updated:

    +
      +
    • Fixes champrojector camera bugs
    • +
    +

    Naksu updated:

    +
      +
    • Grinders will now grind grown items like cocoa pods again
    • +
    • Cameras no longer keep hard references to mobs in their motion tracking list.
    • +
    +

    ShizCalev updated:

    +
      +
    • Creatures made via gold slime cores will now be given the proper name of their master.
    • +
    +

    deathride58 updated:

    +
      +
    • Deltastation's armory now contains reinforced windows surrounding the lethal weaponry. This makes Delta's armory consistent with Box.
    • +
    • There are now decals in places where extra Security lockers can spawn.
    • +
    • Cleaned up semicolons in Meta and Boxstation's .dmms
    • +
    + +

    22 October 2017

    +

    More Robust Than You updated:

    +
      +
    • Blood Brother now properly shows up in player panel
    • +
    +

    Naksu updated:

    +
      +
    • Paper bins no longer let server admins know that pens were eaten.
    • +
    • Removed dangling mob references to last attacker/attacked
    • +
    +

    Robustin updated:

    +
      +
    • Medical biosuits (and hardsuits) now offer heavy, but not complete, radiation resistance.
    • +
    +

    ninjanomnom updated:

    +
      +
    • Contents of silicon mobs are no longer considered for targets of radiation. This blocks them from being contaminated.
    • +
    + +

    21 October 2017

    +

    More Robust Than You updated:

    +
      +
    • Heads of staff will now have cat organs removed at roundstart
    • +
    +

    Robustin updated:

    +
      +
    • Spray tan no longer stuns when ingested.
    • +
    +

    Thunder12345 updated:

    +
      +
    • Sentient cats no longer forget to fall over when they die
    • +
    + +

    20 October 2017

    +

    Kor updated:

    +
      +
    • You can now select your Halloween race, rather than having it assigned randomly via event.
    • +
    +

    Robustin updated:

    +
      +
    • Fixed a bug where detonating maxcaps, especially multiple maxcaps, on Reebe guaranteed that everyone would die and thus the Clock Cult would immediately lose; Reebe maxcap is now 2/5/10.
    • +
    +

    ShizCalev updated:

    +
      +
    • All reflector prisms/mirrors have had their angles corrected.
    • +
    • Remains left over by dusting or soul-stoning a mob are now dissoluble with acid.
    • +
    • Changelings using biodegrade to escape restraints will now leave a pile of goop.
    • +
    • Fixed messages related to changelings using biodegrade not appearing.
    • +
    + +

    19 October 2017

    +

    Kor updated:

    +
      +
    • Blob is now a side antagonist.
    • +
    • Event and admin blobs will now be able to choose their spawn location.
    • +
    • Blob can now win in any mode by gaining enough tiles to reach Critical Mass.
    • +
    • Blobs that have Critical Mass have unlimited points, and a minute after achieving critical mass, they will spread to every tile on station, killing anyone still on board and ending the round.
    • +
    • Using an analyzer on a blob will now reveal its progress towards Critical Mass.
    • +
    • The blob event is now more common.
    • +
    +

    Mercenaryblue updated:

    +
      +
    • You will no longer trip on inactive honkbots.
    • +
    • Sentient Honkbots are no longer forced to speak when somebody trip on them.
    • +
    +

    Naksu updated:

    +
      +
    • Manned turrets stop firing when there's no-one in the turret shooting.
    • +
    • mobs will enter a deep power-saving state when there's not much to do except wander around. change: bees are slightly more passive in general
    • +
    +

    deathride58 updated:

    +
      +
    • You can now press Ctrl+H to stop pulling, or simply H to stop pulling if you're in hotkey mode.
    • +
    +

    ninjanomnom updated:

    +
      +
    • Engineering scanner goggles have a radiation mode now
    • +
    • Objects placed under showers are cleansed of radioactive contamination over a short time.
    • +
    • Showers make sound now.
    • +
    +

    oranges updated:

    +
      +
    • Removed the bluespace pipe
    • +
    + +

    18 October 2017

    +

    DaxDupont updated:

    +
      +
    • Fixes automatic fire on guns.
    • +
    +

    Gun Hog updated:

    +
      +
    • The GPS item now correctly changes its name when the GPS tag is changed.
    • +
    +

    Improvedname updated:

    +
      +
    • Reverts katana's to its orginal size being huge
    • +
    +

    Mercenaryblue updated:

    +
      +
    • it should be far easier to clean out your face from multiple cream pies.
    • +
    +

    More Robust Than You updated:

    +
      +
    • People that are burning slightly less will appear to be burning... slightly less.
    • +
    +

    Robustin updated:

    +
      +
    • The smoke machine now properly generates transparent smoke, transmits chemicals, and displays the proper icons.
    • +
    +

    ShizCalev updated:

    +
      +
    • You can no longer build reinforced floors directly on top of dirt, asteroid sand, ice, or beaches. You'll have to first construct flooring on top of it instead.
    • +
    • Corrected mapping issues introduced with the latest SM engine/radiation update across all relevant maps.
    • +
    • The tools on the Caravan Ambush space ruin have had their speeds corrected.
    • +
    • Slappers will no longer appear as a latex balloon in your hand.
    • +
    • Renault now has a comfy new bed on Metastation!
    • +
    • Engineering cyborgs now have access to geiger counters.
    • +
    +

    Xhuis updated:

    +
      +
    • You can no longer pick up brass chairs.
    • +
    +

    Y0SH1_M4S73R updated:

    +
      +
    • Disabling leg actuators sets the power drain per step to the correct value.
    • +
    +

    duncathan updated:

    +
      +
    • Filters no longer stop passing any gas through if the filtered output is full.
    • +
    +

    ninjanomnom updated:

    +
      +
    • You can vomit blood at high enough radiation.
    • +
    • Radiation knockdown is far far shorter.
    • +
    • Genetics modification is less harmful but still, upgrade your machines.
    • +
    • Pentetic acid is useless for low amounts of radiation but indispensable for high amounts now.
    • +
    • Singularity radiation has been normalized and Pubby engine has been remapped.
    • +
    • No more hair loss spam
    • +
    • Mob rad contamination has been disabled for now. Regular contamination is still a thing.
    • +
    • Fixed turfs not rotating
    • +
    • Fixed stealing structures you shouldn't be moving
    • +
    + +

    17 October 2017

    +

    DaxDupont updated:

    +
      +
    • Fancy boxes(ie: donut boxes) now show the proper content amount in the sprite and no longer go invisible when empty.
    • +
    +

    Mercenaryblue updated:

    +
      +
    • when decapitated, banana-flavored cream no longer hovers where your head used to be.
    • +
    +

    More Robust Than You updated:

    +
      +
    • EI NATH! now causes a flash of light
    • +
    +

    Naksu updated:

    +
      +
    • Pinned notes will now show up on vault, abductor, centcom and large glass airlocks.
    • +
    • Removed a misleading message when handling full stacks of sheets.
    • +
    • Pre-filled glass bottles (uplink, medbay, botany) will now give visual feedback about how much stuff is left inside, and the color of contents will match an empty bottle being filled with the same reagent.
    • +
    • Player-controlled "neutral" mobs such as minebots are now considered valid targets by clock cult's ocular wardens.
    • +
    +

    Xhuis updated:

    +
      +
    • Cogged APCs can now be correctly unlocked with an ID card.
    • +
    +

    duncathan updated:

    +
      +
    • Portable air pumps can output to a maximum of 25 atmospheres.
    • +
    +

    kevinz000 updated:

    +
      +
    • Legacy projectiles have been removed. Instead, all projectiles are now PIXEL PROJECTILES!
    • +
    • Reflectors can now be at any angle you want. Alt click them to set angle!
    • +
    • Pipes can now be layered up to 3 layers.
    • +
    +
    + +GoonStation 13 Development Team +
    + Coders: Stuntwaffle, Showtime, Pantaloons, Nannek, Keelin, Exadv1, hobnob, Justicefries, 0staf, sniperchance, AngriestIBM, BrianOBlivion
    + Spriters: Supernorn, Haruhi, Stuntwaffle, Pantaloons, Rho, SynthOrange, I Said No
    +
    +
    +

    Creative Commons License
    Except where otherwise noted, Goon Station 13 is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 License.
    Rights are currently extended to SomethingAwful Goons only.

    +

    Some icons by Yusuke Kamiyamane. All rights reserved. Licensed under a Creative Commons Attribution 3.0 License.

    +
    + + diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 6a6e5f672c..ab40b78512 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -13457,4 +13457,921 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - bugfix: Thermite no longer removes existing overlays on turfs 2017-10-28: Mark9013100: +<<<<<<< HEAD - tweak: The Medical Cloning manual has been updated. +======= + - tweak: The Medical Cloning manual has been updated. +2017-10-29: + Armhulen: + - rscadd: Frost Spiders now use Frost OIL! + Mercenaryblue: + - rscadd: Skeletons can now have their own spectral instruments + - rscadd: \[Dooting Intensifies\] + - admin: the variable "too_spooky" defines if it will spawn new instruments, by + default TRUE. + Naksu: + - bugfix: Removed meteor-related free lag + - bugfix: Cleaned up dangling mob references from alerts + Xhuis: + - bugfix: You can no longer become an enhanced clockwork golem with mutation toxin. + - balance: Normal clockwork golems now have 20% armor, down from 40%. + as334: + - spellcheck: This changelog has been updated and so read it again if you are interested + in doing assmos. + - rscadd: Atmospherics has been massively expanded including new gases. + - rscadd: These new gases include Brown Gas, Pluoxium, Stimulum, Hyper-Noblium and + Tritium. + - rscadd: Brown Gas is acidic to breath, but mildly stimulation. + - rscadd: Stimulum is more stimulating and much safer. + - rscadd: Pluoxium is a non-reactive form of oxygen that delivers more oxygen into + the bloodstream. + - rscadd: Hyper-Noblium is an extremely noble gas, and stops gases from reacting. + - rscadd: Tritium is radioactive and flammable. + - rscadd: New reactions have also been added to create these gases. + - rscadd: 'Tritium formation: Heat large amounts of oxygen with plasma. Make sure + you have a filter ready and setup!' + - rscadd: Fusion has been reintroduced. Plasma will fuse when heated to a high thermal + energy with Tritium as a catalyst. Make sure to manage the waste products. + - rscadd: 'Brown Gas formation: Heat Oxygen and Nitrogen.' + - rscadd: 'BZ fixation: Heat Tritium and Plasma.' + - rscadd: 'Stimulum formation: Heated Tritium, Plasma, BZ and Brown Gas.' + - rscadd: 'Hyper-Noblium condensation: Needs Nitrogen and Tritium at a super high + heat. Cools rapidly.' + - rscadd: Pluoxium is unable to be formed. + - rscdel: Freon has been removed. Use cold nitrogen for your SME problems now. + - rscadd: Water vapor now freezes the tile it is on when it is cooled heavily. + naltronix: + - bugfix: fixes that table that wasnt accessible in Metastation +2017-10-30: + PKPenguin321: + - tweak: You can now use beakers/cups/etc that have welding fuel in them on welders + to refuel them. + bgobandit: + - tweak: 'Due to cuts to Nanotrasen''s Occupational Safety and Health Administration + (NO-SHA) budget, station fixtures no longer undergo as much safety testing. + (Translation for rank and file staff: More objects on the station will hurt + you.)' +2017-11-02: + ACCount: + - tweak: '"Tail removal" and "tail attachment" surgeries are merged with "organ + manipulation".' + - imageadd: New sprites for reflectors. They finally look like something. + - rscadd: You can lock reflector's rotation by using a screwdriver. Use the screwdriver + again to unlock it. + - rscadd: Reflector examine now shows the current angle and rotation lock status. + - rscadd: You can now use a welder to repair damaged reflectors. + - bugfix: Multiple reflector bugs are fixed. + Improvedname: + - rscdel: Removes statues from gold slime pool + Mercenaryblue: + - imageadd: Updated Clown Box sprite to match the others. + More Robust Than You: + - admin: ONLY ADMINS CAN ACTIVATE THE ARK NOW + - tweak: The Ark's time measurements are now a bit more readable + MrStonedOne: + - tweak: Meteor events will not happen before 25 minutes, the worst versions before + 35 and 45 minutes. + - tweak: Meteor events are now player gated to 15, 20, and 25 players respectively + - balance: The more destructive versions of meteor events now have a slightly higher + chance of triggering, to offset the decrease in how often it is that they will + even qualify. + - bugfix: Fixed the changelog generator. + Naksu: + - tweak: Smartfridges and chem/condimasters now output items in a deterministic + 3x3 grid rather than in a huge pile in the middle of the tile. + SpaceManiac: + - bugfix: Admins can once again spawn nuke teams on demand. + Xhuis: + - admin: Admins can now create sound emitters (/obj/effect/sound_emitter) that can + be customized to play sounds to different people, at different volumes, and + at different locations such as by z-level. They're much more versatile for events + than the Play Sound commands! + - rscadd: You can now add grenades to plushies! You'll need to cut out the stuffing + first. + - tweak: Clockwork cult tips of the round have been updated to match the rework. + - tweak: Abscond and Reebe rifts now place servants directly at the Ark instead + of below the "base" area. + nicbn: + - tweak: Brown gas renamed to nitryl. + ninjanomnom: + - bugfix: Fixes decals not rotating correctly with the turf. + - bugfix: Fixes a runtime causing some turfs to be left behind by removed shuttles. + - code_imp: Shuttles should be roughly 40-50% smoother. + - bugfix: Fixes the cargo shuttle occasionally breaking if a mob got on at exactly + the right time. +2017-11-10: + Anonmare: + - bugfix: Adds an organ storage bag to the syndicate medborg. + AnturK: + - balance: Dying in shapeshifted form reverts you to the original one. (You're still + dead) + Floyd / Qustinnus: + - soundadd: Redtexting as a traitor now plays a depressing tune to you + Floyd / Qustinnus (And all the sounds by Kayozz11 from Yogstation): + - soundadd: Adds about 30 new ambience sounds + - refactor: added new defines for ambience lists. + Iamgoofball: + - tweak: Cooldown on the Ripley's mining drills has been halved. + - tweak: The frequency of the Ripley's ore pulse has been doubled. + Jalleo: + - tweak: Removed a variable to state which RCD's can deconstruct reinforced walls + - balance: Made combat (ERT ones) and admin RCDs able to deconstruct r walls alongside + borg ones + Kor: + - bugfix: Cult mode will once again print out names at round end. + Mark9013100: + - rscadd: Deltastation now has a Whiteship. + - tweak: Charcoal bottles have been renamed, and have been given a more informative + description. + Mercenaryblue: + - spellcheck: spellchecked the hotel staff. + - rscadd: Added frog masks. Reeeeeeeeee!! + More Robust Than You: + - bugfix: Blobbernauts and spores are no longer killed by blob victory + - bugfix: New blob overminds off the station Z level are moved to the station + - bugfix: You can now use banhammers as a weapon + - tweak: Monkeys can no longer transmit diseases through hardsuits + - tweak: Xenobio blobbernauts can no longer walk on blob tiles + Naksu: + - tweak: Added deterministic output slots to the slime processor + - bugfix: Fixed some interactions with ghosts and items + - bugfix: Nonhumans such as monkeys can now be scanned for chemicals with the health + analyzer. + Okand37 (DeltaStation Updates): + - rscadd: Tweaked Atmospherics + - bugfix: Fixed the Incinerator air injector + - rscadd: Tweaked Engineering + - rscadd: Added logs to the Chaplain's closet for gimmicks (bonfires) + - rscadd: Tweaked Security + - bugfix: Fixed medical morgue maintenance not providing radiation shielding and + exterior chemistry windoor + - rscadd: Bar now has a door from the backroom to the theatre stage + - rscadd: Tweaked Locker Room/Dormitories + ShizCalev: + - bugfix: You can now -actually- load pie cannons. + - bugfix: The captain's winter coat can now hold a flashlight. + - bugfix: The captain's and security winter coats can now hold internals tanks. + - tweak: All winter coats can now hold toys, lighters, and cigarettes. + - tweak: The captain's hardsuit can now hold pepperspray. + - rscadd: Updated the Test Map debugging verb to report more issues regarding APCs. + DELTASTATION + - bugfix: Reverted Okand37's morgue changes which broke power in the area. + - bugfix: Corrected wrong area on the Southern airlock leading into electrical maintenance. + ALL STATIONS + - bugfix: Corrected numerous duplicate APCs in areas which led to power issues. + SpaceManiac: + - bugfix: Ghosts can no longer create sparks from the hand teleporter's portals. + - bugfix: Digging on Lavaland no longer shows two progress bars. + - bugfix: The holodeck now has an "Offline" option. + - bugfix: Injury and crit overlays are now scaled properly for zoomed-out views. + - bugfix: Already-downloaded software is now hidden from the NTNet software downloader. + - bugfix: The crafting, language, and building buttons are now positioned correctly + in zoomed-out views. + - bugfix: Bluespace shelter walls no longer smooth with non-shelter walls and windows. + Swindly: + - rscadd: Organ storage bags can be used to perform limb augmentation. + - bugfix: You can now cancel a cavity implant during the implanting/removing step + by using drapes while holding the appropriate tool in your inactive hand. Cyborgs + can cancel the surgery by using drapes alone. + - bugfix: Fixed hot items and fire heating reagents to temperatures higher than + their heat source. + - bugfix: Sprays can now be heated with hot items. + - tweak: The heating of reagents by hot items, fire, and microwaves now scales linearly + with the difference between the reagent holder's temperature and the heat source's + temperature instead of constantly. + - tweak: The body temperature of a mob with reagents is affected by the temperature + of the mob's reagents. + - tweak: Reagent containers can now be heated by hot air. + Thefastfoodguy: + - bugfix: Spamming runes / battlecries / etc will no longer trigger spam prevention + WJohnston: + - bugfix: Ancient station lighting fixed on beta side (medical and atmos remains) + XDTM: + - rscadd: Ghosts now have a Toggle Health Scan verb, which allows them to health + scan mobs they click on. + Xhuis: + - rscadd: Ratvar and Nar-Sie plushes now have a unique interaction. + - balance: Clockwork marauders are now on harm intent. + - balance: The Clockwork Marauder scripture now takes five seconds longer to invoke + per marauder summoned in the last 20 seconds, capping at 30 extra seconds. + - balance: Clockwork marauders no longer gain a health bonus when war is declared. + - tweak: Moved the BoxStation deep fryers up one tile. + - rscadd: Microwaves have new sounds! + YPOQ: + - bugfix: EMPs can pulse multiple wires + as334: + - rscadd: Pluoxium can now be formed by irradiating tiles with CO2 in the air. + - rscadd: Rad collectors now steadily form Tritium at a slow pace. + - balance: Nerfs fusion by making it slower, and produce radioactivity. + - balance: Noblium formation now requires significantly more energy input. + - balance: Tanks now melt if their temperature is above 1 Million Kelvin. + deathride58: + - bugfix: Directional character icon previews now function properly. Other things + relying on getflaticon probably work with directional icons again, as well. + nicbn: + - imageadd: Canister sprites for the new gases + ninjanomnom: + - bugfix: Shuttle parallax has been fixed once more + - bugfix: You can no longer set up the auxiliary base's shuttle beacon overlapping + with the edge of the map + uraniummeltdown: + - tweak: Replica fabricatoring airlocks and windoors keeps the old name + - tweak: Narsie and Ratvar converting airlocks and windoors keeps the old name +2017-11-11: + DaxDupont: + - bugfix: Medbots can inject from one tile away again. + SpaceManiac: + - bugfix: The detective and heads of staff are no longer attacked by portable turrets. + deathride58: + - bugfix: You can no longer delete girders, lattices, or catwalks with the RPD + - bugfix: Fixes runtimes that occur when clicking girders, lattices, catwalks, or + disposal pipes with the RPD in paint mode + ninjanomnom: + - bugfix: Fixes ruin cable spawning and probably some other bugs +2017-11-12: + Cyberboss: + - bugfix: Clockwork slabs no longer refer to components +2017-11-13: + Cobby: + - rscadd: The Xray now only hits the first mob it comes into contact with instead + of being outright removed from the game. + Floyd / Qustinnus: + - soundadd: Reebe now has ambience sounds + 'Floyd / Qustinnus:': + - soundadd: Adds a few sound_loop datums to machinery. + Frozenguy5: + - bugfix: Broken cable cuffs no longer has an invisible sprite. + PKPenguin321: + - rscadd: Welders must now be screwdrivered open to reveal their fuel tank. + - rscadd: You can empty welders into open containers (like beakers or glasses) when + they're screwdrivered open. + - rscadd: You can now insert any chemical into a welder, but all most will do is + clog the fuel. Welding fuel will refuel it as usual. Plasma in welders tends + to explode. + Qbopper and JJRcop: + - tweak: The default internet sound volume was changed from 100 to 25. Stop complaining + in OOC about your ears! + SpaceManiac: + - bugfix: Posters may no longer be placed on diagonal wall corners. + WJohnston: + - rscdel: Removes stationary docking ports for syndicate infiltrator ships on all + maps. Use the docking navigator computer instead! This gives the white ship + and syndicate infiltrator more room to navigate and place custom locations that + are otherwise occupied by fixed shuttle landing zones that are rarely used. + Xhuis: + - rscadd: Deep fryers now have sound. + - tweak: Deep fryers now use cooking oil, a specialized reagent that becomes highly + damaging at high temperatures. You can get it from grinding soybeans and meat. + - tweak: Deep fryers now become more efficient with higher-level micro lasers, using + less oil and frying faster. + - tweak: Deep fryers now slowly use oil as it fries objects, instead of all at once. + - bugfix: You can now correctly refill deep fryers with syringes and pills. + nicn: + - balance: Damage from low pressure has been doubled. + ninjanomnom: + - rscadd: You can now select a nearby area to expand when using a blueprint instead + of making a new area. + - rscadd: New shuttle areas can be created using blueprints. This is currently not + useful but will be used later for shuttle construction. + - tweak: Blueprints can modify existing areas on station. + - admin: Blueprint functionality has been added to the debug tab as a verb. +2017-11-14: + ike709: + - imageadd: Added directional computer sprites. Maps haven't been changed yet. + psykzz: + - refactor: AI Airlock UI to use TGUI + - tweak: Allow AI to swap between electrified door states without having to un-electrify + first. + selea/arsserpentarium: + - rscadd: Integrated circuits have been added to Research! + - rscadd: You can use these to create devices with very complex behaviors. + - rscadd: Research the Integrated circuits printer to get started. +2017-11-15: + Fury: + - rscadd: Added new sprites for the Heirophant Relay (clock cultist telecomms equipment). + Naksu: + - bugfix: 'Removed fire-related free lag. change: fire alarms and cameras no longer + work after being ripped off a wall by a singulo' + - tweak: 'Minor speedups to movement processing. change: Fat mobs no longer gain + temperature by running.' + Robustin: + - refactor: Cult population scaling no longer operates on arbitrary breakpoints. + Each additional player between the between the breakpoints will add to the "chance" + that an additional cultist will spawn. + - tweak: On average you will see less roundstart cultists in lowpop and more roundstart + cultists in highpop. + - tweak: Damage examinations now include a "moderate" classification. Before minor + was <30 and severe was anything 30 or above. Now minor is <25, moderate is 25 + to <50, and severe is 50+. + - tweak: The tesla will now move toward power beacons at a significantly slower + rate. + SpaceManiac: + - bugfix: The post-round station integrity report is now functional again. + ninjanomnom: + - bugfix: Gas overlays no longer block clicks, on 512 +2017-11-22: + ACCount: + - refactor: Old integrated circuit save file format is ditched in favor of JSON. + Readability, both of save files and save code, is improved greatly. + - tweak: Integrated circuit panels now open with screwdriver instead of crowbar, + to match every single other thing on this server. + - tweak: Integrated circuit printer now stores up to 25 metal sheets. + - bugfix: Fixed integrated circuit rechargers not recharging guns properly and not + updating icons. + - bugfix: Fixed multiple bugs in integrated circuits UIs, improved overall usability. + Anonmare: + - balance: Laserpoitners now incapcitate catpeople + AutomaticFrenzy: + - bugfix: cell chargers weren't animating properly + - bugfix: disable_warning wasn't getting checked and the chat was being spammed + Code by Pyko, Ported by Frozenguy5: + - rscadd: Rat Kebabs and Double Rat Kebabs have been added! + Cyberboss: + - server: Server tools API changed to version 3.2.0.1 + - admin: '"ahelp" chat command can now accept a ticket number as opposed to a ckey' + DaxDupont: + - tweak: CentCom has issued a firmware updated for the operating computers. It is + no longer needed to manually refresh the procedure and patient status. + - bugfix: Proximity sensors no longer beep when unarmed. + - bugfix: Plant trays will now properly process fluorine and adjust toxins and water + contents. + Francinum: + - tweak: The shuttle build plate is now better sized for all stations. + Iamgoofball: + - spellcheck: fixes grammar on logic gate descriptions + - spellcheck: fixes grammar on list circuits + - bugfix: fixes grammar on trig circuits + - spellcheck: fixed grammar on output circuits + JJRcop: + - bugfix: Fixes changeling eggs not putting the changeling in control if the brainslug + is destroyed before hatching. + - tweak: The silicon airlock menu looks a little more like it used to. + Kor: + - bugfix: Blobbernauts will no longer spawn if a player is not selected to control + it, preventing AI blobbernauts from running off the blob and to their deaths. + - rscdel: Following complaints that cargo has been selling all the materials they + receive rather than distributing them, mineral exporting has been removed. + MMMiracles: + - balance: Power regen on the regular tesla relay has been reduced to 50, from 150. + Naksu: + - bugfix: Sped up saycode to remove free lag from highpop + - bugfix: Using a chameleon projector will now dismount you from any vehicles you + are riding, in order to prevent wacky space glitches and being sent to a realm + outside space and time. + Shadowlight213: + - code_imp: Added round id to the status world topic + ShizCalev: + - bugfix: Chameleon goggles will no longer go invisible when selecting Optical Tray + scanners. + - rscadd: Engineering and Atmos scanner goggles will now have correctly colored + inhand sprites. + - tweak: The computers on all maps have have been updated for the latest directional + sprite changes. Please report any computers facing in strange directions to + your nearest mapper. + - bugfix: MetaStation - The consoles in medbay have had their directions corrected. + - imageadd: The Nanotrasen logo on modular computers has been fixed, rejoice! + - bugfix: PubbyStation - Unpowered air injectors in various locations have been + fixed. + - bugfix: MetaStation - Air injector leading out of the incinerator has been fixed + - bugfix: MetaStation - Corrected a couple maintenance airlocks being powered by + the wrong areas. + - bugfix: Computers will no longer rotate incorrectly when being deconstructed. + - bugfix: You can now rotate computer frames during construction. + - bugfix: Chairs, PA parts, infrared emitters, and doppler arrays will now rotate + clockwise. + - bugfix: Throwing drinking glasses and cartons will now consistently cause them + to break! + - bugfix: Humans missing legs or are legcuffed will no longer move slower in areas + without gravity. + - bugfix: The structures external to stations are now properly lit. Make sure you + bring a flashlight. + - bugfix: Computers will no longer delete themselves when being built, whoops! + - bugfix: Space cats will no longer have a smashed helmet when they lay down. + Skylar Lineman, your local R&D moonlighter: + - rscadd: Research has been completely overhauled into the techweb system! No more + levels, the station now unlocks research "nodes" with research points passively + generated when there is atleast one research server properly cooled, powered, + and online. + - rscadd: R&D lab has been replaced by the departmental lathe system on the three + major maps. Each department gets a lathe and possibly a circuit imprinter that + only have designs assigned by that department. + - rscadd: The ore redemption machine has been moved into cargo bay on maps with + decentralized research to prevent the hallways from becoming a free for all. + Honk! + - balance: You shouldn't expect balance as this is the initial merge. Please put + all feedback and concerns on the forum so we can revise the system over the + days, weeks, and months, to make this enjoyable for everyone. Heavily wanted + are ideas of how to add more ways of generating points. + - balance: You can get techweb points by setting off bombs with an active science + doppler array listening. The bombs have to have a theoretical radius far above + maxcap to make a difference. You can only go up, not down, in radius, so you + can't get 6 times the points with 6 TTVs. The algorithm is exponentially/logarithmically + scaled to prevent "world destroyer" bombs from instantly finishing research. + SpaceManiac: + - bugfix: HUDs from mechs and helmets no longer conflict with HUD glasses and no + longer inappropriately remove implanted HUDs. + - code_imp: Chasm code has been refactored to be more sane. + - bugfix: Building lattices over chasms no longer sometimes deletes the chasm. + - code_imp: Ladders have been refactored and should be far less buggy. + - bugfix: Jacob's ladder actually works again. + - bugfix: Pizza box stacking works again. + - bugfix: Fix some permanent-on and permanent-off bugs caused by the HUD stacking + change. + WJohnston: + - imageadd: A bunch of new turf decals for mappers to play with, coming in yellow, + white, and red varieties! + - bugfix: Green banded default airlocks now have extended click area like all other + airlocks. + Y0SH1 M4S73R: + - spellcheck: The R&D Server's name is now improper. + - spellcheck: The R&D Server now has an explanation of what it does. + arsserpentarium: + - bugfix: now lists should work properly + duncathan: + - rscadd: The RPD has a shiny new UI! + - rscadd: The RPD can now paint pipes as it lays them, for quicker piping projects. + - rscadd: Atmos scrubbers (vent and portable) can now filter any and all gases. + ike709: + - imageadd: Added new vent and scrubber sprites by Partheo. + - bugfix: Fixed some computers facing the wrong direction. + jammer312: + - bugfix: fixed conjuration spells forgetting about conjured items + kevinz000: + - rscadd: purple bartender suit and apron added to clothesmates! + - rscadd: long hair 3 added, check it out. both have sprites from okand! + nicbn: + - soundadd: Now rolling beds and office chairs have a sound! + oranges: + - rscdel: Removed the shocker circuit + psykzz: + - imageadd: Grilles have new damaged and default sprites + - rscadd: Added TGUI for Turbine computer + tserpas1289: + - tweak: Any suit that could hold emergency oxygen tanks can now also hold plasma + man internals + - tweak: Hydroponics winter coats now can hold emergency oxygen tanks just like + the other winter coats. + - bugfix: Plasma men jumpsuits can now hold accessories like pocket protectors and + medals. + zennerx: + - bugfix: fixed a bug that made you try and scream while unconscious due to a fire + - tweak: Skateboard crashes now give slight brain damage! + - rscadd: Using a helmet prevents brain damage from the skateboard! +2017-11-23: + GupGup: + - bugfix: Fixes hostile mobs attacking surrounding tiles when trying to attack someone + MrStonedOne and Jordie: + - server: As a late note, serverops be advise that mysql is no longer supported. + existing mysql databases will need to be converted to mariadb + Robustin: + - tweak: RND consoles will no longer display options for machines or disks that + are not connected/inserted. + ShizCalev: + - bugfix: Aliens in soft-crit will now use the correct sprite. + XDTM: + - rscadd: 'Added two new symptoms: one allows viruses to still work while dead, + and allows infection of undead species, and one allows infection of inorganic + species (such as plasmapeople or golems).' +2017-11-24: + ACCount: + - rscdel: Removed "console screen" stock part. Just use glass sheets instead. + More Robust Than You: + - tweak: Spessmen are now smart enough to realize you don't need to turn around + to pull cigarette butts + SpaceManiac: + - bugfix: Fix water misters being inappropriately glued to hands in some cases. + - bugfix: Some misplaced decals in the Hotel brig have been corrected. + ninjanomnom: + - bugfix: Custom shuttle dockers can no longer place docking regions inside other + custom docker regions. +2017-11-25: + CosmicScientist: + - bugfix: bolas are back in tablecrafting! + Dorsisdwarf: + - tweak: Catpeople are now distracted instead of debilitated + - rscadd: Normal cats now go for laser pointers + SpaceManiac: + - bugfix: You can no longer buckle people to roller beds from inside of a locker. + YPOQ: + - bugfix: AIs and cyborgs can interact with unscrewed airlocks and APCs. + ninjanomnom: + - bugfix: Fixes thermite burning hotter than the boiling point of stone + zennerx: + - bugfix: Zombies don't reanimate with no head! +2017-11-27: + ACCount: + - rscadd: 'New integrated circuit components: list constructors/deconstructors. + Useful for building lists and taking them apart.' + - bugfix: Fixed multiple bugs in integrated circuits UIs, improved overall usability. + More Robust Than You: + - bugfix: Fixed cult leaders being de-culted upon election if they had a mindshield + implant + Naksu: + - bugfix: Hopefully fixed mesons granting the ability to hear people through walls. + Okand37: + - rscadd: Re-organized Delta's departmental protolathes for all departments. + - rscadd: Re-organized Delta's ORM placement by connecting it to the mining office, + which now has a desk for over handing materials to the outside. + - rscadd: Added a second Nanomed to Deltastation's medical bay. + - rscadd: Nanotrasen has decided to add proper caution signs to most docking ports + on Deltastation, warning individuals to be cautious around these areas. + - rscadd: Two health sensors are now placed in Deltastation's robotics area for + medibots. + - bugfix: Atmospheric Technicians at Deltastation can now open up their gas storage + in the supermatter power area as intended. + WJohnston: + - bugfix: Fixed a case where items would sometimes be placed underneath racks. + XDTM: + - balance: Viruses' healing symptoms have been reworked! + - rscdel: All existing healing symptoms have been removed in favour of new ones. + - rscdel: Weight Even and Weight Gain have been removed, so hunger can be used for + balancing in symptoms. + - rscadd: Starlight Condensation heals toxin damage if you're in space using starlight + as a catalyst. Being up to two tiles away also works, as long as you can still + see it, but slower. + - rscadd: Toxolysis (level 7) rapidly cleanses all chemicals from the body, with + no exception. + - rscadd: 'Cellular Molding heals brute damage depending on your body temperature: + the higher the temperature, the faster the healing. Requires above-average temperature + to activate, and the speed heavily increases while on fire.' + - rscadd: Regenerative Coma (level 8) causes the virus to send you into a deep coma + when you are heavily damaged (>70 brute+burn damage). While you are unconscious, + either from the virus or from other sources, the virus will heal both brute + and burn damage fairly quickly. Sleeping also works, but at reduced speed. + - rscadd: Tissue Hydration heals burn damage if you are wet (negative fire stacks) + or if you have water in your bloodstream. + - rscadd: Plasma Fixation (level 8) stabilizes temperature and heals burns while + plasma is in your body or while standing in a plasma cloud. Does not protect + from the poisoning effects of plasma. + - rscadd: Radioactive Resonance gives a mild constant brute and burn healing while + irradiated. The healing becomes more intense if you reach higher levels of radiation, + but is still less than the alternatives. + - rscadd: Metabolic Boost (level 7) doubles the rate at which you process chemicals, + good and bad, but also increases hunger tenfold. + kevinz000: + - bugfix: Cryo cells can now be properly rotated with a wrench. + ninjanomnom: + - rscadd: 'You can now make a new tasty traditional treat: butterdogs. Watch out, + they''re slippery.' +2017-11-28: + ACCount: + - rscdel: '"Machine prototype" is removed from the game.' + - rscdel: Mass-spectrometers are removed. Would anyone notice if not for this changelog + entry? + Cruix: + - rscadd: AI and observer diagnostic huds will now show the astar path of all bots, + and Pai bots will be given a visible path to follow when called by the AI. + JJRcop: + - admin: Fixed the Make space ninja verb. + Naksu: + - code_imp: rejiggered botcode a little bit + SpaceManiac: + - spellcheck: Admin-added "download research" objectives are now consistent with + automatic ones. + improvedname: + - tweak: toolbelts can now carry geiger counters + uraniummeltdown: + - rscadd: You can make many different types of office and comfy chairs with metal + - tweak: Stack menus use /datum/browser +2017-11-29: + MrStonedOne: + - tweak: The sloth no longer suspiciously moves fast when gliding between tiles. + - balance: The sloth's movespeed when inhabited by a player has been lowered from + once every 1/5 of a second to once every second. + SpaceManiac: + - spellcheck: The techweb node for mech LMGs no longer claims to be for mech tasers. +2017-11-30: + ninjanomnom: + - tweak: Reduced the max volume of sm by 1/5th and made the upper bounds only play + mid delamination. + psykzz: + - bugfix: Fixing the broken turbine computer +2017-12-02: + BeeSting12: + - spellcheck: Occupand ---> Occupant on opened cryogenic pods. + - spellcheck: Cyrogenic ---> Cryogenic on opened cryogenic pods. + CosmicScientist: + - rscadd: You can make plushies kiss one another! + Frozenguy5: + - tweak: The Particle Accelerator's wires can no longer be EMP'd + Naksu: + - code_imp: Cleans up some loc assignments + Robustin: + - tweak: Damage examinations now include a "moderate" classification. Before minor + was <30 and severe was anything 30 or above. Now minor is <25, moderate is 25 + to <50, and severe is 50+. + - balance: Clockwork magicks will now prevent Bags of Holding from being combined + on Reebe. + - bugfix: Flashes will now burn out AFTER flashing when they fail instead of being + a ticking time bomb that waits to screw you over on your next attempt. + SpaceManiac: + - tweak: The R&D Console has been given a much prettier interface. + - tweak: Research scanner goggles now show materials and technology prospects in + a nicer way. + uraniummeltdown: + - imageadd: Construct shells have a new animated sprite +2017-12-03: + ExcessiveUseOfCobblestone: + - bugfix: You can now lay (buckle!) yourself to a bed to avoid being burnt to a + crisp during "the floor is lava" event. + Robustin: + - tweak: Igniting plasma statues no longer ignores ignition temperature and only + creates as much plasma as was used in its creation. + Xhuis: + - rscadd: Light fixtures now turn an ominous, dim red color when they lose power, + and draw from an internal power cell to maintain it until either the cell dies + (usually after 10 minutes) or power is restored. + - rscadd: You can override emergency light functionality from an APC. You can also + click on individual lights as a cyborg or AI to override them individually. + Traitor AIs also have a new ability that disables emergency lights across the + entire station. + zennerx: + - spellcheck: fixed some typos in the weapon firing mechanism description +2017-12-04: + AnturK: + - rscadd: You can now record and replay holopad messages using holodisks. + - rscadd: Holodisks are printable in autolathes. + Xhuis: + - bugfix: You now need fuel in your welder to repair mechs. +2017-12-05: + Cyberboss: + - sounddel: Reduced the volume of showers + Dax Dupont: + - rscadd: Nanotrasen is happy to announce the pinnacle in plasma research! The Disco + Inferno shuttle design is the result of decades of plasma research. Burn, baby, + burn! + MrPerson & ninjanomnom: + - refactor: Completely changed how keyboard input is read. + - rscadd: Holding two directions at the same time will now move you diagonally. + This works with the arrow keys, wasd, and the numpad. + - tweak: Moving diagonally takes twice as long as moving a cardinal direction. + - bugfix: You can use control to turn using wasd and the numpad instead of just + the arrow keys. + - rscdel: 'Some old non-hotkey mode behaviors, especially in relation to chatbox + interaction, can''t be kept with the new system. Of key note: You can''t type + while walking. This is due to limitations of byond and the work necessary to + overcome it is better done as another overhaul allowing custom controls.' + Robustin: + - rscdel: Reverted changes in 3d sound system that tripled the distance that sound + would carry. + SpaceManiac: + - spellcheck: Energy values are now measured in joules. What was previously 1 unit + is now 1 kJ. + - bugfix: Syndicate uplink implants now work again. + Xhuis: + - tweak: Stethoscopes now inform the user if the target can be defibrillated; the + user will hear a "faint, fluttery pulse." + coiax: + - rscadd: Quiet areas of libraries on station have now been equipped with a vending + machine containing suitable recreational activities. +2017-12-06: + Dax Dupont & Alek2ander: + - tweak: Binary chat messages been made more visible. + Revenant Defile ability: + - bugfix: Revenant's Defile now removes salt piles + XDTM: + - rscadd: 'Brain damage has been completely reworked! remove: Brain damage now no + longer simply makes you dumb. Although most of its effects have been shifted + into a brain trauma.' + - rscadd: Every time you take brain damage, there's a chance you'll suffer a brain + trauma. There are many variations of brain traumas, split in mild, severe, and + special. + - rscadd: Mild brain traumas are the easiest to get, can be lightly to moderately + annoying, and can be cured with mannitol and time. + - rscadd: Severe brain traumas are much rarer and require extensive brain damage + before you have a chance to get them; they are usually very debilitating. Unlike + mild traumas, they require surgery to cure. A new surgery procedure has been + added for this, the aptly named Brain Surgery. It can also heal minor traumas. + - rscadd: 'Special brain traumas are rarely gained in place of Severe traumas: they + are either complex or beneficial. However, they are also even easier to cure + than mild traumas, which means that keeping these will usually mean keeping + a mild trauma along with it.' + - rscadd: Mobs can only naturally have one mild trauma and one severe or special + trauma. + - balance: Brain damage will now kill and ruin the brain if it goes above 200. If + it somehow goes above 400, the brain will melt and be destroyed completely. + - balance: Many brain-damaging effects have been given a damage cap, making them + non-lethal. + - rscdel: The Unintelligible mutation has been removed and made into a brain trauma. + - rscdel: Brain damage no longer makes using machines a living hell. + - rscadd: Abductors give minor traumas to people they experiment on. + coiax: + - rscadd: The drone dispenser on Metastation has been moved to the maintenance by + Robotics. +2017-12-07: + ShizCalev: + - bugfix: Games vending machines can now properly be rebuilt. + - bugfix: Games vending machines can now be refilled via supply crates. + - rscadd: Games Supply Crates have been added to the cargo console. + SpaceManiac: + - bugfix: Radio frequency 148.9 is once again serviced by the telecomms system. + Xhuis: + - rscadd: Added the Eminence role to clockcult! Players can elect themselves or + ghosts as the Eminence from the eminence spire structure on Reebe. + - rscadd: The Eminence is incorporeal and invisible, and directs the entire cult. + Anything they say is heard over the Hierophant network, and they can issue commands + by middle-clicking themselves or different turfs. + - rscadd: The Eminence also has a single-use mass recall that warps all servants + to the Ark chamber. + - rscadd: Added traps, triggers, and brass filaments to link them. They can all + be constructed from brass sheets, and do different things and trigger in different + ways. Current traps include the brass skewer and steam vent, and triggers include + the pressure sensor, lever, and repeater. + - rscadd: The Eminence can activate trap triggers by clicking on them! + - rscadd: Servants can deconstruct traps instantly with a wrench. + - rscdel: Mending Mantra has been removed. + - tweak: Clockwork scriptures have been recolored and sorted based on their functions; + yellow scriptures are for construction, red for offense, blue for defense, and + purple for niche. + - balance: Servants now spawn with a PDA and black shoes to make disguise more feasible. + - balance: The Eminence can superheat up to 20 clockwork walls at a time. Superheated + walls are immune to hulk and mech punches, but can still be broken conventionally. + - balance: Clockwork walls are slightly faster to build before the Ark activates, + taking an extra second less. + - bugfix: Poly no longer continually undergoes binary fission when Ratvar is in + range. + - code_imp: The global records alert for servants will no longer display info that + doesn't affect them since the rework. + coiax: + - rscadd: The drone dispenser on Box Station has been moved from the Testing Lab + to the Morgue/Robotics maintenance tunnel. + deathride58: + - config: The default view range can now be defined in the config. The default is + 15x15, which is simplified to 7 by BYOND. For reference, Goonstation's widescreen + range is 21x15. Do note that changing this value will affect the title screen. + The title screen images and the title screen area on the Centcom z-level will + have to be updated if the default view range is changed. +2017-12-08: + Dax Dupont: + - bugfix: Fixed observer chat flavor of silicon chat. + - bugfix: Grilles now no longer revert to a pre-broken icon state when you hit them + after they broke. + Dorsisdwarf: + - tweak: Minor fixes to some techweb nodes + - balance: Made flight suits, combat implants, and combat modules require more nodes + Fox McCloud: + - tweak: Slime blueprints can now make an area compatible with Xenobio consoles, + regardless of the name of the new area + MrDoomBringer: + - imageadd: All stations have been outfitted with brand new Smoke Machines! They + have nicer sprites now! + Shadowlight213: + - rscadd: You now can get a medal for wasting hours talking to the secret debug + tile. + - bugfix: Fixed runtime for the tile when poly's speech file doesn't exist. + Xhuis: + - rscadd: You can now make pet carriers from the autolathe, to carry around chef + meat and other small animals without having to drag them. The HoP, captain, + and CMO also start with carriers in their lockers for their pets. + YPOQ: + - bugfix: Fixed the camera failure, race swap, cursed items, and imposter wizard + random events + - tweak: The cursed items event no longer nullspaces items + jammer312: + - rscadd: Action buttons now remember positions where you locked. + - tweak: Now locking action buttons prevents them from being reset. +2017-12-10: + SpaceManiac: + - bugfix: External airlocks of the mining base and gulag are now cycle-linked. + - tweak: The pAI software interface is now accessible via an action button. + Swindly: + - rscadd: You can kill yourself with a few more items. + XDTM: + - tweak: Instead of activating randomly on speech, Godwoken Syndrome randomly grants + inspiration, causing the next message to be a Voice of God. + Xhuis: + - tweak: Flickering lights will now actually flicker and not go between emergency + lights and normal lighting. + - bugfix: Emergency lights no longer stay on forever in some cases. + kevinz000: + - rscadd: Nanotrasen would like to remind crewmembers and especially medical personnel + to stand clear of cadeavers before applying a defibrillator shock. (You get + shocked if you're pulling/grabbing someone being defibbed.) + - tweak: defib shock/charge sounds upped from 50% to 75%. +2017-12-11: + Anonmare: + - bugfix: Booze-o-mats have beer + Cruix: + - tweak: The white ship navigation computer now takes 10 seconds to designate a + landing spot, and users can no longer see the syndicate shuttle or its custom + landing location. If the white ship landing location would intersect the syndicate + shuttle or its landing location, it will fail after the 10 seconds have elapsed. + Frozenguy5: + - balance: Some hardsuits have had their melee, fire and rad armor ratings tweaked. + Improvedname: + - tweak: cats now drop their ears and tail when butchered. + Robustin: + - bugfix: Modes not in rotation have had their "false report" weights for the Command + Report standardized + SpaceManiac: + - bugfix: The MULEbots that the station starts with now show their ID numbers. + - bugfix: The dependency by Advanced Cybernetic Implants and Experimental Flight + Equipment on Integrated HUDs has been restored. + kevinz000: + - bugfix: flightsuits should no longer disappear when you take them off involuntarily + - bugfix: beam rifles actually fire striaght now + - bugfix: click catchers now actually work + - bugfix: you no longer see space in areas you normally can't see, instead of black. + in reality you can still see space but it's faint enough that you can't tell + so I'll say I fixed it. + uraniummeltdown: + - rscadd: Added MANY new types of airlock assembly that can be built with metal. + Use metal in hand to see the new airlock assembly recipes. + - rscadd: Added new airlock types to the RCD and airlock painter + - rscadd: Vault door assemblies can be built with 8 plasteel, high security assemblies + with 6 plasteel + - rscadd: Glass mineral airlocks are finally constructible. Use glass and mineral + sheets on an airlock assembly in any order to make them. + - tweak: Glass and mineral sheets are now able to be welded out of door assemblies + rather than having to deconstruct the whole thing + - rscdel: Airlock painter no longer works on airlock assemblies (still works on + airlocks) + - bugfix: Titanium airlocks no longer have any missing overlays +2017-12-12: + Mark9013100: + - rscadd: Medical Wardrobes now contain an additional standard and EMT labcoat. + Robustin: + - rscadd: The blood cult revive rune will now replace the souls of braindead or + inactive cultists/constructs when properly invoked. These "revivals" will not + count toward the revive limit. + - rscadd: The clock cult healing rune will now replace the souls of braindead or + inactive cultists/constructs when left atop the rune. These "revivals" will + not drain the rune's energy. + Swindly: + - bugfix: Swarmers can no longer deconstruct objects with living things in them. + kevinz000: + - bugfix: You can now print telecomms equipment again. +2017-12-13: + Naksu: + - bugfix: glass shards and bananium floors no longer make a sound when "walked" + over by a camera or a ghost + SpaceManiac: + - bugfix: Nonstandard power cells found in MULEbots, cyborgs, and elsewhere now + have the correct description. + deathride58: + - bugfix: Genetics will no longer have a random block completely disappear each + round +2017-12-15: + AverageJoe82: + - rscadd: drones now have night vision + - rscdel: drones no longer have lights + Cruix: + - bugfix: Shuttles now place hyperspace ripples where they are about to land again. + Cyberboss: + - config: Added "$include" directives to config files. These are recursive. Only + config.txt will be default loaded if they are specified inside it + - config: Added multi string list entry CROSS_SERVER. e.g. CROSS_SERVER Server+Name + byond://server.net:1337 + - config: CROSS_SERVER_ADDRESS removed + Epoc: + - bugfix: Adds Cybernetic Lungs to the Cyber Organs research node + JStheguy: + - rscadd: Added 10 new assembly designs to the integrated circuit printer, the difference + from current designs is purely aesthetics. + - imageadd: Added the icons for said new assembly designs to electronic_setups.dmi, + changed the current electronic mechanism and electronic machine sprites. + MrStonedOne: + - server: Added new admin flag, AUTOLOGIN, to control if admins start with admin + powers. this defaults to on, and can be removed with -AUTOLOGIN + - admin: Admins with +PERMISSION may now deadmin or readmin other admins via the + permission panel. + Naksu: + - code_imp: Preliminary work on tracking cliented living mobs across Z-levels to + facilitate mob AI changes later + - code_imp: Tidied up some loc assignments + - code_imp: fixes the remaining loc assignments + ShizCalev: + - soundadd: Revamped gun dry-firing sounds. + - tweak: Everyone around you will now hear when your gun goes click. You don't want + to hear click when you want to hear bang! + SpaceManiac: + - code_imp: Remote signaler and other non-telecomms radio code has been cleaned + up. + Xhuis: + - rscadd: Grinding runed metal and brass now produces iron/blood and iron/teslium, + respectively. + - balance: As part of some code-side improvements, the amount of reagents you get + from grinding some objects might be slightly different. + - bugfix: Some grinding recipes that didn't work, like dead mice and glowsticks, + now do. + - bugfix: All-In-One grinders now correctly grind up everything, instead of one + thing at a time. + nicbn: + - imageadd: Closet sprites changed. +2017-12-16: + Armhulen and lagnas2000 (+his team of amazing spriters): + - rscadd: Mi-go have entered your realm! + Robustin: + - balance: Marauder shields now take twice as long to regenerate and only recharge + one charge at a time. + - balance: Marauders now have 120hp down from 150hp. + - bugfix: The wizard event "race swap" should now stick to "safer" species. + - bugfix: Zombies are now properly stunned for a maximum of 2 seconds instead of + 2/10ths of a second. + - tweak: Zombie slowdown adjusted from -2 to -1.6. + SpaceManiac: + - bugfix: The shuttle will no longer be autocalled if the round has already ended. + Xhuis: + - tweak: Vitality matrices don't have visible messages when someone crosses them + anymore. +>>>>>>> 7f8905e... Fixes Mi-Go crediting (#33626) diff --git a/html/changelogs/AutoChangeLog-pr-4014.yml b/html/changelogs/AutoChangeLog-pr-4014.yml new file mode 100644 index 0000000000..1a1698767d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4014.yml @@ -0,0 +1,8 @@ +author: "Skylar Lineman, your local R&D moonlighter" +delete-after: True +changes: + - rscadd: "Research has been completely overhauled into the techweb system! No more levels, the station now unlocks research \"nodes\" with research points passively generated when there is atleast one research server properly cooled, powered, and online." + - rscadd: "R&D lab has been replaced by the departmental lathe system on the three major maps. Each department gets a lathe and possibly a circuit imprinter that only have designs assigned by that department." + - rscadd: "The ore redemption machine has been moved into cargo bay on maps with decentralized research to prevent the hallways from becoming a free for all. Honk!" + - balance: "You shouldn't expect balance as this is the initial merge. Please put all feedback and concerns on the forum so we can revise the system over the days, weeks, and months, to make this enjoyable for everyone. Heavily wanted are ideas of how to add more ways of generating points." + - balance: "You can get techweb points by setting off bombs with an active science doppler array listening. The bombs have to have a theoretical radius far above maxcap to make a difference. You can only go up, not down, in radius, so you can't get 6 times the points with 6 TTVs. The algorithm is exponentially/logarithmically scaled to prevent \"world destroyer\" bombs from instantly finishing research." diff --git a/html/changelogs/AutoChangeLog-pr-4076.yml b/html/changelogs/AutoChangeLog-pr-4076.yml new file mode 100644 index 0000000000..b40f213dd3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4076.yml @@ -0,0 +1,4 @@ +author: "XDTM" +delete-after: True +changes: + - rscadd: "Added two new symptoms: one allows viruses to still work while dead, and allows infection of undead species, and one allows infection of inorganic species (such as plasmapeople or golems)." diff --git a/html/changelogs/AutoChangeLog-pr-4133.yml b/html/changelogs/AutoChangeLog-pr-4133.yml new file mode 100644 index 0000000000..2b50fbd4ea --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4133.yml @@ -0,0 +1,14 @@ +author: "XDTM" +delete-after: True +changes: + - balance: "Viruses' healing symptoms have been reworked!" + - rscdel: "All existing healing symptoms have been removed in favour of new ones." + - rscdel: "Weight Even and Weight Gain have been removed, so hunger can be used for balancing in symptoms." + - rscadd: "Starlight Condensation heals toxin damage if you're in space using starlight as a catalyst. Being up to two tiles away also works, as long as you can still see it, but slower." + - rscadd: "Toxolysis (level 7) rapidly cleanses all chemicals from the body, with no exception." + - rscadd: "Cellular Molding heals brute damage depending on your body temperature: the higher the temperature, the faster the healing. Requires above-average temperature to activate, and the speed heavily increases while on fire." + - rscadd: "Regenerative Coma (level 8) causes the virus to send you into a deep coma when you are heavily damaged (>70 brute+burn damage). While you are unconscious, either from the virus or from other sources, the virus will heal both brute and burn damage fairly quickly. Sleeping also works, but at reduced speed." + - rscadd: "Tissue Hydration heals burn damage if you are wet (negative fire stacks) or if you have water in your bloodstream." + - rscadd: "Plasma Fixation (level 8) stabilizes temperature and heals burns while plasma is in your body or while standing in a plasma cloud. Does not protect from the poisoning effects of plasma." + - rscadd: "Radioactive Resonance gives a mild constant brute and burn healing while irradiated. The healing becomes more intense if you reach higher levels of radiation, but is still less than the alternatives." + - rscadd: "Metabolic Boost (level 7) doubles the rate at which you process chemicals, good and bad, but also increases hunger tenfold." diff --git a/html/changelogs/AutoChangeLog-pr-4136.yml b/html/changelogs/AutoChangeLog-pr-4136.yml new file mode 100644 index 0000000000..0737b28919 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4136.yml @@ -0,0 +1,5 @@ +author: "ACCount" +delete-after: True +changes: + - rscadd: "New integrated circuit components: list constructors/deconstructors. Useful for building lists and taking them apart." + - bugfix: "Fixed multiple bugs in integrated circuits UIs, improved overall usability." diff --git a/html/changelogs/AutoChangeLog-pr-4143.yml b/html/changelogs/AutoChangeLog-pr-4143.yml new file mode 100644 index 0000000000..dc1f281cec --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4143.yml @@ -0,0 +1,4 @@ +author: "Naksu" +delete-after: True +changes: + - code_imp: "rejiggered botcode a little bit" diff --git a/html/changelogs/AutoChangeLog-pr-4144.yml b/html/changelogs/AutoChangeLog-pr-4144.yml new file mode 100644 index 0000000000..bcefc8437a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4144.yml @@ -0,0 +1,5 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "You can make many different types of office and comfy chairs with metal" + - tweak: "Stack menus use /datum/browser" diff --git a/html/changelogs/AutoChangeLog-pr-4145.yml b/html/changelogs/AutoChangeLog-pr-4145.yml new file mode 100644 index 0000000000..c7b269b20f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4145.yml @@ -0,0 +1,4 @@ +author: "improvedname" +delete-after: True +changes: + - tweak: "toolbelts can now carry geiger counters" diff --git a/html/changelogs/AutoChangeLog-pr-4149.yml b/html/changelogs/AutoChangeLog-pr-4149.yml new file mode 100644 index 0000000000..909fc3e1b9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4149.yml @@ -0,0 +1,4 @@ +author: "JJRcop" +delete-after: True +changes: + - admin: "Fixed the Make space ninja verb." diff --git a/html/changelogs/AutoChangeLog-pr-4150.yml b/html/changelogs/AutoChangeLog-pr-4150.yml new file mode 100644 index 0000000000..943af018e5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4150.yml @@ -0,0 +1,4 @@ +author: "ACCount" +delete-after: True +changes: + - rscdel: "Mass-spectrometers are removed. Would anyone notice if not for this changelog entry?" diff --git a/html/changelogs/AutoChangeLog-pr-4152.yml b/html/changelogs/AutoChangeLog-pr-4152.yml new file mode 100644 index 0000000000..df1b1cd09f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4152.yml @@ -0,0 +1,4 @@ +author: "ACCount" +delete-after: True +changes: + - rscdel: "\"Machine prototype\" is removed from the game." diff --git a/html/changelogs/AutoChangeLog-pr-4155.yml b/html/changelogs/AutoChangeLog-pr-4155.yml new file mode 100644 index 0000000000..0f762fae2e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4155.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "AI and observer diagnostic huds will now show the astar path of all bots, and Pai bots will be given a visible path to follow when called by the AI." diff --git a/html/changelogs/AutoChangeLog-pr-4162.yml b/html/changelogs/AutoChangeLog-pr-4162.yml new file mode 100644 index 0000000000..be4968592e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4162.yml @@ -0,0 +1,5 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - tweak: "The sloth no longer suspiciously moves fast when gliding between tiles." + - balance: "The sloth's movespeed when inhabited by a player has been lowered from once every 1/5 of a second to once every second." diff --git a/html/changelogs/AutoChangeLog-pr-4170.yml b/html/changelogs/AutoChangeLog-pr-4170.yml new file mode 100644 index 0000000000..f54be6c190 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4170.yml @@ -0,0 +1,4 @@ +author: "ninjanomnom" +delete-after: True +changes: + - tweak: "Reduced the max volume of sm by 1/5th and made the upper bounds only play mid delamination." diff --git a/html/changelogs/AutoChangeLog-pr-4171.yml b/html/changelogs/AutoChangeLog-pr-4171.yml new file mode 100644 index 0000000000..612f5ad379 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4171.yml @@ -0,0 +1,4 @@ +author: "psykzz" +delete-after: True +changes: + - bugfix: "Fixing the broken turbine computer" diff --git a/html/changelogs/AutoChangeLog-pr-4172.yml b/html/changelogs/AutoChangeLog-pr-4172.yml new file mode 100644 index 0000000000..a2dac53175 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4172.yml @@ -0,0 +1,4 @@ +author: "Robustin" +delete-after: True +changes: + - tweak: "Damage examinations now include a \"moderate\" classification. Before minor was <30 and severe was anything 30 or above. Now minor is <25, moderate is 25 to <50, and severe is 50+." diff --git a/html/changelogs/AutoChangeLog-pr-4175.yml b/html/changelogs/AutoChangeLog-pr-4175.yml new file mode 100644 index 0000000000..1eed117c43 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4175.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - imageadd: "Construct shells have a new animated sprite" diff --git a/html/changelogs/AutoChangeLog-pr-4176.yml b/html/changelogs/AutoChangeLog-pr-4176.yml new file mode 100644 index 0000000000..76ccbf0925 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4176.yml @@ -0,0 +1,8 @@ +author: "Toriate" +delete-after: True +changes: + - rscadd: "Added Lavaknights, a new ghost role of cat people in knight armor." + - rscadd: "Added Hypereutactic blades, NEBs on steroids." + - tweak: "Made NEBs alt click to recolor +wip: Added lavaknight spawners. Someone else needs to add it in to a map or ruin properly." + - imageadd: "added sprites for hypereutactic blades" diff --git a/html/changelogs/AutoChangeLog-pr-4177.yml b/html/changelogs/AutoChangeLog-pr-4177.yml new file mode 100644 index 0000000000..f6e65ed068 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4177.yml @@ -0,0 +1,4 @@ +author: "Robustin" +delete-after: True +changes: + - balance: "Clockwork magicks will now prevent Bags of Holding from being combined on Reebe." diff --git a/html/changelogs/AutoChangeLog-pr-4180.yml b/html/changelogs/AutoChangeLog-pr-4180.yml new file mode 100644 index 0000000000..fb6248b653 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4180.yml @@ -0,0 +1,4 @@ +author: "Robustin" +delete-after: True +changes: + - bugfix: "Flashes will now burn out AFTER flashing when they fail instead of being a ticking time bomb that waits to screw you over on your next attempt." diff --git a/html/changelogs/AutoChangeLog-pr-4182.yml b/html/changelogs/AutoChangeLog-pr-4182.yml new file mode 100644 index 0000000000..6d0c949e11 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4182.yml @@ -0,0 +1,4 @@ +author: "Frozenguy5" +delete-after: True +changes: + - tweak: "The Particle Accelerator's wires can no longer be EMP'd" diff --git a/html/changelogs/AutoChangeLog-pr-4184.yml b/html/changelogs/AutoChangeLog-pr-4184.yml new file mode 100644 index 0000000000..f97a70a206 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4184.yml @@ -0,0 +1,4 @@ +author: "CosmicScientist" +delete-after: True +changes: + - rscadd: "You can make plushies kiss one another!" diff --git a/html/changelogs/AutoChangeLog-pr-4186.yml b/html/changelogs/AutoChangeLog-pr-4186.yml new file mode 100644 index 0000000000..86951d81f1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4186.yml @@ -0,0 +1,4 @@ +author: "Naksu" +delete-after: True +changes: + - code_imp: "Cleans up some loc assignments" diff --git a/html/changelogs/AutoChangeLog-pr-4191.yml b/html/changelogs/AutoChangeLog-pr-4191.yml new file mode 100644 index 0000000000..5904f70b86 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4191.yml @@ -0,0 +1,5 @@ +author: "BeeSting12" +delete-after: True +changes: + - spellcheck: "Occupand ---> Occupant on opened cryogenic pods." + - spellcheck: "Cyrogenic ---> Cryogenic on opened cryogenic pods." diff --git a/html/changelogs/AutoChangeLog-pr-4196.yml b/html/changelogs/AutoChangeLog-pr-4196.yml new file mode 100644 index 0000000000..49ab9fdbd9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4196.yml @@ -0,0 +1,4 @@ +author: "zennerx" +delete-after: True +changes: + - spellcheck: "fixed some typos in the weapon firing mechanism description" diff --git a/html/changelogs/AutoChangeLog-pr-4198.yml b/html/changelogs/AutoChangeLog-pr-4198.yml new file mode 100644 index 0000000000..93e2f2212a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4198.yml @@ -0,0 +1,5 @@ +author: "Xhuis" +delete-after: True +changes: + - rscadd: "Light fixtures now turn an ominous, dim red color when they lose power, and draw from an internal power cell to maintain it until either the cell dies (usually after 10 minutes) or power is restored." + - rscadd: "You can override emergency light functionality from an APC. You can also click on individual lights as a cyborg or AI to override them individually. Traitor AIs also have a new ability that disables emergency lights across the entire station." diff --git a/html/changelogs/AutoChangeLog-pr-4200.yml b/html/changelogs/AutoChangeLog-pr-4200.yml new file mode 100644 index 0000000000..a2321590c7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4200.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "You can now lay (buckle!) yourself to a bed to avoid being burnt to a crisp during \"the floor is lava\" event." diff --git a/html/changelogs/AutoChangeLog-pr-4201.yml b/html/changelogs/AutoChangeLog-pr-4201.yml new file mode 100644 index 0000000000..127a8b26ed --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4201.yml @@ -0,0 +1,4 @@ +author: "Robustin" +delete-after: True +changes: + - tweak: "Igniting plasma statues no longer ignores ignition temperature and only creates as much plasma as was used in its creation." diff --git a/html/changelogs/AutoChangeLog-pr-4207.yml b/html/changelogs/AutoChangeLog-pr-4207.yml new file mode 100644 index 0000000000..692dca99ed --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4207.yml @@ -0,0 +1,4 @@ +author: "Xhuis" +delete-after: True +changes: + - bugfix: "You now need fuel in your welder to repair mechs." diff --git a/html/changelogs/AutoChangeLog-pr-4209.yml b/html/changelogs/AutoChangeLog-pr-4209.yml new file mode 100644 index 0000000000..ee1613d170 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4209.yml @@ -0,0 +1,5 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "You can now record and replay holopad messages using holodisks." + - rscadd: "Holodisks are printable in autolathes." diff --git a/html/changelogs/AutoChangeLog-pr-4215.yml b/html/changelogs/AutoChangeLog-pr-4215.yml new file mode 100644 index 0000000000..6e4fe16805 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4215.yml @@ -0,0 +1,4 @@ +author: "Dax Dupont" +delete-after: True +changes: + - rscadd: "Nanotrasen is happy to announce the pinnacle in plasma research! The Disco Inferno shuttle design is the result of decades of plasma research. Burn, baby, burn!" diff --git a/html/changelogs/AutoChangeLog-pr-4216.yml b/html/changelogs/AutoChangeLog-pr-4216.yml new file mode 100644 index 0000000000..8b39d4aa94 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4216.yml @@ -0,0 +1,4 @@ +author: "Xhuis" +delete-after: True +changes: + - tweak: "Stethoscopes now inform the user if the target can be defibrillated; the user will hear a \"faint, fluttery pulse.\"" diff --git a/html/changelogs/AutoChangeLog-pr-4218.yml b/html/changelogs/AutoChangeLog-pr-4218.yml new file mode 100644 index 0000000000..334c16e021 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4218.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - spellcheck: "Energy values are now measured in joules. What was previously 1 unit is now 1 kJ." diff --git a/html/changelogs/AutoChangeLog-pr-4220.yml b/html/changelogs/AutoChangeLog-pr-4220.yml new file mode 100644 index 0000000000..7287bee043 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4220.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - sounddel: "Reduced the volume of showers" diff --git a/html/changelogs/AutoChangeLog-pr-4234.yml b/html/changelogs/AutoChangeLog-pr-4234.yml new file mode 100644 index 0000000000..3310bdb750 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4234.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "Syndicate uplink implants now work again." diff --git a/html/changelogs/AutoChangeLog-pr-4235.yml b/html/changelogs/AutoChangeLog-pr-4235.yml new file mode 100644 index 0000000000..35197c0edf --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4235.yml @@ -0,0 +1,4 @@ +author: "Robustin" +delete-after: True +changes: + - rscdel: "Reverted changes in 3d sound system that tripled the distance that sound would carry." diff --git a/html/changelogs/AutoChangeLog-pr-4240.yml b/html/changelogs/AutoChangeLog-pr-4240.yml new file mode 100644 index 0000000000..bb77fc8cd8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4240.yml @@ -0,0 +1,5 @@ +author: "coiax" +delete-after: True +changes: + - rscadd: "Quiet areas of libraries on station have now been equipped with a +vending machine containing suitable recreational activities." diff --git a/html/changelogs/AutoChangeLog-pr-4241.yml b/html/changelogs/AutoChangeLog-pr-4241.yml new file mode 100644 index 0000000000..77a17bb5b1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4241.yml @@ -0,0 +1,5 @@ +author: "coiax" +delete-after: True +changes: + - rscadd: "The drone dispenser on Metastation has been moved to the +maintenance by Robotics." diff --git a/html/changelogs/AutoChangeLog-pr-4243.yml b/html/changelogs/AutoChangeLog-pr-4243.yml new file mode 100644 index 0000000000..4971528f94 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4243.yml @@ -0,0 +1,4 @@ +author: "Revenant Defile ability" +delete-after: True +changes: + - bugfix: "Revenant's Defile now removes salt piles" diff --git a/html/changelogs/AutoChangeLog-pr-4244.yml b/html/changelogs/AutoChangeLog-pr-4244.yml new file mode 100644 index 0000000000..d1081a8801 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4244.yml @@ -0,0 +1,4 @@ +author: "Dax Dupont & Alek2ander" +delete-after: True +changes: + - tweak: "Binary chat messages been made more visible." diff --git a/html/changelogs/AutoChangeLog-pr-4246.yml b/html/changelogs/AutoChangeLog-pr-4246.yml new file mode 100644 index 0000000000..555f050d39 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4246.yml @@ -0,0 +1,16 @@ +author: "XDTM" +delete-after: True +changes: + - rscadd: "Brain damage has been completely reworked! +remove: Brain damage now no longer simply makes you dumb. Although most of its effects have been shifted into a brain trauma." + - rscadd: "Every time you take brain damage, there's a chance you'll suffer a brain trauma. There are many variations of brain traumas, split in mild, severe, and special." + - rscadd: "Mild brain traumas are the easiest to get, can be lightly to moderately annoying, and can be cured with mannitol and time." + - rscadd: "Severe brain traumas are much rarer and require extensive brain damage before you have a chance to get them; they are usually very debilitating. Unlike mild traumas, they require surgery to cure. A new surgery procedure has been added for this, the aptly named Brain Surgery. It can also heal minor traumas." + - rscadd: "Special brain traumas are rarely gained in place of Severe traumas: they are either complex or beneficial. +However, they are also even easier to cure than mild traumas, which means that keeping these will usually mean keeping a mild trauma along with it." + - rscadd: "Mobs can only naturally have one mild trauma and one severe or special trauma." + - balance: "Brain damage will now kill and ruin the brain if it goes above 200. If it somehow goes above 400, the brain will melt and be destroyed completely." + - balance: "Many brain-damaging effects have been given a damage cap, making them non-lethal." + - rscdel: "The Unintelligible mutation has been removed and made into a brain trauma." + - rscdel: "Brain damage no longer makes using machines a living hell." + - rscadd: "Abductors give minor traumas to people they experiment on." diff --git a/html/changelogs/AutoChangeLog-pr-4250.yml b/html/changelogs/AutoChangeLog-pr-4250.yml new file mode 100644 index 0000000000..7539b323a8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4250.yml @@ -0,0 +1,16 @@ +author: "Xhuis" +delete-after: True +changes: + - rscadd: "Added the Eminence role to clockcult! Players can elect themselves or ghosts as the Eminence from the eminence spire structure on Reebe." + - rscadd: "The Eminence is incorporeal and invisible, and directs the entire cult. Anything they say is heard over the Hierophant network, and they can issue commands by middle-clicking themselves or different turfs." + - rscadd: "The Eminence also has a single-use mass recall that warps all servants to the Ark chamber." + - rscadd: "Added traps, triggers, and brass filaments to link them. They can all be constructed from brass sheets, and do different things and trigger in different ways. Current traps include the brass skewer and steam vent, and triggers include the pressure sensor, lever, and repeater." + - rscadd: "The Eminence can activate trap triggers by clicking on them!" + - rscadd: "Servants can deconstruct traps instantly with a wrench." + - rscdel: "Mending Mantra has been removed." + - tweak: "Clockwork scriptures have been recolored and sorted based on their functions; yellow scriptures are for construction, red for offense, blue for defense, and purple for niche." + - balance: "Servants now spawn with a PDA and black shoes to make disguise more feasible." + - balance: "The Eminence can superheat up to 20 clockwork walls at a time. Superheated walls are immune to hulk and mech punches, but can still be broken conventionally." + - balance: "Clockwork walls are slightly faster to build before the Ark activates, taking an extra second less." + - bugfix: "Poly no longer continually undergoes binary fission when Ratvar is in range." + - code_imp: "The global records alert for servants will no longer display info that doesn't affect them since the rework." diff --git a/html/changelogs/AutoChangeLog-pr-4254.yml b/html/changelogs/AutoChangeLog-pr-4254.yml new file mode 100644 index 0000000000..cdfa4c7c0b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4254.yml @@ -0,0 +1,6 @@ +author: "ShizCalev" +delete-after: True +changes: + - bugfix: "Games vending machines can now properly be rebuilt." + - bugfix: "Games vending machines can now be refilled via supply crates." + - rscadd: "Games Supply Crates have been added to the cargo console." diff --git a/html/changelogs/AutoChangeLog-pr-4259.yml b/html/changelogs/AutoChangeLog-pr-4259.yml new file mode 100644 index 0000000000..7536cfa7a6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4259.yml @@ -0,0 +1,5 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "Action buttons now remember positions where you locked." + - tweak: "Now locking action buttons prevents them from being reset." diff --git a/html/changelogs/AutoChangeLog-pr-4260.yml b/html/changelogs/AutoChangeLog-pr-4260.yml new file mode 100644 index 0000000000..1880edb973 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4260.yml @@ -0,0 +1,4 @@ +author: "Xhuis" +delete-after: True +changes: + - rscadd: "You can now make pet carriers from the autolathe, to carry around chef meat and other small animals without having to drag them. The HoP, captain, and CMO also start with carriers in their lockers for their pets." diff --git a/html/changelogs/AutoChangeLog-pr-4261.yml b/html/changelogs/AutoChangeLog-pr-4261.yml new file mode 100644 index 0000000000..d7b0bcebf5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4261.yml @@ -0,0 +1,4 @@ +author: "Fox McCloud" +delete-after: True +changes: + - tweak: "Slime blueprints can now make an area compatible with Xenobio consoles, regardless of the name of the new area" diff --git a/html/changelogs/AutoChangeLog-pr-4264.yml b/html/changelogs/AutoChangeLog-pr-4264.yml new file mode 100644 index 0000000000..3a3b5c1f42 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4264.yml @@ -0,0 +1,5 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "You now can get a medal for wasting hours talking to the secret debug tile." + - bugfix: "Fixed runtime for the tile when poly's speech file doesn't exist." diff --git a/html/changelogs/AutoChangeLog-pr-4266.yml b/html/changelogs/AutoChangeLog-pr-4266.yml new file mode 100644 index 0000000000..e66348d5b4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4266.yml @@ -0,0 +1,5 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "Fixed the camera failure, race swap, cursed items, and imposter wizard random events" + - tweak: "The cursed items event no longer nullspaces items" diff --git a/html/changelogs/AutoChangeLog-pr-4267.yml b/html/changelogs/AutoChangeLog-pr-4267.yml new file mode 100644 index 0000000000..97e3a17b9a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4267.yml @@ -0,0 +1,4 @@ +author: "MrDoomBringer" +delete-after: True +changes: + - imageadd: "All stations have been outfitted with brand new Smoke Machines! They have nicer sprites now!" diff --git a/html/changelogs/AutoChangeLog-pr-4270.yml b/html/changelogs/AutoChangeLog-pr-4270.yml new file mode 100644 index 0000000000..06c99c93ee --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4270.yml @@ -0,0 +1,4 @@ +author: "deathride58" +delete-after: True +changes: + - config: "The default view range can now be defined in the config. The default is 15x15, which is simplified to 7 by BYOND. For reference, Goonstation's widescreen range is 21x15. Do note that changing this value will affect the title screen. The title screen images and the title screen area on the Centcom z-level will have to be updated if the default view range is changed." diff --git a/html/changelogs/AutoChangeLog-pr-4272.yml b/html/changelogs/AutoChangeLog-pr-4272.yml new file mode 100644 index 0000000000..8bedafab45 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4272.yml @@ -0,0 +1,5 @@ +author: "coiax" +delete-after: True +changes: + - rscadd: "The drone dispenser on Box Station has been moved from the Testing +Lab to the Morgue/Robotics maintenance tunnel." diff --git a/html/changelogs/AutoChangeLog-pr-4274.yml b/html/changelogs/AutoChangeLog-pr-4274.yml new file mode 100644 index 0000000000..b1915f089b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4274.yml @@ -0,0 +1,4 @@ +author: "Dax Dupont" +delete-after: True +changes: + - bugfix: "Fixed observer chat flavor of silicon chat." diff --git a/html/changelogs/AutoChangeLog-pr-4279.yml b/html/changelogs/AutoChangeLog-pr-4279.yml new file mode 100644 index 0000000000..cddc887068 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4279.yml @@ -0,0 +1,4 @@ +author: "Dax Dupont" +delete-after: True +changes: + - bugfix: "Grilles now no longer revert to a pre-broken icon state when you hit them after they broke." diff --git a/html/changelogs/AutoChangeLog-pr-4283.yml b/html/changelogs/AutoChangeLog-pr-4283.yml new file mode 100644 index 0000000000..a96b866609 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4283.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - tweak: "The pAI software interface is now accessible via an action button." diff --git a/html/changelogs/AutoChangeLog-pr-4286.yml b/html/changelogs/AutoChangeLog-pr-4286.yml new file mode 100644 index 0000000000..83ede8f21d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4286.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "External airlocks of the mining base and gulag are now cycle-linked." diff --git a/html/changelogs/AutoChangeLog-pr-4287.yml b/html/changelogs/AutoChangeLog-pr-4287.yml new file mode 100644 index 0000000000..55bbeb05c2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4287.yml @@ -0,0 +1,4 @@ +author: "XDTM" +delete-after: True +changes: + - tweak: "Instead of activating randomly on speech, Godwoken Syndrome randomly grants inspiration, causing the next message to be a Voice of God." diff --git a/html/changelogs/AutoChangeLog-pr-4289.yml b/html/changelogs/AutoChangeLog-pr-4289.yml new file mode 100644 index 0000000000..d0da6e0f58 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4289.yml @@ -0,0 +1,5 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "Nanotrasen would like to remind crewmembers and especially medical personnel to stand clear of cadeavers before applying a defibrillator shock. (You get shocked if you're pulling/grabbing someone being defibbed.)" + - tweak: "defib shock/charge sounds upped from 50% to 75%." diff --git a/html/changelogs/AutoChangeLog-pr-4290.yml b/html/changelogs/AutoChangeLog-pr-4290.yml new file mode 100644 index 0000000000..a7a034433f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4290.yml @@ -0,0 +1,4 @@ +author: "Swindly" +delete-after: True +changes: + - rscadd: "You can kill yourself with a few more items." diff --git a/html/changelogs/AutoChangeLog-pr-4292.yml b/html/changelogs/AutoChangeLog-pr-4292.yml new file mode 100644 index 0000000000..14dda4b668 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4292.yml @@ -0,0 +1,4 @@ +author: "Xhuis" +delete-after: True +changes: + - tweak: "Flickering lights will now actually flicker and not go between emergency lights and normal lighting." diff --git a/html/changelogs/AutoChangeLog-pr-4296.yml b/html/changelogs/AutoChangeLog-pr-4296.yml new file mode 100644 index 0000000000..1e87a3fdaf --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4296.yml @@ -0,0 +1,4 @@ +author: "Xhuis" +delete-after: True +changes: + - bugfix: "Emergency lights no longer stay on forever in some cases." diff --git a/html/changelogs/AutoChangeLog-pr-4305.yml b/html/changelogs/AutoChangeLog-pr-4305.yml new file mode 100644 index 0000000000..d6ae57f28d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4305.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "The MULEbots that the station starts with now show their ID numbers." diff --git a/html/changelogs/AutoChangeLog-pr-4306.yml b/html/changelogs/AutoChangeLog-pr-4306.yml new file mode 100644 index 0000000000..0a6361f11d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4306.yml @@ -0,0 +1,4 @@ +author: "Improvedname" +delete-after: True +changes: + - tweak: "cats now drop their ears and tail when butchered." diff --git a/html/changelogs/AutoChangeLog-pr-4308.yml b/html/changelogs/AutoChangeLog-pr-4308.yml new file mode 100644 index 0000000000..5f277e0e53 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4308.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "Booze-o-mats have beer" diff --git a/html/changelogs/AutoChangeLog-pr-4312.yml b/html/changelogs/AutoChangeLog-pr-4312.yml new file mode 100644 index 0000000000..8c05f5d79e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4312.yml @@ -0,0 +1,4 @@ +author: "Robustin" +delete-after: True +changes: + - bugfix: "Modes not in rotation have had their \"false report\" weights for the Command Report standardized" diff --git a/html/changelogs/AutoChangeLog-pr-4313.yml b/html/changelogs/AutoChangeLog-pr-4313.yml new file mode 100644 index 0000000000..a1124c765a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4313.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - tweak: "The white ship navigation computer now takes 10 seconds to designate a landing spot, and users can no longer see the syndicate shuttle or its custom landing location. If the white ship landing location would intersect the syndicate shuttle or its landing location, it will fail after the 10 seconds have elapsed." diff --git a/html/changelogs/AutoChangeLog-pr-4314.yml b/html/changelogs/AutoChangeLog-pr-4314.yml new file mode 100644 index 0000000000..e471271981 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4314.yml @@ -0,0 +1,7 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "flightsuits should no longer disappear when you take them off involuntarily" + - bugfix: "beam rifles actually fire striaght now" + - bugfix: "click catchers now actually work" + - bugfix: "you no longer see space in areas you normally can't see, instead of black. in reality you can still see space but it's faint enough that you can't tell so I'll say I fixed it." diff --git a/html/changelogs/AutoChangeLog-pr-4315.yml b/html/changelogs/AutoChangeLog-pr-4315.yml new file mode 100644 index 0000000000..a021f0ccc4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4315.yml @@ -0,0 +1,10 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "Added MANY new types of airlock assembly that can be built with metal. Use metal in hand to see the new airlock assembly recipes." + - rscadd: "Added new airlock types to the RCD and airlock painter" + - rscadd: "Vault door assemblies can be built with 8 plasteel, high security assemblies with 6 plasteel" + - rscadd: "Glass mineral airlocks are finally constructible. Use glass and mineral sheets on an airlock assembly in any order to make them." + - tweak: "Glass and mineral sheets are now able to be welded out of door assemblies rather than having to deconstruct the whole thing" + - rscdel: "Airlock painter no longer works on airlock assemblies (still works on airlocks)" + - bugfix: "Titanium airlocks no longer have any missing overlays" diff --git a/html/changelogs/AutoChangeLog-pr-4319.yml b/html/changelogs/AutoChangeLog-pr-4319.yml new file mode 100644 index 0000000000..851d5f12bc --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4319.yml @@ -0,0 +1,4 @@ +author: "Frozenguy5" +delete-after: True +changes: + - balance: "Some hardsuits have had their melee, fire and rad armor ratings tweaked." diff --git a/html/changelogs/AutoChangeLog-pr-4331.yml b/html/changelogs/AutoChangeLog-pr-4331.yml new file mode 100644 index 0000000000..04532aa4a8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4331.yml @@ -0,0 +1,4 @@ +author: "Swindly" +delete-after: True +changes: + - bugfix: "Swarmers can no longer deconstruct objects with living things in them." diff --git a/html/changelogs/AutoChangeLog-pr-4338.yml b/html/changelogs/AutoChangeLog-pr-4338.yml new file mode 100644 index 0000000000..da4fde1e23 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4338.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "You can now print telecomms equipment again." diff --git a/html/changelogs/AutoChangeLog-pr-4339.yml b/html/changelogs/AutoChangeLog-pr-4339.yml new file mode 100644 index 0000000000..bf7c49d3e8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4339.yml @@ -0,0 +1,5 @@ +author: "Robustin" +delete-after: True +changes: + - rscadd: "The blood cult revive rune will now replace the souls of braindead or inactive cultists/constructs when properly invoked. These \"revivals\" will not count toward the revive limit." + - rscadd: "The clock cult healing rune will now replace the souls of braindead or inactive cultists/constructs when left atop the rune. These \"revivals\" will not drain the rune's energy." diff --git a/html/changelogs/AutoChangeLog-pr-4340.yml b/html/changelogs/AutoChangeLog-pr-4340.yml new file mode 100644 index 0000000000..6992dc2fd8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4340.yml @@ -0,0 +1,4 @@ +author: "deathride58" +delete-after: True +changes: + - bugfix: "fixes mobs not metabolizing their reagents" diff --git a/html/changelogs/AutoChangeLog-pr-4341.yml b/html/changelogs/AutoChangeLog-pr-4341.yml new file mode 100644 index 0000000000..e276d3bcb8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4341.yml @@ -0,0 +1,4 @@ +author: "Mark9013100" +delete-after: True +changes: + - rscadd: "Medical Wardrobes now contain an additional standard and EMT labcoat." diff --git a/html/changelogs/AutoChangeLog-pr-4344.yml b/html/changelogs/AutoChangeLog-pr-4344.yml new file mode 100644 index 0000000000..a020f7882f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4344.yml @@ -0,0 +1,4 @@ +author: "deathride58" +delete-after: True +changes: + - bugfix: "Donator items use the proper sprites when worn again." diff --git a/html/changelogs/AutoChangeLog-pr-4346.yml b/html/changelogs/AutoChangeLog-pr-4346.yml new file mode 100644 index 0000000000..d03954b91f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4346.yml @@ -0,0 +1,4 @@ +author: "deathride58" +delete-after: True +changes: + - bugfix: "The standard-issue PDAs are now holographic again." diff --git a/html/changelogs/AutoChangeLog-pr-4349.yml b/html/changelogs/AutoChangeLog-pr-4349.yml new file mode 100644 index 0000000000..3f1bb91439 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4349.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "Nonstandard power cells found in MULEbots, cyborgs, and elsewhere now have the correct description." diff --git a/html/changelogs/AutoChangeLog-pr-4350.yml b/html/changelogs/AutoChangeLog-pr-4350.yml new file mode 100644 index 0000000000..2116fa9fd5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4350.yml @@ -0,0 +1,4 @@ +author: "deathride58" +delete-after: True +changes: + - bugfix: "Genetics will no longer have a random block completely disappear each round" diff --git a/html/changelogs/AutoChangeLog-pr-4351.yml b/html/changelogs/AutoChangeLog-pr-4351.yml new file mode 100644 index 0000000000..bc5cabdb55 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4351.yml @@ -0,0 +1,4 @@ +author: "Naksu" +delete-after: True +changes: + - bugfix: "glass shards and bananium floors no longer make a sound when \"walked\" over by a camera or a ghost" diff --git a/html/changelogs/AutoChangeLog-pr-4353.yml b/html/changelogs/AutoChangeLog-pr-4353.yml new file mode 100644 index 0000000000..6fcf3e2ebe --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4353.yml @@ -0,0 +1,7 @@ +author: "deathride58" +delete-after: True +changes: + - rscadd: "All maps now have departmental lathes as they're supposed to." + - rscadd: "Pubbystation and Omegastation now have kinkmates! This does not add them back to the rotation, though. Tell Jay to re-enable Pubby and Omega in the server's config." + - rscadd: "Omegastation's dorms now have bolt buttons." + - bugfix: "The table in the back of Boxstation's maint bar gambling area will no longer throw people around." diff --git a/html/changelogs/AutoChangeLog-pr-4354.yml b/html/changelogs/AutoChangeLog-pr-4354.yml new file mode 100644 index 0000000000..e9aa1f0f2b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4354.yml @@ -0,0 +1,4 @@ +author: "Naksu" +delete-after: True +changes: + - code_imp: "Tidied up some loc assignments" diff --git a/html/changelogs/AutoChangeLog-pr-4359.yml b/html/changelogs/AutoChangeLog-pr-4359.yml new file mode 100644 index 0000000000..6679e4b920 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4359.yml @@ -0,0 +1,5 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - server: "Added new admin flag, AUTOLOGIN, to control if admins start with admin powers. this defaults to on, and can be removed with -AUTOLOGIN" + - admin: "Admins with +PERMISSION may now deadmin or readmin other admins via the permission panel." diff --git a/html/changelogs/AutoChangeLog-pr-4361.yml b/html/changelogs/AutoChangeLog-pr-4361.yml new file mode 100644 index 0000000000..140a9a4fe3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4361.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "Shuttles now place hyperspace ripples where they are about to land again." diff --git a/html/changelogs/AutoChangeLog-pr-4363.yml b/html/changelogs/AutoChangeLog-pr-4363.yml new file mode 100644 index 0000000000..fda81eb42b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4363.yml @@ -0,0 +1,5 @@ +author: "JStheguy" +delete-after: True +changes: + - rscadd: "Added 10 new assembly designs to the integrated circuit printer, the difference from current designs is purely aesthetics." + - imageadd: "Added the icons for said new assembly designs to electronic_setups.dmi, changed the current electronic mechanism and electronic machine sprites." diff --git a/html/changelogs/AutoChangeLog-pr-4365.yml b/html/changelogs/AutoChangeLog-pr-4365.yml new file mode 100644 index 0000000000..165bb4d0df --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4365.yml @@ -0,0 +1,4 @@ +author: "Epoc" +delete-after: True +changes: + - bugfix: "Adds Cybernetic Lungs to the Cyber Organs research node" diff --git a/html/changelogs/AutoChangeLog-pr-4372.yml b/html/changelogs/AutoChangeLog-pr-4372.yml new file mode 100644 index 0000000000..7c1aa4b97c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4372.yml @@ -0,0 +1,5 @@ +author: "ShizCalev" +delete-after: True +changes: + - soundadd: "Revamped gun dry-firing sounds." + - tweak: "Everyone around you will now hear when your gun goes click. You don't want to hear click when you want to hear bang!" diff --git a/html/changelogs/AutoChangeLog-pr-4375.yml b/html/changelogs/AutoChangeLog-pr-4375.yml new file mode 100644 index 0000000000..2cf7f4c721 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4375.yml @@ -0,0 +1,4 @@ +author: "Naksu" +delete-after: True +changes: + - code_imp: "fixes the remaining loc assignments" diff --git a/html/changelogs/AutoChangeLog-pr-4377.yml b/html/changelogs/AutoChangeLog-pr-4377.yml new file mode 100644 index 0000000000..5234e24f49 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4377.yml @@ -0,0 +1,7 @@ +author: "Xhuis" +delete-after: True +changes: + - rscadd: "Grinding runed metal and brass now produces iron/blood and iron/teslium, respectively." + - balance: "As part of some code-side improvements, the amount of reagents you get from grinding some objects might be slightly different." + - bugfix: "Some grinding recipes that didn't work, like dead mice and glowsticks, now do." + - bugfix: "All-In-One grinders now correctly grind up everything, instead of one thing at a time." diff --git a/html/changelogs/AutoChangeLog-pr-4378.yml b/html/changelogs/AutoChangeLog-pr-4378.yml new file mode 100644 index 0000000000..22ea638655 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4378.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - imageadd: "Closet sprites changed." diff --git a/html/changelogs/AutoChangeLog-pr-4382.yml b/html/changelogs/AutoChangeLog-pr-4382.yml new file mode 100644 index 0000000000..64568eb274 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4382.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - config: "Added \"$include\" directives to config files. These are recursive. Only config.txt will be default loaded if they are specified inside it" diff --git a/html/changelogs/AutoChangeLog-pr-4383.yml b/html/changelogs/AutoChangeLog-pr-4383.yml new file mode 100644 index 0000000000..cf9c743a03 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4383.yml @@ -0,0 +1,4 @@ +author: "Naksu" +delete-after: True +changes: + - code_imp: "Preliminary work on tracking cliented living mobs across Z-levels to facilitate mob AI changes later" diff --git a/html/changelogs/AutoChangeLog-pr-4384.yml b/html/changelogs/AutoChangeLog-pr-4384.yml new file mode 100644 index 0000000000..d7f2f90350 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4384.yml @@ -0,0 +1,4 @@ +author: "EtheoBoxxman" +delete-after: True +changes: + - rscdel: "Removed chasm that spawns on killing ash walker tendril" diff --git a/html/changelogs/AutoChangeLog-pr-4389.yml b/html/changelogs/AutoChangeLog-pr-4389.yml new file mode 100644 index 0000000000..36f17b95de --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4389.yml @@ -0,0 +1,4 @@ +author: "Toriate" +delete-after: True +changes: + - tweak: "NEBs now consistently alt click to recolor" diff --git a/html/changelogs/AutoChangeLog-pr-4390.yml b/html/changelogs/AutoChangeLog-pr-4390.yml new file mode 100644 index 0000000000..89d3683a34 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4390.yml @@ -0,0 +1,5 @@ +author: "AverageJoe82" +delete-after: True +changes: + - rscadd: "drones now have night vision" + - rscdel: "drones no longer have lights" diff --git a/html/changelogs/AutoChangeLog-pr-4394.yml b/html/changelogs/AutoChangeLog-pr-4394.yml new file mode 100644 index 0000000000..68d57a2d11 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4394.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "The shuttle will no longer be autocalled if the round has already ended." diff --git a/html/changelogs/AutoChangeLog-pr-4412.yml b/html/changelogs/AutoChangeLog-pr-4412.yml new file mode 100644 index 0000000000..6280189218 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4412.yml @@ -0,0 +1,4 @@ +author: "Xhuis" +delete-after: True +changes: + - tweak: "Vitality matrices don't have visible messages when someone crosses them anymore." diff --git a/html/changelogs/AutoChangeLog-pr-4416.yml b/html/changelogs/AutoChangeLog-pr-4416.yml new file mode 100644 index 0000000000..543fe52edd --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4416.yml @@ -0,0 +1,4 @@ +author: "Robustin" +delete-after: True +changes: + - bugfix: "The wizard event \"race swap\" should now stick to \"safer\" species." diff --git a/html/changelogs/AutoChangeLog-pr-4417.yml b/html/changelogs/AutoChangeLog-pr-4417.yml new file mode 100644 index 0000000000..46b7019353 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4417.yml @@ -0,0 +1,4 @@ +author: "Xhuis" +delete-after: True +changes: + - bugfix: "Clockcult power alerts will no longer show outside of the clockcult gamemode (they could be triggered by scarabs.)" diff --git a/html/changelogs/AutoChangeLog-pr-4420.yml b/html/changelogs/AutoChangeLog-pr-4420.yml new file mode 100644 index 0000000000..305d701c7f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4420.yml @@ -0,0 +1,10 @@ +author: "XDTM" +delete-after: True +changes: + - rscadd: "A few new traumas have been added." + - balance: "Thresholds to get brain traumas have been lowered, as they currently pretty much only trigger if you intentionally chug impedrezene." + - tweak: "Melee head hits deal minor brain damage. Crits still do a significant amount." + - tweak: "Nuke Op implants no longer trigger on deathgasp. (They still explode on death)" + - tweak: "You'll now receive messages when crossing certain brain damage thresholds." + - tweak: "Split Personalities are instructed not to suicide while in control." + - tweak: "Godwoken Syndrome now randomly sends Voice of God commands, instead of being controllable." diff --git a/html/changelogs/AutoChangeLog-pr-4433.yml b/html/changelogs/AutoChangeLog-pr-4433.yml new file mode 100644 index 0000000000..39bde17139 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4433.yml @@ -0,0 +1,4 @@ +author: "ninjanomnom" +delete-after: True +changes: + - bugfix: "Decals should now rotate the correct way around." diff --git a/html/changelogs/AutoChangeLog-pr-4437.yml b/html/changelogs/AutoChangeLog-pr-4437.yml new file mode 100644 index 0000000000..9b11b0912e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4437.yml @@ -0,0 +1,4 @@ +author: "nicbn" +delete-after: True +changes: + - bugfix: "Now the chem smoke machine uses stock parts for volume and range." diff --git a/html/changelogs/AutoChangeLog-pr-4442.yml b/html/changelogs/AutoChangeLog-pr-4442.yml new file mode 100644 index 0000000000..e480e91419 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4442.yml @@ -0,0 +1,8 @@ +author: "XDTM" +delete-after: True +changes: + - rscadd: "Abductors can now see if people already have glands! Never worry about abducting the same guy twice again." + - rscadd: "Added the Mind Interface Device to the abductor shop for 2 Credits. Only scientists can use it." + - rscadd: "The MID has two modes: Transmit and Control." + - rscadd: "Transmit will allow you to send a message anytime, anywhere to the mind of a target of your choice, regardless of language barriers. The message will be anonymous, but abductor-like." + - rscadd: "Control allows you to give a temporary directive to a target with an implanted gland, that they MUST follow. Duration and amount of uses varies by gland type. When a gland is spent, it will no longer respond to Control signals. The target forgets ever receiving the objective when the duration ends." diff --git a/html/changelogs/AutoChangeLog-pr-4445.yml b/html/changelogs/AutoChangeLog-pr-4445.yml new file mode 100644 index 0000000000..6dd7a7e486 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4445.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "Fixed captain's PDA showing unusable Toggle Remote Door menu option" diff --git a/html/changelogs/AutoChangeLog-pr-4446.yml b/html/changelogs/AutoChangeLog-pr-4446.yml new file mode 100644 index 0000000000..3811f7ffb7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4446.yml @@ -0,0 +1,5 @@ +author: "coiax" +delete-after: True +changes: + - balance: "The codespeak manual now has unlimited uses and costs 3 TC." + - bugfix: "Nuke ops can now purchase the codespeak manual, as was intended." diff --git a/html/changelogs/AutoChangeLog-pr-4453.yml b/html/changelogs/AutoChangeLog-pr-4453.yml new file mode 100644 index 0000000000..24bce9c510 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4453.yml @@ -0,0 +1,4 @@ +author: "coiax" +delete-after: True +changes: + - rscadd: "A changeling will learn all languages from anyone they absorb." diff --git a/html/changelogs/AutoChangeLog-pr-4458.yml b/html/changelogs/AutoChangeLog-pr-4458.yml new file mode 100644 index 0000000000..4e51890691 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4458.yml @@ -0,0 +1,4 @@ +author: "XDTM" +delete-after: True +changes: + - tweak: "The Disease Outbreak event now can generate random advanced viruses, with more symptoms and higher level as round time goes on." diff --git a/html/changelogs/AutoChangeLog-pr-4464.yml b/html/changelogs/AutoChangeLog-pr-4464.yml new file mode 100644 index 0000000000..17f7d8fc07 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4464.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "You can enforce no smoking zones with a disarm aimed at the smokers mouth." diff --git a/html/changelogs/AutoChangeLog-pr-4466.yml b/html/changelogs/AutoChangeLog-pr-4466.yml new file mode 100644 index 0000000000..e8239ebfb4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4466.yml @@ -0,0 +1,4 @@ +author: "Toriate" +delete-after: True +changes: + - balance: "Roundstart xenos are no longer pierce immune, also no more extra damage from heat." diff --git a/html/changelogs/AutoChangeLog-pr-4467.yml b/html/changelogs/AutoChangeLog-pr-4467.yml new file mode 100644 index 0000000000..ae009bf26f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4467.yml @@ -0,0 +1,4 @@ +author: "improvedname" +delete-after: True +changes: + - bugfix: "Corrects 357. speedloader in the autolathe" diff --git a/html/changelogs/AutoChangeLog-pr-4475.yml b/html/changelogs/AutoChangeLog-pr-4475.yml new file mode 100644 index 0000000000..f37e80ed55 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4475.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "Passing a space transition no longer interrupts pulls." diff --git a/html/changelogs/AutoChangeLog-pr-4477.yml b/html/changelogs/AutoChangeLog-pr-4477.yml new file mode 100644 index 0000000000..bba0dab724 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4477.yml @@ -0,0 +1,4 @@ +author: "Fox McCloud" +delete-after: True +changes: + - bugfix: "Fixes arm implants being immune to EMPs" diff --git a/html/changelogs/AutoChangeLog-pr-4479.yml b/html/changelogs/AutoChangeLog-pr-4479.yml new file mode 100644 index 0000000000..623a1ada72 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4479.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscdel: "Integrated circuit smoke circuits now require 10 units of reagents to fire." diff --git a/html/changelogs/AutoChangeLog-pr-4487.yml b/html/changelogs/AutoChangeLog-pr-4487.yml new file mode 100644 index 0000000000..588566e15c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4487.yml @@ -0,0 +1,4 @@ +author: "ganglyalexander" +delete-after: True +changes: + - bugfix: "module icons for dog borgs now reference to a existing icon" diff --git a/html/changelogs/AutoChangeLog-pr-4488.yml b/html/changelogs/AutoChangeLog-pr-4488.yml new file mode 100644 index 0000000000..21031f2cf3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4488.yml @@ -0,0 +1,5 @@ +author: "coiax" +delete-after: True +changes: + - rscadd: "At the end of the round, all players can see who the antagonists +are." diff --git a/html/changelogs/AutoChangeLog-pr-4490.yml b/html/changelogs/AutoChangeLog-pr-4490.yml new file mode 100644 index 0000000000..6477196745 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4490.yml @@ -0,0 +1,5 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "You can adjust line height in chat settings" + - tweak: "Default chat line height is slightly shorter, from 1.4 to 1.2" diff --git a/icons/effects/96x96.dmi b/icons/effects/96x96.dmi index 102fc01000..644d2a0860 100644 Binary files a/icons/effects/96x96.dmi and b/icons/effects/96x96.dmi differ diff --git a/icons/effects/clockwork_effects.dmi b/icons/effects/clockwork_effects.dmi index fa3bfa36e6..5d6082dc2b 100644 Binary files a/icons/effects/clockwork_effects.dmi and b/icons/effects/clockwork_effects.dmi differ diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index cb4b8f659e..3451915c09 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/icons/effects/vanguard_target.dmi b/icons/effects/vanguard_target.dmi index 73ba014e2d..5220c325e5 100644 Binary files a/icons/effects/vanguard_target.dmi and b/icons/effects/vanguard_target.dmi differ diff --git a/icons/emoji.dmi b/icons/emoji.dmi index 9d3e0630a7..b0434f431f 100644 Binary files a/icons/emoji.dmi and b/icons/emoji.dmi differ diff --git a/icons/misc/language.dmi b/icons/misc/language.dmi index f4894c2b90..4e627f16c7 100644 Binary files a/icons/misc/language.dmi and b/icons/misc/language.dmi differ diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi index 0255204f60..3a7b0648fd 100644 Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ diff --git a/icons/mob/actions/actions_AI.dmi b/icons/mob/actions/actions_AI.dmi index c6e4e1dae7..2ddc7923cc 100644 Binary files a/icons/mob/actions/actions_AI.dmi and b/icons/mob/actions/actions_AI.dmi differ diff --git a/icons/mob/actions/actions_animal.dmi b/icons/mob/actions/actions_animal.dmi index 1dcf7590cd..aefa471dd2 100644 Binary files a/icons/mob/actions/actions_animal.dmi and b/icons/mob/actions/actions_animal.dmi differ diff --git a/icons/mob/actions/actions_clockcult.dmi b/icons/mob/actions/actions_clockcult.dmi index 19fd68f836..4aad4ba569 100644 Binary files a/icons/mob/actions/actions_clockcult.dmi and b/icons/mob/actions/actions_clockcult.dmi differ diff --git a/icons/mob/actions/actions_vehicle.dmi b/icons/mob/actions/actions_vehicle.dmi new file mode 100644 index 0000000000..62b995ef9b Binary files /dev/null and b/icons/mob/actions/actions_vehicle.dmi differ diff --git a/icons/mob/aibots.dmi b/icons/mob/aibots.dmi index c6ee573913..873147c91c 100644 Binary files a/icons/mob/aibots.dmi and b/icons/mob/aibots.dmi differ diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi index b860bd8426..8504b18a4a 100644 Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi index 064fedb3df..89f0d9c3fe 100644 Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ diff --git a/icons/mob/custom_w.dmi b/icons/mob/custom_w.dmi new file mode 100644 index 0000000000..5b054472b2 Binary files /dev/null and b/icons/mob/custom_w.dmi differ diff --git a/icons/mob/feet.dmi b/icons/mob/feet.dmi index de8587dba5..2eab8fa78e 100644 Binary files a/icons/mob/feet.dmi and b/icons/mob/feet.dmi differ diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index 89eb9dbcbc..3aa655b574 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi index 0cdee31ae1..5e33807ec7 100644 Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ diff --git a/icons/mob/inhands/clothing_lefthand.dmi b/icons/mob/inhands/clothing_lefthand.dmi index 38c89769d2..76adebdc11 100644 Binary files a/icons/mob/inhands/clothing_lefthand.dmi and b/icons/mob/inhands/clothing_lefthand.dmi differ diff --git a/icons/mob/inhands/clothing_righthand.dmi b/icons/mob/inhands/clothing_righthand.dmi index c14fbb3fb2..a12053ae1d 100644 Binary files a/icons/mob/inhands/clothing_righthand.dmi and b/icons/mob/inhands/clothing_righthand.dmi differ diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index 198c2ee663..9a7b318e19 100644 Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi index cef6409ca2..9d9350e644 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/mob/lavaland/64x64megafauna.dmi b/icons/mob/lavaland/64x64megafauna.dmi index 7cc2b92a17..64304fdcd1 100644 Binary files a/icons/mob/lavaland/64x64megafauna.dmi and b/icons/mob/lavaland/64x64megafauna.dmi differ diff --git a/icons/mob/lavaland/lavaland_monsters.dmi b/icons/mob/lavaland/lavaland_monsters.dmi index f072421196..fd93db24aa 100644 Binary files a/icons/mob/lavaland/lavaland_monsters.dmi and b/icons/mob/lavaland/lavaland_monsters.dmi differ diff --git a/icons/mob/mask.dmi b/icons/mob/mask.dmi index 3854f252eb..e83588d5ed 100644 Binary files a/icons/mob/mask.dmi and b/icons/mob/mask.dmi differ diff --git a/icons/mob/neck.dmi b/icons/mob/neck.dmi index 17f9d3ade4..59635b8c7d 100644 Binary files a/icons/mob/neck.dmi and b/icons/mob/neck.dmi differ diff --git a/icons/mob/nest.dmi b/icons/mob/nest.dmi index 7dab335929..e75d325e8a 100644 Binary files a/icons/mob/nest.dmi and b/icons/mob/nest.dmi differ diff --git a/icons/mob/screen_cyborg.dmi b/icons/mob/screen_cyborg.dmi index e9fd4ed401..fc236ac7e2 100644 Binary files a/icons/mob/screen_cyborg.dmi and b/icons/mob/screen_cyborg.dmi differ diff --git a/icons/mob/screen_full.dmi b/icons/mob/screen_full.dmi index 988bf59592..502e9ad3f9 100644 Binary files a/icons/mob/screen_full.dmi and b/icons/mob/screen_full.dmi differ diff --git a/icons/mob/screen_gen.dmi b/icons/mob/screen_gen.dmi index 40500e84a8..5a088e451f 100644 Binary files a/icons/mob/screen_gen.dmi and b/icons/mob/screen_gen.dmi differ diff --git a/icons/mob/simple_human.dmi b/icons/mob/simple_human.dmi index f3345c0825..597ee94d72 100644 Binary files a/icons/mob/simple_human.dmi and b/icons/mob/simple_human.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index c251b93f2e..241db46d08 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 38edd8dc7d..5602b03f87 100644 Binary files a/icons/obj/abductor.dmi and b/icons/obj/abductor.dmi differ diff --git a/icons/obj/assemblies/electronic_components.dmi b/icons/obj/assemblies/electronic_components.dmi new file mode 100644 index 0000000000..1852079e73 Binary files /dev/null and b/icons/obj/assemblies/electronic_components.dmi differ diff --git a/icons/obj/assemblies/electronic_misc.dmi b/icons/obj/assemblies/electronic_misc.dmi new file mode 100644 index 0000000000..226b82e499 Binary files /dev/null and b/icons/obj/assemblies/electronic_misc.dmi differ diff --git a/icons/obj/assemblies/electronic_setups.dmi b/icons/obj/assemblies/electronic_setups.dmi new file mode 100644 index 0000000000..643d652be1 Binary files /dev/null and b/icons/obj/assemblies/electronic_setups.dmi differ diff --git a/icons/obj/assemblies/electronic_tools.dmi b/icons/obj/assemblies/electronic_tools.dmi new file mode 100644 index 0000000000..5c0b2faaa9 Binary files /dev/null and b/icons/obj/assemblies/electronic_tools.dmi differ diff --git a/icons/obj/atmospherics/components/thermomachine.dmi b/icons/obj/atmospherics/components/thermomachine.dmi new file mode 100644 index 0000000000..2ff9dac031 Binary files /dev/null and b/icons/obj/atmospherics/components/thermomachine.dmi differ diff --git a/icons/obj/atmospherics/pipes/large.dmi b/icons/obj/atmospherics/pipes/large.dmi deleted file mode 100644 index 77fb29e4de..0000000000 Binary files a/icons/obj/atmospherics/pipes/large.dmi and /dev/null differ diff --git a/icons/obj/atmospherics/pipes/meter.dmi b/icons/obj/atmospherics/pipes/meter.dmi new file mode 100644 index 0000000000..7eabdc9de8 Binary files /dev/null and b/icons/obj/atmospherics/pipes/meter.dmi differ diff --git a/icons/obj/atmospherics/pipes/simple.dmi b/icons/obj/atmospherics/pipes/simple.dmi index bc04b708c5..952e6499e3 100644 Binary files a/icons/obj/atmospherics/pipes/simple.dmi and b/icons/obj/atmospherics/pipes/simple.dmi differ diff --git a/icons/obj/bedsheets.dmi b/icons/obj/bedsheets.dmi index 17dc5b8fb2..d492ae52f6 100644 Binary files a/icons/obj/bedsheets.dmi and b/icons/obj/bedsheets.dmi differ diff --git a/icons/obj/biomass.dmi b/icons/obj/biomass.dmi deleted file mode 100644 index ffb133f768..0000000000 Binary files a/icons/obj/biomass.dmi and /dev/null differ diff --git a/icons/obj/bloodpack.dmi b/icons/obj/bloodpack.dmi index 423b5bb641..ac879aa33c 100644 Binary files a/icons/obj/bloodpack.dmi and b/icons/obj/bloodpack.dmi differ diff --git a/icons/obj/chemical.dmi b/icons/obj/chemical.dmi index 3507d9db53..367be13b3b 100644 Binary files a/icons/obj/chemical.dmi and b/icons/obj/chemical.dmi differ diff --git a/icons/obj/cigarettes.dmi b/icons/obj/cigarettes.dmi index ed8f37c4da..76ac7bd0a8 100644 Binary files a/icons/obj/cigarettes.dmi and b/icons/obj/cigarettes.dmi differ diff --git a/icons/obj/clockwork_objects.dmi b/icons/obj/clockwork_objects.dmi index 561359959b..784c0f55eb 100644 Binary files a/icons/obj/clockwork_objects.dmi and b/icons/obj/clockwork_objects.dmi differ diff --git a/icons/obj/closet.dmi b/icons/obj/closet.dmi index 3f3eda012c..1a89e7127c 100644 Binary files a/icons/obj/closet.dmi and b/icons/obj/closet.dmi differ diff --git a/icons/obj/clothing/accessories.dmi b/icons/obj/clothing/accessories.dmi index 4c3c0fe5ce..63c036ce14 100644 Binary files a/icons/obj/clothing/accessories.dmi and b/icons/obj/clothing/accessories.dmi differ diff --git a/icons/obj/clothing/cloaks.dmi b/icons/obj/clothing/cloaks.dmi index 993c037a05..dd1ae7d727 100644 Binary files a/icons/obj/clothing/cloaks.dmi and b/icons/obj/clothing/cloaks.dmi differ diff --git a/icons/obj/clothing/gloves.dmi b/icons/obj/clothing/gloves.dmi index 48f37887cf..6c193f1044 100644 Binary files a/icons/obj/clothing/gloves.dmi and b/icons/obj/clothing/gloves.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index 6ec16c836f..2a6d2004b3 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi index 786a8c7fd0..b1d7a7106d 100644 Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ diff --git a/icons/obj/clothing/neck.dmi b/icons/obj/clothing/neck.dmi index c41db68326..0f3668ce10 100644 Binary files a/icons/obj/clothing/neck.dmi and b/icons/obj/clothing/neck.dmi differ diff --git a/icons/obj/clothing/shoes.dmi b/icons/obj/clothing/shoes.dmi index 2cf675c571..77b62691d2 100644 Binary files a/icons/obj/clothing/shoes.dmi and b/icons/obj/clothing/shoes.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index d0326b1141..f44fc29f7c 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 cca6f3fa79..c1f91ff3c1 100644 Binary files a/icons/obj/custom.dmi and b/icons/obj/custom.dmi differ diff --git a/icons/obj/decals.dmi b/icons/obj/decals.dmi index 0669549b02..31e700d23d 100644 Binary files a/icons/obj/decals.dmi and b/icons/obj/decals.dmi differ diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index 876f747fc1..88aa6f7985 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ diff --git a/icons/obj/doors/airlocks/shuttle/overlays.dmi b/icons/obj/doors/airlocks/shuttle/overlays.dmi index 50b2e25d8f..b2bb2cfa04 100644 Binary files a/icons/obj/doors/airlocks/shuttle/overlays.dmi and b/icons/obj/doors/airlocks/shuttle/overlays.dmi differ diff --git a/icons/obj/doors/airlocks/station2/glass.dmi b/icons/obj/doors/airlocks/station2/glass.dmi index 94d7ed7429..e10efd4282 100644 Binary files a/icons/obj/doors/airlocks/station2/glass.dmi and b/icons/obj/doors/airlocks/station2/glass.dmi differ diff --git a/icons/obj/doors/airlocks/survival/survival.dmi b/icons/obj/doors/airlocks/survival/survival.dmi index b796b4c8e0..478834eb93 100644 Binary files a/icons/obj/doors/airlocks/survival/survival.dmi and b/icons/obj/doors/airlocks/survival/survival.dmi differ diff --git a/icons/obj/doors/airlocks/survival/survival_overlays.dmi b/icons/obj/doors/airlocks/survival/survival_overlays.dmi index 94c1a9fa34..f6b0d8eb69 100644 Binary files a/icons/obj/doors/airlocks/survival/survival_overlays.dmi and b/icons/obj/doors/airlocks/survival/survival_overlays.dmi differ diff --git a/icons/obj/electronic_assemblies.dmi b/icons/obj/electronic_assemblies.dmi deleted file mode 100644 index 8faa77ad02..0000000000 Binary files a/icons/obj/electronic_assemblies.dmi and /dev/null differ diff --git a/icons/obj/electronic_assemblies2.dmi b/icons/obj/electronic_assemblies2.dmi deleted file mode 100644 index 6cfb51affc..0000000000 Binary files a/icons/obj/electronic_assemblies2.dmi and /dev/null differ diff --git a/icons/obj/flora/_flora.dmi b/icons/obj/flora/_flora.dmi new file mode 100644 index 0000000000..d3e800576e Binary files /dev/null and b/icons/obj/flora/_flora.dmi differ diff --git a/icons/obj/grenade.dmi b/icons/obj/grenade.dmi index 7d413895ca..7f4d65e081 100644 Binary files a/icons/obj/grenade.dmi and b/icons/obj/grenade.dmi differ diff --git a/icons/obj/guns/bayonets.dmi b/icons/obj/guns/bayonets.dmi index 176005b7d7..32b5448b8e 100644 Binary files a/icons/obj/guns/bayonets.dmi and b/icons/obj/guns/bayonets.dmi differ diff --git a/icons/obj/hydroponics/equipment.dmi b/icons/obj/hydroponics/equipment.dmi index ad5f8bc863..3d125d68c7 100644 Binary files a/icons/obj/hydroponics/equipment.dmi and b/icons/obj/hydroponics/equipment.dmi differ diff --git a/icons/obj/items_and_weapons.dmi b/icons/obj/items_and_weapons.dmi index 636d895450..446b093167 100644 Binary files a/icons/obj/items_and_weapons.dmi and b/icons/obj/items_and_weapons.dmi differ diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi index 2048725e56..776bf7a9ec 100644 Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ diff --git a/icons/obj/lighting.dmi b/icons/obj/lighting.dmi index 75b1241840..a17ac1c22e 100644 Binary files a/icons/obj/lighting.dmi and b/icons/obj/lighting.dmi differ diff --git a/icons/obj/machineprototype.dmi b/icons/obj/machineprototype.dmi deleted file mode 100644 index f5312bdba6..0000000000 Binary files a/icons/obj/machineprototype.dmi and /dev/null differ diff --git a/icons/obj/machines/biogenerator.dmi b/icons/obj/machines/biogenerator.dmi new file mode 100644 index 0000000000..7989d6f355 Binary files /dev/null and b/icons/obj/machines/biogenerator.dmi differ diff --git a/icons/obj/machines/camera.dmi b/icons/obj/machines/camera.dmi new file mode 100644 index 0000000000..343a5118e8 Binary files /dev/null and b/icons/obj/machines/camera.dmi differ diff --git a/icons/obj/machines/cloning.dmi b/icons/obj/machines/cloning.dmi new file mode 100644 index 0000000000..de68060740 Binary files /dev/null and b/icons/obj/machines/cloning.dmi differ diff --git a/icons/obj/machines/research.dmi b/icons/obj/machines/research.dmi index cd74eed322..a150880d39 100644 Binary files a/icons/obj/machines/research.dmi and b/icons/obj/machines/research.dmi differ diff --git a/icons/obj/machines/sleeper.dmi b/icons/obj/machines/sleeper.dmi new file mode 100644 index 0000000000..b027d0d7b1 Binary files /dev/null and b/icons/obj/machines/sleeper.dmi differ diff --git a/icons/obj/machines/suit_storage.dmi b/icons/obj/machines/suit_storage.dmi new file mode 100644 index 0000000000..e61f9567c6 Binary files /dev/null and b/icons/obj/machines/suit_storage.dmi differ diff --git a/icons/obj/meter.dmi b/icons/obj/meter.dmi deleted file mode 100644 index 5f3051d8c0..0000000000 Binary files a/icons/obj/meter.dmi and /dev/null differ diff --git a/icons/obj/module.dmi b/icons/obj/module.dmi index c24f7c4c16..f5bd612c22 100644 Binary files a/icons/obj/module.dmi and b/icons/obj/module.dmi differ diff --git a/icons/obj/monitors.dmi b/icons/obj/monitors.dmi index 0a2edd5dbe..b9c34380de 100644 Binary files a/icons/obj/monitors.dmi and b/icons/obj/monitors.dmi differ diff --git a/icons/obj/pda.dmi b/icons/obj/pda.dmi index 5404b908c6..241bb46b98 100644 Binary files a/icons/obj/pda.dmi and b/icons/obj/pda.dmi differ diff --git a/icons/obj/pet_carrier.dmi b/icons/obj/pet_carrier.dmi new file mode 100644 index 0000000000..340636056c Binary files /dev/null and b/icons/obj/pet_carrier.dmi differ diff --git a/icons/obj/plushes.dmi b/icons/obj/plushes.dmi index 7eec51e46e..f0eb817549 100644 Binary files a/icons/obj/plushes.dmi and b/icons/obj/plushes.dmi differ diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi index f563af642f..dadf843041 100644 Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi index 18bbcb3610..d18a1bf262 100755 Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ diff --git a/icons/obj/tubing.dmi b/icons/obj/tubing.dmi deleted file mode 100644 index 89c4bf45e3..0000000000 Binary files a/icons/obj/tubing.dmi and /dev/null differ diff --git a/icons/obj/vending.dmi b/icons/obj/vending.dmi index c7b9bbcdc8..a1471e6418 100644 Binary files a/icons/obj/vending.dmi and b/icons/obj/vending.dmi differ diff --git a/icons/obj/vending_restock.dmi b/icons/obj/vending_restock.dmi index 7f8289a087..a59fdd0f52 100644 Binary files a/icons/obj/vending_restock.dmi and b/icons/obj/vending_restock.dmi differ diff --git a/icons/obj/virology.dmi b/icons/obj/virology.dmi deleted file mode 100644 index 882e54402c..0000000000 Binary files a/icons/obj/virology.dmi and /dev/null differ diff --git a/icons/obj/wizard.dmi b/icons/obj/wizard.dmi index 7ee9d04498..28b00d8707 100644 Binary files a/icons/obj/wizard.dmi and b/icons/obj/wizard.dmi differ diff --git a/interface/interface.dm b/interface/interface.dm index 0e0ecbdc8c..9b87479a33 100644 --- a/interface/interface.dm +++ b/interface/interface.dm @@ -20,7 +20,7 @@ set hidden = 1 var/forumurl = CONFIG_GET(string/forumurl) if(forumurl) - if(alert("This will open the forum in your browser. Are you sure?",,"Yes","No")=="No") + if(alert("This will open the forum in your browser. Are you sure?",,"Yes","No")!="Yes") return src << link(forumurl) else @@ -33,7 +33,7 @@ set hidden = 1 var/rulesurl = CONFIG_GET(string/rulesurl) if(rulesurl) - if(alert("This will open the rules in your browser. Are you sure?",,"Yes","No")=="No") + if(alert("This will open the rules in your browser. Are you sure?",,"Yes","No")!="Yes") return src << link(rulesurl) else @@ -46,7 +46,7 @@ set hidden = 1 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") + if(alert("This will open the Github repository in your browser. Are you sure?",,"Yes","No")!="Yes") return src << link(githuburl) else @@ -63,7 +63,7 @@ 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") + if(tgalert(src, message, "Report Issue","Yes","No")!="Yes") return var/static/issue_template = file2text(".github/ISSUE_TEMPLATE.md") var/servername = CONFIG_GET(string/servername) @@ -119,6 +119,8 @@ Hotkey-Mode: (hotkey-mode must be on) \th = stop pulling \tx = swap-hand \tz = activate held object (or y) +\tShift+e = Put held item into belt or take out most recent item added to belt. +\tShift+b = Put held item into backpack or take out most recent item added to backpack. \tf = cycle-intents-left \tg = cycle-intents-right \t1 = help-intent diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm index 7ad30fb7b5..e1505d6088 100644 --- a/interface/stylesheet.dm +++ b/interface/stylesheet.dm @@ -36,6 +36,9 @@ em {font-style: normal; font-weight: bold;} .say {} .deadsay {color: #5c00e6;} +.binarysay {color: #20c20e; background-color: #000000; display: block;} +.binarysay a {color: #00ff00;} +.binarysay a:active, .binarysay a:visited {color: #88ff88;} .radio {color: #008000;} .sciradio {color: #993399;} .comradio {color: #948f02;} @@ -131,6 +134,7 @@ h1.alert, h2.alert {color: #000000;} .ghostalert {color: #5c00e6; font-style: italic; font-weight: bold;} .alien {color: #543354;} +.alienbold {color: #543354; font-weight: bold;} .noticealien {color: #00c000;} .alertalien {color: #00c000; font-weight: bold;} .borer {color: #543354; font-style: italic;} @@ -156,6 +160,7 @@ h1.alert, h2.alert {color: #000000;} .memo {color: #638500; text-align: center;} .memoedit {text-align: center; font-size: 2;} .abductor {color: #800080; font-style: italic;} +.mind_control {color: #A00D6F; font-size: 3; font-weight: bold; font-style: italic;} .slime {color: #00CED1;} .drone {color: #848482;} .monkey {color: #975032;} diff --git a/modular_citadel/citadel_ghostrole_spawners.dm b/modular_citadel/citadel_ghostrole_spawners.dm new file mode 100644 index 0000000000..b0cddbd594 --- /dev/null +++ b/modular_citadel/citadel_ghostrole_spawners.dm @@ -0,0 +1,43 @@ +/obj/effect/mob_spawn/human/lavaknight + name = "odd cryogenics pod" + desc = "A humming cryo pod. You can barely recognise a faint glow underneath the built up ice. The machine is attempting to wake up its occupant." + mob_name = "a displaced knight from another dimension" + icon = 'icons/obj/machines/sleeper.dmi' + icon_state = "sleeper" + roundstart = FALSE + death = FALSE + random = TRUE + outfit = /datum/outfit/lavaknight + mob_species = /datum/species/human + flavour_text = "You are a knight who conveniently has some form of retrograde amnesia. \ + You cannot remember where you came from. However, a few things remain burnt into your mind, most prominently a vow to never harm another sapient being under any circumstances unless it is hellbent on ending your life. \ + Remember: hostile creatures and such are fair game for attacking, but under no circumstances are you to attack anything capable of thought and/or speech unless it has made it its life's calling to chase you to the ends of the earth." + assignedrole = "Cydonian Knight" + +/obj/effect/mob_spawn/human/lavaknight/special(mob/living/new_spawn) + if(ishuman(new_spawn)) + var/mob/living/carbon/human/H = new_spawn + H.dna.features["ears"] = "Cat" //cat people + H.update_body() + +/obj/effect/mob_spawn/human/lavaknight/Destroy() + new/obj/structure/showcase/machinery/oldpod/used(drop_location()) + return ..() + +/datum/outfit/lavaknight + name = "Cydonian Knight" + uniform = /obj/item/clothing/under/assistantformal + mask = /obj/item/clothing/mask/breath + shoes = /obj/item/clothing/shoes/sneakers/black + r_pocket = /obj/item/melee/transforming/energy/sword/cx + suit = /obj/item/clothing/suit/space/hardsuit/lavaknight + suit_store = /obj/item/tank/internals/oxygen + +/obj/effect/mob_spawn/human/lavaknight/captain + name = "odd gilded cryogenics pod" + desc = "A humming cryo pod that appears to be gilded. You can barely recognise a faint glow underneath the built up ice. The machine is attempting to wake up its occupant." + flavour_text = "You are a knight who conveniently has some form of retrograde amnesia. \ + You cannot remember where you came from. However, a few things remain burnt into your mind, most prominently a vow to never harm another sapient being under any circumstances unless it is hellbent on ending your life. \ + Remember: hostile creatures and such are fair game for attacking, but under no circumstances are you to attack anything capable of thought and/or speech unless it has made it its life's calling to chase you to the ends of the earth. \ + You feel a natural instict to lead, and as such, you should strive to lead your comrades to safety, and hopefully home. You also feel a burning determination to uphold your vow, as well as your fellow comrade's." + l_pocket = /obj/item/twohanded/hypereutactic diff --git a/code/modules/uplink/uplink_item_cit.dm b/modular_citadel/code/datums/uplink_items_cit.dm similarity index 100% rename from code/modules/uplink/uplink_item_cit.dm rename to modular_citadel/code/datums/uplink_items_cit.dm diff --git a/modular_citadel/code/game/objects/items/devices/PDA/PDA.dm b/modular_citadel/code/game/objects/items/devices/PDA/PDA.dm new file mode 100644 index 0000000000..85ac3982ed --- /dev/null +++ b/modular_citadel/code/game/objects/items/devices/PDA/PDA.dm @@ -0,0 +1,4 @@ +//Overrides TG's PDA sprites with Cit's PDA sprites. Remind me to turn this into a pref somewhere down the line. + +/obj/item/device/pda + icon = 'modular_citadel/icons/obj/pda.dmi' diff --git a/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm b/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm new file mode 100644 index 0000000000..d324c95511 --- /dev/null +++ b/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm @@ -0,0 +1,403 @@ +/*///////////////////////////////////////////////////////////////////////// +///////////// The TRUE Energy Sword /////////////////////////// +*////////////////////////////////////////////////////////////////////////// + +/obj/item/melee/transforming/energy/sword/cx + name = "non-eutactic blade" + desc = "The Non-Eutactic Blade utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable." + icon_state = "cxsword_hilt" + icon = 'modular_citadel/icons/eutactic/item/noneutactic.dmi' + item_state = "cxsword" + lefthand_file = 'modular_citadel/icons/eutactic/mob/noneutactic_left.dmi' + righthand_file = 'modular_citadel/icons/eutactic/mob/noneutactic_right.dmi' + force = 3 + throwforce = 5 + hitsound = "swing_hit" //it starts deactivated + hitsound_on = 'sound/weapons/nebhit.ogg' + attack_verb_off = list("tapped", "poked") + throw_speed = 3 + throw_range = 5 + sharpness = IS_SHARP + embed_chance = 40 + embedded_impact_pain_multiplier = 10 + armour_penetration = 0 + block_chance = 60 + light_color = "#37FFF7" + actions_types = list() + +/obj/item/melee/transforming/energy/sword/cx/transform_weapon(mob/living/user, supress_message_text) + active = !active //I'd use a ..() here but it'd inherit from the regular esword's proc instead, so SPAGHETTI CODE + if(active) //also I'd need to rip out the iconstate changing bits + force = force_on + throwforce = throwforce_on + hitsound = hitsound_on + throw_speed = 4 + if(attack_verb_on.len) + attack_verb = attack_verb_on + w_class = w_class_on + START_PROCESSING(SSobj, src) + set_light(brightness_on) + update_icon() + else + force = initial(force) + throwforce = initial(throwforce) + hitsound = initial(hitsound) + throw_speed = initial(throw_speed) + if(attack_verb_off.len) + attack_verb = attack_verb_off + w_class = initial(w_class) + STOP_PROCESSING(SSobj, src) + set_light(0) + update_icon() + transform_messages(user, supress_message_text) + add_fingerprint(user) + return TRUE + +/obj/item/melee/transforming/energy/sword/cx/transform_messages(mob/living/user, supress_message_text) + playsound(user, active ? 'sound/weapons/nebon.ogg' : 'sound/weapons/neboff.ogg', 65, 1) + if(!supress_message_text) + to_chat(user, "[src] [active ? "is now active":"can now be concealed"].") + +/obj/item/melee/transforming/energy/sword/cx/update_icon() + var/mutable_appearance/blade_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/noneutactic.dmi', "cxsword_blade") + var/mutable_appearance/gem_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/noneutactic.dmi', "cxsword_gem") + + if(light_color) + blade_overlay.color = light_color + gem_overlay.color = light_color + + cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other + + add_overlay(gem_overlay) + + if(active) + add_overlay(blade_overlay) + if(ismob(loc)) + var/mob/M = loc + M.update_inv_hands() + +/obj/item/melee/transforming/energy/sword/cx/AltClick(mob/living/user) + if(!in_range(src, user)) //Basic checks to prevent abuse + return + if(user.incapacitated() || !istype(user)) + to_chat(user, "You can't do that right now!") + return + + if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes") + var/energy_color_input = input(usr,"Choose Energy Color") as color|null + if(energy_color_input) + light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1) + update_icon() + update_light() + +/obj/item/melee/transforming/energy/sword/cx/examine(mob/user) + ..() + to_chat(user, "Alt-click to recolor it.") + +/obj/item/melee/transforming/energy/sword/cx/worn_overlays(isinhands, icon_file) + . = ..() + if(active) + if(isinhands) + var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "cxsword_blade") + blade_inhand.color = light_color + . += blade_inhand + +//OBLIGATORY TOY MEMES ///////////////////////////////////// + +/obj/item/toy/sword/cx + name = "\improper DX Non-Euplastic LightSword" + desc = "A deluxe toy replica of an energy sword. Realistic visuals and sounds! Ages 8 and up." + icon = 'modular_citadel/icons/eutactic/item/noneutactic.dmi' + icon_state = "cxsword_hilt" + item_state = "cxsword" + lefthand_file = 'modular_citadel/icons/eutactic/mob/noneutactic_left.dmi' + righthand_file = 'modular_citadel/icons/eutactic/mob/noneutactic_right.dmi' + active = FALSE + w_class = WEIGHT_CLASS_SMALL + attack_verb = list("poked", "jabbed", "hit") + light_color = "#37FFF7" + var/light_brightness = 3 + actions_types = list() + +/obj/item/toy/sword/cx/attack_self(mob/user) + active = !( active ) + + if (active) + to_chat(user, "You activate the holographic blade with a press of a button.") + playsound(user, 'sound/weapons/nebon.ogg', 50, 1) + w_class = WEIGHT_CLASS_BULKY + attack_verb = list("slashed", "stabbed", "ravaged") + set_light(light_brightness) + update_icon() + + else + to_chat(user, "You deactivate the holographic blade with a press of a button.") + playsound(user, 'sound/weapons/neboff.ogg', 50, 1) + w_class = WEIGHT_CLASS_SMALL + attack_verb = list("poked", "jabbed", "hit") + set_light(0) + update_icon() + + add_fingerprint(user) + +/obj/item/toy/sword/cx/update_icon() + var/mutable_appearance/blade_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/noneutactic.dmi', "cxsword_blade") + var/mutable_appearance/gem_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/noneutactic.dmi', "cxsword_gem") + + if(light_color) + blade_overlay.color = light_color + gem_overlay.color = light_color + + cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other + + add_overlay(gem_overlay) + + if(active) + add_overlay(blade_overlay) + if(ismob(loc)) + var/mob/M = loc + M.update_inv_hands() + +/obj/item/toy/sword/cx/AltClick(mob/living/user) + if(!in_range(src, user)) //Basic checks to prevent abuse + return + if(user.incapacitated() || !istype(user)) + to_chat(user, "You can't do that right now!") + return + + if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes") + var/energy_color_input = input(usr,"Choose Energy Color") as color|null + if(energy_color_input) + light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1) + update_icon() + update_light() + +/obj/item/toy/sword/cx/worn_overlays(isinhands, icon_file) + . = ..() + if(active) + if(isinhands) + var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "cxsword_blade") + blade_inhand.color = light_color + . += blade_inhand + +/obj/item/toy/sword/cx/attackby(obj/item/W, mob/living/user, params) + if(istype(W, /obj/item/toy/sword/cx)) + if((W.flags_1 & NODROP_1) || (flags_1 & NODROP_1)) + to_chat(user, "\the [flags_1 & NODROP_1 ? src : W] is stuck to your hand, you can't attach it to \the [flags_1 & NODROP_1 ? W : src]!") + return + else + to_chat(user, "You combine the two plastic swords, making a single supermassive toy! You're fake-cool.") + new /obj/item/twohanded/hypereutactic/toy(user.loc) + qdel(W) + qdel(src) + else + return ..() + +/obj/item/toy/sword/cx/examine(mob/user) + ..() + to_chat(user, "Alt-click to recolor it.") + +///////////////////////////////////////////////////// +// HYPEREUTACTIC Blades ///////////////////////// +///////////////////////////////////////////////////// + +/obj/item/twohanded/hypereutactic + icon = 'modular_citadel/icons/eutactic/item/hypereutactic.dmi' + icon_state = "hypereutactic" + lefthand_file = 'modular_citadel/icons/eutactic/mob/hypereutactic_left.dmi' + righthand_file = 'modular_citadel/icons/eutactic/mob/hypereutactic_right.dmi' + item_state = "hypereutactic" + inhand_x_dimension = 64 + inhand_y_dimension = 64 + name = "hypereutactic blade" + desc = "A supermassive weapon envisioned to cleave the very fabric of space and time itself in twain, the hypereutactic blade dynamically flash-forges a hypereutactic crystaline nanostructure capable of passing through most known forms of matter like a hot knife through butter." + force = 3 + throwforce = 5 + throw_speed = 3 + throw_range = 5 + w_class = WEIGHT_CLASS_SMALL + var/w_class_on = WEIGHT_CLASS_BULKY + force_unwielded = 3 + force_wielded = 40 + wieldsound = 'sound/weapons/nebon.ogg' + unwieldsound = 'sound/weapons/neboff.ogg' + hitsound = "swing_hit" + armour_penetration = 40 + light_color = "#37FFF7" + attack_verb = list("attacked", "slashed", "stabbed", "sliced", "destroyed", "ripped", "devastated", "shredded") + block_chance = 75 + max_integrity = 200 + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 70) + resistance_flags = FIRE_PROOF + var/brightness_on = 6 //TWICE AS BRIGHT AS A REGULAR ESWORD + flags_2 = SLOWS_WHILE_IN_HAND_2 + +/obj/item/twohanded/hypereutactic/wield(mob/living/carbon/M) //Specific wield () hulk checks due to reflection chance for balance issues and switches hitsounds. + if(M.has_dna()) + if(M.dna.check_mutation(HULK)) + to_chat(M, "You lack the grace to wield this!") + return + ..() + if(wielded) + sharpness = IS_SHARP + w_class = w_class_on + hitsound = 'sound/weapons/nebhit.ogg' + START_PROCESSING(SSobj, src) + set_light(brightness_on) + slowdown = 1 + +/obj/item/twohanded/hypereutactic/unwield() //Specific unwield () to switch hitsounds. + sharpness = initial(sharpness) + w_class = initial(w_class) + ..() + hitsound = "swing_hit" + STOP_PROCESSING(SSobj, src) + set_light(0) + slowdown = initial(slowdown) + +/obj/item/twohanded/hypereutactic/update_icon() + var/mutable_appearance/blade_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/hypereutactic.dmi', "hypereutactic_blade") + var/mutable_appearance/gem_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/hypereutactic.dmi', "hypereutactic_gem") + + if(light_color) + blade_overlay.color = light_color + gem_overlay.color = light_color + + cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other + + add_overlay(gem_overlay) + + if(wielded) + add_overlay(blade_overlay) + if(ismob(loc)) + var/mob/M = loc + M.update_inv_hands() + + clean_blood()//blood overlays get weird otherwise, because the sprite changes. (retained from original desword because I have no idea what this is) + +/obj/item/twohanded/hypereutactic/AltClick(mob/living/user) + if(!in_range(src, user)) //Basic checks to prevent abuse + return + if(user.incapacitated() || !istype(user)) + to_chat(user, "You can't do that right now!") + return + + if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes") + var/energy_color_input = input(usr,"Choose Energy Color") as color|null + if(energy_color_input) + light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1) + update_icon() + update_light() + +/obj/item/twohanded/hypereutactic/worn_overlays(isinhands, icon_file) + . = ..() + if(isinhands) + var/mutable_appearance/gem_inhand = mutable_appearance(icon_file, "hypereutactic_gem") + gem_inhand.color = light_color + . += gem_inhand + if(wielded) + var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "hypereutactic_blade") + blade_inhand.color = light_color + . += blade_inhand + +/obj/item/twohanded/hypereutactic/examine(mob/user) + ..() + to_chat(user, "Alt-click to recolor it.") + + + +////////// stuff beneath this is all taken from the desword //////////// wow very professional such OOP wow + + + +/obj/item/twohanded/hypereutactic/attack(mob/target, mob/living/carbon/human/user) + if(user.has_dna()) + if(user.dna.check_mutation(HULK)) + to_chat(user, "You grip the blade too hard and accidentally close it!") + unwield() + return + ..() + if(user.disabilities & CLUMSY && (wielded) && prob(40)) + impale(user) + return + +/obj/item/twohanded/hypereutactic/Destroy() + STOP_PROCESSING(SSobj, src) + . = ..() + +/obj/item/twohanded/hypereutactic/proc/impale(mob/living/user) + to_chat(user, "You spin around a bit before losing your balance and impaling yourself on [src].") + if (force_wielded) + user.take_bodypart_damage(20,25) + else + user.adjustStaminaLoss(25) + +/obj/item/twohanded/hypereutactic/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(wielded) + return ..() + return FALSE + +/obj/item/twohanded/hypereutactic/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0) //In case thats just so happens that it is still activated on the groud, prevents hulk from picking it up + if(wielded) + to_chat(user, "You can't pick up such dangerous item with your meaty hands without losing fingers, better not to!") + return TRUE + +/obj/item/twohanded/hypereutactic/process() + if(wielded) + open_flame() + else + STOP_PROCESSING(SSobj, src) + +/obj/item/twohanded/hypereutactic/IsReflect() + if(wielded) + return TRUE + +/obj/item/twohanded/hypereutactic/ignition_effect(atom/A, mob/user) + // same as /obj/item/melee/transforming/energy, mostly + if(!wielded) + return "" + var/in_mouth = "" + if(iscarbon(user)) + var/mob/living/carbon/C = user + if(C.wear_mask == src) + in_mouth = ", barely missing their nose" + . = "[user] swings [user.p_their()] [src][in_mouth]. [user.p_they()] light[user.p_s()] [A] in the process." + playsound(loc, hitsound, get_clamped_volume(), 1, -1) + add_fingerprint(user) + +////////////////// TOY VERSION ///////////////////////////// + +/obj/item/twohanded/hypereutactic/toy + name = "\improper DX Hyper-Euplastic LightSword" + desc = "A supermassive toy envisioned to cleave the very fabric of space and time itself in twain. Realistic visuals and sounds! Ages 8 and up." + force = 0 + throwforce = 0 + throw_speed = 3 + throw_range = 5 + force_unwielded = 0 + force_wielded = 0 + attack_verb = list("attacked", "struck", "hit") + +/obj/item/twohanded/hypereutactic/toy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) + return FALSE + +/obj/item/twohanded/hypereutactic/toy/IsReflect()//Stops it from reflecting energy projectiles + return FALSE + +//////// Tatortot NEB /////////////// (same stats as regular esword) +/obj/item/melee/transforming/energy/sword/cx/traitor + name = "\improper Dragon's Tooth Sword" + desc = "The Dragon's Tooth sword is a blackmarket modification of a Non-Eutactic Blade, \ + which utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable. \ + It appears to have a wooden grip and a shaved down guard." + icon_state = "cxsword_hilt_traitor" + armour_penetration = 35 + embed_chance = 75 + block_chance = 50 + hitsound_on = 'sound/weapons/blade1.ogg' + light_color = "#37F0FF" + +/obj/item/melee/transforming/energy/sword/cx/traitor/transform_messages(mob/living/user, supress_message_text) + playsound(user, active ? 'sound/weapons/saberon.ogg' : 'sound/weapons/saberoff.ogg', 35, 1) + if(!supress_message_text) + to_chat(user, "[src] [active ? "is now active":"can now be concealed"].") \ No newline at end of file diff --git a/modular_citadel/code/modules/crafting/recipes.dm b/modular_citadel/code/modules/crafting/recipes.dm new file mode 100644 index 0000000000..6ed749e7c6 --- /dev/null +++ b/modular_citadel/code/modules/crafting/recipes.dm @@ -0,0 +1,5 @@ +/datum/crafting_recipe/toyneb + name = "Non-Euplastic Blade" + reqs = list(/obj/item/light/tube = 1, /obj/item/stack/cable_coil = 1, /obj/item/stack/sheet/plastic = 4) + result = /obj/item/toy/sword/cx + category = CAT_MISC \ No newline at end of file diff --git a/modular_citadel/cydonian_armor.dm b/modular_citadel/cydonian_armor.dm new file mode 100644 index 0000000000..0189358d36 --- /dev/null +++ b/modular_citadel/cydonian_armor.dm @@ -0,0 +1,160 @@ +/* + CYDONIAN ARMOR THAT IS RGB AND STUFF WOOOOOOOOOO +*/ + +/obj/item/clothing/head/helmet/space/hardsuit/lavaknight + name = "cydonian helmet" + desc = "A helmet designed with both form and function in mind, it protects the user against physical trauma and hazardous conditions while also having polychromic light strips." + icon = 'modular_citadel/icons/lavaknight/item/head.dmi' + icon_state = "knight_cydonia" + item_state = "knight_yellow" + item_color = null + alternate_worn_icon = 'modular_citadel/icons/lavaknight/mob/head.dmi' + max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT + resistance_flags = FIRE_PROOF | LAVA_PROOF + heat_protection = HEAD + armor = list(melee = 50, bullet = 10, laser = 10, energy = 10, bomb = 50, bio = 100, rad = 50, fire = 100, acid = 100) + brightness_on = 7 + allowed = list(/obj/item/device/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/device/mining_scanner, /obj/item/device/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator) + var/energy_color = "#35FFF0" + var/obj/item/clothing/suit/space/hardsuit/lavaknight/linkedsuit = null + +/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/New() + ..() + if(istype(loc, /obj/item/clothing/suit/space/hardsuit/lavaknight)) + linkedsuit = loc + +/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/attack_self(mob/user) + on = !on + + if(on) + set_light(brightness_on) + else + set_light(0) + for(var/X in actions) + var/datum/action/A = X + A.UpdateButtonIcon() + +/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/update_icon() + var/mutable_appearance/helm_overlay = mutable_appearance('modular_citadel/icons/lavaknight/item/head.dmi', "knight_cydonia_overlay", LIGHTING_LAYER + 1) + + if(energy_color) + helm_overlay.color = energy_color + + helm_overlay.plane = LIGHTING_PLANE + 1 //Magic number is used here because we have no ABOVE_LIGHTING_PLANE plane defined. Lighting plane is 15, HUD is 18 + + cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other + + add_overlay(helm_overlay) + + emissivelights() + +/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/equipped(mob/user, slot) + ..() + if(slot == slot_head) + emissivelights() + +/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/dropped(mob/user) + ..() + emissivelightsoff() + +/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/proc/emissivelights(mob/user = usr) + var/mutable_appearance/energy_overlay = mutable_appearance('modular_citadel/icons/lavaknight/mob/head.dmi', "knight_cydonia_overlay", LIGHTING_LAYER + 1) + energy_overlay.color = energy_color + energy_overlay.plane = LIGHTING_PLANE + 1 + user.cut_overlay(energy_overlay) //honk + user.add_overlay(energy_overlay) //honk + +/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/proc/emissivelightsoff(mob/user = usr) + user.cut_overlay() + linkedsuit.emissivelights() //HONK HONK HONK MAXIMUM SPAGHETTI + user.regenerate_icons() //honk + +/obj/item/clothing/suit/space/hardsuit/lavaknight + icon = 'modular_citadel/icons/lavaknight/item/suit.dmi' + icon_state = "knight_cydonia" + name = "cydonian armor" + desc = "A suit designed with both form and function in mind, it protects the user against physical trauma and hazardous conditions while also having polychromic light strips." + item_state = "swat_suit" + alternate_worn_icon = 'modular_citadel/icons/lavaknight/mob/suit.dmi' + max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT + resistance_flags = FIRE_PROOF | LAVA_PROOF + armor = list(melee = 50, bullet = 10, laser = 10, energy = 10, bomb = 50, bio = 100, rad = 50, fire = 100, acid = 100) + allowed = list(/obj/item/device/flashlight, /obj/item/tank/internals, /obj/item/storage/bag/ore, /obj/item/pickaxe) + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/lavaknight + heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS + actions_types = list(/datum/action/item_action/toggle_helmet) + var/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/linkedhelm + + var/energy_color = "#35FFF0" + +/obj/item/clothing/suit/space/hardsuit/lavaknight/New() + ..() + if(helmet) + linkedhelm = helmet + light_color = energy_color + set_light(1) + +/obj/item/clothing/suit/space/hardsuit/lavaknight/Initialize() + ..() + update_icon() + +/obj/item/clothing/suit/space/hardsuit/lavaknight/update_icon() + var/mutable_appearance/suit_overlay = mutable_appearance('modular_citadel/icons/lavaknight/item/suit.dmi', "knight_cydonia_overlay", LIGHTING_LAYER + 1) + + if(energy_color) + suit_overlay.color = energy_color + + suit_overlay.plane = LIGHTING_PLANE + 1 //Magic number is used here because we have no ABOVE_LIGHTING_PLANE plane defined. Lighting plane is 15. + + cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other + + add_overlay(suit_overlay) + +/obj/item/clothing/suit/space/hardsuit/lavaknight/equipped(mob/user, slot) + ..() + if(slot == slot_wear_suit) + emissivelights() + +/obj/item/clothing/suit/space/hardsuit/lavaknight/dropped(mob/user) + ..() + emissivelightsoff() + +/obj/item/clothing/suit/space/hardsuit/lavaknight/proc/emissivelights(mob/user = usr) + var/mutable_appearance/energy_overlay = mutable_appearance('modular_citadel/icons/lavaknight/mob/suit.dmi', "knight_cydonia_overlay", LIGHTING_LAYER + 1) + energy_overlay.color = energy_color + energy_overlay.plane = LIGHTING_PLANE + 1 + user.cut_overlay(energy_overlay) //honk + user.add_overlay(energy_overlay) //honk + +/obj/item/clothing/suit/space/hardsuit/lavaknight/proc/emissivelightsoff(mob/user = usr) + user.cut_overlays() + user.regenerate_icons() //honk + +/obj/item/clothing/suit/space/hardsuit/lavaknight/AltClick(mob/living/user) + if(user.incapacitated() || !istype(user)) + to_chat(user, "You can't do that right now!") + return + if(!in_range(src, user)) + return + if(user.incapacitated() || !istype(user) || !in_range(src, user)) + return + + if(alert("Are you sure you want to recolor your armor stripes?", "Confirm Repaint", "Yes", "No") == "Yes") + var/energy_color_input = input(usr,"Choose Energy Color") as color|null + if(energy_color_input) + energy_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1) + user.update_inv_wear_suit() + if(linkedhelm) + linkedhelm.energy_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1) + user.update_inv_head() + linkedhelm.update_icon() + update_icon() + user.update_inv_wear_suit() + light_color = energy_color + emissivelights() + update_light() + +/obj/item/clothing/suit/space/hardsuit/lavaknight/examine(mob/user) + ..() + to_chat(user, "Alt-click to recolor it.") \ No newline at end of file diff --git a/modular_citadel/icons/eutactic/item/hypereutactic.dmi b/modular_citadel/icons/eutactic/item/hypereutactic.dmi new file mode 100644 index 0000000000..90a665f676 Binary files /dev/null and b/modular_citadel/icons/eutactic/item/hypereutactic.dmi differ diff --git a/icons/obj/cit_weapons.dmi b/modular_citadel/icons/eutactic/item/noneutactic.dmi similarity index 100% rename from icons/obj/cit_weapons.dmi rename to modular_citadel/icons/eutactic/item/noneutactic.dmi diff --git a/modular_citadel/icons/eutactic/mob/hypereutactic_left.dmi b/modular_citadel/icons/eutactic/mob/hypereutactic_left.dmi new file mode 100644 index 0000000000..ca94055113 Binary files /dev/null and b/modular_citadel/icons/eutactic/mob/hypereutactic_left.dmi differ diff --git a/modular_citadel/icons/eutactic/mob/hypereutactic_right.dmi b/modular_citadel/icons/eutactic/mob/hypereutactic_right.dmi new file mode 100644 index 0000000000..a9b90da740 Binary files /dev/null and b/modular_citadel/icons/eutactic/mob/hypereutactic_right.dmi differ diff --git a/icons/mob/citadel/melee_lefthand.dmi b/modular_citadel/icons/eutactic/mob/noneutactic_left.dmi similarity index 100% rename from icons/mob/citadel/melee_lefthand.dmi rename to modular_citadel/icons/eutactic/mob/noneutactic_left.dmi diff --git a/icons/mob/citadel/melee_righthand.dmi b/modular_citadel/icons/eutactic/mob/noneutactic_right.dmi similarity index 100% rename from icons/mob/citadel/melee_righthand.dmi rename to modular_citadel/icons/eutactic/mob/noneutactic_right.dmi diff --git a/modular_citadel/icons/lavaknight/item/head.dmi b/modular_citadel/icons/lavaknight/item/head.dmi new file mode 100644 index 0000000000..950d4894e9 Binary files /dev/null and b/modular_citadel/icons/lavaknight/item/head.dmi differ diff --git a/modular_citadel/icons/lavaknight/item/suit.dmi b/modular_citadel/icons/lavaknight/item/suit.dmi new file mode 100644 index 0000000000..49cd14b666 Binary files /dev/null and b/modular_citadel/icons/lavaknight/item/suit.dmi differ diff --git a/modular_citadel/icons/lavaknight/mob/head.dmi b/modular_citadel/icons/lavaknight/mob/head.dmi new file mode 100644 index 0000000000..5084c9c66f Binary files /dev/null and b/modular_citadel/icons/lavaknight/mob/head.dmi differ diff --git a/modular_citadel/icons/lavaknight/mob/suit.dmi b/modular_citadel/icons/lavaknight/mob/suit.dmi new file mode 100644 index 0000000000..ed51ceaaa4 Binary files /dev/null and b/modular_citadel/icons/lavaknight/mob/suit.dmi differ diff --git a/modular_citadel/icons/obj/pda.dmi b/modular_citadel/icons/obj/pda.dmi new file mode 100644 index 0000000000..5404b908c6 Binary files /dev/null and b/modular_citadel/icons/obj/pda.dmi differ diff --git a/sound/machines/clockcult/ark_damage.ogg b/sound/machines/clockcult/ark_damage.ogg new file mode 100644 index 0000000000..40ccfc6219 Binary files /dev/null and b/sound/machines/clockcult/ark_damage.ogg differ diff --git a/sound/machines/clockcult/ark_deathrattle.ogg b/sound/machines/clockcult/ark_deathrattle.ogg new file mode 100644 index 0000000000..916ff0429e Binary files /dev/null and b/sound/machines/clockcult/ark_deathrattle.ogg differ diff --git a/sound/machines/clockcult/ark_recall.ogg b/sound/machines/clockcult/ark_recall.ogg new file mode 100644 index 0000000000..a38a0b765b Binary files /dev/null and b/sound/machines/clockcult/ark_recall.ogg differ diff --git a/sound/machines/clockcult/ark_scream.ogg b/sound/machines/clockcult/ark_scream.ogg new file mode 100644 index 0000000000..acdc7c85db Binary files /dev/null and b/sound/machines/clockcult/ark_scream.ogg differ diff --git a/sound/machines/clockcult/brass_skewer.ogg b/sound/machines/clockcult/brass_skewer.ogg new file mode 100644 index 0000000000..927bf9b275 Binary files /dev/null and b/sound/machines/clockcult/brass_skewer.ogg differ diff --git a/sound/machines/clockcult/eminence_command.ogg b/sound/machines/clockcult/eminence_command.ogg new file mode 100644 index 0000000000..59a4e3f26d Binary files /dev/null and b/sound/machines/clockcult/eminence_command.ogg differ diff --git a/sound/machines/clockcult/eminence_selected.ogg b/sound/machines/clockcult/eminence_selected.ogg new file mode 100644 index 0000000000..6d1175faf7 Binary files /dev/null and b/sound/machines/clockcult/eminence_selected.ogg differ diff --git a/sound/weapons/gun_chamber_round.ogg b/sound/weapons/gun_chamber_round.ogg new file mode 100644 index 0000000000..951b9d144d Binary files /dev/null and b/sound/weapons/gun_chamber_round.ogg differ diff --git a/sound/weapons/gun_dry_fire_1.ogg b/sound/weapons/gun_dry_fire_1.ogg new file mode 100644 index 0000000000..a129f2e45e Binary files /dev/null and b/sound/weapons/gun_dry_fire_1.ogg differ diff --git a/sound/weapons/gun_dry_fire_2.ogg b/sound/weapons/gun_dry_fire_2.ogg new file mode 100644 index 0000000000..dec8b72180 Binary files /dev/null and b/sound/weapons/gun_dry_fire_2.ogg differ diff --git a/sound/weapons/gun_dry_fire_3.ogg b/sound/weapons/gun_dry_fire_3.ogg new file mode 100644 index 0000000000..3ebc5f6f69 Binary files /dev/null and b/sound/weapons/gun_dry_fire_3.ogg differ diff --git a/sound/weapons/gun_dry_fire_4.ogg b/sound/weapons/gun_dry_fire_4.ogg new file mode 100644 index 0000000000..b58ee2c7b7 Binary files /dev/null and b/sound/weapons/gun_dry_fire_4.ogg differ diff --git a/sound/weapons/gun_magazine_insert_empty_1.ogg b/sound/weapons/gun_magazine_insert_empty_1.ogg new file mode 100644 index 0000000000..ef34a8e358 Binary files /dev/null and b/sound/weapons/gun_magazine_insert_empty_1.ogg differ diff --git a/sound/weapons/gun_magazine_insert_empty_2.ogg b/sound/weapons/gun_magazine_insert_empty_2.ogg new file mode 100644 index 0000000000..4441937736 Binary files /dev/null and b/sound/weapons/gun_magazine_insert_empty_2.ogg differ diff --git a/sound/weapons/gun_magazine_insert_empty_3.ogg b/sound/weapons/gun_magazine_insert_empty_3.ogg new file mode 100644 index 0000000000..dda772be5d Binary files /dev/null and b/sound/weapons/gun_magazine_insert_empty_3.ogg differ diff --git a/sound/weapons/gun_magazine_insert_empty_4.ogg b/sound/weapons/gun_magazine_insert_empty_4.ogg new file mode 100644 index 0000000000..8ef39d84fb Binary files /dev/null and b/sound/weapons/gun_magazine_insert_empty_4.ogg differ diff --git a/sound/weapons/gun_magazine_insert_full_1.ogg b/sound/weapons/gun_magazine_insert_full_1.ogg new file mode 100644 index 0000000000..dbbede3f71 Binary files /dev/null and b/sound/weapons/gun_magazine_insert_full_1.ogg differ diff --git a/sound/weapons/gun_magazine_insert_full_2.ogg b/sound/weapons/gun_magazine_insert_full_2.ogg new file mode 100644 index 0000000000..7aeee89ef8 Binary files /dev/null and b/sound/weapons/gun_magazine_insert_full_2.ogg differ diff --git a/sound/weapons/gun_magazine_insert_full_3.ogg b/sound/weapons/gun_magazine_insert_full_3.ogg new file mode 100644 index 0000000000..95b9b891ef Binary files /dev/null and b/sound/weapons/gun_magazine_insert_full_3.ogg differ diff --git a/sound/weapons/gun_magazine_insert_full_4.ogg b/sound/weapons/gun_magazine_insert_full_4.ogg new file mode 100644 index 0000000000..d63f0310e5 Binary files /dev/null and b/sound/weapons/gun_magazine_insert_full_4.ogg differ diff --git a/sound/weapons/gun_magazine_insert_full_5.ogg b/sound/weapons/gun_magazine_insert_full_5.ogg new file mode 100644 index 0000000000..cfd6198760 Binary files /dev/null and b/sound/weapons/gun_magazine_insert_full_5.ogg differ diff --git a/sound/weapons/gun_magazine_remove_empty_1.ogg b/sound/weapons/gun_magazine_remove_empty_1.ogg new file mode 100644 index 0000000000..a3ae4fa2eb Binary files /dev/null and b/sound/weapons/gun_magazine_remove_empty_1.ogg differ diff --git a/sound/weapons/gun_magazine_remove_empty_2.ogg b/sound/weapons/gun_magazine_remove_empty_2.ogg new file mode 100644 index 0000000000..da73e52173 Binary files /dev/null and b/sound/weapons/gun_magazine_remove_empty_2.ogg differ diff --git a/sound/weapons/gun_magazine_remove_empty_3.ogg b/sound/weapons/gun_magazine_remove_empty_3.ogg new file mode 100644 index 0000000000..18689dc26b Binary files /dev/null and b/sound/weapons/gun_magazine_remove_empty_3.ogg differ diff --git a/sound/weapons/gun_magazine_remove_empty_4.ogg b/sound/weapons/gun_magazine_remove_empty_4.ogg new file mode 100644 index 0000000000..1012fbf5d7 Binary files /dev/null and b/sound/weapons/gun_magazine_remove_empty_4.ogg differ diff --git a/sound/weapons/gun_magazine_remove_full.ogg b/sound/weapons/gun_magazine_remove_full.ogg new file mode 100644 index 0000000000..9977da3ecd Binary files /dev/null and b/sound/weapons/gun_magazine_remove_full.ogg differ diff --git a/sound/weapons/gun_slide_lock_1.ogg b/sound/weapons/gun_slide_lock_1.ogg new file mode 100644 index 0000000000..65270e2b4c Binary files /dev/null and b/sound/weapons/gun_slide_lock_1.ogg differ diff --git a/sound/weapons/gun_slide_lock_2.ogg b/sound/weapons/gun_slide_lock_2.ogg new file mode 100644 index 0000000000..b0f0d28119 Binary files /dev/null and b/sound/weapons/gun_slide_lock_2.ogg differ diff --git a/sound/weapons/gun_slide_lock_3.ogg b/sound/weapons/gun_slide_lock_3.ogg new file mode 100644 index 0000000000..b30be8ab84 Binary files /dev/null and b/sound/weapons/gun_slide_lock_3.ogg differ diff --git a/sound/weapons/gun_slide_lock_4.ogg b/sound/weapons/gun_slide_lock_4.ogg new file mode 100644 index 0000000000..b10b830be7 Binary files /dev/null and b/sound/weapons/gun_slide_lock_4.ogg differ diff --git a/sound/weapons/gun_slide_lock_5.ogg b/sound/weapons/gun_slide_lock_5.ogg new file mode 100644 index 0000000000..5a4c1fa158 Binary files /dev/null and b/sound/weapons/gun_slide_lock_5.ogg differ diff --git a/strings/clockwork_cult_changelog.txt b/strings/clockwork_cult_changelog.txt new file mode 100644 index 0000000000..b5d2ca10e3 --- /dev/null +++ b/strings/clockwork_cult_changelog.txt @@ -0,0 +1,7 @@ +Added the Eminence, a leader role that servants can become by interacting with the new eminence spire structure in Reebe. +Scripture has been re-colored in the slab interface to show its niche at a glance. +Added traps, including the brass skewer and steam vent. +Added trap triggers, including the pressure sensor, lever, and repeater. +Traps and trap triggers can be linked by using your clockwork slab on them. Traps chained to each other will cause those traps to activate as well. +You can instantly remove traps you misplace by using a wrench on them. +Mending Mantra has been removed. \ No newline at end of file diff --git a/strings/hallucination.json b/strings/hallucination.json index b277f8552f..5efe749d14 100644 --- a/strings/hallucination.json +++ b/strings/hallucination.json @@ -1,229 +1,229 @@ { - "suspicion": [ - "I'm watching you...", - "I know what you're doing", - "What are you hiding?", - "I saw that" - ], + "suspicion": [ + "I'm watching you...", + "I know what you're doing", + "What are you hiding?", + "I saw that" + ], - "greetings": [ - "", - "Hey, ", - "Hi ", - "Hello ", - "Wait, ", - "It's " - ], + "greetings": [ + "", + "Hey, ", + "Hi ", + "Hello ", + "Wait, ", + "It's " + ], - "getout": [ - "Get out", - "Get out!", - "Go away", - "Fuck off", - "OUT!", - "Out!" - ], + "getout": [ + "Get out", + "Get out!", + "Go away", + "Fuck off", + "OUT!", + "Out!" + ], - "weird": [ - "Kchck-Chkck? Kchchck!", - "Kchckchk...", - "EEEeeeeEEEE", - "khhhhh", - "#@*&", - "H**p m*", - "H-hhhhh..." - ], + "weird": [ + "Kchck-Chkck? Kchchck!", + "Kchckchk...", + "EEEeeeeEEEE", + "khhhhh", + "#@*&", + "H**p m*", + "H-hhhhh..." + ], - "didyouhearthat": [ - "Did you hear that?", - "Did you see that?", - "What was that?" - ], + "didyouhearthat": [ + "Did you hear that?", + "Did you see that?", + "What was that?" + ], - "imatraitor": [ - "Hail Ratvar", - "Hail Nar'Sie", - "Hey, i've got some TC left, want something?", - "Viva!", - "I'll spare you if you don't tell anybody about me", - "Hey, are you a traitor too?", - "You're my target, but @pick(excuses)", - "Are you mr. @pick(ling_names)?" - ], + "imatraitor": [ + "Hail Ratvar", + "Hail Nar'Sie", + "Hey, i've got some TC left, want something?", + "Viva!", + "I'll spare you if you don't tell anybody about me", + "Hey, are you a traitor too?", + "You're my target, but @pick(excuses)", + "Are you mr. @pick(ling_names)?" + ], - "excuses": [ - "i like you, so i'll spare you", - "i don't really feel like following objectives today", - "i'm not robust enough to fight you", - "who cares", - "i'll kill you later" - ], + "excuses": [ + "i like you, so i'll spare you", + "i don't really feel like following objectives today", + "i'm not robust enough to fight you", + "who cares", + "i'll kill you later" + ], - "ling_names": [ - "Alpha", - "Beta", - "Gamma", - "Delta", - "Epsilon", - "Eta", - "Theta", - "Lambda", - "Mu", - "Xi", - "Rho", - "Sigma", - "Tau", - "Upsilon", - "Phi", - "Psi", - "Omega" - ], + "ling_names": [ + "Alpha", + "Beta", + "Gamma", + "Delta", + "Epsilon", + "Eta", + "Theta", + "Lambda", + "Mu", + "Xi", + "Rho", + "Sigma", + "Tau", + "Upsilon", + "Phi", + "Psi", + "Omega" + ], - "doubt": [ - "Why?", - "What?", - "Wait, what?", - "Wait", - "Hold on", - "Uh..." - ], + "doubt": [ + "Why?", + "What?", + "Wait, what?", + "Wait", + "Hold on", + "Uh..." + ], - "aggressive": [ - "Give me that!", - "I'm going to kill you!", - "Fuck you!" - ], + "aggressive": [ + "Give me that!", + "I'm going to kill you!", + "Fuck you!" + ], - "help": [ - "HELP", - "HELP ME", - "HELP HIM", - "HELP HER", - "HELP THEM", - "HELP US", - "HELP YOURSELF" - ], + "help": [ + "HELP", + "HELP ME", + "HELP HIM", + "HELP HER", + "HELP THEM", + "HELP US", + "HELP YOURSELF" + ], - "escape": [ - "RUN!!", - "They're behind me!", - "It's here!", - "Follow me!", - "Follow me" - ], + "escape": [ + "RUN!!", + "They're behind me!", + "It's here!", + "Follow me!", + "Follow me" + ], - "infection_advice": [ - "stay away", - "don't get close", - "be careful", - "help me", - "kill me" - ], + "infection_advice": [ + "stay away", + "don't get close", + "be careful", + "help me", + "kill me" + ], - "people": [ - "Captain", - "Hos", - "Cmo", - "Rd", - "Ce", - "Hop", - "Janitor", - "AI", - "Viro", - "Qm", - "[target.first_name()]" - ], + "people": [ + "Captain", + "Hos", + "Cmo", + "Rd", + "Ce", + "Hop", + "Janitor", + "AI", + "Viro", + "Qm", + "[target.first_name()]" + ], - "accusations": [ - "rogue", - "cult", - "a cultist", - "clockcult", - "a clock cultist", - "a revhead", - "a rev", - "a gang leader", - "a gangster", - "a traitor", - "a tator", - "a ling", - "a changeling" - ], + "accusations": [ + "rogue", + "cult", + "a cultist", + "clockcult", + "a clock cultist", + "a revhead", + "a rev", + "a gang leader", + "a gangster", + "a traitor", + "a tator", + "a ling", + "a changeling" + ], - "threat": [ - "Cult", - "Wizard", - "Blob", - "Ling", - "Ops", - "Swarmers", - "Revenant", - "Traitor", - "Harm", - "I hear flashing", - "Help" - ], + "threat": [ + "Cult", + "Wizard", + "Blob", + "Ling", + "Ops", + "Swarmers", + "Revenant", + "Traitor", + "Harm", + "I hear flashing", + "Help" + ], - "location": [ - "bridge", - "armory", - "sec", - "security", - "science", - "engineering", - "cargo", - "medbay", - "atmos", - "maint", - "hops office", - "captains office", - "chapel", - "library", - "tool storage", - "botany", - "kitchen", - "the ai sat" - ], + "location": [ + "bridge", + "armory", + "sec", + "security", + "science", + "engineering", + "cargo", + "medbay", + "atmos", + "maint", + "hops office", + "captains office", + "chapel", + "library", + "tool storage", + "botany", + "kitchen", + "the ai sat" + ], - "advice": [ - "Hmm...not sure about that.", - "Yes. You're doing the right thing.", - "No. Stop what you're doing.", - "You should be wary of that person.", - "Trust that person.", - "That person wants to kill you.", - "Kill that person. You know who.", - "You should go somewhere else. Quickly.", - "Good luck. You'll need it.", - "You have my permission. Do it." - ], + "advice": [ + "Hmm...not sure about that.", + "Yes. You're doing the right thing.", + "No. Stop what you're doing.", + "You should be wary of that person.", + "Trust that person.", + "That person wants to kill you.", + "Kill that person. You know who.", + "You should go somewhere else. Quickly.", + "Good luck. You'll need it.", + "You have my permission. Do it." + ], - "chemicals": [ - "Ooze", - "Fire", - "Earth", - "Lightning", - "Air", - "Magic", - "Spiders", - "Button", - "Surprise", - "Happiness", - "Despair", - "Blood", - "Awesome", - "Infinity", - "Electronics", - "Time", - "Space", - "Pain", - "Guts", - "Life", - "Death", - "Phlebotinium", - "Mana", - "Energy", - "?????" - ] + "chemicals": [ + "Ooze", + "Fire", + "Earth", + "Lightning", + "Air", + "Magic", + "Spiders", + "Button", + "Surprise", + "Happiness", + "Despair", + "Blood", + "Awesome", + "Infinity", + "Electronics", + "Time", + "Space", + "Pain", + "Guts", + "Life", + "Death", + "Phlebotinium", + "Mana", + "Energy", + "?????" + ] -} +} \ No newline at end of file diff --git a/strings/phobia.json b/strings/phobia.json new file mode 100644 index 0000000000..343a475b56 --- /dev/null +++ b/strings/phobia.json @@ -0,0 +1,63 @@ +{ + "spiders": [ + "spider", + "web", + "arachnid" + ], + + "space": [ + "space", + "star", + "universe", + "void", + "galaxy", + "spess" + ], + + "security": [ + " sec ", + "security", + "shitcurity", + "baton", + "taser", + "beepsky", + "hos", + "brig", + "gulag" + ], + + "clowns": [ + "clown", + "honk", + "banana", + "slip" + ], + + "greytide": [ + "assistant", + "grey", + "gasmask", + "gas mask", + "stunprod", + "spear", + "revolution", + "viva" + ], + + "lizards": [ + "lizard", + "ligger", + "hiss", + "wag" + ], + + "skeletons": [ + "skeleton", + "milk", + "xylophone", + "bone", + "calcium", + "the ride never ends", + "doot" + ] +} \ No newline at end of file diff --git a/strings/brain_damage_lines.json b/strings/traumas.json similarity index 79% rename from strings/brain_damage_lines.json rename to strings/traumas.json index 5efd3ac9b2..9b14a7b530 100644 --- a/strings/brain_damage_lines.json +++ b/strings/traumas.json @@ -57,7 +57,7 @@ "i will snatch erry motherfucker birthday", "the ai and borgs are mettacomming I think", "u just did the world a little bit more sad place for someone", - "WHERES THE SLIP REWRITE WHERE THR FUCK ID IT?" + "WHERES THE SLIP REWRITE WHERE THR FUCK ID IT?", "CEMISTRY SUKS!!!!!!!!", "youed call her a toeugh bithc", "git gud!!", @@ -69,9 +69,9 @@ "iS tHis bay?", "NO PRED CAN eVER CATCH MI", "SCIENCE GIB SHINK RAY PLS", - "KILL PUNPUN 4 FUN xDD" + "KILL PUNPUN 4 FUN xDD", "ooc wow rly?", - "i play @pick(roles) to only ORDER not DO" + "i play @pick(roles) to only ORDER not DO", "CRAGO ORDER @pick(cargo) PLS", "erp?", "i want to digest u!!!", @@ -156,7 +156,9 @@ "dullus", "colon marhens", "haylo", - "EEGEE" + "EEGEE", + "mr terry", + "berry" ], "create_verbs": [ @@ -184,33 +186,55 @@ "", ";", ".h" - ], - - "roles": [ - "heds", - "ceptin", - "hop", - "arrdee", - "sek" - ], - - "cargo": [ - "GUNS", - "HATS", - "PIZEH", - "MEMES", - "GLOWY CYSTAL" - - ], - - "s_roles": [ - "ert", - "shadowlig", - "ninja", - "admen", - "mantor", - "bluh daymon", - "wizzerd" - - ] + ], + + "god_foe": [ + "MORTALS", + "HERETICS", + "INSECTS", + "UNBELIEVERS", + "BLASPHEMERS", + "PARASITES", + "WEAKLINGS", + "PEASANTS" + ], + + "god_aggressive": [ + "BEGONE, @pick(god_foe)!", + "DIE, @pick(god_foe)!", + "BLEED, @pick(god_foe)!", + "BURN, @pick(god_foe)!", + "ALL WILL FALL BEFORE ME!", + "ENDLESS SUFFERING AWAITS YOU, @pick(god_foe).", + "DEATH TO @pick(god_foe)!" + ], + + "god_neutral": [ + "STOP", + "HALT.", + "BE SILENT.", + "QUIET", + "SEE THE TRUTH BEFORE YOU, MORTALS.", + "MORTALS, SAY YOUR NAME", + "BEGONE, MORTALS.", + "BE HEALED, MORTALS. I AM FEELING MERCIFUL.", + "DANCE FOR ME, LITTLE MORTALS.", + "YOU. STOP.", + "REST, MORTALS, TOMORROW IS A LONG DAY.", + "YOU MORTALS MAKE ME SICK.", + "HONK..." + ], + + "god_unstun": [ + "GET UP. I HAVE NO TIME TO LOSE.", + "GET UP, PRIEST.", + "GET UP." + ], + + "god_heal": [ + "YOU WILL LIVE TO SEE ANOTHER DAY.", + "YOU SHALL SURVIVE THIS, MY PRIEST.", + "BE HEALED, PRIEST.", + "YOUR LIFE IS IMPORTANT. KEEP IT." + ] } diff --git a/tgstation.dme b/tgstation.dme index 328af157f5..04f2ddcfed 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -54,7 +54,7 @@ #include "code\__DEFINES\logging.dm" #include "code\__DEFINES\machines.dm" #include "code\__DEFINES\maps.dm" -#include "code\__DEFINES\math.dm" +#include "code\__DEFINES\maths.dm" #include "code\__DEFINES\MC.dm" #include "code\__DEFINES\menu.dm" #include "code\__DEFINES\misc.dm" @@ -69,9 +69,11 @@ #include "code\__DEFINES\radiation.dm" #include "code\__DEFINES\radio.dm" #include "code\__DEFINES\reagents.dm" +#include "code\__DEFINES\research.dm" #include "code\__DEFINES\robots.dm" #include "code\__DEFINES\role_preferences.dm" #include "code\__DEFINES\say.dm" +#include "code\__DEFINES\server_tools.config.dm" #include "code\__DEFINES\server_tools.dm" #include "code\__DEFINES\shuttles.dm" #include "code\__DEFINES\sight.dm" @@ -99,7 +101,6 @@ #include "code\__HELPERS\global_lists.dm" #include "code\__HELPERS\icon_smoothing.dm" #include "code\__HELPERS\icons.dm" -#include "code\__HELPERS\maths.dm" #include "code\__HELPERS\matrices.dm" #include "code\__HELPERS\mobs.dm" #include "code\__HELPERS\names.dm" @@ -107,6 +108,7 @@ #include "code\__HELPERS\pronouns.dm" #include "code\__HELPERS\radiation.dm" #include "code\__HELPERS\radio.dm" +#include "code\__HELPERS\roundend.dm" #include "code\__HELPERS\sanitize_values.dm" #include "code\__HELPERS\shell.dm" #include "code\__HELPERS\stat_tracking.dm" @@ -116,6 +118,7 @@ #include "code\__HELPERS\type2type.dm" #include "code\__HELPERS\type2type_vr.dm" #include "code\__HELPERS\unsorted.dm" +#include "code\__HELPERS\view.dm" #include "code\__HELPERS\sorts\__main.dm" #include "code\__HELPERS\sorts\InsertSort.dm" #include "code\__HELPERS\sorts\MergeSort.dm" @@ -188,7 +191,6 @@ #include "code\citadel\cit_spawners.dm" #include "code\citadel\cit_uniforms.dm" #include "code\citadel\cit_vendors.dm" -#include "code\citadel\cit_weapons.dm" #include "code\citadel\dogborgstuff.dm" #include "code\citadel\plasmacases.dm" #include "code\citadel\crew_objectives\cit_crewobjectives_cargo.dm" @@ -222,9 +224,9 @@ #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\configuration\entries\general.dm" #include "code\controllers\subsystem\acid.dm" #include "code\controllers\subsystem\air.dm" #include "code\controllers\subsystem\assets.dm" @@ -257,6 +259,7 @@ #include "code\controllers\subsystem\radiation.dm" #include "code\controllers\subsystem\radio.dm" #include "code\controllers\subsystem\religion.dm" +#include "code\controllers\subsystem\research.dm" #include "code\controllers\subsystem\server_maint.dm" #include "code\controllers\subsystem\shuttle.dm" #include "code\controllers\subsystem\spacedrift.dm" @@ -269,6 +272,7 @@ #include "code\controllers\subsystem\time_track.dm" #include "code\controllers\subsystem\timer.dm" #include "code\controllers\subsystem\title.dm" +#include "code\controllers\subsystem\traumas.dm" #include "code\controllers\subsystem\vote.dm" #include "code\controllers\subsystem\weather.dm" #include "code\controllers\subsystem\processing\circuit.dm" @@ -306,8 +310,8 @@ #include "code\datums\progressbar.dm" #include "code\datums\radiation_wave.dm" #include "code\datums\recipe.dm" -#include "code\datums\riding.dm" #include "code\datums\ruins.dm" +#include "code\datums\saymode.dm" #include "code\datums\shuttles.dm" #include "code\datums\soullink.dm" #include "code\datums\spawners_menu.dm" @@ -326,19 +330,31 @@ #include "code\datums\antagonists\devil.dm" #include "code\datums\antagonists\internal_affairs.dm" #include "code\datums\antagonists\ninja.dm" +#include "code\datums\antagonists\nukeop.dm" #include "code\datums\antagonists\pirate.dm" #include "code\datums\antagonists\revolution.dm" #include "code\datums\antagonists\wizard.dm" +#include "code\datums\brain_damage\brain_trauma.dm" +#include "code\datums\brain_damage\imaginary_friend.dm" +#include "code\datums\brain_damage\mild.dm" +#include "code\datums\brain_damage\phobia.dm" +#include "code\datums\brain_damage\severe.dm" +#include "code\datums\brain_damage\special.dm" +#include "code\datums\brain_damage\split_personality.dm" #include "code\datums\components\_component.dm" #include "code\datums\components\archaeology.dm" +#include "code\datums\components\caltrop.dm" #include "code\datums\components\chasm.dm" #include "code\datums\components\decal.dm" +#include "code\datums\components\knockoff.dm" #include "code\datums\components\infective.dm" +#include "code\datums\components\jousting.dm" #include "code\datums\components\material_container.dm" #include "code\datums\components\ntnet_interface.dm" #include "code\datums\components\paintable.dm" #include "code\datums\components\rad_insulation.dm" #include "code\datums\components\radioactive.dm" +#include "code\datums\components\riding.dm" #include "code\datums\components\signal_redirect.dm" #include "code\datums\components\slippery.dm" #include "code\datums\components\spooky.dm" @@ -388,6 +404,7 @@ #include "code\datums\diseases\advance\symptoms\shivering.dm" #include "code\datums\diseases\advance\symptoms\skin.dm" #include "code\datums\diseases\advance\symptoms\sneeze.dm" +#include "code\datums\diseases\advance\symptoms\species.dm" #include "code\datums\diseases\advance\symptoms\symptoms.dm" #include "code\datums\diseases\advance\symptoms\viral.dm" #include "code\datums\diseases\advance\symptoms\vision.dm" @@ -409,8 +426,16 @@ #include "code\datums\martial\cqc.dm" #include "code\datums\martial\krav_maga.dm" #include "code\datums\martial\plasma_fist.dm" +#include "code\datums\martial\psychotic_brawl.dm" #include "code\datums\martial\sleeping_carp.dm" #include "code\datums\martial\wrestling.dm" +#include "code\datums\mutations\body.dm" +#include "code\datums\mutations\chameleon.dm" +#include "code\datums\mutations\cold_resistance.dm" +#include "code\datums\mutations\hulk.dm" +#include "code\datums\mutations\sight.dm" +#include "code\datums\mutations\speech.dm" +#include "code\datums\mutations\telekinesis.dm" #include "code\datums\ruins\lavaland.dm" #include "code\datums\ruins\space.dm" #include "code\datums\status_effects\buffs.dm" @@ -467,6 +492,7 @@ #include "code\game\gamemodes\antag_hud.dm" #include "code\game\gamemodes\antag_spawner.dm" #include "code\game\gamemodes\antag_spawner_cit.dm" +#include "code\game\gamemodes\antag_team.dm" #include "code\game\gamemodes\cit_objectives.dm" #include "code\game\gamemodes\events.dm" #include "code\game\gamemodes\game_mode.dm" @@ -543,13 +569,16 @@ #include "code\game\gamemodes\clock_cult\clock_items\wraith_spectacles.dm" #include "code\game\gamemodes\clock_cult\clock_items\clock_weapons\_call_weapon.dm" #include "code\game\gamemodes\clock_cult\clock_items\clock_weapons\ratvarian_spear.dm" +#include "code\game\gamemodes\clock_cult\clock_mobs\_eminence.dm" #include "code\game\gamemodes\clock_cult\clock_mobs\clockwork_marauder.dm" #include "code\game\gamemodes\clock_cult\clock_scriptures\scripture_applications.dm" #include "code\game\gamemodes\clock_cult\clock_scriptures\scripture_cyborg.dm" #include "code\game\gamemodes\clock_cult\clock_scriptures\scripture_drivers.dm" #include "code\game\gamemodes\clock_cult\clock_scriptures\scripture_scripts.dm" +#include "code\game\gamemodes\clock_cult\clock_structures\_trap_object.dm" #include "code\game\gamemodes\clock_cult\clock_structures\ark_of_the_clockwork_justicar.dm" #include "code\game\gamemodes\clock_cult\clock_structures\clockwork_obelisk.dm" +#include "code\game\gamemodes\clock_cult\clock_structures\eminence_spire.dm" #include "code\game\gamemodes\clock_cult\clock_structures\heralds_beacon.dm" #include "code\game\gamemodes\clock_cult\clock_structures\mania_motor.dm" #include "code\game\gamemodes\clock_cult\clock_structures\ocular_warden.dm" @@ -557,6 +586,11 @@ #include "code\game\gamemodes\clock_cult\clock_structures\stargazer.dm" #include "code\game\gamemodes\clock_cult\clock_structures\taunting_trail.dm" #include "code\game\gamemodes\clock_cult\clock_structures\wall_gear.dm" +#include "code\game\gamemodes\clock_cult\clock_structures\trap_triggers\lever.dm" +#include "code\game\gamemodes\clock_cult\clock_structures\trap_triggers\pressure_sensor.dm" +#include "code\game\gamemodes\clock_cult\clock_structures\trap_triggers\repeater.dm" +#include "code\game\gamemodes\clock_cult\clock_structures\traps\brass_skewer.dm" +#include "code\game\gamemodes\clock_cult\clock_structures\traps\steam_vent.dm" #include "code\game\gamemodes\cult\cult.dm" #include "code\game\gamemodes\cult\cult_comms.dm" #include "code\game\gamemodes\cult\cult_items.dm" @@ -857,6 +891,7 @@ #include "code\game\objects\items\mop.dm" #include "code\game\objects\items\paint.dm" #include "code\game\objects\items\paiwire.dm" +#include "code\game\objects\items\pet_carrier.dm" #include "code\game\objects\items\pinpointer.dm" #include "code\game\objects\items\plushes.dm" #include "code\game\objects\items\pneumaticCannon.dm" @@ -897,7 +932,6 @@ #include "code\game\objects\items\devices\instruments.dm" #include "code\game\objects\items\devices\laserpointer.dm" #include "code\game\objects\items\devices\lightreplacer.dm" -#include "code\game\objects\items\devices\machineprototype.dm" #include "code\game\objects\items\devices\megaphone.dm" #include "code\game\objects\items\devices\multitool.dm" #include "code\game\objects\items\devices\paicard.dm" @@ -1275,6 +1309,7 @@ #include "code\modules\client\client_defines.dm" #include "code\modules\client\client_procs.dm" #include "code\modules\client\message.dm" +#include "code\modules\client\player_details.dm" #include "code\modules\client\preferences.dm" #include "code\modules\client\preferences_savefile.dm" #include "code\modules\client\preferences_toggles.dm" @@ -1465,7 +1500,6 @@ #include "code\modules\food_and_drinks\kitchen_machinery\food_cart.dm" #include "code\modules\food_and_drinks\kitchen_machinery\gibber.dm" #include "code\modules\food_and_drinks\kitchen_machinery\icecream_vat.dm" -#include "code\modules\food_and_drinks\kitchen_machinery\juicer.dm" #include "code\modules\food_and_drinks\kitchen_machinery\microwave.dm" #include "code\modules\food_and_drinks\kitchen_machinery\monkeyrecycler.dm" #include "code\modules\food_and_drinks\kitchen_machinery\processor.dm" @@ -1558,6 +1592,7 @@ #include "code\modules\integrated_electronics\core\special_pins\char_pin.dm" #include "code\modules\integrated_electronics\core\special_pins\color_pin.dm" #include "code\modules\integrated_electronics\core\special_pins\dir_pin.dm" +#include "code\modules\integrated_electronics\core\special_pins\index_pin.dm" #include "code\modules\integrated_electronics\core\special_pins\list_pin.dm" #include "code\modules\integrated_electronics\core\special_pins\number_pin.dm" #include "code\modules\integrated_electronics\core\special_pins\ref_pin.dm" @@ -1593,6 +1628,7 @@ #include "code\modules\jobs\job_types\security.dm" #include "code\modules\jobs\job_types\silicon.dm" #include "code\modules\jobs\map_changes\map_changes.dm" +#include "code\modules\language\aphasia.dm" #include "code\modules\language\beachbum.dm" #include "code\modules\language\codespeak.dm" #include "code\modules\language\common.dm" @@ -1902,7 +1938,6 @@ #include "code\modules\mob\living\simple_animal\hostile\bear.dm" #include "code\modules\mob\living\simple_animal\hostile\bees.dm" #include "code\modules\mob\living\simple_animal\hostile\carp.dm" -#include "code\modules\mob\living\simple_animal\hostile\creature.dm" #include "code\modules\mob\living\simple_animal\hostile\eyeballs.dm" #include "code\modules\mob\living\simple_animal\hostile\faithless.dm" #include "code\modules\mob\living\simple_animal\hostile\giant_spider.dm" @@ -1915,6 +1950,7 @@ #include "code\modules\mob\living\simple_animal\hostile\mimic.dm" #include "code\modules\mob\living\simple_animal\hostile\mushroom.dm" #include "code\modules\mob\living\simple_animal\hostile\nanotrasen.dm" +#include "code\modules\mob\living\simple_animal\hostile\netherworld.dm" #include "code\modules\mob\living\simple_animal\hostile\pirate.dm" #include "code\modules\mob\living\simple_animal\hostile\russian.dm" #include "code\modules\mob\living\simple_animal\hostile\skeleton.dm" @@ -2194,32 +2230,42 @@ #include "code\modules\recycling\disposal\pipe.dm" #include "code\modules\recycling\disposal\pipe_sorting.dm" #include "code\modules\research\circuitprinter.dm" +#include "code\modules\research\departmental_circuit_imprinter.dm" +#include "code\modules\research\departmental_lathe.dm" #include "code\modules\research\designs.dm" #include "code\modules\research\destructive_analyzer.dm" #include "code\modules\research\experimentor.dm" #include "code\modules\research\message_server.dm" #include "code\modules\research\protolathe.dm" -#include "code\modules\research\rd-readme.dm" #include "code\modules\research\rdconsole.dm" #include "code\modules\research\rdmachines.dm" -#include "code\modules\research\research.dm" +#include "code\modules\research\research_disk.dm" #include "code\modules\research\server.dm" #include "code\modules\research\stock_parts.dm" #include "code\modules\research\designs\AI_module_designs.dm" #include "code\modules\research\designs\autolathe_designs.dm" #include "code\modules\research\designs\biogenerator_designs.dm" +#include "code\modules\research\designs\bluespace_designs.dm" #include "code\modules\research\designs\comp_board_designs.dm" #include "code\modules\research\designs\computer_part_designs.dm" +#include "code\modules\research\designs\electronics_designs.dm" +#include "code\modules\research\designs\equipment_designs.dm" #include "code\modules\research\designs\limbgrower_designs.dm" #include "code\modules\research\designs\machine_designs.dm" #include "code\modules\research\designs\mecha_designs.dm" #include "code\modules\research\designs\mechfabricator_designs.dm" #include "code\modules\research\designs\medical_designs.dm" +#include "code\modules\research\designs\mining_designs.dm" +#include "code\modules\research\designs\misc_designs.dm" #include "code\modules\research\designs\power_designs.dm" #include "code\modules\research\designs\smelting_designs.dm" #include "code\modules\research\designs\stock_parts_designs.dm" #include "code\modules\research\designs\telecomms_designs.dm" #include "code\modules\research\designs\weapon_designs.dm" +#include "code\modules\research\techweb\__techweb_helpers.dm" +#include "code\modules\research\techweb\_techweb.dm" +#include "code\modules\research\techweb\_techweb_node.dm" +#include "code\modules\research\techweb\all_nodes.dm" #include "code\modules\research\xenobiology\xenobio_camera.dm" #include "code\modules\research\xenobiology\xenobiology.dm" #include "code\modules\ruins\lavaland_ruin_code.dm" @@ -2313,6 +2359,7 @@ #include "code\modules\stock_market\stockmarket.dm" #include "code\modules\stock_market\stocks.dm" #include "code\modules\surgery\amputation.dm" +#include "code\modules\surgery\brain_surgery.dm" #include "code\modules\surgery\cavity_implant.dm" #include "code\modules\surgery\core_removal.dm" #include "code\modules\surgery\dental_implant.dm" @@ -2375,15 +2422,20 @@ #include "code\modules\tgui\states\zlevel.dm" #include "code\modules\tooltip\tooltip.dm" #include "code\modules\uplink\uplink.dm" -#include "code\modules\uplink\uplink_item.dm" -#include "code\modules\uplink\uplink_item_cit.dm" +#include "code\modules\uplink\uplink_devices.dm" +#include "code\modules\uplink\uplink_items.dm" +#include "code\modules\uplink\uplink_purchase_log.dm" +#include "code\modules\vehicles\_vehicle.dm" #include "code\modules\vehicles\atv.dm" #include "code\modules\vehicles\bicycle.dm" +#include "code\modules\vehicles\entered.dm" #include "code\modules\vehicles\pimpin_ride.dm" +#include "code\modules\vehicles\ridden.dm" #include "code\modules\vehicles\scooter.dm" #include "code\modules\vehicles\secway.dm" #include "code\modules\vehicles\speedbike.dm" -#include "code\modules\vehicles\vehicle.dm" +#include "code\modules\vehicles\vehicle_actions.dm" +#include "code\modules\vehicles\vehicle_key.dm" #include "code\modules\vore\hook-defs_vr.dm" #include "code\modules\vore\trycatch_vr.dm" #include "code\modules\vore\eating\belly_vr.dm" @@ -2403,5 +2455,11 @@ #include "modular_citadel\cit_medkits.dm" #include "modular_citadel\cit_screenshake.dm" #include "modular_citadel\cit_turfs.dm" +#include "modular_citadel\citadel_ghostrole_spawners.dm" +#include "modular_citadel\cydonian_armor.dm" #include "modular_citadel\polychromic_clothes.dm" +#include "modular_citadel\code\datums\uplink_items_cit.dm" +#include "modular_citadel\code\game\objects\items\devices\PDA\PDA.dm" +#include "modular_citadel\code\game\objects\items\melee\eutactic_blades.dm" +#include "modular_citadel\code\modules\crafting\recipes.dm" // END_INCLUDE diff --git a/tgui/assets/tgui.css b/tgui/assets/tgui.css index ffe61666b9..256b53c106 100644 --- a/tgui/assets/tgui.css +++ b/tgui/assets/tgui.css @@ -1 +1 @@ -@charset "utf-8";body,html{box-sizing:border-box;height:100%;margin:0}html{overflow:hidden;cursor:default}body{overflow:auto;font-family:Verdana,Geneva,sans-serif;font-size:12px;color:#fff;background-color:#2a2a2a;background-image:linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}*,:after,:before{box-sizing:inherit}h1,h2,h3,h4{display:inline-block;margin:0;padding:6px 0}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4{font-size:12px}body.clockwork{background:linear-gradient(180deg,#b18b25 0,#5f380e);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ffb18b25",endColorstr="#ff5f380e",GradientType=0)}body.clockwork .normal{color:#b18b25}body.clockwork .good{color:#cfba47}body.clockwork .average{color:#896b19}body.clockwork .bad{color:#5f380e}body.clockwork .highlight{color:#b18b25}body.clockwork main{display:block;margin-top:32px;padding:2px 6px 0}body.clockwork hr{height:2px;background-color:#b18b25;border:none}body.clockwork .hidden{display:none}body.clockwork .bar .barText,body.clockwork span.button{color:#b18b25;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.clockwork .bold{font-weight:700}body.clockwork .italic{font-style:italic}body.clockwork [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.clockwork div[data-tooltip],body.clockwork span[data-tooltip]{position:relative}body.clockwork div[data-tooltip]:after,body.clockwork span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #170800;background-color:#2d1400}body.clockwork div[data-tooltip]:hover:after,body.clockwork span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.clockwork div[data-tooltip].tooltip-top:after,body.clockwork span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-top:hover:after,body.clockwork span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:after,body.clockwork span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:hover:after,body.clockwork span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-left:after,body.clockwork span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-left:hover:after,body.clockwork span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:after,body.clockwork span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:hover:after,body.clockwork span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #170800;background:#2d1400}body.clockwork .bar .barText{position:absolute;top:0;right:3px}body.clockwork .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#b18b25}body.clockwork .bar .barFill.good{background-color:#cfba47}body.clockwork .bar .barFill.average{background-color:#896b19}body.clockwork .bar .barFill.bad{background-color:#5f380e}body.clockwork span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #170800}body.clockwork span.button .fa{padding-right:2px}body.clockwork span.button.normal{transition:background-color .5s;background-color:#5f380e}body.clockwork span.button.normal.active:focus,body.clockwork span.button.normal.active:hover{transition:background-color .25s;background-color:#704211;outline:0}body.clockwork span.button.disabled{transition:background-color .5s;background-color:#2d1400}body.clockwork span.button.disabled.active:focus,body.clockwork span.button.disabled.active:hover{transition:background-color .25s;background-color:#441e00;outline:0}body.clockwork span.button.selected{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.selected.active:focus,body.clockwork span.button.selected.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.toggle{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.toggle.active:focus,body.clockwork span.button.toggle.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.caution{transition:background-color .5s;background-color:#be6209}body.clockwork span.button.caution.active:focus,body.clockwork span.button.caution.active:hover{transition:background-color .25s;background-color:#cd6a0a;outline:0}body.clockwork span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.clockwork span.button.danger.active:focus,body.clockwork span.button.danger.active:hover{transition:background-color .25s;background-color:#abaf00;outline:0}body.clockwork span.button.gridable{width:125px;margin:2px 0}body.clockwork span.button.gridable.center{text-align:center;width:75px}body.clockwork span.button+span:not(.button),body.clockwork span:not(.button)+span.button{margin-left:5px}body.clockwork div.display{width:100%;padding:4px;margin:6px 0;background-color:#2d1400;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400);background-color:rgba(45,20,0,.9);box-shadow:inset 0 0 5px rgba(0,0,0,.3)}body.clockwork div.display.tabular{padding:0;margin:0}body.clockwork div.display header,body.clockwork div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#cfba47;border-bottom:2px solid #b18b25}body.clockwork div.display header .buttonRight,body.clockwork div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.clockwork div.display article,body.clockwork div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.clockwork input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#b18b25;background-color:#cfba47;border:1px solid #272727}body.clockwork input.number{width:35px}body.clockwork input::-webkit-input-placeholder{color:#999}body.clockwork input:-ms-input-placeholder{color:#999}body.clockwork input::placeholder{color:#999}body.clockwork input::-ms-clear{display:none}body.clockwork svg.linegraph{overflow:hidden}body.clockwork div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#2d1400;font-weight:700;font-style:italic;background-color:#000;background-image:repeating-linear-gradient(-45deg,#000,#000 10px,#170800 0,#170800 20px)}body.clockwork div.notice .label{color:#2d1400}body.clockwork div.notice .content:only-of-type{padding:0}body.clockwork div.notice hr{background-color:#896b19}body.clockwork div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #5f380e;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.clockwork section .cell,body.clockwork section .content,body.clockwork section .label,body.clockwork section .line,body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.clockwork section{display:table-row;width:100%}body.clockwork section:not(:first-child){padding-top:4px}body.clockwork section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.clockwork section .label{width:1%;padding-right:32px;white-space:nowrap;color:#b18b25}body.clockwork section .content:not(:last-child){padding-right:16px}body.clockwork section .line{width:100%}body.clockwork section .cell:not(:first-child){text-align:center;padding-top:0}body.clockwork section .cell span.button{width:75px}body.clockwork section:not(:last-child){padding-right:4px}body.clockwork div.subdisplay{width:100%;margin:0}body.clockwork header.titlebar .close,body.clockwork header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#cfba47}body.clockwork header.titlebar .close:hover,body.clockwork header.titlebar .minimize:hover{color:#d1bd50}body.clockwork header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#5f380e;border-bottom:1px solid #170800;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.clockwork header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.clockwork header.titlebar .title{position:absolute;top:6px;left:46px;color:#cfba47;font-size:16px;white-space:nowrap}body.clockwork header.titlebar .minimize{position:absolute;top:6px;right:46px}body.clockwork header.titlebar .close{position:absolute;top:4px;right:12px}body.nanotrasen{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgNDI1IDIwMCIgb3BhY2l0eT0iLjMzIj4NCiAgPHBhdGggZD0ibSAxNzguMDAzOTksMC4wMzg2OSAtNzEuMjAzOTMsMCBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgLTYuNzYxMzQsNi4wMjU1NSBsIDAsMTg3Ljg3MTQ3IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM0LDYuMDI1NTQgbCA1My4xMDcyLDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xMDEuNTQ0MDE4IDcyLjIxNjI4LDEwNC42OTkzOTggYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDUuNzYwMTUsMi44NzAxNiBsIDczLjU1NDg3LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xODcuODcxNDcgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTM1LC02LjAyNTU1IGwgLTU0LjcxNjQ0LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTMzLDYuMDI1NTUgbCAwLDEwMi42MTkzNSBMIDE4My43NjQxMywyLjkwODg2IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNS43NjAxNCwtMi44NzAxNyB6IiAvPg0KICA8cGF0aCBkPSJNIDQuODQ0NjMzMywyMi4xMDg3NSBBIDEzLjQxMjAzOSwxMi41MDE4NDIgMCAwIDEgMTMuNDc3NTg4LDAuMDM5MjQgbCA2Ni4xMTgzMTUsMCBhIDUuMzY0ODE1OCw1LjAwMDczNyAwIDAgMSA1LjM2NDgyMyw1LjAwMDczIGwgMCw3OS44NzkzMSB6IiAvPg0KICA8cGF0aCBkPSJtIDQyMC4xNTUzNSwxNzcuODkxMTkgYSAxMy40MTIwMzgsMTIuNTAxODQyIDAgMCAxIC04LjYzMjk1LDIyLjA2OTUxIGwgLTY2LjExODMyLDAgYSA1LjM2NDgxNTIsNS4wMDA3MzcgMCAwIDEgLTUuMzY0ODIsLTUuMDAwNzQgbCAwLC03OS44NzkzMSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}body.nanotrasen .normal{color:#40628a}body.nanotrasen .good{color:#537d29}body.nanotrasen .average{color:#be6209}body.nanotrasen .bad{color:#b00e0e}body.nanotrasen .highlight{color:#8ba5c4}body.nanotrasen main{display:block;margin-top:32px;padding:2px 6px 0}body.nanotrasen hr{height:2px;background-color:#40628a;border:none}body.nanotrasen .hidden{display:none}body.nanotrasen .bar .barText,body.nanotrasen span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.nanotrasen .bold{font-weight:700}body.nanotrasen .italic{font-style:italic}body.nanotrasen [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.nanotrasen div[data-tooltip],body.nanotrasen span[data-tooltip]{position:relative}body.nanotrasen div[data-tooltip]:after,body.nanotrasen span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.nanotrasen div[data-tooltip]:hover:after,body.nanotrasen span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.nanotrasen div[data-tooltip].tooltip-top:after,body.nanotrasen span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-top:hover:after,body.nanotrasen span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:after,body.nanotrasen span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:hover:after,body.nanotrasen span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-left:after,body.nanotrasen span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-left:hover:after,body.nanotrasen span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:after,body.nanotrasen span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:hover:after,body.nanotrasen span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #40628a;background:#272727}body.nanotrasen .bar .barText{position:absolute;top:0;right:3px}body.nanotrasen .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#40628a}body.nanotrasen .bar .barFill.good{background-color:#537d29}body.nanotrasen .bar .barFill.average{background-color:#be6209}body.nanotrasen .bar .barFill.bad{background-color:#b00e0e}body.nanotrasen span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.nanotrasen span.button .fa{padding-right:2px}body.nanotrasen span.button.normal{transition:background-color .5s;background-color:#40628a}body.nanotrasen span.button.normal.active:focus,body.nanotrasen span.button.normal.active:hover{transition:background-color .25s;background-color:#4f78aa;outline:0}body.nanotrasen span.button.disabled{transition:background-color .5s;background-color:#999}body.nanotrasen span.button.disabled.active:focus,body.nanotrasen span.button.disabled.active:hover{transition:background-color .25s;background-color:#a8a8a8;outline:0}body.nanotrasen span.button.selected{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.selected.active:focus,body.nanotrasen span.button.selected.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.toggle{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.toggle.active:focus,body.nanotrasen span.button.toggle.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.caution{transition:background-color .5s;background-color:#9a9d00}body.nanotrasen span.button.caution.active:focus,body.nanotrasen span.button.caution.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.nanotrasen span.button.danger{transition:background-color .5s;background-color:#9d0808}body.nanotrasen span.button.danger.active:focus,body.nanotrasen span.button.danger.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.nanotrasen span.button.gridable{width:125px;margin:2px 0}body.nanotrasen span.button.gridable.center{text-align:center;width:75px}body.nanotrasen span.button+span:not(.button),body.nanotrasen span:not(.button)+span.button{margin-left:5px}body.nanotrasen div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000);background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5)}body.nanotrasen div.display.tabular{padding:0;margin:0}body.nanotrasen div.display header,body.nanotrasen div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #40628a}body.nanotrasen div.display header .buttonRight,body.nanotrasen div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.nanotrasen div.display article,body.nanotrasen div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.nanotrasen input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#000;background-color:#fff;border:1px solid #272727}body.nanotrasen input.number{width:35px}body.nanotrasen input::-webkit-input-placeholder{color:#999}body.nanotrasen input:-ms-input-placeholder{color:#999}body.nanotrasen input::placeholder{color:#999}body.nanotrasen input::-ms-clear{display:none}body.nanotrasen svg.linegraph{overflow:hidden}body.nanotrasen div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,#bb9b68,#bb9b68 10px,#b1905d 0,#b1905d 20px)}body.nanotrasen div.notice .label{color:#000}body.nanotrasen div.notice .content:only-of-type{padding:0}body.nanotrasen div.notice hr{background-color:#272727}body.nanotrasen div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.nanotrasen section{display:table-row;width:100%}body.nanotrasen section:not(:first-child){padding-top:4px}body.nanotrasen section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.nanotrasen section .label{width:1%;padding-right:32px;white-space:nowrap;color:#8ba5c4}body.nanotrasen section .content:not(:last-child){padding-right:16px}body.nanotrasen section .line{width:100%}body.nanotrasen section .cell:not(:first-child){text-align:center;padding-top:0}body.nanotrasen section .cell span.button{width:75px}body.nanotrasen section:not(:last-child){padding-right:4px}body.nanotrasen div.subdisplay{width:100%;margin:0}body.nanotrasen header.titlebar .close,body.nanotrasen header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#8ba5c4}body.nanotrasen header.titlebar .close:hover,body.nanotrasen header.titlebar .minimize:hover{color:#9cb2cd}body.nanotrasen header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.nanotrasen header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.nanotrasen header.titlebar .title{position:absolute;top:6px;left:46px;color:#8ba5c4;font-size:16px;white-space:nowrap}body.nanotrasen header.titlebar .minimize{position:absolute;top:6px;right:46px}body.nanotrasen header.titlebar .close{position:absolute;top:4px;right:12px}body.syndicate{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgMjAwIDI4OS43NDIiIG9wYWNpdHk9Ii4zMyI+DQogIDxwYXRoIGQ9Im0gOTMuNTM3Njc3LDAgYyAtMTguMTEzMTI1LDAgLTM0LjIyMDEzMywzLjExMTY0IC00OC4zMjM0ODQsOS4zMzQzNyAtMTMuOTY1MDkyLDYuMjIxNjcgLTI0LjYxMjQ0MiwxNS4wNzExNCAtMzEuOTQwNjUxLDI2LjU0NzEgLTcuMTg5OTM5OCwxMS4zMzc4OSAtMTAuMzAxMjI2NiwyNC43NDkxMSAtMTAuMzAxMjI2Niw0MC4yMzQ3OCAwLDEwLjY0NjYyIDIuNzI1MDAyNiwyMC40NjQ2NSA4LjE3NTExMTYsMjkuNDUyNTggNS42MTUyNzcsOC45ODY4NiAxNC4wMzgyNzcsMTcuMzUyMDQgMjUuMjY4ODIxLDI1LjA5NDM2IDExLjIzMDU0NCw3LjYwNTMxIDI2LjUwNzQyMSwxNS40MTgzNSA0NS44MzA1MTQsMjMuNDM3ODIgMTkuOTgzNzQ4LDguMjk1NTcgMzQuODQ4ODQ4LDE1LjU1NDcxIDQ0LjU5Mjk5OCwyMS43NzYzOCA5Ljc0NDE0LDYuMjIyNzMgMTYuNzYxNywxMi44NTg1IDIxLjA1NTcyLDE5LjkwOTUxIDQuMjk0MDQsNy4wNTIwOCA2LjQ0MTkzLDE1Ljc2NDA4IDYuNDQxOTMsMjYuMTM0NTkgMCwxNi4xNzcwMiAtNS4yMDE5NiwyOC40ODIyMiAtMTUuNjA2NzMsMzYuOTE2ODIgLTEwLjIzOTYsOC40MzQ3IC0yNS4wMjIwMywxMi42NTIzIC00NC4zNDUxNjksMTIuNjUyMyAtMTQuMDM4MTcxLDAgLTI1LjUxNTI0NywtMS42NTk0IC0zNC40MzM2MTgsLTQuOTc3NyAtOC45MTgzNywtMy40NTY2IC0xNi4xODU1NzIsLTguNzExMyAtMjEuODAwODM5LC0xNS43NjMzIC01LjYxNTI3NywtNy4wNTIxIC0xMC4wNzQ3OTUsLTE2LjY2MDg4IC0xMy4zNzc4OTksLTI4LjgyODEyIGwgLTI0Ljc3MzE2MjYyOTM5NDUsMCAwLDU2LjgyNjMyIEMgMzMuODU2NzY5LDI4Ni4wNzYwMSA2My43NDkwNCwyODkuNzQyMDEgODkuNjc4MzgzLDI4OS43NDIwMSBjIDE2LjAyMDAyNywwIDMwLjcxOTc4NywtMS4zODI3IDQ0LjA5NzMzNywtNC4xNDc5IDEzLjU0MjcyLC0yLjkwNDMgMjUuMTA0MSwtNy40Njc2IDM0LjY4MzA5LC0xMy42ODkzIDkuNzQ0MTMsLTYuMzU5NyAxNy4zNDA0MiwtMTQuNTE5NSAyMi43OTA1MiwtMjQuNDc0OCA1LjQ1MDEsLTEwLjA5MzMyIDguMTc1MTEsLTIyLjM5OTU5IDguMTc1MTEsLTM2LjkxNjgyIDAsLTEyLjk5NzY0IC0zLjMwMjEsLTI0LjMzNTM5IC05LjkwODI5LC0zNC4wMTQ2IC02LjQ0MTA1LC05LjgxNzI1IC0xNS41MjU0NSwtMTguNTI3MDcgLTI3LjI1MTQ2LC0yNi4xMzEzMyAtMTEuNTYwODUsLTcuNjA0MjcgLTI3LjkxMDgzLC0xNS44MzE0MiAtNDkuMDUwNjYsLTI0LjY4MDIyIC0xNy41MDY0NCwtNy4xOTAxMiAtMzAuNzE5NjY4LC0xMy42ODk0OCAtMzkuNjM4MDM4LC0xOS40OTcwMSAtOC45MTgzNzEsLTUuODA3NTIgLTE4LjYwNzQ3NCwtMTIuNDM0MDkgLTI0LjA5NjUyNCwtMTguODc0MTcgLTUuNDI2MDQzLC02LjM2NjE2IC05LjY1ODgyNiwtMTUuMDcwMDMgLTkuNjU4ODI2LC0yNC44ODcyOSAwLC05LjI2NDAxIDIuMDc1NDE0LC0xNy4yMTM0NSA2LjIyMzQ1NCwtMjMuODUwMzMgMTEuMDk4Mjk4LC0xNC4zOTc0OCA0MS4yODY2MzgsLTEuNzk1MDcgNDUuMDc1NjA5LDI0LjM0NzYyIDQuODM5MzkyLDYuNzc0OTEgOC44NDkzNSwxNi4yNDcyOSAxMi4wMjk1MTUsMjguNDE1NiBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNC40NzgyNSwtNS45MjQ0OCAtOS45NTQ4OCwtMTAuNjMyMjIgLTE1LjkwODM3LC0xNC4zNzQxMSAxLjY0MDU1LDAuNDc5MDUgMy4xOTAzOSwxLjAyMzc2IDQuNjM4NjUsMS42NDAyNCA2LjQ5ODYxLDIuNjI2MDcgMTIuMTY3OTMsNy4zMjc0NyAxNy4wMDczLDE0LjEwMzQ1IDQuODM5MzksNi43NzQ5MSA4Ljg0OTM1LDE2LjI0NTY3IDEyLjAyOTUyLDI4LjQxMzk3IDAsMCA4LjQ4MTI4LC0wLjEyODk0IDguNDg5NzgsLTAuMDAyIDAuNDE3NzYsNi40MTQ5NCAtMS43NTMzOSw5LjQ1Mjg2IC00LjEyMzQyLDEyLjU2MTA0IC0yLjQxNzQsMy4xNjk3OCAtNS4xNDQ4Niw2Ljc4OTczIC00LjAwMjc4LDEzLjAwMjkgMS41MDc4Niw4LjIwMzE4IDEwLjE4MzU0LDEwLjU5NjQyIDE0LjYyMTk0LDkuMzExNTQgLTMuMzE4NDIsLTAuNDk5MTEgLTUuMzE4NTUsLTEuNzQ5NDggLTUuMzE4NTUsLTEuNzQ5NDggMCwwIDEuODc2NDYsMC45OTg2OCA1LjY1MTE3LC0xLjM1OTgxIC0zLjI3Njk1LDAuOTU1NzEgLTEwLjcwNTI5LC0wLjc5NzM4IC0xMS44MDEyNSwtNi43NjMxMyAtMC45NTc1MiwtNS4yMDg2MSAwLjk0NjU0LC03LjI5NTE0IDMuNDAxMTMsLTEwLjUxNDgyIDIuNDU0NjIsLTMuMjE5NjggNS4yODQyNiwtNi45NTgzMSA0LjY4NDMsLTE0LjQ4ODI0IGwgMC4wMDMsMC4wMDIgOC45MjY3NiwwIDAsLTU1Ljk5OTY3IGMgLTE1LjA3MTI1LC0zLjg3MTY4IC0yNy42NTMxNCwtNi4zNjA0MiAtMzcuNzQ2NzEsLTcuNDY1ODYgLTkuOTU1MzEsLTEuMTA3NTUgLTIwLjE4ODIzLC0xLjY1OTgxIC0zMC42OTY2MTMsLTEuNjU5ODEgeiBtIDcwLjMyMTYwMywxNy4zMDg5MyAwLjIzODA1LDQwLjMwNDkgYyAxLjMxODA4LDEuMjI2NjYgMi40Mzk2NSwyLjI3ODE1IDMuMzQwODEsMy4xMDYwMiA0LjgzOTM5LDYuNzc0OTEgOC44NDkzNCwxNi4yNDU2NiAxMi4wMjk1MSwyOC40MTM5NyBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNi42NzczMSwtNC41OTM4MSAtMTkuODM2NDMsLTEwLjQ3MzA5IC0zNi4xNDA3MSwtMTUuODI1MjIgeiBtIC0yOC4xMjA0OSw1LjYwNTUxIDguNTY0NzksMTcuNzE2NTUgYyAtMTEuOTcwMzcsLTYuNDY2OTcgLTEzLjg0Njc4LC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk3MDUsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IG0gMTUuMjIxOTUsMjQuMDA4NDggOC41NjQ3OSwxNy43MTY1NSBjIC0xMS45NzAzOCwtNi40NjY5NyAtMTMuODQ2NzksLTkuNzE3MjYgLTguNTY0NzksLTE3LjcxNjU1IHogbSAyMi43OTcwNCwwIGMgMi43NzE1LDcuOTk5MjkgMS43ODc0MSwxMS4yNDk1OCAtNC40OTM1NCwxNy43MTY1NSBsIDQuNDkzNTQsLTE3LjcxNjU1IHogbSAtOTkuMTEzODQsMi4yMDc2NCA4LjU2NDc5LDE3LjcxNjU1IGMgLTExLjk3MDM4MiwtNi40NjY5NyAtMTMuODQ2NzgyLC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk1NDIsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#750000 0,#340404);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff750000",endColorstr="#ff340404",GradientType=0)}body.syndicate .normal{color:#40628a}body.syndicate .good{color:#73e573}body.syndicate .average{color:#be6209}body.syndicate .bad{color:#b00e0e}body.syndicate .highlight{color:#000}body.syndicate main{display:block;margin-top:32px;padding:2px 6px 0}body.syndicate hr{height:2px;background-color:#272727;border:none}body.syndicate .hidden{display:none}body.syndicate .bar .barText,body.syndicate span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.syndicate .bold{font-weight:700}body.syndicate .italic{font-style:italic}body.syndicate [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.syndicate div[data-tooltip],body.syndicate span[data-tooltip]{position:relative}body.syndicate div[data-tooltip]:after,body.syndicate span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.syndicate div[data-tooltip]:hover:after,body.syndicate span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.syndicate div[data-tooltip].tooltip-top:after,body.syndicate span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-top:hover:after,body.syndicate span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:after,body.syndicate span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:hover:after,body.syndicate span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-left:after,body.syndicate span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-left:hover:after,body.syndicate span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:after,body.syndicate span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:hover:after,body.syndicate span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #000;background:#272727}body.syndicate .bar .barText{position:absolute;top:0;right:3px}body.syndicate .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#000}body.syndicate .bar .barFill.good{background-color:#73e573}body.syndicate .bar .barFill.average{background-color:#be6209}body.syndicate .bar .barFill.bad{background-color:#b00e0e}body.syndicate span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.syndicate span.button .fa{padding-right:2px}body.syndicate span.button.normal{transition:background-color .5s;background-color:#397439}body.syndicate span.button.normal.active:focus,body.syndicate span.button.normal.active:hover{transition:background-color .25s;background-color:#4a964a;outline:0}body.syndicate span.button.disabled{transition:background-color .5s;background-color:#363636}body.syndicate span.button.disabled.active:focus,body.syndicate span.button.disabled.active:hover{transition:background-color .25s;background-color:#545454;outline:0}body.syndicate span.button.selected{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.selected.active:focus,body.syndicate span.button.selected.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.toggle{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.toggle.active:focus,body.syndicate span.button.toggle.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.caution{transition:background-color .5s;background-color:#be6209}body.syndicate span.button.caution.active:focus,body.syndicate span.button.caution.active:hover{transition:background-color .25s;background-color:#eb790b;outline:0}body.syndicate span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.syndicate span.button.danger.active:focus,body.syndicate span.button.danger.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.syndicate span.button.gridable{width:125px;margin:2px 0}body.syndicate span.button.gridable.center{text-align:center;width:75px}body.syndicate span.button+span:not(.button),body.syndicate span:not(.button)+span.button{margin-left:5px}body.syndicate div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000);background-color:rgba(0,0,0,.5);box-shadow:inset 0 0 5px rgba(0,0,0,.75)}body.syndicate div.display.tabular{padding:0;margin:0}body.syndicate div.display header,body.syndicate div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #272727}body.syndicate div.display header .buttonRight,body.syndicate div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.syndicate div.display article,body.syndicate div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.syndicate input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#fff;background-color:#9d0808;border:1px solid #272727}body.syndicate input.number{width:35px}body.syndicate input::-webkit-input-placeholder{color:#999}body.syndicate input:-ms-input-placeholder{color:#999}body.syndicate input::placeholder{color:#999}body.syndicate input::-ms-clear{display:none}body.syndicate svg.linegraph{overflow:hidden}body.syndicate div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#750000;background-image:repeating-linear-gradient(-45deg,#750000,#750000 10px,#910101 0,#910101 20px)}body.syndicate div.notice .label{color:#000}body.syndicate div.notice .content:only-of-type{padding:0}body.syndicate div.notice hr{background-color:#272727}body.syndicate div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.syndicate section{display:table-row;width:100%}body.syndicate section:not(:first-child){padding-top:4px}body.syndicate section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.syndicate section .label{width:1%;padding-right:32px;white-space:nowrap;color:#fff}body.syndicate section .content:not(:last-child){padding-right:16px}body.syndicate section .line{width:100%}body.syndicate section .cell:not(:first-child){text-align:center;padding-top:0}body.syndicate section .cell span.button{width:75px}body.syndicate section:not(:last-child){padding-right:4px}body.syndicate div.subdisplay{width:100%;margin:0}body.syndicate header.titlebar .close,body.syndicate header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#e74242}body.syndicate header.titlebar .close:hover,body.syndicate header.titlebar .minimize:hover{color:#eb5e5e}body.syndicate header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.syndicate header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.syndicate header.titlebar .title{position:absolute;top:6px;left:46px;color:#e74242;font-size:16px;white-space:nowrap}body.syndicate header.titlebar .minimize{position:absolute;top:6px;right:46px}body.syndicate header.titlebar .close{position:absolute;top:4px;right:12px}.no-icons header.titlebar .statusicon{font-size:20px}.no-icons header.titlebar .statusicon:after{content:"O"}.no-icons header.titlebar .minimize{top:-2px;font-size:20px}.no-icons header.titlebar .minimize:after{content:"—"}.no-icons header.titlebar .close{font-size:20px}.no-icons header.titlebar .close:after{content:"X"} \ No newline at end of file +@charset "utf-8";body,html{box-sizing:border-box;height:100%;margin:0}html{overflow:hidden;cursor:default}body{overflow:auto;font-family:Verdana,Geneva,sans-serif;font-size:12px;color:#fff;background-color:#2a2a2a;background-image:linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}*,:after,:before{box-sizing:inherit}h1,h2,h3,h4{display:inline-block;margin:0;padding:6px 0}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4{font-size:12px}body.clockwork{background:linear-gradient(180deg,#b18b25 0,#5f380e);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ffb18b25",endColorstr="#ff5f380e",GradientType=0)}body.clockwork .normal{color:#b18b25}body.clockwork .good{color:#cfba47}body.clockwork .average{color:#896b19}body.clockwork .bad{color:#5f380e}body.clockwork .highlight{color:#b18b25}body.clockwork main{display:block;margin-top:32px;padding:2px 6px 0}body.clockwork hr{height:2px;background-color:#b18b25;border:none}body.clockwork .hidden{display:none}body.clockwork .bar .barText,body.clockwork span.button{color:#b18b25;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.clockwork .bold{font-weight:700}body.clockwork .italic{font-style:italic}body.clockwork [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.clockwork div[data-tooltip],body.clockwork span[data-tooltip]{position:relative}body.clockwork div[data-tooltip]:after,body.clockwork span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #170800;background-color:#2d1400}body.clockwork div[data-tooltip]:hover:after,body.clockwork span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.clockwork div[data-tooltip].tooltip-top:after,body.clockwork span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-top:hover:after,body.clockwork span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:after,body.clockwork span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:hover:after,body.clockwork span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-left:after,body.clockwork span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-left:hover:after,body.clockwork span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:after,body.clockwork span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:hover:after,body.clockwork span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #170800;background:#2d1400}body.clockwork .bar .barText{position:absolute;top:0;right:3px}body.clockwork .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#b18b25}body.clockwork .bar .barFill.good{background-color:#cfba47}body.clockwork .bar .barFill.average{background-color:#896b19}body.clockwork .bar .barFill.bad{background-color:#5f380e}body.clockwork span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #170800}body.clockwork span.button .fa{padding-right:2px}body.clockwork span.button.normal{transition:background-color .5s;background-color:#5f380e}body.clockwork span.button.normal.active:focus,body.clockwork span.button.normal.active:hover{transition:background-color .25s;background-color:#704211;outline:0}body.clockwork span.button.disabled{transition:background-color .5s;background-color:#2d1400}body.clockwork span.button.disabled.active:focus,body.clockwork span.button.disabled.active:hover{transition:background-color .25s;background-color:#441e00;outline:0}body.clockwork span.button.selected{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.selected.active:focus,body.clockwork span.button.selected.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.toggle{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.toggle.active:focus,body.clockwork span.button.toggle.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.caution{transition:background-color .5s;background-color:#be6209}body.clockwork span.button.caution.active:focus,body.clockwork span.button.caution.active:hover{transition:background-color .25s;background-color:#cd6a0a;outline:0}body.clockwork span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.clockwork span.button.danger.active:focus,body.clockwork span.button.danger.active:hover{transition:background-color .25s;background-color:#abaf00;outline:0}body.clockwork span.button.gridable{width:125px;margin:2px 0}body.clockwork span.button.gridable.center{text-align:center;width:75px}body.clockwork span.button+span:not(.button),body.clockwork span:not(.button)+span.button{margin-left:5px}body.clockwork div.display{width:100%;padding:4px;margin:6px 0;background-color:#2d1400;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400);background-color:rgba(45,20,0,.9);box-shadow:inset 0 0 5px rgba(0,0,0,.3)}body.clockwork div.display.tabular{padding:0;margin:0}body.clockwork div.display header,body.clockwork div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#cfba47;border-bottom:2px solid #b18b25}body.clockwork div.display header .buttonRight,body.clockwork div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.clockwork div.display article,body.clockwork div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.clockwork input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#b18b25;background-color:#cfba47;border:1px solid #272727}body.clockwork input.number{width:35px}body.clockwork input:-ms-input-placeholder{color:#999}body.clockwork input::placeholder{color:#999}body.clockwork input::-ms-clear{display:none}body.clockwork svg.linegraph{overflow:hidden}body.clockwork div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#2d1400;font-weight:700;font-style:italic;background-color:#000;background-image:repeating-linear-gradient(-45deg,#000,#000 10px,#170800 0,#170800 20px)}body.clockwork div.notice .label{color:#2d1400}body.clockwork div.notice .content:only-of-type{padding:0}body.clockwork div.notice hr{background-color:#896b19}body.clockwork div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #5f380e;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.clockwork section .cell,body.clockwork section .content,body.clockwork section .label,body.clockwork section .line,body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.clockwork section{display:table-row;width:100%}body.clockwork section:not(:first-child){padding-top:4px}body.clockwork section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.clockwork section .label{width:1%;padding-right:32px;white-space:nowrap;color:#b18b25}body.clockwork section .content:not(:last-child){padding-right:16px}body.clockwork section .line{width:100%}body.clockwork section .cell:not(:first-child){text-align:center;padding-top:0}body.clockwork section .cell span.button{width:75px}body.clockwork section:not(:last-child){padding-right:4px}body.clockwork div.subdisplay{width:100%;margin:0}body.clockwork header.titlebar .close,body.clockwork header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#cfba47}body.clockwork header.titlebar .close:hover,body.clockwork header.titlebar .minimize:hover{color:#d1bd50}body.clockwork header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#5f380e;border-bottom:1px solid #170800;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.clockwork header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.clockwork header.titlebar .title{position:absolute;top:6px;left:46px;color:#cfba47;font-size:16px;white-space:nowrap}body.clockwork header.titlebar .minimize{position:absolute;top:6px;right:46px}body.clockwork header.titlebar .close{position:absolute;top:4px;right:12px}body.nanotrasen{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgNDI1IDIwMCIgb3BhY2l0eT0iLjMzIj4NCiAgPHBhdGggZD0ibSAxNzguMDAzOTksMC4wMzg2OSAtNzEuMjAzOTMsMCBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgLTYuNzYxMzQsNi4wMjU1NSBsIDAsMTg3Ljg3MTQ3IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM0LDYuMDI1NTQgbCA1My4xMDcyLDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xMDEuNTQ0MDE4IDcyLjIxNjI4LDEwNC42OTkzOTggYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDUuNzYwMTUsMi44NzAxNiBsIDczLjU1NDg3LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xODcuODcxNDcgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTM1LC02LjAyNTU1IGwgLTU0LjcxNjQ0LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTMzLDYuMDI1NTUgbCAwLDEwMi42MTkzNSBMIDE4My43NjQxMywyLjkwODg2IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNS43NjAxNCwtMi44NzAxNyB6IiAvPg0KICA8cGF0aCBkPSJNIDQuODQ0NjMzMywyMi4xMDg3NSBBIDEzLjQxMjAzOSwxMi41MDE4NDIgMCAwIDEgMTMuNDc3NTg4LDAuMDM5MjQgbCA2Ni4xMTgzMTUsMCBhIDUuMzY0ODE1OCw1LjAwMDczNyAwIDAgMSA1LjM2NDgyMyw1LjAwMDczIGwgMCw3OS44NzkzMSB6IiAvPg0KICA8cGF0aCBkPSJtIDQyMC4xNTUzNSwxNzcuODkxMTkgYSAxMy40MTIwMzgsMTIuNTAxODQyIDAgMCAxIC04LjYzMjk1LDIyLjA2OTUxIGwgLTY2LjExODMyLDAgYSA1LjM2NDgxNTIsNS4wMDA3MzcgMCAwIDEgLTUuMzY0ODIsLTUuMDAwNzQgbCAwLC03OS44NzkzMSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}body.nanotrasen .normal{color:#40628a}body.nanotrasen .good{color:#537d29}body.nanotrasen .average{color:#be6209}body.nanotrasen .bad{color:#b00e0e}body.nanotrasen .highlight{color:#8ba5c4}body.nanotrasen main{display:block;margin-top:32px;padding:2px 6px 0}body.nanotrasen hr{height:2px;background-color:#40628a;border:none}body.nanotrasen .hidden{display:none}body.nanotrasen .bar .barText,body.nanotrasen span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.nanotrasen .bold{font-weight:700}body.nanotrasen .italic{font-style:italic}body.nanotrasen [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.nanotrasen div[data-tooltip],body.nanotrasen span[data-tooltip]{position:relative}body.nanotrasen div[data-tooltip]:after,body.nanotrasen span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.nanotrasen div[data-tooltip]:hover:after,body.nanotrasen span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.nanotrasen div[data-tooltip].tooltip-top:after,body.nanotrasen span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-top:hover:after,body.nanotrasen span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:after,body.nanotrasen span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:hover:after,body.nanotrasen span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-left:after,body.nanotrasen span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-left:hover:after,body.nanotrasen span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:after,body.nanotrasen span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:hover:after,body.nanotrasen span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #40628a;background:#272727}body.nanotrasen .bar .barText{position:absolute;top:0;right:3px}body.nanotrasen .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#40628a}body.nanotrasen .bar .barFill.good{background-color:#537d29}body.nanotrasen .bar .barFill.average{background-color:#be6209}body.nanotrasen .bar .barFill.bad{background-color:#b00e0e}body.nanotrasen span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.nanotrasen span.button .fa{padding-right:2px}body.nanotrasen span.button.normal{transition:background-color .5s;background-color:#40628a}body.nanotrasen span.button.normal.active:focus,body.nanotrasen span.button.normal.active:hover{transition:background-color .25s;background-color:#4f78aa;outline:0}body.nanotrasen span.button.disabled{transition:background-color .5s;background-color:#999}body.nanotrasen span.button.disabled.active:focus,body.nanotrasen span.button.disabled.active:hover{transition:background-color .25s;background-color:#a8a8a8;outline:0}body.nanotrasen span.button.selected{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.selected.active:focus,body.nanotrasen span.button.selected.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.toggle{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.toggle.active:focus,body.nanotrasen span.button.toggle.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.caution{transition:background-color .5s;background-color:#9a9d00}body.nanotrasen span.button.caution.active:focus,body.nanotrasen span.button.caution.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.nanotrasen span.button.danger{transition:background-color .5s;background-color:#9d0808}body.nanotrasen span.button.danger.active:focus,body.nanotrasen span.button.danger.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.nanotrasen span.button.gridable{width:125px;margin:2px 0}body.nanotrasen span.button.gridable.center{text-align:center;width:75px}body.nanotrasen span.button+span:not(.button),body.nanotrasen span:not(.button)+span.button{margin-left:5px}body.nanotrasen div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000);background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5)}body.nanotrasen div.display.tabular{padding:0;margin:0}body.nanotrasen div.display header,body.nanotrasen div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #40628a}body.nanotrasen div.display header .buttonRight,body.nanotrasen div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.nanotrasen div.display article,body.nanotrasen div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.nanotrasen input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#000;background-color:#fff;border:1px solid #272727}body.nanotrasen input.number{width:35px}body.nanotrasen input:-ms-input-placeholder{color:#999}body.nanotrasen input::placeholder{color:#999}body.nanotrasen input::-ms-clear{display:none}body.nanotrasen svg.linegraph{overflow:hidden}body.nanotrasen div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,#bb9b68,#bb9b68 10px,#b1905d 0,#b1905d 20px)}body.nanotrasen div.notice .label{color:#000}body.nanotrasen div.notice .content:only-of-type{padding:0}body.nanotrasen div.notice hr{background-color:#272727}body.nanotrasen div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.nanotrasen section{display:table-row;width:100%}body.nanotrasen section:not(:first-child){padding-top:4px}body.nanotrasen section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.nanotrasen section .label{width:1%;padding-right:32px;white-space:nowrap;color:#8ba5c4}body.nanotrasen section .content:not(:last-child){padding-right:16px}body.nanotrasen section .line{width:100%}body.nanotrasen section .cell:not(:first-child){text-align:center;padding-top:0}body.nanotrasen section .cell span.button{width:75px}body.nanotrasen section:not(:last-child){padding-right:4px}body.nanotrasen div.subdisplay{width:100%;margin:0}body.nanotrasen header.titlebar .close,body.nanotrasen header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#8ba5c4}body.nanotrasen header.titlebar .close:hover,body.nanotrasen header.titlebar .minimize:hover{color:#9cb2cd}body.nanotrasen header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.nanotrasen header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.nanotrasen header.titlebar .title{position:absolute;top:6px;left:46px;color:#8ba5c4;font-size:16px;white-space:nowrap}body.nanotrasen header.titlebar .minimize{position:absolute;top:6px;right:46px}body.nanotrasen header.titlebar .close{position:absolute;top:4px;right:12px}body.syndicate{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgMjAwIDI4OS43NDIiIG9wYWNpdHk9Ii4zMyI+DQogIDxwYXRoIGQ9Im0gOTMuNTM3Njc3LDAgYyAtMTguMTEzMTI1LDAgLTM0LjIyMDEzMywzLjExMTY0IC00OC4zMjM0ODQsOS4zMzQzNyAtMTMuOTY1MDkyLDYuMjIxNjcgLTI0LjYxMjQ0MiwxNS4wNzExNCAtMzEuOTQwNjUxLDI2LjU0NzEgLTcuMTg5OTM5OCwxMS4zMzc4OSAtMTAuMzAxMjI2NiwyNC43NDkxMSAtMTAuMzAxMjI2Niw0MC4yMzQ3OCAwLDEwLjY0NjYyIDIuNzI1MDAyNiwyMC40NjQ2NSA4LjE3NTExMTYsMjkuNDUyNTggNS42MTUyNzcsOC45ODY4NiAxNC4wMzgyNzcsMTcuMzUyMDQgMjUuMjY4ODIxLDI1LjA5NDM2IDExLjIzMDU0NCw3LjYwNTMxIDI2LjUwNzQyMSwxNS40MTgzNSA0NS44MzA1MTQsMjMuNDM3ODIgMTkuOTgzNzQ4LDguMjk1NTcgMzQuODQ4ODQ4LDE1LjU1NDcxIDQ0LjU5Mjk5OCwyMS43NzYzOCA5Ljc0NDE0LDYuMjIyNzMgMTYuNzYxNywxMi44NTg1IDIxLjA1NTcyLDE5LjkwOTUxIDQuMjk0MDQsNy4wNTIwOCA2LjQ0MTkzLDE1Ljc2NDA4IDYuNDQxOTMsMjYuMTM0NTkgMCwxNi4xNzcwMiAtNS4yMDE5NiwyOC40ODIyMiAtMTUuNjA2NzMsMzYuOTE2ODIgLTEwLjIzOTYsOC40MzQ3IC0yNS4wMjIwMywxMi42NTIzIC00NC4zNDUxNjksMTIuNjUyMyAtMTQuMDM4MTcxLDAgLTI1LjUxNTI0NywtMS42NTk0IC0zNC40MzM2MTgsLTQuOTc3NyAtOC45MTgzNywtMy40NTY2IC0xNi4xODU1NzIsLTguNzExMyAtMjEuODAwODM5LC0xNS43NjMzIC01LjYxNTI3NywtNy4wNTIxIC0xMC4wNzQ3OTUsLTE2LjY2MDg4IC0xMy4zNzc4OTksLTI4LjgyODEyIGwgLTI0Ljc3MzE2MjYyOTM5NDUsMCAwLDU2LjgyNjMyIEMgMzMuODU2NzY5LDI4Ni4wNzYwMSA2My43NDkwNCwyODkuNzQyMDEgODkuNjc4MzgzLDI4OS43NDIwMSBjIDE2LjAyMDAyNywwIDMwLjcxOTc4NywtMS4zODI3IDQ0LjA5NzMzNywtNC4xNDc5IDEzLjU0MjcyLC0yLjkwNDMgMjUuMTA0MSwtNy40Njc2IDM0LjY4MzA5LC0xMy42ODkzIDkuNzQ0MTMsLTYuMzU5NyAxNy4zNDA0MiwtMTQuNTE5NSAyMi43OTA1MiwtMjQuNDc0OCA1LjQ1MDEsLTEwLjA5MzMyIDguMTc1MTEsLTIyLjM5OTU5IDguMTc1MTEsLTM2LjkxNjgyIDAsLTEyLjk5NzY0IC0zLjMwMjEsLTI0LjMzNTM5IC05LjkwODI5LC0zNC4wMTQ2IC02LjQ0MTA1LC05LjgxNzI1IC0xNS41MjU0NSwtMTguNTI3MDcgLTI3LjI1MTQ2LC0yNi4xMzEzMyAtMTEuNTYwODUsLTcuNjA0MjcgLTI3LjkxMDgzLC0xNS44MzE0MiAtNDkuMDUwNjYsLTI0LjY4MDIyIC0xNy41MDY0NCwtNy4xOTAxMiAtMzAuNzE5NjY4LC0xMy42ODk0OCAtMzkuNjM4MDM4LC0xOS40OTcwMSAtOC45MTgzNzEsLTUuODA3NTIgLTE4LjYwNzQ3NCwtMTIuNDM0MDkgLTI0LjA5NjUyNCwtMTguODc0MTcgLTUuNDI2MDQzLC02LjM2NjE2IC05LjY1ODgyNiwtMTUuMDcwMDMgLTkuNjU4ODI2LC0yNC44ODcyOSAwLC05LjI2NDAxIDIuMDc1NDE0LC0xNy4yMTM0NSA2LjIyMzQ1NCwtMjMuODUwMzMgMTEuMDk4Mjk4LC0xNC4zOTc0OCA0MS4yODY2MzgsLTEuNzk1MDcgNDUuMDc1NjA5LDI0LjM0NzYyIDQuODM5MzkyLDYuNzc0OTEgOC44NDkzNSwxNi4yNDcyOSAxMi4wMjk1MTUsMjguNDE1NiBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNC40NzgyNSwtNS45MjQ0OCAtOS45NTQ4OCwtMTAuNjMyMjIgLTE1LjkwODM3LC0xNC4zNzQxMSAxLjY0MDU1LDAuNDc5MDUgMy4xOTAzOSwxLjAyMzc2IDQuNjM4NjUsMS42NDAyNCA2LjQ5ODYxLDIuNjI2MDcgMTIuMTY3OTMsNy4zMjc0NyAxNy4wMDczLDE0LjEwMzQ1IDQuODM5MzksNi43NzQ5MSA4Ljg0OTM1LDE2LjI0NTY3IDEyLjAyOTUyLDI4LjQxMzk3IDAsMCA4LjQ4MTI4LC0wLjEyODk0IDguNDg5NzgsLTAuMDAyIDAuNDE3NzYsNi40MTQ5NCAtMS43NTMzOSw5LjQ1Mjg2IC00LjEyMzQyLDEyLjU2MTA0IC0yLjQxNzQsMy4xNjk3OCAtNS4xNDQ4Niw2Ljc4OTczIC00LjAwMjc4LDEzLjAwMjkgMS41MDc4Niw4LjIwMzE4IDEwLjE4MzU0LDEwLjU5NjQyIDE0LjYyMTk0LDkuMzExNTQgLTMuMzE4NDIsLTAuNDk5MTEgLTUuMzE4NTUsLTEuNzQ5NDggLTUuMzE4NTUsLTEuNzQ5NDggMCwwIDEuODc2NDYsMC45OTg2OCA1LjY1MTE3LC0xLjM1OTgxIC0zLjI3Njk1LDAuOTU1NzEgLTEwLjcwNTI5LC0wLjc5NzM4IC0xMS44MDEyNSwtNi43NjMxMyAtMC45NTc1MiwtNS4yMDg2MSAwLjk0NjU0LC03LjI5NTE0IDMuNDAxMTMsLTEwLjUxNDgyIDIuNDU0NjIsLTMuMjE5NjggNS4yODQyNiwtNi45NTgzMSA0LjY4NDMsLTE0LjQ4ODI0IGwgMC4wMDMsMC4wMDIgOC45MjY3NiwwIDAsLTU1Ljk5OTY3IGMgLTE1LjA3MTI1LC0zLjg3MTY4IC0yNy42NTMxNCwtNi4zNjA0MiAtMzcuNzQ2NzEsLTcuNDY1ODYgLTkuOTU1MzEsLTEuMTA3NTUgLTIwLjE4ODIzLC0xLjY1OTgxIC0zMC42OTY2MTMsLTEuNjU5ODEgeiBtIDcwLjMyMTYwMywxNy4zMDg5MyAwLjIzODA1LDQwLjMwNDkgYyAxLjMxODA4LDEuMjI2NjYgMi40Mzk2NSwyLjI3ODE1IDMuMzQwODEsMy4xMDYwMiA0LjgzOTM5LDYuNzc0OTEgOC44NDkzNCwxNi4yNDU2NiAxMi4wMjk1MSwyOC40MTM5NyBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNi42NzczMSwtNC41OTM4MSAtMTkuODM2NDMsLTEwLjQ3MzA5IC0zNi4xNDA3MSwtMTUuODI1MjIgeiBtIC0yOC4xMjA0OSw1LjYwNTUxIDguNTY0NzksMTcuNzE2NTUgYyAtMTEuOTcwMzcsLTYuNDY2OTcgLTEzLjg0Njc4LC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk3MDUsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IG0gMTUuMjIxOTUsMjQuMDA4NDggOC41NjQ3OSwxNy43MTY1NSBjIC0xMS45NzAzOCwtNi40NjY5NyAtMTMuODQ2NzksLTkuNzE3MjYgLTguNTY0NzksLTE3LjcxNjU1IHogbSAyMi43OTcwNCwwIGMgMi43NzE1LDcuOTk5MjkgMS43ODc0MSwxMS4yNDk1OCAtNC40OTM1NCwxNy43MTY1NSBsIDQuNDkzNTQsLTE3LjcxNjU1IHogbSAtOTkuMTEzODQsMi4yMDc2NCA4LjU2NDc5LDE3LjcxNjU1IGMgLTExLjk3MDM4MiwtNi40NjY5NyAtMTMuODQ2NzgyLC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk1NDIsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#750000 0,#340404);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff750000",endColorstr="#ff340404",GradientType=0)}body.syndicate .normal{color:#40628a}body.syndicate .good{color:#73e573}body.syndicate .average{color:#be6209}body.syndicate .bad{color:#b00e0e}body.syndicate .highlight{color:#000}body.syndicate main{display:block;margin-top:32px;padding:2px 6px 0}body.syndicate hr{height:2px;background-color:#272727;border:none}body.syndicate .hidden{display:none}body.syndicate .bar .barText,body.syndicate span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.syndicate .bold{font-weight:700}body.syndicate .italic{font-style:italic}body.syndicate [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.syndicate div[data-tooltip],body.syndicate span[data-tooltip]{position:relative}body.syndicate div[data-tooltip]:after,body.syndicate span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.syndicate div[data-tooltip]:hover:after,body.syndicate span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.syndicate div[data-tooltip].tooltip-top:after,body.syndicate span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-top:hover:after,body.syndicate span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:after,body.syndicate span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:hover:after,body.syndicate span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-left:after,body.syndicate span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-left:hover:after,body.syndicate span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:after,body.syndicate span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:hover:after,body.syndicate span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #000;background:#272727}body.syndicate .bar .barText{position:absolute;top:0;right:3px}body.syndicate .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#000}body.syndicate .bar .barFill.good{background-color:#73e573}body.syndicate .bar .barFill.average{background-color:#be6209}body.syndicate .bar .barFill.bad{background-color:#b00e0e}body.syndicate span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.syndicate span.button .fa{padding-right:2px}body.syndicate span.button.normal{transition:background-color .5s;background-color:#397439}body.syndicate span.button.normal.active:focus,body.syndicate span.button.normal.active:hover{transition:background-color .25s;background-color:#4a964a;outline:0}body.syndicate span.button.disabled{transition:background-color .5s;background-color:#363636}body.syndicate span.button.disabled.active:focus,body.syndicate span.button.disabled.active:hover{transition:background-color .25s;background-color:#545454;outline:0}body.syndicate span.button.selected{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.selected.active:focus,body.syndicate span.button.selected.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.toggle{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.toggle.active:focus,body.syndicate span.button.toggle.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.caution{transition:background-color .5s;background-color:#be6209}body.syndicate span.button.caution.active:focus,body.syndicate span.button.caution.active:hover{transition:background-color .25s;background-color:#eb790b;outline:0}body.syndicate span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.syndicate span.button.danger.active:focus,body.syndicate span.button.danger.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.syndicate span.button.gridable{width:125px;margin:2px 0}body.syndicate span.button.gridable.center{text-align:center;width:75px}body.syndicate span.button+span:not(.button),body.syndicate span:not(.button)+span.button{margin-left:5px}body.syndicate div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000);background-color:rgba(0,0,0,.5);box-shadow:inset 0 0 5px rgba(0,0,0,.75)}body.syndicate div.display.tabular{padding:0;margin:0}body.syndicate div.display header,body.syndicate div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #272727}body.syndicate div.display header .buttonRight,body.syndicate div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.syndicate div.display article,body.syndicate div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.syndicate input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#fff;background-color:#9d0808;border:1px solid #272727}body.syndicate input.number{width:35px}body.syndicate input:-ms-input-placeholder{color:#999}body.syndicate input::placeholder{color:#999}body.syndicate input::-ms-clear{display:none}body.syndicate svg.linegraph{overflow:hidden}body.syndicate div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#750000;background-image:repeating-linear-gradient(-45deg,#750000,#750000 10px,#910101 0,#910101 20px)}body.syndicate div.notice .label{color:#000}body.syndicate div.notice .content:only-of-type{padding:0}body.syndicate div.notice hr{background-color:#272727}body.syndicate div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.syndicate section{display:table-row;width:100%}body.syndicate section:not(:first-child){padding-top:4px}body.syndicate section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.syndicate section .label{width:1%;padding-right:32px;white-space:nowrap;color:#fff}body.syndicate section .content:not(:last-child){padding-right:16px}body.syndicate section .line{width:100%}body.syndicate section .cell:not(:first-child){text-align:center;padding-top:0}body.syndicate section .cell span.button{width:75px}body.syndicate section:not(:last-child){padding-right:4px}body.syndicate div.subdisplay{width:100%;margin:0}body.syndicate header.titlebar .close,body.syndicate header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#e74242}body.syndicate header.titlebar .close:hover,body.syndicate header.titlebar .minimize:hover{color:#eb5e5e}body.syndicate header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.syndicate header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.syndicate header.titlebar .title{position:absolute;top:6px;left:46px;color:#e74242;font-size:16px;white-space:nowrap}body.syndicate header.titlebar .minimize{position:absolute;top:6px;right:46px}body.syndicate header.titlebar .close{position:absolute;top:4px;right:12px}.no-icons header.titlebar .statusicon{font-size:20px}.no-icons header.titlebar .statusicon:after{content:"O"}.no-icons header.titlebar .minimize{top:-2px;font-size:20px}.no-icons header.titlebar .minimize:after{content:"—"}.no-icons header.titlebar .close{font-size:20px}.no-icons header.titlebar .close:after{content:"X"} \ No newline at end of file diff --git a/tgui/assets/tgui.js b/tgui/assets/tgui.js index 16752bdaa9..8f28e9df0e 100644 --- a/tgui/assets/tgui.js +++ b/tgui/assets/tgui.js @@ -6,12 +6,12 @@ return t.set(e,+a+n)}function O(t,e){return Jo(this,t,void 0===e?1:+e)}function }function Hi(t){for(var e={};t;)Ki(t,e),$i(t,e),t=t._Parent!==Rv?t._Parent:!1;return e}function Ki(t,e){ru.forEach(function(n){Qi(n.useDefaults?t.prototype:t,e,n.name)})}function Qi(t,e,n){var a,r=Object.keys(t[n]);r.length&&((a=e[n])||(a=e[n]={}),r.filter(function(t){return!(t in a)}).forEach(function(e){return a[e]=t[n][e]}))}function $i(t,e){Object.keys(t.prototype).forEach(function(n){if("computed"!==n){var a=t.prototype[n];if(n in e){if("function"==typeof e[n]&&"function"==typeof a&&e[n]._method){var r=void 0,i=a._method;i&&(a=a._method),r=Pv(e[n]._method,a),i&&(r._method=r),e[n]=r}}else e[n]=a._method?a._method:a}})}function Yi(){for(var t=arguments.length,e=Array(t),n=0;t>n;n++)e[n]=arguments[n];return e.length?e.reduce(Ji,this):Ji(this)}function Ji(t){var e,n,r=void 0===arguments[1]?{}:arguments[1];return r.prototype instanceof Rv&&(r=Av(r)),e=function(t){return this instanceof e?void Om(this,t):new e(t)},n=Eo(t.prototype),n.constructor=e,Co(e,{defaults:{value:n},extend:{value:Yi,writable:!0,configurable:!0},_Parent:{value:t}}),uu.extend(t,n,r),Wp.extend(t,n,r),r.computed&&(n.computed=a(Eo(t.prototype.computed),r.computed)),e.prototype=n,e}var Xi,Zi,to,eo,no,ao,ro,io=3,oo={el:void 0,append:!1,template:{v:io,t:[]},preserveWhitespace:!1,sanitize:!1,stripComments:!0,delimiters:["{{","}}"],tripleDelimiters:["{{{","}}}"],interpolate:!1,data:{},computed:{},magic:!1,modifyArrays:!0,adapt:[],isolated:!1,twoway:!0,lazy:!1,noIntro:!1,transitionsEnabled:!0,complete:void 0,css:null,noCssTransform:!1},so=oo,po={linear:function(t){return t},easeIn:function(t){return Math.pow(t,3)},easeOut:function(t){return Math.pow(t-1,3)+1},easeInOut:function(t){return(t/=.5)<1?.5*Math.pow(t,3):.5*(Math.pow(t-2,3)+2)}};Xi="object"==typeof document,Zi="undefined"!=typeof navigator&&/jsDom/.test(navigator.appName),to="undefined"!=typeof console&&"function"==typeof console.warn&&"function"==typeof console.warn.apply;try{Object.defineProperty({},"test",{value:0}),eo=!0}catch(uo){eo=!1}no={html:"http://www.w3.org/1999/xhtml",mathml:"http://www.w3.org/1998/Math/MathML",svg:"http://www.w3.org/2000/svg",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"},ao="undefined"==typeof document?!1:document&&document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1"),ro=["o","ms","moz","webkit"];var co,lo,fo,ho,mo,vo,go,bo,yo;if(co=ao?function(t,e){return e&&e!==no.html?document.createElementNS(e,t):document.createElement(t)}:function(t,e){if(e&&e!==no.html)throw"This browser does not support namespaces other than http://www.w3.org/1999/xhtml. The most likely cause of this error is that you're trying to render SVG in an older browser. See http://docs.ractivejs.org/latest/svg-and-older-browsers for more information";return document.createElement(t)},Xi){for(fo=co("div"),ho=["matches","matchesSelector"],yo=function(t){return function(e,n){return e[t](n)}},go=ho.length;go--&&!lo;)if(mo=ho[go],fo[mo])lo=yo(mo);else for(bo=ro.length;bo--;)if(vo=ro[go]+mo.substr(0,1).toUpperCase()+mo.substring(1),fo[vo]){lo=yo(vo);break}lo||(lo=function(t,e){var n,a,r;for(a=t.parentNode,a||(fo.innerHTML="",a=fo,t=t.cloneNode(),fo.appendChild(t)),n=a.querySelectorAll(e),r=n.length;r--;)if(n[r]===t)return!0;return!1})}else lo=null;var xo,_o,wo,ko=function(){};"undefined"==typeof window?wo=null:(xo=window,_o=xo.document,wo={},_o||(wo=null),Date.now||(Date.now=function(){return+new Date}),String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+/,"").replace(/\s+$/,"")}),Object.keys||(Object.keys=function(){var t=Object.prototype.hasOwnProperty,e=!{toString:null}.propertyIsEnumerable("toString"),n=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],a=n.length;return function(r){if("object"!=typeof r&&"function"!=typeof r||null===r)throw new TypeError("Object.keys called on non-object");var i=[];for(var o in r)t.call(r,o)&&i.push(o);if(e)for(var s=0;a>s;s++)t.call(r,n[s])&&i.push(n[s]);return i}}()),Array.prototype.indexOf||(Array.prototype.indexOf=function(t,e){var n;for(void 0===e&&(e=0),0>e&&(e+=this.length),0>e&&(e=0),n=this.length;n>e;e++)if(this.hasOwnProperty(e)&&this[e]===t)return e;return-1}),Array.prototype.forEach||(Array.prototype.forEach=function(t,e){var n,a;for(n=0,a=this.length;a>n;n+=1)this.hasOwnProperty(n)&&t.call(e,this[n],n,this)}),Array.prototype.map||(Array.prototype.map=function(t,e){var n,a,r,i=this,o=[];for(i instanceof String&&(i=""+i,r=!0),n=0,a=i.length;a>n;n+=1)(i.hasOwnProperty(n)||r)&&(o[n]=t.call(e,i[n],n,i));return o}),"function"!=typeof Array.prototype.reduce&&(Array.prototype.reduce=function(t,e){var n,a,r,i;if("function"!=typeof t)throw new TypeError(t+" is not a function");for(r=this.length,i=!1,arguments.length>1&&(a=e,i=!0),n=0;r>n;n+=1)this.hasOwnProperty(n)?i&&(a=t(a,this[n],n,this)):(a=this[n],i=!0);if(!i)throw new TypeError("Reduce of empty array with no initial value");return a}),Array.prototype.filter||(Array.prototype.filter=function(t,e){var n,a,r=[];for(n=0,a=this.length;a>n;n+=1)this.hasOwnProperty(n)&&t.call(e,this[n],n,this)&&(r[r.length]=this[n]);return r}),Array.prototype.every||(Array.prototype.every=function(t,e){var n,a,r;if(null==this)throw new TypeError;if(n=Object(this),a=n.length>>>0,"function"!=typeof t)throw new TypeError;for(r=0;a>r;r+=1)if(r in n&&!t.call(e,n[r],r,n))return!1;return!0}),"function"!=typeof Function.prototype.bind&&(Function.prototype.bind=function(t){var e,n,a,r,i=[].slice;if("function"!=typeof this)throw new TypeError("Function.prototype.bind called on non-function");return e=i.call(arguments,1),n=this,a=function(){},r=function(){var r=this instanceof a&&t?this:t;return n.apply(r,e.concat(i.call(arguments)))},a.prototype=this.prototype,r.prototype=new a,r}),xo.addEventListener||!function(t,e){var n,a,r,i,o,s;t.appearsToBeIELessEqual8=!0,n=function(t,e){var n,a=this;for(n in t)a[n]=t[n];a.currentTarget=e,a.target=t.srcElement||e,a.timeStamp=+new Date,a.preventDefault=function(){t.returnValue=!1},a.stopPropagation=function(){t.cancelBubble=!0}},a=function(t,e){var a,r,i=this;a=i.listeners||(i.listeners=[]),r=a.length,a[r]=[e,function(t){e.call(i,new n(t,i))}],i.attachEvent("on"+t,a[r][1])},r=function(t,e){var n,a,r=this;if(r.listeners)for(n=r.listeners,a=n.length;a--;)n[a][0]===e&&r.detachEvent("on"+t,n[a][1])},t.addEventListener=e.addEventListener=a,t.removeEventListener=e.removeEventListener=r,"Element"in t?(t.Element.prototype.addEventListener=a,t.Element.prototype.removeEventListener=r):(s=e.createElement,e.createElement=function(t){var e=s(t);return e.addEventListener=a,e.removeEventListener=r,e},i=e.getElementsByTagName("head")[0],o=e.createElement("style"),i.insertBefore(o,i.firstChild))}(xo,_o),xo.getComputedStyle||(wo.getComputedStyle=function(){function t(n,a,r,i){var o,s=a[r],p=parseFloat(s),u=s.split(/\d/)[0];return isNaN(p)&&/^thin|medium|thick$/.test(s)&&(p=e(s),u=""),i=null!=i?i:/%|em/.test(u)&&n.parentElement?t(n.parentElement,n.parentElement.currentStyle,"fontSize",null):16,o="fontSize"==r?i:/width/i.test(r)?n.clientWidth:n.clientHeight,"em"==u?p*i:"in"==u?96*p:"pt"==u?96*p/72:"%"==u?p/100*o:p}function e(t){var e,n;return i[t]||(e=document.createElement("div"),e.style.display="block",e.style.position="fixed",e.style.width=e.style.height="0",e.style.borderRight=t+" solid black",document.getElementsByTagName("body")[0].appendChild(e),n=e.getBoundingClientRect(),i[t]=n.right-n.left),i[t]}function n(t,e){var n="border"==e?"Width":"",a=e+"Top"+n,r=e+"Right"+n,i=e+"Bottom"+n,o=e+"Left"+n;t[e]=(t[a]==t[r]==t[i]==t[o]?[t[a]]:t[a]==t[i]&&t[o]==t[r]?[t[a],t[r]]:t[o]==t[r]?[t[a],t[r],t[i]]:[t[a],t[r],t[i],t[o]]).join(" ")}function a(e){var a,r,i,s;a=e.currentStyle,r=this,i=t(e,a,"fontSize",null);for(s in a)"normal"===a[s]&&o.hasOwnProperty(s)?r[s]=o[s]:/width|height|margin.|padding.|border.+W/.test(s)?"auto"===a[s]?/^width|height/.test(s)?r[s]=("width"===s?e.clientWidth:e.clientHeight)+"px":/(?:padding)?Top|Bottom$/.test(s)&&(r[s]="0px"):r[s]=t(e,a,s,i)+"px":"styleFloat"===s?r["float"]=a[s]:r[s]=a[s];return n(r,"margin"),n(r,"padding"),n(r,"border"),r.fontSize=i+"px",r}function r(t){return new a(t)}var i={},o={fontWeight:400,lineHeight:1.2,letterSpacing:0};return a.prototype={constructor:a,getPropertyPriority:ko,getPropertyValue:function(t){return this[t]||""},item:ko,removeProperty:ko,setProperty:ko,getPropertyCSSValue:ko},r}()));var Eo,So,Co,Po=wo;try{Object.defineProperty({},"test",{value:0}),Xi&&Object.defineProperty(document.createElement("div"),"test",{value:0}),So=Object.defineProperty}catch(Ao){So=function(t,e,n){t[e]=n.value}}try{try{Object.defineProperties({},{test:{value:0}})}catch(Ao){throw Ao}Xi&&Object.defineProperties(co("div"),{test:{value:0}}),Co=Object.defineProperties}catch(Ao){Co=function(t,e){var n;for(n in e)e.hasOwnProperty(n)&&So(t,n,e[n])}}try{Object.create(null),Eo=Object.create}catch(Ao){Eo=function(){var t=function(){};return function(e,n){var a;return null===e?{}:(t.prototype=e,a=new t,n&&Object.defineProperties(a,n),a)}}()}var Oo,To,jo,Ro=Object.prototype.hasOwnProperty,Mo=Object.prototype.toString,Lo=/^\[object (?:Array|FileList)\]$/,Do={};to?!function(){var t=["%cRactive.js %c0.7.3 %cin debug mode, %cmore...","color: rgb(114, 157, 52); font-weight: normal;","color: rgb(85, 85, 85); font-weight: normal;","color: rgb(85, 85, 85); font-weight: normal;","color: rgb(82, 140, 224); font-weight: normal; text-decoration: underline;"],e="You're running Ractive 0.7.3 in debug mode - messages will be printed to the console to help you fix problems and optimise your application.\n\nTo disable debug mode, add this line at the start of your app:\n Ractive.DEBUG = false;\n\nTo disable debug mode when your app is minified, add this snippet:\n Ractive.DEBUG = /unminified/.test(function(){/*unminified*/});\n\nGet help and support:\n http://docs.ractivejs.org\n http://stackoverflow.com/questions/tagged/ractivejs\n http://groups.google.com/forum/#!forum/ractive-js\n http://twitter.com/ractivejs\n\nFound a bug? Raise an issue:\n https://github.com/ractivejs/ractive/issues\n\n";jo=function(){var n=!!console.groupCollapsed;console[n?"groupCollapsed":"log"].apply(console,t),console.log(e),n&&console.groupEnd(t),jo=ko},To=function(t,e){if(jo(),"object"==typeof e[e.length-1]){var n=e.pop(),a=n?n.ractive:null;if(a){var r=void 0;a.component&&(r=a.component.name)&&(t="<"+r+"> "+t);var i=void 0;(i=n.node||a.fragment&&a.fragment.rendered&&a.find("*"))&&e.push(i)}}console.warn.apply(console,["%cRactive.js: %c"+t,"color: rgb(114, 157, 52);","color: rgb(85, 85, 85);"].concat(e))},Oo=function(){console.log.apply(console,arguments)}}():To=Oo=jo=ko;var No="Bad arguments",Fo='A function was specified for "%s" %s, but no %s was returned',Io=function(t,e){return'Missing "'+t+'" '+e+" plugin. You may need to download a plugin via http://docs.ractivejs.org/latest/plugins#"+e+"s"},Bo=function(t,e,n,a){if(t===e)return y(e);if(a){var r=g("interpolators",n,a);if(r)return r(t,e)||y(e);l(Io(a,"interpolator"))}return Go.number(t,e)||Go.array(t,e)||Go.object(t,e)||y(e)},qo=Bo,Uo={number:function(t,e){var n;return p(t)&&p(e)?(t=+t,e=+e,n=e-t,n?function(e){return t+e*n}:function(){return t}):null},array:function(t,e){var n,a,r,o;if(!i(t)||!i(e))return null;for(n=[],a=[],o=r=Math.min(t.length,e.length);o--;)a[o]=qo(t[o],e[o]);for(o=r;o=this.duration?(null!==i&&(bs.start(this.root),this.root.viewmodel.set(i,this.to),bs.end()),this.step&&this.step(1,this.to),this.complete(this.to),r=this.root._animations.indexOf(this),-1===r&&m("Animation was not found"),this.root._animations.splice(r,1),this.running=!1,!1):(e=this.easing?this.easing(t/this.duration):t/this.duration,null!==i&&(n=this.interpolator(e),bs.start(this.root),this.root.viewmodel.set(i,n),bs.end()),this.step&&this.step(e,n),!0)):!1},stop:function(){var t;this.running=!1,t=this.root._animations.indexOf(this),-1===t&&m("Animation was not found"),this.root._animations.splice(t,1)}};var ks=ws,Es=nt,Ss={stop:ko},Cs=rt,Ps=new is("detach"),As=it,Os=ot,Ts=function(){var t,e,n;t=this._root[this._isComponentQuery?"liveComponentQueries":"liveQueries"],e=this.selector,n=t.indexOf(e),-1!==n&&(t.splice(n,1),t[e]=null)},js=function(t,e){var n,a,r,i,o,s,p,u,c,l;for(n=pt(t.component||t._ractive.proxy),a=pt(e.component||e._ractive.proxy),r=D(n),i=D(a);r&&r===i;)n.pop(),a.pop(),o=r,r=D(n),i=D(a);if(r=r.component||r,i=i.component||i,c=r.parentFragment,l=i.parentFragment,c===l)return s=c.items.indexOf(r),p=l.items.indexOf(i),s-p||n.length-a.length;if(u=o.fragments)return s=u.indexOf(c),p=u.indexOf(l),s-p||n.length-a.length;throw Error("An unexpected condition was met while comparing the position of two components. Please file an issue at https://github.com/RactiveJS/Ractive/issues - thanks!")},Rs=function(t,e){var n;return t.compareDocumentPosition?(n=t.compareDocumentPosition(e),2&n?1:-1):js(t,e)},Ms=function(){this.sort(this._isComponentQuery?js:Rs),this._dirty=!1},Ls=function(){var t=this;this._dirty||(this._dirty=!0,bs.scheduleTask(function(){t._sort()}))},Ds=function(t){var e=this.indexOf(this._isComponentQuery?t.instance:t);-1!==e&&this.splice(e,1)},Ns=ut,Fs=ct,Is=lt,Bs=dt,qs=ft,Us=ht,Gs={enqueue:function(t,e){t.event&&(t._eventQueue=t._eventQueue||[],t._eventQueue.push(t.event)),t.event=e},dequeue:function(t){t._eventQueue&&t._eventQueue.length?t.event=t._eventQueue.pop():delete t.event}},Vs=Gs,zs=mt,Ws=bt,Hs=yt,Ks={capture:!0,noUnwrap:!0,fullRootGet:!0},Qs=xt,$s=new is("insert"),Ys=wt,Js=function(t,e,n,a){this.root=t,this.keypath=e,this.callback=n,this.defer=a.defer,this.context=a&&a.context?a.context:t};Js.prototype={init:function(t){this.value=this.root.get(this.keypath.str),t!==!1?this.update():this.oldValue=this.value},setValue:function(t){var e=this;s(t,this.value)||(this.value=t,this.defer&&this.ready?bs.scheduleTask(function(){return e.update()}):this.update())},update:function(){this.updating||(this.updating=!0,this.callback.call(this.context,this.value,this.oldValue,this.keypath.str),this.oldValue=this.value,this.updating=!1)}};var Xs,Zs=Js,tp=kt,ep=Array.prototype.slice;Xs=function(t,e,n,a){this.root=t,this.callback=n,this.defer=a.defer,this.keypath=e,this.regex=RegExp("^"+e.str.replace(/\./g,"\\.").replace(/\*/g,"([^\\.]+)")+"$"),this.values={},this.defer&&(this.proxies=[]),this.context=a&&a.context?a.context:t},Xs.prototype={init:function(t){var e,n;if(e=tp(this.root,this.keypath),t!==!1)for(n in e)e.hasOwnProperty(n)&&this.update(E(n));else this.values=e},update:function(t){var e,n=this;if(t.isPattern){e=tp(this.root,t);for(t in e)e.hasOwnProperty(t)&&this.update(E(t))}else if(!this.root.viewmodel.implicitChanges[t.str])return this.defer&&this.ready?void bs.scheduleTask(function(){return n.getProxy(t).update()}):void this.reallyUpdate(t)},reallyUpdate:function(t){var e,n,a,r;return e=t.str,n=this.root.viewmodel.get(t),this.updating?void(this.values[e]=n):(this.updating=!0,s(n,this.values[e])&&this.ready||(a=ep.call(this.regex.exec(e),1),r=[n,this.values[e],e].concat(a),this.values[e]=n,this.callback.apply(this.context,r)),void(this.updating=!1))},getProxy:function(t){var e=this;return this.proxies[t.str]||(this.proxies[t.str]={update:function(){return e.reallyUpdate(t)}}),this.proxies[t.str]}};var np,ap,rp,ip,op,sp,pp=Xs,up=Et,cp={},lp=St,dp=Ct,fp=function(t){return t.trim()},hp=function(t){return""!==t},mp=Pt,vp=At,gp=Ot,bp=Tt,yp=Array.prototype,xp=function(t){return function(e){for(var n=arguments.length,a=Array(n>1?n-1:0),r=1;n>r;r++)a[r-1]=arguments[r];var o,s,p,u,c=[];if(e=E(P(e)),o=this.viewmodel.get(e),s=o.length,!i(o))throw Error("Called ractive."+t+"('"+e.str+"'), but '"+e.str+"' does not refer to an array");return c=bp(o,t,a),u=yp[t].apply(o,a),p=bs.start(this,!0).then(function(){return u}),c?this.viewmodel.smartUpdate(e,o,c):this.viewmodel.mark(e),bs.end(),p}},_p=xp("pop"),wp=xp("push"),kp="/* Ractive.js component styles */\n",Ep=[],Sp=!1;Xi?(rp=document.createElement("style"),rp.type="text/css",ip=document.getElementsByTagName("head")[0],sp=!1,op=rp.styleSheet,ap=function(){var t=kp+Ep.map(function(t){return"\n/* {"+t.id+"} */\n"+t.styles}).join("\n");op?op.cssText=t:rp.innerHTML=t,sp||(ip.appendChild(rp),sp=!0)},np={add:function(t){Ep.push(t),Sp=!0},apply:function(){Sp&&(ap(),Sp=!1)}}):np={add:ko,apply:ko};var Cp,Pp,Ap,Op=np,Tp=Rt,jp=new is("render"),Rp=new is("complete"),Mp={extend:function(t,e,n){e.adapt=Lt(e.adapt,L(n.adapt))},init:function(){}},Lp=Mp,Dp=Dt,Np=/(?:^|\})?\s*([^\{\}]+)\s*\{/g,Fp=/\/\*.*?\*\//g,Ip=/((?:(?:\[[^\]+]\])|(?:[^\s\+\>\~:]))+)((?::[^\s\+\>\~\(]+(?:\([^\)]+\))?)?\s*[\s\+\>\~]?)\s*/g,Bp=/^@media/,qp=/\[data-ractive-css~="\{[a-z0-9-]+\}"]/g,Up=1,Gp={name:"css",extend:function(t,e,n){if(n.css){var a=Up++,r=n.noCssTransform?n.css:Dp(n.css,a);e.cssId=a,Op.add({id:a,styles:r})}},init:function(){}},Vp=Gp,zp={name:"data",extend:function(t,e,n){var a=void 0,r=void 0;if(n.data&&u(n.data))for(a in n.data)r=n.data[a],r&&"object"==typeof r&&(u(r)||i(r))&&m("Passing a `data` option with object and array properties to Ractive.extend() is discouraged, as mutating them is likely to cause bugs. Consider using a data function instead:\n\n // this...\n data: function () {\n return {\n myObject: {}\n };\n })\n\n // instead of this:\n data: {\n myObject: {}\n }");e.data=Bt(e.data,n.data)},init:function(t,e,n){var a=Bt(t.prototype.data,n.data);return"function"==typeof a&&(a=a.call(e)),a||{}},reset:function(t){var e=this.init(t.constructor,t,t.viewmodel);return t.viewmodel.reset(e),!0}},Wp=zp,Hp=null,Kp=["preserveWhitespace","sanitize","stripComments","delimiters","tripleDelimiters","interpolate"],Qp={fromId:zt,isHashedId:Wt,isParsed:Ht,getParseOptions:Kt,createHelper:Gt,parse:Vt},$p=Qp,Yp={name:"template",extend:function(t,e,n){var a;"template"in n&&(a=n.template,"function"==typeof a?e.template=a:e.template=Jt(a,e))},init:function(t,e,n){var a,r;a="template"in n?n.template:t.prototype.template,"function"==typeof a&&(r=a,a=$t(e,r),e._config.template={fn:r,result:a}),a=Jt(a,e),e.template=a.t,a.p&&Xt(e.partials,a.p)},reset:function(t){var e,n=Qt(t);return n?(e=Jt(n,t),t.template=e.t,Xt(t.partials,e.p,!0),!0):void 0}},Jp=Yp;Cp=["adaptors","components","computed","decorators","easing","events","interpolators","partials","transitions"],Pp=function(t,e){this.name=t,this.useDefaults=e},Pp.prototype={constructor:Pp,extend:function(t,e,n){this.configure(this.useDefaults?t.defaults:t,this.useDefaults?e:e.constructor,n)},init:function(){},configure:function(t,e,n){var a,r=this.name,i=n[r];a=Eo(t[r]);for(var o in i)a[o]=i[o];e[r]=a},reset:function(t){var e=t[this.name],n=!1;return Object.keys(e).forEach(function(t){var a=e[t];a._fn&&(a._fn.isOwner?e[t]=a._fn:delete e[t],n=!0)}),n}},Ap=Cp.map(function(t){return new Pp(t,"computed"===t)});var Xp,Zp,tu,eu,nu,au,ru=Ap,iu=Zt,ou=ae;eu={adapt:Lp,css:Vp,data:Wp,template:Jp},tu=Object.keys(so),au=oe(tu.filter(function(t){return!eu[t]})),nu=oe(tu.concat(ru.map(function(t){return t.name}))),Zp=[].concat(tu.filter(function(t){return!ru[t]&&!eu[t]}),ru,eu.data,eu.template,eu.css),Xp={extend:function(t,e,n){return re("extend",t,e,n)},init:function(t,e,n){return re("init",t,e,n)},reset:function(t){return Zp.filter(function(e){return e.reset&&e.reset(t)}).map(function(t){return t.name})},order:Zp};var su,pu,uu=Xp,cu=se,lu=pe,du=ue,fu=ce,hu=le,mu=de,vu=fe,gu=he,bu=/^\s+/;pu=function(t){this.name="ParseError",this.message=t;try{throw Error(t)}catch(e){this.stack=e.stack}},pu.prototype=Error.prototype,su=function(t,e){var n,a,r=0;for(this.str=t,this.options=e||{},this.pos=0,this.lines=this.str.split("\n"),this.lineEnds=this.lines.map(function(t){var e=r+t.length+1;return r=e,e},0),this.init&&this.init(t,e),n=[];this.posn;n+=1)if(this.pos=e,r=t[n](this))return r;return null},getLinePos:function(t){for(var e,n=0,a=0;t>=this.lineEnds[n];)a=this.lineEnds[n],n+=1;return e=t-a,[n+1,e+1,t]},error:function(t){var e=this.getLinePos(this.pos),n=e[0],a=e[1],r=this.lines[e[0]-1],i=0,o=r.replace(/\t/g,function(t,n){return n/g,lc=/&/g;var gc=function(){return e(this.node)},bc=function(t){this.type=ku,this.text=t.template};bc.prototype={detach:gc,firstNode:function(){return this.node},render:function(){return this.node||(this.node=document.createTextNode(this.text)),this.node},toString:function(t){return t?Ee(this.text):this.text},unrender:function(t){return t?this.detach():void 0}};var yc=bc,xc=Se,_c=Ce,wc=function(t,e,n){var a;this.ref=e,this.resolved=!1,this.root=t.root,this.parentFragment=t.parentFragment,this.callback=n,a=ls(t.root,e,t.parentFragment),void 0!=a?this.resolve(a):bs.addUnresolved(this)};wc.prototype={resolve:function(t){this.keypath&&!t&&bs.addUnresolved(this),this.resolved=!0,this.keypath=t,this.callback(t)},forceResolution:function(){this.resolve(E(this.ref))},rebind:function(t,e){var n;void 0!=this.keypath&&(n=this.keypath.replace(t,e),void 0!==n&&this.resolve(n))},unbind:function(){this.resolved||bs.removeUnresolved(this)}};var kc=wc,Ec=function(t,e,n){this.parentFragment=t.parentFragment,this.ref=e,this.callback=n,this.rebind()},Sc={"@keypath":{prefix:"c",prop:["context"]},"@index":{prefix:"i",prop:["index"]},"@key":{prefix:"k",prop:["key","index"]}};Ec.prototype={rebind:function(){var t,e=this.ref,n=this.parentFragment,a=Sc[e];if(!a)throw Error('Unknown special reference "'+e+'" - valid references are @index, @key and @keypath');if(this.cached)return this.callback(E("@"+a.prefix+Pe(this.cached,a)));if(-1!==a.prop.indexOf("index")||-1!==a.prop.indexOf("key"))for(;n;){if(n.owner.currentSubtype===Bu&&void 0!==(t=Pe(n,a)))return this.cached=n,n.registerIndexRef(this),this.callback(E("@"+a.prefix+t));n=!n.parent&&n.owner&&n.owner.component&&n.owner.component.parentFragment&&!n.owner.component.instance.isolated?n.owner.component.parentFragment:n.parent}else for(;n;){if(void 0!==(t=Pe(n,a)))return this.callback(E("@"+a.prefix+t.str));n=n.parent}},unbind:function(){this.cached&&this.cached.unregisterIndexRef(this)}};var Cc=Ec,Pc=function(t,e,n){this.parentFragment=t.parentFragment,this.ref=e,this.callback=n,e.ref.fragment.registerIndexRef(this),this.rebind()};Pc.prototype={rebind:function(){var t,e=this.ref.ref;t="k"===e.ref.t?"k"+e.fragment.key:"i"+e.fragment.index,void 0!==t&&this.callback(E("@"+t))},unbind:function(){this.ref.ref.fragment.unregisterIndexRef(this)}};var Ac=Pc,Oc=Ae;Ae.resolve=function(t){var e,n,a={};for(e in t.refs)n=t.refs[e],a[n.ref.n]="k"===n.ref.t?n.fragment.key:n.fragment.index;return a};var Tc,jc=Oe,Rc=Te,Mc={},Lc=Function.prototype.bind;Tc=function(t,e,n,a){var r,i=this;r=t.root,this.root=r,this.parentFragment=e,this.callback=a,this.owner=t,this.str=n.s,this.keypaths=[],this.pending=n.r.length,this.refResolvers=n.r.map(function(t,e){return jc(i,t,function(t){i.resolve(e,t)})}),this.ready=!0,this.bubble()},Tc.prototype={bubble:function(){this.ready&&(this.uniqueString=Re(this.str,this.keypaths),this.keypath=Me(this.uniqueString),this.createEvaluator(),this.callback(this.keypath))},unbind:function(){for(var t;t=this.refResolvers.pop();)t.unbind()},resolve:function(t,e){this.keypaths[t]=e,this.bubble()},createEvaluator:function(){var t,e,n,a,r,i=this;a=this.keypath,t=this.root.viewmodel.computations[a.str],t?this.root.viewmodel.mark(a):(r=Rc(this.str,this.refResolvers.length),e=this.keypaths.map(function(t){var e;return"undefined"===t?function(){}:t.isSpecial?(e=t.value,function(){return e}):function(){var e=i.root.viewmodel.get(t,{noUnwrap:!0,fullRootGet:!0});return"function"==typeof e&&(e=De(e,i.root)),e}}),n={deps:this.keypaths.filter(Le),getter:function(){var t=e.map(je);return r.apply(null,t)}},t=this.root.viewmodel.compute(a,n))},rebind:function(t,e){this.refResolvers.forEach(function(n){return n.rebind(t,e)})}};var Dc=Tc,Nc=function(t,e,n){var a=this;this.resolver=e,this.root=e.root,this.parentFragment=n,this.viewmodel=e.root.viewmodel,"string"==typeof t?this.value=t:t.t===Nu?this.refResolver=jc(this,t.n,function(t){a.resolve(t)}):new Dc(e,n,t,function(t){a.resolve(t)})};Nc.prototype={resolve:function(t){this.keypath&&this.viewmodel.unregister(this.keypath,this),this.keypath=t,this.value=this.viewmodel.get(t),this.bind(),this.resolver.bubble()},bind:function(){this.viewmodel.register(this.keypath,this)},rebind:function(t,e){this.refResolver&&this.refResolver.rebind(t,e)},setValue:function(t){this.value=t,this.resolver.bubble()},unbind:function(){this.keypath&&this.viewmodel.unregister(this.keypath,this),this.refResolver&&this.refResolver.unbind()},forceResolution:function(){this.refResolver&&this.refResolver.forceResolution()}};var Fc=Nc,Ic=function(t,e,n){var a,r,i,o,s=this;this.parentFragment=o=t.parentFragment,this.root=a=t.root,this.mustache=t,this.ref=r=e.r,this.callback=n,this.unresolved=[],(i=ls(a,r,o))?this.base=i:this.baseResolver=new kc(this,r,function(t){s.base=t,s.baseResolver=null,s.bubble()}),this.members=e.m.map(function(t){return new Fc(t,s,o)}),this.ready=!0,this.bubble()};Ic.prototype={getKeypath:function(){var t=this.members.map(Ne);return!t.every(Fe)||this.baseResolver?null:this.base.join(t.join("."))},bubble:function(){this.ready&&!this.baseResolver&&this.callback(this.getKeypath())},unbind:function(){this.members.forEach(K)},rebind:function(t,e){var n;if(this.base){var a=this.base.replace(t,e);a&&a!==this.base&&(this.base=a,n=!0)}this.members.forEach(function(a){a.rebind(t,e)&&(n=!0)}),n&&this.bubble()},forceResolution:function(){this.baseResolver&&(this.base=E(this.ref),this.baseResolver.unbind(),this.baseResolver=null),this.members.forEach(Ie),this.bubble()}};var Bc=Ic,qc=Be,Uc=qe,Gc=Ue,Vc={getValue:_c,init:qc,resolve:Uc,rebind:Gc},zc=function(t){this.type=Eu,Vc.init(this,t)};zc.prototype={update:function(){this.node.data=void 0==this.value?"":this.value},resolve:Vc.resolve,rebind:Vc.rebind,detach:gc,unbind:xc,render:function(){return this.node||(this.node=document.createTextNode(n(this.value))),this.node},unrender:function(t){t&&e(this.node)},getValue:Vc.getValue,setValue:function(t){var e;this.keypath&&(e=this.root.viewmodel.wrapped[this.keypath.str])&&(t=e.get()),s(t,this.value)||(this.value=t,this.parentFragment.bubble(),this.node&&bs.addView(this))},firstNode:function(){return this.node},toString:function(t){var e=""+n(this.value);return t?Ee(e):e}};var Wc=zc,Hc=Ge,Kc=Ve,Qc=ze,$c=We,Yc=He,Jc=Ke,Xc=Qe,Zc=$e,tl=Ye,el=function(t,e){Vc.rebind.call(this,t,e)},nl=Xe,al=Ze,rl=ln,il=dn,ol=fn,sl=vn,pl=function(t){this.type=Cu,this.subtype=this.currentSubtype=t.template.n,this.inverted=this.subtype===Iu,this.pElement=t.pElement,this.fragments=[],this.fragmentsToCreate=[],this.fragmentsToRender=[],this.fragmentsToUnrender=[],t.template.i&&(this.indexRefs=t.template.i.split(",").map(function(t,e){return{n:t,t:0===e?"k":"i"}})),this.renderedFragments=[],this.length=0,Vc.init(this,t)};pl.prototype={bubble:Hc,detach:Kc,find:Qc,findAll:$c,findAllComponents:Yc,findComponent:Jc,findNextNode:Xc,firstNode:Zc,getIndexRef:function(t){if(this.indexRefs)for(var e=this.indexRefs.length;e--;){var n=this.indexRefs[e];if(n.n===t)return n}},getValue:Vc.getValue,shuffle:tl,rebind:el,render:nl,resolve:Vc.resolve,setValue:al,toString:rl,unbind:il,unrender:ol,update:sl};var ul,cl,ll=pl,dl=gn,fl=bn,hl=yn,ml=xn,vl={};try{co("table").innerHTML="foo"}catch(Ao){ul=!0,cl={TABLE:['',"
    "],THEAD:['',"
    "],TBODY:['',"
    "],TR:['',"
    "],SELECT:['"]}}var gl=function(t,e,n){var a,r,i,o,s,p=[];if(null!=t&&""!==t){for(ul&&(r=cl[e.tagName])?(a=_n("DIV"),a.innerHTML=r[0]+t+r[1],a=a.querySelector(".x"),"SELECT"===a.tagName&&(i=a.options[a.selectedIndex])):e.namespaceURI===no.svg?(a=_n("DIV"),a.innerHTML=''+t+"",a=a.querySelector(".x")):(a=_n(e.tagName),a.innerHTML=t,"SELECT"===a.tagName&&(i=a.options[a.selectedIndex]));o=a.firstChild;)p.push(o),n.appendChild(o);if("SELECT"===e.tagName)for(s=p.length;s--;)p[s]!==i&&(p[s].selected=!1)}return p},bl=wn,yl=En,xl=Sn,_l=Cn,wl=Pn,kl=An,El=function(t){this.type=Su,Vc.init(this,t)};El.prototype={detach:dl,find:fl,findAll:hl,firstNode:ml,getValue:Vc.getValue,rebind:Vc.rebind,render:yl,resolve:Vc.resolve,setValue:xl,toString:_l,unbind:xc,unrender:wl,update:kl};var Sl,Cl,Pl,Al,Ol=El,Tl=function(){this.parentFragment.bubble()},jl=On,Rl=function(t){return this.node?lo(this.node,t)?this.node:this.fragment&&this.fragment.find?this.fragment.find(t):void 0:null},Ml=function(t,e){e._test(this,!0)&&e.live&&(this.liveQueries||(this.liveQueries=[])).push(e),this.fragment&&this.fragment.findAll(t,e)},Ll=function(t,e){this.fragment&&this.fragment.findAllComponents(t,e)},Dl=function(t){return this.fragment?this.fragment.findComponent(t):void 0},Nl=Tn,Fl=jn,Il=Rn,Bl=/^true|on|yes|1$/i,ql=/^[0-9]+$/,Ul=function(t,e){var n,a,r;return r=e.a||{},a={},n=r.twoway,void 0!==n&&(a.twoway=0===n||Bl.test(n)),n=r.lazy,void 0!==n&&(0!==n&&ql.test(n)?a.lazy=parseInt(n):a.lazy=0===n||Bl.test(n)),a},Gl=Mn;Sl="altGlyph altGlyphDef altGlyphItem animateColor animateMotion animateTransform clipPath feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap feDistantLight feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur feImage feMerge feMergeNode feMorphology feOffset fePointLight feSpecularLighting feSpotLight feTile feTurbulence foreignObject glyphRef linearGradient radialGradient textPath vkern".split(" "),Cl="attributeName attributeType baseFrequency baseProfile calcMode clipPathUnits contentScriptType contentStyleType diffuseConstant edgeMode externalResourcesRequired filterRes filterUnits glyphRef gradientTransform gradientUnits kernelMatrix kernelUnitLength keyPoints keySplines keyTimes lengthAdjust limitingConeAngle markerHeight markerUnits markerWidth maskContentUnits maskUnits numOctaves pathLength patternContentUnits patternTransform patternUnits pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits refX refY repeatCount repeatDur requiredExtensions requiredFeatures specularConstant specularExponent spreadMethod startOffset stdDeviation stitchTiles surfaceScale systemLanguage tableValues targetX targetY textLength viewBox viewTarget xChannelSelector yChannelSelector zoomAndPan".split(" "),Pl=function(t){for(var e={},n=t.length;n--;)e[t[n].toLowerCase()]=t[n];return e},Al=Pl(Sl.concat(Cl));var Vl=function(t){var e=t.toLowerCase();return Al[e]||e},zl=function(t,e){var n,a;if(n=e.indexOf(":"),-1===n||(a=e.substr(0,n),"xmlns"===a))t.name=t.element.namespace!==no.html?Vl(e):e;else if(e=e.substring(n+1),t.name=Vl(e),t.namespace=no[a.toLowerCase()],t.namespacePrefix=a,!t.namespace)throw'Unknown namespace ("'+a+'")'},Wl=Ln,Hl=Dn,Kl=Nn,Ql=Fn,$l={"accept-charset":"acceptCharset",accesskey:"accessKey",bgcolor:"bgColor","class":"className",codebase:"codeBase",colspan:"colSpan",contenteditable:"contentEditable",datetime:"dateTime",dirname:"dirName","for":"htmlFor","http-equiv":"httpEquiv",ismap:"isMap",maxlength:"maxLength",novalidate:"noValidate",pubdate:"pubDate",readonly:"readOnly",rowspan:"rowSpan",tabindex:"tabIndex",usemap:"useMap"},Yl=In,Jl=qn,Xl=Un,Zl=Gn,td=Vn,ed=zn,nd=Wn,ad=Hn,rd=Kn,id=Qn,od=$n,sd=Yn,pd=Jn,ud=Xn,cd=Zn,ld=function(t){this.init(t)};ld.prototype={bubble:Gl,init:Hl,rebind:Kl,render:Ql,toString:Yl,unbind:Jl,update:cd};var dd,fd=ld,hd=function(t,e){var n,a,r=[];for(n in e)"twoway"!==n&&"lazy"!==n&&e.hasOwnProperty(n)&&(a=new fd({element:t,name:n,value:e[n],root:t.root}),r[n]=a,"value"!==n&&r.push(a));return(a=r.value)&&r.push(a),r};"undefined"!=typeof document&&(dd=co("div"));var md=function(t,e){this.element=t,this.root=t.root,this.parentFragment=t.parentFragment,this.attributes=[],this.fragment=new rv({root:t.root,owner:this,template:[e]})};md.prototype={bubble:function(){this.node&&this.update(),this.element.bubble()},rebind:function(t,e){this.fragment.rebind(t,e)},render:function(t){this.node=t,this.isSvg=t.namespaceURI===no.svg,this.update()},unbind:function(){this.fragment.unbind()},update:function(){var t,e,n=this;t=""+this.fragment,e=ta(t,this.isSvg),this.attributes.filter(function(t){return ea(e,t)}).forEach(function(t){n.node.removeAttribute(t.name)}),e.forEach(function(t){n.node.setAttribute(t.name,t.value)}),this.attributes=e},toString:function(){return""+this.fragment}};var vd=md,gd=function(t,e){return e?e.map(function(e){return new vd(t,e)}):[]},bd=function(t){var e,n,a,r;if(this.element=t,this.root=t.root,this.attribute=t.attributes[this.name||"value"],e=this.attribute.interpolator,e.twowayBinding=this,n=e.keypath){if("}"===n.str.slice(-1))return v("Two-way binding does not work with expressions (`%s` on <%s>)",e.resolver.uniqueString,t.name,{ractive:this.root}),!1;if(n.isSpecial)return v("Two-way binding does not work with %s",e.resolver.ref,{ractive:this.root}),!1}else{var i=e.template.r?"'"+e.template.r+"' reference":"expression";m("The %s being used for two-way binding is ambiguous, and may cause unexpected results. Consider initialising your data to eliminate the ambiguity",i,{ractive:this.root}),e.resolver.forceResolution(),n=e.keypath}this.attribute.isTwoway=!0,this.keypath=n,a=this.root.viewmodel.get(n),void 0===a&&this.getInitialValue&&(a=this.getInitialValue(),void 0!==a&&this.root.viewmodel.set(n,a)),(r=na(t))&&(this.resetValue=a,r.formBindings.push(this))};bd.prototype={handleChange:function(){var t=this;bs.start(this.root),this.attribute.locked=!0,this.root.viewmodel.set(this.keypath,this.getValue()),bs.scheduleTask(function(){return t.attribute.locked=!1}),bs.end()},rebound:function(){var t,e,n;e=this.keypath,n=this.attribute.interpolator.keypath,e!==n&&(N(this.root._twowayBindings[e.str],this),this.keypath=n,t=this.root._twowayBindings[n.str]||(this.root._twowayBindings[n.str]=[]),t.push(this))},unbind:function(){}},bd.extend=function(t){var e,n=this;return e=function(t){bd.call(this,t),this.init&&this.init()},e.prototype=Eo(n.prototype),a(e.prototype,t),e.extend=bd.extend,e};var yd,xd=bd,_d=aa;yd=xd.extend({getInitialValue:function(){return""},getValue:function(){return this.element.node.value},render:function(){var t,e=this.element.node,n=!1;this.rendered=!0,t=this.root.lazy,this.element.lazy===!0?t=!0:this.element.lazy===!1?t=!1:p(this.element.lazy)?(t=!1,n=+this.element.lazy):p(t||"")&&(n=+t,t=!1,this.element.lazy=n),this.handler=n?ia:_d,e.addEventListener("change",_d,!1),t||(e.addEventListener("input",this.handler,!1),e.attachEvent&&e.addEventListener("keyup",this.handler,!1)),e.addEventListener("blur",ra,!1)},unrender:function(){var t=this.element.node;this.rendered=!1,t.removeEventListener("change",_d,!1),t.removeEventListener("input",this.handler,!1),t.removeEventListener("keyup",this.handler,!1),t.removeEventListener("blur",ra,!1)}});var wd=yd,kd=wd.extend({getInitialValue:function(){return this.element.fragment?""+this.element.fragment:""},getValue:function(){return this.element.node.innerHTML}}),Ed=kd,Sd=oa,Cd={},Pd=xd.extend({name:"checked",init:function(){this.siblings=Sd(this.root._guid,"radio",this.element.getAttribute("name")),this.siblings.push(this)},render:function(){var t=this.element.node;t.addEventListener("change",_d,!1),t.attachEvent&&t.addEventListener("click",_d,!1)},unrender:function(){var t=this.element.node;t.removeEventListener("change",_d,!1),t.removeEventListener("click",_d,!1)},handleChange:function(){bs.start(this.root),this.siblings.forEach(function(t){t.root.viewmodel.set(t.keypath,t.getValue())}),bs.end()},getValue:function(){return this.element.node.checked},unbind:function(){N(this.siblings,this)}}),Ad=Pd,Od=xd.extend({name:"name",init:function(){this.siblings=Sd(this.root._guid,"radioname",this.keypath.str),this.siblings.push(this),this.radioName=!0},getInitialValue:function(){return this.element.getAttribute("checked")?this.element.getAttribute("value"):void 0},render:function(){var t=this.element.node;t.name="{{"+this.keypath.str+"}}",t.checked=this.root.viewmodel.get(this.keypath)==this.element.getAttribute("value"),t.addEventListener("change",_d,!1),t.attachEvent&&t.addEventListener("click",_d,!1)},unrender:function(){var t=this.element.node;t.removeEventListener("change",_d,!1),t.removeEventListener("click",_d,!1)},getValue:function(){var t=this.element.node;return t._ractive?t._ractive.value:t.value},handleChange:function(){this.element.node.checked&&xd.prototype.handleChange.call(this)},rebound:function(t,e){var n;xd.prototype.rebound.call(this,t,e),(n=this.element.node)&&(n.name="{{"+this.keypath.str+"}}")},unbind:function(){N(this.siblings,this)}}),Td=Od,jd=xd.extend({name:"name",getInitialValue:function(){return this.noInitialValue=!0,[]},init:function(){var t,e;this.checkboxName=!0,this.siblings=Sd(this.root._guid,"checkboxes",this.keypath.str),this.siblings.push(this),this.noInitialValue&&(this.siblings.noInitialValue=!0),this.siblings.noInitialValue&&this.element.getAttribute("checked")&&(t=this.root.viewmodel.get(this.keypath),e=this.element.getAttribute("value"),t.push(e))},unbind:function(){N(this.siblings,this)},render:function(){var t,e,n=this.element.node;t=this.root.viewmodel.get(this.keypath),e=this.element.getAttribute("value"),i(t)?this.isChecked=R(t,e):this.isChecked=t==e,n.name="{{"+this.keypath.str+"}}",n.checked=this.isChecked,n.addEventListener("change",_d,!1),n.attachEvent&&n.addEventListener("click",_d,!1)},unrender:function(){var t=this.element.node;t.removeEventListener("change",_d,!1),t.removeEventListener("click",_d,!1)},changed:function(){var t=!!this.isChecked;return this.isChecked=this.element.node.checked,this.isChecked===t},handleChange:function(){this.isChecked=this.element.node.checked,xd.prototype.handleChange.call(this)},getValue:function(){return this.siblings.filter(sa).map(pa)}}),Rd=jd,Md=xd.extend({name:"checked",render:function(){var t=this.element.node;t.addEventListener("change",_d,!1),t.attachEvent&&t.addEventListener("click",_d,!1)},unrender:function(){var t=this.element.node;t.removeEventListener("change",_d,!1),t.removeEventListener("click",_d,!1)},getValue:function(){return this.element.node.checked}}),Ld=Md,Dd=xd.extend({getInitialValue:function(){var t,e,n,a,r=this.element.options;if(void 0===this.element.getAttribute("value")&&(e=t=r.length,t)){for(;e--;)if(r[e].getAttribute("selected")){n=r[e].getAttribute("value"),a=!0;break}if(!a)for(;++ee;e+=1)if(a=t[e],t[e].selected)return r=a._ractive?a._ractive.value:a.value},forceUpdate:function(){var t=this,e=this.getValue();void 0!==e&&(this.attribute.locked=!0,bs.scheduleTask(function(){return t.attribute.locked=!1}),this.root.viewmodel.set(this.keypath,e))}}),Nd=Dd,Fd=Nd.extend({getInitialValue:function(){return this.element.options.filter(function(t){return t.getAttribute("selected")}).map(function(t){return t.getAttribute("value")})},render:function(){var t;this.element.node.addEventListener("change",_d,!1),t=this.root.viewmodel.get(this.keypath),void 0===t&&this.handleChange()},unrender:function(){this.element.node.removeEventListener("change",_d,!1)},setValue:function(){throw Error("TODO not implemented yet")},getValue:function(){var t,e,n,a,r,i;for(t=[],e=this.element.node.options,a=e.length,n=0;a>n;n+=1)r=e[n],r.selected&&(i=r._ractive?r._ractive.value:r.value,t.push(i));return t},handleChange:function(){var t,e,n;return t=this.attribute,e=t.value,n=this.getValue(),void 0!==e&&M(n,e)||Nd.prototype.handleChange.call(this),this},forceUpdate:function(){var t=this,e=this.getValue();void 0!==e&&(this.attribute.locked=!0,bs.scheduleTask(function(){return t.attribute.locked=!1}),this.root.viewmodel.set(this.keypath,e))},updateModel:function(){void 0!==this.attribute.value&&this.attribute.value.length||this.root.viewmodel.set(this.keypath,this.initialValue)}}),Id=Fd,Bd=xd.extend({render:function(){this.element.node.addEventListener("change",_d,!1)},unrender:function(){this.element.node.removeEventListener("change",_d,!1)},getValue:function(){return this.element.node.files}}),qd=Bd,Ud=wd.extend({getInitialValue:function(){},getValue:function(){var t=parseFloat(this.element.node.value);return isNaN(t)?void 0:t}}),Gd=ua,Vd=la,zd=da,Wd=fa,Hd=ha,Kd=/^event(?:\.(.+))?/,Qd=ba,$d=ya,Yd={},Jd={touchstart:!0,touchmove:!0,touchend:!0,touchcancel:!0,touchleave:!0},Xd=_a,Zd=wa,tf=ka,ef=Ea,nf=Sa,af=function(t,e,n){this.init(t,e,n)};af.prototype={bubble:Vd,fire:zd,getAction:Wd,init:Hd,listen:$d,rebind:Xd,render:Zd,resolve:tf,unbind:ef,unrender:nf};var rf=af,of=function(t,e){var n,a,r,i,o=[];for(a in e)if(e.hasOwnProperty(a))for(r=a.split("-"),n=r.length;n--;)i=new rf(t,r[n],e[a]),o.push(i);return o},sf=function(t,e){var n,a,r,i=this;this.element=t,this.root=n=t.root,a=e.n||e,("string"==typeof a||(r=new rv({template:a,root:n,owner:t}),a=""+r,r.unbind(),""!==a))&&(e.a?this.params=e.a:e.d&&(this.fragment=new rv({template:e.d,root:n,owner:t}),this.params=this.fragment.getArgsList(),this.fragment.bubble=function(){this.dirtyArgs=this.dirtyValue=!0,i.params=this.getArgsList(),i.ready&&i.update()}),this.fn=g("decorators",n,a),this.fn||l(Io(a,"decorator")))};sf.prototype={init:function(){var t,e,n;if(t=this.element.node,this.params?(n=[t].concat(this.params),e=this.fn.apply(this.root,n)):e=this.fn.call(this.root,t),!e||!e.teardown)throw Error("Decorator definition must return an object with a teardown method");this.actual=e,this.ready=!0},update:function(){this.actual.update?this.actual.update.apply(this.root,this.params):(this.actual.teardown(!0),this.init())},rebind:function(t,e){this.fragment&&this.fragment.rebind(t,e)},teardown:function(t){this.torndown=!0,this.ready&&this.actual.teardown(),!t&&this.fragment&&this.fragment.unbind()}};var pf,uf,cf,lf=sf,df=Ra,ff=Ma,hf=Ba,mf=function(t){return t.replace(/-([a-zA-Z])/g,function(t,e){return e.toUpperCase()})};Xi?(uf={},cf=co("div").style,pf=function(t){var e,n,a;if(t=mf(t),!uf[t])if(void 0!==cf[t])uf[t]=t;else for(a=t.charAt(0).toUpperCase()+t.substring(1),e=ro.length;e--;)if(n=ro[e],void 0!==cf[n+a]){uf[t]=n+a;break}return uf[t]}):pf=null;var vf,gf,bf=pf;Xi?(gf=window.getComputedStyle||Po.getComputedStyle,vf=function(t){var e,n,a,r,o;if(e=gf(this.node),"string"==typeof t)return o=e[bf(t)],"0px"===o&&(o=0),o;if(!i(t))throw Error("Transition$getStyle must be passed a string, or an array of strings representing CSS properties");for(n={},a=t.length;a--;)r=t[a],o=e[bf(r)],"0px"===o&&(o=0),n[r]=o;return n}):vf=null;var yf=vf,xf=function(t,e){var n;if("string"==typeof t)this.node.style[bf(t)]=e;else for(n in t)t.hasOwnProperty(n)&&(this.node.style[bf(n)]=t[n]);return this},_f=function(t){var e;this.duration=t.duration,this.step=t.step,this.complete=t.complete,"string"==typeof t.easing?(e=t.root.easing[t.easing],e||(v(Io(t.easing,"easing")),e=qa)):e="function"==typeof t.easing?t.easing:qa,this.easing=e,this.start=ns(),this.end=this.start+this.duration,this.running=!0,_s.add(this)};_f.prototype={tick:function(t){var e,n;return this.running?t>this.end?(this.step&&this.step(1),this.complete&&this.complete(1),!1):(e=t-this.start,n=this.easing(e/this.duration),this.step&&this.step(n),!0):!1},stop:function(){this.abort&&this.abort(),this.running=!1}};var wf,kf,Ef,Sf,Cf,Pf,Af,Of,Tf=_f,jf=RegExp("^-(?:"+ro.join("|")+")-"),Rf=function(t){return t.replace(jf,"")},Mf=RegExp("^(?:"+ro.join("|")+")([A-Z])"),Lf=function(t){var e;return t?(Mf.test(t)&&(t="-"+t),e=t.replace(/[A-Z]/g,function(t){return"-"+t.toLowerCase()})):""},Df={},Nf={};Xi?(kf=co("div").style,function(){void 0!==kf.transition?(Ef="transition",Sf="transitionend",Cf=!0):void 0!==kf.webkitTransition?(Ef="webkitTransition",Sf="webkitTransitionEnd",Cf=!0):Cf=!1}(),Ef&&(Pf=Ef+"Duration",Af=Ef+"Property",Of=Ef+"TimingFunction"),wf=function(t,e,n,a,r){setTimeout(function(){var i,o,s,p,u;p=function(){o&&s&&(t.root.fire(t.name+":end",t.node,t.isIntro),r())},i=(t.node.namespaceURI||"")+t.node.tagName,t.node.style[Af]=a.map(bf).map(Lf).join(","),t.node.style[Of]=Lf(n.easing||"linear"),t.node.style[Pf]=n.duration/1e3+"s",u=function(e){var n;n=a.indexOf(mf(Rf(e.propertyName))),-1!==n&&a.splice(n,1),a.length||(t.node.removeEventListener(Sf,u,!1),s=!0,p())},t.node.addEventListener(Sf,u,!1),setTimeout(function(){for(var r,c,l,d,f,h=a.length,v=[];h--;)d=a[h],r=i+d,Cf&&!Nf[r]&&(t.node.style[bf(d)]=e[d],Df[r]||(c=t.getStyle(d),Df[r]=t.getStyle(d)!=e[d],Nf[r]=!Df[r],Nf[r]&&(t.node.style[bf(d)]=c))),(!Cf||Nf[r])&&(void 0===c&&(c=t.getStyle(d)),l=a.indexOf(d),-1===l?m("Something very strange happened with transitions. Please raise an issue at https://github.com/ractivejs/ractive/issues - thanks!",{node:t.node}):a.splice(l,1),f=/[^\d]*$/.exec(e[d])[0],v.push({name:bf(d),interpolator:qo(parseFloat(c),parseFloat(e[d])),suffix:f}));v.length?new Tf({root:t.root,duration:n.duration,easing:mf(n.easing||""),step:function(e){var n,a;for(a=v.length;a--;)n=v[a],t.node.style[n.name]=n.interpolator(e)+n.suffix},complete:function(){o=!0,p()}}):o=!0,a.length||(t.node.removeEventListener(Sf,u,!1),s=!0,p())},0)},n.delay||0)}):wf=null;var Ff,If,Bf,qf,Uf,Gf=wf;if("undefined"!=typeof document){if(Ff="hidden",Uf={},Ff in document)Bf="";else for(qf=ro.length;qf--;)If=ro[qf],Ff=If+"Hidden",Ff in document&&(Bf=If);void 0!==Bf?(document.addEventListener(Bf+"visibilitychange",Ua),Ua()):("onfocusout"in document?(document.addEventListener("focusout",Ga),document.addEventListener("focusin",Va)):(window.addEventListener("pagehide",Ga),window.addEventListener("blur",Ga),window.addEventListener("pageshow",Va),window.addEventListener("focus",Va)),Uf.hidden=!1)}var Vf,zf,Wf,Hf=Uf;Xi?(zf=window.getComputedStyle||Po.getComputedStyle,Vf=function(t,e,n){var a,r=this;if(4===arguments.length)throw Error("t.animateStyle() returns a promise - use .then() instead of passing a callback");if(Hf.hidden)return this.setStyle(t,e),Wf||(Wf=us.resolve());"string"==typeof t?(a={},a[t]=e):(a=t,n=e),n||(v('The "%s" transition does not supply an options object to `t.animateStyle()`. This will break in a future version of Ractive. For more info see https://github.com/RactiveJS/Ractive/issues/340',this.name),n=this);var i=new us(function(t){var e,i,o,s,p,u,c;if(!n.duration)return r.setStyle(a),void t();for(e=Object.keys(a),i=[],o=zf(r.node),p={},u=e.length;u--;)c=e[u],s=o[bf(c)],"0px"===s&&(s=0),s!=a[c]&&(i.push(c),r.node.style[bf(c)]=s);return i.length?void Gf(r,a,n,i,t):void t()});return i}):Vf=null;var Kf=Vf,Qf=function(t,e){return"number"==typeof t?t={duration:t}:"string"==typeof t?t="slow"===t?{duration:600}:"fast"===t?{duration:200}:{duration:400}:t||(t={}),r({},t,e)},$f=za,Yf=function(t,e,n){this.init(t,e,n)};Yf.prototype={init:hf,start:$f,getStyle:yf,setStyle:xf,animateStyle:Kf,processParams:Qf};var Jf,Xf,Zf=Yf,th=Ha;Jf=function(){var t=this.node,e=this.fragment.toString(!1);if(window&&window.appearsToBeIELessEqual8&&(t.type="text/css"),t.styleSheet)t.styleSheet.cssText=e;else{for(;t.hasChildNodes();)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(e))}},Xf=function(){this.node.type&&"text/javascript"!==this.node.type||m("Script tag was updated. This does not cause the code to be re-evaluated!",{ractive:this.root}),this.node.text=this.fragment.toString(!1)};var eh=function(){var t,e;return this.template.y?"":(t="<"+this.template.e,t+=this.attributes.map(Xa).join("")+this.conditionalAttributes.map(Xa).join(""),"option"===this.name&&Ya(this)&&(t+=" selected"),"input"===this.name&&Ja(this)&&(t+=" checked"),t+=">","textarea"===this.name&&void 0!==this.getAttribute("value")?t+=Ee(this.getAttribute("value")):void 0!==this.getAttribute("contenteditable")&&(t+=this.getAttribute("value")||""),this.fragment&&(e="script"!==this.name&&"style"!==this.name,t+=this.fragment.toString(e)),ic.test(this.template.e)||(t+=""),t)},nh=Za,ah=tr,rh=function(t){this.init(t)};rh.prototype={bubble:Tl,detach:jl,find:Rl,findAll:Ml,findAllComponents:Ll,findComponent:Dl,findNextNode:Nl,firstNode:Fl,getAttribute:Il,init:df,rebind:ff,render:th,toString:eh,unbind:nh,unrender:ah};var ih=rh,oh=/^\s*$/,sh=/^\s*/,ph=function(t){var e,n,a,r;return e=t.split("\n"),n=e[0],void 0!==n&&oh.test(n)&&e.shift(),a=D(e),void 0!==a&&oh.test(a)&&e.pop(),r=e.reduce(nr,null),r&&(t=e.map(function(t){return t.replace(r,"")}).join("\n")),t},uh=ar,ch=function(t,e){var n;return e?n=t.split("\n").map(function(t,n){return n?e+t:t}).join("\n"):t},lh='Could not find template for partial "%s"',dh=function(t){var e,n;e=this.parentFragment=t.parentFragment,this.root=e.root,this.type=Au,this.index=t.index,this.name=t.template.r,this.rendered=!1,this.fragment=this.fragmentToRender=this.fragmentToUnrender=null,Vc.init(this,t),this.keypath||((n=uh(this.root,this.name,e))?(xc.call(this),this.isNamed=!0,this.setTemplate(n)):v(lh,this.name))};dh.prototype={bubble:function(){this.parentFragment.bubble()},detach:function(){return this.fragment.detach()},find:function(t){return this.fragment.find(t)},findAll:function(t,e){return this.fragment.findAll(t,e)},findComponent:function(t){return this.fragment.findComponent(t)},findAllComponents:function(t,e){return this.fragment.findAllComponents(t,e)},firstNode:function(){return this.fragment.firstNode()},findNextNode:function(){return this.parentFragment.findNextNode(this)},getPartialName:function(){return this.isNamed&&this.name?this.name:void 0===this.value?this.name:this.value},getValue:function(){return this.fragment.getValue()},rebind:function(t,e){this.isNamed||Gc.call(this,t,e),this.fragment&&this.fragment.rebind(t,e)},render:function(){return this.docFrag=document.createDocumentFragment(),this.update(),this.rendered=!0,this.docFrag},resolve:Vc.resolve,setValue:function(t){var e;(void 0===t||t!==this.value)&&(void 0!==t&&(e=uh(this.root,""+t,this.parentFragment)),!e&&this.name&&(e=uh(this.root,this.name,this.parentFragment))&&(xc.call(this),this.isNamed=!0),e||v(lh,this.name,{ractive:this.root}),this.value=t,this.setTemplate(e||[]),this.bubble(),this.rendered&&bs.addView(this))},setTemplate:function(t){this.fragment&&(this.fragment.unbind(),this.rendered&&(this.fragmentToUnrender=this.fragment)),this.fragment=new rv({template:t,root:this.root,owner:this,pElement:this.parentFragment.pElement}),this.fragmentToRender=this.fragment},toString:function(t){var e,n,a,r;return e=this.fragment.toString(t),n=this.parentFragment.items[this.index-1],n&&n.type===ku?(a=n.text.split("\n").pop(),(r=/^\s+$/.exec(a))?ch(e,r[0]):e):e},unbind:function(){this.isNamed||xc.call(this),this.fragment&&this.fragment.unbind()},unrender:function(t){this.rendered&&(this.fragment&&this.fragment.unrender(t),this.rendered=!1)},update:function(){var t,e;this.fragmentToUnrender&&(this.fragmentToUnrender.unrender(!0),this.fragmentToUnrender=null),this.fragmentToRender&&(this.docFrag.appendChild(this.fragmentToRender.render()),this.fragmentToRender=null), this.rendered&&(t=this.parentFragment.getNode(),e=this.parentFragment.findNextNode(this),t.insertBefore(this.docFrag,e))}};var fh,hh,mh,vh=dh,gh=pr,bh=ur,yh=new is("detach"),xh=cr,_h=lr,wh=dr,kh=fr,Eh=hr,Sh=mr,Ch=function(t,e,n,a){var r=t.root,i=t.keypath;a?r.viewmodel.smartUpdate(i,e,a):r.viewmodel.mark(i)},Ph=[],Ah=["pop","push","reverse","shift","sort","splice","unshift"];Ah.forEach(function(t){var e=function(){for(var e=arguments.length,n=Array(e),a=0;e>a;a++)n[a]=arguments[a];var r,i,o,s;for(r=bp(this,t,n),i=Array.prototype[t].apply(this,arguments),bs.start(),this._ractive.setting=!0,s=this._ractive.wrappers.length;s--;)o=this._ractive.wrappers[s],bs.addRactive(o.root),Ch(o,this,t,r);return bs.end(),this._ractive.setting=!1,i};So(Ph,t,{value:e})}),fh={},fh.__proto__?(hh=function(t){t.__proto__=Ph},mh=function(t){t.__proto__=Array.prototype}):(hh=function(t){var e,n;for(e=Ah.length;e--;)n=Ah[e],So(t,n,{value:Ph[n],configurable:!0})},mh=function(t){var e;for(e=Ah.length;e--;)delete t[Ah[e]]}),hh.unpatch=mh;var Oh,Th,jh,Rh=hh;Oh={filter:function(t){return i(t)&&(!t._ractive||!t._ractive.setting)},wrap:function(t,e,n){return new Th(t,e,n)}},Th=function(t,e,n){this.root=t,this.value=e,this.keypath=E(n),e._ractive||(So(e,"_ractive",{value:{wrappers:[],instances:[],setting:!1},configurable:!0}),Rh(e)),e._ractive.instances[t._guid]||(e._ractive.instances[t._guid]=0,e._ractive.instances.push(t)),e._ractive.instances[t._guid]+=1,e._ractive.wrappers.push(this)},Th.prototype={get:function(){return this.value},teardown:function(){var t,e,n,a,r;if(t=this.value,e=t._ractive,n=e.wrappers,a=e.instances,e.setting)return!1;if(r=n.indexOf(this),-1===r)throw Error(jh);if(n.splice(r,1),n.length){if(a[this.root._guid]-=1,!a[this.root._guid]){if(r=a.indexOf(this.root),-1===r)throw Error(jh);a.splice(r,1)}}else delete t._ractive,Rh.unpatch(this.value)}},jh="Something went wrong in a rather interesting way";var Mh,Lh,Dh=Oh,Nh=/^\s*[0-9]+\s*$/,Fh=function(t){return Nh.test(t)?[]:{}};try{Object.defineProperty({},"test",{value:0}),Mh={filter:function(t,e,n){var a,r;return e?(e=E(e),(a=n.viewmodel.wrapped[e.parent.str])&&!a.magic?!1:(r=n.viewmodel.get(e.parent),i(r)&&/^[0-9]+$/.test(e.lastKey)?!1:r&&("object"==typeof r||"function"==typeof r))):!1},wrap:function(t,e,n){return new Lh(t,e,n)}},Lh=function(t,e,n){var a,r,i;return n=E(n),this.magic=!0,this.ractive=t,this.keypath=n,this.value=e,this.prop=n.lastKey,a=n.parent,this.obj=a.isRoot?t.viewmodel.data:t.viewmodel.get(a),r=this.originalDescriptor=Object.getOwnPropertyDescriptor(this.obj,this.prop),r&&r.set&&(i=r.set._ractiveWrappers)?void(-1===i.indexOf(this)&&i.push(this)):void vr(this,e,r)},Lh.prototype={get:function(){return this.value},reset:function(t){return this.updating?void 0:(this.updating=!0,this.obj[this.prop]=t,bs.addRactive(this.ractive),this.ractive.viewmodel.mark(this.keypath,{keepExistingWrapper:!0}),this.updating=!1,!0)},set:function(t,e){this.updating||(this.obj[this.prop]||(this.updating=!0,this.obj[this.prop]=Fh(t),this.updating=!1),this.obj[this.prop][t]=e)},teardown:function(){var t,e,n,a,r;return this.updating?!1:(t=Object.getOwnPropertyDescriptor(this.obj,this.prop),e=t&&t.set,void(e&&(a=e._ractiveWrappers,r=a.indexOf(this),-1!==r&&a.splice(r,1),a.length||(n=this.obj[this.prop],Object.defineProperty(this.obj,this.prop,this.originalDescriptor||{writable:!0,enumerable:!0,configurable:!0}),this.obj[this.prop]=n))))}}}catch(Ao){Mh=!1}var Ih,Bh,qh=Mh;qh&&(Ih={filter:function(t,e,n){return qh.filter(t,e,n)&&Dh.filter(t)},wrap:function(t,e,n){return new Bh(t,e,n)}},Bh=function(t,e,n){this.value=e,this.magic=!0,this.magicWrapper=qh.wrap(t,e,n),this.arrayWrapper=Dh.wrap(t,e,n)},Bh.prototype={get:function(){return this.value},teardown:function(){this.arrayWrapper.teardown(),this.magicWrapper.teardown()},reset:function(t){return this.magicWrapper.reset(t)}});var Uh=Ih,Gh=gr,Vh={},zh=xr,Wh=_r,Hh=Er,Kh=Or,Qh=Tr,$h=function(t,e){this.computation=t,this.viewmodel=t.viewmodel,this.ref=e,this.root=this.viewmodel.ractive,this.parentFragment=this.root.component&&this.root.component.parentFragment};$h.prototype={resolve:function(t){this.computation.softDeps.push(t),this.computation.unresolvedDeps[t.str]=null,this.viewmodel.register(t,this.computation,"computed")}};var Yh=$h,Jh=function(t,e){this.key=t,this.getter=e.getter,this.setter=e.setter,this.hardDeps=e.deps||[],this.softDeps=[],this.unresolvedDeps={},this.depValues={},this._dirty=this._firstRun=!0};Jh.prototype={constructor:Jh,init:function(t){var e,n=this;this.viewmodel=t,this.bypass=!0,e=t.get(this.key),t.clearCache(this.key.str),this.bypass=!1,this.setter&&void 0!==e&&this.set(e),this.hardDeps&&this.hardDeps.forEach(function(e){return t.register(e,n,"computed")})},invalidate:function(){this._dirty=!0},get:function(){var t,e,n=this,a=!1;if(this.getting){var r="The "+this.key.str+" computation indirectly called itself. This probably indicates a bug in the computation. It is commonly caused by `array.sort(...)` - if that's the case, clone the array first with `array.slice().sort(...)`";return h(r),this.value}if(this.getting=!0,this._dirty){if(this._firstRun||!this.hardDeps.length&&!this.softDeps.length?a=!0:[this.hardDeps,this.softDeps].forEach(function(t){var e,r,i;if(!a)for(i=t.length;i--;)if(e=t[i],r=n.viewmodel.get(e),!s(r,n.depValues[e.str]))return n.depValues[e.str]=r,void(a=!0)}),a){this.viewmodel.capture();try{this.value=this.getter()}catch(i){m('Failed to compute "%s"',this.key.str),d(i.stack||i),this.value=void 0}t=this.viewmodel.release(),e=this.updateDependencies(t),e&&[this.hardDeps,this.softDeps].forEach(function(t){t.forEach(function(t){n.depValues[t.str]=n.viewmodel.get(t)})})}this._dirty=!1}return this.getting=this._firstRun=!1,this.value},set:function(t){if(this.setting)return void(this.value=t);if(!this.setter)throw Error("Computed properties without setters are read-only. (This may change in a future version of Ractive!)");this.setter(t)},updateDependencies:function(t){var e,n,a,r,i;for(n=this.softDeps,e=n.length;e--;)a=n[e],-1===t.indexOf(a)&&(r=!0,this.viewmodel.unregister(a,this,"computed"));for(e=t.length;e--;)a=t[e],-1!==n.indexOf(a)||this.hardDeps&&-1!==this.hardDeps.indexOf(a)||(r=!0,jr(this.viewmodel,a)&&!this.unresolvedDeps[a.str]?(i=new Yh(this,a.str),t.splice(e,1),this.unresolvedDeps[a.str]=i,bs.addUnresolved(i)):this.viewmodel.register(a,this,"computed"));return r&&(this.softDeps=t.slice()),r}};var Xh=Jh,Zh=Rr,tm={FAILED_LOOKUP:!0},em=Mr,nm={},am=Dr,rm=Nr,im=function(t,e){this.localKey=t,this.keypath=e.keypath,this.origin=e.origin,this.deps=[],this.unresolved=[],this.resolved=!1};im.prototype={forceResolution:function(){this.keypath=this.localKey,this.setup()},get:function(t,e){return this.resolved?this.origin.get(this.map(t),e):void 0},getValue:function(){return this.keypath?this.origin.get(this.keypath):void 0},initViewmodel:function(t){this.local=t,this.setup()},map:function(t){return void 0===typeof this.keypath?this.localKey:t.replace(this.localKey,this.keypath)},register:function(t,e,n){this.deps.push({keypath:t,dep:e,group:n}),this.resolved&&this.origin.register(this.map(t),e,n)},resolve:function(t){void 0!==this.keypath&&this.unbind(!0),this.keypath=t,this.setup()},set:function(t,e){this.resolved||this.forceResolution(),this.origin.set(this.map(t),e)},setup:function(){var t=this;void 0!==this.keypath&&(this.resolved=!0,this.deps.length&&(this.deps.forEach(function(e){var n=t.map(e.keypath);if(t.origin.register(n,e.dep,e.group),e.dep.setValue)e.dep.setValue(t.origin.get(n));else{if(!e.dep.invalidate)throw Error("An unexpected error occurred. Please raise an issue at https://github.com/ractivejs/ractive/issues - thanks!");e.dep.invalidate()}}),this.origin.mark(this.keypath)))},setValue:function(t){if(!this.keypath)throw Error("Mapping does not have keypath, cannot set value. Please raise an issue at https://github.com/ractivejs/ractive/issues - thanks!");this.origin.set(this.keypath,t)},unbind:function(t){var e=this;t||delete this.local.mappings[this.localKey],this.resolved&&(this.deps.forEach(function(t){e.origin.unregister(e.map(t.keypath),t.dep,t.group)}),this.tracker&&this.origin.unregister(this.keypath,this.tracker))},unregister:function(t,e,n){var a,r;if(this.resolved){for(a=this.deps,r=a.length;r--;)if(a[r].dep===e){a.splice(r,1);break}this.origin.unregister(this.map(t),e,n)}}};var om=Fr,sm=function(t,e){var n,a,r,i;return n={},a=0,r=t.map(function(t,r){var o,s,p;s=a,p=e.length;do{if(o=e.indexOf(t,s),-1===o)return i=!0,-1;s=o+1}while(n[o]&&p>s);return o===a&&(a+=1),o!==r&&(i=!0),n[o]=!0,o})},pm=Ir,um={},cm=Ur,lm=Vr,dm=zr,fm=Wr,hm=Kr,mm={implicit:!0},vm={noCascade:!0},gm=$r,bm=Yr,ym=function(t){var e,n,a=t.adapt,r=t.data,i=t.ractive,o=t.computed,s=t.mappings;this.ractive=i,this.adaptors=a,this.onchange=t.onchange,this.cache={},this.cacheMap=Eo(null),this.deps={computed:Eo(null),"default":Eo(null)},this.depsMap={computed:Eo(null),"default":Eo(null)},this.patternObservers=[],this.specials=Eo(null),this.wrapped=Eo(null),this.computations=Eo(null),this.captureGroups=[],this.unresolvedImplicitDependencies=[],this.changes=[],this.implicitChanges={},this.noCascade={},this.data=r,this.mappings=Eo(null);for(e in s)this.map(E(e),s[e]);if(r)for(e in r)(n=this.mappings[e])&&void 0===n.getValue()&&n.setValue(r[e]);for(e in o)s&&e in s&&l("Cannot map to a computed property ('%s')",e),this.compute(E(e),o[e]);this.ready=!0};ym.prototype={adapt:Gh,applyChanges:Hh,capture:Kh,clearCache:Qh,compute:Zh,get:em,init:am,map:rm,mark:om,merge:pm,register:cm,release:lm,reset:dm,set:fm,smartUpdate:hm,teardown:gm,unregister:bm};var xm=ym;Xr.prototype={constructor:Xr,begin:function(t){this.inProcess[t._guid]=!0},end:function(t){var e=t.parent;e&&this.inProcess[e._guid]?Zr(this.queue,e).push(t):ti(this,t),delete this.inProcess[t._guid]}};var _m=Xr,wm=ei,km=/\$\{([^\}]+)\}/g,Em=new is("construct"),Sm=new is("config"),Cm=new _m("init"),Pm=0,Am=["adaptors","components","decorators","easing","events","interpolators","partials","transitions"],Om=ii,Tm=ci;ci.prototype={bubble:function(){this.dirty||(this.dirty=!0,bs.addView(this))},update:function(){this.callback(this.fragment.getValue()),this.dirty=!1},rebind:function(t,e){this.fragment.rebind(t,e)},unbind:function(){this.fragment.unbind()}};var jm=function(t,e,n,r,o){var s,p,u,c,l,d,f={},h={},v={},g=[];for(p=t.parentFragment,u=t.root,o=o||{},a(f,o),o.content=r||[],f[""]=o.content,e.defaults.el&&m("The <%s/> component has a default `el` property; it has been disregarded",t.name),c=p;c;){if(c.owner.type===Ru){l=c.owner.container;break}c=c.parent}return n&&Object.keys(n).forEach(function(e){var a,r,o=n[e];if("string"==typeof o)a=dc(o),h[e]=a?a.value:o;else if(0===o)h[e]=!0;else{if(!i(o))throw Error("erm wut");di(o)?(v[e]={origin:t.root.viewmodel,keypath:void 0},r=li(t,o[0],function(t){t.isSpecial?d?s.set(e,t.value):(h[e]=t.value,delete v[e]):d?s.viewmodel.mappings[e].resolve(t):v[e].keypath=t})):r=new Tm(t,o,function(t){d?s.set(e,t):h[e]=t}),g.push(r)}}),s=Eo(e.prototype),Om(s,{el:null,append:!0,data:h,partials:o,magic:u.magic||e.defaults.magic,modifyArrays:u.modifyArrays,adapt:u.adapt},{parent:u,component:t,container:l,mappings:v,inlinePartials:f,cssIds:p.cssIds}),d=!0,t.resolvers=g,s},Rm=fi,Mm=function(t){var e,n;for(e=t.root;e;)(n=e._liveComponentQueries["_"+t.name])&&n.push(t.instance),e=e.parent},Lm=mi,Dm=vi,Nm=gi,Fm=bi,Im=yi,Bm=new is("teardown"),qm=_i,Um=function(t,e){this.init(t,e)};Um.prototype={detach:bh,find:xh,findAll:_h,findAllComponents:wh,findComponent:kh,findNextNode:Eh,firstNode:Sh,init:Lm,rebind:Dm,render:Nm,toString:Fm,unbind:Im,unrender:qm};var Gm=Um,Vm=function(t){this.type=Ou,this.value=t.template.c};Vm.prototype={detach:gc,firstNode:function(){return this.node},render:function(){return this.node||(this.node=document.createComment(this.value)),this.node},toString:function(){return""},unrender:function(t){t&&this.node.parentNode.removeChild(this.node)}};var zm=Vm,Wm=function(t){var e,n;this.type=Ru,this.container=e=t.parentFragment.root,this.component=n=e.component,this.container=e,this.containerFragment=t.parentFragment,this.parentFragment=n.parentFragment;var a=this.name=t.template.n||"",r=e._inlinePartials[a];r||(m('Could not find template for partial "'+a+'"',{ractive:t.root}),r=[]),this.fragment=new rv({owner:this,root:e.parent,template:r,pElement:this.containerFragment.pElement}),i(n.yielders[a])?n.yielders[a].push(this):n.yielders[a]=[this],bs.scheduleTask(function(){if(n.yielders[a].length>1)throw Error("A component template can only have one {{yield"+(a?" "+a:"")+"}} declaration at a time")})};Wm.prototype={detach:function(){return this.fragment.detach()},find:function(t){return this.fragment.find(t)},findAll:function(t,e){return this.fragment.findAll(t,e)},findComponent:function(t){return this.fragment.findComponent(t)},findAllComponents:function(t,e){return this.fragment.findAllComponents(t,e)},findNextNode:function(){return this.containerFragment.findNextNode(this)},firstNode:function(){return this.fragment.firstNode()},getValue:function(t){return this.fragment.getValue(t)},render:function(){return this.fragment.render()},unbind:function(){this.fragment.unbind()},unrender:function(t){this.fragment.unrender(t),N(this.component.yielders[this.name],this)},rebind:function(t,e){this.fragment.rebind(t,e)},toString:function(){return""+this.fragment}};var Hm=Wm,Km=function(t){this.declaration=t.template.a};Km.prototype={init:ko,render:ko,unrender:ko,teardown:ko,toString:function(){return""}};var Qm=Km,$m=wi,Ym=Ei,Jm=Si,Xm=Ci,Zm=Oi,tv=ji,ev=function(t){this.init(t)};ev.prototype={bubble:cu,detach:lu,find:du,findAll:fu,findAllComponents:hu,findComponent:mu,findNextNode:vu,firstNode:gu,getArgsList:hc,getNode:mc,getValue:vc,init:$m,rebind:Ym,registerIndexRef:function(t){var e=this.registeredIndexRefs;-1===e.indexOf(t)&&e.push(t)},render:Jm,toString:Xm,unbind:Zm,unregisterIndexRef:function(t){var e=this.registeredIndexRefs;e.splice(e.indexOf(t),1)},unrender:tv};var nv,av,rv=ev,iv=Ri,ov=["template","partials","components","decorators","events"],sv=new is("reset"),pv=function(t,e){function n(e,a,r){r&&r.partials[t]||e.forEach(function(e){e.type===Au&&e.getPartialName()===t&&a.push(e),e.fragment&&n(e.fragment.items,a,r),i(e.fragments)?n(e.fragments,a,r):i(e.items)?n(e.items,a,r):e.type===ju&&e.instance&&n(e.instance.fragment.items,a,e.instance),e.type===Pu&&(i(e.attributes)&&n(e.attributes,a,r),i(e.conditionalAttributes)&&n(e.conditionalAttributes,a,r))})}var a,r=[];return n(this.fragment.items,r),this.partials[t]=e,a=bs.start(this,!0),r.forEach(function(e){e.value=void 0,e.setValue(t)}),bs.end(),a},uv=Mi,cv=xp("reverse"),lv=Li,dv=xp("shift"),fv=xp("sort"),hv=xp("splice"),mv=Ni,vv=Fi,gv=new is("teardown"),bv=Bi,yv=qi,xv=Ui,_v=new is("unrender"),wv=xp("unshift"),kv=Gi,Ev=new is("update"),Sv=Vi,Cv={add:Zo,animate:Es,detach:Cs,find:As,findAll:Fs,findAllComponents:Is,findComponent:Bs,findContainer:qs,findParent:Us,fire:Ws,get:Hs,insert:Qs,merge:Ys,observe:lp,observeOnce:dp,off:mp,on:vp,once:gp,pop:_p,push:wp,render:Tp,reset:iv,resetPartial:pv,resetTemplate:uv,reverse:cv,set:lv,shift:dv,sort:fv,splice:hv,subtract:mv,teardown:vv,toggle:bv,toHTML:yv,toHtml:yv,unrender:xv,unshift:wv,update:kv,updateModel:Sv},Pv=function(t,e,n){return n||Wi(t,e)?function(){var n,a="_super"in this,r=this._super;return this._super=e,n=t.apply(this,arguments),a&&(this._super=r),n}:t},Av=Hi,Ov=Yi,Tv=function(t){var e,n,a={};return t&&(e=t._ractive)?(a.ractive=e.root,a.keypath=e.keypath.str,a.index={},(n=Oc(e.proxy.parentFragment))&&(a.index=Oc.resolve(n)),a):a};nv=function(t){return this instanceof nv?void Om(this,t):new nv(t)},av={DEBUG:{writable:!0,value:!0},DEBUG_PROMISES:{writable:!0,value:!0},extend:{value:Ov},getNodeInfo:{value:Tv},parse:{value:Hp},Promise:{value:us},svg:{value:ao},magic:{value:eo},VERSION:{value:"0.7.3"},adaptors:{writable:!0,value:{}},components:{writable:!0,value:{}},decorators:{writable:!0,value:{}},easing:{writable:!0,value:po},events:{writable:!0,value:{}},interpolators:{writable:!0,value:Go},partials:{writable:!0,value:{}},transitions:{writable:!0,value:{}}},Co(nv,av),nv.prototype=a(Cv,so),nv.prototype.constructor=nv,nv.defaults=nv.prototype;var jv="function";if(typeof Date.now!==jv||typeof String.prototype.trim!==jv||typeof Object.keys!==jv||typeof Array.prototype.indexOf!==jv||typeof Array.prototype.forEach!==jv||typeof Array.prototype.map!==jv||typeof Array.prototype.filter!==jv||"undefined"!=typeof window&&typeof window.addEventListener!==jv)throw Error("It looks like you're attempting to use Ractive.js in an older browser. You'll need to use one of the 'legacy builds' in order to continue - see http://docs.ractivejs.org/latest/legacy-builds for more information.");var Rv=nv;return Rv})},{}],206:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={oninit:function(){var t=this;this.observe("value",function(e,n,a){var r=t.get(),i=r.min,o=r.max,s=Math.clamp(i,o,e);t.animate("percentage",Math.round((s-i)/(o-i)*100))})}}}(r),r.exports.template={v:3,t:[" ",{p:[13,1,305],t:7,e:"div",a:{"class":"bar"},f:[{p:[14,3,326],t:7,e:"div",a:{"class":["barFill ",{t:2,r:"state",p:[14,23,346]}],style:["width: ",{t:2,r:"percentage",p:[14,48,371]},"%"]}}," ",{p:[15,3,398],t:7,e:"span",a:{"class":"barText"},f:[{t:16,p:[15,25,420]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],207:[function(t,e,n){var a=t(205),r={exports:{}};!function(e){"use strict";var n=t(325),a=t(324);e.exports={computed:{clickable:function(){return!this.get("enabled")||this.get("state")&&"toggle"!=this.get("state")?!1:!0},enabled:function(){return this.get("config.status")===n.UI_INTERACTIVE?!0:!1},styles:function(){var t="";if(this.get("class")&&(t+=" "+this.get("class")),this.get("tooltip-side")&&(t=" tooltip-"+this.get("tooltip-side")),this.get("grid")&&(t+=" gridable"),this.get("enabled")){var e=this.get("state"),n=this.get("style");return e?"inactive "+e+" "+t:"active normal "+n+" "+t}return"inactive disabled "+t}},oninit:function(){var t=this;this.on("press",function(e){var n=t.get(),r=n.action,i=n.params;(0,a.act)(t.get("config.ref"),r,i),e.node.blur()})},data:{iconStackToHTML:function(t){var e="",n=t.split(",");if(n.length){e+='';for(var a=n,r=Array.isArray(a),i=0,a=r?a:a[Symbol.iterator]();;){var o;if(r){if(i>=a.length)break;o=a[i++]}else{if(i=a.next(),i.done)break;o=i.value}var s=o,p=/([\w\-]+)\s*(\dx)/g,u=p.exec(s),c=u[1],l=u[2];e+=''}}return e&&(e+=""),e}}}}(r),r.exports.template={v:3,t:[" ",{p:[70,1,2019],t:7,e:"span",a:{"class":["button ",{t:2,r:"styles",p:[70,21,2039]}],unselectable:"on","data-tooltip":[{t:2,r:"tooltip",p:[73,17,2124]}]},m:[{t:4,f:["tabindex='0'"],r:"clickable",p:[72,3,2075]}],v:{"mouseover-mousemove":"hover",mouseleave:"unhover","click-enter":{n:[{t:4,f:["press"],r:"clickable",p:[76,19,2217]}],d:[]}},f:[{t:4,f:[{p:[78,5,2265],t:7,e:"i",a:{"class":["fa fa-",{t:2,r:"icon",p:[78,21,2281]}]}}],n:50,r:"icon",p:[77,3,2247]}," ",{t:4,f:[{t:3,x:{r:["iconStackToHTML","icon_stack"],s:"_0(_1)"},p:[81,6,2335]}],n:50,r:"icon_stack",p:[80,3,2310]}," ",{t:16,p:[83,3,2383]}]}]},e.exports=a.extend(r.exports)},{205:205,324:324,325:325}],208:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"div",a:{"class":"display"},f:[{t:4,f:[{p:[3,5,44],t:7,e:"header",f:[{p:[4,7,60],t:7,e:"h3",f:[{t:2,r:"title",p:[4,11,64]}]}," ",{t:4,f:[{p:[6,9,110],t:7,e:"div",a:{"class":"buttonRight"},f:[{t:16,n:"button",p:[6,34,135]}]}],n:50,r:"button",p:[5,7,86]}]}],n:50,r:"title",p:[2,3,25]}," ",{p:[10,3,202],t:7,e:"article",f:[{t:16,p:[11,5,217]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],209:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={oninit:function(){var t=this;this.on("clear",function(){t.set("value",""),t.find("input").focus()})}}}(r),r.exports.template={v:3,t:[" ",{p:[12,1,170],t:7,e:"input",a:{type:"text",value:[{t:2,r:"value",p:[12,27,196]}],placeholder:[{t:2,r:"placeholder",p:[12,51,220]}]}}," ",{p:[13,1,240],t:7,e:"ui-button",a:{icon:"refresh"},v:{press:"clear"}}]},e.exports=a.extend(r.exports)},{205:205}],210:[function(t,e,n){var a=t(205),r={exports:{}};!function(e){"use strict";e.exports={data:{graph:t(201),xaccessor:function(t){return t.x},yaccessor:function(t){return t.y}},computed:{size:function(){var t=this.get("points");return t[0].length},scale:function(){var t=this.get("points");return Math.max.apply(Math,Array.map(t,function(t){return Math.max.apply(Math,Array.map(t,function(t){return t.y}))}))},xaxis:function(){var t=this.get("xinc"),e=this.get("size");return Array.from(Array(e).keys()).filter(function(e){return e&&e%t==0})},yaxis:function(){var t=this.get("yinc"),e=this.get("scale");return Array.from(Array(t).keys()).map(function(t){return Math.round(e*(++t/100)*10)})}},oninit:function(){var t=this;this.on({enter:function(t){this.set("selected",t.index.count)},exit:function(t){this.set("selected")}}),window.addEventListener("resize",function(e){t.set("width",t.el.clientWidth)})},onrender:function(){this.set("width",this.el.clientWidth)}}}(r),r.exports.template={v:3,t:[" ",{p:[47,1,1269],t:7,e:"svg",a:{"class":"linegraph",width:"100%",height:[{t:2,x:{r:["height"],s:"_0+10"},p:[47,45,1313]}]},f:[{p:[48,3,1334],t:7,e:"g",a:{transform:"translate(0, 5)"},f:[{t:4,f:[{t:4,f:[{p:[51,9,1504],t:7,e:"line",a:{x1:[{t:2,x:{r:["xscale","."],s:"_0(_1)"},p:[51,19,1514]}],x2:[{t:2,x:{r:["xscale","."],s:"_0(_1)"},p:[51,38,1533]}],y1:"0",y2:[{t:2,r:"height",p:[51,64,1559]}],stroke:"darkgray"}}," ",{t:4,f:[{p:[53,11,1635],t:7,e:"text",a:{x:[{t:2,x:{r:["xscale","."],s:"_0(_1)"},p:[53,20,1644]}],y:[{t:2,x:{r:["height"],s:"_0-5"},p:[53,38,1662]}],"text-anchor":"middle",fill:"white"},f:[{t:2,x:{r:["size",".","xfactor"],s:"(_0-_1)*_2"},p:[53,88,1712]}," ",{t:2,r:"xunit",p:[53,113,1737]}]}],n:50,x:{r:["@index"],s:"_0%2==0"},p:[52,9,1600]}],n:52,r:"xaxis",p:[50,7,1479]}," ",{t:4,f:[{p:[57,9,1820],t:7,e:"line",a:{x1:"0",x2:[{t:2,r:"width",p:[57,26,1837]}],y1:[{t:2,x:{r:["yscale","."],s:"_0(_1)"},p:[57,41,1852]}],y2:[{t:2,x:{r:["yscale","."],s:"_0(_1)"},p:[57,60,1871]}],stroke:"darkgray"}}," ",{p:[58,9,1915],t:7,e:"text",a:{x:"0",y:[{t:2,x:{r:["yscale","."],s:"_0(_1)-5"},p:[58,24,1930]}],"text-anchor":"begin",fill:"white"},f:[{t:2,x:{r:[".","yfactor"],s:"_0*_1"},p:[58,76,1982]}," ",{t:2,r:"yunit",p:[58,92,1998]}]}],n:52,r:"yaxis",p:[56,7,1795]}," ",{t:4,f:[{p:[61,9,2071],t:7,e:"path",a:{d:[{t:2,x:{r:["area.path"],s:"_0.print()"},p:[61,18,2080]}],fill:[{t:2,rx:{r:"colors",m:[{t:30,n:"curve"}]},p:[61,47,2109]}],opacity:"0.1"}}],n:52,i:"curve",r:"curves",p:[60,7,2039]}," ",{t:4,f:[{p:[64,9,2200],t:7,e:"path",a:{d:[{t:2,x:{r:["line.path"],s:"_0.print()"},p:[64,18,2209]}],stroke:[{t:2,rx:{r:"colors",m:[{t:30,n:"curve"}]},p:[64,49,2240]}],fill:"none"}}],n:52,i:"curve",r:"curves",p:[63,7,2168]}," ",{t:4,f:[{t:4,f:[{p:[68,11,2375],t:7,e:"circle",a:{transform:["translate(",{t:2,r:".",p:[68,40,2404]},")"],r:[{t:2,x:{r:["selected","count"],s:"_0==_1?10:4"},p:[68,51,2415]}],fill:[{t:2,rx:{r:"colors",m:[{t:30,n:"curve"}]},p:[68,89,2453]}]},v:{mouseenter:"enter",mouseleave:"exit"}}],n:52,i:"count",x:{r:["line.path"],s:"_0.points()"},p:[67,9,2329]}],n:52,i:"curve",r:"curves",p:[66,7,2297]}," ",{t:4,f:[{t:4,f:[{t:4,f:[{p:[74,13,2678],t:7,e:"text",a:{transform:["translate(",{t:2,r:".",p:[74,40,2705]},") ",{t:2,x:{r:["count","size"],s:'_0<=_1/2?"translate(15, 4)":"translate(-15, 4)"'},p:[74,47,2712]}],"text-anchor":[{t:2,x:{r:["count","size"],s:'_0<=_1/2?"start":"end"'},p:[74,126,2791]}],fill:"white"},f:[{t:2,x:{r:["count","item","yfactor"],s:"_1[_0].y*_2"},p:[75,15,2861]}," ",{t:2,r:"yunit",p:[75,43,2889]}," @ ",{t:2,x:{r:["size","count","item","xfactor"],s:"(_0-_2[_1].x)*_3"},p:[75,55,2901]}," ",{t:2,r:"xunit",p:[75,92,2938]}]}],n:50,x:{r:["selected","count"],s:"_0==_1"},p:[73,11,2638]}],n:52,i:"count",x:{r:["line.path"],s:"_0.points()"},p:[72,9,2592]}],n:52,i:"curve",r:"curves",p:[71,7,2560]}," ",{t:4,f:[{p:[81,9,3063],t:7,e:"g",a:{transform:["translate(",{t:2,x:{r:["width","curves.length","@index"],s:"(_0/(_1+1))*(_2+1)"},p:[81,33,3087]},", 10)"]},f:[{p:[82,11,3154],t:7,e:"circle",a:{r:"4",fill:[{t:2,rx:{r:"colors",m:[{t:30,n:"curve"}]},p:[82,31,3174]}]}}," ",{p:[83,11,3206],t:7,e:"text",a:{x:"8",y:"4",fill:"white"},f:[{t:2,rx:{r:"legend",m:[{t:30,n:"curve"}]},p:[83,42,3237]}]}]}],n:52,i:"curve",r:"curves",p:[80,7,3031]}],x:{r:["graph","points","xaccessor","yaccessor","width","height"],s:"_0({data:_1,xaccessor:_2,yaccessor:_3,width:_4,height:_5})"},p:[49,5,1371]}]}]}]},e.exports=a.extend(r.exports)},{201:201,205:205}],211:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"div",a:{"class":"notice"},f:[{t:16,p:[2,3,24]}]}]},e.exports=a.extend(r.exports)},{205:205}],212:[function(t,e,n){var a=t(205),r={exports:{}};!function(e){"use strict";var n=t(324),a=t(326);e.exports={oninit:function(){var t=this,e=a.resize.bind(this),r=function(){return t.set({resize:!1,x:null,y:null})};this.observe("config.fancy",function(a,i,o){(0,n.winset)(t.get("config.window"),"can-resize",!a),a?(document.addEventListener("mousemove",e),document.addEventListener("mouseup",r)):(document.removeEventListener("mousemove",e),document.removeEventListener("mouseup",r))}),this.on("resize",function(){return t.toggle("resize")})}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[28,3,766],t:7,e:"div",a:{"class":"resize"},v:{mousedown:"resize"}}],n:50,r:"config.fancy",p:[27,1,742]}]},e.exports=a.extend(r.exports)},{205:205,324:324,326:326}],213:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"section",a:{"class":[{t:4,f:["candystripe"],r:"candystripe",p:[1,17,16]}]},f:[{t:4,f:[{p:[3,5,84],t:7,e:"span",a:{"class":"label",style:[{t:4,f:["color:",{t:2,r:"labelcolor",p:[3,53,132]}],r:"labelcolor",p:[3,32,111]}]},f:[{t:2,r:"label",p:[3,84,163]},":"]}],n:50,r:"label",p:[2,3,65]}," ",{t:4,f:[{t:16,p:[6,5,215]}],n:50,r:"nowrap",p:[5,3,195]},{t:4,n:51,f:[{p:[8,5,242],t:7,e:"div",a:{"class":"content",style:[{t:4,f:["float:right;"],r:"right",p:[8,33,270]}]},f:[{t:16,p:[9,7,312]}]}],r:"nowrap"}]}]},e.exports=a.extend(r.exports)},{205:205}],214:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"div",a:{"class":"subdisplay"},f:[{t:4,f:[{p:[3,5,47],t:7,e:"header",f:[{p:[4,7,63],t:7,e:"h4",f:[{t:2,r:"title",p:[4,11,67]}]}," ",{t:4,f:[{t:16,n:"button",p:[5,21,103]}],n:50,r:"button",p:[5,7,89]}]}],n:50,r:"title",p:[2,3,28]}," ",{p:[8,3,156],t:7,e:"article",f:[{t:16,p:[9,5,171]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],215:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={oninit:function(){var t=this;this.set("active",this.findComponent("tab").get("name")),this.on("switch",function(e){t.set("active",e.node.textContent.trim())}),this.observe("active",function(e,n,a){for(var r=t.findAllComponents("tab"),i=Array.isArray(r),o=0,r=i?r:r[Symbol.iterator]();;){var s;if(i){if(o>=r.length)break;s=r[o++]}else{if(o=r.next(),o.done)break;s=o.value}var p=s;p.set("shown",p.get("name")===e)}})}}}(r),r.exports.template={v:3,t:[" "," ",{p:[20,1,524],t:7,e:"header",f:[{t:4,f:[{p:[22,5,556],t:7,e:"ui-button",a:{pane:[{t:2,r:".",p:[22,22,573]}]},v:{press:"switch"},f:[{t:2,r:".",p:[22,47,598]}]}],n:52,r:"tabs",p:[21,3,536]}]}," ",{p:[25,1,641],t:7,e:"ui-display",f:[{t:8,r:"content",p:[26,3,657]}]}]},r.exports.components=r.exports.components||{};var i={tab:t(216)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,216:216}],216:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{t:16,p:[2,3,17]}],n:50,r:"shown",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{205:205}],217:[function(t,e,n){var a=t(205),r={exports:{}};!function(e){"use strict";var n=t(325),a=t(324),r=t(326);e.exports={computed:{visualStatus:function(){switch(this.get("config.status")){case n.UI_INTERACTIVE:return"good";case n.UI_UPDATE:return"average";case n.UI_DISABLED:return"bad";default:return"bad"}}},oninit:function(){var t=this,e=r.drag.bind(this),n=function(e){return t.set({drag:!1,x:null,y:null})};this.observe("config.fancy",function(r,i,o){(0,a.winset)(t.get("config.window"),"titlebar",!r&&t.get("config.titlebar")),r?(document.addEventListener("mousemove",e),document.addEventListener("mouseup",n)):(document.removeEventListener("mousemove",e),document.removeEventListener("mouseup",n))}),this.on({drag:function(){this.toggle("drag")},close:function(){(0,a.winset)(this.get("config.window"),"is-visible",!1),window.location.href=(0,a.href)({command:"uiclose "+this.get("config.ref")},"winset")},minimize:function(){(0,a.winset)(this.get("config.window"),"is-minimized",!0)}})}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[50,3,1440],t:7,e:"header",a:{"class":"titlebar"},v:{mousedown:"drag"},f:[{p:[51,5,1491],t:7,e:"i",a:{"class":["statusicon fa fa-eye fa-2x ",{t:2,r:"visualStatus",p:[51,42,1528]}]}}," ",{p:[52,5,1556],t:7,e:"span",a:{"class":"title"},f:[{t:16,p:[52,25,1576]}]}," ",{t:4,f:[{p:[54,7,1626],t:7,e:"i",a:{"class":"minimize fa fa-minus fa-2x"},v:{click:"minimize"}}," ",{p:[55,7,1696],t:7,e:"i",a:{"class":"close fa fa-close fa-2x"},v:{click:"close"}}],n:50,r:"config.fancy",p:[53,5,1598]}]}],n:50,r:"config.titlebar",p:[49,1,1413]}]},e.exports=a.extend(r.exports)},{205:205,324:324,325:325,326:326}],218:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";var e=[11,10,9,8];t.exports={data:{userAgent:navigator.userAgent},computed:{ie:function(){if(document.documentMode)return document.documentMode;for(var t in e){var n=document.createElement("div");if(n.innerHTML="",n.getElementsByTagName("span").length)return t}}},oninit:function(){var t=this;this.on("debug",function(){return t.toggle("debug")})}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[27,3,662],t:7,e:"ui-notice",f:[{p:[28,5,679],t:7,e:"span",f:["You have an old (IE",{t:2,r:"ie",p:[28,30,704]},"), end-of-life (click 'EOL Info' for more information) version of Internet Explorer installed."]},{p:[28,137,811],t:7,e:"br"}," ",{p:[29,5,822],t:7,e:"span",f:["To upgrade, click 'Upgrade IE' to download IE11 from Microsoft."]},{p:[29,81,898],t:7,e:"br"}," ",{p:[30,5,909],t:7,e:"span",f:["If you are unable to upgrade directly, click 'IE VMs' to download a VM with IE11 or Edge from Microsoft."]},{p:[30,122,1026],t:7,e:"br"}," ",{p:[31,5,1037],t:7,e:"span",f:["Otherwise, click 'No Frills' below to disable potentially incompatible features (and this message)."]}," ",{p:[32,5,1155],t:7,e:"hr"}," ",{p:[33,5,1166],t:7,e:"ui-button",a:{icon:"close",action:"tgui:nofrills"},f:["No Frills"]}," ",{p:[34,5,1240],t:7,e:"ui-button",a:{icon:"internet-explorer",action:"tgui:link",params:'{"url": "http://windows.microsoft.com/en-us/internet-explorer/download-ie"}'},f:["Upgrade IE"]}," ",{p:[36,5,1416],t:7,e:"ui-button",a:{icon:"edge",action:"tgui:link",params:'{"url": "https://dev.windows.com/en-us/microsoft-edge/tools/vms"}'},f:["IE VMs"]}," ",{p:[38,5,1565],t:7,e:"ui-button",a:{icon:"info",action:"tgui:link",params:'{"url": "https://support.microsoft.com/en-us/lifecycle#gp/Microsoft-Internet-Explorer"}'},f:["EOL Info"]}," ",{p:[40,5,1738],t:7,e:"ui-button",a:{icon:"bug"},v:{press:"debug"},f:["Debug Info"]}," ",{t:4,f:[{p:[42,7,1826],t:7,e:"hr"}," ",{p:[43,7,1839],t:7,e:"span",f:["Detected: IE",{t:2,r:"ie",p:[43,25,1857]}]},{p:[43,38,1870],t:7,e:"br"}," ",{p:[44,7,1883],t:7,e:"span",f:["User Agent: ",{t:2,r:"userAgent",p:[44,25,1901]}]}],n:50,r:"debug",p:[41,5,1805]}]}],n:50,x:{r:["config.fancy","ie"],s:"_0&&_1&&_1<11"},p:[26,1,621]}]},e.exports=a.extend(r.exports)},{205:205}],219:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{powerState:function(t){switch(t){case 2:return"good";case 1:return"average";default: -return"bad"}},shockState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[22,1,348],t:7,e:"ui-display",a:{title:"Power Status"},f:[{p:[23,2,384],t:7,e:"ui-section",a:{label:"Main"},f:[{p:[24,3,413],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.power.main"],s:"_0(_1)"},p:[24,16,426]}]},f:[{t:2,x:{r:["data.power.main"],s:'_0?"Online":"Offline"'},p:[24,49,459]}]}," ",{t:4,f:["[ ",{p:[26,6,567],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.main_1","data.wires.main_2"],s:"!_0||!_1"},p:[25,3,512]},{t:4,n:51,f:[{t:4,f:["[ ",{t:2,r:"data.power.main_timeleft",p:[29,7,674]}," seconds left ]"],n:50,x:{r:["data.power.main_timeleft"],s:"_0>0"},p:[28,4,630]}],x:{r:["data.wires.main_1","data.wires.main_2"],s:"!_0||!_1"}}," ",{p:[32,3,744],t:7,e:"div",a:{style:"float:right"},f:[{p:[33,4,774],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"disrupt-main",state:[{t:2,x:{r:["data.power.main"],s:'_0?null:"disabled"'},p:[33,63,833]}]},f:["Disrupt"]}]}]}," ",{p:[36,2,922],t:7,e:"ui-section",a:{label:"Backup"},f:[{p:[37,3,953],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.power.backup"],s:"_0(_1)"},p:[37,16,966]}]},f:[{t:2,x:{r:["data.power.backup"],s:'_0?"Online":"Offline"'},p:[37,51,1001]}]}," ",{t:4,f:["[ ",{p:[39,6,1115],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.backup_1","data.wires.backup_2"],s:"!_0||!_1"},p:[38,3,1056]},{t:4,n:51,f:[{t:4,f:["[ ",{t:2,r:"data.power.backup_timeleft",p:[42,7,1224]}," seconds left ]"],n:50,x:{r:["data.power.backup_timeleft"],s:"_0>0"},p:[41,4,1178]}],x:{r:["data.wires.backup_1","data.wires.backup_2"],s:"!_0||!_1"}}," ",{p:[45,3,1296],t:7,e:"div",a:{style:"float:right"},f:[{p:[46,4,1326],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"disrupt-backup",state:[{t:2,x:{r:["data.power.backup"],s:'_0?null:"disabled"'},p:[46,65,1387]}]},f:["Disrupt"]}]}]}," ",{p:[49,2,1478],t:7,e:"ui-section",a:{label:"Electrify"},f:[{p:[50,3,1512],t:7,e:"span",a:{"class":[{t:2,x:{r:["shockState","data.shock"],s:"_0(_1)"},p:[50,16,1525]}]},f:[{t:2,x:{r:["data.shock"],s:'_0==2?"Safe":"Electrified"'},p:[50,44,1553]}]}," ",{t:4,f:["[ ",{p:[52,6,1640],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.shock"],s:"!_0"},p:[51,3,1608]},{t:4,n:51,f:[{t:4,f:["[ ",{p:[55,7,1742],t:7,e:"span",a:{"class":"bad"},f:[{t:2,r:"data.shock_timeleft",p:[55,25,1760]}," seconds left"]}," ]"],n:50,x:{r:["data.shock_timeleft"],s:"_0>0"},p:[54,4,1703]}," ",{t:4,f:["[ ",{p:[58,7,1863],t:7,e:"span",a:{"class":"bad"},f:["Permanent"]}," ]"],n:50,x:{r:["data.shock_timeleft"],s:"_0==-1"},p:[57,4,1822]}],x:{r:["data.wires.shock"],s:"!_0"}}," ",{p:[61,3,1926],t:7,e:"div",a:{style:"float:right"},f:[{p:[62,4,1956],t:7,e:"ui-button",a:{icon:"wrench",action:"shock-restore",state:[{t:2,x:{r:["data.wires.shock","data.shock"],s:'_0&&_1==0?null:"disabled"'},p:[62,59,2011]}]},f:["Restore"]}," ",{p:[63,4,2094],t:7,e:"ui-button",a:{icon:"bolt",action:"shock-temp",state:[{t:2,x:{r:["data.wires.shock"],s:"!_0"},p:[63,54,2144]}]},f:["Set (Temporary)"]}," ",{p:[64,4,2199],t:7,e:"ui-button",a:{icon:"bolt",action:"shock-perm",state:[{t:2,x:{r:["data.wires.shock"],s:"!_0"},p:[64,53,2248]}]},f:["Set (Permanent)"]}]}]}]}," ",{p:[68,1,2341],t:7,e:"ui-display",a:{title:"Access & Door Control"},f:[{p:[69,2,2386],t:7,e:"ui-section",a:{label:"ID Scan"},f:[{t:4,f:["[ ",{p:[71,6,2455],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.id_scanner"],s:"!_0"},p:[70,3,2418]}," ",{p:[73,3,2516],t:7,e:"div",a:{style:"float:right"},f:[{p:[74,4,2546],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.id_scanner"],s:"!_0"},p:[74,22,2564]}],icon:"power-off",action:"idscan-on",style:[{t:2,x:{r:["data.id_scanner"],s:'_0?"selected":""'},p:[74,93,2635]}]},f:["Enabled"]}," ",{p:[75,4,2698],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.id_scanner"],s:"!_0"},p:[75,22,2716]}],icon:"close",action:"idscan-off",style:[{t:2,x:{r:["data.id_scanner"],s:'_0?"":"selected"'},p:[75,90,2784]}]},f:["Disabled"]}]}]}," ",{p:[78,2,2872],t:7,e:"ui-section",a:{label:"Emergency Access"},f:[{p:[79,3,2913],t:7,e:"div",a:{style:"float:right"},f:[{p:[80,4,2943],t:7,e:"ui-button",a:{icon:"power-off",action:"emergency-on",style:[{t:2,x:{r:["data.emergency"],s:'_0?"selected":""'},p:[80,61,3e3]}]},f:["Enabled"]}," ",{p:[81,4,3062],t:7,e:"ui-button",a:{icon:"close",action:"emergency-off",style:[{t:2,x:{r:["data.emergency"],s:'_0?"":"selected"'},p:[81,58,3116]}]},f:["Disabled"]}]}]}," ",{p:[84,2,3203],t:7,e:"br"}," ",{p:[85,2,3212],t:7,e:"ui-section",a:{label:"Door bolts"},f:[{t:4,f:["[ ",{p:[87,6,3279],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.bolts"],s:"!_0"},p:[86,3,3247]}," ",{p:[89,3,3340],t:7,e:"div",a:{style:"float:right"},f:[{p:[90,4,3370],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.bolts"],s:"!_0"},p:[90,22,3388]}],icon:"unlock",action:"bolt-raise",style:[{t:2,x:{r:["data.locked"],s:'_0?"":"selected"'},p:[90,85,3451]}]},f:["Raised"]}," ",{p:[91,4,3509],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.bolts"],s:"!_0"},p:[91,22,3527]}],icon:"lock",action:"bolt-drop",style:[{t:2,x:{r:["data.locked"],s:'_0?"selected":""'},p:[91,82,3587]}]},f:["Dropped"]}]}]}," ",{p:[94,2,3670],t:7,e:"ui-section",a:{label:"Door bolt lights"},f:[{t:4,f:["[ ",{p:[96,6,3744],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.lights"],s:"!_0"},p:[95,3,3711]}," ",{p:[98,3,3805],t:7,e:"div",a:{style:"float:right"},f:[{p:[99,4,3835],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.lights"],s:"!_0"},p:[99,22,3853]}],icon:"power-off",action:"light-on",style:[{t:2,x:{r:["data.lights"],s:'_0?"selected":""'},p:[99,88,3919]}]},f:["Enabled"]}," ",{p:[100,4,3978],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.lights"],s:"!_0"},p:[100,22,3996]}],icon:"close",action:"light-off",style:[{t:2,x:{r:["data.lights"],s:'_0?"":"selected"'},p:[100,85,4059]}]},f:["Disabled"]}]}]}," ",{p:[103,2,4143],t:7,e:"ui-section",a:{label:"Door force sensors"},f:[{t:4,f:["[ ",{p:[105,6,4217],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.safe"],s:"!_0"},p:[104,3,4186]}," ",{p:[107,3,4278],t:7,e:"div",a:{style:"float:right"},f:[{p:[108,4,4308],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.safe"],s:"!_0"},p:[108,22,4326]}],icon:"power-off",action:"safe-on",style:[{t:2,x:{r:["data.safe"],s:'_0?"selected":""'},p:[108,85,4389]}]},f:["Enabled"]}," ",{p:[109,4,4446],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.safe"],s:"!_0"},p:[109,22,4464]}],icon:"close",action:"safe-off",style:[{t:2,x:{r:["data.safe"],s:'_0?"":"selected"'},p:[109,82,4524]}]},f:["Disabled"]}]}]}," ",{p:[112,2,4606],t:7,e:"ui-section",a:{label:"Door timing saftey"},f:[{t:4,f:["[ ",{p:[114,6,4682],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.timing"],s:"!_0"},p:[113,3,4649]}," ",{p:[116,3,4743],t:7,e:"div",a:{style:"float:right"},f:[{p:[117,4,4773],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.timing"],s:"!_0"},p:[117,22,4791]}],icon:"power-off",action:"speed-on",style:[{t:2,x:{r:["data.speed"],s:'_0?"selected":""'},p:[117,88,4857]}]},f:["Enabled"]}," ",{p:[118,4,4915],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.timing"],s:"!_0"},p:[118,22,4933]}],icon:"close",action:"speed-off",style:[{t:2,x:{r:["data.speed"],s:'_0?"":"selected"'},p:[118,85,4996]}]},f:["Disabled"]}]}]}," ",{p:[121,2,5079],t:7,e:"br"}," ",{p:[122,2,5088],t:7,e:"ui-section",a:{label:"Door control"},f:[{t:4,f:["[ ",{p:[124,6,5166],t:7,e:"span",a:{"class":"bad"},f:["Door is ",{t:2,x:{r:["data.locked","data.welded"],s:'(_0?"bolted":"")+(_0&&_1?" and ":"")+(_1?"welded":"")'},p:[124,32,5192]}]}," ]"],n:50,x:{r:["data.locked","data.welded"],s:"_0||_1"},p:[123,3,5125]}," ",{p:[126,3,5327],t:7,e:"div",a:{style:"float:right"},f:[{p:[127,4,5357],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.locked","data.welded","data.opened"],s:'(_0||_1)||(_2&&"disabled")'},p:[127,22,5375]}],icon:"sign-out",action:"open-close"},f:["Open door"]}," ",{p:[128,4,5502],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.locked","data.welded","data.opened"],s:'(_0||_1)||(!_2&&"disabled")'},p:[128,22,5520]}],icon:"sign-in",action:"open-close"},f:["Close door"]}]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],220:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" "," "," "," "," ",{p:[7,1,267],t:7,e:"ui-notice",f:[{t:4,f:[{p:[9,5,312],t:7,e:"ui-section",a:{label:"Interface Lock"},f:[{p:[10,7,355],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"lock":"unlock"'},p:[10,24,372]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Engaged":"Disengaged"'},p:[10,75,423]}]}]}],n:50,r:"data.siliconUser",p:[8,3,282]},{t:4,n:51,f:[{p:[13,5,514],t:7,e:"span",f:["Swipe an ID card to ",{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[13,31,540]}," this interface."]}],r:"data.siliconUser"}]}," ",{p:[16,1,625],t:7,e:"status"}," ",{t:4,f:[{t:4,f:[{p:[19,7,719],t:7,e:"ui-display",a:{title:"Air Controls"},f:[{p:[20,9,762],t:7,e:"ui-section",f:[{p:[21,11,786],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.atmos_alarm"],s:'_0?"exclamation-triangle":"exclamation"'},p:[21,28,803]}],style:[{t:2,x:{r:["data.atmos_alarm"],s:'_0?"caution":null'},p:[21,98,873]}],action:[{t:2,x:{r:["data.atmos_alarm"],s:'_0?"reset":"alarm"'},p:[22,23,937]}]},f:["Area Atmosphere Alarm"]}]}," ",{p:[24,9,1045],t:7,e:"ui-section",f:[{p:[25,11,1069],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0==3?"exclamation-triangle":"exclamation"'},p:[25,28,1086]}],style:[{t:2,x:{r:["data.mode"],s:'_0==3?"danger":null'},p:[25,96,1154]}],action:"mode",params:['{"mode": ',{t:2,x:{r:["data.mode"],s:"_0==3?1:3"},p:[26,44,1236]},"}"]},f:["Panic Siphon"]}]}," ",{p:[28,9,1322],t:7,e:"br"}," ",{p:[29,9,1337],t:7,e:"ui-section",f:[{p:[30,11,1361],t:7,e:"ui-button",a:{icon:"sign-out",action:"tgui:view",params:'{"screen": "vents"}'},f:["Vent Controls"]}]}," ",{p:[32,9,1494],t:7,e:"ui-section",f:[{p:[33,11,1518],t:7,e:"ui-button",a:{icon:"filter",action:"tgui:view",params:'{"screen": "scrubbers"}'},f:["Scrubber Controls"]}]}," ",{p:[35,9,1657],t:7,e:"ui-section",f:[{p:[36,11,1681],t:7,e:"ui-button",a:{icon:"cog",action:"tgui:view",params:'{"screen": "modes"}'},f:["Operating Mode"]}]}," ",{p:[38,9,1810],t:7,e:"ui-section",f:[{p:[39,11,1834],t:7,e:"ui-button",a:{icon:"bar-chart",action:"tgui:view",params:'{"screen": "thresholds"}'},f:["Alarm Thresholds"]}]}]}],n:50,x:{r:["config.screen"],s:'_0=="home"'},p:[18,3,680]},{t:4,n:51,f:[{t:4,n:50,x:{r:["config.screen"],s:'_0=="vents"'},f:[{p:[43,5,2032],t:7,e:"vents"}]},{t:4,n:50,x:{r:["config.screen"],s:'(!(_0=="vents"))&&(_0=="scrubbers")'},f:[" ",{p:[45,5,2089],t:7,e:"scrubbers"}]},{t:4,n:50,x:{r:["config.screen"],s:'(!(_0=="vents"))&&((!(_0=="scrubbers"))&&(_0=="modes"))'},f:[" ",{p:[47,5,2146],t:7,e:"modes"}]},{t:4,n:50,x:{r:["config.screen"],s:'(!(_0=="vents"))&&((!(_0=="scrubbers"))&&((!(_0=="modes"))&&(_0=="thresholds")))'},f:[" ",{p:[49,5,2204],t:7,e:"thresholds"}]}],x:{r:["config.screen"],s:'_0=="home"'}}],n:50,x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"},p:[17,1,636]}]},r.exports.components=r.exports.components||{};var i={vents:t(226),modes:t(222),thresholds:t(225),status:t(224),scrubbers:t(223)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,222:222,223:223,224:224,225:225,226:226}],221:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-button",a:{icon:"arrow-left",action:"tgui:view",params:'{"screen": "home"}'},f:["Back"]}]},e.exports=a.extend(r.exports)},{205:205}],222:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:{button:[{p:[5,5,115],t:7,e:"back"}]},t:7,e:"ui-display",a:{title:"Operating Modes",button:0},f:[" ",{t:4,f:[{p:[8,5,168],t:7,e:"ui-section",f:[{p:[9,7,188],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["selected"],s:'_0?"check-square-o":"square-o"'},p:[9,24,205]}],state:[{t:2,x:{r:["selected","danger"],s:'_0?_1?"danger":"selected":null'},p:[10,16,267]}],action:"mode",params:['{"mode": ',{t:2,r:"mode",p:[11,40,361]},"}"]},f:[{t:2,r:"name",p:[11,51,372]}]}]}],n:52,r:"data.modes",p:[7,3,142]}]}]},r.exports.components=r.exports.components||{};var i={back:t(221)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,221:221}],223:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" "," ",{p:{button:[{p:[6,5,185],t:7,e:"back"}]},t:7,e:"ui-display",a:{title:"Scrubber Controls",button:0},f:[" ",{t:4,f:[{p:[9,5,242],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"long_name",p:[9,27,264]}]},f:[{p:[10,7,287],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[11,9,323],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["power"],s:'_0?"power-off":"close"'},p:[11,26,340]}],style:[{t:2,x:{r:["power"],s:'_0?"selected":null'},p:[11,68,382]}],action:"power",params:['{"id_tag": "',{t:2,r:"id_tag",p:[12,46,459]},'", "val": ',{t:2,x:{r:["power"],s:"+!_0"},p:[12,66,479]},"}"]},f:[{t:2,x:{r:["power"],s:'_0?"On":"Off"'},p:[12,80,493]}]}]}," ",{p:[14,7,558],t:7,e:"ui-section",a:{label:"Mode"},f:[{p:[15,9,593],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["scrubbing"],s:'_0?"filter":"sign-in"'},p:[15,26,610]}],style:[{t:2,x:{r:["scrubbing"],s:'_0?null:"danger"'},p:[15,71,655]}],action:"scrubbing",params:['{"id_tag": "',{t:2,r:"id_tag",p:[16,50,738]},'", "val": ',{t:2,x:{r:["scrubbing"],s:"+!_0"},p:[16,70,758]},"}"]},f:[{t:2,x:{r:["scrubbing"],s:'_0?"Scrubbing":"Siphoning"'},p:[16,88,776]}]}]}," ",{p:[18,7,858],t:7,e:"ui-section",a:{label:"Range"},f:[{p:[19,9,894],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["widenet"],s:'_0?"expand":"compress"'},p:[19,26,911]}],style:[{t:2,x:{r:["widenet"],s:'_0?"selected":null'},p:[19,70,955]}],action:"widenet",params:['{"id_tag": "',{t:2,r:"id_tag",p:[20,48,1036]},'", "val": ',{t:2,x:{r:["widenet"],s:"+!_0"},p:[20,68,1056]},"}"]},f:[{t:2,x:{r:["widenet"],s:'_0?"Expanded":"Normal"'},p:[20,84,1072]}]}]}," ",{p:[22,7,1148],t:7,e:"ui-section",a:{label:"Filters"},f:[{p:[23,9,1186],t:7,e:"filters"}]}]}],n:52,r:"data.scrubbers",p:[8,3,212]},{t:4,n:51,f:[{p:[27,5,1257],t:7,e:"span",a:{"class":"bad"},f:["Error: No scrubbers connected."]}],r:"data.scrubbers"}]}]},r.exports.components=r.exports.components||{};var i={filters:t(299),back:t(221)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,221:221,299:299}],224:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Air Status"},f:[{t:4,f:[{t:4,f:[{p:[4,7,110],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[4,26,129]}]},f:[{p:[5,6,146],t:7,e:"span",a:{"class":[{t:2,x:{r:["danger_level"],s:'_0==2?"bad":_0==1?"average":"good"'},p:[5,19,159]}]},f:[{t:2,x:{r:["value"],s:"Math.fixed(_0,2)"},p:[6,5,237]},{t:2,r:"unit",p:[6,29,261]}]}]}],n:52,r:"adata.environment_data",p:[3,5,70]}," ",{p:[10,5,322],t:7,e:"ui-section",a:{label:"Local Status"},f:[{p:[11,7,363],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.danger_level"],s:'_0==2?"bad bold":_0==1?"average bold":"good"'},p:[11,20,376]}]},f:[{t:2,x:{r:["data.danger_level"],s:'_0==2?"Danger (Internals Required)":_0==1?"Caution":"Optimal"'},p:[12,6,475]}]}]}," ",{p:[15,5,619],t:7,e:"ui-section",a:{label:"Area Status"},f:[{p:[16,7,659],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.atmos_alarm","data.fire_alarm"],s:'_0||_1?"bad bold":"good"'},p:[16,20,672]}]},f:[{t:2,x:{r:["data.atmos_alarm","fire_alarm"],s:'_0?"Atmosphere Alarm":_1?"Fire Alarm":"Nominal"'},p:[17,8,744]}]}]}],n:50,r:"data.environment_data",p:[2,3,35]},{t:4,n:51,f:[{p:[21,5,876],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[22,7,912],t:7,e:"span",a:{"class":"bad bold"},f:["Cannot obtain air sample for analysis."]}]}],r:"data.environment_data"}," ",{t:4,f:[{p:[26,5,1040],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[27,7,1076],t:7,e:"span",a:{"class":"bad bold"},f:["Safety measures offline. Device may exhibit abnormal behavior."]}]}],n:50,r:"data.emagged",p:[25,3,1014]}]}]},e.exports=a.extend(r.exports)},{205:205}],225:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.css=" th, td {\r\n padding-right: 16px;\r\n text-align: left;\r\n }",r.exports.template={v:3,t:[" ",{p:{button:[{p:[5,5,116],t:7,e:"back"}]},t:7,e:"ui-display",a:{title:"Alarm Thresholds",button:0},f:[" ",{p:[7,3,143],t:7,e:"table",f:[{p:[8,5,156],t:7,e:"thead",f:[{p:[8,12,163],t:7,e:"tr",f:[{p:[9,7,175],t:7,e:"th"}," ",{p:[10,7,192],t:7,e:"th",f:[{p:[10,11,196],t:7,e:"span",a:{"class":"bad"},f:["min2"]}]}," ",{p:[11,7,238],t:7,e:"th",f:[{p:[11,11,242],t:7,e:"span",a:{"class":"average"},f:["min1"]}]}," ",{p:[12,7,288],t:7,e:"th",f:[{p:[12,11,292],t:7,e:"span",a:{"class":"average"},f:["max1"]}]}," ",{p:[13,7,338],t:7,e:"th",f:[{p:[13,11,342],t:7,e:"span",a:{"class":"bad"},f:["max2"]}]}]}]}," ",{p:[15,5,401],t:7,e:"tbody",f:[{t:4,f:[{p:[16,32,441],t:7,e:"tr",f:[{p:[17,9,455],t:7,e:"th",f:[{t:3,r:"name",p:[17,13,459]}]}," ",{t:4,f:[{p:[18,27,502],t:7,e:"td",f:[{p:[19,11,518],t:7,e:"ui-button",a:{action:"threshold",params:['{"env": "',{t:2,r:"env",p:[19,58,565]},'", "var": "',{t:2,r:"val",p:[19,76,583]},'"}']},f:[{t:2,x:{r:["selected"],s:"Math.fixed(_0,2)"},p:[19,87,594]}]}]}],n:52,r:"settings",p:[18,9,484]}]}],n:52,r:"data.thresholds",p:[16,7,416]}]}," ",{p:[23,3,697],t:7,e:"table",f:[]}]}]}," "]},r.exports.components=r.exports.components||{};var i={back:t(221)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,221:221}],226:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:{button:[{p:[5,5,113],t:7,e:"back"}]},t:7,e:"ui-display",a:{title:"Vent Controls",button:0},f:[" ",{t:4,f:[{p:[8,5,166],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"long_name",p:[8,27,188]}]},f:[{p:[9,7,211],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[10,9,247],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["power"],s:'_0?"power-off":"close"'},p:[10,26,264]}],style:[{t:2,x:{r:["power"],s:'_0?"selected":null'},p:[10,68,306]}],action:"power",params:['{"id_tag": "',{t:2,r:"id_tag",p:[11,46,383]},'", "val": ',{t:2,x:{r:["power"],s:"+!_0"},p:[11,66,403]},"}"]},f:[{t:2,x:{r:["power"],s:'_0?"On":"Off"'},p:[11,80,417]}]}]}," ",{p:[13,7,482],t:7,e:"ui-section",a:{label:"Mode"},f:[{p:[14,9,517],t:7,e:"span",f:[{t:2,x:{r:["direction"],s:'_0=="release"?"Pressurizing":"Siphoning"'},p:[14,15,523]}]}]}," ",{p:[16,7,616],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[17,9,665],t:7,e:"ui-button",a:{icon:"sign-in",style:[{t:2,x:{r:["incheck"],s:'_0?"selected":null'},p:[17,42,698]}],action:"incheck",params:['{"id_tag": "',{t:2,r:"id_tag",p:[18,48,779]},'", "val": ',{t:2,r:"checks",p:[18,68,799]},"}"]},f:["Internal"]}," ",{p:[19,9,842],t:7,e:"ui-button",a:{icon:"sign-out",style:[{t:2,x:{r:["excheck"],s:'_0?"selected":null'},p:[19,43,876]}],action:"excheck",params:['{"id_tag": "',{t:2,r:"id_tag",p:[20,48,957]},'", "val": ',{t:2,r:"checks",p:[20,68,977]},"}"]},f:["External"]}]}," ",{t:4,f:[{p:[23,9,1064],t:7,e:"ui-section",a:{label:"Internal Target Pressure"},f:[{p:[24,11,1121],t:7,e:"ui-button",a:{icon:"pencil",action:"set_internal_pressure",params:['{"id_tag": "',{t:2,r:"id_tag",p:[25,33,1210]},'"}']},f:[{t:2,x:{r:["internal"],s:"Math.fixed(_0)"},p:[25,47,1224]}]}," ",{p:[26,11,1272],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["intdefault"],s:'_0?"disabled":null'},p:[26,44,1305]}],action:"reset_internal_pressure",params:['{"id_tag": "',{t:2,r:"id_tag",p:[27,33,1407]},'"}']},f:["Reset"]}]}],n:50,r:"incheck",p:[22,7,1039]}," ",{t:4,f:[{p:[31,11,1511],t:7,e:"ui-section",a:{label:"External Target Pressure"},f:[{p:[32,13,1570],t:7,e:"ui-button",a:{icon:"pencil",action:"set_external_pressure",params:['{"id_tag": "',{t:2,r:"id_tag",p:[33,35,1661]},'"}']},f:[{t:2,x:{r:["external"],s:"Math.fixed(_0)"},p:[33,49,1675]}]}," ",{p:[34,13,1725],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["extdefault"],s:'_0?"disabled":null'},p:[34,46,1758]}],action:"reset_external_pressure",params:['{"id_tag": "',{t:2,r:"id_tag",p:[35,35,1862]},'"}']},f:["Reset"]}]}],n:50,r:"excheck",p:[30,7,1484]}]}],n:52,r:"data.vents",p:[7,3,140]},{t:4,n:51,f:[{p:[40,5,1973],t:7,e:"span",a:{"class":"bad"},f:["Error: No vents connected."]}],r:"data.vents"}]}]},r.exports.components=r.exports.components||{};var i={back:t(221)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,221:221}],227:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.css=" table {\r\n width: 100%;\r\n border-spacing: 2px;\r\n }\r\n th {\r\n text-align: left;\r\n }\r\n td {\r\n vertical-align: top;\r\n }\r\n td .button {\r\n margin-top: 4px\r\n }",r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-section",f:[{p:[3,5,34],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.oneAccess"],s:'_0?"unlock":"lock"'},p:[3,22,51]}],action:"one_access"},f:[{t:2,x:{r:["data.oneAccess"],s:'_0?"One":"All"'},p:[3,82,111]}," Required"]}," ",{p:[4,5,172],t:7,e:"ui-button",a:{icon:"refresh",action:"clear"},f:["Clear"]}]}," ",{p:[6,3,251],t:7,e:"hr"}," ",{p:[7,3,260],t:7,e:"table",f:[{p:[8,3,271],t:7,e:"thead",f:[{p:[9,4,283],t:7,e:"tr",f:[{t:4,f:[{p:[10,5,315],t:7,e:"th",f:[{p:[10,9,319],t:7,e:"span",a:{"class":"highlight bold"},f:[{t:2,r:"name",p:[10,38,348]}]}]}],n:52,r:"data.regions",p:[9,8,287]}]}]}," ",{p:[13,3,403],t:7,e:"tbody",f:[{p:[14,4,415],t:7,e:"tr",f:[{t:4,f:[{p:[15,5,447],t:7,e:"td",f:[{t:4,f:[{p:[16,11,481],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["req"],s:'_0?"check-square-o":"square-o"'},p:[16,28,498]}],style:[{t:2,x:{r:["req"],s:'_0?"selected":null'},p:[16,76,546]}],action:"set",params:['{"access": "',{t:2,r:"id",p:[17,46,621]},'"}']},f:[{t:2,r:"name",p:[17,56,631]}]}," ",{p:[18,9,661],t:7,e:"br"}],n:52,r:"accesses",p:[15,9,451]}]}],n:52,r:"data.regions",p:[14,8,419]}]}]}]}]}," "]},e.exports=a.extend(r.exports)},{205:205}],228:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{powerState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}}},computed:{malfAction:function(){switch(this.get("data.malfStatus")){case 1:return"hack";case 2:return"occupy";case 3:return"deoccupy"}},malfButton:function(){switch(this.get("data.malfStatus")){case 1:return"Override Programming";case 2:case 4:return"Shunt Core Process";case 3:return"Return to Main Core"}},malfIcon:function(){switch(this.get("data.malfStatus")){case 1:return"terminal";case 2:case 4:return"caret-square-o-down";case 3:return"caret-square-o-left"}},powerCellStatusState:function(){var t=this.get("data.powerCellStatus");return t>50?"good":t>25?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[46,2,1206],t:7,e:"ui-notice",f:[{p:[47,3,1221],t:7,e:"b",f:[{p:[47,6,1224],t:7,e:"h3",f:["SYSTEM FAILURE"]}]}," ",{p:[48,3,1255],t:7,e:"i",f:["I/O regulators malfunction detected! Waiting for system reboot..."]},{p:[48,75,1327],t:7,e:"br"}," Automatic reboot in ",{t:2,r:"data.failTime",p:[49,23,1355]}," seconds... ",{p:[50,3,1387],t:7,e:"ui-button",a:{icon:"refresh",action:"reboot"},f:["Reboot Now"]},{p:[50,67,1451],t:7,e:"br"},{p:[50,71,1455],t:7,e:"br"},{p:[50,75,1459],t:7,e:"br"}]}],n:50,r:"data.failTime",p:[45,1,1182]},{t:4,n:51,f:[{p:[53,2,1491],t:7,e:"ui-notice",f:[{t:4,f:[{p:[55,3,1535],t:7,e:"ui-section",a:{label:"Interface Lock"},f:[{p:[56,5,1576],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"lock":"unlock"'},p:[56,22,1593]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Engaged":"Disengaged"'},p:[56,73,1644]}]}]}],n:50,r:"data.siliconUser",p:[54,4,1507]},{t:4,n:51,f:[{p:[59,3,1732],t:7,e:"span",f:["Swipe an ID card to ",{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[59,29,1758]}," this interface."]}],r:"data.siliconUser"}]}," ",{p:[62,2,1846],t:7,e:"ui-display",a:{title:"Power Status"},f:[{p:[63,4,1884],t:7,e:"ui-section",a:{label:"Main Breaker"},f:[{t:4,f:[{p:[65,5,1967],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.isOperating"],s:'_0?"good":"bad"'},p:[65,18,1980]}]},f:[{t:2,x:{r:["data.isOperating"],s:'_0?"On":"Off"'},p:[65,57,2019]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"},p:[64,3,1921]},{t:4,n:51,f:[{p:[67,5,2079],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isOperating"],s:'_0?"power-off":"close"'},p:[67,22,2096]}],style:[{t:2,x:{r:["data.isOperating"],s:'_0?"selected":null'},p:[67,75,2149]}],action:"breaker"},f:[{t:2,x:{r:["data.isOperating"],s:'_0?"On":"Off"'},p:[68,21,2212]}]}],x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"}}]}," ",{p:[71,4,2293],t:7,e:"ui-section",a:{label:"External Power"},f:[{p:[72,3,2332],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.externalPower"],s:"_0(_1)"},p:[72,16,2345]}]},f:[{t:2,x:{r:["data.externalPower"],s:'_0==2?"Good":_0==1?"Low":"None"'},p:[72,52,2381]}]}]}," ",{p:[74,4,2490],t:7,e:"ui-section",a:{label:"Power Cell"},f:[{t:4,f:[{p:[76,5,2567],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.powerCellStatus",p:[76,38,2600]}],state:[{t:2,r:"powerCellStatusState",p:[76,71,2633]}]},f:[{t:2,x:{r:["adata.powerCellStatus"],s:"Math.fixed(_0)"},p:[76,97,2659]},"%"]}],n:50,x:{r:["data.powerCellStatus"],s:"_0!=null"},p:[75,3,2525]},{t:4,n:51,f:[{p:[78,5,2724],t:7,e:"span",a:{"class":"bad"},f:["Removed"]}],x:{r:["data.powerCellStatus"],s:"_0!=null"}}]}," ",{t:4,f:[{p:[82,3,2830],t:7,e:"ui-section",a:{label:"Charge Mode"},f:[{t:4,f:[{p:[84,4,2913],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.chargeMode"],s:'_0?"good":"bad"'},p:[84,17,2926]}]},f:[{t:2,x:{r:["data.chargeMode"],s:'_0?"Auto":"Off"'},p:[84,55,2964]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"},p:[83,5,2868]},{t:4,n:51,f:[{p:[86,4,3026],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.chargeMode"],s:'_0?"refresh":"close"'},p:[86,21,3043]}],style:[{t:2,x:{r:["data.chargeMode"],s:'_0?"selected":null'},p:[86,71,3093]}],action:"charge"},f:[{t:2,x:{r:["data.chargeMode"],s:'_0?"Auto":"Off"'},p:[87,22,3156]}]}],x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"}}," [",{p:[90,6,3236],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.chargingStatus"],s:"_0(_1)"},p:[90,19,3249]}]},f:[{t:2,x:{r:["data.chargingStatus"],s:'_0==2?"Fully Charged":_0==1?"Charging":"Not Charging"'},p:[90,56,3286]}]},"]"]}],n:50,x:{r:["data.powerCellStatus"],s:"_0!=null"},p:[81,4,2790]}]}," ",{p:[94,2,3445],t:7,e:"ui-display",a:{title:"Power Channels"},f:[{t:4,f:[{p:[96,3,3517],t:7,e:"ui-section",a:{label:[{t:2,r:"title",p:[96,22,3536]}],nowrap:0},f:[{p:[97,5,3560],t:7,e:"div",a:{"class":"content"},f:[{t:2,rx:{r:"adata.powerChannels",m:[{t:30,n:"@index"},"powerLoad"]},p:[97,26,3581]}]}," ",{p:[98,5,3634],t:7,e:"div",a:{"class":"content"},f:[{p:[98,26,3655],t:7,e:"span",a:{"class":[{t:2,x:{r:["status"],s:'_0>=2?"good":"bad"'},p:[98,39,3668]}]},f:[{t:2,x:{r:["status"],s:'_0>=2?"On":"Off"'},p:[98,73,3702]}]}]}," ",{p:[99,5,3751],t:7,e:"div",a:{"class":"content"},f:["[",{p:[99,27,3773],t:7,e:"span",f:[{t:2,x:{r:["status"],s:'_0==1||_0==3?"Auto":"Manual"'},p:[99,33,3779]}]},"]"]}," ",{p:[100,5,3849],t:7,e:"div",a:{"class":"content",style:"float:right"},f:[{t:4,f:[{p:[102,6,3942],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["status"],s:'_0==1||_0==3?"selected":null'},p:[102,39,3975]}],action:"channel",params:[{t:2,r:"topicParams.auto",p:[103,30,4057]}]},f:["Auto"]}," ",{p:[104,6,4102],t:7,e:"ui-button",a:{icon:"power-off",state:[{t:2,x:{r:["status"],s:'_0==2?"selected":null'},p:[104,41,4137]}],action:"channel",params:[{t:2,r:"topicParams.on",p:[105,13,4204]}]},f:["On"]}," ",{p:[106,6,4245],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["status"],s:'_0==0?"selected":null'},p:[106,37,4276]}],action:"channel",params:[{t:2,r:"topicParams.off",p:[107,13,4343]}]},f:["Off"]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"},p:[101,4,3895]}]}]}],n:52,r:"data.powerChannels",p:[95,4,3485]}," ",{p:[112,4,4439],t:7,e:"ui-section",a:{label:"Total Load"},f:[{p:[113,3,4474],t:7,e:"span",a:{"class":"bold"},f:[{t:2,r:"adata.totalLoad",p:[113,22,4493]}]}]}]}," ",{t:4,f:[{p:[117,4,4585],t:7,e:"ui-display",a:{title:"System Overrides"},f:[{p:[118,3,4626],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"overload"},f:["Overload"]}," ",{t:4,f:[{p:[120,5,4727],t:7,e:"ui-button",a:{icon:[{t:2,r:"malfIcon",p:[120,22,4744]}],state:[{t:2,x:{r:["data.malfStatus"],s:'_0==4?"disabled":null'},p:[120,43,4765]}],action:[{t:2,r:"malfAction",p:[120,97,4819]}]},f:[{t:2,r:"malfButton",p:[120,113,4835]}]}],n:50,r:"data.malfStatus",p:[119,3,4698]}]}],n:50,r:"data.siliconUser",p:[116,2,4556]}," ",{p:[124,2,4903],t:7,e:"ui-notice",f:[{p:[125,4,4919],t:7,e:"ui-section",a:{label:"Cover Lock"},f:[{t:4,f:[{p:[127,5,5e3],t:7,e:"span",f:[{t:2,x:{r:["data.coverLocked"],s:'_0?"Engaged":"Disengaged"'},p:[127,11,5006]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"},p:[126,3,4954]},{t:4,n:51,f:[{p:[129,5,5078],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.coverLocked"],s:'_0?"lock":"unlock"'},p:[129,22,5095]}],action:"cover"},f:[{t:2,x:{r:["data.coverLocked"],s:'_0?"Engaged":"Disengaged"'},p:[129,79,5152]}]}],x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"}}]}]}],r:"data.failTime"}]},e.exports=a.extend(r.exports)},{205:205}],229:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Alarms"},f:[{p:[2,3,31],t:7,e:"ul",f:[{t:4,f:[{p:[4,7,72],t:7,e:"li",f:[{p:[4,11,76],t:7,e:"ui-button",a:{icon:"close",style:"danger",action:"clear",params:['{"zone": "',{t:2,r:".",p:[4,83,148]},'"}']},f:[{t:2,r:".",p:[4,92,157]}]}]}],n:52,r:"data.priority",p:[3,5,41]},{t:4,n:51,f:[{p:[6,7,201],t:7,e:"li",f:[{p:[6,11,205],t:7,e:"span",a:{"class":"good"},f:["No Priority Alerts"]}]}],r:"data.priority"}," ",{t:4,f:[{p:[9,7,303],t:7,e:"li",f:[{p:[9,11,307],t:7,e:"ui-button",a:{icon:"close",style:"caution",action:"clear",params:['{"zone": "',{t:2,r:".",p:[9,84,380]},'"}']},f:[{t:2,r:".",p:[9,93,389]}]}]}],n:52,r:"data.minor",p:[8,5,275]},{t:4,n:51,f:[{p:[11,7,433],t:7,e:"li",f:[{p:[11,11,437],t:7,e:"span",a:{"class":"good"},f:["No Minor Alerts"]}]}],r:"data.minor"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],230:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:[{t:2,x:{r:["data.tank","data.sensors.0.long_name"],s:"_0?_1:null"},p:[1,20,19]}]},f:[{t:4,f:[{p:[3,5,102],t:7,e:"ui-subdisplay",a:{title:[{t:2,x:{r:["data.tank","long_name"],s:"!_0?_1:null"},p:[3,27,124]}]},f:[{p:[4,7,167],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[5,3,200],t:7,e:"span",f:[{t:2,x:{r:["pressure"],s:"Math.fixed(_0,2)"},p:[5,9,206]}," kPa"]}]}," ",{t:4,f:[{p:[8,9,302],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[9,11,346],t:7,e:"span",f:[{t:2,x:{r:["temperature"],s:"Math.fixed(_0,2)"},p:[9,17,352]}," K"]}]}],n:50,r:"temperature",p:[7,7,273]}," ",{t:4,f:[{p:[13,9,462],t:7,e:"ui-section",a:{label:[{t:2,r:"id",p:[13,28,481]}]},f:[{p:[14,5,495],t:7,e:"span",f:[{t:2,x:{r:["."],s:"Math.fixed(_0,2)"},p:[14,11,501]},"%"]}]}],n:52,i:"id",r:"gases",p:[12,4,434]}]}],n:52,r:"adata.sensors",p:[2,3,73]}]}," ",{t:4,f:[{p:{button:[{p:[23,5,704],t:7,e:"ui-button",a:{icon:"refresh",action:"reconnect"},f:["Reconnect"]}]},t:7,e:"ui-display",a:{title:"Controls",button:0},f:[" ",{p:[25,5,792],t:7,e:"ui-section",a:{label:"Input Injector"},f:[{p:[26,7,835],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.inputting"],s:'_0?"power-off":"close"'},p:[26,24,852]}],style:[{t:2,x:{r:["data.inputting"],s:'_0?"selected":null'},p:[26,75,903]}],action:"input"},f:[{t:2,x:{r:["data.inputting"],s:'_0?"Injecting":"Off"'},p:[27,9,968]}]}]}," ",{p:[29,5,1044],t:7,e:"ui-section",a:{label:"Input Rate"},f:[{p:[30,7,1083],t:7,e:"span",f:[{t:2,x:{r:["adata.inputRate"],s:"Math.fixed(_0)"},p:[30,13,1089]}," L/s"]}]}," ",{p:[32,5,1156],t:7,e:"ui-section", -a:{label:"Output Regulator"},f:[{p:[33,7,1201],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.outputting"],s:'_0?"power-off":"close"'},p:[33,24,1218]}],style:[{t:2,x:{r:["data.outputting"],s:'_0?"selected":null'},p:[33,76,1270]}],action:"output"},f:[{t:2,x:{r:["data.outputting"],s:'_0?"Open":"Closed"'},p:[34,9,1337]}]}]}," ",{p:[36,5,1412],t:7,e:"ui-section",a:{label:"Output Pressure"},f:[{p:[37,7,1456],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure"},f:[{t:2,x:{r:["adata.outputPressure"],s:"Math.round(_0)"},p:[37,50,1499]}," kPa"]}]}]}],n:50,r:"data.tank",p:[20,1,618]}]},e.exports=a.extend(r.exports)},{205:205}],231:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,5,48],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[3,22,65]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[3,66,109]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[4,22,164]}]}]}," ",{p:[6,3,223],t:7,e:"ui-section",a:{label:"Output Pressure"},f:[{p:[7,5,265],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[8,5,360],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.pressure","data.max_pressure"],s:'_0==_1?"disabled":null'},p:[8,35,390]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}," ",{p:[9,5,518],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[9,11,524]}," kPa"]}]}," ",{p:[11,3,586],t:7,e:"ui-section",a:{label:"Filter"},f:[{t:4,f:[{p:[13,7,654],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[13,25,672]}],action:"filter",params:['{"mode": ',{t:2,r:"id",p:[14,42,748]},"}"]},f:[{t:2,r:"name",p:[14,51,757]}]}],n:52,r:"data.filter_types",p:[12,5,619]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],232:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,5,48],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[3,22,65]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[3,66,109]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[4,22,164]}]}]}," ",{p:[6,3,223],t:7,e:"ui-section",a:{label:"Output Pressure"},f:[{p:[7,5,265],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[8,5,360],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.set_pressure","data.max_pressure"],s:'_0==_1?"disabled":null'},p:[8,35,390]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}," ",{p:[9,5,522],t:7,e:"span",f:[{t:2,x:{r:["adata.set_pressure"],s:"Math.round(_0)"},p:[9,11,528]}," kPa"]}]}," ",{p:[11,3,594],t:7,e:"ui-section",a:{label:"Node 1"},f:[{p:[12,5,627],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.node1_concentration"],s:'_0==0?"disabled":null'},p:[12,44,666]}],action:"node1",params:'{"concentration": -0.1}'}}," ",{p:[14,5,783],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.node1_concentration"],s:'_0==0?"disabled":null'},p:[14,39,817]}],action:"node1",params:'{"concentration": -0.01}'}}," ",{p:[16,5,935],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.node1_concentration"],s:'_0==100?"disabled":null'},p:[16,38,968]}],action:"node1",params:'{"concentration": 0.01}'}}," ",{p:[18,5,1087],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.node1_concentration"],s:'_0==100?"disabled":null'},p:[18,43,1125]}],action:"node1",params:'{"concentration": 0.1}'}}," ",{p:[20,5,1243],t:7,e:"span",f:[{t:2,x:{r:["adata.node1_concentration"],s:"Math.round(_0)"},p:[20,11,1249]},"%"]}]}," ",{p:[22,3,1319],t:7,e:"ui-section",a:{label:"Node 2"},f:[{p:[23,5,1352],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.node2_concentration"],s:'_0==0?"disabled":null'},p:[23,44,1391]}],action:"node2",params:'{"concentration": -0.1}'}}," ",{p:[25,5,1508],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.node2_concentration"],s:'_0==0?"disabled":null'},p:[25,39,1542]}],action:"node2",params:'{"concentration": -0.01}'}}," ",{p:[27,5,1660],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.node2_concentration"],s:'_0==100?"disabled":null'},p:[27,38,1693]}],action:"node2",params:'{"concentration": 0.01}'}}," ",{p:[29,5,1812],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.node2_concentration"],s:'_0==100?"disabled":null'},p:[29,43,1850]}],action:"node2",params:'{"concentration": 0.1}'}}," ",{p:[31,5,1968],t:7,e:"span",f:[{t:2,x:{r:["adata.node2_concentration"],s:"Math.round(_0)"},p:[31,11,1974]},"%"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],233:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,5,48],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[3,22,65]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[3,66,109]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[4,22,164]}]}]}," ",{t:4,f:[{p:[7,5,250],t:7,e:"ui-section",a:{label:"Transfer Rate"},f:[{p:[8,7,292],t:7,e:"ui-button",a:{icon:"pencil",action:"rate",params:'{"rate": "input"}'},f:["Set"]}," ",{p:[9,7,381],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.rate","data.max_rate"],s:'_0==_1?"disabled":null'},p:[9,37,411]}],action:"rate",params:'{"rate": "max"}'},f:["Max"]}," ",{p:[10,7,525],t:7,e:"span",f:[{t:2,x:{r:["adata.rate"],s:"Math.round(_0)"},p:[10,13,531]}," L/s"]}]}],n:50,r:"data.max_rate",p:[6,3,223]},{t:4,n:51,f:[{p:[13,5,605],t:7,e:"ui-section",a:{label:"Output Pressure"},f:[{p:[14,7,649],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[15,7,746],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.pressure","data.max_pressure"],s:'_0==_1?"disabled":null'},p:[15,37,776]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}," ",{p:[16,7,906],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[16,13,912]}," kPa"]}]}],r:"data.max_rate"}]}]},e.exports=a.extend(r.exports)},{205:205}],234:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{p:[3,5,67],t:7,e:"ui-button",a:{icon:"clock-o",style:[{t:2,x:{r:["data.timing"],s:'_0?"selected":null'},p:[3,38,100]}],action:[{t:2,x:{r:["data.timing"],s:'_0?"stop":"start"'},p:[3,83,145]}]},f:[{t:2,x:{r:["data.timing"],s:'_0?"Stop":"Start"'},p:[3,119,181]}]}," ",{p:[4,5,233],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"flash",style:[{t:2,x:{r:["data.flash_charging"],s:'_0?"disabled":null'},p:[4,57,285]}]},f:[{t:2,x:{r:["data.flash_charging"],s:'_0?"Recharging":"Flash"'},p:[4,102,330]}]}]},t:7,e:"ui-display",a:{title:"Cell Timer",button:0},f:[" ",{p:[6,3,410],t:7,e:"ui-section",f:[{p:[7,5,428],t:7,e:"ui-button",a:{icon:"fast-backward",action:"time",params:'{"adjust": -600}'}}," ",{p:[8,5,518],t:7,e:"ui-button",a:{icon:"backward",action:"time",params:'{"adjust": -100}'}}," ",{p:[9,5,603],t:7,e:"span",f:[{t:2,x:{r:["text","data.minutes"],s:"_0.zeroPad(_1,2)"},p:[9,11,609]},":",{t:2,x:{r:["text","data.seconds"],s:"_0.zeroPad(_1,2)"},p:[9,45,643]}]}," ",{p:[10,5,689],t:7,e:"ui-button",a:{icon:"forward",action:"time",params:'{"adjust": 100}'}}," ",{p:[11,5,772],t:7,e:"ui-button",a:{icon:"fast-forward",action:"time",params:'{"adjust": 600}'}}]}," ",{p:[13,3,875],t:7,e:"ui-section",f:[{p:[14,7,895],t:7,e:"ui-button",a:{icon:"hourglass-start",action:"preset",params:'{"preset": "short"}'},f:["Short"]}," ",{p:[15,7,999],t:7,e:"ui-button",a:{icon:"hourglass-start",action:"preset",params:'{"preset": "medium"}'},f:["Medium"]}," ",{p:[16,7,1105],t:7,e:"ui-button",a:{icon:"hourglass-start",action:"preset",params:'{"preset": "long"}'},f:["Long"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],235:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,23],t:7,e:"ui-notice",f:[{t:2,r:"data.notice",p:[3,5,40]}]}],n:50,r:"data.notice",p:[1,1,0]},{p:[6,1,82],t:7,e:"ui-display",a:{title:"Bluespace Artillery Control",button:0},f:[{t:4,f:[{p:[8,3,167],t:7,e:"ui-section",a:{label:"Target"},f:[{p:[9,5,200],t:7,e:"ui-button",a:{icon:"crosshairs",action:"recalibrate"},f:[{t:2,r:"data.target",p:[9,55,250]}]}]}," ",{p:[11,3,298],t:7,e:"ui-section",a:{label:"Controls"},f:[{t:4,f:[{p:[13,3,356],t:7,e:"ui-notice",f:[{p:[14,4,372],t:7,e:"span",f:["Bluespace Artillery firing protocols must be globally unlocked from two keycard authentication devices first!"]}]}],n:50,x:{r:["data.unlocked"],s:"!_0"},p:[12,2,330]},{t:4,n:51,f:[{p:[17,3,525],t:7,e:"ui-button",a:{icon:"warning",state:[{t:2,x:{r:["data.ready"],s:'_0?null:"disabled"'},p:[17,36,558]}],action:"fire"},f:["FIRE!"]}],x:{r:["data.unlocked"],s:"!_0"}}]}],n:50,r:"data.connected",p:[7,3,141]}," ",{t:4,f:[{p:[22,3,694],t:7,e:"ui-section",a:{label:"Maintenance"},f:[{p:[23,7,734],t:7,e:"ui-button",a:{icon:"wrench",action:"build"},f:["Complete Deployment."]}]}],n:50,x:{r:["data.connected"],s:"!_0"},p:[21,3,667]}]}]},e.exports=a.extend(r.exports)},{205:205}],236:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,3,15],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.hasHoldingTank"],s:'_0?"is":"is not"'},p:[2,23,35]}," connected to a tank."]}]}," ",{p:{button:[{p:[6,5,185],t:7,e:"ui-button",a:{icon:"pencil",action:"relabel"},f:["Relabel"]}]},t:7,e:"ui-display",a:{title:"Canister",button:0},f:[" ",{p:[8,3,266],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[9,5,301],t:7,e:"span",f:[{t:2,x:{r:["adata.tankPressure"],s:"Math.round(_0)"},p:[9,11,307]}," kPa"]}]}," ",{p:[11,3,373],t:7,e:"ui-section",a:{label:"Port"},f:[{p:[12,5,404],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.portConnected"],s:'_0?"good":"average"'},p:[12,18,417]}]},f:[{t:2,x:{r:["data.portConnected"],s:'_0?"Connected":"Not Connected"'},p:[12,63,462]}]}]}," ",{t:4,f:[{p:[15,3,573],t:7,e:"ui-section",a:{label:"Access"},f:[{p:[16,7,608],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.restricted"],s:'_0?"lock":"unlock"'},p:[16,24,625]}],style:[{t:2,x:{r:[],s:'"caution"'},p:[17,14,680]}],action:"restricted"},f:[{t:2,x:{r:["data.restricted"],s:'_0?"Restricted to Engineering":"Public"'},p:[18,27,722]}]}]}],n:50,r:"data.isPrototype",p:[14,3,544]}]}," ",{p:[22,1,839],t:7,e:"ui-display",a:{title:"Valve"},f:[{p:[23,3,869],t:7,e:"ui-section",a:{label:"Release Pressure"},f:[{p:[24,5,912],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.minReleasePressure",p:[24,18,925]}],max:[{t:2,r:"data.maxReleasePressure",p:[24,52,959]}],value:[{t:2,r:"data.releasePressure",p:[25,14,1002]}]},f:[{t:2,x:{r:["adata.releasePressure"],s:"Math.round(_0)"},p:[25,40,1028]}," kPa"]}]}," ",{p:[27,3,1099],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[28,5,1144],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.releasePressure","data.defaultReleasePressure"],s:'_0!=_1?null:"disabled"'},p:[28,38,1177]}],action:"pressure",params:'{"pressure": "reset"}'},f:["Reset"]}," ",{p:[30,5,1333],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.releasePressure","data.minReleasePressure"],s:'_0>_1?null:"disabled"'},p:[30,36,1364]}],action:"pressure",params:'{"pressure": "min"}'},f:["Min"]}," ",{p:[32,5,1511],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[33,5,1606],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.releasePressure","data.maxReleasePressure"],s:'_0<_1?null:"disabled"'},p:[33,35,1636]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}]}," ",{p:[36,3,1798],t:7,e:"ui-section",a:{label:"Valve"},f:[{p:[37,5,1830],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.valveOpen"],s:'_0?"unlock":"lock"'},p:[37,22,1847]}],style:[{t:2,x:{r:["data.valveOpen","data.hasHoldingTank"],s:'_0?_1?"caution":"danger":null'},p:[38,14,1901]}],action:"valve"},f:[{t:2,x:{r:["data.valveOpen"],s:'_0?"Open":"Closed"'},p:[39,22,1995]}]}]}]}," ",{t:4,f:[{p:[42,1,2090],t:7,e:"ui-display",a:{title:"Valve Toggle Timer"},f:[{t:4,f:[{p:[44,5,2155],t:7,e:"ui-section",a:{label:"Adjust Timer"},f:[{p:[45,7,2196],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.timer_is_not_default"],s:'_0?null:"disabled"'},p:[45,40,2229]}],action:"timer",params:'{"change": "reset"}'},f:["Reset"]}," ",{p:[47,7,2358],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.timer_is_not_min"],s:'_0?null:"disabled"'},p:[47,38,2389]}],action:"timer",params:'{"change": "decrease"}'},f:["Decrease"]}," ",{p:[49,7,2520],t:7,e:"ui-button",a:{icon:"pencil",state:[{t:2,x:{r:[],s:'"disabled"'},p:[49,39,2552]}],action:"timer",params:'{"change": "input"}'},f:["Set"]}," ",{p:[51,7,2637],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.timer_is_not_max"],s:'_0?null:"disabled"'},p:[51,37,2667]}],action:"timer",params:'{"change": "increase"}'},f:["Increase"]}]}],n:51,r:"data.timing",p:[43,3,2133]}," ",{p:[55,3,2833],t:7,e:"ui-section",a:{label:"Timer"},f:[{p:[56,6,2866],t:7,e:"ui-button",a:{icon:"clock-o",style:[{t:2,x:{r:["data.timing"],s:'_0?"danger":"caution"'},p:[56,39,2899]}],action:"toggle_timer"},f:[{t:2,x:{r:["data.timing"],s:'_0?"On":"Off"'},p:[57,30,2969]}]}," ",{p:[59,2,3017],t:7,e:"ui-section",a:{label:"Time until Valve Toggle"},f:[{p:[60,2,3064],t:7,e:"span",f:[{t:2,x:{r:["data.timing","data.time_left","data.timer_set"],s:"_0?_1:_2"},p:[60,8,3070]}]}]}]}]}],n:50,r:"data.isPrototype",p:[41,1,2062]},{p:{button:[{t:4,f:[{p:[69,7,3277],t:7,e:"ui-button",a:{icon:"eject",style:[{t:2,x:{r:["data.valveOpen"],s:'_0?"danger":null'},p:[69,38,3308]}],action:"eject"},f:["Eject"]}],n:50,r:"data.hasHoldingTank",p:[68,5,3242]}]},t:7,e:"ui-display",a:{title:"Holding Tank",button:0},f:[" ",{t:4,f:[{p:[73,3,3442],t:7,e:"ui-section",a:{label:"Label"},f:[{t:2,r:"data.holdingTank.name",p:[74,4,3473]}]}," ",{p:[76,3,3519],t:7,e:"ui-section",a:{label:"Pressure"},f:[{t:2,x:{r:["adata.holdingTank.tankPressure"],s:"Math.round(_0)"},p:[77,4,3553]}," kPa"]}],n:50,r:"data.hasHoldingTank",p:[72,3,3411]},{t:4,n:51,f:[{p:[80,3,3635],t:7,e:"ui-section",f:[{p:[81,4,3652],t:7,e:"span",a:{"class":"average"},f:["No Holding Tank"]}]}],r:"data.hasHoldingTank"}]}]},e.exports=a.extend(r.exports)},{205:205}],237:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{tabs:function(){return Object.keys(this.get("data.supplies"))}}}}(r),r.exports.template={v:3,t:[" ",{p:[11,1,158],t:7,e:"ui-display",a:{title:"Cargo"},f:[{p:[12,3,188],t:7,e:"ui-section",a:{label:"Shuttle"},f:[{t:4,f:[{p:[14,7,270],t:7,e:"ui-button",a:{action:"send"},f:[{t:2,r:"data.location",p:[14,32,295]}]}],n:50,x:{r:["data.docked","data.requestonly"],s:"_0&&!_1"},p:[13,5,222]},{t:4,n:51,f:[{p:[16,7,346],t:7,e:"span",f:[{t:2,r:"data.location",p:[16,13,352]}]}],x:{r:["data.docked","data.requestonly"],s:"_0&&!_1"}}]}," ",{p:[19,3,410],t:7,e:"ui-section",a:{label:"Credits"},f:[{p:[20,5,444],t:7,e:"span",f:[{t:2,x:{r:["adata.points"],s:"Math.floor(_0)"},p:[20,11,450]}]}]}," ",{p:[22,3,506],t:7,e:"ui-section",a:{label:"CentCom Message"},f:[{p:[23,7,550],t:7,e:"span",f:[{t:2,r:"data.message",p:[23,13,556]}]}]}," ",{t:4,f:[{p:[26,5,644],t:7,e:"ui-section",a:{label:"Loan"},f:[{t:4,f:[{p:[28,9,716],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.away","data.docked"],s:'_0&&_1?null:"disabled"'},p:[29,17,744]}],action:"loan"},f:["Loan Shuttle"]}],n:50,x:{r:["data.loan_dispatched"],s:"!_0"},p:[27,7,677]},{t:4,n:51,f:[{p:[32,9,868],t:7,e:"span",a:{"class":"bad"},f:["Loaned to CentCom"]}],x:{r:["data.loan_dispatched"],s:"!_0"}}]}],n:50,x:{r:["data.loan","data.requestonly"],s:"_0&&!_1"},p:[25,3,600]}]}," ",{t:4,f:[{p:{button:[{p:[40,7,1066],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["data.cart.length"],s:'_0?null:"disabled"'},p:[40,38,1097]}],action:"clear"},f:["Clear"]}]},t:7,e:"ui-display",a:{title:"Cart",button:0},f:[" ",{t:4,f:[{p:[43,7,1222],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{p:[44,9,1263],t:7,e:"div",a:{"class":"content"},f:["#",{t:2,r:"id",p:[44,31,1285]}]}," ",{p:[45,9,1307],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"object",p:[45,30,1328]}]}," ",{p:[46,9,1354],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"cost",p:[46,30,1375]}," Credits"]}," ",{p:[47,9,1407],t:7,e:"div",a:{"class":"content"},f:[{p:[48,11,1440],t:7,e:"ui-button",a:{icon:"minus",action:"remove",params:['{"id": "',{t:2,r:"id",p:[48,67,1496]},'"}']}}]}]}],n:52,r:"data.cart",p:[42,5,1195]},{t:4,n:51,f:[{p:[52,7,1566],t:7,e:"span",f:["Nothing in Cart"]}],r:"data.cart"}]}],n:50,x:{r:["data.requestonly"],s:"!_0"},p:[37,1,972]},{p:{button:[{t:4,f:[{p:[59,7,1735],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["data.requests.length"],s:'_0?null:"disabled"'},p:[59,38,1766]}],action:"denyall"},f:["Clear"]}],n:50,x:{r:["data.requestonly"],s:"!_0"},p:[58,5,1702]}]},t:7,e:"ui-display",a:{title:"Requests",button:0},f:[" ",{t:4,f:[{p:[63,5,1908],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{p:[64,7,1947],t:7,e:"div",a:{"class":"content"},f:["#",{t:2,r:"id",p:[64,29,1969]}]}," ",{p:[65,7,1989],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"object",p:[65,28,2010]}]}," ",{p:[66,7,2034],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"cost",p:[66,28,2055]}," Credits"]}," ",{p:[67,7,2085],t:7,e:"div",a:{"class":"content"},f:["By ",{t:2,r:"orderer",p:[67,31,2109]}]}," ",{p:[68,7,2134],t:7,e:"div",a:{"class":"content"},f:["Comment: ",{t:2,r:"reason",p:[68,37,2164]}]}," ",{t:4,f:[{p:[70,9,2223],t:7,e:"div",a:{"class":"content"},f:[{p:[71,11,2256],t:7,e:"ui-button",a:{icon:"check",action:"approve",params:['{"id": "',{t:2,r:"id",p:[71,68,2313]},'"}']}}," ",{p:[72,11,2336],t:7,e:"ui-button",a:{icon:"close",action:"deny",params:['{"id": "',{t:2,r:"id",p:[72,65,2390]},'"}']}}]}],n:50,x:{r:["data.requestonly"],s:"!_0"},p:[69,7,2188]}]}],n:52,r:"data.requests",p:[62,3,1879]},{t:4,n:51,f:[{p:[77,7,2473],t:7,e:"span",f:["No Requests"]}],r:"data.requests"}]}," ",{p:[80,1,2529],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"tabs",p:[80,16,2544]}]},f:[{t:4,f:[{p:[82,5,2587],t:7,e:"tab",a:{name:[{t:2,r:"name",p:[82,16,2598]}]},f:[{t:4,f:[{p:[84,9,2641],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[84,28,2660]}],candystripe:0,right:0},f:[{p:[85,11,2700],t:7,e:"ui-button",a:{action:"add",params:['{"id": "',{t:2,r:"id",p:[85,51,2740]},'"}']},f:[{t:2,r:"cost",p:[85,61,2750]}," Credits"]}]}],n:52,r:"packs",p:[83,7,2616]}]}],n:52,r:"data.supplies",p:[81,3,2558]}]}]},e.exports=a.extend(r.exports)},{205:205}],238:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Cellular Emporium",button:0},f:[{p:[2,3,49],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.can_readapt"],s:'_0?null:"disabled"'},p:[2,36,82]}],action:"readapt"},f:["Readapt"]}," ",{p:[4,3,169],t:7,e:"ui-section",a:{label:"Genetic Points Remaining",right:0},f:[{t:2,r:"data.genetic_points_remaining",p:[5,5,226]}]}]}," ",{p:[8,1,293],t:7,e:"ui-display",f:[{t:4,f:[{p:[10,3,335],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[10,22,354]}],candystripe:0,right:0},f:[{p:[11,5,388],t:7,e:"span",f:[{t:2,r:"desc",p:[11,11,394]}]}," ",{p:[12,5,415],t:7,e:"span",f:[{t:2,r:"helptext",p:[12,11,421]}]}," ",{p:[13,5,446],t:7,e:"span",f:["Cost: ",{t:2,r:"dna_cost",p:[13,17,458]}]}," ",{p:[14,5,483],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["owned","can_purchase"],s:'_0?"selected":_1?null:"disabled"'},p:[15,14,508]}],action:"evolve",params:['{"name": "',{t:2,r:"name",p:[17,25,615]},'"}']},f:[{t:2,x:{r:["owned"],s:'_0?"Evolved":"Evolve"'},p:[18,7,635]}]}]}],n:52,r:"data.abilities",p:[9,1,307]},{t:4,f:[{p:[23,3,738],t:7,e:"span",a:{"class":"warning"},f:["No abilities availible."]}],n:51,r:"data.abilities",p:[22,1,715]}]}]},e.exports=a.extend(r.exports)},{205:205}],239:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[2,3,31],t:7,e:"ui-section",a:{label:"Energy"},f:[{p:[3,5,64],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.maxEnergy",p:[3,26,85]}],value:[{t:2,r:"data.energy",p:[3,53,112]}]},f:[{t:2,x:{r:["adata.energy"],s:"Math.fixed(_0)"},p:[3,70,129]}," Units"]}]}]}," ",{p:{button:[{t:4,f:[{p:[9,7,315],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.amount","."],s:'_0==_1?"selected":null'},p:[9,37,345]}],action:"amount",params:['{"target": ',{t:2,r:".",p:[9,114,422]},"}"]},f:[{t:2,r:".",p:[9,122,430]}]}],n:52,r:"data.beakerTransferAmounts",p:[8,5,271]}]},t:7,e:"ui-display",a:{title:"Dispense",button:0},f:[" ",{p:[12,3,482],t:7,e:"ui-section",f:[{t:4,f:[{p:[14,7,532],t:7,e:"ui-button",a:{grid:0,icon:"tint",action:"dispense",params:['{"reagent": "',{t:2,r:"id",p:[14,74,599]},'"}']},f:[{t:2,r:"title",p:[14,84,609]}]}],n:52,r:"data.chemicals",p:[13,5,500]}]}]}," ",{p:{button:[{t:4,f:[{p:[21,7,786],t:7,e:"ui-button",a:{icon:"minus",action:"remove",params:['{"amount": ',{t:2,r:".",p:[21,66,845]},"}"]},f:[{t:2,r:".",p:[21,74,853]}]}],n:52,r:"data.beakerTransferAmounts",p:[20,5,742]}," ",{p:[23,5,891],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[23,36,922]}],action:"eject"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{p:[25,3,1019],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{p:[27,7,1089],t:7,e:"span",f:[{t:2,x:{r:["adata.beakerCurrentVolume"],s:"Math.round(_0)"},p:[27,13,1095]},"/",{t:2,r:"data.beakerMaxVolume",p:[27,55,1137]}," Units"]}," ",{p:[28,7,1182],t:7,e:"br"}," ",{t:4,f:[{p:[30,9,1235],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[30,52,1278]}," units of ",{t:2,r:"name",p:[30,87,1313]}]},{p:[30,102,1328],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[29,7,1195]},{t:4,n:51,f:[{p:[32,9,1359],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[26,5,1054]},{t:4,n:51,f:[{p:[35,7,1435],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],240:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Thermostat"},f:[{p:[2,3,35],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,5,67],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isActive"],s:'_0?"power-off":"close"'},p:[3,22,84]}],style:[{t:2,x:{r:["data.isActive"],s:'_0?"selected":null'},p:[4,10,137]}],state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[5,10,186]}],action:"power"},f:[{t:2,x:{r:["data.isActive"],s:'_0?"On":"Off"'},p:[6,18,249]}]}]}," ",{p:[8,3,314],t:7,e:"ui-section",a:{label:"Target"},f:[{p:[9,4,346],t:7,e:"ui-button",a:{icon:"pencil",action:"temperature",params:'{"target": "input"}'},f:[{t:2,x:{r:["adata.targetTemp"],s:"Math.round(_0)"},p:[9,79,421]}," K"]}]}]}," ",{p:{button:[{p:[14,5,564],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[14,36,595]}],action:"eject"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{p:[16,3,692],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{p:[18,7,762],t:7,e:"span",f:["Temperature: ",{t:2,x:{r:["adata.currentTemp"],s:"Math.round(_0)"},p:[18,26,781]}," K"]}," ",{p:[19,7,831],t:7,e:"br"}," ",{t:4,f:[{p:[21,9,885],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[21,52,928]}," units of ",{t:2,r:"name",p:[21,87,963]}]},{p:[21,102,978],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[20,7,845]},{t:4,n:51,f:[{p:[23,9,1009],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[17,5,727]},{t:4,n:51,f:[{p:[26,7,1085],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],241:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,32],t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[{p:[3,3,70],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?"Eject":"close"'},p:[3,20,87]}],style:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?"selected":null'},p:[4,11,143]}],state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[5,11,199]}],action:"eject"},f:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?"Eject and Clear Buffer":"No beaker"'},p:[7,5,268]}]}," ",{p:[10,3,357],t:7,e:"ui-section",f:[{t:4,f:[{t:4,f:[{p:[13,6,443],t:7,e:"ui-section",a:{label:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[13,25,462]}," units of ",{t:2,r:"name",p:[13,60,497]}],nowrap:0},f:[{p:[14,7,522],t:7,e:"div",a:{"class":"content",style:"float:right"},f:[{p:[15,8,572],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[15,61,625]},'", "amount": 1}']},f:["1"]}," ",{p:[16,8,670],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[16,61,723]},'", "amount": 5}']},f:["5"]}," ",{p:[17,8,768],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[17,61,821]},'", "amount": 10}']},f:["10"]}," ",{p:[18,8,868],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[18,61,921]},'", "amount": 1000}']},f:["All"]}," ",{p:[19,8,971],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[19,61,1024]},'", "amount": -1}']},f:["Custom"]}," ",{p:[20,8,1075],t:7,e:"ui-button",a:{action:"analyze",params:['{"id": "',{t:2,r:"id",p:[20,52,1119]},'"}']},f:["Analyze"]}]}]}],n:52,r:"data.beakerContents",p:[12,5,407]},{t:4,n:51,f:[{p:[24,5,1201],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"data.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[11,4,374]},{t:4,n:51,f:[{p:[27,5,1272],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}," ",{p:[32,2,1360],t:7,e:"ui-display",a:{title:"Buffer"},f:[{p:[33,3,1391],t:7,e:"ui-button",a:{action:"toggleMode",state:[{t:2,x:{r:["data.mode"],s:'_0?null:"selected"'},p:[33,41,1429]}]},f:["Destroy"]}," ",{p:[34,3,1487],t:7,e:"ui-button",a:{action:"toggleMode",state:[{t:2,x:{r:["data.mode"],s:'_0?"selected":null'},p:[34,41,1525]}]},f:["Transfer to Beaker"]}," ",{p:[35,3,1594],t:7,e:"ui-section",f:[{t:4,f:[{p:[37,5,1646],t:7,e:"ui-section",a:{label:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[37,24,1665]}," units of ",{t:2,r:"name",p:[37,59,1700]}],nowrap:0},f:[{p:[38,6,1724],t:7,e:"div",a:{"class":"content",style:"float:right"},f:[{p:[39,7,1773],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[39,62,1828]},'", "amount": 1}']},f:["1"]}," ",{p:[40,7,1872],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[40,62,1927]},'", "amount": 5}']},f:["5"]}," ",{p:[41,7,1971],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[41,62,2026]},'", "amount": 10}']},f:["10"]}," ",{p:[42,7,2072],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[42,62,2127]},'", "amount": 1000}']},f:["All"]}," ",{p:[43,7,2176],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[43,62,2231]},'", "amount": -1}']},f:["Custom"]}," ",{p:[44,7,2281],t:7,e:"ui-button",a:{action:"analyze",params:['{"id": "',{t:2,r:"id",p:[44,51,2325]},'"}']},f:["Analyze"]}]}]}],n:52,r:"data.bufferContents",p:[36,4,1611]}]}]}," ",{t:4,f:[{p:[52,3,2461],t:7,e:"ui-display",a:{title:"Pills, Bottles and Patches"},f:[{t:4,f:[{p:[54,5,2551],t:7,e:"ui-button",a:{action:"ejectp",state:[{t:2,x:{r:["data.isPillBottleLoaded"],s:'_0?null:"disabled"'},p:[54,39,2585]}]},f:[{t:2,x:{r:["data.isPillBottleLoaded"],s:'_0?"Eject":"No Pill bottle loaded"'},p:[54,88,2634]}]}," ",{p:[55,5,2715],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.pillBotContent",p:[55,27,2737]},"/",{t:2,r:"data.pillBotMaxContent",p:[55,51,2761]}]}],n:50,r:"data.isPillBottleLoaded",p:[53,4,2514]},{t:4,n:51,f:[{p:[57,5,2813],t:7,e:"span",a:{"class":"average"},f:["No Pillbottle"]}],r:"data.isPillBottleLoaded"}," ",{p:[60,4,2877],t:7,e:"br"}," ",{p:[61,4,2887],t:7,e:"br"}," ",{p:[62,4,2897],t:7,e:"ui-button",a:{action:"createPill",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[62,63,2956]}]},f:["Create Pill (max 50µ)"]}," ",{p:[63,4,3040],t:7,e:"br"}," ",{p:[64,4,3050],t:7,e:"ui-button",a:{action:"createPill",params:'{"many": 1}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[64,63,3109]}]},f:["Create Multiple Pills"]}," ",{p:[65,4,3193],t:7,e:"br"}," ",{p:[66,4,3203],t:7,e:"br"}," ",{p:[67,4,3213],t:7,e:"ui-button",a:{action:"createPatch",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[67,64,3273]}]},f:["Create Patch (max 40µ)"]}," ",{p:[68,4,3358],t:7,e:"br"}," ",{p:[69,4,3368],t:7,e:"ui-button",a:{action:"createPatch",params:'{"many": 1}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[69,64,3428]}]},f:["Create Multiple Patches"]}," ",{p:[70,4,3514],t:7,e:"br"}," ",{p:[71,4,3524],t:7,e:"br"}," ",{p:[72,4,3534],t:7,e:"ui-button",a:{action:"createBottle",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[72,65,3595]}]},f:["Create Bottle (max 30µ)"]}," ",{p:[73,4,3681],t:7,e:"br"}," ",{p:[74,4,3691],t:7,e:"ui-button",a:{action:"createBottle",params:'{"many": 1}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[74,65,3752]}]},f:["Dispense Buffer to Bottles"]}]}],n:50,x:{r:["data.condi"],s:"!_0"},p:[51,2,2438]},{t:4,n:51,f:[{p:[79,3,3874],t:7,e:"ui-display",a:{title:"Condiments bottles and packs"},f:[{p:[80,4,3929],t:7,e:"ui-button",a:{action:"createPill",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[80,63,3988]}]},f:["Create Pack (max 10µ)"]}," ",{p:[81,4,4072],t:7,e:"br"}," ",{p:[82,4,4082],t:7,e:"br"}," ",{p:[83,4,4092],t:7,e:"ui-button",a:{action:"createBottle",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[83,65,4153]}]},f:["Create Bottle (max 50µ)"]}]}],x:{r:["data.condi"],s:"!_0"}}],n:50,x:{r:["data.screen"],s:'_0=="home"'},p:[1,1,0]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.screen"],s:'_0=="analyze"'},f:[{p:[87,2,4301],t:7,e:"ui-display",a:{title:[{t:2,r:"data.analyzeVars.name",p:[87,20,4319]}]},f:[{p:[88,3,4350],t:7,e:"span",a:{"class":"highlight"},f:["Description:"]}," ",{p:[89,3,4398],t:7,e:"span",a:{"class":"content",style:"float:center"},f:[{t:2,r:"data.analyzeVars.description",p:[89,46,4441]}]}," ",{p:[90,3,4484],t:7,e:"br"}," ",{p:[91,3,4493],t:7,e:"span",a:{"class":"highlight"},f:["Color:"]}," ",{p:[92,3,4535],t:7,e:"span",a:{style:["color: ",{t:2,r:"data.analyzeVars.color",p:[92,23,4555]},"; background-color: ",{t:2,r:"data.analyzeVars.color",p:[92,69,4601]}]},f:[{t:2,r:"data.analyzeVars.color",p:[92,97,4629]}]}," ",{p:[93,3,4666],t:7,e:"br"}," ",{p:[94,3,4675],t:7,e:"span",a:{"class":"highlight"},f:["State:"]}," ",{p:[95,3,4717],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.state",p:[95,25,4739]}]}," ",{p:[96,3,4776],t:7,e:"br"}," ",{p:[97,3,4785],t:7,e:"span",a:{"class":"highlight"},f:["Metabolization Rate:"]}," ",{p:[98,3,4841],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.metaRate",p:[98,25,4863]},"µ/minute"]}," ",{p:[99,3,4911],t:7,e:"br"}," ",{p:[100,3,4920],t:7,e:"span",a:{"class":"highlight"},f:["Overdose Threshold:"]}," ",{p:[101,3,4975],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.overD",p:[101,25,4997]}]}," ",{p:[102,3,5034],t:7,e:"br"}," ",{p:[103,3,5043],t:7,e:"span",a:{"class":"highlight"},f:["Addiction Threshold:"]}," ",{p:[104,3,5099],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.addicD",p:[104,25,5121]}]}," ",{p:[105,3,5159],t:7,e:"br"}," ",{p:[106,3,5168],t:7,e:"br"}," ",{p:[107,3,5177],t:7,e:"ui-button",a:{action:"goScreen",params:'{"screen": "home"}'},f:["Back"]}]}]}],x:{r:["data.screen"],s:'_0=="home"'}}]},e.exports=a.extend(r.exports)},{205:205}],242:[function(t,e,n){ -var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-button",a:{action:"toggle"},f:[{t:2,x:{r:["data.recollection"],s:'_0?"Recital":"Recollection"'},p:[2,30,43]}]}]}," ",{t:4,f:[{p:[5,3,149],t:7,e:"ui-display",f:[{t:3,r:"data.rec_text",p:[6,3,165]}," ",{t:4,f:[{p:[8,4,231],t:7,e:"br"},{p:[8,8,235],t:7,e:"ui-button",a:{action:"rec_category",params:['{"category": "',{t:2,r:"name",p:[8,63,290]},'"}']},f:[{t:3,r:"name",p:[8,75,302]}," - ",{t:3,r:"desc",p:[8,88,315]}]}],n:52,r:"data.recollection_categories",p:[7,3,188]}," ",{t:3,r:"data.rec_section",p:[10,3,354]}," ",{t:3,r:"data.rec_binds",p:[11,3,380]}]}],n:50,r:"data.recollection",p:[4,1,120]},{t:4,n:51,f:[{p:[14,2,431],t:7,e:"ui-display",a:{title:"Power",button:0},f:[{p:[15,4,469],t:7,e:"ui-section",f:[{t:3,r:"data.power",p:[16,6,488]}]}]}," ",{p:[19,2,541],t:7,e:"ui-display",f:[{p:[20,3,557],t:7,e:"ui-section",f:[{p:[21,4,574],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.selected"],s:'_0=="Driver"?"selected":null'},p:[21,22,592]}],action:"select",params:'{"category": "Driver"}'},f:["Driver"]}," ",{p:[22,4,715],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.selected"],s:'_0=="Script"?"selected":null'},p:[22,22,733]}],action:"select",params:'{"category": "Script"}'},f:["Scripts"]}," ",{p:[23,4,857],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.selected"],s:'_0=="Application"?"selected":null'},p:[23,22,875]}],action:"select",params:'{"category": "Application"}'},f:["Applications"]}," ",{p:[24,4,1014],t:7,e:"br"},{t:3,r:"data.tier_info",p:[24,8,1018]}]},{p:[25,16,1055],t:7,e:"hr"}," ",{p:[26,3,1063],t:7,e:"ui-section",f:[{t:4,f:[{p:[28,4,1108],t:7,e:"div",f:[{p:[28,9,1113],t:7,e:"ui-button",a:{tooltip:[{t:3,r:"tip",p:[28,29,1133]}],"tooltip-side":"right",action:"recite",params:['{"category": "',{t:2,r:"type",p:[28,99,1203]},'"}']},f:["Recite ",{t:3,r:"required",p:[28,118,1222]}]}," ",{t:4,f:[{t:4,f:[{p:[31,6,1298],t:7,e:"ui-button",a:{action:"bind",params:['{"category": "',{t:2,r:"type",p:[31,53,1345]},'"}']},f:["Unbind ",{t:3,r:"bound",p:[31,72,1364]}]}],n:50,r:"bound",p:[30,5,1278]},{t:4,n:51,f:[{p:[33,6,1408],t:7,e:"ui-button",a:{action:"bind",params:['{"category": "',{t:2,r:"type",p:[33,53,1455]},'"}']},f:["Quickbind"]}],r:"bound"}],n:50,r:"quickbind",p:[29,6,1255]}," ",{t:3,r:"name",p:[36,6,1522]}," ",{t:3,r:"descname",p:[36,17,1533]}," ",{t:3,r:"invokers",p:[36,32,1548]}]}],n:52,r:"data.scripture",p:[27,3,1079]}]}]}],r:"data.recollection"}]},e.exports=a.extend(r.exports)},{205:205}],243:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Codex Gigas"},f:[{p:[2,2,35],t:7,e:"ui-section",f:[{t:2,r:"data.name",p:[3,3,51]}]}," ",{p:[5,5,86],t:7,e:"ui-section",a:{label:"Prefix"},f:[{p:[6,3,117],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[6,22,136]}],action:"Dark "},f:["Dark"]}," ",{p:[7,3,221],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[7,22,240]}],action:"Hellish "},f:["Hellish"]}," ",{p:[8,3,331],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[8,22,350]}],action:"Fallen "},f:["Fallen"]}," ",{p:[9,3,439],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[9,22,458]}],action:"Fiery "},f:["Fiery"]}," ",{p:[10,3,545],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[10,22,564]}],action:"Sinful "},f:["Sinful"]}," ",{p:[11,3,653],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[11,22,672]}],action:"Blood "},f:["Blood"]}," ",{p:[12,3,759],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[12,22,778]}],action:"Fluffy "},f:["Fluffy"]}]}," ",{p:[14,5,888],t:7,e:"ui-section",a:{label:"Title"},f:[{p:[15,3,918],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[15,22,937]}],action:"Lord "},f:["Lord"]}," ",{p:[16,3,1022],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[16,22,1041]}],action:"Prelate "},f:["Prelate"]}," ",{p:[17,3,1132],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[17,22,1151]}],action:"Count "},f:["Count"]}," ",{p:[18,3,1238],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[18,22,1257]}],action:"Viscount "},f:["Viscount"]}," ",{p:[19,3,1350],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[19,22,1369]}],action:"Vizier "},f:["Vizier"]}," ",{p:[20,3,1458],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[20,22,1477]}],action:"Elder "},f:["Elder"]}," ",{p:[21,3,1564],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[21,22,1583]}],action:"Adept "},f:["Adept"]}]}," ",{p:[23,5,1691],t:7,e:"ui-section",a:{label:"Name"},f:[{p:[24,3,1720],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[24,22,1739]}],action:"hal"},f:["hal"]}," ",{p:[25,3,1821],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[25,22,1840]}],action:"ve"},f:["ve"]}," ",{p:[26,3,1920],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[26,22,1939]}],action:"odr"},f:["odr"]}," ",{p:[27,3,2021],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[27,22,2040]}],action:"neit"},f:["neit"]}," ",{p:[28,3,2124],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[28,22,2143]}],action:"ci"},f:["ci"]}," ",{p:[29,3,2223],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[29,22,2242]}],action:"quon"},f:["quon"]}," ",{p:[30,3,2326],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[30,22,2345]}],action:"mya"},f:["mya"]}," ",{p:[31,3,2427],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[31,22,2446]}],action:"folth"},f:["folth"]}," ",{p:[32,3,2532],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[32,22,2551]}],action:"wren"},f:["wren"]}," ",{p:[33,3,2635],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[33,22,2654]}],action:"geyr"},f:["geyr"]}," ",{p:[34,3,2738],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[34,22,2757]}],action:"hil"},f:["hil"]}," ",{p:[35,3,2839],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[35,22,2858]}],action:"niet"},f:["niet"]}," ",{p:[36,3,2942],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[36,22,2961]}],action:"twou"},f:["twou"]}," ",{p:[37,3,3045],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[37,22,3064]}],action:"phi"},f:["phi"]}," ",{p:[38,3,3146],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[38,22,3165]}],action:"coa"},f:["coa"]}]}," ",{p:[40,5,3268],t:7,e:"ui-section",a:{label:"suffix"},f:[{p:[41,3,3299],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[41,22,3318]}],action:" the Red"},f:["the Red"]}," ",{p:[42,3,3409],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[42,22,3428]}],action:" the Soulless"},f:["the Soulless"]}," ",{p:[43,3,3529],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[43,22,3548]}],action:" the Master"},f:["the Master"]}," ",{p:[44,3,3645],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[44,22,3664]}],action:", the Lord of all things"},f:["the Lord of all things"]}," ",{p:[45,3,3786],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[45,22,3805]}],action:", Jr."},f:["jr"]}]}," ",{p:[47,5,3909],t:7,e:"ui-section",a:{label:"submit"},f:[{p:[48,3,3941],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0>=4?null:"disabled"'},p:[48,21,3959]}],action:"search"},f:["search"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],244:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[2,1,2],t:7,e:"ui-button",a:{icon:"circle",action:"clean_order"},f:["Clear Order"]},{p:[2,70,71],t:7,e:"br"},{p:[2,74,75],t:7,e:"br"}," ",{p:[3,1,81],t:7,e:"i",f:["Your new computer device you always dreamed of is just four steps away..."]},{p:[3,81,161],t:7,e:"hr"}," ",{t:4,f:[" ",{p:[5,1,223],t:7,e:"div",a:{"class":"item"},f:[{p:[6,2,244],t:7,e:"h2",f:["Step 1: Select your device type"]}," ",{p:[7,2,287],t:7,e:"ui-button",a:{icon:"calc",action:"pick_device",params:'{"pick" : "1"}'},f:["Laptop"]}," ",{p:[8,2,377],t:7,e:"ui-button",a:{icon:"calc",action:"pick_device",params:'{"pick" : "2"}'},f:["LTablet"]}]}],n:50,x:{r:["data.state"],s:"_0==0"},p:[4,1,167]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.state"],s:"_0==1"},f:[{p:[11,1,502],t:7,e:"div",a:{"class":"item"},f:[{p:[12,2,523],t:7,e:"h2",f:["Step 2: Personalise your device"]}," ",{p:[13,2,566],t:7,e:"table",f:[{p:[14,3,577],t:7,e:"tr",f:[{p:[15,4,586],t:7,e:"td",f:[{p:[15,8,590],t:7,e:"b",f:["Current Price:"]}]},{p:[16,4,616],t:7,e:"td",f:[{t:2,r:"data.totalprice",p:[16,8,620]},"C"]}]}," ",{p:[18,3,653],t:7,e:"tr",f:[{p:[19,4,663],t:7,e:"td",f:[{p:[19,8,667],t:7,e:"b",f:["Battery:"]}]},{p:[20,4,687],t:7,e:"td",f:[{p:[20,8,691],t:7,e:"ui-button",a:{action:"hw_battery",params:'{"battery" : "1"}',state:[{t:2,x:{r:["data.hw_battery"],s:'_0==1?"selected":null'},p:[20,73,756]}]},f:["Standard"]}]},{p:[21,4,827],t:7,e:"td",f:[{p:[21,8,831],t:7,e:"ui-button",a:{action:"hw_battery",params:'{"battery" : "2"}',state:[{t:2,x:{r:["data.hw_battery"],s:'_0==2?"selected":null'},p:[21,73,896]}]},f:["Upgraded"]}]},{p:[22,4,967],t:7,e:"td",f:[{p:[22,8,971],t:7,e:"ui-button",a:{action:"hw_battery",params:'{"battery" : "3"}',state:[{t:2,x:{r:["data.hw_battery"],s:'_0==3?"selected":null'},p:[22,73,1036]}]},f:["Advanced"]}]}]}," ",{p:[24,3,1115],t:7,e:"tr",f:[{p:[25,4,1124],t:7,e:"td",f:[{p:[25,8,1128],t:7,e:"b",f:["Hard Drive:"]}]},{p:[26,4,1151],t:7,e:"td",f:[{p:[26,8,1155],t:7,e:"ui-button",a:{action:"hw_disk",params:'{"disk" : "1"}',state:[{t:2,x:{r:["data.hw_disk"],s:'_0==1?"selected":null'},p:[26,67,1214]}]},f:["Standard"]}]},{p:[27,4,1282],t:7,e:"td",f:[{p:[27,8,1286],t:7,e:"ui-button",a:{action:"hw_disk",params:'{"disk" : "2"}',state:[{t:2,x:{r:["data.hw_disk"],s:'_0==2?"selected":null'},p:[27,67,1345]}]},f:["Upgraded"]}]},{p:[28,4,1413],t:7,e:"td",f:[{p:[28,8,1417],t:7,e:"ui-button",a:{action:"hw_disk",params:'{"disk" : "3"}',state:[{t:2,x:{r:["data.hw_disk"],s:'_0==3?"selected":null'},p:[28,67,1476]}]},f:["Advanced"]}]}]}," ",{p:[30,3,1552],t:7,e:"tr",f:[{p:[31,4,1561],t:7,e:"td",f:[{p:[31,8,1565],t:7,e:"b",f:["Network Card:"]}]},{p:[32,4,1590],t:7,e:"td",f:[{p:[32,8,1594],t:7,e:"ui-button",a:{action:"hw_netcard",params:'{"netcard" : "0"}',state:[{t:2,x:{r:["data.hw_netcard"],s:'_0==0?"selected":null'},p:[32,73,1659]}]},f:["None"]}]},{p:[33,4,1726],t:7,e:"td",f:[{p:[33,8,1730],t:7,e:"ui-button",a:{action:"hw_netcard",params:'{"netcard" : "1"}',state:[{t:2,x:{r:["data.hw_netcard"],s:'_0==1?"selected":null'},p:[33,73,1795]}]},f:["Standard"]}]},{p:[34,4,1866],t:7,e:"td",f:[{p:[34,8,1870],t:7,e:"ui-button",a:{action:"hw_netcard",params:'{"netcard" : "2"}',state:[{t:2,x:{r:["data.hw_netcard"],s:'_0==2?"selected":null'},p:[34,73,1935]}]},f:["Advanced"]}]}]}," ",{p:[36,3,2014],t:7,e:"tr",f:[{p:[37,4,2023],t:7,e:"td",f:[{p:[37,8,2027],t:7,e:"b",f:["Nano Printer:"]}]},{p:[38,4,2052],t:7,e:"td",f:[{p:[38,8,2056],t:7,e:"ui-button",a:{action:"hw_nanoprint",params:'{"print" : "0"}',state:[{t:2,x:{r:["data.hw_nanoprint"],s:'_0==0?"selected":null'},p:[38,73,2121]}]},f:["None"]}]},{p:[39,4,2190],t:7,e:"td",f:[{p:[39,8,2194],t:7,e:"ui-button",a:{action:"hw_nanoprint",params:'{"print" : "1"}',state:[{t:2,x:{r:["data.hw_nanoprint"],s:'_0==1?"selected":null'},p:[39,73,2259]}]},f:["Standard"]}]}]}," ",{p:[41,3,2340],t:7,e:"tr",f:[{p:[42,4,2349],t:7,e:"td",f:[{p:[42,8,2353],t:7,e:"b",f:["Card Reader:"]}]},{p:[43,4,2377],t:7,e:"td",f:[{p:[43,8,2381],t:7,e:"ui-button",a:{action:"hw_card",params:'{"card" : "0"}',state:[{t:2,x:{r:["data.hw_card"],s:'_0==0?"selected":null'},p:[43,67,2440]}]},f:["None"]}]},{p:[44,4,2504],t:7,e:"td",f:[{p:[44,8,2508],t:7,e:"ui-button",a:{action:"hw_card",params:'{"card" : "1"}',state:[{t:2,x:{r:["data.hw_card"],s:'_0==1?"selected":null'},p:[44,67,2567]}]},f:["Standard"]}]}]}]}," ",{t:4,f:[" ",{p:[49,4,2706],t:7,e:"table",f:[{p:[50,5,2719],t:7,e:"tr",f:[{p:[51,6,2730],t:7,e:"td",f:[{p:[51,10,2734],t:7,e:"b",f:["Processor Unit:"]}]},{p:[52,6,2763],t:7,e:"td",f:[{p:[52,10,2767],t:7,e:"ui-button",a:{action:"hw_cpu",params:'{"cpu" : "1"}',state:[{t:2,x:{r:["data.hw_cpu"],s:'_0==1?"selected":null'},p:[52,67,2824]}]},f:["Standard"]}]},{p:[53,6,2893],t:7,e:"td",f:[{p:[53,10,2897],t:7,e:"ui-button",a:{action:"hw_cpu",params:'{"cpu" : "2"}',state:[{t:2,x:{r:["data.hw_cpu"],s:'_0==2?"selected":null'},p:[53,67,2954]}]},f:["Advanced"]}]}]}," ",{p:[55,5,3033],t:7,e:"tr",f:[{p:[56,6,3044],t:7,e:"td",f:[{p:[56,10,3048],t:7,e:"b",f:["Tesla Relay:"]}]},{p:[57,6,3074],t:7,e:"td",f:[{p:[57,10,3078],t:7,e:"ui-button",a:{action:"hw_tesla",params:'{"tesla" : "0"}',state:[{t:2,x:{r:["data.hw_tesla"],s:'_0==0?"selected":null'},p:[57,71,3139]}]},f:["None"]}]},{p:[58,6,3206],t:7,e:"td",f:[{p:[58,10,3210],t:7,e:"ui-button",a:{action:"hw_tesla",params:'{"tesla" : "1"}',state:[{t:2,x:{r:["data.hw_tesla"],s:'_0==1?"selected":null'},p:[58,71,3271]}]},f:["Standard"]}]}]}]}],n:50,x:{r:["data.devtype"],s:"_0!=2"},p:[48,3,2659]}," ",{p:[62,3,3374],t:7,e:"table",f:[{p:[63,4,3386],t:7,e:"tr",f:[{p:[64,5,3396],t:7,e:"td",f:[{p:[64,9,3400],t:7,e:"b",f:["Confirm Order:"]}]},{p:[65,5,3427],t:7,e:"td",f:[{p:[65,9,3431],t:7,e:"ui-button",a:{action:"confirm_order"},f:["CONFIRM"]}]}]}]}," ",{p:[69,2,3512],t:7,e:"hr"}," ",{p:[70,2,3519],t:7,e:"b",f:["Battery"]}," allows your device to operate without external utility power source. Advanced batteries increase battery life.",{p:[70,127,3644],t:7,e:"br"}," ",{p:[71,2,3651],t:7,e:"b",f:["Hard Drive"]}," stores file on your device. Advanced drives can store more files, but use more power, shortening battery life.",{p:[71,130,3779],t:7,e:"br"}," ",{p:[72,2,3786],t:7,e:"b",f:["Network Card"]}," allows your device to wirelessly connect to stationwide NTNet network. Basic cards are limited to on-station use, while advanced cards can operate anywhere near the station, which includes the asteroid outposts.",{p:[72,233,4017],t:7,e:"br"}," ",{p:[73,2,4024],t:7,e:"b",f:["Processor Unit"]}," is critical for your device's functionality. It allows you to run programs from your hard drive. Advanced CPUs use more power, but allow you to run more programs on background at once.",{p:[73,208,4230],t:7,e:"br"}," ",{p:[74,2,4237],t:7,e:"b",f:["Tesla Relay"]}," is an advanced wireless power relay that allows your device to connect to nearby area power controller to provide alternative power source. This component is currently unavailable on tablet computers due to size restrictions.",{p:[74,246,4481],t:7,e:"br"}," ",{p:[75,2,4488],t:7,e:"b",f:["Nano Printer"]}," is device that allows for various paperwork manipulations, such as, scanning of documents or printing new ones. This device was certified EcoFriendlyPlus and is capable of recycling existing paper for printing purposes.",{p:[75,241,4727],t:7,e:"br"}," ",{p:[76,2,4734],t:7,e:"b",f:["Card Reader"]}," adds a slot that allows you to manipulate RFID cards. Please note that this is not necessary to allow the device to read your identification, it is just necessary to manipulate other cards."]}]},{t:4,n:50,x:{r:["data.state"],s:"(!(_0==1))&&(_0==2)"},f:[" ",{p:[79,2,4981],t:7,e:"h2",f:["Step 3: Payment"]}," ",{p:[80,2,5008],t:7,e:"b",f:["Your device is now ready for fabrication.."]},{p:[80,51,5057],t:7,e:"br"}," ",{p:[81,2,5064],t:7,e:"i",f:["Please ensure the required amount of credits are in the machine, then press purchase."]},{p:[81,94,5156],t:7,e:"br"}," ",{p:[82,2,5163],t:7,e:"i",f:["Current credits: ",{p:[82,22,5183],t:7,e:"b",f:[{t:2,r:"data.credits",p:[82,25,5186]},"C"]}]},{p:[82,50,5211],t:7,e:"br"}," ",{p:[83,2,5218],t:7,e:"i",f:["Total price: ",{p:[83,18,5234],t:7,e:"b",f:[{t:2,r:"data.totalprice",p:[83,21,5237]},"C"]}]},{p:[83,49,5265],t:7,e:"br"},{p:[83,53,5269],t:7,e:"br"}," ",{p:[84,2,5276],t:7,e:"ui-button",a:{action:"purchase",state:[{t:2,x:{r:["data.credits","data.totalprice"],s:'_0>=_1?null:"disabled"'},p:[84,38,5312]}]},f:["PURCHASE"]}]},{t:4,n:50,x:{r:["data.state"],s:"(!(_0==1))&&((!(_0==2))&&(_0==3))"},f:[" ",{p:[87,2,5423],t:7,e:"h2",f:["Step 4: Thank you for your purchase"]},{p:[87,46,5467],t:7,e:"br"}," ",{p:[88,2,5474],t:7,e:"b",f:["Should you experience any issues with your new device, contact your local network admin for assistance."]}]}],x:{r:["data.state"],s:"_0==0"}}]},e.exports=a.extend(r.exports)},{205:205}],245:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,1,22],t:7,e:"ui-display",f:[{p:[3,2,37],t:7,e:"ui-section",a:{label:"Cap"},f:[{p:[4,3,65],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.is_capped"],s:'_0?"power-off":"close"'},p:[4,20,82]}],style:[{t:2,x:{r:["data.is_capped"],s:'_0?null:"selected"'},p:[4,71,133]}],action:"toggle_cap"},f:[{t:2,x:{r:["data.is_capped"],s:'_0?"On":"Off"'},p:[6,4,202]}]}]}]}],n:50,r:"data.has_cap",p:[1,1,0]},{p:[10,1,288],t:7,e:"ui-display",f:[{t:4,f:[{p:[14,2,419],t:7,e:"ui-section",f:[{p:[15,3,435],t:7,e:"ui-button",a:{action:"select_colour"},f:["Select New Colour"]}]}],n:50,r:"data.can_change_colour",p:[13,1,386]}]}," ",{p:[19,1,540],t:7,e:"ui-display",a:{title:"Stencil"},f:[{t:4,f:[{p:[21,2,599],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[21,21,618]}]},f:[{t:4,f:[{p:[23,7,655],t:7,e:"ui-button",a:{action:"select_stencil",params:['{"item":"',{t:2,r:"item",p:[23,59,707]},'"}'],style:[{t:2,x:{r:["item","data.selected_stencil"],s:'_0==_1?"selected":null'},p:[24,12,731]}]},f:[{t:2,r:"item",p:[25,4,791]}]}],n:52,r:"items",p:[22,3,632]}]}],n:52,r:"data.drawables",p:[20,3,572]}]}," ",{p:[31,1,874],t:7,e:"ui-display",a:{title:"Text Mode"},f:[{p:[32,2,907],t:7,e:"ui-section",a:{label:"Current Buffer"},f:[{t:2,r:"text_buffer",p:[32,37,942]}]}," ",{p:[34,2,976],t:7,e:"ui-section",f:[{p:[34,14,988],t:7,e:"ui-button",a:{action:"enter_text"},f:["New Text"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],246:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Occupant"},f:[{p:[2,3,33],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[3,3,66],t:7,e:"span",f:[{t:2,x:{r:["data.occupant.name"],s:'_0?_0:"No Occupant"'},p:[3,9,72]}]}]}," ",{t:4,f:[{p:[6,5,189],t:7,e:"ui-section",a:{label:"State"},f:[{p:[7,7,223],t:7,e:"span",a:{"class":[{t:2,r:"data.occupant.statstate",p:[7,20,236]}]},f:[{t:2,r:"data.occupant.stat",p:[7,49,265]}]}]}," ",{p:[9,4,317],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[10,6,356],t:7,e:"span",a:{"class":[{t:2,r:"data.occupant.temperaturestatus",p:[10,19,369]}]},f:[{t:2,r:"data.occupant.bodyTemperature",p:[10,56,406]}," K"]}]}," ",{p:[12,5,472],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[13,7,507],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.occupant.minHealth",p:[13,20,520]}],max:[{t:2,r:"data.occupant.maxHealth",p:[13,54,554]}],value:[{t:2,r:"data.occupant.health",p:[13,90,590]}],state:[{t:2,x:{r:["data.occupant.health"],s:'_0>=0?"good":"average"'},p:[14,16,632]}]},f:[{t:2,r:"data.occupant.health",p:[14,68,684]}]}]}," ",{t:4,f:[{p:[17,7,908],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[17,26,927]}]},f:[{p:[18,9,948],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.occupant.maxHealth",p:[18,30,969]}],value:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[18,66,1005]}],state:"bad"},f:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[18,103,1042]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Respiratory",type:"oxyLoss"},{label:"Toxin",type:"toxLoss"},{label:"Burn",type:"fireLoss"}]'},p:[16,5,742]}],n:50,r:"data.hasOccupant",p:[5,3,159]}]}," ",{p:[23,1,1138],t:7,e:"ui-display",a:{title:"Cell"},f:[{p:[24,3,1167],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[25,5,1199],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isOperating"],s:'_0?"power-off":"close"'},p:[25,22,1216]}],style:[{t:2,x:{r:["data.isOperating"],s:'_0?"selected":null'},p:[26,14,1276]}],state:[{t:2,x:{r:["data.isOpen"],s:'_0?"disabled":null'},p:[27,14,1332]}],action:"power"},f:[{t:2,x:{r:["data.isOperating"],s:'_0?"On":"Off"'},p:[28,22,1391]}]}]}," ",{p:[30,3,1459],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[31,3,1495],t:7,e:"span",a:{"class":[{t:2,r:"data.temperaturestatus",p:[31,16,1508]}]},f:[{t:2,r:"data.cellTemperature",p:[31,44,1536]}," K"]}]}," ",{p:[33,2,1588],t:7,e:"ui-section",a:{label:"Door"},f:[{p:[34,5,1619],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isOpen"],s:'_0?"unlock":"lock"'},p:[34,22,1636]}],action:"door"},f:[{t:2,x:{r:["data.isOpen"],s:'_0?"Open":"Closed"'},p:[34,73,1687]}]}," ",{p:[35,5,1740],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.autoEject"],s:'_0?"sign-out":"sign-in"'},p:[35,22,1757]}],action:"autoeject"},f:[{t:2,x:{r:["data.autoEject"],s:'_0?"Auto":"Manual"'},p:[35,86,1821]}]}]}]}," ",{p:{button:[{p:[40,5,1967],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[40,36,1998]}],action:"ejectbeaker"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{p:[42,3,2101],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{t:4,f:[{p:[45,9,2211],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,r:"volume",p:[45,52,2254]}," units of ",{t:2,r:"name",p:[45,72,2274]}]},{p:[45,87,2289],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[44,7,2171]},{t:4,n:51,f:[{p:[47,9,2320],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[43,5,2136]},{t:4,n:51,f:[{p:[50,7,2396],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],247:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,2,15],t:7,e:"ui-section",a:{label:"State"},f:[{t:4,f:[{p:[4,4,76],t:7,e:"span",a:{"class":"good"},f:["Ready"]}],n:50,r:"data.full_pressure",p:[3,3,45]},{t:4,n:51,f:[{t:4,f:[{p:[7,5,153],t:7,e:"span",a:{"class":"bad"},f:["Power Disabled"]}],n:50,r:"data.panel_open",p:[6,4,124]},{t:4,n:51,f:[{t:4,f:[{p:[10,6,248],t:7,e:"span",a:{"class":"average"},f:["Pressurizing"]}],n:50,r:"data.pressure_charging",p:[9,5,211]},{t:4,n:51,f:[{p:[12,6,310],t:7,e:"span",a:{"class":"bad"},f:["Off"]}],r:"data.pressure_charging"}],r:"data.panel_open"}],r:"data.full_pressure"}]}," ",{p:[17,2,393],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[18,3,426],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.per",p:[18,36,459]}],state:"good"},f:[{t:2,r:"data.per",p:[18,63,486]},"%"]}]}," ",{p:[20,5,530],t:7,e:"ui-section",a:{label:"Handle"},f:[{p:[21,9,567],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.flush"],s:'_0?"toggle-on":"toggle-off"'},p:[22,10,589]}],state:[{t:2,x:{r:["data.isai","data.panel_open"],s:'_0||_1?"disabled":null'},p:[23,11,647]}],action:[{t:2,x:{r:["data.flush"],s:'_0?"handle-0":"handle-1"'},p:[24,12,714]}]},f:[{t:2,x:{r:["data.flush"],s:'_0?"Disengage":"Engage"'},p:[25,5,763]}]}]}," ",{p:[27,2,837],t:7,e:"ui-section",a:{label:"Eject"},f:[{p:[28,3,867],t:7,e:"ui-button",a:{icon:"sign-out",state:[{t:2,x:{r:["data.isai"],s:'_0?"disabled":null'},p:[28,37,901]}],action:"eject"},f:["Eject Contents"]},{p:[28,114,978],t:7,e:"br"}]}," ",{p:[30,2,1002],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[31,3,1032],t:7,e:"ui-button",a:{icon:"power-off",state:[{t:2,x:{r:["data.panel_open"],s:'_0?"disabled":null'},p:[31,38,1067]}],action:[{t:2,x:{r:["data.pressure_charging"],s:'_0?"pump-0":"pump-1"'},p:[31,87,1116]}],style:[{t:2,x:{r:["data.pressure_charging"],s:'_0?"selected":null'},p:[31,145,1174]}]}},{p:[31,206,1235],t:7,e:"br"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],248:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"DNA Vault Database"},f:[{p:[2,3,43],t:7,e:"ui-section",a:{label:"Human DNA"},f:[{p:[3,7,81],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.dna_max",p:[3,28,102]}],value:[{t:2,r:"data.dna",p:[3,53,127]}]},f:[{t:2,r:"data.dna",p:[3,67,141]},"/",{t:2,r:"data.dna_max",p:[3,80,154]}," Samples"]}]}," ",{p:[5,3,208],t:7,e:"ui-section",a:{label:"Plant Data"},f:[{p:[6,5,245],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.plants_max",p:[6,26,266]}],value:[{t:2,r:"data.plants",p:[6,54,294]}]},f:[{t:2,r:"data.plants",p:[6,71,311]},"/",{t:2,r:"data.plants_max",p:[6,87,327]}," Samples"]}]}," ",{p:[8,3,384],t:7,e:"ui-section",a:{label:"Animal Data"},f:[{p:[9,5,422],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.animals_max",p:[9,26,443]}],value:[{t:2,r:"data.animals",p:[9,55,472]}]},f:[{t:2,r:"data.animals",p:[9,73,490]},"/",{t:2,r:"data.animals_max",p:[9,90,507]}," Samples"]}]}]}," ",{t:4,f:[{p:[13,1,616],t:7,e:"ui-display",a:{title:"Personal Gene Therapy"},f:[{p:[14,3,663],t:7,e:"ui-section",f:[{p:[15,2,678],t:7,e:"span",f:["Applicable gene therapy treatments:"]}]}," ",{p:[17,3,747],t:7,e:"ui-section",f:[{p:[18,2,762],t:7,e:"ui-button",a:{action:"gene",params:['{"choice": "',{t:2,r:"data.choiceA",p:[18,47,807]},'"}']},f:[{t:2,r:"data.choiceA",p:[18,67,827]}]}," ",{p:[19,2,858],t:7,e:"ui-button",a:{action:"gene",params:['{"choice": "',{t:2,r:"data.choiceB",p:[19,47,903]},'"}']},f:[{t:2,r:"data.choiceB",p:[19,67,923]}]}]}]}],n:50,x:{r:["data.completed","data.used"],s:"_0&&!_1"},p:[12,1,578]}]},e.exports=a.extend(r.exports)},{205:205}],249:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Occupant"},f:[{p:[2,3,33],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[3,3,66],t:7,e:"span",f:[{t:2,x:{r:["data.occupant.name"],s:'_0?_0:"No Occupant"'},p:[3,9,72]}]}]}," ",{t:4,f:[{p:[6,5,183],t:7,e:"ui-section",a:{label:"Items in storage"},f:[{p:[7,4,225],t:7,e:"span",f:[{t:2,r:"data.items",p:[7,10,231]}]}]}],n:50,r:"data.items",p:[5,3,159]}," ",{t:4,f:[{p:[11,5,310],t:7,e:"ui-section",a:{label:"State"},f:[{p:[12,7,344],t:7,e:"span",a:{"class":[{t:2,r:"data.occupant.statstate",p:[12,20,357]}]},f:[{t:2,r:"data.occupant.stat",p:[12,49,386]}]}]}," ",{p:[14,5,439],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[15,7,474],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.occupant.minHealth",p:[15,20,487]}],max:[{t:2,r:"data.occupant.maxHealth",p:[15,54,521]}],value:[{t:2,r:"data.occupant.health",p:[15,90,557]}],state:[{t:2,x:{r:["data.occupant.health"],s:'_0>=0?"good":"average"'},p:[16,16,599]}]},f:[{t:2,x:{r:["adata.occupant.health"],s:"Math.round(_0)"},p:[16,68,651]}]}]}," ",{t:4,f:[{p:[19,7,888],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[19,26,907]}]},f:[{p:[20,9,928],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.occupant.maxHealth",p:[20,30,949]}],value:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[20,66,985]}],state:"bad"},f:[{t:2,x:{r:["type","adata.occupant"],s:"Math.round(_1[_0])"},p:[20,103,1022]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Respiratory",type:"oxyLoss"},{label:"Toxin",type:"toxLoss"},{label:"Burn",type:"fireLoss"}]'},p:[18,5,722]}," ",{p:[23,5,1109],t:7,e:"ui-section",a:{label:"Cells"},f:[{p:[24,9,1145],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"bad":"good"'},p:[24,22,1158]}]},f:[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"Damaged":"Healthy"'},p:[24,68,1204]}]}]}," ",{p:[26,5,1287],t:7,e:"ui-section",a:{label:"Brain"},f:[{p:[27,9,1323],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"bad":"good"'},p:[27,22,1336]}]},f:[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"Abnormal":"Healthy"'},p:[27,68,1382]}]}]}," ",{p:[29,5,1466],t:7,e:"ui-section",a:{label:"Bloodstream"},f:[{t:4,f:[{p:[31,11,1553],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,1)"},p:[31,54,1596]}," units of ",{t:2,r:"name",p:[31,89,1631]}]},{p:[31,104,1646],t:7,e:"br"}],n:52,r:"adata.occupant.reagents",p:[30,9,1508]},{t:4,n:51,f:[{p:[33,11,1681],t:7,e:"span",a:{"class":"good"},f:["Pure"]}],r:"adata.occupant.reagents"}]}],n:50,r:"data.occupied",p:[10,3,283]}]}," ",{p:[38,1,1777],t:7,e:"ui-display",a:{title:"Operations"},f:[{p:[39,3,1812],t:7,e:"ui-section",a:{label:"Inject"},f:[{t:4,f:[{p:[41,7,1872],t:7,e:"ui-button",a:{icon:"flask",state:[{t:2,x:{r:["data.occupied"],s:'_0?null:"disabled"'},p:[41,38,1903]}],action:"inject",params:['{"chem": "',{t:2,r:"id",p:[41,111,1976]},'"}']},f:[{t:2,r:"name",p:[41,121,1986]}]},{p:[41,141,2006],t:7,e:"br"}],n:52,r:"data.chem",p:[40,5,1845]}]}," ",{p:[44,2,2046],t:7,e:"ui-section",a:{label:"Eject"},f:[{p:[45,6,2079],t:7,e:"ui-button",a:{icon:"sign-out",action:"eject"},f:["Eject Contents"]}]}," ",{p:[47,2,2166],t:7,e:"ui-section",a:{label:"Self Cleaning"},f:[{p:[48,3,2204],t:7,e:"ui-button",a:{icon:"recycle",action:"cleaning"},f:["Self-Clean Cycle"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],250:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,24],t:7,e:"ui-display",a:{title:[{t:2,r:"data.question",p:[2,21,42]}]},f:[{p:[3,5,66],t:7,e:"ui-section",f:[{t:4,f:[{p:[5,9,118],t:7,e:"ui-button",a:{action:"vote",params:['{"answer": "',{t:2,r:"answer",p:[6,45,174]},'"}'],style:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[7,18,206]}]},f:[{t:2,r:"answer",p:[7,53,241]}," (",{t:2,r:"amount",p:[7,65,253]},")"]}],n:52,r:"data.answers",p:[4,7,86]}]}]}],n:50,r:"data.shaking",p:[1,1,0]},{t:4,n:51,f:[{p:[13,3,353],t:7,e:"ui-notice",f:["The eightball is not currently being shaken."]}],r:"data.shaking"}]},e.exports=a.extend(r.exports)},{205:205}],251:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,5,17],t:7,e:"span",f:["Time Until Launch: ",{t:2,r:"data.timer_str",p:[2,30,42]}]}]}," ",{p:[4,1,83],t:7,e:"ui-notice",f:[{p:[5,3,98],t:7,e:"span",f:["Engines: ",{t:2,x:{r:["data.engines_started"],s:'_0?"Online":"Idle"'},p:[5,18,113]}]}]}," ",{p:[7,1,180],t:7,e:"ui-display",a:{title:"Early Launch"},f:[{p:[8,2,216],t:7,e:"span",f:["Authorizations Remaining: ",{t:2,x:{r:["data.emagged","data.authorizations_remaining"],s:'_0?"ERROR":_1'},p:[9,2,250]}]}," ",{p:[10,2,318],t:7,e:"ui-button",a:{icon:"exclamation-triangle",action:"authorize",style:"danger",state:[{t:2,x:{r:["data.enabled"],s:'_0?null:"disabled"'},p:[12,10,404]}]},f:["AUTHORIZE"]}," ",{p:[15,2,473],t:7,e:"ui-button",a:{icon:"minus",action:"repeal",state:[{t:2,x:{r:["data.enabled"],s:'_0?null:"disabled"'},p:[16,10,523]}]},f:["Repeal"]}," ",{p:[19,2,589],t:7,e:"ui-button",a:{icon:"close",action:"abort",state:[{t:2,x:{r:["data.enabled"],s:'_0?null:"disabled"'},p:[20,10,638]}]},f:["Repeal All"]}]}," ",{p:[24,1,722],t:7,e:"ui-display",a:{title:"Authorizations"},f:[{t:4,f:[{p:[26,3,793],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{t:2,r:"name",p:[26,34,824]}," (",{t:2,r:"job",p:[26,44,834]},")"]}],n:52,r:"data.authorizations",p:[25,2,760]},{t:4,n:51,f:[{p:[28,3,870],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:["No authorizations."]}],r:"data.authorizations"}]}]},e.exports=a.extend(r.exports)},{205:205}],252:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-section",a:{label:"Message"},f:[{t:2,r:"data.hidden_message",p:[3,5,50]}]}," ",{p:[5,3,94],t:7,e:"ui-section",a:{label:"Created On"},f:[{t:2,r:"data.realdate",p:[6,5,131] -}]}," ",{p:[8,3,169],t:7,e:"ui-section",a:{label:"Approval"},f:[{p:[9,5,204],t:7,e:"ui-button",a:{icon:"arrow-up",state:[{t:2,x:{r:["data.is_creator","data.has_liked"],s:'_0?"disabled":_1?"selected":null'},p:[11,14,252]}],action:"like"},f:[{t:2,r:"data.num_likes",p:[12,21,344]}]}," ",{p:[13,5,380],t:7,e:"ui-button",a:{icon:"circle",state:[{t:2,x:{r:["data.is_creator","data.has_liked","data.has_disliked"],s:'_0?"disabled":!_1&&!_2?"selected":null'},p:[15,14,426]}],action:"neutral"}}," ",{p:[17,5,562],t:7,e:"ui-button",a:{icon:"arrow-down",state:[{t:2,x:{r:["data.is_creator","data.has_disliked"],s:'_0?"disabled":_1?"selected":null'},p:[19,14,612]}],action:"dislike"},f:[{t:2,r:"data.num_dislikes",p:[20,24,710]}]}]}]}," ",{t:4,f:[{p:[24,3,805],t:7,e:"ui-display",a:{title:"Admin Panel"},f:[{p:[25,5,843],t:7,e:"ui-section",a:{label:"Creator Ckey"},f:[{t:2,r:"data.creator_key",p:[25,38,876]}]}," ",{p:[26,5,915],t:7,e:"ui-section",a:{label:"Creator Character Name"},f:[{t:2,r:"data.creator_name",p:[26,48,958]}]}," ",{p:[27,5,998],t:7,e:"ui-button",a:{icon:"remove",action:"delete",style:"danger"},f:["Delete"]}]}],n:50,r:"data.admin_mode",p:[23,1,778]}]},e.exports=a.extend(r.exports)},{205:205}],253:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,3,15],t:7,e:"span",f:["The requested interface (",{t:2,r:"config.interface",p:[2,34,46]},") was not found. Does it exist?"]}]}]},e.exports=a.extend(r.exports)},{205:205}],254:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,20],t:7,e:"ui-notice",f:["Currently syncing with the database"]}],n:50,r:"data.sync",p:[1,1,0]},{t:4,n:51,f:[{p:{button:[{p:[8,4,163],t:7,e:"ui-button",a:{icon:"eject",action:"eject_all"},f:["Eject all"]}," ",{p:[9,4,232],t:7,e:"ui-button",a:{icon:["toggle-",{t:2,x:{r:["data.show_materials"],s:'_0?"off":"on"'},p:[9,28,256]}],action:"toggle_materials_visibility"},f:[{t:2,x:{r:["data.show_materials"],s:'_0?"Hide":"Show"'},p:[10,5,339]}]}]},t:7,e:"ui-display",a:{title:"Materials",button:0},f:[" ",{t:4,f:[{p:[14,4,449],t:7,e:"div",a:{"class":"display tabular"},f:[{p:[15,5,484],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[16,6,520],t:7,e:"section",a:{"class":"cell"}}," ",{p:[17,6,559],t:7,e:"section",a:{"class":"cell"},f:["Mineral"]}," ",{p:[20,6,620],t:7,e:"section",a:{"class":"cell"},f:["Amount"]}," ",{p:[23,6,680],t:7,e:"section",a:{"class":"cell"}}," ",{p:[24,6,719],t:7,e:"section",a:{"class":"cell"}}]}," ",{t:4,f:[{p:[27,6,808],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[28,7,845],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[29,8,876]}]}," ",{p:[31,7,910],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"amount",p:[32,8,941]}]}," ",{p:[34,7,977],t:7,e:"section",a:{"class":"cell"},f:[{p:[35,8,1008],t:7,e:"ui-button",a:{icon:"eject"},f:["Release amount"]}]}," ",{p:[37,7,1084],t:7,e:"section",a:{"class":"cell",style:"width: 40px;"},f:[{p:[38,8,1136],t:7,e:"ui-button",a:{icon:"eject"},f:["Release all"]}]}]}],n:52,r:"data.all_materials",p:[26,5,773]}]}],n:50,r:"data.show_materials",p:[13,3,417]}]}," ",{p:[45,2,1274],t:7,e:"ui-display",a:{title:"Categories"},f:[{t:4,f:[{p:[47,4,1334],t:7,e:"ui-button",f:[{t:2,r:".",p:[47,15,1345]}]}],r:"data.categories",p:[46,3,1309]}]}],r:"data.sync"}]},e.exports=a.extend(r.exports)},{205:205}],255:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[3,5,49],t:7,e:"ui-button",a:{action:"toggle_power",style:[{t:2,x:{r:["data.toggle"],s:'_0?"selected":null'},p:[5,18,111]}]},f:["Turn ",{t:2,x:{r:["data.toggle"],s:'_0?"off":"on"'},p:[6,16,166]}]}]}," ",{p:[9,3,235],t:7,e:"ui-display",a:{title:"Logging"},f:[{t:4,f:[{p:[11,3,292],t:7,e:"ui-section",a:{label:">"},f:[{t:2,r:".",p:[11,25,314]},{p:[11,30,319],t:7,e:"ui-section",f:[]}]}],n:52,r:"data.logs",p:[10,5,269]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],256:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{seclevelState:function(){switch(this.get("data.seclevel")){case"blue":return"average";case"red":return"bad";case"delta":return"bad bold";default:return"good"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[16,1,323],t:7,e:"ui-display",f:[{p:[17,5,341],t:7,e:"ui-section",a:{label:"Alert Level"},f:[{p:[18,9,383],t:7,e:"span",a:{"class":[{t:2,r:"seclevelState",p:[18,22,396]}]},f:[{t:2,x:{r:["text","data.seclevel"],s:"_0.titleCase(_1)"},p:[18,41,415]}]}]}," ",{p:[20,5,480],t:7,e:"ui-section",a:{label:"Controls"},f:[{p:[21,9,519],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.alarm"],s:'_0?"close":"bell-o"'},p:[21,26,536]}],action:[{t:2,x:{r:["data.alarm"],s:'_0?"reset":"alarm"'},p:[21,71,581]}]},f:[{t:2,x:{r:["data.alarm"],s:'_0?"Reset":"Activate"'},p:[22,13,631]}]}]}," ",{t:4,f:[{p:[25,7,733],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[26,9,771],t:7,e:"span",a:{"class":"bad bold"},f:["Safety measures offline. Device may exhibit abnormal behavior."]}]}],n:50,r:"data.emagged",p:[24,5,705]}]}]},e.exports=a.extend(r.exports)},{205:205}],257:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[2,1,31],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,2,60],t:7,e:"ui-button",a:{icon:"power-off",style:[{t:2,x:{r:["data.power"],s:'_0?"selected":"danger"'},p:[3,37,95]}],action:"power"},f:[{t:2,x:{r:["data.power"],s:'_0?"Enabled":"Disabled"'},p:[3,92,150]}]}]}," ",{p:[5,1,218],t:7,e:"ui-section",a:{label:"Tag"},f:[{p:[6,2,245],t:7,e:"ui-button",a:{icon:"pencil",action:"rename"},f:[{t:2,r:"data.tag",p:[6,43,286]}]}]}," ",{p:[8,1,327],t:7,e:"ui-section",a:{label:"Scanning mode"},f:[{p:[9,2,364],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.updating"],s:'_0?"unlock":"lock"'},p:[9,18,380]}],style:[{t:2,x:{r:["data.updating"],s:'_0?null:"danger"'},p:[9,63,425]}],action:"updating",tooltip:"Toggle between automatic scanning or scan only when a button is pressed.","tooltip-side":"right"},f:[{t:2,x:{r:["data.updating"],s:'_0?"AUTO":"MANUAL"'},p:[9,221,583]}]}]}," ",{p:[11,1,649],t:7,e:"ui-section",a:{label:"Detection range"},f:[{p:[12,2,688],t:7,e:"ui-button",a:{icon:"refresh",style:[{t:2,x:{r:["data.globalmode"],s:'_0?null:"selected"'},p:[12,35,721]}],action:"globalmode",tooltip:"Local sector or whole region scanning.","tooltip-side":"right"},f:[{t:2,x:{r:["data.globalmode"],s:'_0?"MAXIMUM":"LOCAL"'},p:[12,165,851]}]}]}]}," ",{t:4,f:[{p:[16,2,957],t:7,e:"ui-display",a:{title:"Current Location"},f:[{p:[17,3,998],t:7,e:"span",f:[{t:2,r:"data.current",p:[17,9,1004]}]}]}," ",{p:[20,2,1048],t:7,e:"ui-display",a:{title:"Detected Signals"},f:[{t:4,f:[{p:[22,3,1114],t:7,e:"ui-section",a:{label:[{t:2,r:"entrytag",p:[22,21,1132]}]},f:[{p:[23,3,1149],t:7,e:"span",f:[{t:2,r:"area",p:[23,9,1155]}," (",{t:2,r:"coord",p:[23,19,1165]},")"]}," ",{t:4,f:[{p:[25,4,1209],t:7,e:"span",f:["Dist: ",{t:2,r:"dist",p:[25,16,1221]},"m Dir: ",{t:2,r:"degrees",p:[25,31,1236]},"° (",{t:2,r:"direction",p:[25,45,1250]},")"]}],n:50,r:"direction",p:[24,3,1187]}]}],n:52,r:"data.signals",p:[21,2,1088]}]}],n:50,r:"data.power",p:[15,1,936]}]},e.exports=a.extend(r.exports)},{205:205}],258:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Labor Camp Teleporter"},f:[{p:[2,2,45],t:7,e:"ui-section",a:{label:"Teleporter Status"},f:[{p:[3,3,87],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.teleporter"],s:'_0?"good":"bad"'},p:[3,16,100]}]},f:[{t:2,x:{r:["data.teleporter"],s:'_0?"Connected":"Not connected"'},p:[3,54,138]}]}]}," ",{t:4,f:[{p:[6,4,244],t:7,e:"ui-section",a:{label:"Location"},f:[{p:[7,5,279],t:7,e:"span",f:[{t:2,r:"data.teleporter_location",p:[7,11,285]}]}]}," ",{p:[9,4,343],t:7,e:"ui-section",a:{label:"Locked status"},f:[{p:[10,5,383],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.teleporter_lock"],s:'_0?"lock":"unlock"'},p:[10,22,400]}],action:"teleporter_lock"},f:[{t:2,x:{r:["data.teleporter_lock"],s:'_0?"Locked":"Unlocked"'},p:[10,93,471]}]}," ",{p:[11,5,537],t:7,e:"ui-button",a:{action:"toggle_open"},f:[{t:2,x:{r:["data.teleporter_state_open"],s:'_0?"Open":"Closed"'},p:[11,37,569]}]}]}],n:50,r:"data.teleporter",p:[5,3,216]},{t:4,n:51,f:[{p:[14,4,666],t:7,e:"span",f:[{p:[14,10,672],t:7,e:"ui-button",a:{action:"scan_teleporter"},f:["Scan Teleporter"]}]}],r:"data.teleporter"}]}," ",{p:[17,1,770],t:7,e:"ui-display",a:{title:"Labor Camp Beacon"},f:[{p:[18,2,811],t:7,e:"ui-section",a:{label:"Beacon Status"},f:[{p:[19,3,849],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.beacon"],s:'_0?"good":"bad"'},p:[19,16,862]}]},f:[{t:2,x:{r:["data.beacon"],s:'_0?"Connected":"Not connected"'},p:[19,50,896]}]}]}," ",{t:4,f:[{p:[22,3,992],t:7,e:"ui-section",a:{label:"Location"},f:[{p:[23,4,1026],t:7,e:"span",f:[{t:2,r:"data.beacon_location",p:[23,10,1032]}]}]}],n:50,r:"data.beacon",p:[21,2,969]},{t:4,n:51,f:[{p:[26,4,1097],t:7,e:"span",f:[{p:[26,10,1103],t:7,e:"ui-button",a:{action:"scan_beacon"},f:["Scan Beacon"]}]}],r:"data.beacon"}]}," ",{p:[29,1,1193],t:7,e:"ui-display",a:{title:"Prisoner details"},f:[{p:[30,2,1233],t:7,e:"ui-section",a:{label:"Prisoner ID"},f:[{p:[31,3,1269],t:7,e:"ui-button",a:{action:"handle_id"},f:[{t:2,x:{r:["data.id","data.id_name"],s:'_0?_1:"-------------"'},p:[31,33,1299]}]}]}," ",{t:4,f:[{p:[34,2,1392],t:7,e:"ui-section",a:{label:"Set ID goal"},f:[{p:[35,4,1429],t:7,e:"ui-button",a:{action:"set_goal"},f:[{t:2,r:"data.goal",p:[35,33,1458]}]}]}],n:50,r:"data.id",p:[33,2,1374]}," ",{p:[38,2,1512],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[39,3,1545],t:7,e:"span",f:[{t:2,x:{r:["data.prisoner.name"],s:'_0?_0:"No Occupant"'},p:[39,9,1551]}]}]}," ",{t:4,f:[{p:[42,3,1661],t:7,e:"ui-section",a:{label:"Criminal Status"},f:[{p:[43,4,1702],t:7,e:"span",f:[{t:2,r:"data.prisoner.crimstat",p:[43,10,1708]}]}]}],n:50,r:"data.prisoner",p:[41,2,1636]}]}," ",{p:[47,1,1785],t:7,e:"ui-display",f:[{p:[48,2,1800],t:7,e:"center",f:[{p:[48,10,1808],t:7,e:"ui-button",a:{action:"teleport",state:[{t:2,x:{r:["data.can_teleport"],s:'_0?null:"disabled"'},p:[48,45,1843]}]},f:["Process Prisoner"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],259:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,2,15],t:7,e:"center",f:[{p:[2,10,23],t:7,e:"ui-button",a:{action:"handle_id"},f:[{t:2,x:{r:["data.id","data.id_name"],s:'_0?_1:"-------------"'},p:[2,40,53]}]}]}]}," ",{p:[4,1,135],t:7,e:"ui-display",a:{title:"Stored Items"},f:[{t:4,f:[{p:[6,3,194],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[6,22,213]}]},f:[{p:[7,4,228],t:7,e:"ui-button",a:{action:"release_items",params:['{"mobref":',{t:2,r:"mob",p:[7,56,280]},"}"],state:[{t:2,x:{r:["data.can_reclaim"],s:'_0?null:"disabled"'},p:[7,72,296]}]},f:["Drop Items"]}]}],n:52,r:"data.mobs",p:[5,2,171]}]}]},e.exports=a.extend(r.exports)},{205:205}],260:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{p:[3,3,70],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.emagged"],s:'_0?"un":null'},p:[3,20,87]},"lock"],state:[{t:2,x:{r:["data.can_toggle_safety"],s:'_0?null:"disabled"'},p:[3,63,130]}],action:"safety"},f:["Safeties: ",{p:[4,14,209],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.emagged"],s:'_0?"bad":"good"'},p:[4,27,222]}]},f:[{t:2,x:{r:["data.emagged"],s:'_0?"OFF":"ON"'},p:[4,62,257]}]}]}]},t:7,e:"ui-display",a:{title:"Default Programs",button:0},f:[" ",{t:4,f:[{p:[8,2,363],t:7,e:"ui-button",a:{action:"load_program",params:['{"type": ',{t:2,r:"type",p:[8,52,413]},"}"],style:[{t:2,x:{r:["data.program","type"],s:'_0==_1?"selected":null'},p:[8,70,431]}]},f:[{t:2,r:"name",p:[9,5,483]}," "]},{p:[10,14,506],t:7,e:"br"}],n:52,r:"data.default_programs",p:[7,2,329]}]}," ",{t:4,f:[{p:[14,2,562],t:7,e:"ui-display",a:{title:"Dangerous Programs"},f:[{t:4,f:[{p:[16,4,638],t:7,e:"ui-button",a:{icon:"warning",action:"load_program",params:['{"type": ',{t:2,r:"type",p:[16,69,703]},"}"],style:[{t:2,x:{r:["data.program","type"],s:'_0==_1?"selected":null'},p:[16,87,721]}]},f:[{t:2,r:"name",p:[17,5,773]}," "]},{p:[18,16,798],t:7,e:"br"}],n:52,r:"data.emag_programs",p:[15,3,605]}]}],n:50,r:"data.emagged",p:[13,1,539]}]},e.exports=a.extend(r.exports)},{205:205}],261:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{occupantStatState:function(){switch(this.get("data.occupant.stat")){case 0:return"good";case 1:return"average";default:return"bad"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[15,1,280],t:7,e:"ui-display",a:{title:"Occupant"},f:[{p:[16,3,313],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[17,3,346],t:7,e:"span",f:[{t:2,x:{r:["data.occupant.name"],s:'_0?_0:"No Occupant"'},p:[17,9,352]}]}]}," ",{t:4,f:[{p:[20,5,466],t:7,e:"ui-section",a:{label:"State"},f:[{p:[21,7,500],t:7,e:"span",a:{"class":[{t:2,r:"occupantStatState",p:[21,20,513]}]},f:[{t:2,x:{r:["data.occupant.stat"],s:'_0==0?"Conscious":_0==1?"Unconcious":"Dead"'},p:[21,43,536]}]}]}],n:50,r:"data.occupied",p:[19,3,439]}]}," ",{p:[25,1,680],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[26,2,712],t:7,e:"ui-section",a:{label:"Door"},f:[{p:[27,5,743],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.open"],s:'_0?"unlock":"lock"'},p:[27,22,760]}],action:"door"},f:[{t:2,x:{r:["data.open"],s:'_0?"Open":"Closed"'},p:[27,71,809]}]}]}," ",{p:[29,3,874],t:7,e:"ui-section",a:{label:"Uses"},f:[{t:2,r:"data.ready_implants",p:[30,5,905]}," ",{t:4,f:[{p:[32,7,969],t:7,e:"span",a:{"class":"fa fa-cog fa-spin"}}],n:50,r:"data.replenishing",p:[31,5,936]}]}," ",{p:[35,3,1036],t:7,e:"ui-section",a:{label:"Activate"},f:[{p:[36,7,1073],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.occupied","data.ready_implants","data.ready"],s:'_0&&_1>0&&_2?null:"disabled"'},p:[36,25,1091]}],action:"implant"},f:[{t:2,x:{r:["data.ready","data.special_name"],s:'_0?(_1?_1:"Implant"):"Recharging"'},p:[37,9,1198]}," "]},{p:[38,19,1302],t:7,e:"br"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],262:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{healthState:function(){var t=this.get("data.health");return t>70?"good":t>50?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[15,3,296],t:7,e:"ui-notice",f:[{p:[16,5,313],t:7,e:"span",f:["Wipe in progress!"]}]}],n:50,r:"data.wiping",p:[14,1,273]},{p:{button:[{t:4,f:[{p:[22,7,479],t:7,e:"ui-button",a:{icon:"trash",state:[{t:2,x:{r:["data.isDead"],s:'_0?"disabled":null'},p:[22,38,510]}],action:"wipe"},f:[{t:2,x:{r:["data.wiping"],s:'_0?"Stop Wiping":"Wipe"'},p:[22,89,561]}," AI"]}],n:50,r:"data.name",p:[21,5,454]}]},t:7,e:"ui-display",a:{title:[{t:2,x:{r:["data.name"],s:'_0||"Empty Card"'},p:[19,19,388]}],button:0},f:[" ",{t:4,f:[{p:[26,5,672],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[27,9,709],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.isDead","data.isBraindead"],s:'_0||_1?"bad":"good"'},p:[27,22,722]}]},f:[{t:2,x:{r:["data.isDead","data.isBraindead"],s:'_0||_1?"Offline":"Operational"'},p:[27,76,776]}]}]}," ",{p:[29,5,871],t:7,e:"ui-section",a:{label:"Software Integrity"},f:[{p:[30,7,918],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.health",p:[30,40,951]}],state:[{t:2,r:"healthState",p:[30,64,975]}]},f:[{t:2,x:{r:["adata.health"],s:"Math.round(_0)"},p:[30,81,992]},"%"]}]}," ",{p:[32,5,1055],t:7,e:"ui-section",a:{label:"Laws"},f:[{t:4,f:[{p:[34,9,1117],t:7,e:"span",a:{"class":"highlight"},f:[{t:2,r:".",p:[34,33,1141]}]},{p:[34,45,1153],t:7,e:"br"}],n:52,r:"data.laws",p:[33,7,1088]}]}," ",{p:[37,5,1200],t:7,e:"ui-section",a:{label:"Settings"},f:[{p:[38,7,1237],t:7,e:"ui-button",a:{icon:"signal",style:[{t:2,x:{r:["data.wireless"],s:'_0?"selected":null'},p:[38,39,1269]}],action:"wireless"},f:["Wireless Activity"]}," ",{p:[39,7,1363],t:7,e:"ui-button",a:{icon:"microphone",style:[{t:2,x:{r:["data.radio"],s:'_0?"selected":null'},p:[39,43,1399]}],action:"radio"},f:["Subspace Radio"]}]}],n:50,r:"data.name",p:[25,3,649]}]}]},e.exports=a.extend(r.exports)},{205:205}],263:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,23],t:7,e:"ui-notice",f:[{p:[3,3,38],t:7,e:"span",f:["Waiting for another device to confirm your request..."]}]}],n:50,r:"data.waiting",p:[1,1,0]},{t:4,n:51,f:[{p:[6,2,132],t:7,e:"ui-display",f:[{p:[7,3,148],t:7,e:"ui-section",f:[{t:4,f:[{p:[9,5,197],t:7,e:"ui-button",a:{icon:"check",action:"auth_swipe"},f:["Authorize ",{t:2,r:"data.auth_required",p:[9,59,251]}]}],n:50,r:"data.auth_required",p:[8,4,165]},{t:4,n:51,f:[{p:[11,5,304],t:7,e:"ui-button",a:{icon:"warning",state:[{t:2,x:{r:["data.red_alert"],s:'_0?"disabled":null'},p:[11,38,337]}],action:"red_alert"},f:["Red Alert"]}," ",{p:[12,5,423],t:7,e:"ui-button",a:{icon:"wrench",state:[{t:2,x:{r:["data.emergency_maint"],s:'_0?"disabled":null'},p:[12,37,455]}],action:"emergency_maint"},f:["Emergency Maintenance Access"]}," ",{p:[13,5,572],t:7,e:"ui-button",a:{icon:"warning",state:"null",action:"bsa_unlock"},f:["Bluespace Artillery Unlock"]}],r:"data.auth_required"}]}]}],r:"data.waiting"}]},e.exports=a.extend(r.exports)},{205:205}],264:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Ore values"},f:[{t:4,f:[{p:[3,3,57],t:7,e:"ui-section",a:{label:[{t:2,r:"ore",p:[3,22,76]}]},f:[{p:[4,4,90],t:7,e:"span",f:[{t:2,r:"value",p:[4,10,96]}]}]}],n:52,r:"data.ores",p:[2,2,34]}]}," ",{p:[8,1,158],t:7,e:"ui-display",a:{title:"Points"},f:[{p:[9,2,188],t:7,e:"ui-section",a:{label:"ID"},f:[{p:[10,3,215],t:7,e:"ui-button",a:{action:"handle_id"},f:[{t:2,x:{r:["data.id","data.id_name"],s:'_0?_1:"-------------"'},p:[10,33,245]}]}]}," ",{t:4,f:[{p:[13,3,339],t:7,e:"ui-section",a:{label:"Points collected"},f:[{p:[14,4,381],t:7,e:"span",f:[{t:2,r:"data.points",p:[14,10,387]}]}]}," ",{p:[16,3,430],t:7,e:"ui-section",a:{label:"Goal"},f:[{p:[17,4,460],t:7,e:"span",f:[{t:2,r:"data.goal",p:[17,10,466]}]}]}," ",{p:[19,3,507],t:7,e:"ui-section",a:{label:"Unclaimed points"},f:[{p:[20,4,549],t:7,e:"span",f:[{t:2,r:"data.unclaimed_points",p:[20,10,555]}]}," ",{p:[21,4,592],t:7,e:"ui-button",a:{action:"claim_points",state:[{t:2,x:{r:["data.unclaimed_points"],s:'_0?null:"disabled"'},p:[21,43,631]}]},f:["Claim points"]}]}],n:50,r:"data.id",p:[12,2,320]}]}," ",{p:[25,1,745],t:7,e:"ui-display",f:[{p:[26,2,760],t:7,e:"center",f:[{p:[27,3,772],t:7,e:"ui-button",a:{action:"move_shuttle",state:[{t:2,x:{r:["data.can_go_home"],s:'_0?null:"disabled"'},p:[27,42,811]}]},f:["Move shuttle"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],265:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Known Languages"},f:[{t:4,f:[{p:[3,5,70],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[3,23,88]}]},f:[{p:[4,7,105],t:7,e:"span",f:[{t:2,r:"desc",p:[4,13,111]}]}," ",{p:[5,7,134],t:7,e:"span",f:["Key: ,",{t:2,r:"key",p:[5,19,146]}]}," ",{t:4,f:[{p:[7,9,192],t:7,e:"span",f:["(gained from mob)"]}],n:50,r:"shadow",p:[6,7,168]}," ",{p:[9,7,245],t:7,e:"span",f:[{t:2,x:{r:["can_speak"],s:'_0?"Can Speak":"Cannot Speak"'},p:[9,13,251]}]}," ",{t:4,f:[{p:[11,9,342],t:7,e:"ui-button",a:{action:"select_default",params:['{"language_name":"',{t:2,r:"name",p:[13,37,425]},'"}'],style:[{t:2,x:{r:["is_default","can_speak"],s:'_0?"selected":_1?null:"disabled"'},p:[14,18,455]}]},f:[{t:2,x:{r:["is_default"],s:'_0?"Default Language":"Select as Default"'},p:[15,10,526]}]}],n:50,r:"data.is_living",p:[10,7,310]}," ",{t:4,f:[{t:4,f:[{p:[20,11,685],t:7,e:"ui-button",a:{action:"grant_language",params:['{"language_name":"',{t:2,r:"name",p:[20,72,746]},'"}']},f:["Grant"]}],n:50,r:"shadow",p:[19,9,659]},{t:4,n:51,f:[{p:[22,11,805],t:7,e:"ui-button",a:{action:"remove_language",params:['{"language_name":"',{t:2,r:"name",p:[22,73,867]},'"}']},f:["Remove"]}],r:"shadow"}],n:50,r:"data.admin_mode",p:[18,7,626]}]}],n:52,r:"data.languages",p:[2,3,40]}]}," ",{t:4,f:[{t:4,f:[{p:[30,5,1033],t:7,e:"ui-button",a:{action:"toggle_omnitongue",style:[{t:2,x:{r:["data.omnitongue"],s:'_0?"selected":null'},p:[32,14,1092]}]},f:["Omnitongue ",{t:2,x:{r:["data.omnitongue"],s:'_0?"Enabled":"Disabled"'},p:[33,19,1152]}]}],n:50,r:"data.is_living",p:[29,3,1005]}," ",{p:[36,3,1231],t:7,e:"ui-display",a:{title:"Unknown Languages"},f:[{t:4,f:[{p:[38,7,1315],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[38,25,1333]}]},f:[{p:[39,9,1352],t:7,e:"span",f:[{t:2,r:"desc",p:[39,15,1358]}]}," ",{p:[40,9,1383],t:7,e:"span",f:["Key: ,",{t:2,r:"key",p:[40,21,1395]}]}," ",{p:[41,9,1419],t:7,e:"ui-button",a:{action:"grant_language",params:['{"language_name":"',{t:2,r:"name",p:[43,37,1502]},'"}']},f:["Grant"]}]}],n:52,r:"data.unknown_languages",p:[37,5,1275]}]}],n:50,r:"data.admin_mode",p:[28,1,978]}]},e.exports=a.extend(r.exports)},{205:205}],266:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Controls"},f:[{t:4,f:[{t:4,f:[{p:[4,4,84],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[5,5,118],t:7,e:"span",f:["Launchpad closed."]}]}],n:50,r:"data.pad_closed",p:[3,3,56]},{t:4,n:51,f:[{p:[8,4,183],t:7,e:"ui-section",a:{label:"Launchpad"},f:[{p:[9,4,218],t:7,e:"span",f:[{p:[9,10,224],t:7,e:"b",f:[{t:2,r:"data.pad_name",p:[9,13,227]}]}]},{p:[9,41,255],t:7,e:"br"}," ",{p:[10,4,264],t:7,e:"ui-button",a:{icon:"pencil",action:"rename"},f:["Rename"]}," ",{p:[11,4,328],t:7,e:"ui-button",a:{icon:"remove",style:"danger",action:"remove"},f:["Remove"]}]}," ",{p:[14,4,427],t:7,e:"ui-section",a:{label:"Set Target"},f:[{p:[15,4,463],t:7,e:"table",f:[{p:[16,4,475],t:7,e:"tr",f:[{p:[17,5,485],t:7,e:"td",a:{style:"width:25px!important"},f:[{p:[17,38,518],t:7,e:"ui-button",a:{action:"up-left"},f:["↖"]}]}," ",{p:[18,5,570],t:7,e:"td",a:{style:"width:25px!important; text-align:center"},f:[{p:[18,57,622],t:7,e:"ui-button",a:{action:"up"},f:["↑"]}]}," ",{p:[19,5,669],t:7,e:"td",a:{style:"width:25px!important; text-align:right"},f:[{p:[19,56,720],t:7,e:"ui-button",a:{action:"up-right"},f:["↗"]}]}]}," ",{p:[21,4,782],t:7,e:"tr",f:[{p:[22,5,792],t:7,e:"td",a:{style:"width:25px!important"},f:[{p:[22,38,825],t:7,e:"ui-button",a:{action:"left",style:"width:35px!important"},f:["←"]}]}," ",{p:[23,5,903],t:7,e:"td",a:{style:"width:25px!important; text-align:center"},f:[{p:[23,57,955],t:7,e:"ui-button",a:{action:"reset"},f:["R"]}]}," ",{p:[24,5,1005],t:7,e:"td",a:{style:"width:25px!important; text-align:right"},f:[{p:[24,56,1056],t:7,e:"ui-button",a:{action:"right"},f:["→"]}]}]}," ",{p:[26,4,1115],t:7,e:"tr",f:[{p:[27,5,1125],t:7,e:"td",a:{style:"width:25px!important"},f:[{p:[27,38,1158],t:7,e:"ui-button",a:{action:"down-left"},f:["↙"]}]}," ",{p:[28,5,1212],t:7,e:"td",a:{style:"width:25px!important; text-align:center"},f:[{p:[28,57,1264],t:7,e:"ui-button",a:{action:"down"},f:["↓"]}]}," ",{p:[29,5,1313],t:7,e:"td",a:{style:"width:25px!important; text-align:right"},f:[{p:[29,56,1364],t:7,e:"ui-button",a:{action:"down-right"},f:["↘"]}]}]}]}]}," ",{p:[33,4,1459],t:7,e:"ui-section",a:{label:"Current Target"},f:[{p:[34,5,1500],t:7,e:"span",f:[{t:2,r:"data.abs_y",p:[34,11,1506]}," ",{t:2,r:"data.north_south",p:[34,26,1521]}]},{p:[34,53,1548],t:7,e:"br"}," ",{p:[35,5,1558],t:7,e:"span",f:[{t:2,r:"data.abs_x",p:[35,11,1564]}," ",{t:2,r:"data.east_west",p:[35,26,1579]}]}]}," ",{p:[37,4,1627],t:7,e:"ui-section",a:{label:"Activate"},f:[{p:[38,5,1662],t:7,e:"ui-button",a:{action:"launch",tooltip:"Teleport everything on the pad to the target.","tooltip-side":"down"},f:["Launch"]}," ",{p:[39,5,1789],t:7,e:"ui-button",a:{action:"pull",tooltip:"Teleport everything from the target to the pad.","tooltip-side":"down"},f:["Pull"]}]}],r:"data.pad_closed"}],n:50,r:"data.has_pad",p:[2,2,32]},{t:4,n:51,f:[{p:[45,3,1956],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[46,4,1989],t:7,e:"span",f:["No launchpad found. Link the remote to a launchpad."]}]}],r:"data.has_pad"}]}]},e.exports=a.extend(r.exports)},{205:205}],267:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{mechChargeState:function(t){var e=this.get("data.recharge_port.mech.cell.maxcharge");return t>=e/1.5?"good":t>=e/3?"average":"bad"},mechHealthState:function(t){var e=this.get("data.recharge_port.mech.maxhealth");return t>e/1.5?"good":t>e/3?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[20,1,545],t:7,e:"ui-display",a:{title:"Mech Status"},f:[{t:4,f:[{t:4,f:[{p:[23,4,646],t:7,e:"ui-section",a:{label:"Integrity"},f:[{p:[24,6,683],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.recharge_port.mech.maxhealth",p:[24,27,704]}],value:[{t:2,r:"adata.recharge_port.mech.health",p:[24,74,751]}],state:[{t:2,x:{r:["mechHealthState","adata.recharge_port.mech.health"],s:"_0(_1)"},p:[24,117,794]}]},f:[{t:2,x:{r:["adata.recharge_port.mech.health"],s:"Math.round(_0)"},p:[24,171,848]},"/",{t:2,r:"adata.recharge_port.mech.maxhealth",p:[24,219,896]}]}]}," ",{t:4,f:[{t:4,f:[{p:[28,5,1061],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[28,31,1087],t:7,e:"span",a:{"class":"bad"},f:["Cell Critical Failure"]}]}],n:50,r:"data.recharge_port.mech.cell.critfail",p:[27,3,1010]},{t:4,n:51,f:[{p:[30,11,1170],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[31,13,1210],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.recharge_port.mech.cell.maxcharge",p:[31,34,1231]}],value:[{t:2,r:"adata.recharge_port.mech.cell.charge",p:[31,86,1283]}],state:[{t:2,x:{r:["mechChargeState","adata.recharge_port.mech.cell.charge"],s:"_0(_1)"},p:[31,134,1331]}]},f:[{t:2,x:{r:["adata.recharge_port.mech.cell.charge"],s:"Math.round(_0)"},p:[31,193,1390]},"/",{t:2,x:{r:["adata.recharge_port.mech.cell.maxcharge"],s:"Math.round(_0)"},p:[31,246,1443]}]}]}],r:"data.recharge_port.mech.cell.critfail"}],n:50,r:"data.recharge_port.mech.cell",p:[26,4,970]},{t:4,n:51,f:[{p:[35,3,1558],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[35,29,1584],t:7,e:"span",a:{"class":"bad"},f:["Cell Missing"]}]}],r:"data.recharge_port.mech.cell"}],n:50,r:"data.recharge_port.mech",p:[22,2,610]},{t:4,n:51,f:[{p:[38,4,1662],t:7,e:"ui-section",f:["Mech Not Found"]}],r:"data.recharge_port.mech"}],n:50,r:"data.recharge_port",p:[21,3,581]},{t:4,n:51,f:[{p:[41,5,1729],t:7,e:"ui-section",f:["Recharging Port Not Found"]}," ",{p:[42,2,1782],t:7,e:"ui-button",a:{icon:"refresh",action:"reconnect"},f:["Reconnect"]}],r:"data.recharge_port"}]}]},e.exports=a.extend(r.exports)},{205:205}],268:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{t:4,f:[{p:[3,5,45],t:7,e:"ui-section",a:{label:"Interface Lock"},f:[{p:[4,7,88],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"lock":"unlock"'},p:[4,24,105]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Engaged":"Disengaged"'},p:[4,75,156]}]}]}],n:50,r:"data.siliconUser",p:[2,3,15]},{t:4,n:51,f:[{p:[7,5,247],t:7,e:"span",f:["Swipe an ID card to ",{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[7,31,273]}," this interface."]}],r:"data.siliconUser"}]}," ",{p:[10,1,358],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[11,3,389],t:7,e:"ui-section",a:{label:"Power"},f:[{t:4,f:[{p:[13,7,470],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[13,24,487]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[13,68,531]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[13,116,579]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"},p:[12,5,421]},{t:4,n:51,f:[{p:[15,7,639],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.on"],s:'_0?"good":"bad"'},p:[15,20,652]}],state:[{t:2,x:{r:["data.cell"],s:'_0?null:"disabled"'},p:[15,57,689]}]},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[15,92,724]}]}],x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"}}]}," ",{p:[18,3,791],t:7,e:"ui-section",a:{label:"Cell"},f:[{p:[19,5,822],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.cell"],s:'_0?null:"bad"'},p:[19,18,835]}]},f:[{t:2,x:{r:["data.cell","data.cellPercent"],s:'_0?_1+"%":"No Cell"'},p:[19,48,865]}]}]}," ",{p:[21,3,943],t:7,e:"ui-section",a:{label:"Mode"},f:[{p:[22,5,974],t:7,e:"span",a:{"class":[{t:2,r:"data.modeStatus",p:[22,18,987]}]},f:[{t:2,r:"data.mode",p:[22,39,1008]}]}]}," ",{p:[24,3,1049],t:7,e:"ui-section",a:{label:"Load"},f:[{p:[25,5,1080],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.load"],s:'_0?"good":"average"'},p:[25,18,1093]}]},f:[{t:2,x:{r:["data.load"],s:'_0?_0:"None"'},p:[25,54,1129]}]}]}," ",{p:[27,3,1191],t:7,e:"ui-section",a:{label:"Destination"},f:[{p:[28,5,1229],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.destination"],s:'_0?"good":"average"'},p:[28,18,1242]}]},f:[{t:2,x:{r:["data.destination"],s:'_0?_0:"None"'},p:[28,60,1284]}]}]}]}," ",{t:4,f:[{p:{button:[{t:4,f:[{p:[35,9,1513],t:7,e:"ui-button",a:{icon:"eject",action:"unload"},f:["Unload"]}],n:50,r:"data.load",p:[34,7,1486]}," ",{t:4,f:[{p:[38,9,1623],t:7,e:"ui-button",a:{icon:"eject",action:"ejectpai"},f:["Eject PAI"]}],n:50,r:"data.haspai",p:[37,7,1594]}," ",{p:[40,7,1709],t:7,e:"ui-button",a:{icon:"pencil",action:"setid"},f:["Set ID"]}]},t:7,e:"ui-display",a:{title:"Controls",button:0},f:[" ",{p:[42,5,1791],t:7,e:"ui-section",a:{label:"Destination"},f:[{p:[43,7,1831],t:7,e:"ui-button",a:{icon:"pencil",action:"destination"},f:["Set Destination"]}," ",{p:[44,7,1912],t:7,e:"ui-button",a:{icon:"stop",action:"stop"},f:["Stop"]}," ",{p:[45,7,1973],t:7,e:"ui-button",a:{icon:"play",action:"go"},f:["Go"]}]}," ",{p:[47,5,2047],t:7,e:"ui-section",a:{label:"Home"},f:[{p:[48,7,2080],t:7,e:"ui-button",a:{icon:"home",action:"home"},f:["Go Home"]}," ",{p:[49,7,2144],t:7,e:"ui-button",a:{icon:"pencil",action:"sethome"},f:["Set Home"]}]}," ",{p:[51,5,2231],t:7,e:"ui-section",a:{label:"Settings"},f:[{p:[52,7,2268],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.autoReturn"],s:'_0?"check-square-o":"square-o"'},p:[52,24,2285]}],style:[{t:2,x:{r:["data.autoReturn"],s:'_0?"selected":null'},p:[52,84,2345]}],action:"autoret"},f:["Auto-Return Home"]}," ",{p:[54,7,2449],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.autoPickup"],s:'_0?"check-square-o":"square-o"'},p:[54,24,2466]}],style:[{t:2,x:{r:["data.autoPickup"],s:'_0?"selected":null'},p:[54,84,2526]}],action:"autopick"},f:["Auto-Pickup Crate"]}," ",{p:[56,7,2632],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.reportDelivery"],s:'_0?"check-square-o":"square-o"'},p:[56,24,2649]}],style:[{t:2,x:{r:["data.reportDelivery"],s:'_0?"selected":null'},p:[56,88,2713]}],action:"report"},f:["Report Deliveries"]}]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"},p:[31,1,1373]}]},e.exports=a.extend(r.exports)},{205:205}],269:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Relay"},f:[{t:4,f:[{p:[3,3,57],t:7,e:"h2",f:["NETWORK BUFFERS OVERLOADED"]}," ",{p:[4,3,96],t:7,e:"h3",f:["Overload Recovery Mode"]}," ",{p:[5,3,131],t:7,e:"i",f:["This system is suffering temporary outage due to overflow of traffic buffers. Until buffered traffic is processed, all further requests will be dropped. Frequent occurences of this error may indicate insufficient hardware capacity of your network. Please contact your network planning department for instructions on how to resolve this issue."]}," ",{p:[6,3,484],t:7,e:"h3",f:["ADMINISTRATIVE OVERRIDE"]}," ",{p:[7,3,520],t:7,e:"b",f:["CAUTION - Data loss may occur"]}," ",{p:[8,3,562],t:7,e:"ui-button",a:{icon:"signal",action:"restart"},f:["Purge buffered traffic"]}],n:50,r:"data.dos_crashed",p:[2,2,29]},{t:4,n:51,f:[{p:[12,3,663],t:7,e:"ui-section",a:{label:"Relay status"},f:[{p:[13,4,701],t:7,e:"ui-button",a:{icon:"power-off",action:"toggle"},f:[{t:2,x:{r:["data.enabled"],s:'_0?"ENABLED":"DISABLED"'},p:[14,6,752]}]}]}," ",{p:[18,3,836],t:7,e:"ui-section",a:{label:"Network buffer status"},f:[{t:2,r:"data.dos_overload",p:[19,4,883]}," / ",{t:2,r:"data.dos_capacity",p:[19,28,907]}," GQ"]}],r:"data.dos_crashed"}]}]},e.exports=a.extend(r.exports)},{205:205}],270:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{healthState:function(){var t=this.get("data.health");return t>70?"good":t>50?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[15,1,320], -t:7,e:"ntosheader"}," ",{t:4,f:[{p:[18,3,363],t:7,e:"ui-notice",f:[{p:[19,5,380],t:7,e:"span",f:["Reconstruction in progress!"]}]}],n:50,r:"data.restoring",p:[17,1,337]},{p:[24,1,451],t:7,e:"ui-display",f:[{p:[26,1,467],t:7,e:"div",a:{"class":"item"},f:[{p:[27,3,489],t:7,e:"div",a:{"class":"itemLabel"},f:["Inserted AI:"]}," ",{p:[30,3,541],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[31,2,569],t:7,e:"ui-button",a:{icon:"eject",action:"PRG_eject",state:[{t:2,x:{r:["data.nocard"],s:'_0?"disabled":null'},p:[31,52,619]}]},f:[{t:2,x:{r:["data.name"],s:'_0?_0:"---"'},p:[31,89,656]}]}]}]}," ",{t:4,f:[{p:[36,2,744],t:7,e:"b",f:["ERROR: ",{t:2,r:"data.error",p:[36,12,754]}]}],n:50,r:"data.error",p:[35,1,723]},{t:4,n:51,f:[{p:[38,2,785],t:7,e:"h2",f:["System Status"]}," ",{p:[39,2,810],t:7,e:"div",a:{"class":"item"},f:[{p:[40,3,832],t:7,e:"div",a:{"class":"itemLabel"},f:["Current AI:"]}," ",{p:[43,3,885],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.name",p:[44,4,915]}]}," ",{p:[46,3,942],t:7,e:"div",a:{"class":"itemLabel"},f:["Status:"]}," ",{p:[49,3,991],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:["Nonfunctional"],n:50,r:"data.isDead",p:[50,4,1021]},{t:4,n:51,f:["Functional"],r:"data.isDead"}]}," ",{p:[56,3,1114],t:7,e:"div",a:{"class":"itemLabel"},f:["System Integrity:"]}," ",{p:[59,3,1173],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[60,4,1203],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.health",p:[60,37,1236]}],state:[{t:2,r:"healthState",p:[61,11,1264]}]},f:[{t:2,x:{r:["adata.health"],s:"Math.round(_0)"},p:[61,28,1281]},"%"]}]}," ",{p:[63,3,1336],t:7,e:"div",a:{"class":"itemLabel"},f:["Active Laws:"]}," ",{p:[66,3,1390],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[67,4,1420],t:7,e:"table",f:[{t:4,f:[{p:[69,6,1462],t:7,e:"tr",f:[{p:[69,10,1466],t:7,e:"td",f:[{p:[69,14,1470],t:7,e:"span",a:{"class":"highlight"},f:[{t:2,r:".",p:[69,38,1494]}]}]}]}],n:52,r:"data.ai_laws",p:[68,5,1433]}]}]}," ",{p:[73,2,1547],t:7,e:"ui-section",a:{label:"Operations"},f:[{p:[74,3,1582],t:7,e:"ui-button",a:{icon:"plus",style:[{t:2,x:{r:["data.restoring"],s:'_0?"disabled":null'},p:[74,33,1612]}],action:"PRG_beginReconstruction"},f:["Begin Reconstruction"]}]}]}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],271:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[5,1,91],t:7,e:"ui-button",a:{action:"PRG_switchm",icon:"home",params:'{"target" : "mod"}',state:[{t:2,x:{r:["data.mmode"],s:'_0==1?"disabled":null'},p:[5,80,170]}]},f:["Access Modification"]}],n:50,r:"data.have_id_slot",p:[4,1,64]},{p:[7,1,253],t:7,e:"ui-button",a:{action:"PRG_switchm",icon:"folder-open",params:'{"target" : "manage"}',state:[{t:2,x:{r:["data.mmode"],s:'_0==2?"disabled":null'},p:[7,90,342]}]},f:["Job Management"]}," ",{p:[8,1,411],t:7,e:"ui-button",a:{action:"PRG_switchm",icon:"folder-open",params:'{"target" : "manifest"}',state:[{t:2,x:{r:["data.mmode"],s:'!_0?"disabled":null'},p:[8,92,502]}]},f:["Crew Manifest"]}," ",{t:4,f:[{p:[10,1,593],t:7,e:"ui-button",a:{action:"PRG_print",icon:"print",state:[{t:2,x:{r:["data.has_id","data.mmode"],s:'!_1||_0&&_1==1?null:"disabled"'},p:[10,51,643]}]},f:["Print"]}],n:50,r:"data.have_printer",p:[9,1,566]},{t:4,f:[{p:[14,1,766],t:7,e:"div",a:{"class":"item"},f:[{p:[15,3,788],t:7,e:"h2",f:["Crew Manifest"]}," ",{p:[16,3,814],t:7,e:"br"},"Please use security record computer to modify entries.",{p:[16,61,872],t:7,e:"br"},{p:[16,65,876],t:7,e:"br"}]}," ",{t:4,f:[{p:[19,2,916],t:7,e:"div",a:{"class":"item"},f:[{t:2,r:"name",p:[20,2,937]}," - ",{t:2,r:"rank",p:[20,13,948]}]}],n:52,r:"data.manifest",p:[18,1,890]}],n:50,x:{r:["data.mmode"],s:"!_0"},p:[13,1,745]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.mmode"],s:"_0==2"},f:[{p:[25,1,1008],t:7,e:"div",a:{"class":"item"},f:[{p:[26,3,1030],t:7,e:"h2",f:["Job Management"]}]}," ",{p:[28,1,1063],t:7,e:"table",f:[{p:[29,1,1072],t:7,e:"tr",f:[{p:[29,5,1076],t:7,e:"td",a:{style:"width:25%"},f:[{p:[29,27,1098],t:7,e:"b",f:["Job"]}]},{p:[29,42,1113],t:7,e:"td",a:{style:"width:25%"},f:[{p:[29,64,1135],t:7,e:"b",f:["Slots"]}]},{p:[29,81,1152],t:7,e:"td",a:{style:"width:25%"},f:[{p:[29,103,1174],t:7,e:"b",f:["Open job"]}]},{p:[29,123,1194],t:7,e:"td",a:{style:"width:25%"},f:[{p:[29,145,1216],t:7,e:"b",f:["Close job"]}]}]}," ",{t:4,f:[{p:[32,2,1269],t:7,e:"tr",f:[{p:[32,6,1273],t:7,e:"td",f:[{t:2,r:"title",p:[32,10,1277]}]},{p:[32,24,1291],t:7,e:"td",f:[{t:2,r:"current",p:[32,28,1295]},"/",{t:2,r:"total",p:[32,40,1307]}]},{p:[32,54,1321],t:7,e:"td",f:[{p:[32,58,1325],t:7,e:"ui-button",a:{action:"PRG_open_job",params:['{"target" : "',{t:2,r:"title",p:[32,112,1379]},'"}'],state:[{t:2,x:{r:["status_open"],s:'_0?null:"disabled"'},p:[32,132,1399]}]},f:[{t:2,r:"desc_open",p:[32,169,1436]}]},{p:[32,194,1461],t:7,e:"br"}]},{p:[32,203,1470],t:7,e:"td",f:[{p:[32,207,1474],t:7,e:"ui-button",a:{action:"PRG_close_job",params:['{"target" : "',{t:2,r:"title",p:[32,262,1529]},'"}'],state:[{t:2,x:{r:["status_close"],s:'_0?null:"disabled"'},p:[32,282,1549]}]},f:[{t:2,r:"desc_close",p:[32,320,1587]}]}]}]}],n:52,r:"data.slots",p:[30,1,1244]}]}]},{t:4,n:50,x:{r:["data.mmode"],s:"!(_0==2)"},f:[" ",{p:[40,1,1665],t:7,e:"div",a:{"class":"item"},f:[{p:[41,3,1687],t:7,e:"h2",f:["Access Modification"]}]}," ",{t:4,f:[{p:[45,3,1751],t:7,e:"span",a:{"class":"alert"},f:[{p:[45,23,1771],t:7,e:"i",f:["Please insert the ID into the terminal to proceed."]}]},{p:[45,87,1835],t:7,e:"br"}],n:50,x:{r:["data.has_id"],s:"!_0"},p:[44,1,1727]},{p:[48,1,1852],t:7,e:"div",a:{"class":"item"},f:[{p:[49,3,1874],t:7,e:"div",a:{"class":"itemLabel"},f:["Target Identity:"]}," ",{p:[52,3,1930],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[53,2,1958],t:7,e:"ui-button",a:{icon:"eject",action:"PRG_eject",params:'{"target" : "id"}'},f:[{t:2,r:"data.id_name",p:[53,72,2028]}]}]}]}," ",{p:[56,1,2076],t:7,e:"div",a:{"class":"item"},f:[{p:[57,3,2098],t:7,e:"div",a:{"class":"itemLabel"},f:["Auth Identity:"]}," ",{p:[60,3,2152],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[61,2,2180],t:7,e:"ui-button",a:{icon:"eject",action:"PRG_eject",params:'{"target" : "auth"}'},f:[{t:2,r:"data.auth_name",p:[61,74,2252]}]}]}]}," ",{p:[64,1,2302],t:7,e:"hr"}," ",{t:4,f:[{t:4,f:[{p:[68,2,2362],t:7,e:"div",a:{"class":"item"},f:[{p:[69,4,2385],t:7,e:"h2",f:["Details"]}]}," ",{t:4,f:[{p:[73,2,2436],t:7,e:"div",a:{"class":"item"},f:[{p:[74,4,2459],t:7,e:"div",a:{"class":"itemLabel"},f:["Registered Name:"]}," ",{p:[77,4,2518],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.id_owner",p:[78,3,2547]}]}]}," ",{p:[81,2,2587],t:7,e:"div",a:{"class":"item"},f:[{p:[82,4,2610],t:7,e:"div",a:{"class":"itemLabel"},f:["Rank:"]}," ",{p:[85,4,2658],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.id_rank",p:[86,3,2687]}]}]}," ",{p:[89,2,2726],t:7,e:"div",a:{"class":"item"},f:[{p:[90,4,2749],t:7,e:"div",a:{"class":"itemLabel"},f:["Demote:"]}," ",{p:[93,4,2799],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[94,3,2828],t:7,e:"ui-button",a:{action:"PRG_terminate",icon:"gear",state:[{t:2,x:{r:["data.id_rank"],s:'_0=="Unassigned"?"disabled":null'},p:[94,56,2881]}]},f:["Demote ",{t:2,r:"data.id_owner",p:[94,117,2942]}]}]}]}],n:50,r:"data.minor",p:[72,2,2415]},{t:4,n:51,f:[{p:[99,2,3007],t:7,e:"div",a:{"class":"item"},f:[{p:[100,4,3030],t:7,e:"div",a:{"class":"itemLabel"},f:["Registered Name:"]}," ",{p:[103,4,3089],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[104,3,3118],t:7,e:"ui-button",a:{action:"PRG_edit",icon:"pencil",params:'{"name" : "1"}'},f:[{t:2,r:"data.id_owner",p:[104,70,3185]}]}]}]}," ",{p:[108,2,3239],t:7,e:"div",a:{"class":"item"},f:[{p:[109,4,3262],t:7,e:"h2",f:["Assignment"]}]}," ",{p:[111,3,3294],t:7,e:"ui-button",a:{action:"PRG_togglea",icon:"gear"},f:[{t:2,x:{r:["data.assignments"],s:'_0?"Hide assignments":"Show assignments"'},p:[111,47,3338]}]}," ",{p:[112,2,3415],t:7,e:"div",a:{"class":"item"},f:[{p:[113,4,3438],t:7,e:"span",a:{id:"allvalue.jobsslot"},f:[]}]}," ",{p:[117,2,3495],t:7,e:"div",a:{"class":"item"},f:[{t:4,f:[{p:[119,4,3547],t:7,e:"div",a:{id:"all-value.jobs"},f:[{p:[120,3,3576],t:7,e:"table",f:[{p:[121,5,3589],t:7,e:"tr",f:[{p:[122,4,3598],t:7,e:"th",f:["Command"]}," ",{p:[123,4,3619],t:7,e:"td",f:[{p:[124,6,3630],t:7,e:"ui-button",a:{action:"PRG_assign",params:'{"assign_target" : "Captain"}',state:[{t:2,x:{r:["data.id_rank"],s:'_0=="Captain"?"selected":null'},p:[124,83,3707]}]},f:["Captain"]}]}]}," ",{p:[127,5,3804],t:7,e:"tr",f:[{p:[128,4,3813],t:7,e:"th",f:["Special"]}," ",{p:[129,4,3834],t:7,e:"td",f:[{p:[130,6,3845],t:7,e:"ui-button",a:{action:"PRG_assign",params:'{"assign_target" : "Custom"}'},f:["Custom"]}]}]}," ",{p:[133,5,3959],t:7,e:"tr",f:[{p:[134,4,3968],t:7,e:"th",a:{style:"color: '#FFA500';"},f:["Engineering"]}," ",{p:[135,4,4019],t:7,e:"td",f:[{t:4,f:[{p:[137,5,4067],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[137,64,4126]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[137,82,4144]}]},f:[{t:2,r:"display_name",p:[137,127,4189]}]}],n:52,r:"data.engineering_jobs",p:[136,6,4030]}]}]}," ",{p:[141,5,4260],t:7,e:"tr",f:[{p:[142,4,4269],t:7,e:"th",a:{style:"color: '#008000';"},f:["Medical"]}," ",{p:[143,4,4316],t:7,e:"td",f:[{t:4,f:[{p:[145,5,4360],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[145,64,4419]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[145,82,4437]}]},f:[{t:2,r:"display_name",p:[145,127,4482]}]}],n:52,r:"data.medical_jobs",p:[144,6,4327]}]}]}," ",{p:[149,5,4553],t:7,e:"tr",f:[{p:[150,4,4562],t:7,e:"th",a:{style:"color: '#800080';"},f:["Science"]}," ",{p:[151,4,4609],t:7,e:"td",f:[{t:4,f:[{p:[153,5,4653],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[153,64,4712]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[153,82,4730]}]},f:[{t:2,r:"display_name",p:[153,127,4775]}]}],n:52,r:"data.science_jobs",p:[152,6,4620]}]}]}," ",{p:[157,5,4846],t:7,e:"tr",f:[{p:[158,4,4855],t:7,e:"th",a:{style:"color: '#DD0000';"},f:["Security"]}," ",{p:[159,4,4903],t:7,e:"td",f:[{t:4,f:[{p:[161,5,4948],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[161,64,5007]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[161,82,5025]}]},f:[{t:2,r:"display_name",p:[161,127,5070]}]}],n:52,r:"data.security_jobs",p:[160,6,4914]}]}]}," ",{p:[165,5,5141],t:7,e:"tr",f:[{p:[166,4,5150],t:7,e:"th",a:{style:"color: '#cc6600';"},f:["Cargo"]}," ",{p:[167,4,5195],t:7,e:"td",f:[{t:4,f:[{p:[169,5,5237],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[169,64,5296]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[169,82,5314]}]},f:[{t:2,r:"display_name",p:[169,127,5359]}]}],n:52,r:"data.cargo_jobs",p:[168,6,5206]}]}]}," ",{p:[173,5,5430],t:7,e:"tr",f:[{p:[174,4,5439],t:7,e:"th",a:{style:"color: '#808080';"},f:["Civilian"]}," ",{p:[175,4,5487],t:7,e:"td",f:[{t:4,f:[{p:[177,5,5532],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[177,64,5591]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[177,82,5609]}]},f:[{t:2,r:"display_name",p:[177,127,5654]}]}],n:52,r:"data.civilian_jobs",p:[176,6,5498]}]}]}," ",{t:4,f:[{p:[182,4,5757],t:7,e:"tr",f:[{p:[183,6,5768],t:7,e:"th",a:{style:"color: '#A52A2A';"},f:["CentCom"]}," ",{p:[184,6,5817],t:7,e:"td",f:[{t:4,f:[{p:[186,7,5862],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[186,66,5921]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[186,84,5939]}]},f:[{t:2,r:"display_name",p:[186,129,5984]}]}],n:52,r:"data.centcom_jobs",p:[185,5,5827]}]}]}],n:50,r:"data.centcom_access",p:[181,5,5725]}]}]}],n:50,r:"data.assignments",p:[118,4,3518]}]}],r:"data.minor"}," ",{t:4,f:[{p:[198,4,6153],t:7,e:"div",a:{"class":"item"},f:[{p:[199,3,6175],t:7,e:"h2",f:["Central Command"]}]}," ",{p:[201,4,6215],t:7,e:"div",a:{"class":"item",style:"width: 100%"},f:[{t:4,f:[{p:[203,5,6296],t:7,e:"div",a:{"class":"itemContentWide"},f:[{p:[204,5,6331],t:7,e:"ui-button",a:{action:"PRG_access",params:['{"access_target" : "',{t:2,r:"ref",p:[204,64,6390]},'", "allowed" : "',{t:2,r:"allowed",p:[204,87,6413]},'"}'],state:[{t:2,x:{r:["allowed"],s:'_0?"toggle":null'},p:[204,109,6435]}]},f:[{t:2,r:"desc",p:[204,140,6466]}]}]}],n:52,r:"data.all_centcom_access",p:[202,3,6257]}]}],n:50,r:"data.centcom_access",p:[197,2,6121]},{t:4,n:51,f:[{p:[209,4,6538],t:7,e:"div",a:{"class":"item"},f:[{p:[210,3,6560],t:7,e:"h2",f:[{t:2,r:"data.station_name",p:[210,7,6564]}]}]}," ",{p:[212,4,6606],t:7,e:"div",a:{"class":"item",style:"width: 100%"},f:[{t:4,f:[{p:[214,5,6676],t:7,e:"div",a:{style:"float: left; width: 175px; min-height: 250px"},f:[{p:[215,4,6739],t:7,e:"div",a:{"class":"average"},f:[{p:[215,25,6760],t:7,e:"ui-button",a:{action:"PRG_regsel",state:[{t:2,x:{r:["selected"],s:'_0?"toggle":null'},p:[215,63,6798]}],params:['{"region" : "',{t:2,r:"regid",p:[215,116,6851]},'"}']},f:[{p:[215,129,6864],t:7,e:"b",f:[{t:2,r:"name",p:[215,132,6867]}]}]}]}," ",{p:[216,4,6902],t:7,e:"br"}," ",{t:4,f:[{p:[218,6,6938],t:7,e:"div",a:{"class":"itemContentWide"},f:[{p:[219,5,6973],t:7,e:"ui-button",a:{action:"PRG_access",params:['{"access_target" : "',{t:2,r:"ref",p:[219,64,7032]},'", "allowed" : "',{t:2,r:"allowed",p:[219,87,7055]},'"}'],state:[{t:2,x:{r:["allowed"],s:'_0?"toggle":null'},p:[219,109,7077]}]},f:[{t:2,r:"desc",p:[219,140,7108]}]}]}],n:52,r:"accesses",p:[217,6,6913]}]}],n:52,r:"data.regions",p:[213,3,6648]}]}],r:"data.centcom_access"}],n:50,r:"data.has_id",p:[67,3,2340]}],n:50,r:"data.authenticated",p:[66,1,2310]}]}],x:{r:["data.mmode"],s:"!_0"}}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],272:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{chargeState:function(t){var e=this.get("data.battery.max");return t>e/2?"good":t>e/4?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[15,1,311],t:7,e:"ntosheader"}," ",{p:[17,1,328],t:7,e:"ui-display",f:[{p:[18,2,343],t:7,e:"i",f:["Welcome to computer configuration utility. Please consult your system administrator if you have any questions about your device."]},{p:[18,137,478],t:7,e:"hr"}," ",{p:[19,2,485],t:7,e:"ui-display",a:{title:"Power Supply"},f:[{p:[20,3,522],t:7,e:"ui-section",a:{label:"Power Usage"},f:[{t:2,r:"data.power_usage",p:[21,4,559]},"W"]}," ",{t:4,f:[{p:[25,4,630],t:7,e:"ui-section",a:{label:"Battery Status"},f:["Active"]}," ",{p:[28,4,701],t:7,e:"ui-section",a:{label:"Battery Rating"},f:[{t:2,r:"data.battery.max",p:[29,5,742]}]}," ",{p:[31,4,785],t:7,e:"ui-section",a:{label:"Battery Charge"},f:[{p:[32,5,826],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.battery.max",p:[32,26,847]}],value:[{t:2,r:"adata.battery.charge",p:[32,56,877]}],state:[{t:2,x:{r:["chargeState","adata.battery.charge"],s:"_0(_1)"},p:[32,89,910]}]},f:[{t:2,x:{r:["adata.battery.charge"],s:"Math.round(_0)"},p:[32,128,949]},"/",{t:2,r:"adata.battery.max",p:[32,165,986]}]}]}],n:50,r:"data.battery",p:[24,3,605]},{t:4,n:51,f:[{p:[35,4,1051],t:7,e:"ui-section",a:{label:"Battery Status"},f:["Not Available"]}],r:"data.battery"}]}," ",{p:[41,2,1156],t:7,e:"ui-display",a:{title:"File System"},f:[{p:[42,3,1192],t:7,e:"ui-section",a:{label:"Used Capacity"},f:[{p:[43,4,1231],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.disk_size",p:[43,25,1252]}],value:[{t:2,r:"adata.disk_used",p:[43,53,1280]}],state:"good"},f:[{t:2,x:{r:["adata.disk_used"],s:"Math.round(_0)"},p:[43,87,1314]},"GQ / ",{t:2,r:"adata.disk_size",p:[43,123,1350]},"GQ"]}]}]}," ",{p:[47,2,1419],t:7,e:"ui-display",a:{title:"Computer Components"},f:[{t:4,f:[{p:[49,4,1491],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"name",p:[49,26,1513]}]},f:[{p:[50,5,1529],t:7,e:"div",a:{style:"display: table-caption; margin-left: 3px"},f:[{t:2,r:"desc",p:[50,59,1583]}]}," ",{p:[52,5,1605],t:7,e:"ui-section",a:{label:"State"},f:[{p:[53,6,1638],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["critical"],s:'_0?"disabled":null'},p:[53,24,1656]}],action:"PC_toggle_component",params:['{"name": "',{t:2,r:"name",p:[53,105,1737]},'"}']},f:[{t:2,x:{r:["enabled"],s:'_0?"Enabled":"Disabled"'},p:[54,7,1757]}]}]}," ",{t:4,f:[{p:[59,6,1868],t:7,e:"ui-section",a:{label:"Power Usage"},f:[{t:2,r:"powerusage",p:[60,7,1908]},"W"]}],n:50,r:"powerusage",p:[58,5,1843]}]}," ",{p:[64,4,1985],t:7,e:"br"}],n:52,r:"data.hardware",p:[48,3,1463]}]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],273:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:[{p:[7,3,103],t:7,e:"h2",f:["An error has occurred and this program can not continue."]}," Additional information: ",{t:2,r:"data.error",p:[8,27,196]},{p:[8,41,210],t:7,e:"br"}," ",{p:[9,3,218],t:7,e:"i",f:["Please try again. If the problem persists contact your system administrator for assistance."]}," ",{p:[10,3,320],t:7,e:"ui-button",a:{action:"PRG_closefile"},f:["Restart program"]}],n:50,r:"data.error",p:[6,2,81]},{t:4,n:51,f:[{t:4,f:[{p:[13,4,422],t:7,e:"h2",f:["Viewing file ",{t:2,r:"data.filename",p:[13,21,439]}]}," ",{p:[14,4,466],t:7,e:"div",a:{"class":"item"},f:[{p:[15,4,489],t:7,e:"ui-button",a:{action:"PRG_closefile"},f:["CLOSE"]}," ",{p:[16,4,545],t:7,e:"ui-button",a:{action:"PRG_edit"},f:["EDIT"]}," ",{p:[17,4,595],t:7,e:"ui-button",a:{action:"PRG_printfile"},f:["PRINT"]}," "]},{p:[18,10,657],t:7,e:"hr"}," ",{t:3,r:"data.filedata",p:[19,4,666]}],n:50,r:"data.filename",p:[12,3,396]},{t:4,n:51,f:[{p:[21,4,702],t:7,e:"h2",f:["Available files (local):"]}," ",{p:[22,4,740],t:7,e:"table",f:[{p:[23,5,753],t:7,e:"tr",f:[{p:[24,6,764],t:7,e:"th",f:["File name"]}," ",{p:[25,6,789],t:7,e:"th",f:["File type"]}," ",{p:[26,6,814],t:7,e:"th",f:["File size (GQ)"]}," ",{p:[27,6,844],t:7,e:"th",f:["Operations"]}]}," ",{t:4,f:[{p:[30,6,907],t:7,e:"tr",f:[{p:[31,7,919],t:7,e:"td",f:[{t:2,r:"name",p:[31,11,923]}]}," ",{p:[32,7,944],t:7,e:"td",f:[".",{t:2,r:"type",p:[32,12,949]}]}," ",{p:[33,7,970],t:7,e:"td",f:[{t:2,r:"size",p:[33,11,974]},"GQ"]}," ",{p:[34,7,997],t:7,e:"td",f:[{p:[35,8,1010],t:7,e:"ui-button",a:{action:"PRG_openfile",params:['{"name": "',{t:2,r:"name",p:[35,59,1061]},'"}']},f:["VIEW"]}," ",{p:[36,8,1098],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[36,26,1116]}],action:"PRG_deletefile",params:['{"name": "',{t:2,r:"name",p:[36,105,1195]},'"}']},f:["DELETE"]}," ",{p:[37,8,1234],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[37,26,1252]}],action:"PRG_rename",params:['{"name": "',{t:2,r:"name",p:[37,101,1327]},'"}']},f:["RENAME"]}," ",{p:[38,8,1366],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[38,26,1384]}],action:"PRG_clone",params:['{"name": "',{t:2,r:"name",p:[38,100,1458]},'"}']},f:["CLONE"]}," ",{t:4,f:[{p:[40,9,1531],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[40,27,1549]}],action:"PRG_copytousb",params:['{"name": "',{t:2,r:"name",p:[40,105,1627]},'"}']},f:["EXPORT"]}],n:50,r:"data.usbconnected",p:[39,8,1496]}]}]}],n:52,r:"data.files",p:[29,5,880]}]}," ",{t:4,f:[{p:[47,4,1761],t:7,e:"h2",f:["Available files (portable device):"]}," ",{p:[48,4,1809],t:7,e:"table",f:[{p:[49,5,1822],t:7,e:"tr",f:[{p:[50,6,1833],t:7,e:"th",f:["File name"]}," ",{p:[51,6,1858],t:7,e:"th",f:["File type"]}," ",{p:[52,6,1883],t:7,e:"th",f:["File size (GQ)"]}," ",{p:[53,6,1913],t:7,e:"th",f:["Operations"]}]}," ",{t:4,f:[{p:[56,6,1979],t:7,e:"tr",f:[{p:[57,7,1991],t:7,e:"td",f:[{t:2,r:"name",p:[57,11,1995]}]}," ",{p:[58,7,2016],t:7,e:"td",f:[".",{t:2,r:"type",p:[58,12,2021]}]}," ",{p:[59,7,2042],t:7,e:"td",f:[{t:2,r:"size",p:[59,11,2046]},"GQ"]}," ",{p:[60,7,2069],t:7,e:"td",f:[{p:[61,8,2082],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[61,26,2100]}],action:"PRG_usbdeletefile",params:['{"name": "',{t:2,r:"name",p:[61,108,2182]},'"}']},f:["DELETE"]}," ",{t:4,f:[{p:[63,9,2256],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[63,27,2274]}],action:"PRG_copyfromusb",params:['{"name": "',{t:2,r:"name",p:[63,107,2354]},'"}']},f:["IMPORT"]}],n:50,r:"data.usbconnected",p:[62,8,2221]}]}]}],n:52,r:"data.usbfiles",p:[55,5,1949]}]}],n:50,r:"data.usbconnected",p:[46,4,1731]}," ",{p:[70,4,2470],t:7,e:"ui-button",a:{action:"PRG_newtextfile"},f:["NEW DATA FILE"]}],r:"data.filename"}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],274:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[5,2,79],t:7,e:"i",f:["No program loaded. Please select program from list below."]}," ",{p:[6,2,146],t:7,e:"table",f:[{t:4,f:[{p:[8,4,185],t:7,e:"tr",f:[{p:[8,8,189],t:7,e:"td",f:[{p:[8,12,193],t:7,e:"ui-button",a:{action:"PC_runprogram",params:['{"name": "',{t:2,r:"name",p:[8,64,245]},'"}']},f:[{t:2,r:"desc",p:[9,5,263]}]}]},{p:[11,4,293],t:7,e:"td",f:[{p:[11,8,297],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["running"],s:'_0?null:"disabled"'},p:[11,26,315]}],icon:"close",action:"PC_killprogram",params:['{"name": "',{t:2,r:"name",p:[11,114,403]},'"}']}}]}]}],n:52,r:"data.programs",p:[7,3,157]}]}," ",{p:[14,2,454],t:7,e:"br"},{p:[14,6,458],t:7,e:"br"}," ",{t:4,f:[{p:[16,3,491],t:7,e:"ui-button",a:{action:"PC_toggle_light",style:[{t:2,x:{r:["data.light_on"],s:'_0?"selected":null'},p:[16,46,534]}]},f:["Toggle Flashlight"]},{p:[16,114,602],t:7,e:"br"}," ",{p:[17,3,610],t:7,e:"ui-button",a:{action:"PC_light_color"},f:["Change Flashlight Color ",{p:[17,62,669],t:7,e:"span",a:{style:["border:1px solid #161616; background-color: ",{t:2,r:"data.comp_light_color",p:[17,119,726]},";"]},f:["   "]}]}],n:50,r:"data.has_light",p:[15,2,465]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],275:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:[{p:[6,3,105],t:7,e:"h1",f:["ADMINISTRATIVE MODE"]}],n:50,r:"data.adminmode",p:[5,2,79]}," ",{t:4,f:[{p:[10,3,170],t:7,e:"div",a:{"class":"itemLabel"},f:["Current channel:"]}," ",{p:[13,3,229],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.title",p:[14,4,259]}]}," ",{p:[16,3,287],t:7,e:"div",a:{"class":"itemLabel"},f:["Operator access:"]}," ",{p:[19,3,346],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:[{p:[21,5,406],t:7,e:"b",f:["Enabled"]}],n:50,r:"data.is_operator",p:[20,4,376]},{t:4,n:51,f:[{p:[23,5,439],t:7,e:"b",f:["Disabled"]}],r:"data.is_operator"}]}," ",{p:[26,3,480],t:7,e:"div",a:{"class":"itemLabel"},f:["Controls:"]}," ",{p:[29,3,532],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[30,4,562],t:7,e:"table",f:[{p:[31,5,575],t:7,e:"tr",f:[{p:[31,9,579],t:7,e:"td",f:[{p:[31,13,583],t:7,e:"ui-button",a:{action:"PRG_speak"},f:["Send message"]}]}]},{p:[32,5,643],t:7,e:"tr",f:[{p:[32,9,647],t:7,e:"td",f:[{p:[32,13,651],t:7,e:"ui-button",a:{action:"PRG_changename"},f:["Change nickname"]}]}]},{p:[33,5,719],t:7,e:"tr",f:[{p:[33,9,723],t:7,e:"td",f:[{p:[33,13,727],t:7,e:"ui-button",a:{action:"PRG_toggleadmin"},f:["Toggle administration mode"]}]}]},{p:[34,5,807],t:7,e:"tr",f:[{p:[34,9,811],t:7,e:"td",f:[{p:[34,13,815],t:7,e:"ui-button",a:{action:"PRG_leavechannel"},f:["Leave channel"]}]}]},{p:[35,5,883],t:7,e:"tr",f:[{p:[35,9,887],t:7,e:"td",f:[{p:[35,13,891],t:7,e:"ui-button",a:{action:"PRG_savelog"},f:["Save log to local drive"]}," ",{t:4,f:[{p:[37,6,995],t:7,e:"tr",f:[{p:[37,10,999],t:7,e:"td",f:[{p:[37,14,1003],t:7,e:"ui-button",a:{action:"PRG_renamechannel"},f:["Rename channel"]}]}]},{p:[38,6,1074],t:7,e:"tr",f:[{p:[38,10,1078],t:7,e:"td",f:[{p:[38,14,1082],t:7,e:"ui-button",a:{action:"PRG_setpassword"},f:["Set password"]}]}]},{p:[39,6,1149],t:7,e:"tr",f:[{p:[39,10,1153],t:7,e:"td",f:[{p:[39,14,1157],t:7,e:"ui-button",a:{action:"PRG_deletechannel"},f:["Delete channel"]}]}]}],n:50,r:"data.is_operator",p:[36,5,964]}]}]}]}]}," ",{p:[43,3,1263],t:7,e:"b",f:["Chat Window"]}," ",{p:[44,4,1286],t:7,e:"div",a:{"class":"statusDisplay",style:"overflow: auto;"},f:[{p:[45,4,1342],t:7,e:"div",a:{"class":"item"},f:[{p:[46,5,1366],t:7,e:"div",a:{"class":"itemContent",style:"width: 100%;"},f:[{t:4,f:[{t:2,r:"msg",p:[48,7,1450]},{p:[48,14,1457],t:7,e:"br"}],n:52,r:"data.messages",p:[47,6,1419]}]}]}]}," ",{p:[53,3,1516],t:7,e:"b",f:["Connected Users"]},{p:[53,25,1538],t:7,e:"br"}," ",{t:4,f:[{t:2,r:"name",p:[55,4,1573]},{p:[55,12,1581],t:7,e:"br"}],n:52,r:"data.clients",p:[54,3,1546]}],n:50,r:"data.title",p:[9,2,148]},{t:4,n:51,f:[{p:[58,3,1613],t:7,e:"b",f:["Controls:"]}," ",{p:[59,3,1633],t:7,e:"table",f:[{p:[60,4,1645],t:7,e:"tr",f:[{p:[60,8,1649],t:7,e:"td",f:[{p:[60,12,1653],t:7,e:"ui-button",a:{action:"PRG_changename"},f:["Change nickname"]}]}]},{p:[61,4,1720],t:7,e:"tr",f:[{p:[61,8,1724],t:7,e:"td",f:[{p:[61,12,1728],t:7,e:"ui-button",a:{action:"PRG_newchannel"},f:["New Channel"]}]}]},{p:[62,4,1791],t:7,e:"tr",f:[{p:[62,8,1795],t:7,e:"td",f:[{p:[62,12,1799],t:7,e:"ui-button",a:{action:"PRG_toggleadmin"},f:["Toggle administration mode"]}]}]}]}," ",{p:[64,3,1889],t:7,e:"b",f:["Available channels:"]}," ",{p:[65,3,1919],t:7,e:"table",f:[{t:4,f:[{p:[67,4,1964],t:7,e:"tr",f:[{p:[67,8,1968],t:7,e:"td",f:[{p:[67,12,1972],t:7,e:"ui-button",a:{action:"PRG_joinchannel",params:['{"id": "',{t:2,r:"id",p:[67,64,2024]},'"}']},f:[{t:2,r:"chan",p:[67,74,2034]}]},{p:[67,94,2054],t:7,e:"br"}]}]}],n:52,r:"data.all_channels",p:[66,3,1930]}]}],r:"data.title"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],276:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:["##SYSTEM ERROR: ",{t:2,r:"data.error",p:[6,19,117]},{p:[6,33,131],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["RESET"]}],n:50,r:"data.error",p:[5,2,79]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.target"],s:"_0"},f:["##DoS traffic generator active. Tx: ",{t:2,r:"data.speed",p:[8,39,243]},"GQ/s",{p:[8,57,261],t:7,e:"br"}," ",{t:4,f:[{t:2,r:"nums",p:[10,4,300]},{p:[10,12,308],t:7,e:"br"}],n:52,r:"data.dos_strings",p:[9,3,269]}," ",{p:[12,3,329],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["ABORT"]}]},{t:4,n:50,x:{r:["data.target"],s:"!(_0)"},f:[" ##DoS traffic generator ready. Select target device.",{p:[14,55,443],t:7,e:"br"}," ",{t:4,f:["Targeted device ID: ",{t:2,r:"data.focus",p:[16,24,494]}],n:50,r:"data.focus",p:[15,3,451]},{t:4,n:51,f:["Targeted device ID: None"],r:"data.focus"}," ",{p:[20,3,564],t:7,e:"ui-button",a:{action:"PRG_execute"},f:["EXECUTE"]},{p:[20,54,615],t:7,e:"div",a:{style:"clear:both"}}," Detected devices on network:",{p:[21,31,677],t:7,e:"br"}," ",{t:4,f:[{p:[23,4,711],t:7,e:"ui-button",a:{action:"PRG_target_relay",params:['{"targid": "',{t:2,r:"id",p:[23,61,768]},'"}']},f:[{t:2,r:"id",p:[23,71,778]}]}],n:52,r:"data.relays",p:[22,3,685]}]}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],277:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[5,2,79],t:7,e:"i",f:["Welcome to software download utility. Please select which software you wish to download."]},{p:[5,97,174],t:7,e:"hr"}," ",{t:4,f:[{p:[7,3,203],t:7,e:"ui-display",a:{title:"Download Error"},f:[{p:[8,4,243],t:7,e:"ui-section",a:{label:"Information"},f:[{t:2,r:"data.error",p:[9,5,281]}]}," ",{p:[11,4,318],t:7,e:"ui-section",a:{label:"Reset Program"},f:[{p:[12,5,358],t:7,e:"ui-button",a:{icon:"times",action:"PRG_reseterror"},f:["RESET"]}]}]}],n:50,r:"data.error",p:[6,2,181]},{t:4,n:51,f:[{t:4,f:[{p:[19,4,516],t:7,e:"ui-display",a:{title:"Download Running"},f:[{p:[20,5,559],t:7,e:"i",f:["Please wait..."]}," ",{p:[21,5,586],t:7,e:"ui-section",a:{label:"File name"},f:[{t:2,r:"data.downloadname",p:[22,6,623]}]}," ",{p:[24,5,669],t:7,e:"ui-section",a:{label:"File description"},f:[{t:2,r:"data.downloaddesc",p:[25,6,713]}]}," ",{p:[27,5,759],t:7,e:"ui-section",a:{label:"File size"},f:[{t:2,r:"data.downloadsize",p:[28,6,796]},"GQ"]}," ",{p:[30,5,844],t:7,e:"ui-section",a:{label:"Transfer Rate"},f:[{t:2,r:"data.downloadspeed",p:[31,6,885]}," GQ/s"]}," ",{p:[33,5,937],t:7,e:"ui-section",a:{label:"Download progress"},f:[{p:[34,6,982],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.downloadsize",p:[34,27,1003]}],value:[{t:2,r:"adata.downloadcompletion",p:[34,58,1034]}],state:"good"},f:[{t:2,x:{r:["adata.downloadcompletion"],s:"Math.round(_0)"},p:[34,101,1077]},"GQ / ",{t:2,r:"adata.downloadsize",p:[34,146,1122]},"GQ"]}]}]}],n:50,r:"data.downloadname",p:[18,3,486]}],r:"data.error"}," ",{t:4,f:[{t:4,f:[{p:[41,4,1270],t:7,e:"ui-display",a:{title:"File System"},f:[{p:[42,5,1308],t:7,e:"ui-section",a:{label:"Used Capacity"},f:[{p:[43,6,1349],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.disk_size",p:[43,27,1370]}],value:[{t:2,r:"adata.disk_used",p:[43,55,1398]}],state:"good"},f:[{t:2,x:{r:["adata.disk_used"],s:"Math.round(_0)"},p:[43,89,1432]},"GQ / ",{t:2,r:"adata.disk_size",p:[43,125,1468]},"GQ"]}]}]}," ",{p:[47,4,1545],t:7,e:"ui-display",a:{title:"Primary Software Repository"},f:[{t:4,f:[{p:[49,6,1642],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"filedesc",p:[49,28,1664]}]},f:[{p:[50,7,1686],t:7,e:"div",a:{style:"display: table-caption; margin-left: 3px"},f:[{t:2,r:"fileinfo",p:[50,61,1740]}]}," ",{p:[52,7,1774],t:7,e:"ui-section",a:{label:"File name"},f:[{t:2,r:"filename",p:[53,8,1813]}," (",{t:2,r:"size",p:[53,22,1827]}," GQ)"]}," ",{p:[55,7,1868],t:7,e:"ui-section",a:{label:"Compatibility"},f:[{t:2,r:"compatibility",p:[56,8,1911]}]}," ",{p:[58,7,1957],t:7,e:"ui-button",a:{icon:"signal",action:"PRG_downloadfile",params:['{"filename": "',{t:2,r:"filename",p:[58,80,2030]},'"}']},f:["DOWNLOAD"]}]}," ",{p:[62,6,2113],t:7,e:"br"}],n:52,r:"data.downloadable_programs",p:[48,5,1599]}]}," ",{t:4,f:[{p:[67,5,2194],t:7,e:"ui-display",a:{title:"UNKNOWN Software Repository"},f:[{p:[68,6,2249],t:7,e:"i",f:["Please note that Nanotrasen does not recommend download of software from non-official servers."]}," ",{t:4,f:[{p:[70,7,2395],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"filedesc",p:[70,29,2417]}]},f:[{p:[71,8,2440],t:7,e:"div",a:{style:"display: table-caption; margin-left: 3px"},f:[{t:2,r:"fileinfo",p:[71,62,2494]}]}," ",{p:[73,8,2530],t:7,e:"ui-section",a:{label:"File name"},f:[{t:2,r:"filename",p:[74,9,2570]}," (",{t:2,r:"size",p:[74,23,2584]}," GQ)"]}," ",{p:[76,8,2627],t:7,e:"ui-section",a:{label:"Compatibility"},f:[{t:2,r:"compatibility",p:[77,9,2671]}]}," ",{p:[79,8,2719],t:7,e:"ui-button",a:{icon:"signal",action:"PRG_downloadfile",params:['{"filename": "',{t:2,r:"filename",p:[79,81,2792]},'"}']},f:["DOWNLOAD"]}]}," ",{p:[83,7,2879],t:7,e:"br"}],n:52,r:"data.hacked_programs",p:[69,6,2357]}]}],n:50,r:"data.hackedavailable",p:[66,4,2160]}],n:50,x:{r:["data.error"],s:"!_0"},p:[40,3,1246]}],n:50,x:{r:["data.downloadname"], -s:"!_0"},p:[39,2,1216]}," ",{p:[89,2,2954],t:7,e:"br"},{p:[89,6,2958],t:7,e:"br"},{p:[89,10,2962],t:7,e:"hr"},{p:[89,14,2966],t:7,e:"i",f:["NTOS v2.0.4b Copyright Nanotrasen 2557 - 2559"]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],278:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[6,2,81],t:7,e:"ui-display",a:{title:"WIRELESS CONNECTIVITY"},f:[{p:[8,3,129],t:7,e:"ui-section",a:{label:"Active NTNetRelays"},f:[{p:[9,4,173],t:7,e:"b",f:[{t:2,r:"data.ntnetrelays",p:[9,7,176]}]}]}," ",{t:4,f:[{p:[12,4,250],t:7,e:"ui-section",a:{label:"System status"},f:[{p:[13,6,291],t:7,e:"b",f:[{t:2,x:{r:["data.ntnetstatus"],s:'_0?"ENABLED":"DISABLED"'},p:[13,9,294]}]}]}," ",{p:[15,4,366],t:7,e:"ui-section",a:{label:"Control"},f:[{p:[17,4,401],t:7,e:"ui-button",a:{icon:"plus",action:"toggleWireless"},f:["TOGGLE"]}]}," ",{p:[21,4,500],t:7,e:"br"},{p:[21,8,504],t:7,e:"br"}," ",{p:[22,4,513],t:7,e:"i",f:["Caution - Disabling wireless transmitters when using wireless device may prevent you from re-enabling them again!"]}],n:50,r:"data.ntnetrelays",p:[11,3,221]},{t:4,n:51,f:[{p:[24,4,650],t:7,e:"br"},{p:[24,8,654],t:7,e:"p",f:["Wireless coverage unavailable, no relays are connected."]}],r:"data.ntnetrelays"}]}," ",{p:[29,2,750],t:7,e:"ui-display",a:{title:"FIREWALL CONFIGURATION"},f:[{p:[31,2,798],t:7,e:"table",f:[{p:[32,3,809],t:7,e:"tr",f:[{p:[33,4,818],t:7,e:"th",f:["PROTOCOL"]},{p:[34,4,835],t:7,e:"th",f:["STATUS"]},{p:[35,4,850],t:7,e:"th",f:["CONTROL"]}]},{p:[36,3,865],t:7,e:"tr",f:[" ",{p:[37,4,874],t:7,e:"td",f:["Software Downloads"]},{p:[38,4,901],t:7,e:"td",f:[{t:2,x:{r:["data.config_softwaredownload"],s:'_0?"ENABLED":"DISABLED"'},p:[38,8,905]}]},{p:[39,4,967],t:7,e:"td",f:[" ",{p:[39,9,972],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "1"}'},f:["TOGGLE"]}]}]},{p:[40,3,1051],t:7,e:"tr",f:[" ",{p:[41,4,1060],t:7,e:"td",f:["Peer to Peer Traffic"]},{p:[42,4,1089],t:7,e:"td",f:[{t:2,x:{r:["data.config_peertopeer"],s:'_0?"ENABLED":"DISABLED"'},p:[42,8,1093]}]},{p:[43,4,1149],t:7,e:"td",f:[{p:[43,8,1153],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "2"}'},f:["TOGGLE"]}]}]},{p:[44,3,1232],t:7,e:"tr",f:[" ",{p:[45,4,1241],t:7,e:"td",f:["Communication Systems"]},{p:[46,4,1271],t:7,e:"td",f:[{t:2,x:{r:["data.config_communication"],s:'_0?"ENABLED":"DISABLED"'},p:[46,8,1275]}]},{p:[47,4,1334],t:7,e:"td",f:[{p:[47,8,1338],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "3"}'},f:["TOGGLE"]}]}]},{p:[48,3,1417],t:7,e:"tr",f:[" ",{p:[49,4,1426],t:7,e:"td",f:["Remote System Control"]},{p:[50,4,1456],t:7,e:"td",f:[{t:2,x:{r:["data.config_systemcontrol"],s:'_0?"ENABLED":"DISABLED"'},p:[50,8,1460]}]},{p:[51,4,1519],t:7,e:"td",f:[{p:[51,8,1523],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "4"}'},f:["TOGGLE"]}]}]}]}]}," ",{p:[55,2,1630],t:7,e:"ui-display",a:{title:"SECURITY SYSTEMS"},f:[{t:4,f:[{p:[58,4,1699],t:7,e:"ui-notice",f:[{p:[59,5,1716],t:7,e:"h1",f:["NETWORK INCURSION DETECTED"]}]}," ",{p:[61,5,1774],t:7,e:"i",f:["An abnormal activity has been detected in the network. Please verify system logs for more information"]}],n:50,r:"data.idsalarm",p:[57,3,1673]}," ",{p:[64,3,1902],t:7,e:"ui-section",a:{label:"Intrusion Detection System"},f:[{p:[65,4,1954],t:7,e:"b",f:[{t:2,x:{r:["data.idsstatus"],s:'_0?"ENABLED":"DISABLED"'},p:[65,7,1957]}]}]}," ",{p:[68,3,2029],t:7,e:"ui-section",a:{label:"Maximal Log Count"},f:[{p:[69,4,2072],t:7,e:"b",f:[{t:2,r:"data.ntnetmaxlogs",p:[69,7,2075]}]}]}," ",{p:[72,3,2125],t:7,e:"ui-section",a:{label:"Controls"},f:[]}," ",{p:[74,4,2176],t:7,e:"table",f:[{p:[75,4,2188],t:7,e:"tr",f:[{p:[75,8,2192],t:7,e:"td",f:[{p:[75,12,2196],t:7,e:"ui-button",a:{action:"resetIDS"},f:["RESET IDS"]}]}]},{p:[76,4,2251],t:7,e:"tr",f:[{p:[76,8,2255],t:7,e:"td",f:[{p:[76,12,2259],t:7,e:"ui-button",a:{action:"toggleIDS"},f:["TOGGLE IDS"]}]}]},{p:[77,4,2316],t:7,e:"tr",f:[{p:[77,8,2320],t:7,e:"td",f:[{p:[77,12,2324],t:7,e:"ui-button",a:{action:"updatemaxlogs"},f:["SET LOG LIMIT"]}]}]},{p:[78,4,2388],t:7,e:"tr",f:[{p:[78,8,2392],t:7,e:"td",f:[{p:[78,12,2396],t:7,e:"ui-button",a:{action:"purgelogs"},f:["PURGE LOGS"]}]}]}]}," ",{p:[81,3,2467],t:7,e:"ui-subdisplay",a:{title:"System Logs"},f:[{p:[82,3,2506],t:7,e:"div",a:{"class":"statusDisplay",style:"overflow: auto;"},f:[{p:[83,3,2561],t:7,e:"div",a:{"class":"item"},f:[{p:[84,4,2584],t:7,e:"div",a:{"class":"itemContent",style:"width: 100%;"},f:[{t:4,f:[{t:2,r:"entry",p:[86,6,2667]},{p:[86,15,2676],t:7,e:"br"}],n:52,r:"data.ntnetlogs",p:[85,5,2636]}]}]}]}]}]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],279:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:[{p:[7,2,102],t:7,e:"div",a:{"class":"item"},f:[{p:[8,3,124],t:7,e:"h2",f:["An error has occurred during operation..."]}," ",{p:[9,3,178],t:7,e:"b",f:["Additional information:"]},{t:2,r:"data.error",p:[9,34,209]},{p:[9,48,223],t:7,e:"br"}," ",{p:[10,3,231],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Clear"]}]}],n:50,r:"data.error",p:[6,2,81]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.downloading"],s:"_0"},f:[{p:[13,3,321],t:7,e:"h2",f:["Download in progress..."]}," ",{p:[14,3,357],t:7,e:"div",a:{"class":"itemLabel"},f:["Downloaded file:"]}," ",{p:[17,3,416],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.download_name",p:[18,4,446]}]}," ",{p:[20,3,483],t:7,e:"div",a:{"class":"itemLabel"},f:["Download progress:"]}," ",{p:[23,3,544],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.download_progress",p:[24,4,574]}," / ",{t:2,r:"data.download_size",p:[24,33,603]}," GQ"]}," ",{p:[26,3,642],t:7,e:"div",a:{"class":"itemLabel"},f:["Transfer speed:"]}," ",{p:[29,3,700],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.download_netspeed",p:[30,4,730]},"GQ/s"]}," ",{p:[32,3,774],t:7,e:"div",a:{"class":"itemLabel"},f:["Controls:"]}," ",{p:[35,3,826],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[36,4,856],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Abort download"]}]}]},{t:4,n:50,x:{r:["data.downloading","data.uploading"],s:"(!(_0))&&(_1)"},f:[" ",{p:[39,3,954],t:7,e:"h2",f:["Server enabled"]}," ",{p:[40,3,981],t:7,e:"div",a:{"class":"itemLabel"},f:["Connected clients:"]}," ",{p:[43,3,1042],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.upload_clients",p:[44,4,1072]}]}," ",{p:[46,3,1109],t:7,e:"div",a:{"class":"itemLabel"},f:["Provided file:"]}," ",{p:[49,3,1166],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.upload_filename",p:[50,4,1196]}]}," ",{p:[52,3,1234],t:7,e:"div",a:{"class":"itemLabel"},f:["Server password:"]}," ",{p:[55,3,1293],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:["ENABLED"],n:50,r:"data.upload_haspassword",p:[56,4,1323]},{t:4,n:51,f:["DISABLED"],r:"data.upload_haspassword"}]}," ",{p:[62,3,1420],t:7,e:"div",a:{"class":"itemLabel"},f:["Commands:"]}," ",{p:[65,3,1472],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[66,4,1502],t:7,e:"ui-button",a:{action:"PRG_setpassword"},f:["Set password"]}," ",{p:[67,4,1567],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Exit server"]}]}]},{t:4,n:50,x:{r:["data.downloading","data.uploading","data.upload_filelist"],s:"(!(_0))&&((!(_1))&&(_2))"},f:[" ",{p:[70,3,1668],t:7,e:"h2",f:["File transfer server ready. Select file to upload:"]}," ",{p:[71,3,1732],t:7,e:"table",f:[{p:[72,3,1743],t:7,e:"tr",f:[{p:[72,7,1747],t:7,e:"th",f:["File name"]},{p:[72,20,1760],t:7,e:"th",f:["File size"]},{p:[72,33,1773],t:7,e:"th",f:["Controls ",{t:4,f:[{p:[74,4,1824],t:7,e:"tr",f:[{p:[74,8,1828],t:7,e:"td",f:[{t:2,r:"filename",p:[74,12,1832]}]},{p:[75,4,1849],t:7,e:"td",f:[{t:2,r:"size",p:[75,8,1853]},"GQ"]},{p:[76,4,1868],t:7,e:"td",f:[{p:[76,8,1872],t:7,e:"ui-button",a:{action:"PRG_uploadfile",params:['{"id": "',{t:2,r:"uid",p:[76,59,1923]},'"}']},f:["Select"]}]}]}],n:52,r:"data.upload_filelist",p:[73,3,1789]}]}]}]}," ",{p:[79,3,1981],t:7,e:"hr"}," ",{p:[80,3,1989],t:7,e:"ui-button",a:{action:"PRG_setpassword"},f:["Set password"]}," ",{p:[81,3,2053],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Return"]}]},{t:4,n:50,x:{r:["data.downloading","data.uploading","data.upload_filelist"],s:"(!(_0))&&((!(_1))&&(!(_2)))"},f:[" ",{p:[83,3,2116],t:7,e:"h2",f:["Available files:"]}," ",{p:[84,3,2145],t:7,e:"table",a:{border:"1",style:"border-collapse: collapse"},f:[{p:[84,55,2197],t:7,e:"tr",f:[{p:[84,59,2201],t:7,e:"th",f:["Server UID"]},{p:[84,73,2215],t:7,e:"th",f:["File Name"]},{p:[84,86,2228],t:7,e:"th",f:["File Size"]},{p:[84,99,2241],t:7,e:"th",f:["Password Protection"]},{p:[84,122,2264],t:7,e:"th",f:["Operations ",{t:4,f:[{p:[86,5,2311],t:7,e:"tr",f:[{p:[86,9,2315],t:7,e:"td",f:[{t:2,r:"uid",p:[86,13,2319]}]},{p:[87,5,2332],t:7,e:"td",f:[{t:2,r:"filename",p:[87,9,2336]}]},{p:[88,5,2354],t:7,e:"td",f:[{t:2,r:"size",p:[88,9,2358]},"GQ ",{t:4,f:[{p:[90,6,2400],t:7,e:"td",f:["Enabled"]}],n:50,r:"haspassword",p:[89,5,2374]}," ",{t:4,f:[{p:[93,6,2457],t:7,e:"td",f:["Disabled"]}],n:50,x:{r:["haspassword"],s:"!_0"},p:[92,5,2430]}]},{p:[96,5,2494],t:7,e:"td",f:[{p:[96,9,2498],t:7,e:"ui-button",a:{action:"PRG_downloadfile",params:['{"id": "',{t:2,r:"uid",p:[96,62,2551]},'"}']},f:["Download"]}]}]}],n:52,r:"data.servers",p:[85,4,2283]}]}]}]}," ",{p:[99,3,2612],t:7,e:"hr"}," ",{p:[100,3,2620],t:7,e:"ui-button",a:{action:"PRG_uploadmenu"},f:["Send file"]}]}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],280:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{chargingState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}},chargingMode:function(t){return 2==t?"Full":1==t?"Charging":"Draining"},channelState:function(t){return t>=2?"good":"bad"},channelPower:function(t){return t>=2?"On":"Off"},channelMode:function(t){return 1==t||3==t?"Auto":"Manual"}},computed:{graphData:function(){var t=this.get("data.history");return Object.keys(t).map(function(e){return t[e].map(function(t,e){return{x:e,y:t}})})}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[43,1,1082],t:7,e:"ntosheader"}," ",{p:[45,1,1099],t:7,e:"ui-display",a:{title:"Network"},f:[{t:4,f:[{p:[47,5,1157],t:7,e:"ui-linegraph",a:{points:[{t:2,r:"graphData",p:[47,27,1179]}],height:"500",legend:'["Available", "Load"]',colors:'["rgb(0, 102, 0)", "rgb(153, 0, 0)"]',xunit:"seconds ago",xfactor:[{t:2,r:"data.interval",p:[49,38,1331]}],yunit:"W",yfactor:"1",xinc:[{t:2,x:{r:["data.stored"],s:"_0/10"},p:[50,15,1387]}],yinc:"9"}}],n:50,r:"config.fancy",p:[46,3,1131]},{t:4,n:51,f:[{p:[52,5,1437],t:7,e:"ui-section",a:{label:"Available"},f:[{p:[53,7,1475],t:7,e:"span",f:[{t:2,r:"data.supply",p:[53,13,1481]}]}]}," ",{p:[55,5,1528],t:7,e:"ui-section",a:{label:"Load"},f:[{p:[56,9,1563],t:7,e:"span",f:[{t:2,r:"data.demand",p:[56,15,1569]}]}]}],r:"config.fancy"}]}," ",{p:[60,1,1638],t:7,e:"ui-display",a:{title:"Areas"},f:[{p:[61,3,1668],t:7,e:"ui-section",a:{nowrap:0},f:[{p:[62,5,1693],t:7,e:"div",a:{"class":"content"},f:["Area"]}," ",{p:[63,5,1730],t:7,e:"div",a:{"class":"content"},f:["Charge"]}," ",{p:[64,5,1769],t:7,e:"div",a:{"class":"content"},f:["Load"]}," ",{p:[65,5,1806],t:7,e:"div",a:{"class":"content"},f:["Status"]}," ",{p:[66,5,1845],t:7,e:"div",a:{"class":"content"},f:["Equipment"]}," ",{p:[67,5,1887],t:7,e:"div",a:{"class":"content"},f:["Lighting"]}," ",{p:[68,5,1928],t:7,e:"div",a:{"class":"content"},f:["Environment"]}]}," ",{t:4,f:[{p:[71,5,2013],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[71,24,2032]}],nowrap:0},f:[{p:[72,7,2057],t:7,e:"div",a:{"class":"content"},f:[{t:2,x:{r:["@index","adata.areas"],s:"Math.round(_1[_0].charge)"},p:[72,28,2078]}," %"]}," ",{p:[73,7,2136],t:7,e:"div",a:{"class":"content"},f:[{t:2,rx:{r:"adata.areas",m:[{t:30,n:"@index"},"load"]},p:[73,28,2157]}]}," ",{p:[74,7,2199],t:7,e:"div",a:{"class":"content"},f:[{p:[74,28,2220],t:7,e:"span",a:{"class":[{t:2,x:{r:["chargingState","charging"],s:"_0(_1)"},p:[74,41,2233]}]},f:[{t:2,x:{r:["chargingMode","charging"],s:"_0(_1)"},p:[74,70,2262]}]}]}," ",{p:[75,7,2309],t:7,e:"div",a:{"class":"content"},f:[{p:[75,28,2330],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","eqp"],s:"_0(_1)"},p:[75,41,2343]}]},f:[{t:2,x:{r:["channelPower","eqp"],s:"_0(_1)"},p:[75,64,2366]}," [",{p:[75,87,2389],t:7,e:"span",f:[{t:2,x:{r:["channelMode","eqp"],s:"_0(_1)"},p:[75,93,2395]}]},"]"]}]}," ",{p:[76,7,2444],t:7,e:"div",a:{"class":"content"},f:[{p:[76,28,2465],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","lgt"],s:"_0(_1)"},p:[76,41,2478]}]},f:[{t:2,x:{r:["channelPower","lgt"],s:"_0(_1)"},p:[76,64,2501]}," [",{p:[76,87,2524],t:7,e:"span",f:[{t:2,x:{r:["channelMode","lgt"],s:"_0(_1)"},p:[76,93,2530]}]},"]"]}]}," ",{p:[77,7,2579],t:7,e:"div",a:{"class":"content"},f:[{p:[77,28,2600],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","env"],s:"_0(_1)"},p:[77,41,2613]}]},f:[{t:2,x:{r:["channelPower","env"],s:"_0(_1)"},p:[77,64,2636]}," [",{p:[77,87,2659],t:7,e:"span",f:[{t:2,x:{r:["channelMode","env"],s:"_0(_1)"},p:[77,93,2665]}]},"]"]}]}]}],n:52,r:"data.areas",p:[70,3,1987]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],281:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[5,2,79],t:7,e:"div",a:{"class":"item"},f:[{p:[6,3,101],t:7,e:"div",a:{"class":"itemLabel"},f:["Payload status:"]}," ",{p:[9,3,158],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:["ARMED"],n:50,r:"data.armed",p:[10,4,188]},{t:4,n:51,f:["DISARMED"],r:"data.armed"}]}," ",{p:[16,3,270],t:7,e:"div",a:{"class":"itemLabel"},f:["Controls:"]}," ",{p:[19,3,321],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[20,4,351],t:7,e:"table",f:[{p:[21,4,363],t:7,e:"tr",f:[{p:[21,8,367],t:7,e:"td",f:[{p:[21,12,371],t:7,e:"ui-button",a:{action:"PRG_obfuscate"},f:["OBFUSCATE PROGRAM NAME"]}]}]},{p:[22,4,444],t:7,e:"tr",f:[{p:[22,8,448],t:7,e:"td",f:[{p:[22,12,452],t:7,e:"ui-button",a:{action:"PRG_arm",state:[{t:2,x:{r:["data.armed"],s:'_0?"danger":null'},p:[22,47,487]}]},f:[{t:2,x:{r:["data.armed"],s:'_0?"DISARM":"ARM"'},p:[22,81,521]}]}," ",{p:[23,4,571],t:7,e:"ui-button",a:{icon:"radiation",state:[{t:2,x:{r:["data.armed"],s:'_0?null:"disabled"'},p:[23,39,606]}],action:"PRG_activate"},f:["ACTIVATE"]}]}]}]}]}]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],282:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[5,3,95],t:7,e:"ui-display",a:{title:[{t:2,r:"class",p:[5,22,114]}," Alarms"]},f:[{p:[6,5,138],t:7,e:"ul",f:[{t:4,f:[{p:[8,9,171],t:7,e:"li",f:[{t:2,r:".",p:[8,13,175]}]}],n:52,r:".",p:[7,7,150]},{t:4,n:51,f:[{p:[10,9,211],t:7,e:"li",f:["System Nominal"]}],r:"."}]}]}],n:52,i:"class",r:"data.alarms",p:[4,1,64]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],283:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{integState:function(t){var e=100;return t==e?"good":t>e/2?"average":"bad"},bigState:function(t,e,n){return charge>n?"bad":t>e?"average":"good"}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[23,1,421],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[27,2,462],t:7,e:"ui-button",a:{action:"PRG_clear"},f:["Back to Menu"]},{p:[27,56,516],t:7,e:"br"}," ",{p:[28,3,524],t:7,e:"ui-display",a:{title:"Supermatter Status:"},f:[{p:[29,3,568],t:7,e:"ui-section",a:{label:"Core Integrity"},f:[{p:[30,5,609],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"adata.SM_integrity",p:[30,38,642]}],state:[{t:2,x:{r:["integState","adata.SM_integrity"],s:"_0(_1)"},p:[30,69,673]}]},f:[{t:2,r:"data.SM_integrity",p:[30,105,709]},"%"]}]}," ",{p:[32,3,761],t:7,e:"ui-section",a:{label:"Relative EER"},f:[{p:[33,5,800],t:7,e:"span",a:{"class":[{t:2,x:{r:["bigState","data.SM_power"],s:"_0(_1,150,300)"},p:[33,18,813]}]},f:[{t:2,r:"data.SM_power",p:[33,55,850]}," MeV/cm3"]}]}," ",{p:[35,3,903],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[36,5,941],t:7,e:"span",a:{"class":[{t:2,x:{r:["bigState","data.SM_ambienttemp"],s:"_0(_1,4000,5000)"},p:[36,18,954]}]},f:[{t:2,r:"data.SM_ambienttemp",p:[36,63,999]}," K"]}]}," ",{p:[38,3,1052],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[39,5,1087],t:7,e:"span",a:{"class":[{t:2,x:{r:["bigState","data.SM_ambientpressure"],s:"_0(_1,5000,10000)"},p:[39,18,1100]}]},f:[{t:2,r:"data.SM_ambientpressure",p:[39,68,1150]}," kPa"]}]}]}," ",{p:[42,3,1227],t:7,e:"hr"},{p:[42,7,1231],t:7,e:"br"}," ",{p:[43,3,1239],t:7,e:"ui-display",a:{title:"Gas Composition:"},f:[{t:4,f:[{p:[45,5,1307],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[45,24,1326]}]},f:[{t:2,r:"amount",p:[46,6,1343]}," %"]}],n:52,r:"data.gases",p:[44,4,1281]}]}],n:50,r:"data.active",p:[26,1,440]},{t:4,n:51,f:[{p:[51,2,1418],t:7,e:"ui-button",a:{action:"PRG_refresh"},f:["Refresh"]},{p:[51,53,1469],t:7,e:"br"}," ",{p:[52,2,1476],t:7,e:"ui-display",a:{title:"Detected Supermatters"},f:[{t:4,f:[{p:[54,3,1552],t:7,e:"ui-section",a:{label:"Area"},f:[{t:2,r:"area_name",p:[55,5,1583]}," - (#",{t:2,r:"uid",p:[55,23,1601]},")"]}," ",{p:[57,3,1630],t:7,e:"ui-section",a:{label:"Integrity"},f:[{t:2,r:"integrity",p:[58,5,1666]}," %"]}," ",{p:[60,3,1702],t:7,e:"ui-section",a:{label:"Options"},f:[{p:[61,5,1736],t:7,e:"ui-button",a:{action:"PRG_set",params:['{"target" : "',{t:2,r:"uid",p:[61,54,1785]},'"}']},f:["View Details"]}]}],n:52,r:"data.supermatters",p:[53,2,1521]}]}],r:"data.active"}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],284:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"div",a:{"class":"item",style:"float: left"},f:[{p:[2,2,41],t:7,e:"table",f:[{p:[2,9,48],t:7,e:"tr",f:[{t:4,f:[{p:[4,3,113],t:7,e:"td",f:[{p:[4,7,117],t:7,e:"img",a:{src:[{t:2,r:"data.PC_batteryicon",p:[4,17,127]}]}}]}],n:50,x:{r:["data.PC_batteryicon","data.PC_showbatteryicon"],s:"_0&&_1"},p:[3,2,55]}," ",{t:4,f:[{p:[7,3,226],t:7,e:"td",f:[{p:[7,7,230],t:7,e:"b",f:[{t:2,r:"data.PC_batterypercent",p:[7,10,233]}]}]}],n:50,x:{r:["data.PC_batterypercent","data.PC_showbatteryicon"],s:"_0&&_1"},p:[6,2,165]}," ",{t:4,f:[{p:[10,3,305],t:7,e:"td",f:[{p:[10,7,309],t:7,e:"img",a:{src:[{t:2,r:"data.PC_ntneticon",p:[10,17,319]}]}}]}],n:50,r:"data.PC_ntneticon",p:[9,2,276]}," ",{t:4,f:[{p:[13,3,386],t:7,e:"td",f:[{p:[13,7,390],t:7,e:"img",a:{src:[{t:2,r:"data.PC_apclinkicon",p:[13,17,400]}]}}]}],n:50,r:"data.PC_apclinkicon",p:[12,2,355]}," ",{t:4,f:[{p:[16,3,469],t:7,e:"td",f:[{p:[16,7,473],t:7,e:"b",f:[{t:2,r:"data.PC_stationtime",p:[16,10,476]}]}]}],n:50,r:"data.PC_stationtime",p:[15,2,438]}," ",{t:4,f:[{p:[19,3,552],t:7,e:"td",f:[{p:[19,7,556],t:7,e:"img",a:{src:[{t:2,r:"icon",p:[19,17,566]}]}}]}],n:52,r:"data.PC_programheaders",p:[18,2,516]}]}]}]}," ",{p:[23,1,609],t:7,e:"div",a:{style:"float: right; margin-top: 5px"},f:[{p:[24,2,655],t:7,e:"ui-button",a:{action:"PC_shutdown"},f:["Shutdown"]}," ",{t:4,f:[{p:[26,3,745],t:7,e:"ui-button",a:{action:"PC_exit"},f:["EXIT PROGRAM"]}," ",{p:[27,3,801],t:7,e:"ui-button",a:{action:"PC_minimize"},f:["Minimize Program"]}],n:50,r:"data.PC_showexitprogram",p:[25,2,710]}]}," ",{p:[30,1,881],t:7,e:"div",a:{style:"clear: both"}}]},e.exports=a.extend(r.exports)},{205:205}],285:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Auth. Disk:"},f:[{t:4,f:[{p:[3,7,69],t:7,e:"ui-button",a:{icon:"eject",style:"selected",action:"eject_disk"},f:["++++++++++"]}],n:50,r:"data.disk_present",p:[2,3,36]},{t:4,n:51,f:[{p:[5,7,172],t:7,e:"ui-button",a:{icon:"plus",action:"insert_disk"},f:["----------"]}],r:"data.disk_present"}]}," ",{p:[8,1,266],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[9,3,297],t:7,e:"span",f:[{t:2,r:"data.status1",p:[9,9,303]},"-",{t:2,r:"data.status2",p:[9,26,320]}]}]}," ",{p:[11,1,360],t:7,e:"ui-display",a:{title:"Timer"},f:[{p:[12,3,390],t:7,e:"ui-section",a:{label:"Time to Detonation"},f:[{p:[13,5,435],t:7,e:"span",f:[{t:2,x:{r:["data.timing","data.time_left","data.timer_set"],s:"_0?_1:_2"},p:[13,11,441]}]}]}," ",{t:4,f:[{p:[16,5,540],t:7,e:"ui-section",a:{label:"Adjust Timer"},f:[{p:[17,7,581],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.timer_is_not_default"],s:'_0&&_1&&_2?null:"disabled"'},p:[17,40,614]}],action:"timer",params:'{"change": "reset"}'},f:["Reset"]}," ",{p:[19,7,786],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.timer_is_not_min"],s:'_0&&_1&&_2?null:"disabled"'},p:[19,38,817]}],action:"timer",params:'{"change": "decrease"}'},f:["Decrease"]}," ",{p:[21,7,991],t:7,e:"ui-button",a:{icon:"pencil",state:[{t:2,x:{r:["data.disk_present","data.code_approved"],s:'_0&&_1?null:"disabled"'},p:[21,39,1023]}],action:"timer",params:'{"change": "input"}'},f:["Set"]}," ",{p:[22,7,1155],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.timer_is_not_max"],s:'_0&&_1&&_2?null:"disabled"'},p:[22,37,1185]}],action:"timer",params:'{"change": "increase"}'},f:["Increase"]}]}],n:51,r:"data.timing",p:[15,3,518]}," ",{p:[26,3,1394],t:7,e:"ui-section",a:{label:"Timer"},f:[{p:[27,5,1426],t:7,e:"ui-button",a:{icon:"clock-o",style:[{t:2,x:{r:["data.timing"],s:'_0?"danger":"caution"'},p:[27,38,1459]}],action:"toggle_timer",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.safety"],s:'_0&&_1&&!_2?null:"disabled"'},p:[29,14,1542]}]},f:[{t:2,x:{r:["data.timing"],s:'_0?"On":"Off"'},p:[30,7,1631]}]}]}]}," ",{p:[34,1,1713],t:7,e:"ui-display",a:{title:"Anchoring"},f:[{p:[35,3,1747],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.disk_present","data.code_approved"],s:'_0&&_1?null:"disabled"'},p:[36,12,1770]}],icon:[{t:2,x:{r:["data.anchored"],s:'_0?"lock":"unlock"'},p:[37,11,1846]}],style:[{t:2,x:{r:["data.anchored"],s:'_0?null:"caution"'},p:[38,12,1897]}],action:"anchor"},f:[{t:2,x:{r:["data.anchored"],s:'_0?"Engaged":"Off"'},p:[39,21,1956]}]}]}," ",{p:[41,1,2022],t:7,e:"ui-display",a:{title:"Safety"},f:[{p:[42,3,2053],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.disk_present","data.code_approved"],s:'_0&&_1?null:"disabled"'},p:[43,12,2076]}],icon:[{t:2,x:{r:["data.safety"],s:'_0?"lock":"unlock"'},p:[44,11,2152]}],action:"safety",style:[{t:2,x:{r:["data.safety"],s:'_0?"caution":"danger"'},p:[45,12,2217]}]},f:[{p:[46,7,2265],t:7,e:"span",f:[{t:2,x:{r:["data.safety"],s:'_0?"On":"Off"'},p:[46,13,2271]}]}]}]}," ",{p:[49,1,2341],t:7,e:"ui-display",a:{title:"Code"},f:[{p:[50,3,2370],t:7,e:"ui-section",a:{label:"Message"},f:[{t:2,r:"data.message",p:[50,31,2398]}]}," ",{p:[51,3,2431],t:7,e:"ui-section",a:{label:"Keypad"},f:[{p:[52,5,2464],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[52,39,2498]}],params:'{"digit":"1"}'},f:["1"]}," ",{p:[53,5,2583],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[53,39,2617]}],params:'{"digit":"2"}'},f:["2"]}," ",{p:[54,5,2702],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[54,39,2736]}],params:'{"digit":"3"}'},f:["3"]}," ",{p:[55,5,2821],t:7,e:"br"}," ",{p:[56,5,2831],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[56,39,2865]}],params:'{"digit":"4"}'},f:["4"]}," ",{p:[57,5,2950],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[57,39,2984]}],params:'{"digit":"5"}'},f:["5"]}," ",{p:[58,5,3069],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[58,39,3103]}],params:'{"digit":"6"}'},f:["6"]}," ",{p:[59,5,3188],t:7,e:"br"}," ",{p:[60,5,3198],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[60,39,3232]}],params:'{"digit":"7"}'},f:["7"]}," ",{p:[61,5,3317],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[61,39,3351]}],params:'{"digit":"8"}'},f:["8"]}," ",{p:[62,5,3436],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[62,39,3470]}],params:'{"digit":"9"}'},f:["9"]}," ",{p:[63,5,3555],t:7,e:"br"}," ",{p:[64,5,3565],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[64,39,3599]}],params:'{"digit":"R"}'},f:["R"]}," ",{p:[65,5,3684],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[65,39,3718]}],params:'{"digit":"0"}'},f:["0"]}," ",{p:[66,5,3803],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[66,39,3837]}],params:'{"digit":"E"}'},f:["E"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],286:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,25],t:7,e:"ui-notice",f:["No table detected!"]}],n:51,r:"data.table",p:[1,1,0]},{p:[6,1,88],t:7,e:"ui-display",f:[{p:[7,2,103],t:7,e:"ui-display",a:{title:"Patient State"},f:[{t:4,f:[{p:[9,4,166],t:7,e:"ui-section",a:{label:"State"},f:[{p:[10,5,198],t:7,e:"span",a:{"class":[{t:2,r:"data.patient.statstate",p:[10,18,211]}]},f:[{t:2,r:"data.patient.stat",p:[10,46,239]}]}]}," ",{p:[12,4,290],t:7,e:"ui-section",a:{label:"Blood Type"},f:[{p:[13,5,327],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.patient.blood_type",p:[13,27,349]}]}]}," ",{p:[15,4,406],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[16,5,439],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.patient.minHealth",p:[16,18,452]}],max:[{t:2,r:"data.patient.maxHealth",p:[16,51,485]}],value:[{t:2,r:"data.patient.health",p:[16,86,520]}],state:[{t:2,x:{r:["data.patient.health"],s:'_0>=0?"good":"average"'},p:[17,12,557]}]},f:[{t:2,x:{r:["adata.patient.health"],s:"Math.round(_0)"},p:[17,63,608]}]}]}," ",{t:4,f:[{p:[20,5,840],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[20,24,859]}]},f:[{p:[21,6,877],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.patient.maxHealth",p:[21,27,898]}],value:[{t:2,rx:{r:"data.patient",m:[{t:30,n:"type"}]},p:[21,62,933]}],state:"bad"},f:[{t:2,x:{r:["type","adata.patient"],s:"Math.round(_1[_0])"},p:[21,98,969]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Burn",type:"fireLoss"},{label:"Toxin",type:"toxLoss"},{label:"Respiratory",type:"oxyLoss"}]'},p:[19,4,676]}],n:50,r:"data.patient",p:[8,3,141]},{t:4,n:51,f:["No patient detected."],r:"data.patient"}]}," ",{p:[28,2,1113],t:7,e:"ui-display",a:{title:"Initiated Procedures"},f:[{t:4,f:[{t:4,f:[{p:[31,5,1217],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"name",p:[31,27,1239]}]},f:[{p:[32,6,1256],t:7,e:"ui-section",a:{label:"Next Step"},f:[{p:[33,7,1294],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"next_step",p:[33,29,1316]}]}]}," ",{t:4,f:[{p:[36,7,1395],t:7,e:"ui-section",a:{label:"Alternative Step"},f:[{p:[37,8,1441],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"alternative_step",p:[37,30,1463]}]}]}],n:50,r:"alternative_step",p:[35,6,1363]}]}],n:52,r:"data.procedures",p:[30,4,1186]}],n:50,r:"data.procedures",p:[29,3,1158]},{t:4,n:51,f:["No active procedures."],r:"data.procedures"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],287:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,2,15],t:7,e:"ui-section",f:["This machine only accepts ore. Gibtonite and Slag are not accepted."]}," ",{p:[5,2,117],t:7,e:"ui-section",f:["Current unclaimed points: ",{t:2,r:"data.unclaimedPoints",p:[6,29,159]}," ",{t:4,f:[{p:[8,4,220],t:7,e:"ui-button",a:{action:"Claim"},f:["Claim Points"]}],n:50,r:"data.unclaimedPoints",p:[7,3,187]}]}," ",{p:[13,2,311],t:7,e:"ui-section",f:[{t:4,f:[{p:[15,4,350],t:7,e:"ui-button",a:{action:"Eject"},f:["Eject ID"]}," You have ",{t:2,r:"data.claimedPoints",p:[18,13,421]}," mining points collected."],n:50,r:"data.hasID",p:[14,3,327]},{t:4,n:51,f:[{p:[20,4,485],t:7,e:"ui-button",a:{action:"Insert"},f:["Insert ID"]}],r:"data.hasID"}]}]}," ",{p:[26,1,588],t:7,e:"ui-display",f:[{t:4,f:[{p:[28,3,627],t:7,e:"ui-section",f:[{p:[29,4,644],t:7,e:"ui-button",a:{action:"diskEject",icon:"eject"},f:["Eject Disk"]}]}," ",{t:4,f:[{p:[34,4,772],t:7,e:"ui-section",a:{"class":"candystripe"},f:[{p:[35,5,808],t:7,e:"ui-button",a:{action:"diskUpload",state:[{t:2,x:{r:["canupload"],s:'(_0)?null:"disabled"'},p:[35,42,845]}],icon:"upload",align:"right",params:['{ "design" : "',{t:2,r:"index",p:[35,129,932]},'" }']},f:["Upload"]}," File ",{t:2,r:"index",p:[38,10,988]},": ",{t:2,r:"name",p:[38,21,999]}]}],n:52,r:"data.diskDesigns",p:[33,3,741]}],n:50,r:"data.hasDisk",p:[27,2,603]},{t:4,n:51,f:[{p:[42,3,1053],t:7,e:"ui-section",f:[{p:[43,4,1070],t:7,e:"ui-button",a:{action:"diskInsert",icon:"floppy-o"},f:["Insert Disk"]}]}],r:"data.hasDisk"}]}," ",{p:[49,1,1195],t:7,e:"div",a:{"class":"display tabular"},f:[{p:[50,2,1227],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[51,4,1261],t:7,e:"section",a:{"class":"cell"},f:["Mineral"]}," ",{p:[54,4,1316],t:7,e:"section",a:{"class":"cell"},f:["Sheets"]}," ",{p:[57,4,1370],t:7,e:"section",a:{"class":"cell"},f:[]}," ",{p:[59,4,1412],t:7,e:"section",a:{"class":"cell"},f:[{p:[60,5,1440],t:7,e:"ui-button",a:{"class":"center mineral",grid:0,action:"Release",params:'{"id" : "all"}'},f:["Release All"]}]}," ",{p:[64,4,1576],t:7,e:"section",a:{"class":"cell"},f:["Ore Value"]}]}," ",{t:4,f:[{p:[69,3,1673],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[70,4,1707],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[71,5,1735]}]}," ",{p:[73,4,1763],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"amount",p:[74,5,1805]}]}," ",{p:[76,4,1835],t:7,e:"section",a:{"class":"cell"},f:[{p:[77,5,1863],t:7,e:"input",a:{value:[{t:2,r:"sheets",p:[77,18,1876]}],placeholder:"###","class":"number"}}]}," ",{p:[79,4,1941],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{p:[80,5,1983],t:7,e:"ui-button",a:{"class":"center",grid:0,action:"Release",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[80,59,2037]}],params:['{ "id" : ',{t:2,r:"id",p:[80,114,2092]},', "sheets" : ',{t:2,r:"sheets",p:[80,133,2111]}," }"]},f:["Release"]}]}," ",{p:[84,4,2178],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"value",p:[85,5,2220]}]}]}],n:52,r:"data.materials",p:[68,2,1645]}," ",{t:4,f:[{p:[90,3,2298],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[91,4,2332],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[92,5,2360]}]}," ",{p:[94,4,2388],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"amount",p:[95,5,2430]}]}," ",{p:[97,4,2460],t:7,e:"section",a:{"class":"cell"},f:[{p:[98,5,2488],t:7,e:"input",a:{value:[{t:2,r:"sheets",p:[98,18,2501]}],placeholder:"###","class":"number"}}]}," ",{p:[100,4,2566],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{p:[101,5,2608],t:7,e:"ui-button",a:{"class":"center",grid:0,action:"Smelt",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[101,57,2660]}],params:['{ "id" : ',{t:2,r:"id",p:[101,113,2716]},', "sheets" : ',{t:2,r:"sheets",p:[101,132,2735]}," }"]},f:["Smelt"]}]}," ",{p:[105,4,2799],t:7,e:"section", -a:{"class":"cell",align:"right"},f:[{p:[106,5,2841],t:7,e:"ui-button",a:{"class":"center",grid:0,action:"SmeltAll",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[106,60,2896]}],params:['{ "id" : ',{t:2,r:"id",p:[106,116,2952]}," }"]},f:["Smelt All"]}]}]}],n:52,r:"data.alloys",p:[89,2,2273]}]}]},e.exports=a.extend(r.exports)},{205:205}],288:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:{button:[{p:[4,4,87],t:7,e:"ui-button",a:{icon:"remove",state:[{t:2,x:{r:["data.has_beaker"],s:'_0?null:"disabled"'},p:[4,36,119]}],action:"empty_eject_beaker"},f:["Empty and eject"]}," ",{p:[7,4,231],t:7,e:"ui-button",a:{icon:"trash",state:[{t:2,x:{r:["data.has_beaker"],s:'_0?null:"disabled"'},p:[7,35,262]}],action:"empty_beaker"},f:["Empty"]}," ",{p:[10,4,358],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.has_beaker"],s:'_0?null:"disabled"'},p:[10,35,389]}],action:"eject_beaker"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{t:4,f:[{p:[15,4,528],t:7,e:"ui-section",f:[{t:4,f:[{p:[17,6,578],t:7,e:"span",a:{"class":"bad"},f:["The beaker is empty!"]}],n:50,r:"data.beaker_empty",p:[16,5,546]},{t:4,n:51,f:[{p:[19,6,644],t:7,e:"ui-subdisplay",a:{title:"Blood"},f:[{t:4,f:[{p:[21,8,712],t:7,e:"ui-section",a:{label:"Blood DNA"},f:[{t:2,r:"data.blood.dna",p:[21,38,742]}]}," ",{p:[22,8,782],t:7,e:"ui-section",a:{label:"Blood type"},f:[{t:2,r:"data.blood.type",p:[22,39,813]}]}],n:50,r:"data.has_blood",p:[20,7,681]},{t:4,n:51,f:[{p:[24,8,870],t:7,e:"ui-section",f:[{p:[25,9,892],t:7,e:"span",a:{"class":"average"},f:["No blood sample detected."]}]}],r:"data.has_blood"}]}],r:"data.beaker_empty"}]}],n:50,r:"data.has_beaker",p:[14,3,500]},{t:4,n:51,f:[{p:[32,4,1054],t:7,e:"ui-section",f:[{p:[33,5,1072],t:7,e:"span",a:{"class":"bad"},f:["No beaker loaded."]}]}],r:"data.has_beaker"}]}," ",{t:4,f:[{p:[38,3,1188],t:7,e:"ui-display",a:{title:"Diseases"},f:[{t:4,f:[{p:{button:[{t:4,f:[{p:[43,8,1343],t:7,e:"ui-button",a:{icon:"pencil",action:"rename_disease",state:[{t:2,x:{r:["can_rename"],s:'_0?"":"disabled"'},p:[43,64,1399]}],params:['{"index": ',{t:2,r:"index",p:[43,116,1451]},"}"]},f:["Name advanced disease"]}],n:50,r:"is_adv",p:[42,7,1320]}," ",{p:[47,7,1538],t:7,e:"ui-button",a:{icon:"flask",action:"create_culture_bottle",state:[{t:2,x:{r:["data.is_ready"],s:'_0?"":"disabled"'},p:[47,69,1600]}],params:['{"index": ',{t:2,r:"index",p:[47,124,1655]},"}"]},f:["Create virus culture bottle"]}]},t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[40,24,1269]}],button:0},f:[" ",{p:[51,6,1749],t:7,e:"ui-section",a:{label:"Disease agent"},f:[{t:2,r:"agent",p:[51,40,1783]}]}," ",{p:[52,6,1812],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"description",p:[52,38,1844]}]}," ",{p:[53,6,1879],t:7,e:"ui-section",a:{label:"Spread"},f:[{t:2,r:"spread",p:[53,33,1906]}]}," ",{p:[54,6,1936],t:7,e:"ui-section",a:{label:"Possible cure"},f:[{t:2,r:"cure",p:[54,40,1970]}]}," ",{t:4,f:[{p:[56,7,2021],t:7,e:"ui-section",a:{label:"Symptoms"},f:[{t:4,f:[{p:[58,9,2087],t:7,e:"ui-button",a:{action:"symptom_details",state:"",params:['{"picked_symptom": ',{t:2,r:"sym_index",p:[58,81,2159]},', "index": ',{t:2,r:"index",p:[58,105,2183]},"}"]},f:[{t:2,r:"name",p:[59,10,2206]}," "]},{p:[60,21,2236],t:7,e:"br"}],n:52,r:"symptoms",p:[57,8,2059]}]}," ",{p:[63,7,2289],t:7,e:"ui-section",a:{label:"Resistance"},f:[{t:2,r:"resistance",p:[63,38,2320]}]}," ",{p:[64,7,2355],t:7,e:"ui-section",a:{label:"Stealth"},f:[{t:2,r:"stealth",p:[64,35,2383]}]}," ",{p:[65,7,2415],t:7,e:"ui-section",a:{label:"Stage speed"},f:[{t:2,r:"stage_speed",p:[65,39,2447]}]}," ",{p:[66,7,2483],t:7,e:"ui-section",a:{label:"Transmittability"},f:[{t:2,r:"transmission",p:[66,44,2520]}]}],n:50,r:"is_adv",p:[55,6,1999]}]}],n:52,r:"data.viruses",p:[39,4,1222]},{t:4,n:51,f:[{p:[70,5,2601],t:7,e:"ui-section",f:[{p:[71,6,2620],t:7,e:"span",a:{"class":"average"},f:["No detectable virus in the blood sample."]}]}],r:"data.viruses"}]}," ",{p:[75,3,2743],t:7,e:"ui-display",a:{title:"Antibodies"},f:[{t:4,f:[{p:[77,5,2811],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[77,24,2830]}]},f:[{p:[78,7,2848],t:7,e:"ui-button",a:{icon:"eyedropper",state:[{t:2,x:{r:["data.is_ready"],s:'_0?"":"disabled"'},p:[78,43,2884]}],action:"create_vaccine_bottle",params:['{"index": ',{t:2,r:"id",p:[78,129,2970]},"}"]},f:["Create vaccine bottle"]}]}],n:52,r:"data.resistances",p:[76,4,2779]},{t:4,n:51,f:[{p:[83,5,3067],t:7,e:"ui-section",f:[{p:[84,6,3086],t:7,e:"span",a:{"class":"average"},f:["No antibodies detected in the blood sample."]}]}],r:"data.resistances"}]}],n:50,r:"data.has_blood",p:[37,2,1162]}],n:50,x:{r:["data.mode"],s:"_0==1"},p:[1,1,0]},{t:4,n:51,f:[{p:[90,2,3231],t:7,e:"ui-button",a:{icon:"undo",state:"",action:"back"},f:["Back"]}," ",{t:4,f:[{p:[94,4,3330],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[94,23,3349]}]},f:[{p:[95,4,3364],t:7,e:"ui-section",f:[{t:2,r:"desc",p:[96,5,3382]}," ",{t:4,f:[{p:[98,5,3417],t:7,e:"br"}," ",{p:[99,5,3428],t:7,e:"b",f:["This symptom has been neutered, and has no effect. It will still affect the virus' statistics."]}],n:50,r:"neutered",p:[97,4,3395]}]}," ",{p:[102,4,3564],t:7,e:"ui-section",f:[{p:[103,5,3582],t:7,e:"ui-section",a:{label:"Level"},f:[{t:2,r:"level",p:[103,31,3608]}]}," ",{p:[104,5,3636],t:7,e:"ui-section",a:{label:"Resistance"},f:[{t:2,r:"resistance",p:[104,36,3667]}]}," ",{p:[105,5,3700],t:7,e:"ui-section",a:{label:"Stealth"},f:[{t:2,r:"stealth",p:[105,33,3728]}]}," ",{p:[106,5,3758],t:7,e:"ui-section",a:{label:"Stage speed"},f:[{t:2,r:"stage_speed",p:[106,37,3790]}]}," ",{p:[107,5,3824],t:7,e:"ui-section",a:{label:"Transmittability"},f:[{t:2,r:"transmission",p:[107,42,3861]}]}]}," ",{p:[109,4,3913],t:7,e:"ui-subdisplay",a:{title:"Effect Thresholds"},f:[{p:[110,5,3960],t:7,e:"ui-section",f:[{t:3,r:"threshold_desc",p:[110,17,3972]}]}]}]}],n:53,r:"data.symptom",p:[93,2,3303]}],x:{r:["data.mode"],s:"_0==1"}}]},e.exports=a.extend(r.exports)},{205:205}],289:[function(t,e,n){var a=t(205),r={exports:{}};!function(e){"use strict";var n=t(327);e.exports={data:{filter:"",tooltiptext:function(t,e,n){var a="";return t&&(a+="REQUIREMENTS: "+t+" "),e&&(a+="CATALYSTS: "+e+" "),n&&(a+="TOOLS: "+n),a}},oninit:function(){var t=this;this.on({hover:function(t){this.set("hovered",t.context.params)},unhover:function(t){this.set("hovered")}}),this.observe("filter",function(e,a,r){var i=null;i=t.get("data.display_compact")?t.findAll(".section"):t.findAll(".display:not(:first-child)"),(0,n.filterMulti)(i,t.get("filter").toLowerCase())},{init:!1})}}}(r),r.exports.template={v:3,t:[" ",{p:[48,1,1342],t:7,e:"ui-display",a:{title:[{t:2,r:"data.category",p:[48,20,1361]},{t:4,f:[" : ",{t:2,r:"data.subcategory",p:[48,64,1405]}],n:50,r:"data.subcategory",p:[48,37,1378]}]},f:[{t:4,f:[{p:[50,3,1459],t:7,e:"ui-section",f:["Crafting... ",{p:[51,16,1488],t:7,e:"i",a:{"class":"fa-spin fa fa-spinner"}}]}],n:50,r:"data.busy",p:[49,2,1438]},{t:4,n:51,f:[{p:[54,3,1557],t:7,e:"ui-section",f:[{p:[55,4,1574],t:7,e:"table",a:{style:"width:100%"},f:[{p:[56,5,1606],t:7,e:"tr",f:[{p:[57,6,1617],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[58,7,1659],t:7,e:"ui-button",a:{icon:"arrow-left",action:"backwardCat"},f:[{t:2,r:"data.prev_cat",p:[59,8,1718]}]}]}," ",{p:[62,6,1774],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[63,7,1816],t:7,e:"ui-button",a:{icon:"arrow-right",action:"forwardCat"},f:[{t:2,r:"data.next_cat",p:[64,7,1874]}]}]}," ",{p:[67,6,1930],t:7,e:"td",a:{style:"float:right!important"},f:[{t:4,f:[{p:[69,7,2014],t:7,e:"ui-button",a:{icon:"lock",action:"toggle_recipes"},f:["Showing Craftable Recipes"]}],n:50,r:"data.display_craftable_only",p:[68,6,1971]},{t:4,n:51,f:[{p:[73,7,2138],t:7,e:"ui-button",a:{icon:"unlock",action:"toggle_recipes"},f:["Showing All Recipes"]}],r:"data.display_craftable_only"}]}," ",{p:[78,6,2268],t:7,e:"td",a:{style:"float:right!important"},f:[{p:[79,7,2310],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.display_compact"],s:'_0?"check-square-o":"square-o"'},p:[79,24,2327]}],action:"toggle_compact"},f:["Compact"]}]}]}," ",{p:[84,5,2474],t:7,e:"tr",f:[{t:4,f:[{p:[86,6,2515],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[87,7,2557],t:7,e:"ui-button",a:{icon:"arrow-left",action:"backwardSubCat"},f:[{t:2,r:"data.prev_subcat",p:[88,8,2619]}]}]}," ",{p:[91,6,2678],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[92,7,2720],t:7,e:"ui-button",a:{icon:"arrow-right",action:"forwardSubCat"},f:[{t:2,r:"data.next_subcat",p:[93,8,2782]}]}]}],n:50,r:"data.subcategory",p:[85,5,2484]}]}]}," ",{t:4,f:[{t:4,f:[" ",{p:[101,6,2992],t:7,e:"ui-input",a:{value:[{t:2,r:"filter",p:[101,23,3009]}],placeholder:"Filter.."}}],n:51,r:"data.display_compact",p:[100,5,2902]}],n:50,r:"config.fancy",p:[99,4,2876]}]}," ",{t:4,f:[{p:[106,5,3144],t:7,e:"ui-display",f:[{t:4,f:[{p:[108,6,3193],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[108,25,3212]}]},f:[{p:[109,7,3230],t:7,e:"ui-button",a:{tooltip:[{t:2,x:{r:["tooltiptext","req_text","catalyst_text","tool_text"],s:"_0(_1,_2,_3)"},p:[109,27,3250]}],"tooltip-side":"right",action:"make",params:['{"recipe": "',{t:2,r:"ref",p:[109,135,3358]},'"}'],icon:"gears"},v:{hover:"hover",unhover:"unhover"},f:["Craft"]}]}],n:52,r:"data.can_craft",p:[107,5,3162]}," ",{t:4,f:[{t:4,f:[{p:[116,7,3567],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[116,26,3586]}]},f:[{p:[117,8,3605],t:7,e:"ui-button",a:{tooltip:[{t:2,x:{r:["tooltiptext","req_text","catalyst_text","tool_text"],s:"_0(_1,_2,_3)"},p:[117,28,3625]}],"tooltip-side":"right",state:"disabled",icon:"gears"},v:{hover:"hover",unhover:"unhover"},f:["Craft"]}]}],n:52,r:"data.cant_craft",p:[115,6,3534]}],n:51,r:"data.display_craftable_only",p:[114,5,3495]}]}],n:50,r:"data.display_compact",p:[105,4,3110]},{t:4,n:51,f:[{t:4,f:[{p:[126,6,3947],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[126,25,3966]}]},f:[{t:4,f:[{p:[128,8,4009],t:7,e:"ui-section",a:{label:"Requirements"},f:[{t:2,r:"req_text",p:[129,9,4052]}]}],n:50,r:"req_text",p:[127,7,3984]}," ",{t:4,f:[{p:[133,8,4139],t:7,e:"ui-section",a:{label:"Catalysts"},f:[{t:2,r:"catalyst_text",p:[134,9,4179]}]}],n:50,r:"catalyst_text",p:[132,7,4109]}," ",{t:4,f:[{p:[138,8,4267],t:7,e:"ui-section",a:{label:"Tools"},f:[{t:2,r:"tool_text",p:[139,9,4303]}]}],n:50,r:"tool_text",p:[137,7,4241]}," ",{p:[142,7,4361],t:7,e:"ui-section",f:[{p:[143,8,4382],t:7,e:"ui-button",a:{icon:"gears",action:"make",params:['{"recipe": "',{t:2,r:"ref",p:[143,66,4440]},'"}']},f:["Craft"]}]}]}],n:52,r:"data.can_craft",p:[125,5,3916]}," ",{t:4,f:[{t:4,f:[{p:[151,7,4621],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[151,26,4640]}]},f:[{t:4,f:[{p:[153,9,4685],t:7,e:"ui-section",a:{label:"Requirements"},f:[{t:2,r:"req_text",p:[154,10,4729]}]}],n:50,r:"req_text",p:[152,8,4659]}," ",{t:4,f:[{p:[158,9,4820],t:7,e:"ui-section",a:{label:"Catalysts"},f:[{t:2,r:"catalyst_text",p:[159,10,4861]}]}],n:50,r:"catalyst_text",p:[157,8,4789]}," ",{t:4,f:[{p:[163,9,4953],t:7,e:"ui-section",a:{label:"Tools"},f:[{t:2,r:"tool_text",p:[164,10,4990]}]}],n:50,r:"tool_text",p:[162,8,4926]}]}],n:52,r:"data.cant_craft",p:[150,6,4588]}],n:51,r:"data.display_craftable_only",p:[149,5,4549]}],r:"data.display_compact"}],r:"data.busy"}]}]},e.exports=a.extend(r.exports)},{205:205,327:327}],290:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,3,15],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.holding"],s:'_0?"is":"is not"'},p:[2,23,35]}," connected to a tank."]}]}," ",{p:[4,1,113],t:7,e:"ui-display",a:{title:"Status",button:0},f:[{p:[5,3,151],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[6,5,186],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[6,11,192]}," kPa"]}]}," ",{p:[8,3,254],t:7,e:"ui-section",a:{label:"Port"},f:[{p:[9,5,285],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected"],s:'_0?"good":"average"'},p:[9,18,298]}]},f:[{t:2,x:{r:["data.connected"],s:'_0?"Connected":"Not Connected"'},p:[9,59,339]}]}]}]}," ",{p:[12,1,430],t:7,e:"ui-display",a:{title:"Pump"},f:[{p:[13,3,459],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[14,5,491],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[14,22,508]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":"null"'},p:[15,14,559]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[16,22,616]}]}]}," ",{p:[18,3,675],t:7,e:"ui-section",a:{label:"Direction"},f:[{p:[19,5,711],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.direction"],s:'_0=="out"?"sign-out":"sign-in"'},p:[19,22,728]}],action:"direction"},f:[{t:2,x:{r:["data.direction"],s:'_0=="out"?"Out":"In"'},p:[20,26,808]}]}]}," ",{p:[22,3,883],t:7,e:"ui-section",a:{label:"Target Pressure"},f:[{p:[23,5,925],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.min_pressure",p:[23,18,938]}],max:[{t:2,r:"data.max_pressure",p:[23,46,966]}],value:[{t:2,r:"data.target_pressure",p:[24,14,1003]}]},f:[{t:2,x:{r:["adata.target_pressure"],s:"Math.round(_0)"},p:[24,40,1029]}," kPa"]}]}," ",{p:[26,3,1100],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[27,5,1145],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.target_pressure","data.default_pressure"],s:'_0!=_1?null:"disabled"'},p:[27,38,1178]}],action:"pressure",params:'{"pressure": "reset"}'},f:["Reset"]}," ",{p:[29,5,1328],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.target_pressure","data.min_pressure"],s:'_0>_1?null:"disabled"'},p:[29,36,1359]}],action:"pressure",params:'{"pressure": "min"}'},f:["Min"]}," ",{p:[31,5,1500],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[32,5,1595],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.target_pressure","data.max_pressure"],s:'_0<_1?null:"disabled"'},p:[32,35,1625]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}]}]}," ",{p:{button:[{t:4,f:[{p:[39,7,1891],t:7,e:"ui-button",a:{icon:"eject",style:[{t:2,x:{r:["data.on"],s:'_0?"danger":null'},p:[39,38,1922]}],action:"eject"},f:["Eject"]}],n:50,r:"data.holding",p:[38,5,1863]}]},t:7,e:"ui-display",a:{title:"Holding Tank",button:0},f:[" ",{t:4,f:[{p:[43,3,2042],t:7,e:"ui-section",a:{label:"Label"},f:[{t:2,r:"data.holding.name",p:[44,4,2073]}]}," ",{p:[46,3,2115],t:7,e:"ui-section",a:{label:"Pressure"},f:[{t:2,x:{r:["adata.holding.pressure"],s:"Math.round(_0)"},p:[47,4,2149]}," kPa"]}],n:50,r:"data.holding",p:[42,3,2018]},{t:4,n:51,f:[{p:[50,3,2223],t:7,e:"ui-section",f:[{p:[51,4,2240],t:7,e:"span",a:{"class":"average"},f:["No Holding Tank"]}]}],r:"data.holding"}]}]},e.exports=a.extend(r.exports)},{205:205}],291:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[3,1,69],t:7,e:"ui-notice",f:[{p:[4,3,84],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.holding"],s:'_0?"is":"is not"'},p:[4,23,104]}," connected to a tank."]}]}," ",{p:[6,1,182],t:7,e:"ui-display",a:{title:"Status",button:0},f:[{p:[7,3,220],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[8,5,255],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[8,11,261]}," kPa"]}]}," ",{p:[10,3,323],t:7,e:"ui-section",a:{label:"Port"},f:[{p:[11,5,354],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected"],s:'_0?"good":"average"'},p:[11,18,367]}]},f:[{t:2,x:{r:["data.connected"],s:'_0?"Connected":"Not Connected"'},p:[11,59,408]}]}]}]}," ",{p:[14,1,499],t:7,e:"ui-display",a:{title:"Filter"},f:[{p:[15,3,530],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[16,5,562],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[16,22,579]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":"null"'},p:[17,14,630]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[18,22,687]}]}]}]}," ",{p:{button:[{t:4,f:[{p:[24,7,856],t:7,e:"ui-button",a:{icon:"eject",style:[{t:2,x:{r:["data.on"],s:'_0?"danger":null'},p:[24,38,887]}],action:"eject"},f:["Eject"]}],n:50,r:"data.holding",p:[23,5,828]}]},t:7,e:"ui-display",a:{title:"Holding Tank",button:0},f:[" ",{t:4,f:[{p:[28,3,1007],t:7,e:"ui-section",a:{label:"Label"},f:[{t:2,r:"data.holding.name",p:[29,4,1038]}]}," ",{p:[31,3,1080],t:7,e:"ui-section",a:{label:"Pressure"},f:[{t:2,x:{r:["adata.holding.pressure"],s:"Math.round(_0)"},p:[32,4,1114]}," kPa"]}],n:50,r:"data.holding",p:[27,3,983]},{t:4,n:51,f:[{p:[35,3,1188],t:7,e:"ui-section",f:[{p:[36,4,1205],t:7,e:"span",a:{"class":"average"},f:["No Holding Tank"]}]}],r:"data.holding"}]}," ",{p:[40,1,1293],t:7,e:"ui-display",a:{title:"Filters"},f:[{t:4,f:[{p:[42,5,1345],t:7,e:"filters"}],n:53,r:"data",p:[41,3,1325]}]}]},r.exports.components=r.exports.components||{};var i={filters:t(299)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,299:299}],292:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{chargingState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}},chargingMode:function(t){return 2==t?"Full":1==t?"Charging":"Draining"},channelState:function(t){return t>=2?"good":"bad"},channelPower:function(t){return t>=2?"On":"Off"},channelMode:function(t){return 1==t||3==t?"Auto":"Manual"}},computed:{graphData:function(){var t=this.get("data.history");return Object.keys(t).map(function(e){return t[e].map(function(t,e){return{x:e,y:t}})})}}}}(r),r.exports.template={v:3,t:[" ",{p:[42,1,1035],t:7,e:"ui-display",a:{title:"Network"},f:[{t:4,f:[{p:[44,5,1093],t:7,e:"ui-linegraph",a:{points:[{t:2,r:"graphData",p:[44,27,1115]}],height:"500",legend:'["Available", "Load"]',colors:'["rgb(0, 102, 0)", "rgb(153, 0, 0)"]',xunit:"seconds ago",xfactor:[{t:2,r:"data.interval",p:[46,38,1267]}],yunit:"W",yfactor:"1",xinc:[{t:2,x:{r:["data.stored"],s:"_0/10"},p:[47,15,1323]}],yinc:"9"}}],n:50,r:"config.fancy",p:[43,3,1067]},{t:4,n:51,f:[{p:[49,5,1373],t:7,e:"ui-section",a:{label:"Available"},f:[{p:[50,7,1411],t:7,e:"span",f:[{t:2,r:"data.supply",p:[50,13,1417]}]}]}," ",{p:[52,5,1464],t:7,e:"ui-section",a:{label:"Load"},f:[{p:[53,9,1499],t:7,e:"span",f:[{t:2,r:"data.demand",p:[53,15,1505]}]}]}],r:"config.fancy"}]}," ",{p:[57,1,1574],t:7,e:"ui-display",a:{title:"Areas"},f:[{p:[58,3,1604],t:7,e:"ui-section",a:{nowrap:0},f:[{p:[59,5,1629],t:7,e:"div",a:{"class":"content"},f:["Area"]}," ",{p:[60,5,1666],t:7,e:"div",a:{"class":"content"},f:["Charge"]}," ",{p:[61,5,1705],t:7,e:"div",a:{"class":"content"},f:["Load"]}," ",{p:[62,5,1742],t:7,e:"div",a:{"class":"content"},f:["Status"]}," ",{p:[63,5,1781],t:7,e:"div",a:{"class":"content"},f:["Equipment"]}," ",{p:[64,5,1823],t:7,e:"div",a:{"class":"content"},f:["Lighting"]}," ",{p:[65,5,1864],t:7,e:"div",a:{"class":"content"},f:["Environment"]}]}," ",{t:4,f:[{p:[68,5,1949],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[68,24,1968]}],nowrap:0},f:[{p:[69,7,1993],t:7,e:"div",a:{"class":"content"},f:[{t:2,x:{r:["@index","adata.areas"],s:"Math.round(_1[_0].charge)"},p:[69,28,2014]}," %"]}," ",{p:[70,7,2072],t:7,e:"div",a:{"class":"content"},f:[{t:2,rx:{r:"adata.areas",m:[{t:30,n:"@index"},"load"]},p:[70,28,2093]}]}," ",{p:[71,7,2135],t:7,e:"div",a:{"class":"content"},f:[{p:[71,28,2156],t:7,e:"span",a:{"class":[{t:2,x:{r:["chargingState","charging"],s:"_0(_1)"},p:[71,41,2169]}]},f:[{t:2,x:{r:["chargingMode","charging"],s:"_0(_1)"},p:[71,70,2198]}]}]}," ",{p:[72,7,2245],t:7,e:"div",a:{"class":"content"},f:[{p:[72,28,2266],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","eqp"],s:"_0(_1)"},p:[72,41,2279]}]},f:[{t:2,x:{r:["channelPower","eqp"],s:"_0(_1)"},p:[72,64,2302]}," [",{p:[72,87,2325],t:7,e:"span",f:[{t:2,x:{r:["channelMode","eqp"],s:"_0(_1)"},p:[72,93,2331]}]},"]"]}]}," ",{p:[73,7,2380],t:7,e:"div",a:{"class":"content"},f:[{p:[73,28,2401],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","lgt"],s:"_0(_1)"},p:[73,41,2414]}]},f:[{t:2,x:{r:["channelPower","lgt"],s:"_0(_1)"},p:[73,64,2437]}," [",{p:[73,87,2460],t:7,e:"span",f:[{t:2,x:{r:["channelMode","lgt"],s:"_0(_1)"},p:[73,93,2466]}]},"]"]}]}," ",{p:[74,7,2515],t:7,e:"div",a:{"class":"content"},f:[{p:[74,28,2536],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","env"],s:"_0(_1)"},p:[74,41,2549]}]},f:[{t:2,x:{r:["channelPower","env"],s:"_0(_1)"},p:[74,64,2572]}," [",{p:[74,87,2595],t:7,e:"span",f:[{t:2,x:{r:["channelMode","env"],s:"_0(_1)"},p:[74,93,2601]}]},"]"]}]}]}],n:52,r:"data.areas",p:[67,3,1923]}]}]},e.exports=a.extend(r.exports)},{205:205}],293:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{readableFrequency:function(){return Math.round(this.get("adata.frequency"))/10}}}}(r),r.exports.template={v:3,t:[" ",{p:[11,1,177],t:7,e:"ui-display",a:{title:"Settings"},f:[{t:4,f:[{p:[13,5,236],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[14,7,270],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.listening"],s:'_0?"power-off":"close"'},p:[14,24,287]}],style:[{t:2,x:{r:["data.listening"],s:'_0?"selected":null'},p:[14,75,338]}],action:"listen"},f:[{t:2,x:{r:["data.listening"],s:'_0?"On":"Off"'},p:[16,9,413]}]}]}],n:50,r:"data.headset",p:[12,3,210]},{t:4,n:51,f:[{p:[19,5,494],t:7,e:"ui-section",a:{label:"Microphone"},f:[{p:[20,7,533],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.broadcasting"],s:'_0?"power-off":"close"'},p:[20,24,550]}],style:[{t:2,x:{r:["data.broadcasting"],s:'_0?"selected":null'},p:[20,78,604]}],action:"broadcast"},f:[{t:2,x:{r:["data.broadcasting"],s:'_0?"Engaged":"Disengaged"'},p:[22,9,685]}]}]}," ",{p:[24,5,769],t:7,e:"ui-section",a:{label:"Speaker"},f:[{p:[25,7,805],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.listening"],s:'_0?"power-off":"close"'},p:[25,24,822]}],style:[{t:2,x:{r:["data.listening"],s:'_0?"selected":null'},p:[25,75,873]}],action:"listen"},f:[{t:2,x:{r:["data.listening"],s:'_0?"Engaged":"Disengaged"'},p:[27,9,948]}]}]}],r:"data.headset"}," ",{t:4,f:[{p:[31,5,1064],t:7,e:"ui-section",a:{label:"High Volume"},f:[{p:[32,7,1104],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.useCommand"],s:'_0?"power-off":"close"'},p:[32,24,1121]}],style:[{t:2,x:{r:["data.useCommand"],s:'_0?"selected":null'},p:[32,76,1173]}],action:"command"},f:[{t:2,x:{r:["data.useCommand"],s:'_0?"On":"Off"'},p:[34,9,1250]}]}]}],n:50,r:"data.command",p:[30,3,1038]}]}," ",{p:[38,1,1342],t:7,e:"ui-display",a:{title:"Channel"},f:[{p:[39,3,1374],t:7,e:"ui-section",a:{label:"Frequency"},f:[{t:4,f:[{p:[41,7,1439],t:7,e:"span",f:[{t:2,r:"readableFrequency",p:[41,13,1445]}]}],n:50,r:"data.freqlock",p:[40,5,1410]},{t:4,n:51,f:[{p:[43,7,1495],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.frequency","data.minFrequency"],s:'_0==_1?"disabled":null'},p:[43,46,1534]}],action:"frequency",params:'{"adjust": -1}'}}," ",{p:[44,7,1646],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.frequency","data.minFrequency"],s:'_0==_1?"disabled":null'},p:[44,41,1680]}],action:"frequency",params:'{"adjust": -.2}'}}," ",{p:[45,7,1793],t:7,e:"ui-button",a:{icon:"pencil",action:"frequency",params:'{"tune": "input"}'},f:[{t:2,r:"readableFrequency",p:[45,78,1864]}]}," ",{p:[46,7,1905],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.frequency","data.maxFrequency"],s:'_0==_1?"disabled":null'},p:[46,40,1938]}],action:"frequency",params:'{"adjust": .2}'}}," ",{p:[47,7,2050],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.frequency","data.maxFrequency"],s:'_0==_1?"disabled":null'},p:[47,45,2088]}],action:"frequency",params:'{"adjust": 1}'}}],r:"data.freqlock"}]}," ",{t:4,f:[{p:[51,5,2262],t:7,e:"ui-section",a:{label:"Subspace Transmission"},f:[{p:[52,7,2312],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.subspace"],s:'_0?"power-off":"close"'},p:[52,24,2329]}],style:[{t:2,x:{r:["data.subspace"],s:'_0?"selected":null'},p:[52,74,2379]}],action:"subspace"},f:[{t:2,x:{r:["data.subspace"],s:'_0?"Active":"Inactive"'},p:[53,29,2447]}]}]}],n:50,r:"data.subspaceSwitchable",p:[50,3,2225]}," ",{t:4,f:[{p:[57,5,2578],t:7,e:"ui-section",a:{label:"Channels"},f:[{t:4,f:[{p:[59,9,2656],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["."],s:'_0?"check-square-o":"square-o"'},p:[59,26,2673]}],style:[{t:2,x:{r:["."],s:'_0?"selected":null'},p:[60,18,2730]}],action:"channel",params:['{"channel": "',{t:2,r:"channel",p:[61,49,2806]},'"}']},f:[{t:2,r:"channel",p:[62,11,2833]}]},{p:[62,34,2856],t:7,e:"br"}],n:52,i:"channel",r:"data.channels",p:[58,7,2615]}]}],n:50,x:{r:["data.subspace","data.channels"],s:"_0&&_1"},p:[56,3,2534]}]}]},e.exports=a.extend(r.exports)},{205:205}],294:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,1,25],t:7,e:"ui-notice",f:[{p:[3,3,40],t:7,e:"span",f:["The grinder is currently processing and cannot be used."]}]}],n:50,r:"data.processing",p:[1,1,0]},{p:{button:[{p:[8,5,208],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.operating","data.contents"],s:'(_0==0)&&_1?null:"disabled"'},p:[8,36,239]}],action:"eject"},f:["Eject Contents"]}]},t:7,e:"ui-display",a:{title:"Processing Chamber",button:0},f:[" ",{p:[10,3,364],t:7,e:"ui-section",a:{label:"Grinding"},f:[{p:[11,5,399],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.operating"],s:'_0?"average":"good"'},p:[11,18,412]}]},f:[{t:2,x:{r:["data.operating"],s:'_0?"Busy":"Ready"'},p:[11,59,453]}]}," ",{p:[12,2,500],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.operating","data.contents"],s:'(_0==0)&&_1?null:"disabled"'},p:[12,35,533]}],action:"grind"},f:["Activate"]}]}," ",{p:[14,3,653],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{t:4,f:[{p:[17,9,755],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:["The ",{t:2,r:"name",p:[17,56,802]}]},{p:[17,71,817],t:7,e:"br"}],n:52,r:"adata.contentslist",p:[16,7,717]},{t:4,n:51,f:[{p:[19,9,848],t:7,e:"span",f:["No Contents"]}],r:"adata.contentslist"}],n:50,r:"data.contents",p:[15,5,688]},{t:4,n:51,f:[{p:[22,7,911],t:7,e:"span",f:["No Contents"]}],r:"data.contents"}]}]}," ",{p:{button:[{p:[28,5,1047],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.operating","data.isBeakerLoaded"],s:'(_0==0)&&_1?null:"disabled"'},p:[28,36,1078]}],action:"detach"},f:["Detach"]}]},t:7,e:"ui-display",a:{title:"Container",button:0},f:[" ",{p:[30,3,1202],t:7,e:"ui-section",a:{label:"Reagents"},f:[{t:4,f:[{p:[32,7,1272],t:7,e:"span",f:[{t:2,x:{r:["adata.beakerCurrentVolume"],s:"Math.round(_0)"},p:[32,13,1278]},"/",{t:2,r:"data.beakerMaxVolume",p:[32,55,1320]}," Units"]}," ",{p:[33,7,1365],t:7,e:"br"}," ",{t:4,f:[{p:[35,9,1418],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[35,52,1461]}," units of ",{t:2,r:"name",p:[35,87,1496]}]},{p:[35,102,1511],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[34,7,1378]},{t:4,n:51,f:[{p:[37,9,1542],t:7,e:"span",a:{"class":"bad"},f:["Container Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[31,5,1237]},{t:4,n:51,f:[{p:[40,7,1621],t:7,e:"span",a:{"class":"average"},f:["No Container"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],295:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" "," ",{t:4,f:[{p:[5,2,123],t:7,e:"dirsel"}],n:50,x:{r:["data.mode"],s:"_0>=0"},p:[4,1,98]},{t:4,f:[{p:[8,2,187],t:7,e:"colorsel"}],n:50,x:{r:["data.mode"],s:"_0==-2||_0==0"},p:[7,1,143]},{p:[10,1,209],t:7,e:"ui-display",a:{title:"Utilities"},f:[{p:[11,2,242],t:7,e:"ui-section",f:[{p:[12,3,258],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0>=0?"check-square-o":"square-o"'},p:[12,20,275]}],state:[{t:2,x:{r:["data.mode"],s:'_0>=0?"selected":null'},p:[12,79,334]}],action:"mode",params:['{"mode": ',{t:2,r:"data.screen",p:[13,35,409]},"}"]},f:["Lay Pipes"]}]}," ",{p:[15,2,467],t:7,e:"ui-section",f:[{p:[16,3,483],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0==-1?"check-square-o":"square-o"'},p:[16,20,500]}],state:[{t:2,x:{r:["data.mode"],s:'_0==-1?"selected":null'},p:[16,80,560]}],action:"mode",params:'{"mode": -1}'},f:["Eat Pipes"]}]}," ",{p:[19,2,681],t:7,e:"ui-section",f:[{p:[20,3,697],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0==-2?"check-square-o":"square-o"'},p:[20,20,714]}],state:[{t:2,x:{r:["data.mode"],s:'_0==-2?"selected":null'},p:[20,80,774]}],action:"mode",params:'{"mode": -2}'},f:["Paint Pipes"]}]}]}," ",{p:[24,1,911],t:7,e:"ui-display",a:{title:"Category"},f:[{p:[25,2,943],t:7,e:"ui-section",f:[{p:[26,3,959],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.screen"],s:'_0==0?"check-square-o":"square-o"'},p:[26,20,976]}],state:[{t:2,x:{r:["data.screen"],s:'_0==0?"selected":null'},p:[26,81,1037]}],action:"screen",params:'{"screen": 0}'},f:["Atmospherics"]}," ",{p:[28,3,1150],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.screen"],s:'_0==2?"check-square-o":"square-o"'},p:[28,20,1167]}],state:[{t:2,x:{r:["data.screen"],s:'_0==2?"selected":null'},p:[28,81,1228]}],action:"screen",params:'{"screen": 2}'},f:["Disposals"]}]}," ",{t:4,f:[{p:[32,3,1381],t:7,e:"ui-section",a:{label:"Piping Layer"},f:[{p:[33,4,1419],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.piping_layer"],s:'_0==1?"selected":null'},p:[33,22,1437]}],action:"piping_layer",params:'{"piping_layer": 1}'},f:["1"]}," ",{p:[35,4,1559],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.piping_layer"],s:'_0==2?"selected":null'},p:[35,22,1577]}],action:"piping_layer",params:'{"piping_layer": 2}'},f:["2"]}," ",{p:[37,4,1699],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.piping_layer"],s:'_0==3?"selected":null'},p:[37,22,1717]}],action:"piping_layer",params:'{"piping_layer": 3}'},f:["3"]}]}],n:50,x:{r:["data.screen"],s:"_0==0"},p:[31,2,1353]}]}," ",{t:4,f:[{p:[43,2,1906],t:7,e:"ui-display",a:{title:[{t:2,r:"cat_name",p:[43,21,1925]}]},f:[{t:4,f:[{p:[45,4,1965],t:7,e:"ui-section",f:[{p:[46,5,1983],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[46,23,2001]}],action:"pipe_type",params:['{"pipe_type": ',{t:2,r:"pipe_index",p:[47,28,2082]},', "category": ',{t:2,r:"cat_name",p:[47,56,2110]},"}"]},f:[{t:2,r:"pipe_name",p:[47,71,2125]}]}]}],n:52,r:"recipes",p:[44,3,1943]}]}],n:52,r:"data.categories",p:[42,1,1878]}]},r.exports.components=r.exports.components||{};var i={colorsel:t(296),dirsel:t(297)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,296:296,297:297}],296:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Color"},f:[{t:4,f:[{p:[3,3,60],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[3,21,78]}],action:"color",params:['{"paint_color": ',{t:2,r:"color_name",p:[4,28,155]},"}"]},f:[{t:2,r:"color_name",p:[4,45,172]}]}],n:52,r:"data.paint_colors",p:[2,2,29]}]}]},e.exports=a.extend(r.exports)},{205:205}],297:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Direction"},f:[{t:4,f:[{p:[3,3,64],t:7,e:"ui-section",f:[{t:4,f:[{p:[5,5,105],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[5,23,123]}],action:"setdir",params:['{"dir": ',{t:2,r:"dir",p:[6,22,195]},', "flipped": ',{t:2,r:"flipped",p:[6,42,215]},"}"]},f:[{p:[6,56,229],t:7,e:"img",a:{src:["pipe.",{t:2,r:"dir",p:[6,71,244]},".",{t:2,r:"icon_state",p:[6,79,252]},".png"],title:[{t:2,r:"dir_name",p:[6,106,279]}]}}]}],n:52,r:"previews",p:[4,4,81]}]}],n:52,r:"data.preview_rows",p:[2,2,33]}]}]},e.exports=a.extend(r.exports)},{205:205}],298:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,23],t:7,e:"ui-notice",f:[{t:2,r:"data.notice",p:[3,5,40]}]}],n:50,r:"data.notice",p:[1,1,0]},{p:[6,1,82],t:7,e:"ui-display",a:{title:"Satellite Network Control",button:0},f:[{t:4,f:[{p:[8,4,168],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{p:[9,9,209],t:7,e:"div",a:{"class":"content"},f:["#",{t:2,r:"id",p:[9,31,231]}]}," ",{p:[10,9,253],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"mode",p:[10,30,274]}]}," ",{p:[11,9,298],t:7,e:"div",a:{"class":"content"},f:[{p:[12,11,331],t:7,e:"ui-button",a:{action:"toggle",params:['{"id": "',{t:2,r:"id",p:[12,54,374]},'"}']},f:[{t:2,x:{r:["active"],s:'_0?"Deactivate":"Activate"'},p:[12,64,384]}]}]}]}],n:52,r:"data.satellites",p:[7,2,138]}]}," ",{t:4,f:[{p:[18,1,528],t:7,e:"ui-display",a:{title:"Station Shield Coverage" -},f:[{p:[19,3,576],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.meteor_shield_coverage_max",p:[19,24,597]}],value:[{t:2,r:"data.meteor_shield_coverage",p:[19,68,641]}]},f:[{t:2,x:{r:["data.meteor_shield_coverage","data.meteor_shield_coverage_max"],s:"100*_0/_1"},p:[19,101,674]}," %"]}," ",{p:[20,1,758],t:7,e:"ui-display",f:[]}]}],n:50,r:"data.meteor_shield",p:[17,1,500]}]},e.exports=a.extend(r.exports)},{205:205}],299:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,26],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["enabled"],s:'_0?"check-square-o":"square-o"'},p:[2,20,43]}],style:[{t:2,x:{r:["enabled"],s:'_0?"selected":null'},p:[2,72,95]}],action:"toggle_filter",params:['{"id_tag": "',{t:2,r:"id_tag",p:[3,48,176]},'", "val": ',{t:2,r:"gas_id",p:[3,68,196]},"}"]},f:[{t:2,r:"gas_name",p:[3,81,209]}]}],n:52,r:"filter_types",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{205:205}],300:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" "," "," ",{p:[5,1,200],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.tabs",p:[5,16,215]}]},f:[{p:[6,2,233],t:7,e:"tab",a:{name:"Status"},f:[{p:[7,3,256],t:7,e:"status"}]}," ",{p:[9,2,277],t:7,e:"tab",a:{name:"Templates"},f:[{p:[10,3,303],t:7,e:"templates"}]}," ",{p:[12,2,327],t:7,e:"tab",a:{name:"Modification"},f:[{t:4,f:[{p:[14,3,381],t:7,e:"modification"}],n:50,r:"data.selected",p:[13,3,356]}," ",{t:4,f:[{p:[17,3,437],t:7,e:"span",a:{"class":"bad"},f:["No shuttle selected."]}],n:50,x:{r:["data.selected"],s:"!_0"},p:[16,3,411]}]}]}]},r.exports.components=r.exports.components||{};var i={modification:t(301),templates:t(303),status:t(302)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,301:301,302:302,303:303}],301:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:["Selected: ",{t:2,r:"data.selected.name",p:[1,30,29]}]},f:[{t:4,f:[{p:[3,5,96],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"data.selected.description",p:[3,37,128]}]}],n:50,r:"data.selected.description",p:[2,3,57]}," ",{t:4,f:[{p:[6,5,224],t:7,e:"ui-section",a:{label:"Admin Notes"},f:[{t:2,r:"data.selected.admin_notes",p:[6,37,256]}]}],n:50,r:"data.selected.admin_notes",p:[5,3,185]}]}," ",{t:4,f:[{p:[11,3,361],t:7,e:"ui-display",a:{title:["Existing Shuttle: ",{t:2,r:"data.existing_shuttle.name",p:[11,40,398]}]},f:["Status: ",{t:2,r:"data.existing_shuttle.status",p:[12,13,444]}," ",{t:4,f:["(",{t:2,r:"data.existing_shuttle.timeleft",p:[14,8,526]},")"],n:50,r:"data.existing_shuttle.timer",p:[13,5,482]}," ",{p:[16,5,580],t:7,e:"ui-button",a:{action:"jump_to",params:['{"type": "mobile", "id": "',{t:2,r:"data.existing_shuttle.id",p:[17,41,649]},'"}']},f:["Jump To"]}]}],n:50,r:"data.existing_shuttle",p:[10,1,328]},{t:4,f:[{p:[24,3,778],t:7,e:"ui-display",a:{title:"Existing Shuttle: None"}}],n:50,x:{r:["data.existing_shuttle"],s:"!_0"},p:[23,1,744]},{p:[27,1,847],t:7,e:"ui-button",a:{action:"preview",params:['{"shuttle_id": "',{t:2,r:"data.selected.shuttle_id",p:[28,27,902]},'"}']},f:["Preview"]}," ",{p:[31,1,961],t:7,e:"ui-button",a:{action:"load",params:['{"shuttle_id": "',{t:2,r:"data.selected.shuttle_id",p:[32,27,1013]},'"}'],style:"danger"},f:["Load"]}," ",{p:[37,1,1089],t:7,e:"ui-display",a:{title:"Status"},f:[]}]},e.exports=a.extend(r.exports)},{205:205}],302:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,27],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[2,22,46]}," (",{t:2,r:"id",p:[2,32,56]},")"]},f:[{t:2,r:"status",p:[3,5,71]}," ",{t:4,f:["(",{t:2,r:"timeleft",p:[5,8,109]},")"],n:50,r:"timer",p:[4,5,87]}," ",{p:[7,5,141],t:7,e:"ui-button",a:{action:"jump_to",params:['{"type": "mobile", "id": "',{t:2,r:"id",p:[7,67,203]},'"}']},f:["Jump To"]}," ",{p:[10,5,252],t:7,e:"ui-button",a:{action:"fast_travel",params:['{"id": "',{t:2,r:"id",p:[10,53,300]},'"}'],state:[{t:2,x:{r:["can_fast_travel"],s:'_0?null:"disabled"'},p:[10,70,317]}]},f:["Fast Travel"]}]}],n:52,r:"data.shuttles",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{205:205}],303:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.templates_tabs",p:[1,16,15]}]},f:[{t:4,f:[{p:[3,5,74],t:7,e:"tab",a:{name:[{t:2,r:"port_id",p:[3,16,85]}]},f:[{t:4,f:[{p:[5,9,135],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[5,28,154]}]},f:[{t:4,f:[{p:[7,13,209],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"description",p:[7,45,241]}]}],n:50,r:"description",p:[6,11,176]}," ",{t:4,f:[{p:[10,13,333],t:7,e:"ui-section",a:{label:"Admin Notes"},f:[{t:2,r:"admin_notes",p:[10,45,365]}]}],n:50,r:"admin_notes",p:[9,11,300]}," ",{p:[13,11,426],t:7,e:"ui-button",a:{action:"select_template",params:['{"shuttle_id": "',{t:2,r:"shuttle_id",p:[14,37,499]},'"}'],state:[{t:2,x:{r:["data.selected.shuttle_id","shuttle_id"],s:'_0==_1?"selected":null'},p:[15,20,537]}]},f:[{t:2,x:{r:["data.selected.shuttle_id","shuttle_id"],s:'_0==_1?"Selected":"Select"'},p:[17,13,630]}]}]}],n:52,r:"templates",p:[4,7,106]}]}],n:52,r:"data.templates",p:[2,3,44]}]}]},e.exports=a.extend(r.exports)},{205:205}],304:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Occupant"},f:[{p:[2,3,33],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[3,3,66],t:7,e:"span",f:[{t:2,x:{r:["data.occupant.name"],s:'_0?_0:"No Occupant"'},p:[3,9,72]}]}]}," ",{t:4,f:[{p:[6,5,186],t:7,e:"ui-section",a:{label:"State"},f:[{p:[7,7,220],t:7,e:"span",a:{"class":[{t:2,r:"data.occupant.statstate",p:[7,20,233]}]},f:[{t:2,r:"data.occupant.stat",p:[7,49,262]}]}]}," ",{p:[9,5,315],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[10,7,350],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.occupant.minHealth",p:[10,20,363]}],max:[{t:2,r:"data.occupant.maxHealth",p:[10,54,397]}],value:[{t:2,r:"data.occupant.health",p:[10,90,433]}],state:[{t:2,x:{r:["data.occupant.health"],s:'_0>=0?"good":"average"'},p:[11,16,475]}]},f:[{t:2,x:{r:["adata.occupant.health"],s:"Math.round(_0)"},p:[11,68,527]}]}]}," ",{t:4,f:[{p:[14,7,764],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[14,26,783]}]},f:[{p:[15,9,804],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.occupant.maxHealth",p:[15,30,825]}],value:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[15,66,861]}],state:"bad"},f:[{t:2,x:{r:["type","adata.occupant"],s:"Math.round(_1[_0])"},p:[15,103,898]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Respiratory",type:"oxyLoss"},{label:"Toxin",type:"toxLoss"},{label:"Burn",type:"fireLoss"}]'},p:[13,5,598]}," ",{p:[18,5,985],t:7,e:"ui-section",a:{label:"Cells"},f:[{p:[19,9,1021],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"bad":"good"'},p:[19,22,1034]}]},f:[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"Damaged":"Healthy"'},p:[19,68,1080]}]}]}," ",{p:[21,5,1163],t:7,e:"ui-section",a:{label:"Brain"},f:[{p:[22,9,1199],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"bad":"good"'},p:[22,22,1212]}]},f:[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"Abnormal":"Healthy"'},p:[22,68,1258]}]}]}," ",{p:[24,5,1342],t:7,e:"ui-section",a:{label:"Bloodstream"},f:[{t:4,f:[{p:[26,11,1429],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,1)"},p:[26,54,1472]}," units of ",{t:2,r:"name",p:[26,89,1507]}]},{p:[26,104,1522],t:7,e:"br"}],n:52,r:"adata.occupant.reagents",p:[25,9,1384]},{t:4,n:51,f:[{p:[28,11,1557],t:7,e:"span",a:{"class":"good"},f:["Pure"]}],r:"adata.occupant.reagents"}]}],n:50,r:"data.occupied",p:[5,3,159]}]}," ",{p:[33,1,1653],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[34,2,1685],t:7,e:"ui-section",a:{label:"Door"},f:[{p:[35,5,1716],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.open"],s:'_0?"unlock":"lock"'},p:[35,22,1733]}],action:"door"},f:[{t:2,x:{r:["data.open"],s:'_0?"Open":"Closed"'},p:[35,71,1782]}]}]}," ",{p:[37,3,1847],t:7,e:"ui-section",a:{label:"Inject"},f:[{t:4,f:[{p:[39,7,1908],t:7,e:"ui-button",a:{icon:"flask",state:[{t:2,x:{r:["data.occupied","allowed"],s:'_0&&_1?null:"disabled"'},p:[39,38,1939]}],action:"inject",params:['{"chem": "',{t:2,r:"id",p:[39,122,2023]},'"}']},f:[{t:2,r:"name",p:[39,132,2033]}]},{p:[39,152,2053],t:7,e:"br"}],n:52,r:"data.chems",p:[38,5,1880]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],305:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,25],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[2,22,44]}],labelcolor:[{t:2,r:"htmlcolor",p:[2,44,66]}],candystripe:0,right:0},f:[{p:[3,5,105],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[3,32,132],t:7,e:"span",a:{"class":[{t:2,x:{r:["status"],s:'_0=="Dead"?"bad bold":_0=="Unconscious"?"average bold":"good"'},p:[3,45,145]}]},f:[{t:2,r:"status",p:[3,132,232]}]}]}," ",{p:[4,5,268],t:7,e:"ui-section",a:{label:"Jelly"},f:[{t:2,r:"exoticblood",p:[4,31,294]}]}," ",{p:[5,5,328],t:7,e:"ui-section",a:{label:"Location"},f:[{t:2,r:"area",p:[5,34,357]}]}," ",{p:[7,5,386],t:7,e:"ui-button",a:{state:[{t:2,r:"swap_button_state",p:[8,14,411]}],action:"swap",params:['{"ref": "',{t:2,r:"ref",p:[9,38,472]},'"}']},f:[{t:2,x:{r:["is_current"],s:'_0?"You Are Here":"Swap"'},p:[10,7,491]}]}]}],n:52,r:"data.bodies",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{205:205}],306:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{t:4,f:[{p:[4,23,82],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.drying"],s:'_0?"stop":"tint"'},p:[4,40,99]}],action:"Dry"},f:[{t:2,x:{r:["data.drying"],s:'_0?"Stop drying":"Dry"'},p:[4,88,147]}]}],n:50,r:"data.isdryer",p:[4,3,62]}]},t:7,e:"ui-display",a:{title:"Storage",button:0},f:[" ",{t:4,f:[{p:[7,3,258],t:7,e:"ui-notice",f:[{p:[8,5,275],t:7,e:"span",f:["Unfortunately, this ",{t:2,r:"data.name",p:[8,31,301]}," is empty."]}]}],n:50,x:{r:["data.contents.length"],s:"_0==0"},p:[6,1,221]},{t:4,n:51,f:[{p:[11,1,359],t:7,e:"div",a:{"class":"display tabular"},f:[{p:[12,2,391],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[13,4,425],t:7,e:"section",a:{"class":"cell bold"},f:["Item"]}," ",{p:[16,4,482],t:7,e:"section",a:{"class":"cell bold"},f:["Quantity"]}," ",{p:[19,4,543],t:7,e:"section",a:{"class":"cell bold",align:"center"},f:[{t:4,f:[{t:2,r:"data.verb",p:[20,22,608]}],n:50,r:"data.verb",p:[20,5,591]},{t:4,n:51,f:["Dispense"],r:"data.verb"}]}]}," ",{t:4,f:[{p:[24,3,703],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[25,4,737],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[26,5,765]}]}," ",{p:[28,4,793],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"amount",p:[29,5,835]}]}," ",{p:[31,4,865],t:7,e:"section",a:{"class":"table",alight:"right"},f:[{p:[32,5,909],t:7,e:"section",a:{"class":"cell"}}," ",{p:[33,5,947],t:7,e:"section",a:{"class":"cell"},f:[{p:[34,6,976],t:7,e:"ui-button",a:{grid:0,action:"Release",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[34,45,1015]}],params:['{ "name" : ',{t:2,r:"name",p:[34,102,1072]},', "amount" : 1 }']},f:["One"]}]}," ",{p:[38,5,1151],t:7,e:"section",a:{"class":"cell"},f:[{p:[39,6,1180],t:7,e:"ui-button",a:{grid:0,action:"Release",state:[{t:2,x:{r:["amount"],s:'(_0>1)?null:"disabled"'},p:[39,45,1219]}],params:['{ "name" : ',{t:2,r:"name",p:[39,101,1275]}," }"]},f:["Many"]}]}]}]}],n:52,r:"data.contents",p:[23,2,676]}]}],x:{r:["data.contents.length"],s:"_0==0"}}]}]},e.exports=a.extend(r.exports)},{205:205}],307:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{capacityPercentState:function(){var t=this.get("data.capacityPercent");return t>50?"good":t>15?"average":"bad"},inputState:function(){return this.get("data.capacityPercent")>=100?"good":this.get("data.inputting")?"average":"bad"},outputState:function(){return this.get("data.outputting")?"good":this.get("data.charge")>0?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[24,1,663],t:7,e:"ui-display",a:{title:"Storage"},f:[{p:[25,3,695],t:7,e:"ui-section",a:{label:"Stored Energy"},f:[{p:[26,5,735],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.capacityPercent",p:[26,38,768]}],state:[{t:2,r:"capacityPercentState",p:[26,71,801]}]},f:[{t:2,x:{r:["adata.capacityPercent"],s:"Math.fixed(_0)"},p:[26,97,827]},"%"]}]}]}," ",{p:[29,1,908],t:7,e:"ui-display",a:{title:"Input"},f:[{p:[30,3,938],t:7,e:"ui-section",a:{label:"Charge Mode"},f:[{p:[31,5,976],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"refresh":"close"'},p:[31,22,993]}],style:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"selected":null'},p:[31,74,1045]}],action:"tryinput"},f:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"Auto":"Off"'},p:[32,25,1113]}]},"   [",{p:[34,6,1182],t:7,e:"span",a:{"class":[{t:2,r:"inputState",p:[34,19,1195]}]},f:[{t:2,x:{r:["data.capacityPercent","data.inputting"],s:'_0>=100?"Fully Charged":_1?"Charging":"Not Charging"'},p:[34,35,1211]}]},"]"]}," ",{p:[36,3,1335],t:7,e:"ui-section",a:{label:"Target Input"},f:[{p:[37,5,1374],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.inputLevelMax",p:[37,26,1395]}],value:[{t:2,r:"data.inputLevel",p:[37,57,1426]}]},f:[{t:2,r:"adata.inputLevel_text",p:[37,78,1447]}]}]}," ",{p:[39,3,1501],t:7,e:"ui-section",a:{label:"Adjust Input"},f:[{p:[40,5,1540],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.inputLevel"],s:'_0==0?"disabled":null'},p:[40,44,1579]}],action:"input",params:'{"target": "min"}'}}," ",{p:[41,5,1674],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.inputLevel"],s:'_0==0?"disabled":null'},p:[41,39,1708]}],action:"input",params:'{"adjust": -10000}'}}," ",{p:[42,5,1804],t:7,e:"ui-button",a:{icon:"pencil",action:"input",params:'{"target": "input"}'},f:["Set"]}," ",{p:[43,5,1894],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.inputLevel","data.inputLevelMax"],s:'_0==_1?"disabled":null'},p:[43,38,1927]}],action:"input",params:'{"adjust": 10000}'}}," ",{p:[44,5,2039],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.inputLevel","data.inputLevelMax"],s:'_0==_1?"disabled":null'},p:[44,43,2077]}],action:"input",params:'{"target": "max"}'}}]}," ",{p:[46,3,2204],t:7,e:"ui-section",a:{label:"Available"},f:[{p:[47,3,2238],t:7,e:"span",f:[{t:2,r:"adata.inputAvailable",p:[47,9,2244]}]}]}]}," ",{p:[50,1,2308],t:7,e:"ui-display",a:{title:"Output"},f:[{p:[51,3,2339],t:7,e:"ui-section",a:{label:"Output Mode"},f:[{p:[52,5,2377],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"power-off":"close"'},p:[52,22,2394]}],style:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"selected":null'},p:[52,77,2449]}],action:"tryoutput"},f:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"On":"Off"'},p:[53,26,2519]}]},"   [",{p:[55,6,2587],t:7,e:"span",a:{"class":[{t:2,r:"outputState",p:[55,19,2600]}]},f:[{t:2,x:{r:["data.outputting","data.charge"],s:'_0?"Sending":_1>0?"Not Sending":"No Charge"'},p:[55,36,2617]}]},"]"]}," ",{p:[57,3,2724],t:7,e:"ui-section",a:{label:"Target Output"},f:[{p:[58,5,2764],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.outputLevelMax",p:[58,26,2785]}],value:[{t:2,r:"data.outputLevel",p:[58,58,2817]}]},f:[{t:2,r:"adata.outputLevel_text",p:[58,80,2839]}]}]}," ",{p:[60,3,2894],t:7,e:"ui-section",a:{label:"Adjust Output"},f:[{p:[61,5,2934],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.outputLevel"],s:'_0==0?"disabled":null'},p:[61,44,2973]}],action:"output",params:'{"target": "min"}'}}," ",{p:[62,5,3070],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.outputLevel"],s:'_0==0?"disabled":null'},p:[62,39,3104]}],action:"output",params:'{"adjust": -10000}'}}," ",{p:[63,5,3202],t:7,e:"ui-button",a:{icon:"pencil",action:"output",params:'{"target": "input"}'},f:["Set"]}," ",{p:[64,5,3293],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.outputLevel","data.outputLevelMax"],s:'_0==_1?"disabled":null'},p:[64,38,3326]}],action:"output",params:'{"adjust": 10000}'}}," ",{p:[65,5,3441],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.outputLevel","data.outputLevelMax"],s:'_0==_1?"disabled":null'},p:[65,43,3479]}],action:"output",params:'{"target": "max"}'}}]}," ",{p:[67,3,3609],t:7,e:"ui-section",a:{label:"Outputting"},f:[{p:[68,3,3644],t:7,e:"span",f:[{t:2,r:"adata.outputUsed",p:[68,9,3650]}]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],308:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:["\ufeff",{t:4,f:[" ",{p:[2,2,33],t:7,e:"ui-display",a:{title:"Dispersal Tank"},f:[{p:[3,2,72],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[4,6,105],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.active"],s:'_0?"power-off":"close"'},p:[4,23,122]}],style:[{t:2,x:{r:["data.active"],s:'_0?"selected":null'},p:[5,11,174]}],state:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?null:"disabled"'},p:[6,11,222]}],action:"power"},f:[{t:2,x:{r:["data.active"],s:'_0?"On":"Off"'},p:[7,19,284]}]}]}," ",{p:[10,2,349],t:7,e:"ui-section",a:{label:"Smoke Radius Setting"},f:[{p:[11,4,395],t:7,e:"div",a:{"class":"content",style:"float:left"},f:[{p:[12,5,441],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.setting"],s:'_0==3?"selected":null'},p:[12,35,471]}],action:"setting",params:'{"amount": 3}'},f:["3"]}," ",{p:[13,5,573],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.setting"],s:'_0==6?"selected":null'},p:[13,35,603]}],action:"setting",params:'{"amount": 6}'},f:["6"]}," ",{p:[14,5,705],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.setting"],s:'_0==9?"selected":null'},p:[14,35,735]}],action:"setting",params:'{"amount": 9}'},f:["9"]}," ",{p:[15,5,837],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.setting"],s:'_0==12?"selected":null'},p:[15,35,867]}],action:"setting",params:'{"amount": 12}'},f:["12"]}," ",{p:[16,5,972],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.setting"],s:'_0==15?"selected":null'},p:[16,35,1002]}],action:"setting",params:'{"amount": 15}'},f:["15"]}]}]}," ",{p:[19,5,1139],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{p:[21,10,1212],t:7,e:"span",f:[{t:2,x:{r:["adata.TankCurrentVolume"],s:"Math.round(_0)"},p:[21,16,1218]},"/",{t:2,r:"data.TankMaxVolume",p:[21,56,1258]}," Units"]}," ",{p:[22,10,1304],t:7,e:"br"}," ",{p:[23,5,1315],t:7,e:"br"}," ",{t:4,f:[{p:[25,13,1374],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[25,56,1417]}," units of ",{t:2,r:"name",p:[25,91,1452]}]},{p:[25,106,1467],t:7,e:"br"}],n:52,r:"adata.TankContents",p:[24,11,1332]}],n:50,r:"data.isTankLoaded",p:[20,7,1176]},{t:4,n:51,f:[{p:[28,12,1519],t:7,e:"span",a:{"class":"bad"},f:["Tank Empty"]}],r:"data.isTankLoaded"}," ",{p:[30,4,1571],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?"Eject":"Close"'},p:[30,21,1588]}],style:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?"selected":null'},p:[31,12,1643]}],state:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?null:"disabled"'},p:[32,12,1698]}],action:"purge"},f:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?"Purge Contents":"No chemicals detected"'},p:[33,20,1761]}]}]}]}],n:50,x:{r:["data.screen"],s:'_0=="home"'},p:[1,2,1]}]},e.exports=a.extend(r.exports)},{205:205}],309:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[2,3,31],t:7,e:"ui-section",a:{label:"Generated Power"},f:[{t:2,x:{r:["adata.generated"],s:"Math.round(_0)"},p:[3,5,73]},"W"]}," ",{p:[5,3,126],t:7,e:"ui-section",a:{label:"Orientation"},f:[{p:[6,5,164],t:7,e:"span",f:[{t:2,x:{r:["adata.angle"],s:"Math.round(_0)"},p:[6,11,170]},"° (",{t:2,r:"data.direction",p:[6,45,204]},")"]}]}," ",{p:[8,3,251],t:7,e:"ui-section",a:{label:"Adjust Angle"},f:[{p:[9,5,290],t:7,e:"ui-button",a:{icon:"step-backward",action:"angle",params:'{"adjust": -15}'},f:["15°"]}," ",{p:[10,5,387],t:7,e:"ui-button",a:{icon:"backward",action:"angle",params:'{"adjust": -5}'},f:["5°"]}," ",{p:[11,5,477],t:7,e:"ui-button",a:{icon:"forward",action:"angle",params:'{"adjust": 5}'},f:["5°"]}," ",{p:[12,5,565],t:7,e:"ui-button",a:{icon:"step-forward",action:"angle",params:'{"adjust": 15}'},f:["15°"]}]}]}," ",{p:[15,1,687],t:7,e:"ui-display",a:{title:"Tracking"},f:[{p:[16,3,720],t:7,e:"ui-section",a:{label:"Tracker Mode"},f:[{p:[17,5,759],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["data.tracking_state"],s:'_0==0?"selected":null'},p:[17,36,790]}],action:"tracking",params:'{"mode": 0}'},f:["Off"]}," ",{p:[19,5,907],t:7,e:"ui-button",a:{icon:"clock-o",state:[{t:2,x:{r:["data.tracking_state"],s:'_0==1?"selected":null'},p:[19,38,940]}],action:"tracking",params:'{"mode": 1}'},f:["Timed"]}," ",{p:[21,5,1059],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.connected_tracker","data.tracking_state"],s:'_0?_1==2?"selected":null:"disabled"'},p:[21,38,1092]}],action:"tracking",params:'{"mode": 2}'},f:["Auto"]}]}," ",{p:[24,3,1262],t:7,e:"ui-section",a:{label:"Tracking Rate"},f:[{p:[25,3,1300],t:7,e:"span",f:[{t:2,x:{r:["adata.tracking_rate"],s:"Math.round(_0)"},p:[25,9,1306]},"°/h (",{t:2,r:"data.rotating_way",p:[25,53,1350]},")"]}]}," ",{p:[27,3,1399],t:7,e:"ui-section",a:{label:"Adjust Rate"},f:[{p:[28,5,1437],t:7,e:"ui-button",a:{icon:"fast-backward",action:"rate",params:'{"adjust": -180}'},f:["180°"]}," ",{p:[29,5,1535],t:7,e:"ui-button",a:{icon:"step-backward",action:"rate",params:'{"adjust": -30}'},f:["30°"]}," ",{p:[30,5,1631],t:7,e:"ui-button",a:{icon:"backward",action:"rate",params:'{"adjust": -5}'},f:["5°"]}," ",{p:[31,5,1720],t:7,e:"ui-button",a:{icon:"forward",action:"rate",params:'{"adjust": 5}'},f:["5°"]}," ",{p:[32,5,1807],t:7,e:"ui-button",a:{icon:"step-forward",action:"rate",params:'{"adjust": 30}'},f:["30°"]}," ",{p:[33,5,1901],t:7,e:"ui-button",a:{icon:"fast-forward",action:"rate",params:'{"adjust": 180}'},f:["180°"]}]}]}," ",{p:{button:[{p:[38,5,2088],t:7,e:"ui-button",a:{icon:"refresh",action:"refresh"},f:["Refresh"]}]},t:7,e:"ui-display",a:{title:"Devices",button:0},f:[" ",{p:[40,2,2169],t:7,e:"ui-section",a:{label:"Solar Tracker"},f:[{p:[41,5,2209],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected_tracker"],s:'_0?"good":"bad"'},p:[41,18,2222]}]},f:[{t:2,x:{r:["data.connected_tracker"],s:'_0?"":"Not "'},p:[41,63,2267]},"Found"]}]}," ",{p:[43,2,2338],t:7,e:"ui-section",a:{label:"Solar Panels"},f:[{p:[44,3,2375],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected_panels"],s:'_0?"good":"bad"'},p:[44,16,2388]}]},f:[{t:2,x:{r:["adata.connected_panels"],s:"Math.round(_0)"},p:[44,60,2432]}," Panels Connected"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],310:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{t:4,f:[{p:[4,7,87],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.hasPowercell"],s:'_0?null:"disabled"'},p:[4,38,118]}],action:"eject"},f:["Eject"]}],n:50,r:"data.open",p:[3,5,62]}]},t:7,e:"ui-display",a:{title:"Power",button:0},f:[" ",{p:[7,3,226],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[8,5,258],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[8,22,275]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[9,14,326]}],state:[{t:2,x:{r:["data.hasPowercell"],s:'_0?null:"disabled"'},p:[9,54,366]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[10,22,431]}]}]}," ",{p:[12,3,490],t:7,e:"ui-section",a:{label:"Cell"},f:[{t:4,f:[{p:[14,7,554],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.powerLevel",p:[14,40,587]}]},f:[{t:2,x:{r:["adata.powerLevel"],s:"Math.fixed(_0)"},p:[14,61,608]},"%"]}],n:50,r:"data.hasPowercell",p:[13,5,521]},{t:4,n:51,f:[{p:[16,4,667],t:7,e:"span",a:{"class":"bad"},f:["No Cell"]}],r:"data.hasPowercell"}]}]}," ",{p:[20,1,744],t:7,e:"ui-display",a:{title:"Thermostat"},f:[{p:[21,3,779],t:7,e:"ui-section",a:{label:"Current Temperature"},f:[{p:[22,3,823],t:7,e:"span",f:[{t:2,x:{r:["adata.currentTemp"],s:"Math.round(_0)"},p:[22,9,829]},"°C"]}]}," ",{p:[24,2,894],t:7,e:"ui-section",a:{label:"Target Temperature"},f:[{p:[25,3,937],t:7,e:"span",f:[{t:2,x:{r:["adata.targetTemp"],s:"Math.round(_0)"},p:[25,9,943]},"°C"]}]}," ",{t:4,f:[{p:[28,5,1031],t:7,e:"ui-section",a:{label:"Adjust Target"},f:[{p:[29,7,1073],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.targetTemp","data.minTemp"],s:'_0>_1?null:"disabled"'},p:[29,46,1112]}],action:"target",params:'{"adjust": -20}'}}," ",{p:[30,7,1218],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.targetTemp","data.minTemp"],s:'_0>_1?null:"disabled"'},p:[30,41,1252]}],action:"target",params:'{"adjust": -5}'}}," ",{p:[31,7,1357],t:7,e:"ui-button",a:{icon:"pencil",action:"target",params:'{"target": "input"}'},f:["Set"]}," ",{p:[32,7,1450],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.targetTemp","data.maxTemp"],s:'_0<_1?null:"disabled"'},p:[32,40,1483]}],action:"target",params:'{"adjust": 5}'}}," ",{p:[33,7,1587],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.targetTemp","data.maxTemp"],s:'_0<_1?null:"disabled"'},p:[33,45,1625]}],action:"target",params:'{"adjust": 20}'}}]}],n:50,r:"data.open",p:[27,3,1008]}," ",{p:[36,3,1754],t:7,e:"ui-section",a:{label:"Mode"},f:[{t:4,f:[{p:[38,7,1808],t:7,e:"ui-button",a:{icon:"long-arrow-up",state:[{t:2,x:{r:["data.mode"],s:'_0=="heat"?"selected":null'},p:[38,46,1847]}],action:"mode",params:'{"mode": "heat"}'},f:["Heat"]}," ",{p:[39,7,1956],t:7,e:"ui-button",a:{icon:"long-arrow-down",state:[{t:2,x:{r:["data.mode"],s:'_0=="cool"?"selected":null'},p:[39,48,1997]}],action:"mode",params:'{"mode": "cool"}'},f:["Cool"]}," ",{p:[40,7,2106],t:7,e:"ui-button",a:{icon:"arrows-v",state:[{t:2,x:{r:["data.mode"],s:'_0=="auto"?"selected":null'},p:[40,41,2140]}],action:"mode",params:'{"mode": "auto"}'},f:["Auto"]}],n:50,r:"data.open",p:[37,3,1783]},{t:4,n:51,f:[{p:[42,4,2258],t:7,e:"span",f:[{t:2,x:{r:["text","data.mode"],s:"_0.titleCase(_1)"},p:[42,10,2264]}]}],r:"data.open"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],311:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:{button:[{p:[4,8,97],t:7,e:"ui-button",a:{action:"jump",params:['{"name" : ',{t:2,r:"name",p:[4,51,140]},"}"]},f:["Jump"]}," ",{p:[7,9,195],t:7,e:"ui-button",a:{action:"spawn",params:['{"name" : ',{t:2,r:"name",p:[7,53,239]},"}"]},f:["Spawn"]}]},t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[2,22,46]}],button:0},f:[" ",{p:[11,3,308],t:7,e:"ui-section",a:{label:"Description"},f:[{p:[12,5,346],t:7,e:"span",f:[{t:3,r:"desc",p:[12,11,352]}]}]}," ",{p:[14,3,390],t:7,e:"ui-section",a:{label:"Spawners left"},f:[{p:[15,5,430],t:7,e:"span",f:[{t:2,r:"amount_left",p:[15,11,436]}]}]}]}],n:52,r:"data.spawners",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{205:205}],312:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,31],t:7,e:"ui-display",a:{title:[{t:2,r:"class",p:[2,22,50]}," Alarms"]},f:[{p:[3,5,74],t:7,e:"ul",f:[{t:4,f:[{p:[5,9,107],t:7,e:"li",f:[{t:2,r:".",p:[5,13,111]}]}],n:52,r:".",p:[4,7,86]},{t:4,n:51,f:[{p:[7,9,147],t:7,e:"li",f:["System Nominal"]}],r:"."}]}]}],n:52,i:"class",r:"data.alarms",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{205:205}],313:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,42],t:7,e:"ui-notice",f:[{p:[3,5,59],t:7,e:"span",f:["Biological entity detected in contents. Please remove."]}]}],n:50,x:{r:["data.occupied","data.safeties"],s:"_0&&_1"},p:[1,1,0]},{t:4,f:[{p:[7,3,179],t:7,e:"ui-notice",f:[{p:[8,5,196],t:7,e:"span",f:["Contents are being disinfected. Please wait."]}]}],n:50,r:"data.uv_active",p:[6,1,153]},{t:4,n:51,f:[{p:{button:[{t:4,f:[{p:[13,25,369],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[13,42,386]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Unlock":"Lock"'},p:[13,93,437]}]}],n:50,x:{r:["data.open"],s:"!_0"},p:[13,7,351]}," ",{t:4,f:[{p:[14,27,519],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.open"],s:'_0?"sign-out":"sign-in"'},p:[14,44,536]}],action:"door"},f:[{t:2,x:{r:["data.open"],s:'_0?"Close":"Open"'},p:[14,98,590]}]}],n:50,x:{r:["data.locked"],s:"!_0"},p:[14,7,499]}]},t:7,e:"ui-display",a:{title:"Storage",button:0},f:[" ",{t:4,f:[{p:[17,7,692],t:7,e:"ui-notice",f:[{p:[18,9,713],t:7,e:"span",f:["Unit Locked"]}]}],n:50,r:"data.locked",p:[16,5,665]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.open"],s:"_0"},f:[{p:[21,9,793],t:7,e:"ui-section",a:{label:"Helmet"},f:[{p:[22,11,832],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.helmet"],s:'_0?"square":"square-o"'},p:[22,28,849]}],state:[{t:2,x:{r:["data.helmet"],s:'_0?null:"disabled"'},p:[22,75,896]}],action:"dispense",params:'{"item": "helmet"}'},f:[{t:2,x:{r:["data.helmet"],s:'_0||"Empty"'},p:[23,59,992]}]}]}," ",{p:[25,9,1063],t:7,e:"ui-section",a:{label:"Suit"},f:[{p:[26,11,1100],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.suit"],s:'_0?"square":"square-o"'},p:[26,28,1117]}],state:[{t:2,x:{r:["data.suit"],s:'_0?null:"disabled"'},p:[26,74,1163]}],action:"dispense",params:'{"item": "suit"}'},f:[{t:2,x:{r:["data.suit"],s:'_0||"Empty"'},p:[27,57,1255]}]}]}," ",{p:[29,9,1324],t:7,e:"ui-section",a:{label:"Mask"},f:[{p:[30,11,1361],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mask"],s:'_0?"square":"square-o"'},p:[30,28,1378]}],state:[{t:2,x:{r:["data.mask"],s:'_0?null:"disabled"'},p:[30,74,1424]}],action:"dispense",params:'{"item": "mask"}'},f:[{t:2,x:{r:["data.mask"],s:'_0||"Empty"'},p:[31,57,1516]}]}]}," ",{p:[33,9,1585],t:7,e:"ui-section",a:{label:"Storage"},f:[{p:[34,11,1625],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.storage"],s:'_0?"square":"square-o"'},p:[34,28,1642]}],state:[{t:2,x:{r:["data.storage"],s:'_0?null:"disabled"'},p:[34,77,1691]}],action:"dispense",params:'{"item": "storage"}'},f:[{t:2,x:{r:["data.storage"],s:'_0||"Empty"'},p:[35,60,1789]}]}]}]},{t:4,n:50,x:{r:["data.open"],s:"!(_0)"},f:[" ",{p:[38,7,1873],t:7,e:"ui-button",a:{icon:"recycle",state:[{t:2,x:{r:["data.occupied","data.safeties"],s:'_0&&_1?"disabled":null'},p:[38,40,1906]}],action:"uv"},f:["Disinfect"]}]}],r:"data.locked"}]}],r:"data.uv_active"}]},e.exports=a.extend(r.exports)},{205:205}],314:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,5,18],t:7,e:"ui-section",a:{label:"Dispense"},f:[{p:[3,9,57],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.plasma"],s:'_0?"square":"square-o"'},p:[3,26,74]}],state:[{t:2,x:{r:["data.plasma"],s:'_0?null:"disabled"'},p:[3,74,122]}],action:"plasma"},f:["Plasma (",{t:2,x:{r:["adata.plasma"],s:"Math.round(_0)"},p:[4,37,196]},")"]}," ",{p:[5,9,247],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.oxygen"],s:'_0?"square":"square-o"'},p:[5,26,264]}],state:[{t:2,x:{r:["data.oxygen"],s:'_0?null:"disabled"'},p:[5,74,312]}],action:"oxygen"},f:["Oxygen (",{t:2,x:{r:["adata.oxygen"],s:"Math.round(_0)"},p:[6,37,386]},")"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],315:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{tankPressureState:function(){var t=this.get("data.tankPressure");return t>=200?"good":t>=100?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[14,1,295],t:7,e:"ui-notice",f:[{p:[15,3,310],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.connected"],s:'_0?"is":"is not"'},p:[15,23,330]}," connected to a mask."]}]}," ",{p:[17,1,409],t:7,e:"ui-display",f:[{p:[18,3,425],t:7,e:"ui-section",a:{label:"Tank Pressure"},f:[{p:[19,7,467],t:7,e:"ui-bar",a:{min:"0",max:"1013",value:[{t:2,r:"data.tankPressure",p:[19,41,501]}],state:[{t:2,r:"tankPressureState",p:[20,16,540]}]},f:[{t:2,x:{r:["adata.tankPressure"],s:"Math.round(_0)"},p:[20,39,563]}," kPa"]}]}," ",{p:[22,3,631],t:7,e:"ui-section",a:{label:"Release Pressure"},f:[{p:[23,5,674],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.minReleasePressure",p:[23,18,687]}],max:[{t:2,r:"data.maxReleasePressure",p:[23,52,721]}],value:[{t:2,r:"data.releasePressure",p:[24,14,764]}]},f:[{t:2,x:{r:["adata.releasePressure"],s:"Math.round(_0)"},p:[24,40,790]}," kPa"]}]}," ",{p:[26,3,861],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[27,5,906],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.releasePressure","data.defaultReleasePressure"],s:'_0!=_1?null:"disabled"'},p:[27,38,939]}],action:"pressure", -params:'{"pressure": "reset"}'},f:["Reset"]}," ",{p:[29,5,1095],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.releasePressure","data.minReleasePressure"],s:'_0>_1?null:"disabled"'},p:[29,36,1126]}],action:"pressure",params:'{"pressure": "min"}'},f:["Min"]}," ",{p:[31,5,1273],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[32,5,1368],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.releasePressure","data.maxReleasePressure"],s:'_0<_1?null:"disabled"'},p:[32,35,1398]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],316:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[2,5,33],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[3,9,75],t:7,e:"span",f:[{t:2,x:{r:["adata.temperature"],s:"Math.fixed(_0,2)"},p:[3,15,81]}," K"]}]}," ",{p:[5,5,151],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[6,9,190],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.fixed(_0,2)"},p:[6,15,196]}," kPa"]}]}]}," ",{p:[9,1,276],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[10,5,311],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[11,9,347],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[11,26,364]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[11,70,408]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[12,28,469]}]}]}," ",{p:[14,5,531],t:7,e:"ui-section",a:{label:"Target Temperature"},f:[{p:[15,9,580],t:7,e:"ui-button",a:{icon:"fast-backward",style:[{t:2,x:{r:["data.target","data.min"],s:'_0==_1?"disabled":null'},p:[15,48,619]}],action:"target",params:'{"adjust": -20}'}}," ",{p:[17,9,733],t:7,e:"ui-button",a:{icon:"backward",style:[{t:2,x:{r:["data.target","data.min"],s:'_0==_1?"disabled":null'},p:[17,43,767]}],action:"target",params:'{"adjust": -5}'}}," ",{p:[19,9,880],t:7,e:"ui-button",a:{icon:"pencil",action:"target",params:'{"target": "input"}'},f:[{t:2,x:{r:["adata.target"],s:"Math.fixed(_0,2)"},p:[19,79,950]}]}," ",{p:[20,9,1003],t:7,e:"ui-button",a:{icon:"forward",style:[{t:2,x:{r:["data.target","data.max"],s:'_0==_1?"disabled":null'},p:[20,42,1036]}],action:"target",params:'{"adjust": 5}'}}," ",{p:[22,9,1148],t:7,e:"ui-button",a:{icon:"fast-forward",style:[{t:2,x:{r:["data.target","data.max"],s:'_0==_1?"disabled":null'},p:[22,47,1186]}],action:"target",params:'{"adjust": 20}'}}]}]}]},e.exports=a.extend(r.exports)},{205:205}],317:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{powerState:function(t){switch(t){case 1:return"good";default:return"bad"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[13,1,173],t:7,e:"ui-notice",f:[{p:[14,2,187],t:7,e:"ui-section",a:{label:"Reconnect"},f:[{p:[15,3,221],t:7,e:"div",a:{style:"float:right"},f:[{p:[16,4,251],t:7,e:"ui-button",a:{icon:"refresh",action:"reconnect",state:[{t:2,r:"data.connected",p:[16,56,303]}]},f:["Reconnect"]}]}]}]}," ",{p:[20,1,386],t:7,e:"ui-display",a:{title:"Turbine Controller"},f:[{p:[21,2,428],t:7,e:"ui-section",a:{label:"Status"},f:[{t:4,f:[{p:[23,4,484],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.online"],s:"_0(_1)"},p:[23,17,497]}]},f:[{t:2,x:{r:["data.online","data.compressor_broke","data.turbine_broke"],s:'_0&&!(_1||_2)?"Online":"Offline"'},p:[23,46,526]}]}],n:50,r:"data.working",p:[22,3,459]},{t:4,n:51,f:[{p:[25,4,638],t:7,e:"span",a:{"class":"bad"},f:["Broken"]}],r:"data.working"}," ",{p:[27,3,684],t:7,e:"div",a:{style:"float:right"},f:[{p:[28,4,714],t:7,e:"ui-button",a:{icon:"power-off",action:"power",state:[{t:2,r:"data.working",p:[28,54,764]}],style:[{t:2,x:{r:["data.online"],s:'_0?"selected":""'},p:[28,79,789]}]},f:["On"]}," ",{p:[29,4,843],t:7,e:"ui-button",a:{icon:"close",action:"power",state:[{t:2,r:"data.working",p:[29,50,889]}],style:[{t:2,x:{r:["data.online"],s:'_0?"":"selected"'},p:[29,75,914]}]},f:["Off"]}]}," ",{t:4,f:[{p:[32,4,1012],t:7,e:"br"}," [ ",{p:[33,6,1023],t:7,e:"span",a:{"class":"bad"},f:["Compressor is inoperable"]}," ]"],n:50,r:"data.compressor_broke",p:[31,3,978]}," ",{t:4,f:[{p:[36,4,1120],t:7,e:"br"}," [ ",{p:[37,6,1131],t:7,e:"span",a:{"class":"bad"},f:["Turbine is inoperable"]}," ]"],n:50,r:"data.turbine_broke",p:[35,3,1089]}]}]}," ",{p:[41,1,1223],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[42,2,1253],t:7,e:"ui-section",a:{label:"Turbine Speed"},f:[{p:[43,3,1291],t:7,e:"span",f:[{t:2,x:{r:["data.working","data.rpm"],s:'_0?_1:"--"'},p:[43,9,1297]}," RPM"]}]}," ",{p:[45,2,1361],t:7,e:"ui-section",a:{label:"Internal Temp"},f:[{p:[46,3,1399],t:7,e:"span",f:[{t:2,x:{r:["data.working","data.temp"],s:'_0?_1:"--"'},p:[46,9,1405]}," K"]}]}," ",{p:[48,2,1468],t:7,e:"ui-section",a:{label:"Generated Power"},f:[{p:[49,3,1508],t:7,e:"span",f:[{t:2,x:{r:["data.working","data.power"],s:'_0?_1:"--"'},p:[49,9,1514]}]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],318:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{},oninit:function(){this.on({hover:function(t){var e=this.get("data.telecrystals");e>=t.context.params.cost&&this.set("hovered",t.context.params)},unhover:function(t){this.set("hovered")}})}}}(r),r.exports.template={v:3,t:[" ",{p:{button:[{t:4,f:[{p:[23,7,482],t:7,e:"ui-button",a:{icon:"lock",action:"lock"},f:["Lock"]}],n:50,r:"data.lockable",p:[22,5,453]}]},t:7,e:"ui-display",a:{title:"Uplink",button:0},f:[" ",{p:[26,3,568],t:7,e:"ui-section",a:{label:"Telecrystals",right:0},f:[{p:[27,5,613],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.telecrystals"],s:'_0>0?"good":"bad"'},p:[27,18,626]}]},f:[{t:2,r:"data.telecrystals",p:[27,62,670]}," TC"]}]}]}," ",{t:4,f:[{p:[31,3,764],t:7,e:"ui-display",f:[{p:[32,2,779],t:7,e:"ui-button",a:{action:"select",params:['{"category": "',{t:2,r:"name",p:[32,51,828]},'"}']},f:[{t:2,r:"name",p:[32,63,840]}]}," ",{t:4,f:[{p:[34,4,883],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[34,23,902]}],candystripe:0,right:0},f:[{p:[35,3,934],t:7,e:"ui-button",a:{tooltip:[{t:2,r:"name",p:[35,23,954]},": ",{t:2,r:"desc",p:[35,33,964]}],"tooltip-side":"left",state:[{t:2,x:{r:["data.telecrystals","hovered.cost","cost","hovered.item","name"],s:'_0<_2||(_0-_1<_2&&_3!=_4)?"disabled":null'},p:[36,12,1006]}],action:"buy",params:['{"category": "',{t:2,r:"category",p:[37,40,1165]},'", "item": ',{t:2,r:"name",p:[37,63,1188]},', "cost": ',{t:2,r:"cost",p:[37,81,1206]},"}"]},v:{hover:"hover",unhover:"unhover"},f:[{t:2,r:"cost",p:[38,43,1260]}," TC"]}]}],n:52,r:"items",p:[33,2,863]}]}],n:52,r:"data.categories",p:[30,1,735]}]},e.exports=a.extend(r.exports)},{205:205}],319:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Products"},f:[{t:4,f:[{p:[3,2,58],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[3,21,77]}],labelcolor:[{t:2,r:"color",p:[3,43,99]}],candystripe:0,right:0},f:[{p:[4,3,132],t:7,e:"span",f:[{p:[4,9,138],t:7,e:"b",f:[{t:2,r:"amount",p:[4,12,141]}]}]}," ",{p:[5,3,166],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["amount"],s:'(_0>0)?null:"disabled"'},p:[5,22,185]}],icon:[{t:2,x:{r:["amount"],s:'(_0>0)?"cart-arrow-down":"ban"'},p:[5,66,229]}],action:"vend",params:['{"key": ',{t:2,r:"key",p:[5,142,305]},"}"]},f:[{t:2,x:{r:["amount"],s:'(_0>0)?"Vend":"Sold Out"'},p:[5,152,315]}]}]}],n:52,r:"data.products",p:[2,2,32]}]}," ",{t:4,f:[{p:[10,2,434],t:7,e:"ui-display",a:{title:"Coin Slot"},f:[{p:[11,3,468],t:7,e:"ui-section",a:{label:"Coin"},f:[{p:[12,3,497],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.coin"],s:'_0?"bold":null'},p:[12,16,510]}]},f:[{t:2,x:{r:["data.coin"],s:'_0?_0:"No Coin"'},p:[12,47,541]}]}," ",{p:[13,4,590],t:7,e:"ui-button",a:{icon:"arrow-circle-up",state:[{t:2,x:{r:["data.coin","data.canvend"],s:'_0&&_1?null:"disabled"'},p:[13,45,631]}],action:"eject"},f:["Eject Coin"]}]}]}],n:50,r:"data.coinslot",p:[9,1,410]}]},e.exports=a.extend(r.exports)},{205:205}],320:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{healthState:function(t){var e=this.get("data.vr_avatar.maxhealth");return t>e/1.5?"good":t>e/3?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[14,1,292],t:7,e:"ui-display",f:[{t:4,f:[{p:[16,3,333],t:7,e:"ui-display",a:{title:"Virtual Avatar"},f:[{p:[17,4,373],t:7,e:"ui-section",a:{label:"Name"},f:[{t:2,r:"data.vr_avatar.name",p:[18,5,404]}]}," ",{p:[20,4,450],t:7,e:"ui-section",a:{label:"Status"},f:[{t:2,r:"data.vr_avatar.status",p:[21,5,483]}]}," ",{p:[23,4,531],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[24,5,564],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.vr_avatar.maxhealth",p:[24,26,585]}],value:[{t:2,r:"adata.vr_avatar.health",p:[24,64,623]}],state:[{t:2,x:{r:["healthState","adata.vr_avatar.health"],s:"_0(_1)"},p:[24,99,658]}]},f:[{t:2,x:{r:["adata.vr_avatar.health"],s:"Math.round(_0)"},p:[24,140,699]},"/",{t:2,r:"adata.vr_avatar.maxhealth",p:[24,179,738]}]}]}]}],n:50,r:"data.vr_avatar",p:[15,2,307]},{t:4,n:51,f:[{p:[28,3,826],t:7,e:"ui-display",a:{title:"Virtual Avatar"},f:["No Virtual Avatar detected"]}],r:"data.vr_avatar"}," ",{p:[32,2,922],t:7,e:"ui-display",a:{title:"VR Commands"},f:[{p:[33,3,958],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.toggle_open"],s:'_0?"times":"plus"'},p:[33,20,975]}],action:"toggle_open"},f:[{t:2,x:{r:["data.toggle_open"],s:'_0?"Close":"Open"'},p:[34,4,1042]}," the VR Sleeper"]}," ",{t:4,f:[{p:[37,4,1144],t:7,e:"ui-button",a:{icon:"signal",action:"vr_connect"},f:["Connect to VR"]}],n:50,r:"data.isoccupant",p:[36,3,1116]}," ",{t:4,f:[{p:[42,4,1267],t:7,e:"ui-button",a:{icon:"ban",action:"delete_avatar"},f:["Delete Virtual Avatar"]}],n:50,r:"data.vr_avatar",p:[41,3,1240]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],321:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{t:4,f:[{p:[3,5,42],t:7,e:"ui-section",a:{label:[{t:2,r:"color",p:[3,24,61]},{t:2,x:{r:["wire"],s:'_0?" ("+_0+")":""'},p:[3,33,70]}],labelcolor:[{t:2,r:"color",p:[3,80,117]}],candystripe:0,right:0},f:[{p:[4,7,154],t:7,e:"ui-button",a:{action:"cut",params:['{"wire":"',{t:2,r:"color",p:[4,48,195]},'"}']},f:[{t:2,x:{r:["cut"],s:'_0?"Mend":"Cut"'},p:[4,61,208]}]}," ",{p:[5,7,252],t:7,e:"ui-button",a:{action:"pulse",params:['{"wire":"',{t:2,r:"color",p:[5,50,295]},'"}']},f:["Pulse"]}," ",{p:[6,7,333],t:7,e:"ui-button",a:{action:"attach",params:['{"wire":"',{t:2,r:"color",p:[6,51,377]},'"}']},f:[{t:2,x:{r:["attached"],s:'_0?"Detach":"Attach"'},p:[6,64,390]}]}]}],n:52,r:"data.wires",p:[2,3,16]}]}," ",{t:4,f:[{p:[11,3,508],t:7,e:"ui-display",f:[{t:4,f:[{p:[13,7,555],t:7,e:"ui-section",f:[{t:2,r:".",p:[13,19,567]}]}],n:52,r:"data.status",p:[12,5,526]}]}],n:50,r:"data.status",p:[10,1,485]}]},e.exports=a.extend(r.exports)},{205:205}],322:[function(t,e,n){(function(e){"use strict";var n=t(205),a=e.interopRequireDefault(n);t(194),t(1),t(190),t(193);var r=t(323),i=e.interopRequireDefault(r),o=t(324),s=t(191),p=t(192),u=e.interopRequireDefault(p);a["default"].DEBUG=/minified/.test(function(){}),Object.assign(Math,t(328)),window.initialize=function(e){window.tgui=window.tgui||new i["default"]({el:"#container",data:function(){var n=JSON.parse(e);return{constants:t(325),text:t(329),config:n.config,data:n.data,adata:n.data}}})};var c=document.getElementById("data"),l=c.textContent,d=c.getAttribute("data-ref");"{}"!==l&&(window.initialize(l),c.remove()),(0,o.act)(d,"tgui:initialize"),(0,s.loadCSS)("font-awesome.min.css");var f=new u["default"]("FontAwesome");f.check("").then(function(){return document.body.classList.add("icons")})["catch"](function(){return document.body.classList.add("no-icons")})}).call(this,t("babel/external-helpers"))},{1:1,190:190,191:191,192:192,193:193,194:194,205:205,323:323,324:324,325:325,328:328,329:329,"babel/external-helpers":"babel/external-helpers"}],323:[function(t,e,n){var a=t(205),r={exports:{}};!function(e){"use strict";var n=t(324),a=t(326);e.exports={components:{"ui-bar":t(206),"ui-button":t(207),"ui-display":t(208),"ui-input":t(209),"ui-linegraph":t(210),"ui-notice":t(211),"ui-section":t(213),"ui-subdisplay":t(214),"ui-tabs":t(215)},events:{enter:t(203).enter,space:t(203).space},transitions:{fade:t(204)},onconfig:function(){var e=this.get("config.interface"),n={ai_airlock:t(219),airalarm:t(220),"airalarm/back":t(221),"airalarm/modes":t(222),"airalarm/scrubbers":t(223),"airalarm/status":t(224),"airalarm/thresholds":t(225),"airalarm/vents":t(226),airlock_electronics:t(227),apc:t(228),atmos_alert:t(229),atmos_control:t(230),atmos_filter:t(231),atmos_mixer:t(232),atmos_pump:t(233),brig_timer:t(234),bsa:t(235),canister:t(236),cargo:t(237),cellular_emporium:t(238),chem_dispenser:t(239),chem_heater:t(240),chem_master:t(241),clockwork_slab:t(242),codex_gigas:t(243),computer_fabricator:t(244),crayon:t(245),cryo:t(246),disposal_unit:t(247),dna_vault:t(248),dogborg_sleeper:t(249),eightball:t(250),emergency_shuttle_console:t(251),engraved_message:t(252),error:t(253),"exofab - Copia":t(254),exonet_node:t(255),firealarm:t(256),gps:t(257),gulag_console:t(258),gulag_item_reclaimer:t(259),holodeck:t(260),implantchair:t(261),intellicard:t(262),keycard_auth:t(263),labor_claim_console:t(264),language_menu:t(265),launchpad_remote:t(266),mech_bay_power_console:t(267),mulebot:t(268),ntnet_relay:t(269),ntos_ai_restorer:t(270),ntos_card:t(271),ntos_configuration:t(272),ntos_file_manager:t(273),ntos_main:t(274),ntos_net_chat:t(275),ntos_net_dos:t(276),ntos_net_downloader:t(277),ntos_net_monitor:t(278),ntos_net_transfer:t(279),ntos_power_monitor:t(280),ntos_revelation:t(281),ntos_station_alert:t(282),ntos_supermatter_monitor:t(283),ntosheader:t(284),nuclear_bomb:t(285),operating_computer:t(286),ore_redemption_machine:t(287),pandemic:t(288),personal_crafting:t(289),portable_pump:t(290),portable_scrubber:t(291),power_monitor:t(292),radio:t(293),reagentgrinder:t(294),rpd:t(295),"rpd/colorsel":t(296),"rpd/dirsel":t(297),sat_control:t(298),scrubbing_types:t(299),shuttle_manipulator:t(300),"shuttle_manipulator/modification":t(301),"shuttle_manipulator/status":t(302),"shuttle_manipulator/templates":t(303),sleeper:t(304),slime_swap_body:t(305),smartvend:t(306),smes:t(307),smoke_machine:t(308),solar_control:t(309),space_heater:t(310),spawners_menu:t(311),station_alert:t(312),suit_storage_unit:t(313),tank_dispenser:t(314),tanks:t(315),thermomachine:t(316),turbine_computer:t(317),uplink:t(318),vending:t(319),vr_sleeper:t(320),wires:t(321)};e in n?this.components["interface"]=n[e]:this.components["interface"]=n.error},oninit:function(){this.observe("config.style",function(t,e,n){t&&document.body.classList.add(t),e&&document.body.classList.remove(e)})},oncomplete:function(){if(this.get("config.locked")){var t=(0,a.lock)(window.screenLeft,window.screenTop),e=t.x,r=t.y;(0,n.winset)(this.get("config.window"),"pos",e+","+r)}(0,n.winset)("mapwindow.map","focus",!0)}}}(r),r.exports.template={v:3,t:[" "," "," "," ",{p:[56,1,1874],t:7,e:"titlebar",f:[{t:3,r:"config.title",p:[56,11,1884]}]}," ",{p:[57,1,1915],t:7,e:"main",f:[{p:[58,3,1925],t:7,e:"warnings"}," ",{p:[59,3,1940],t:7,e:"interface"}]}," ",{t:4,f:[{p:[62,3,1990],t:7,e:"resize"}],n:50,r:"config.titlebar",p:[61,1,1963]}]},r.exports.components=r.exports.components||{};var i={warnings:t(218),titlebar:t(217),resize:t(212)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{203:203,204:204,205:205,206:206,207:207,208:208,209:209,210:210,211:211,212:212,213:213,214:214,215:215,217:217,218:218,219:219,220:220,221:221,222:222,223:223,224:224,225:225,226:226,227:227,228:228,229:229,230:230,231:231,232:232,233:233,234:234,235:235,236:236,237:237,238:238,239:239,240:240,241:241,242:242,243:243,244:244,245:245,246:246,247:247,248:248,249:249,250:250,251:251,252:252,253:253,254:254,255:255,256:256,257:257,258:258,259:259,260:260,261:261,262:262,263:263,264:264,265:265,266:266,267:267,268:268,269:269,270:270,271:271,272:272,273:273,274:274,275:275,276:276,277:277,278:278,279:279,280:280,281:281,282:282,283:283,284:284,285:285,286:286,287:287,288:288,289:289,290:290,291:291,292:292,293:293,294:294,295:295,296:296,297:297,298:298,299:299,300:300,301:301,302:302,303:303,304:304,305:305,306:306,307:307,308:308,309:309,310:310,311:311,312:312,313:313,314:314,315:315,316:316,317:317,318:318,319:319,320:320,321:321,324:324,326:326}],324:[function(t,e,n){"use strict";function a(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return"byond://"+e+"?"+Object.keys(t).map(function(e){return o(e)+"="+o(t[e])}).join("&")}function r(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};window.location.href=a(Object.assign({src:t,action:e},n))}function i(t,e,n){var r;window.location.href=a((r={},r[t+"."+e]=n,r),"winset")}n.__esModule=!0,n.href=a,n.act=r,n.winset=i;var o=encodeURIComponent},{}],325:[function(t,e,n){"use strict";n.__esModule=!0;n.UI_INTERACTIVE=2,n.UI_UPDATE=1,n.UI_DISABLED=0,n.UI_CLOSE=-1},{}],326:[function(t,e,n){"use strict";function a(t,e){return 0>t?t=0:t+window.innerWidth>window.screen.availWidth&&(t=window.screen.availWidth-window.innerWidth),0>e?e=0:e+window.innerHeight>window.screen.availHeight&&(e=window.screen.availHeight-window.innerHeight),{x:t,y:e}}function r(t){if(t.preventDefault(),this.get("drag")){if(this.get("x")){var e=t.screenX-this.get("x")+window.screenLeft,n=t.screenY-this.get("y")+window.screenTop;if(this.get("config.locked")){var r=a(e,n);e=r.x,n=r.y}(0,s.winset)(this.get("config.window"),"pos",e+","+n)}this.set({x:t.screenX,y:t.screenY})}}function i(t,e){return t=Math.clamp(100,window.screen.width,t),e=Math.clamp(100,window.screen.height,e),{x:t,y:e}}function o(t){if(t.preventDefault(),this.get("resize")){if(this.get("x")){var e=t.screenX-this.get("x")+window.innerWidth,n=t.screenY-this.get("y")+window.innerHeight,a=i(e,n);e=a.x,n=a.y,(0,s.winset)(this.get("config.window"),"size",e+","+n)}this.set({x:t.screenX,y:t.screenY})}}n.__esModule=!0,n.lock=a,n.drag=r,n.sane=i,n.resize=o;var s=t(324)},{324:324}],327:[function(t,e,n){"use strict";function a(t,e){for(var n=t,a=Array.isArray(n),i=0,n=a?n:n[Symbol.iterator]();;){var o;if(a){if(i>=n.length)break;o=n[i++]}else{if(i=n.next(),i.done)break;o=i.value}var s=o;s.textContent.toLowerCase().includes(e)?(s.style.display="",r(s,e)):s.style.display="none"}}function r(t,e){for(var n=t.queryAll("section"),a=t.query("header").textContent.toLowerCase().includes(e),r=n,i=Array.isArray(r),o=0,r=i?r:r[Symbol.iterator]();;){var s;if(i){if(o>=r.length)break;s=r[o++]}else{if(o=r.next(),o.done)break;s=o.value}var p=s;a||p.textContent.toLowerCase().includes(e)?p.style.display="":p.style.display="none"}}n.__esModule=!0,n.filterMulti=a,n.filter=r},{}],328:[function(t,e,n){"use strict";function a(t,e,n){return Math.max(t,Math.min(n,e))}function r(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;return+(Math.round(t+"e"+e)+"e-"+e)}n.__esModule=!0,n.clamp=a,n.fixed=r},{}],329:[function(t,e,n){"use strict";function a(t){return t[0].toUpperCase()+t.slice(1).toLowerCase()}function r(t){return t.replace(/\w\S*/g,a)}function i(t,e){for(t=""+t;t.length1){for(var p=Array(o),u=0;o>u;u++)p[u]=arguments[u+3];n.children=p}return{$$typeof:t,type:e,key:void 0===a?null:""+a,ref:null,props:n,_owner:null}}}(),e.asyncIterator=function(t){if("function"==typeof Symbol){if(Symbol.asyncIterator){var e=t[Symbol.asyncIterator];if(null!=e)return e.call(t)}if(Symbol.iterator)return t[Symbol.iterator]()}throw new TypeError("Object is not async iterable")},e.asyncGenerator=function(){function t(t){this.value=t}function e(e){function n(t,e){return new Promise(function(n,r){var s={key:t,arg:e,resolve:n,reject:r,next:null};o?o=o.next=s:(i=o=s,a(t,e))})}function a(n,i){try{var o=e[n](i),s=o.value;s instanceof t?Promise.resolve(s.value).then(function(t){a("next",t)},function(t){a("throw",t)}):r(o.done?"return":"normal",o.value)}catch(p){r("throw",p)}}function r(t,e){switch(t){case"return":i.resolve({value:e,done:!0});break;case"throw":i.reject(e);break;default:i.resolve({value:e,done:!1})}i=i.next,i?a(i.key,i.arg):o=null}var i,o;this._invoke=n,"function"!=typeof e["return"]&&(this["return"]=void 0)}return"function"==typeof Symbol&&Symbol.asyncIterator&&(e.prototype[Symbol.asyncIterator]=function(){return this}),e.prototype.next=function(t){return this._invoke("next",t)},e.prototype["throw"]=function(t){return this._invoke("throw",t)},e.prototype["return"]=function(t){return this._invoke("return",t)},{wrap:function(t){return function(){return new e(t.apply(this,arguments))}},await:function(e){return new t(e)}}}(),e.asyncGeneratorDelegate=function(t,e){function n(n,a){return r=!0,a=new Promise(function(e){e(t[n](a))}),{done:!1,value:e(a)}}var a={},r=!1;return"function"==typeof Symbol&&Symbol.iterator&&(a[Symbol.iterator]=function(){return this}),a.next=function(t){return r?(r=!1,t):n("next",t)},"function"==typeof t["throw"]&&(a["throw"]=function(t){if(r)throw r=!1,t;return n("throw",t)}),"function"==typeof t["return"]&&(a["return"]=function(t){return n("return",t)}),a},e.asyncToGenerator=function(t){return function(){var e=t.apply(this,arguments);return new Promise(function(t,n){function a(r,i){try{var o=e[r](i),s=o.value}catch(p){return void n(p)}return o.done?void t(s):Promise.resolve(s).then(function(t){a("next",t)},function(t){a("throw",t)})}return a("next")})}},e.classCallCheck=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},e.createClass=function(){function t(t,e){for(var n=0;n=0||Object.prototype.hasOwnProperty.call(t,a)&&(n[a]=t[a]);return n},e.possibleConstructorReturn=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e},e.selfGlobal=void 0===t?self:t,e.set=function a(t,e,n,r){var i=Object.getOwnPropertyDescriptor(t,e);if(void 0===i){var o=Object.getPrototypeOf(t);null!==o&&a(o,e,n,r)}else if("value"in i&&i.writable)i.value=n;else{var s=i.set;void 0!==s&&s.call(r,n)}return n},e.slicedToArray=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(p){r=!0,i=p}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),e.slicedToArrayLoose=function(t,e){if(Array.isArray(t))return t;if(Symbol.iterator in Object(t)){for(var n,a=[],r=t[Symbol.iterator]();!(n=r.next()).done&&(a.push(n.value),!e||a.length!==e););return a}throw new TypeError("Invalid attempt to destructure non-iterable instance")},e.taggedTemplateLiteral=function(t,e){return Object.freeze(Object.defineProperties(t,{raw:{value:Object.freeze(e)}}))},e.taggedTemplateLiteralLoose=function(t,e){return t.raw=e,t},e.temporalRef=function(t,e,n){if(t===n)throw new ReferenceError(e+" is not defined - temporal dead zone");return t},e.temporalUndefined={},e.toArray=function(t){return Array.isArray(t)?t:Array.from(t)},e.toConsumableArray=function(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);e0"},p:[28,4,630]}],x:{r:["data.wires.main_1","data.wires.main_2"],s:"!_0||!_1"}}," ",{p:[32,3,744],t:7,e:"div",a:{style:"float:right"},f:[{p:[33,4,774],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"disrupt-main",state:[{t:2,x:{r:["data.power.main"],s:'_0?null:"disabled"'},p:[33,63,833]}]},f:["Disrupt"]}]}]}," ",{p:[36,2,922],t:7,e:"ui-section",a:{label:"Backup"},f:[{p:[37,3,953],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.power.backup"],s:"_0(_1)"},p:[37,16,966]}]},f:[{t:2,x:{r:["data.power.backup"],s:'_0?"Online":"Offline"'},p:[37,51,1001]}]}," ",{t:4,f:["[ ",{p:[39,6,1115],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.backup_1","data.wires.backup_2"],s:"!_0||!_1"},p:[38,3,1056]},{t:4,n:51,f:[{t:4,f:["[ ",{t:2,r:"data.power.backup_timeleft",p:[42,7,1224]}," seconds left ]"],n:50,x:{r:["data.power.backup_timeleft"],s:"_0>0"},p:[41,4,1178]}],x:{r:["data.wires.backup_1","data.wires.backup_2"],s:"!_0||!_1"}}," ",{p:[45,3,1296],t:7,e:"div",a:{style:"float:right"},f:[{p:[46,4,1326],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"disrupt-backup",state:[{t:2,x:{r:["data.power.backup"],s:'_0?null:"disabled"'},p:[46,65,1387]}]},f:["Disrupt"]}]}]}," ",{p:[49,2,1478],t:7,e:"ui-section",a:{label:"Electrify"},f:[{p:[50,3,1512],t:7,e:"span",a:{"class":[{t:2,x:{r:["shockState","data.shock"],s:"_0(_1)"},p:[50,16,1525]}]},f:[{t:2,x:{r:["data.shock"],s:'_0==2?"Safe":"Electrified"'},p:[50,44,1553]}]}," ",{t:4,f:["[ ",{p:[52,6,1640],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.shock"],s:"!_0"},p:[51,3,1608]},{t:4,n:51,f:[{t:4,f:["[ ",{p:[55,7,1742],t:7,e:"span",a:{"class":"bad"},f:[{t:2,r:"data.shock_timeleft",p:[55,25,1760]}," seconds left"]}," ]"],n:50,x:{r:["data.shock_timeleft"],s:"_0>0"},p:[54,4,1703]}," ",{t:4,f:["[ ",{p:[58,7,1863],t:7,e:"span",a:{"class":"bad"},f:["Permanent"]}," ]"],n:50,x:{r:["data.shock_timeleft"],s:"_0==-1"},p:[57,4,1822]}],x:{r:["data.wires.shock"],s:"!_0"}}," ",{p:[61,3,1926],t:7,e:"div",a:{style:"float:right"},f:[{p:[62,4,1956],t:7,e:"ui-button",a:{icon:"wrench",action:"shock-restore",state:[{t:2,x:{r:["data.wires.shock","data.shock"],s:'_0&&_1==0?null:"disabled"'},p:[62,59,2011]}]},f:["Restore"]}," ",{p:[63,4,2094],t:7,e:"ui-button",a:{icon:"bolt",action:"shock-temp",state:[{t:2,x:{r:["data.wires.shock"],s:"!_0"},p:[63,54,2144]}]},f:["Set (Temporary)"]}," ",{p:[64,4,2199],t:7,e:"ui-button",a:{icon:"bolt",action:"shock-perm",state:[{t:2,x:{r:["data.wires.shock"],s:"!_0"},p:[64,53,2248]}]},f:["Set (Permanent)"]}]}]}]}," ",{p:[68,1,2341],t:7,e:"ui-display",a:{title:"Access & Door Control"},f:[{p:[69,2,2386],t:7,e:"ui-section",a:{label:"ID Scan"},f:[{t:4,f:["[ ",{p:[71,6,2455],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.id_scanner"],s:"!_0"},p:[70,3,2418]}," ",{p:[73,3,2516],t:7,e:"div",a:{style:"float:right"},f:[{p:[74,4,2546],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.id_scanner"],s:"!_0"},p:[74,22,2564]}],icon:"power-off",action:"idscan-on",style:[{t:2,x:{r:["data.id_scanner"],s:'_0?"selected":""'},p:[74,93,2635]}]},f:["Enabled"]}," ",{p:[75,4,2698],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.id_scanner"],s:"!_0"},p:[75,22,2716]}],icon:"close",action:"idscan-off",style:[{t:2,x:{r:["data.id_scanner"],s:'_0?"":"selected"'},p:[75,90,2784]}]},f:["Disabled"]}]}]}," ",{p:[78,2,2872],t:7,e:"ui-section",a:{label:"Emergency Access"},f:[{p:[79,3,2913],t:7,e:"div",a:{style:"float:right"},f:[{p:[80,4,2943],t:7,e:"ui-button",a:{icon:"power-off",action:"emergency-on",style:[{t:2,x:{r:["data.emergency"],s:'_0?"selected":""'},p:[80,61,3e3]}]},f:["Enabled"]}," ",{p:[81,4,3062],t:7,e:"ui-button",a:{icon:"close",action:"emergency-off",style:[{t:2,x:{r:["data.emergency"],s:'_0?"":"selected"'},p:[81,58,3116]}]},f:["Disabled"]}]}]}," ",{p:[84,2,3203],t:7,e:"br"}," ",{p:[85,2,3212],t:7,e:"ui-section",a:{label:"Door bolts"},f:[{t:4,f:["[ ",{p:[87,6,3279],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.bolts"],s:"!_0"},p:[86,3,3247]}," ",{p:[89,3,3340],t:7,e:"div",a:{style:"float:right"},f:[{p:[90,4,3370],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.bolts"],s:"!_0"},p:[90,22,3388]}],icon:"unlock",action:"bolt-raise",style:[{t:2,x:{r:["data.locked"],s:'_0?"":"selected"'},p:[90,85,3451]}]},f:["Raised"]}," ",{p:[91,4,3509],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.bolts"],s:"!_0"},p:[91,22,3527]}],icon:"lock",action:"bolt-drop",style:[{t:2,x:{r:["data.locked"],s:'_0?"selected":""'},p:[91,82,3587]}]},f:["Dropped"]}]}]}," ",{p:[94,2,3670],t:7,e:"ui-section",a:{label:"Door bolt lights"},f:[{t:4,f:["[ ",{p:[96,6,3744],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.lights"],s:"!_0"},p:[95,3,3711]}," ",{p:[98,3,3805],t:7,e:"div",a:{style:"float:right"},f:[{p:[99,4,3835],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.lights"],s:"!_0"},p:[99,22,3853]}],icon:"power-off",action:"light-on",style:[{t:2,x:{r:["data.lights"],s:'_0?"selected":""'},p:[99,88,3919]}]},f:["Enabled"]}," ",{p:[100,4,3978],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.lights"],s:"!_0"},p:[100,22,3996]}],icon:"close",action:"light-off",style:[{t:2,x:{r:["data.lights"],s:'_0?"":"selected"'},p:[100,85,4059]}]},f:["Disabled"]}]}]}," ",{p:[103,2,4143],t:7,e:"ui-section",a:{label:"Door force sensors"},f:[{t:4,f:["[ ",{p:[105,6,4217],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.safe"],s:"!_0"},p:[104,3,4186]}," ",{p:[107,3,4278],t:7,e:"div",a:{style:"float:right"},f:[{p:[108,4,4308],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.safe"],s:"!_0"},p:[108,22,4326]}],icon:"power-off",action:"safe-on",style:[{t:2,x:{r:["data.safe"],s:'_0?"selected":""'},p:[108,85,4389]}]},f:["Enabled"]}," ",{p:[109,4,4446],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.safe"],s:"!_0"},p:[109,22,4464]}],icon:"close",action:"safe-off",style:[{t:2,x:{r:["data.safe"],s:'_0?"":"selected"'},p:[109,82,4524]}]},f:["Disabled"]}]}]}," ",{p:[112,2,4606],t:7,e:"ui-section",a:{label:"Door timing saftey"},f:[{t:4,f:["[ ",{p:[114,6,4682],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.timing"],s:"!_0"},p:[113,3,4649]}," ",{p:[116,3,4743],t:7,e:"div",a:{style:"float:right"},f:[{p:[117,4,4773],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.timing"],s:"!_0"},p:[117,22,4791]}],icon:"power-off",action:"speed-on",style:[{t:2,x:{r:["data.speed"],s:'_0?"selected":""'},p:[117,88,4857]}]},f:["Enabled"]}," ",{p:[118,4,4915],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.timing"],s:"!_0"},p:[118,22,4933]}],icon:"close",action:"speed-off",style:[{t:2,x:{r:["data.speed"],s:'_0?"":"selected"'},p:[118,85,4996]}]},f:["Disabled"]}]}]}," ",{p:[121,2,5079],t:7,e:"br"}," ",{p:[122,2,5088],t:7,e:"ui-section",a:{label:"Door control"},f:[{t:4,f:["[ ",{p:[124,6,5166],t:7,e:"span",a:{"class":"bad"},f:["Door is ",{t:2,x:{r:["data.locked","data.welded"],s:'(_0?"bolted":"")+(_0&&_1?" and ":"")+(_1?"welded":"")'},p:[124,32,5192]}]}," ]"],n:50,x:{r:["data.locked","data.welded"],s:"_0||_1"},p:[123,3,5125]}," ",{p:[126,3,5327],t:7,e:"div",a:{style:"float:right"},f:[{p:[127,4,5357],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.locked","data.welded","data.opened"],s:'(_0||_1)||(_2&&"disabled")'},p:[127,22,5375]}],icon:"sign-out",action:"open-close"},f:["Open door"]}," ",{p:[128,4,5502],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.locked","data.welded","data.opened"],s:'(_0||_1)||(!_2&&"disabled")'},p:[128,22,5520]}],icon:"sign-in",action:"open-close"},f:["Close door"]}]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],220:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" "," "," "," "," ",{p:[7,1,267],t:7,e:"ui-notice",f:[{t:4,f:[{p:[9,5,312],t:7,e:"ui-section",a:{label:"Interface Lock"},f:[{p:[10,7,355],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"lock":"unlock"'},p:[10,24,372]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Engaged":"Disengaged"'},p:[10,75,423]}]}]}],n:50,r:"data.siliconUser",p:[8,3,282]},{t:4,n:51,f:[{p:[13,5,514],t:7,e:"span",f:["Swipe an ID card to ",{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[13,31,540]}," this interface."]}],r:"data.siliconUser"}]}," ",{p:[16,1,625],t:7,e:"status"}," ",{t:4,f:[{t:4,f:[{p:[19,7,719],t:7,e:"ui-display",a:{title:"Air Controls"},f:[{p:[20,9,762],t:7,e:"ui-section",f:[{p:[21,11,786],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.atmos_alarm"],s:'_0?"exclamation-triangle":"exclamation"'},p:[21,28,803]}],style:[{t:2,x:{r:["data.atmos_alarm"],s:'_0?"caution":null'},p:[21,98,873]}],action:[{t:2,x:{r:["data.atmos_alarm"],s:'_0?"reset":"alarm"'},p:[22,23,937]}]},f:["Area Atmosphere Alarm"]}]}," ",{p:[24,9,1045],t:7,e:"ui-section",f:[{p:[25,11,1069],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0==3?"exclamation-triangle":"exclamation"'},p:[25,28,1086]}],style:[{t:2,x:{r:["data.mode"],s:'_0==3?"danger":null'},p:[25,96,1154]}],action:"mode",params:['{"mode": ',{t:2,x:{r:["data.mode"],s:"_0==3?1:3"},p:[26,44,1236]},"}"]},f:["Panic Siphon"]}]}," ",{p:[28,9,1322],t:7,e:"br"}," ",{p:[29,9,1337],t:7,e:"ui-section",f:[{p:[30,11,1361],t:7,e:"ui-button",a:{icon:"sign-out",action:"tgui:view",params:'{"screen": "vents"}'},f:["Vent Controls"]}]}," ",{p:[32,9,1494],t:7,e:"ui-section",f:[{p:[33,11,1518],t:7,e:"ui-button",a:{icon:"filter",action:"tgui:view",params:'{"screen": "scrubbers"}'},f:["Scrubber Controls"]}]}," ",{p:[35,9,1657],t:7,e:"ui-section",f:[{p:[36,11,1681],t:7,e:"ui-button",a:{icon:"cog",action:"tgui:view",params:'{"screen": "modes"}'},f:["Operating Mode"]}]}," ",{p:[38,9,1810],t:7,e:"ui-section",f:[{p:[39,11,1834],t:7,e:"ui-button",a:{icon:"bar-chart",action:"tgui:view",params:'{"screen": "thresholds"}'},f:["Alarm Thresholds"]}]}]}],n:50,x:{r:["config.screen"],s:'_0=="home"'},p:[18,3,680]},{t:4,n:51,f:[{t:4,n:50,x:{r:["config.screen"],s:'_0=="vents"'},f:[{p:[43,5,2032],t:7,e:"vents"}]},{t:4,n:50,x:{r:["config.screen"],s:'(!(_0=="vents"))&&(_0=="scrubbers")'},f:[" ",{p:[45,5,2089],t:7,e:"scrubbers"}]},{t:4,n:50,x:{r:["config.screen"],s:'(!(_0=="vents"))&&((!(_0=="scrubbers"))&&(_0=="modes"))'},f:[" ",{p:[47,5,2146],t:7,e:"modes"}]},{t:4,n:50,x:{r:["config.screen"],s:'(!(_0=="vents"))&&((!(_0=="scrubbers"))&&((!(_0=="modes"))&&(_0=="thresholds")))'},f:[" ",{p:[49,5,2204],t:7,e:"thresholds"}]}],x:{r:["config.screen"],s:'_0=="home"'}}],n:50,x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"},p:[17,1,636]}]},r.exports.components=r.exports.components||{};var i={vents:t(226),modes:t(222),thresholds:t(225),status:t(224),scrubbers:t(223)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,222:222,223:223,224:224,225:225,226:226}],221:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-button",a:{icon:"arrow-left",action:"tgui:view",params:'{"screen": "home"}'},f:["Back"]}]},e.exports=a.extend(r.exports)},{205:205}],222:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:{button:[{p:[5,5,115],t:7,e:"back"}]},t:7,e:"ui-display",a:{title:"Operating Modes",button:0},f:[" ",{t:4,f:[{p:[8,5,168],t:7,e:"ui-section",f:[{p:[9,7,188],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["selected"],s:'_0?"check-square-o":"square-o"'},p:[9,24,205]}],state:[{t:2,x:{r:["selected","danger"],s:'_0?_1?"danger":"selected":null'},p:[10,16,267]}],action:"mode",params:['{"mode": ',{t:2,r:"mode",p:[11,40,361]},"}"]},f:[{t:2,r:"name",p:[11,51,372]}]}]}],n:52,r:"data.modes",p:[7,3,142]}]}]},r.exports.components=r.exports.components||{};var i={back:t(221)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,221:221}],223:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" "," ",{p:{button:[{p:[6,5,185],t:7,e:"back"}]},t:7,e:"ui-display",a:{title:"Scrubber Controls",button:0},f:[" ",{t:4,f:[{p:[9,5,242],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"long_name",p:[9,27,264]}]},f:[{p:[10,7,287],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[11,9,323],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["power"],s:'_0?"power-off":"close"'},p:[11,26,340]}],style:[{t:2,x:{r:["power"],s:'_0?"selected":null'},p:[11,68,382]}],action:"power",params:['{"id_tag": "',{t:2,r:"id_tag",p:[12,46,459]},'", "val": ',{t:2,x:{r:["power"],s:"+!_0"},p:[12,66,479]},"}"]},f:[{t:2,x:{r:["power"],s:'_0?"On":"Off"'},p:[12,80,493]}]}]}," ",{p:[14,7,558],t:7,e:"ui-section",a:{label:"Mode"},f:[{p:[15,9,593],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["scrubbing"],s:'_0?"filter":"sign-in"'},p:[15,26,610]}],style:[{t:2,x:{r:["scrubbing"],s:'_0?null:"danger"'},p:[15,71,655]}],action:"scrubbing",params:['{"id_tag": "',{t:2,r:"id_tag",p:[16,50,738]},'", "val": ',{t:2,x:{r:["scrubbing"],s:"+!_0"},p:[16,70,758]},"}"]},f:[{t:2,x:{r:["scrubbing"],s:'_0?"Scrubbing":"Siphoning"'},p:[16,88,776]}]}]}," ",{p:[18,7,858],t:7,e:"ui-section",a:{label:"Range"},f:[{p:[19,9,894],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["widenet"],s:'_0?"expand":"compress"'},p:[19,26,911]}],style:[{t:2,x:{r:["widenet"],s:'_0?"selected":null'},p:[19,70,955]}],action:"widenet",params:['{"id_tag": "',{t:2,r:"id_tag",p:[20,48,1036]},'", "val": ',{t:2,x:{r:["widenet"],s:"+!_0"},p:[20,68,1056]},"}"]},f:[{t:2,x:{r:["widenet"],s:'_0?"Expanded":"Normal"'},p:[20,84,1072]}]}]}," ",{p:[22,7,1148],t:7,e:"ui-section",a:{label:"Filters"},f:[{p:[23,9,1186],t:7,e:"filters"}]}]}],n:52,r:"data.scrubbers",p:[8,3,212]},{t:4,n:51,f:[{p:[27,5,1257],t:7,e:"span",a:{"class":"bad"},f:["Error: No scrubbers connected."]}],r:"data.scrubbers"}]}]},r.exports.components=r.exports.components||{};var i={filters:t(299),back:t(221)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,221:221,299:299}],224:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Air Status"},f:[{t:4,f:[{t:4,f:[{p:[4,7,110],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[4,26,129]}]},f:[{p:[5,6,146],t:7,e:"span",a:{"class":[{t:2,x:{r:["danger_level"],s:'_0==2?"bad":_0==1?"average":"good"'},p:[5,19,159]}]},f:[{t:2,x:{r:["value"],s:"Math.fixed(_0,2)"},p:[6,5,237]},{t:2,r:"unit",p:[6,29,261]}]}]}],n:52,r:"adata.environment_data",p:[3,5,70]}," ",{p:[10,5,322],t:7,e:"ui-section",a:{label:"Local Status"},f:[{p:[11,7,363],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.danger_level"],s:'_0==2?"bad bold":_0==1?"average bold":"good"'},p:[11,20,376]}]},f:[{t:2,x:{r:["data.danger_level"],s:'_0==2?"Danger (Internals Required)":_0==1?"Caution":"Optimal"'},p:[12,6,475]}]}]}," ",{p:[15,5,619],t:7,e:"ui-section",a:{label:"Area Status"},f:[{p:[16,7,659],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.atmos_alarm","data.fire_alarm"],s:'_0||_1?"bad bold":"good"'},p:[16,20,672]}]},f:[{t:2,x:{r:["data.atmos_alarm","fire_alarm"],s:'_0?"Atmosphere Alarm":_1?"Fire Alarm":"Nominal"'},p:[17,8,744]}]}]}],n:50,r:"data.environment_data",p:[2,3,35]},{t:4,n:51,f:[{p:[21,5,876],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[22,7,912],t:7,e:"span",a:{"class":"bad bold"},f:["Cannot obtain air sample for analysis."]}]}],r:"data.environment_data"}," ",{t:4,f:[{p:[26,5,1040],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[27,7,1076],t:7,e:"span",a:{"class":"bad bold"},f:["Safety measures offline. Device may exhibit abnormal behavior."]}]}],n:50,r:"data.emagged",p:[25,3,1014]}]}]},e.exports=a.extend(r.exports)},{205:205}],225:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.css=" th, td {\r\n padding-right: 16px;\r\n text-align: left;\r\n }",r.exports.template={v:3,t:[" ",{p:{button:[{p:[5,5,116],t:7,e:"back"}]},t:7,e:"ui-display",a:{title:"Alarm Thresholds",button:0},f:[" ",{p:[7,3,143],t:7,e:"table",f:[{p:[8,5,156],t:7,e:"thead",f:[{p:[8,12,163],t:7,e:"tr",f:[{p:[9,7,175],t:7,e:"th"}," ",{p:[10,7,192],t:7,e:"th",f:[{p:[10,11,196],t:7,e:"span",a:{"class":"bad"},f:["min2"]}]}," ",{p:[11,7,238],t:7,e:"th",f:[{p:[11,11,242],t:7,e:"span",a:{"class":"average"},f:["min1"]}]}," ",{p:[12,7,288],t:7,e:"th",f:[{p:[12,11,292],t:7,e:"span",a:{"class":"average"},f:["max1"]}]}," ",{p:[13,7,338],t:7,e:"th",f:[{p:[13,11,342],t:7,e:"span",a:{"class":"bad"},f:["max2"]}]}]}]}," ",{p:[15,5,401],t:7,e:"tbody",f:[{t:4,f:[{p:[16,32,441],t:7,e:"tr",f:[{p:[17,9,455],t:7,e:"th",f:[{t:3,r:"name",p:[17,13,459]}]}," ",{t:4,f:[{p:[18,27,502],t:7,e:"td",f:[{p:[19,11,518],t:7,e:"ui-button",a:{action:"threshold",params:['{"env": "',{t:2,r:"env",p:[19,58,565]},'", "var": "',{t:2,r:"val",p:[19,76,583]},'"}']},f:[{t:2,x:{r:["selected"],s:"Math.fixed(_0,2)"},p:[19,87,594]}]}]}],n:52,r:"settings",p:[18,9,484]}]}],n:52,r:"data.thresholds",p:[16,7,416]}]}," ",{p:[23,3,697],t:7,e:"table",f:[]}]}]}," "]},r.exports.components=r.exports.components||{};var i={back:t(221)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,221:221}],226:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:{button:[{p:[5,5,113],t:7,e:"back"}]},t:7,e:"ui-display",a:{title:"Vent Controls",button:0},f:[" ",{t:4,f:[{p:[8,5,166],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"long_name",p:[8,27,188]}]},f:[{p:[9,7,211],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[10,9,247],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["power"],s:'_0?"power-off":"close"'},p:[10,26,264]}],style:[{t:2,x:{r:["power"],s:'_0?"selected":null'},p:[10,68,306]}],action:"power",params:['{"id_tag": "',{t:2,r:"id_tag",p:[11,46,383]},'", "val": ',{t:2,x:{r:["power"],s:"+!_0"},p:[11,66,403]},"}"]},f:[{t:2,x:{r:["power"],s:'_0?"On":"Off"'},p:[11,80,417]}]}]}," ",{p:[13,7,482],t:7,e:"ui-section",a:{label:"Mode"},f:[{p:[14,9,517],t:7,e:"span",f:[{t:2,x:{r:["direction"],s:'_0=="release"?"Pressurizing":"Siphoning"'},p:[14,15,523]}]}]}," ",{p:[16,7,616],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[17,9,665],t:7,e:"ui-button",a:{icon:"sign-in",style:[{t:2,x:{r:["incheck"],s:'_0?"selected":null'},p:[17,42,698]}],action:"incheck",params:['{"id_tag": "',{t:2,r:"id_tag",p:[18,48,779]},'", "val": ',{t:2,r:"checks",p:[18,68,799]},"}"]},f:["Internal"]}," ",{p:[19,9,842],t:7,e:"ui-button",a:{icon:"sign-out",style:[{t:2,x:{r:["excheck"],s:'_0?"selected":null'},p:[19,43,876]}],action:"excheck",params:['{"id_tag": "',{t:2,r:"id_tag",p:[20,48,957]},'", "val": ',{t:2,r:"checks",p:[20,68,977]},"}"]},f:["External"]}]}," ",{t:4,f:[{p:[23,9,1064],t:7,e:"ui-section",a:{label:"Internal Target Pressure"},f:[{p:[24,11,1121],t:7,e:"ui-button",a:{icon:"pencil",action:"set_internal_pressure",params:['{"id_tag": "',{t:2,r:"id_tag",p:[25,33,1210]},'"}']},f:[{t:2,x:{r:["internal"],s:"Math.fixed(_0)"},p:[25,47,1224]}]}," ",{p:[26,11,1272],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["intdefault"],s:'_0?"disabled":null'},p:[26,44,1305]}],action:"reset_internal_pressure",params:['{"id_tag": "',{t:2,r:"id_tag",p:[27,33,1407]},'"}']},f:["Reset"]}]}],n:50,r:"incheck",p:[22,7,1039]}," ",{t:4,f:[{p:[31,11,1511],t:7,e:"ui-section",a:{label:"External Target Pressure"},f:[{p:[32,13,1570],t:7,e:"ui-button",a:{icon:"pencil",action:"set_external_pressure",params:['{"id_tag": "',{t:2,r:"id_tag",p:[33,35,1661]},'"}']},f:[{t:2,x:{r:["external"],s:"Math.fixed(_0)"},p:[33,49,1675]}]}," ",{p:[34,13,1725],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["extdefault"],s:'_0?"disabled":null'},p:[34,46,1758]}],action:"reset_external_pressure",params:['{"id_tag": "',{t:2,r:"id_tag",p:[35,35,1862]},'"}']},f:["Reset"]}]}],n:50,r:"excheck",p:[30,7,1484]}]}],n:52,r:"data.vents",p:[7,3,140]},{t:4,n:51,f:[{p:[40,5,1973],t:7,e:"span",a:{"class":"bad"},f:["Error: No vents connected."]}],r:"data.vents"}]}]},r.exports.components=r.exports.components||{};var i={back:t(221)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,221:221}],227:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.css=" table {\r\n width: 100%;\r\n border-spacing: 2px;\r\n }\r\n th {\r\n text-align: left;\r\n }\r\n td {\r\n vertical-align: top;\r\n }\r\n td .button {\r\n margin-top: 4px\r\n }",r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-section",f:[{p:[3,5,34],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.oneAccess"],s:'_0?"unlock":"lock"'},p:[3,22,51]}],action:"one_access"},f:[{t:2,x:{r:["data.oneAccess"],s:'_0?"One":"All"'},p:[3,82,111]}," Required"]}," ",{p:[4,5,172],t:7,e:"ui-button",a:{icon:"refresh",action:"clear"},f:["Clear"]}]}," ",{p:[6,3,251],t:7,e:"hr"}," ",{p:[7,3,260],t:7,e:"table",f:[{p:[8,3,271],t:7,e:"thead",f:[{p:[9,4,283],t:7,e:"tr",f:[{t:4,f:[{p:[10,5,315],t:7,e:"th",f:[{p:[10,9,319],t:7,e:"span",a:{"class":"highlight bold"},f:[{t:2,r:"name",p:[10,38,348]}]}]}],n:52,r:"data.regions",p:[9,8,287]}]}]}," ",{p:[13,3,403],t:7,e:"tbody",f:[{p:[14,4,415],t:7,e:"tr",f:[{t:4,f:[{p:[15,5,447],t:7,e:"td",f:[{t:4,f:[{p:[16,11,481],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["req"],s:'_0?"check-square-o":"square-o"'},p:[16,28,498]}],style:[{t:2,x:{r:["req"],s:'_0?"selected":null'},p:[16,76,546]}],action:"set",params:['{"access": "',{t:2,r:"id",p:[17,46,621]},'"}']},f:[{t:2,r:"name",p:[17,56,631]}]}," ",{p:[18,9,661],t:7,e:"br"}],n:52,r:"accesses",p:[15,9,451]}]}],n:52,r:"data.regions",p:[14,8,419]}]}]}]}]}," "]},e.exports=a.extend(r.exports)},{205:205}],228:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{powerState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}}},computed:{malfAction:function(){switch(this.get("data.malfStatus")){case 1:return"hack";case 2:return"occupy";case 3:return"deoccupy"}},malfButton:function(){switch(this.get("data.malfStatus")){case 1:return"Override Programming";case 2:case 4:return"Shunt Core Process";case 3:return"Return to Main Core"}},malfIcon:function(){switch(this.get("data.malfStatus")){case 1:return"terminal";case 2:case 4:return"caret-square-o-down";case 3:return"caret-square-o-left"}},powerCellStatusState:function(){var t=this.get("data.powerCellStatus");return t>50?"good":t>25?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[46,2,1206],t:7,e:"ui-notice",f:[{p:[47,3,1221],t:7,e:"b",f:[{p:[47,6,1224],t:7,e:"h3",f:["SYSTEM FAILURE"]}]}," ",{p:[48,3,1255],t:7,e:"i",f:["I/O regulators malfunction detected! Waiting for system reboot..."]},{p:[48,75,1327],t:7,e:"br"}," Automatic reboot in ",{t:2,r:"data.failTime",p:[49,23,1355]}," seconds... ",{p:[50,3,1387],t:7,e:"ui-button",a:{icon:"refresh",action:"reboot"},f:["Reboot Now"]},{p:[50,67,1451],t:7,e:"br"},{p:[50,71,1455],t:7,e:"br"},{p:[50,75,1459],t:7,e:"br"}]}],n:50,r:"data.failTime",p:[45,1,1182]},{t:4,n:51,f:[{p:[53,2,1491],t:7,e:"ui-notice",f:[{t:4,f:[{p:[55,3,1535],t:7,e:"ui-section",a:{label:"Interface Lock"},f:[{p:[56,5,1576],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"lock":"unlock"'},p:[56,22,1593]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Engaged":"Disengaged"'},p:[56,73,1644]}]}]}],n:50,r:"data.siliconUser",p:[54,4,1507]},{t:4,n:51,f:[{p:[59,3,1732],t:7,e:"span",f:["Swipe an ID card to ",{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[59,29,1758]}," this interface."]}],r:"data.siliconUser"}]}," ",{p:[62,2,1846],t:7,e:"ui-display",a:{title:"Power Status"},f:[{p:[63,4,1884],t:7,e:"ui-section",a:{label:"Main Breaker"},f:[{t:4,f:[{p:[65,5,1967],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.isOperating"],s:'_0?"good":"bad"'},p:[65,18,1980]}]},f:[{t:2,x:{r:["data.isOperating"],s:'_0?"On":"Off"'},p:[65,57,2019]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"},p:[64,3,1921]},{t:4,n:51,f:[{p:[67,5,2079],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isOperating"],s:'_0?"power-off":"close"'},p:[67,22,2096]}],style:[{t:2,x:{r:["data.isOperating"],s:'_0?"selected":null'},p:[67,75,2149]}],action:"breaker"},f:[{t:2,x:{r:["data.isOperating"],s:'_0?"On":"Off"'},p:[68,21,2212]}]}],x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"}}]}," ",{p:[71,4,2293],t:7,e:"ui-section",a:{label:"External Power"},f:[{p:[72,3,2332],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.externalPower"],s:"_0(_1)"},p:[72,16,2345]}]},f:[{t:2,x:{r:["data.externalPower"],s:'_0==2?"Good":_0==1?"Low":"None"'},p:[72,52,2381]}]}]}," ",{p:[74,4,2490],t:7,e:"ui-section",a:{label:"Power Cell"},f:[{t:4,f:[{p:[76,5,2567],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.powerCellStatus",p:[76,38,2600]}],state:[{t:2,r:"powerCellStatusState",p:[76,71,2633]}]},f:[{t:2,x:{r:["adata.powerCellStatus"],s:"Math.fixed(_0)"},p:[76,97,2659]},"%"]}],n:50,x:{r:["data.powerCellStatus"],s:"_0!=null"},p:[75,3,2525]},{t:4,n:51,f:[{p:[78,5,2724],t:7,e:"span",a:{"class":"bad"},f:["Removed"]}],x:{r:["data.powerCellStatus"],s:"_0!=null"}}]}," ",{t:4,f:[{p:[82,3,2830],t:7,e:"ui-section",a:{label:"Charge Mode"},f:[{t:4,f:[{p:[84,4,2913],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.chargeMode"],s:'_0?"good":"bad"'},p:[84,17,2926]}]},f:[{t:2,x:{r:["data.chargeMode"],s:'_0?"Auto":"Off"'},p:[84,55,2964]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"},p:[83,5,2868]},{t:4,n:51,f:[{p:[86,4,3026],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.chargeMode"],s:'_0?"refresh":"close"'},p:[86,21,3043]}],style:[{t:2,x:{r:["data.chargeMode"],s:'_0?"selected":null'},p:[86,71,3093]}],action:"charge"},f:[{t:2,x:{r:["data.chargeMode"],s:'_0?"Auto":"Off"'},p:[87,22,3156]}]}],x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"}}," [",{p:[90,6,3236],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.chargingStatus"],s:"_0(_1)"},p:[90,19,3249]}]},f:[{t:2,x:{r:["data.chargingStatus"],s:'_0==2?"Fully Charged":_0==1?"Charging":"Not Charging"'},p:[90,56,3286]}]},"]"]}],n:50,x:{r:["data.powerCellStatus"],s:"_0!=null"},p:[81,4,2790]}]}," ",{p:[94,2,3445],t:7,e:"ui-display",a:{title:"Power Channels"},f:[{t:4,f:[{p:[96,3,3517],t:7,e:"ui-section",a:{label:[{t:2,r:"title",p:[96,22,3536]}],nowrap:0},f:[{p:[97,5,3560],t:7,e:"div",a:{"class":"content"},f:[{t:2,rx:{r:"adata.powerChannels",m:[{t:30,n:"@index"},"powerLoad"]},p:[97,26,3581]}]}," ",{p:[98,5,3634],t:7,e:"div",a:{"class":"content"},f:[{p:[98,26,3655],t:7,e:"span",a:{"class":[{t:2,x:{r:["status"],s:'_0>=2?"good":"bad"'},p:[98,39,3668]}]},f:[{t:2,x:{r:["status"],s:'_0>=2?"On":"Off"'},p:[98,73,3702]}]}]}," ",{p:[99,5,3751],t:7,e:"div",a:{"class":"content"},f:["[",{p:[99,27,3773],t:7,e:"span",f:[{t:2,x:{r:["status"],s:'_0==1||_0==3?"Auto":"Manual"'},p:[99,33,3779]}]},"]"]}," ",{p:[100,5,3849],t:7,e:"div",a:{"class":"content",style:"float:right"},f:[{t:4,f:[{p:[102,6,3942],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["status"],s:'_0==1||_0==3?"selected":null'},p:[102,39,3975]}],action:"channel",params:[{t:2,r:"topicParams.auto",p:[103,30,4057]}]},f:["Auto"]}," ",{p:[104,6,4102],t:7,e:"ui-button",a:{icon:"power-off",state:[{t:2,x:{r:["status"],s:'_0==2?"selected":null'},p:[104,41,4137]}],action:"channel",params:[{t:2,r:"topicParams.on",p:[105,13,4204]}]},f:["On"]}," ",{p:[106,6,4245],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["status"],s:'_0==0?"selected":null'},p:[106,37,4276]}],action:"channel",params:[{t:2,r:"topicParams.off",p:[107,13,4343]}]},f:["Off"]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"},p:[101,4,3895]}]}]}],n:52,r:"data.powerChannels",p:[95,4,3485]}," ",{p:[112,4,4439],t:7,e:"ui-section",a:{label:"Total Load"},f:[{p:[113,3,4474],t:7,e:"span",a:{"class":"bold"},f:[{t:2,r:"adata.totalLoad",p:[113,22,4493]}]}]}]}," ",{t:4,f:[{p:[117,4,4585],t:7,e:"ui-display",a:{title:"System Overrides"},f:[{p:[118,3,4626],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"overload"},f:["Overload"]}," ",{t:4,f:[{p:[120,5,4727],t:7,e:"ui-button",a:{icon:[{t:2,r:"malfIcon",p:[120,22,4744]}],state:[{t:2,x:{r:["data.malfStatus"],s:'_0==4?"disabled":null'},p:[120,43,4765]}],action:[{t:2,r:"malfAction",p:[120,97,4819]}]},f:[{t:2,r:"malfButton",p:[120,113,4835]}]}],n:50,r:"data.malfStatus",p:[119,3,4698]}]}],n:50,r:"data.siliconUser",p:[116,2,4556]}," ",{p:[124,2,4903],t:7,e:"ui-notice",f:[{p:[125,4,4919],t:7,e:"ui-section",a:{label:"Emergency Light Fallback"},f:[{t:4,f:[{p:[127,8,5020],t:7,e:"span",f:[{t:2,x:{r:["data.emergencyLights"],s:'_0?"Enabled":"Disabled"'},p:[127,14,5026]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"},p:[126,6,4971]},{t:4,n:51,f:[{p:[129,8,5106],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"emergency_lighting"},f:[{t:2,x:{r:["data.emergencyLights"],s:'_0?"Enabled":"Disabled"'},p:[129,66,5164]}]}],x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"}}]}]}," ",{p:[133,2,5275],t:7,e:"ui-notice",f:[{p:[134,4,5291],t:7,e:"ui-section",a:{label:"Cover Lock"},f:[{t:4,f:[{p:[136,5,5372],t:7,e:"span",f:[{t:2,x:{r:["data.coverLocked"],s:'_0?"Engaged":"Disengaged"'},p:[136,11,5378]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"},p:[135,3,5326]},{t:4,n:51,f:[{p:[138,5,5450],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.coverLocked"],s:'_0?"lock":"unlock"'},p:[138,22,5467]}],action:"cover"},f:[{t:2,x:{r:["data.coverLocked"],s:'_0?"Engaged":"Disengaged"'},p:[138,79,5524]}]}],x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"}}]}]}],r:"data.failTime"}]},e.exports=a.extend(r.exports)},{205:205}],229:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Alarms"},f:[{p:[2,3,31],t:7,e:"ul",f:[{t:4,f:[{p:[4,7,72],t:7,e:"li",f:[{p:[4,11,76],t:7,e:"ui-button",a:{icon:"close",style:"danger",action:"clear",params:['{"zone": "',{t:2,r:".",p:[4,83,148]},'"}']},f:[{t:2,r:".",p:[4,92,157]}]}]}],n:52,r:"data.priority",p:[3,5,41]},{t:4,n:51,f:[{p:[6,7,201],t:7,e:"li",f:[{p:[6,11,205],t:7,e:"span",a:{"class":"good"},f:["No Priority Alerts"]}]}],r:"data.priority"}," ",{t:4,f:[{p:[9,7,303],t:7,e:"li",f:[{p:[9,11,307],t:7,e:"ui-button",a:{icon:"close",style:"caution",action:"clear",params:['{"zone": "',{t:2,r:".",p:[9,84,380]},'"}']},f:[{t:2,r:".",p:[9,93,389]}]}]}],n:52,r:"data.minor",p:[8,5,275]},{t:4,n:51,f:[{p:[11,7,433],t:7,e:"li",f:[{p:[11,11,437],t:7,e:"span",a:{"class":"good"},f:["No Minor Alerts"]}]}],r:"data.minor"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],230:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:[{t:2,x:{r:["data.tank","data.sensors.0.long_name"],s:"_0?_1:null"},p:[1,20,19]}]},f:[{t:4,f:[{p:[3,5,102],t:7,e:"ui-subdisplay",a:{title:[{t:2,x:{r:["data.tank","long_name"],s:"!_0?_1:null"},p:[3,27,124]}]},f:[{p:[4,7,167],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[5,3,200],t:7,e:"span",f:[{t:2,x:{r:["pressure"],s:"Math.fixed(_0,2)"},p:[5,9,206]}," kPa"]}]}," ",{t:4,f:[{p:[8,9,302],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[9,11,346],t:7,e:"span",f:[{t:2,x:{r:["temperature"],s:"Math.fixed(_0,2)"},p:[9,17,352]}," K"]}]}],n:50,r:"temperature",p:[7,7,273]}," ",{t:4,f:[{p:[13,9,462],t:7,e:"ui-section",a:{label:[{t:2,r:"id",p:[13,28,481]}]},f:[{p:[14,5,495],t:7,e:"span",f:[{t:2,x:{r:["."],s:"Math.fixed(_0,2)"},p:[14,11,501]},"%"]}]}],n:52,i:"id",r:"gases",p:[12,4,434]}]}],n:52,r:"adata.sensors",p:[2,3,73]}]}," ",{t:4,f:[{p:{button:[{p:[23,5,704],t:7,e:"ui-button",a:{icon:"refresh",action:"reconnect"},f:["Reconnect"]}]},t:7,e:"ui-display",a:{title:"Controls",button:0 +},f:[" ",{p:[25,5,792],t:7,e:"ui-section",a:{label:"Input Injector"},f:[{p:[26,7,835],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.inputting"],s:'_0?"power-off":"close"'},p:[26,24,852]}],style:[{t:2,x:{r:["data.inputting"],s:'_0?"selected":null'},p:[26,75,903]}],action:"input"},f:[{t:2,x:{r:["data.inputting"],s:'_0?"Injecting":"Off"'},p:[27,9,968]}]}]}," ",{p:[29,5,1044],t:7,e:"ui-section",a:{label:"Input Rate"},f:[{p:[30,7,1083],t:7,e:"span",f:[{t:2,x:{r:["adata.inputRate"],s:"Math.fixed(_0)"},p:[30,13,1089]}," L/s"]}]}," ",{p:[32,5,1156],t:7,e:"ui-section",a:{label:"Output Regulator"},f:[{p:[33,7,1201],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.outputting"],s:'_0?"power-off":"close"'},p:[33,24,1218]}],style:[{t:2,x:{r:["data.outputting"],s:'_0?"selected":null'},p:[33,76,1270]}],action:"output"},f:[{t:2,x:{r:["data.outputting"],s:'_0?"Open":"Closed"'},p:[34,9,1337]}]}]}," ",{p:[36,5,1412],t:7,e:"ui-section",a:{label:"Output Pressure"},f:[{p:[37,7,1456],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure"},f:[{t:2,x:{r:["adata.outputPressure"],s:"Math.round(_0)"},p:[37,50,1499]}," kPa"]}]}]}],n:50,r:"data.tank",p:[20,1,618]}]},e.exports=a.extend(r.exports)},{205:205}],231:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,5,48],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[3,22,65]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[3,66,109]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[4,22,164]}]}]}," ",{p:[6,3,223],t:7,e:"ui-section",a:{label:"Output Pressure"},f:[{p:[7,5,265],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[8,5,360],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.pressure","data.max_pressure"],s:'_0==_1?"disabled":null'},p:[8,35,390]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}," ",{p:[9,5,518],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[9,11,524]}," kPa"]}]}," ",{p:[11,3,586],t:7,e:"ui-section",a:{label:"Filter"},f:[{t:4,f:[{p:[13,7,654],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[13,25,672]}],action:"filter",params:['{"mode": ',{t:2,r:"id",p:[14,42,748]},"}"]},f:[{t:2,r:"name",p:[14,51,757]}]}],n:52,r:"data.filter_types",p:[12,5,619]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],232:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,5,48],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[3,22,65]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[3,66,109]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[4,22,164]}]}]}," ",{p:[6,3,223],t:7,e:"ui-section",a:{label:"Output Pressure"},f:[{p:[7,5,265],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[8,5,360],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.set_pressure","data.max_pressure"],s:'_0==_1?"disabled":null'},p:[8,35,390]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}," ",{p:[9,5,522],t:7,e:"span",f:[{t:2,x:{r:["adata.set_pressure"],s:"Math.round(_0)"},p:[9,11,528]}," kPa"]}]}," ",{p:[11,3,594],t:7,e:"ui-section",a:{label:"Node 1"},f:[{p:[12,5,627],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.node1_concentration"],s:'_0==0?"disabled":null'},p:[12,44,666]}],action:"node1",params:'{"concentration": -0.1}'}}," ",{p:[14,5,783],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.node1_concentration"],s:'_0==0?"disabled":null'},p:[14,39,817]}],action:"node1",params:'{"concentration": -0.01}'}}," ",{p:[16,5,935],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.node1_concentration"],s:'_0==100?"disabled":null'},p:[16,38,968]}],action:"node1",params:'{"concentration": 0.01}'}}," ",{p:[18,5,1087],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.node1_concentration"],s:'_0==100?"disabled":null'},p:[18,43,1125]}],action:"node1",params:'{"concentration": 0.1}'}}," ",{p:[20,5,1243],t:7,e:"span",f:[{t:2,x:{r:["adata.node1_concentration"],s:"Math.round(_0)"},p:[20,11,1249]},"%"]}]}," ",{p:[22,3,1319],t:7,e:"ui-section",a:{label:"Node 2"},f:[{p:[23,5,1352],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.node2_concentration"],s:'_0==0?"disabled":null'},p:[23,44,1391]}],action:"node2",params:'{"concentration": -0.1}'}}," ",{p:[25,5,1508],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.node2_concentration"],s:'_0==0?"disabled":null'},p:[25,39,1542]}],action:"node2",params:'{"concentration": -0.01}'}}," ",{p:[27,5,1660],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.node2_concentration"],s:'_0==100?"disabled":null'},p:[27,38,1693]}],action:"node2",params:'{"concentration": 0.01}'}}," ",{p:[29,5,1812],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.node2_concentration"],s:'_0==100?"disabled":null'},p:[29,43,1850]}],action:"node2",params:'{"concentration": 0.1}'}}," ",{p:[31,5,1968],t:7,e:"span",f:[{t:2,x:{r:["adata.node2_concentration"],s:"Math.round(_0)"},p:[31,11,1974]},"%"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],233:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,5,48],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[3,22,65]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[3,66,109]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[4,22,164]}]}]}," ",{t:4,f:[{p:[7,5,250],t:7,e:"ui-section",a:{label:"Transfer Rate"},f:[{p:[8,7,292],t:7,e:"ui-button",a:{icon:"pencil",action:"rate",params:'{"rate": "input"}'},f:["Set"]}," ",{p:[9,7,381],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.rate","data.max_rate"],s:'_0==_1?"disabled":null'},p:[9,37,411]}],action:"rate",params:'{"rate": "max"}'},f:["Max"]}," ",{p:[10,7,525],t:7,e:"span",f:[{t:2,x:{r:["adata.rate"],s:"Math.round(_0)"},p:[10,13,531]}," L/s"]}]}],n:50,r:"data.max_rate",p:[6,3,223]},{t:4,n:51,f:[{p:[13,5,605],t:7,e:"ui-section",a:{label:"Output Pressure"},f:[{p:[14,7,649],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[15,7,746],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.pressure","data.max_pressure"],s:'_0==_1?"disabled":null'},p:[15,37,776]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}," ",{p:[16,7,906],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[16,13,912]}," kPa"]}]}],r:"data.max_rate"}]}]},e.exports=a.extend(r.exports)},{205:205}],234:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{p:[3,5,67],t:7,e:"ui-button",a:{icon:"clock-o",style:[{t:2,x:{r:["data.timing"],s:'_0?"selected":null'},p:[3,38,100]}],action:[{t:2,x:{r:["data.timing"],s:'_0?"stop":"start"'},p:[3,83,145]}]},f:[{t:2,x:{r:["data.timing"],s:'_0?"Stop":"Start"'},p:[3,119,181]}]}," ",{p:[4,5,233],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"flash",style:[{t:2,x:{r:["data.flash_charging"],s:'_0?"disabled":null'},p:[4,57,285]}]},f:[{t:2,x:{r:["data.flash_charging"],s:'_0?"Recharging":"Flash"'},p:[4,102,330]}]}]},t:7,e:"ui-display",a:{title:"Cell Timer",button:0},f:[" ",{p:[6,3,410],t:7,e:"ui-section",f:[{p:[7,5,428],t:7,e:"ui-button",a:{icon:"fast-backward",action:"time",params:'{"adjust": -600}'}}," ",{p:[8,5,518],t:7,e:"ui-button",a:{icon:"backward",action:"time",params:'{"adjust": -100}'}}," ",{p:[9,5,603],t:7,e:"span",f:[{t:2,x:{r:["text","data.minutes"],s:"_0.zeroPad(_1,2)"},p:[9,11,609]},":",{t:2,x:{r:["text","data.seconds"],s:"_0.zeroPad(_1,2)"},p:[9,45,643]}]}," ",{p:[10,5,689],t:7,e:"ui-button",a:{icon:"forward",action:"time",params:'{"adjust": 100}'}}," ",{p:[11,5,772],t:7,e:"ui-button",a:{icon:"fast-forward",action:"time",params:'{"adjust": 600}'}}]}," ",{p:[13,3,875],t:7,e:"ui-section",f:[{p:[14,7,895],t:7,e:"ui-button",a:{icon:"hourglass-start",action:"preset",params:'{"preset": "short"}'},f:["Short"]}," ",{p:[15,7,999],t:7,e:"ui-button",a:{icon:"hourglass-start",action:"preset",params:'{"preset": "medium"}'},f:["Medium"]}," ",{p:[16,7,1105],t:7,e:"ui-button",a:{icon:"hourglass-start",action:"preset",params:'{"preset": "long"}'},f:["Long"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],235:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,23],t:7,e:"ui-notice",f:[{t:2,r:"data.notice",p:[3,5,40]}]}],n:50,r:"data.notice",p:[1,1,0]},{p:[6,1,82],t:7,e:"ui-display",a:{title:"Bluespace Artillery Control",button:0},f:[{t:4,f:[{p:[8,3,167],t:7,e:"ui-section",a:{label:"Target"},f:[{p:[9,5,200],t:7,e:"ui-button",a:{icon:"crosshairs",action:"recalibrate"},f:[{t:2,r:"data.target",p:[9,55,250]}]}]}," ",{p:[11,3,298],t:7,e:"ui-section",a:{label:"Controls"},f:[{t:4,f:[{p:[13,3,356],t:7,e:"ui-notice",f:[{p:[14,4,372],t:7,e:"span",f:["Bluespace Artillery firing protocols must be globally unlocked from two keycard authentication devices first!"]}]}],n:50,x:{r:["data.unlocked"],s:"!_0"},p:[12,2,330]},{t:4,n:51,f:[{p:[17,3,525],t:7,e:"ui-button",a:{icon:"warning",state:[{t:2,x:{r:["data.ready"],s:'_0?null:"disabled"'},p:[17,36,558]}],action:"fire"},f:["FIRE!"]}],x:{r:["data.unlocked"],s:"!_0"}}]}],n:50,r:"data.connected",p:[7,3,141]}," ",{t:4,f:[{p:[22,3,694],t:7,e:"ui-section",a:{label:"Maintenance"},f:[{p:[23,7,734],t:7,e:"ui-button",a:{icon:"wrench",action:"build"},f:["Complete Deployment."]}]}],n:50,x:{r:["data.connected"],s:"!_0"},p:[21,3,667]}]}]},e.exports=a.extend(r.exports)},{205:205}],236:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,3,15],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.hasHoldingTank"],s:'_0?"is":"is not"'},p:[2,23,35]}," connected to a tank."]}]}," ",{p:{button:[{p:[6,5,185],t:7,e:"ui-button",a:{icon:"pencil",action:"relabel"},f:["Relabel"]}]},t:7,e:"ui-display",a:{title:"Canister",button:0},f:[" ",{p:[8,3,266],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[9,5,301],t:7,e:"span",f:[{t:2,x:{r:["adata.tankPressure"],s:"Math.round(_0)"},p:[9,11,307]}," kPa"]}]}," ",{p:[11,3,373],t:7,e:"ui-section",a:{label:"Port"},f:[{p:[12,5,404],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.portConnected"],s:'_0?"good":"average"'},p:[12,18,417]}]},f:[{t:2,x:{r:["data.portConnected"],s:'_0?"Connected":"Not Connected"'},p:[12,63,462]}]}]}," ",{t:4,f:[{p:[15,3,573],t:7,e:"ui-section",a:{label:"Access"},f:[{p:[16,7,608],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.restricted"],s:'_0?"lock":"unlock"'},p:[16,24,625]}],style:[{t:2,x:{r:[],s:'"caution"'},p:[17,14,680]}],action:"restricted"},f:[{t:2,x:{r:["data.restricted"],s:'_0?"Restricted to Engineering":"Public"'},p:[18,27,722]}]}]}],n:50,r:"data.isPrototype",p:[14,3,544]}]}," ",{p:[22,1,839],t:7,e:"ui-display",a:{title:"Valve"},f:[{p:[23,3,869],t:7,e:"ui-section",a:{label:"Release Pressure"},f:[{p:[24,5,912],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.minReleasePressure",p:[24,18,925]}],max:[{t:2,r:"data.maxReleasePressure",p:[24,52,959]}],value:[{t:2,r:"data.releasePressure",p:[25,14,1002]}]},f:[{t:2,x:{r:["adata.releasePressure"],s:"Math.round(_0)"},p:[25,40,1028]}," kPa"]}]}," ",{p:[27,3,1099],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[28,5,1144],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.releasePressure","data.defaultReleasePressure"],s:'_0!=_1?null:"disabled"'},p:[28,38,1177]}],action:"pressure",params:'{"pressure": "reset"}'},f:["Reset"]}," ",{p:[30,5,1333],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.releasePressure","data.minReleasePressure"],s:'_0>_1?null:"disabled"'},p:[30,36,1364]}],action:"pressure",params:'{"pressure": "min"}'},f:["Min"]}," ",{p:[32,5,1511],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[33,5,1606],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.releasePressure","data.maxReleasePressure"],s:'_0<_1?null:"disabled"'},p:[33,35,1636]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}]}," ",{p:[36,3,1798],t:7,e:"ui-section",a:{label:"Valve"},f:[{p:[37,5,1830],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.valveOpen"],s:'_0?"unlock":"lock"'},p:[37,22,1847]}],style:[{t:2,x:{r:["data.valveOpen","data.hasHoldingTank"],s:'_0?_1?"caution":"danger":null'},p:[38,14,1901]}],action:"valve"},f:[{t:2,x:{r:["data.valveOpen"],s:'_0?"Open":"Closed"'},p:[39,22,1995]}]}]}]}," ",{t:4,f:[{p:[42,1,2090],t:7,e:"ui-display",a:{title:"Valve Toggle Timer"},f:[{t:4,f:[{p:[44,5,2155],t:7,e:"ui-section",a:{label:"Adjust Timer"},f:[{p:[45,7,2196],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.timer_is_not_default"],s:'_0?null:"disabled"'},p:[45,40,2229]}],action:"timer",params:'{"change": "reset"}'},f:["Reset"]}," ",{p:[47,7,2358],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.timer_is_not_min"],s:'_0?null:"disabled"'},p:[47,38,2389]}],action:"timer",params:'{"change": "decrease"}'},f:["Decrease"]}," ",{p:[49,7,2520],t:7,e:"ui-button",a:{icon:"pencil",state:[{t:2,x:{r:[],s:'"disabled"'},p:[49,39,2552]}],action:"timer",params:'{"change": "input"}'},f:["Set"]}," ",{p:[51,7,2637],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.timer_is_not_max"],s:'_0?null:"disabled"'},p:[51,37,2667]}],action:"timer",params:'{"change": "increase"}'},f:["Increase"]}]}],n:51,r:"data.timing",p:[43,3,2133]}," ",{p:[55,3,2833],t:7,e:"ui-section",a:{label:"Timer"},f:[{p:[56,6,2866],t:7,e:"ui-button",a:{icon:"clock-o",style:[{t:2,x:{r:["data.timing"],s:'_0?"danger":"caution"'},p:[56,39,2899]}],action:"toggle_timer"},f:[{t:2,x:{r:["data.timing"],s:'_0?"On":"Off"'},p:[57,30,2969]}]}," ",{p:[59,2,3017],t:7,e:"ui-section",a:{label:"Time until Valve Toggle"},f:[{p:[60,2,3064],t:7,e:"span",f:[{t:2,x:{r:["data.timing","data.time_left","data.timer_set"],s:"_0?_1:_2"},p:[60,8,3070]}]}]}]}]}],n:50,r:"data.isPrototype",p:[41,1,2062]},{p:{button:[{t:4,f:[{p:[69,7,3277],t:7,e:"ui-button",a:{icon:"eject",style:[{t:2,x:{r:["data.valveOpen"],s:'_0?"danger":null'},p:[69,38,3308]}],action:"eject"},f:["Eject"]}],n:50,r:"data.hasHoldingTank",p:[68,5,3242]}]},t:7,e:"ui-display",a:{title:"Holding Tank",button:0},f:[" ",{t:4,f:[{p:[73,3,3442],t:7,e:"ui-section",a:{label:"Label"},f:[{t:2,r:"data.holdingTank.name",p:[74,4,3473]}]}," ",{p:[76,3,3519],t:7,e:"ui-section",a:{label:"Pressure"},f:[{t:2,x:{r:["adata.holdingTank.tankPressure"],s:"Math.round(_0)"},p:[77,4,3553]}," kPa"]}],n:50,r:"data.hasHoldingTank",p:[72,3,3411]},{t:4,n:51,f:[{p:[80,3,3635],t:7,e:"ui-section",f:[{p:[81,4,3652],t:7,e:"span",a:{"class":"average"},f:["No Holding Tank"]}]}],r:"data.hasHoldingTank"}]}]},e.exports=a.extend(r.exports)},{205:205}],237:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{tabs:function(){return Object.keys(this.get("data.supplies"))}}}}(r),r.exports.template={v:3,t:[" ",{p:[11,1,158],t:7,e:"ui-display",a:{title:"Cargo"},f:[{p:[12,3,188],t:7,e:"ui-section",a:{label:"Shuttle"},f:[{t:4,f:[{p:[14,7,270],t:7,e:"ui-button",a:{action:"send"},f:[{t:2,r:"data.location",p:[14,32,295]}]}],n:50,x:{r:["data.docked","data.requestonly"],s:"_0&&!_1"},p:[13,5,222]},{t:4,n:51,f:[{p:[16,7,346],t:7,e:"span",f:[{t:2,r:"data.location",p:[16,13,352]}]}],x:{r:["data.docked","data.requestonly"],s:"_0&&!_1"}}]}," ",{p:[19,3,410],t:7,e:"ui-section",a:{label:"Credits"},f:[{p:[20,5,444],t:7,e:"span",f:[{t:2,x:{r:["adata.points"],s:"Math.floor(_0)"},p:[20,11,450]}]}]}," ",{p:[22,3,506],t:7,e:"ui-section",a:{label:"CentCom Message"},f:[{p:[23,7,550],t:7,e:"span",f:[{t:2,r:"data.message",p:[23,13,556]}]}]}," ",{t:4,f:[{p:[26,5,644],t:7,e:"ui-section",a:{label:"Loan"},f:[{t:4,f:[{p:[28,9,716],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.away","data.docked"],s:'_0&&_1?null:"disabled"'},p:[29,17,744]}],action:"loan"},f:["Loan Shuttle"]}],n:50,x:{r:["data.loan_dispatched"],s:"!_0"},p:[27,7,677]},{t:4,n:51,f:[{p:[32,9,868],t:7,e:"span",a:{"class":"bad"},f:["Loaned to CentCom"]}],x:{r:["data.loan_dispatched"],s:"!_0"}}]}],n:50,x:{r:["data.loan","data.requestonly"],s:"_0&&!_1"},p:[25,3,600]}]}," ",{t:4,f:[{p:{button:[{p:[40,7,1066],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["data.cart.length"],s:'_0?null:"disabled"'},p:[40,38,1097]}],action:"clear"},f:["Clear"]}]},t:7,e:"ui-display",a:{title:"Cart",button:0},f:[" ",{t:4,f:[{p:[43,7,1222],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{p:[44,9,1263],t:7,e:"div",a:{"class":"content"},f:["#",{t:2,r:"id",p:[44,31,1285]}]}," ",{p:[45,9,1307],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"object",p:[45,30,1328]}]}," ",{p:[46,9,1354],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"cost",p:[46,30,1375]}," Credits"]}," ",{p:[47,9,1407],t:7,e:"div",a:{"class":"content"},f:[{p:[48,11,1440],t:7,e:"ui-button",a:{icon:"minus",action:"remove",params:['{"id": "',{t:2,r:"id",p:[48,67,1496]},'"}']}}]}]}],n:52,r:"data.cart",p:[42,5,1195]},{t:4,n:51,f:[{p:[52,7,1566],t:7,e:"span",f:["Nothing in Cart"]}],r:"data.cart"}]}],n:50,x:{r:["data.requestonly"],s:"!_0"},p:[37,1,972]},{p:{button:[{t:4,f:[{p:[59,7,1735],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["data.requests.length"],s:'_0?null:"disabled"'},p:[59,38,1766]}],action:"denyall"},f:["Clear"]}],n:50,x:{r:["data.requestonly"],s:"!_0"},p:[58,5,1702]}]},t:7,e:"ui-display",a:{title:"Requests",button:0},f:[" ",{t:4,f:[{p:[63,5,1908],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{p:[64,7,1947],t:7,e:"div",a:{"class":"content"},f:["#",{t:2,r:"id",p:[64,29,1969]}]}," ",{p:[65,7,1989],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"object",p:[65,28,2010]}]}," ",{p:[66,7,2034],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"cost",p:[66,28,2055]}," Credits"]}," ",{p:[67,7,2085],t:7,e:"div",a:{"class":"content"},f:["By ",{t:2,r:"orderer",p:[67,31,2109]}]}," ",{p:[68,7,2134],t:7,e:"div",a:{"class":"content"},f:["Comment: ",{t:2,r:"reason",p:[68,37,2164]}]}," ",{t:4,f:[{p:[70,9,2223],t:7,e:"div",a:{"class":"content"},f:[{p:[71,11,2256],t:7,e:"ui-button",a:{icon:"check",action:"approve",params:['{"id": "',{t:2,r:"id",p:[71,68,2313]},'"}']}}," ",{p:[72,11,2336],t:7,e:"ui-button",a:{icon:"close",action:"deny",params:['{"id": "',{t:2,r:"id",p:[72,65,2390]},'"}']}}]}],n:50,x:{r:["data.requestonly"],s:"!_0"},p:[69,7,2188]}]}],n:52,r:"data.requests",p:[62,3,1879]},{t:4,n:51,f:[{p:[77,7,2473],t:7,e:"span",f:["No Requests"]}],r:"data.requests"}]}," ",{p:[80,1,2529],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"tabs",p:[80,16,2544]}]},f:[{t:4,f:[{p:[82,5,2587],t:7,e:"tab",a:{name:[{t:2,r:"name",p:[82,16,2598]}]},f:[{t:4,f:[{p:[84,9,2641],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[84,28,2660]}],candystripe:0,right:0},f:[{p:[85,11,2700],t:7,e:"ui-button",a:{action:"add",params:['{"id": "',{t:2,r:"id",p:[85,51,2740]},'"}']},f:[{t:2,r:"cost",p:[85,61,2750]}," Credits"]}]}],n:52,r:"packs",p:[83,7,2616]}]}],n:52,r:"data.supplies",p:[81,3,2558]}]}]},e.exports=a.extend(r.exports)},{205:205}],238:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Cellular Emporium",button:0},f:[{p:[2,3,49],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.can_readapt"],s:'_0?null:"disabled"'},p:[2,36,82]}],action:"readapt"},f:["Readapt"]}," ",{p:[4,3,169],t:7,e:"ui-section",a:{label:"Genetic Points Remaining",right:0},f:[{t:2,r:"data.genetic_points_remaining",p:[5,5,226]}]}]}," ",{p:[8,1,293],t:7,e:"ui-display",f:[{t:4,f:[{p:[10,3,335],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[10,22,354]}],candystripe:0,right:0},f:[{p:[11,5,388],t:7,e:"span",f:[{t:2,r:"desc",p:[11,11,394]}]}," ",{p:[12,5,415],t:7,e:"span",f:[{t:2,r:"helptext",p:[12,11,421]}]}," ",{p:[13,5,446],t:7,e:"span",f:["Cost: ",{t:2,r:"dna_cost",p:[13,17,458]}]}," ",{p:[14,5,483],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["owned","can_purchase"],s:'_0?"selected":_1?null:"disabled"'},p:[15,14,508]}],action:"evolve",params:['{"name": "',{t:2,r:"name",p:[17,25,615]},'"}']},f:[{t:2,x:{r:["owned"],s:'_0?"Evolved":"Evolve"'},p:[18,7,635]}]}]}],n:52,r:"data.abilities",p:[9,1,307]},{t:4,f:[{p:[23,3,738],t:7,e:"span",a:{"class":"warning"},f:["No abilities availible."]}],n:51,r:"data.abilities",p:[22,1,715]}]}]},e.exports=a.extend(r.exports)},{205:205}],239:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[2,3,31],t:7,e:"ui-section",a:{label:"Energy"},f:[{p:[3,5,64],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.maxEnergy",p:[3,26,85]}],value:[{t:2,r:"data.energy",p:[3,53,112]}]},f:[{t:2,x:{r:["adata.energy"],s:"Math.fixed(_0)"},p:[3,70,129]}," Units"]}]}]}," ",{p:{button:[{t:4,f:[{p:[9,7,315],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.amount","."],s:'_0==_1?"selected":null'},p:[9,37,345]}],action:"amount",params:['{"target": ',{t:2,r:".",p:[9,114,422]},"}"]},f:[{t:2,r:".",p:[9,122,430]}]}],n:52,r:"data.beakerTransferAmounts",p:[8,5,271]}]},t:7,e:"ui-display",a:{title:"Dispense",button:0},f:[" ",{p:[12,3,482],t:7,e:"ui-section",f:[{t:4,f:[{p:[14,7,532],t:7,e:"ui-button",a:{grid:0,icon:"tint",action:"dispense",params:['{"reagent": "',{t:2,r:"id",p:[14,74,599]},'"}']},f:[{t:2,r:"title",p:[14,84,609]}]}],n:52,r:"data.chemicals",p:[13,5,500]}]}]}," ",{p:{button:[{t:4,f:[{p:[21,7,786],t:7,e:"ui-button",a:{icon:"minus",action:"remove",params:['{"amount": ',{t:2,r:".",p:[21,66,845]},"}"]},f:[{t:2,r:".",p:[21,74,853]}]}],n:52,r:"data.beakerTransferAmounts",p:[20,5,742]}," ",{p:[23,5,891],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[23,36,922]}],action:"eject"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{p:[25,3,1019],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{p:[27,7,1089],t:7,e:"span",f:[{t:2,x:{r:["adata.beakerCurrentVolume"],s:"Math.round(_0)"},p:[27,13,1095]},"/",{t:2,r:"data.beakerMaxVolume",p:[27,55,1137]}," Units"]}," ",{p:[28,7,1182],t:7,e:"br"}," ",{t:4,f:[{p:[30,9,1235],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[30,52,1278]}," units of ",{t:2,r:"name",p:[30,87,1313]}]},{p:[30,102,1328],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[29,7,1195]},{t:4,n:51,f:[{p:[32,9,1359],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[26,5,1054]},{t:4,n:51,f:[{p:[35,7,1435],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],240:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Thermostat"},f:[{p:[2,3,35],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,5,67],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isActive"],s:'_0?"power-off":"close"'},p:[3,22,84]}],style:[{t:2,x:{r:["data.isActive"],s:'_0?"selected":null'},p:[4,10,137]}],state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[5,10,186]}],action:"power"},f:[{t:2,x:{r:["data.isActive"],s:'_0?"On":"Off"'},p:[6,18,249]}]}]}," ",{p:[8,3,314],t:7,e:"ui-section",a:{label:"Target"},f:[{p:[9,4,346],t:7,e:"ui-button",a:{icon:"pencil",action:"temperature",params:'{"target": "input"}'},f:[{t:2,x:{r:["adata.targetTemp"],s:"Math.round(_0)"},p:[9,79,421]}," K"]}]}]}," ",{p:{button:[{p:[14,5,564],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[14,36,595]}],action:"eject"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{p:[16,3,692],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{p:[18,7,762],t:7,e:"span",f:["Temperature: ",{t:2,x:{r:["adata.currentTemp"],s:"Math.round(_0)"},p:[18,26,781]}," K"]}," ",{p:[19,7,831],t:7,e:"br"}," ",{t:4,f:[{p:[21,9,885],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[21,52,928]}," units of ",{t:2,r:"name",p:[21,87,963]}]},{p:[21,102,978],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[20,7,845]},{t:4,n:51,f:[{p:[23,9,1009],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[17,5,727]},{t:4,n:51,f:[{p:[26,7,1085],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],241:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,32],t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[{p:[3,3,70],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?"Eject":"close"'},p:[3,20,87]}],style:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?"selected":null'},p:[4,11,143]}],state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[5,11,199]}],action:"eject"},f:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?"Eject and Clear Buffer":"No beaker"'},p:[7,5,268]}]}," ",{p:[10,3,357],t:7,e:"ui-section",f:[{t:4,f:[{t:4,f:[{p:[13,6,443],t:7,e:"ui-section",a:{label:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[13,25,462]}," units of ",{t:2,r:"name",p:[13,60,497]}],nowrap:0},f:[{p:[14,7,522],t:7,e:"div",a:{"class":"content",style:"float:right"},f:[{p:[15,8,572],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[15,61,625]},'", "amount": 1}']},f:["1"]}," ",{p:[16,8,670],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[16,61,723]},'", "amount": 5}']},f:["5"]}," ",{p:[17,8,768],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[17,61,821]},'", "amount": 10}']},f:["10"]}," ",{p:[18,8,868],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[18,61,921]},'", "amount": 1000}']},f:["All"]}," ",{p:[19,8,971],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[19,61,1024]},'", "amount": -1}']},f:["Custom"]}," ",{p:[20,8,1075],t:7,e:"ui-button",a:{action:"analyze",params:['{"id": "',{t:2,r:"id",p:[20,52,1119]},'"}']},f:["Analyze"]}]}]}],n:52,r:"data.beakerContents",p:[12,5,407]},{t:4,n:51,f:[{p:[24,5,1201],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"data.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[11,4,374]},{t:4,n:51,f:[{p:[27,5,1272],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}," ",{p:[32,2,1360],t:7,e:"ui-display",a:{title:"Buffer"},f:[{p:[33,3,1391],t:7,e:"ui-button",a:{action:"toggleMode",state:[{t:2,x:{r:["data.mode"],s:'_0?null:"selected"'},p:[33,41,1429]}]},f:["Destroy"]}," ",{p:[34,3,1487],t:7,e:"ui-button",a:{action:"toggleMode",state:[{t:2,x:{r:["data.mode"],s:'_0?"selected":null'},p:[34,41,1525]}]},f:["Transfer to Beaker"]}," ",{p:[35,3,1594],t:7,e:"ui-section",f:[{t:4,f:[{p:[37,5,1646],t:7,e:"ui-section",a:{label:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[37,24,1665]}," units of ",{t:2,r:"name",p:[37,59,1700]}],nowrap:0},f:[{p:[38,6,1724],t:7,e:"div",a:{"class":"content",style:"float:right"},f:[{p:[39,7,1773],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[39,62,1828]},'", "amount": 1}']},f:["1"]}," ",{p:[40,7,1872],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[40,62,1927]},'", "amount": 5}']},f:["5"]}," ",{p:[41,7,1971],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[41,62,2026]},'", "amount": 10}']},f:["10"]}," ",{p:[42,7,2072],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[42,62,2127]},'", "amount": 1000}']},f:["All"]}," ",{p:[43,7,2176],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[43,62,2231]},'", "amount": -1}']},f:["Custom"]}," ",{p:[44,7,2281],t:7,e:"ui-button",a:{action:"analyze",params:['{"id": "',{t:2,r:"id",p:[44,51,2325]},'"}']},f:["Analyze"]}]}]}],n:52,r:"data.bufferContents",p:[36,4,1611]}]}]}," ",{t:4,f:[{p:[52,3,2461],t:7,e:"ui-display",a:{title:"Pills, Bottles and Patches"},f:[{t:4,f:[{p:[54,5,2551],t:7,e:"ui-button",a:{action:"ejectp",state:[{t:2,x:{r:["data.isPillBottleLoaded"],s:'_0?null:"disabled"'},p:[54,39,2585]}]},f:[{t:2,x:{r:["data.isPillBottleLoaded"],s:'_0?"Eject":"No Pill bottle loaded"'},p:[54,88,2634]}]}," ",{p:[55,5,2715],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.pillBotContent",p:[55,27,2737]},"/",{t:2,r:"data.pillBotMaxContent",p:[55,51,2761]}]}],n:50,r:"data.isPillBottleLoaded",p:[53,4,2514]},{t:4,n:51,f:[{p:[57,5,2813],t:7,e:"span",a:{"class":"average"},f:["No Pillbottle"]}],r:"data.isPillBottleLoaded"}," ",{p:[60,4,2877],t:7,e:"br"}," ",{p:[61,4,2887],t:7,e:"br"}," ",{p:[62,4,2897],t:7,e:"ui-button",a:{action:"createPill",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[62,63,2956]}]},f:["Create Pill (max 50µ)"]}," ",{p:[63,4,3040],t:7,e:"br"}," ",{p:[64,4,3050],t:7,e:"ui-button",a:{action:"createPill",params:'{"many": 1}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[64,63,3109]}]},f:["Create Multiple Pills"]}," ",{p:[65,4,3193],t:7,e:"br"}," ",{p:[66,4,3203],t:7,e:"br"}," ",{p:[67,4,3213],t:7,e:"ui-button",a:{action:"createPatch",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[67,64,3273]}]},f:["Create Patch (max 40µ)"]}," ",{p:[68,4,3358],t:7,e:"br"}," ",{p:[69,4,3368],t:7,e:"ui-button",a:{action:"createPatch",params:'{"many": 1}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[69,64,3428]}]},f:["Create Multiple Patches"]}," ",{p:[70,4,3514],t:7,e:"br"}," ",{p:[71,4,3524],t:7,e:"br"}," ",{p:[72,4,3534],t:7,e:"ui-button",a:{action:"createBottle",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[72,65,3595]}]},f:["Create Bottle (max 30µ)"]}," ",{p:[73,4,3681],t:7,e:"br"}," ",{p:[74,4,3691],t:7,e:"ui-button",a:{action:"createBottle",params:'{"many": 1}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[74,65,3752]}]},f:["Dispense Buffer to Bottles"]}]}],n:50,x:{r:["data.condi"],s:"!_0"},p:[51,2,2438]},{t:4,n:51,f:[{p:[79,3,3874],t:7,e:"ui-display",a:{title:"Condiments bottles and packs"},f:[{p:[80,4,3929],t:7,e:"ui-button",a:{action:"createPill",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[80,63,3988]}]},f:["Create Pack (max 10µ)"]}," ",{p:[81,4,4072],t:7,e:"br"}," ",{p:[82,4,4082],t:7,e:"br"}," ",{p:[83,4,4092],t:7,e:"ui-button",a:{action:"createBottle",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[83,65,4153]}]},f:["Create Bottle (max 50µ)"]}]}],x:{r:["data.condi"],s:"!_0"}}],n:50,x:{r:["data.screen"],s:'_0=="home"'},p:[1,1,0]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.screen"],s:'_0=="analyze"'},f:[{p:[87,2,4301],t:7,e:"ui-display",a:{title:[{t:2,r:"data.analyzeVars.name",p:[87,20,4319]}]},f:[{p:[88,3,4350],t:7,e:"span",a:{"class":"highlight"},f:["Description:"]}," ",{p:[89,3,4398],t:7,e:"span",a:{"class":"content",style:"float:center"},f:[{t:2,r:"data.analyzeVars.description",p:[89,46,4441]}]}," ",{p:[90,3,4484],t:7,e:"br"}," ",{p:[91,3,4493],t:7,e:"span",a:{"class":"highlight"},f:["Color:"]}," ",{p:[92,3,4535],t:7,e:"span",a:{style:["color: ",{t:2,r:"data.analyzeVars.color",p:[92,23,4555]},"; background-color: ",{t:2,r:"data.analyzeVars.color",p:[92,69,4601]}]},f:[{t:2,r:"data.analyzeVars.color",p:[92,97,4629]}]}," ",{p:[93,3,4666],t:7,e:"br"}," ",{p:[94,3,4675],t:7,e:"span",a:{"class":"highlight"},f:["State:"]}," ",{p:[95,3,4717],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.state",p:[95,25,4739]}]}," ",{p:[96,3,4776],t:7,e:"br"}," ",{p:[97,3,4785],t:7,e:"span",a:{"class":"highlight"},f:["Metabolization Rate:"]}," ",{p:[98,3,4841],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.metaRate",p:[98,25,4863]},"µ/minute"]}," ",{p:[99,3,4911],t:7,e:"br"}," ",{p:[100,3,4920],t:7,e:"span",a:{"class":"highlight"},f:["Overdose Threshold:"]}," ",{p:[101,3,4975],t:7,e:"span", +a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.overD",p:[101,25,4997]}]}," ",{p:[102,3,5034],t:7,e:"br"}," ",{p:[103,3,5043],t:7,e:"span",a:{"class":"highlight"},f:["Addiction Threshold:"]}," ",{p:[104,3,5099],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.addicD",p:[104,25,5121]}]}," ",{p:[105,3,5159],t:7,e:"br"}," ",{p:[106,3,5168],t:7,e:"br"}," ",{p:[107,3,5177],t:7,e:"ui-button",a:{action:"goScreen",params:'{"screen": "home"}'},f:["Back"]}]}]}],x:{r:["data.screen"],s:'_0=="home"'}}]},e.exports=a.extend(r.exports)},{205:205}],242:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-button",a:{action:"toggle"},f:[{t:2,x:{r:["data.recollection"],s:'_0?"Recital":"Recollection"'},p:[2,30,43]}]}]}," ",{t:4,f:[{p:[5,3,149],t:7,e:"ui-display",f:[{t:3,r:"data.rec_text",p:[6,3,165]}," ",{t:4,f:[{p:[8,4,231],t:7,e:"br"},{p:[8,8,235],t:7,e:"ui-button",a:{action:"rec_category",params:['{"category": "',{t:2,r:"name",p:[8,63,290]},'"}']},f:[{t:3,r:"name",p:[8,75,302]}," - ",{t:3,r:"desc",p:[8,88,315]}]}],n:52,r:"data.recollection_categories",p:[7,3,188]}," ",{t:3,r:"data.rec_section",p:[10,3,354]}," ",{t:3,r:"data.rec_binds",p:[11,3,380]}]}],n:50,r:"data.recollection",p:[4,1,120]},{t:4,n:51,f:[{p:[14,2,431],t:7,e:"ui-display",a:{title:"Power",button:0},f:[{p:[15,4,469],t:7,e:"ui-section",f:[{t:3,r:"data.power",p:[16,6,488]}]}]}," ",{p:[19,2,541],t:7,e:"ui-display",f:[{p:[20,3,557],t:7,e:"ui-section",f:[{p:[21,4,574],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.selected"],s:'_0=="Driver"?"selected":null'},p:[21,22,592]}],action:"select",params:'{"category": "Driver"}'},f:["Driver"]}," ",{p:[22,4,715],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.selected"],s:'_0=="Script"?"selected":null'},p:[22,22,733]}],action:"select",params:'{"category": "Script"}'},f:["Scripts"]}," ",{p:[23,4,857],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.selected"],s:'_0=="Application"?"selected":null'},p:[23,22,875]}],action:"select",params:'{"category": "Application"}'},f:["Applications"]}," ",{p:[24,4,1014],t:7,e:"br"},{t:3,r:"data.tier_info",p:[24,8,1018]}]}," ",{p:[26,3,1059],t:7,e:"ui-section",f:[{t:3,r:"data.scripturecolors",p:[27,4,1076]}]},{p:[28,16,1119],t:7,e:"hr"}," ",{p:[29,3,1127],t:7,e:"ui-section",f:[{t:4,f:[{p:[31,4,1172],t:7,e:"div",f:[{p:[31,9,1177],t:7,e:"ui-button",a:{tooltip:[{t:3,r:"tip",p:[31,29,1197]}],"tooltip-side":"right",action:"recite",params:['{"category": "',{t:2,r:"type",p:[31,99,1267]},'"}']},f:["Recite ",{t:3,r:"required",p:[31,118,1286]}]}," ",{t:4,f:[{t:4,f:[{p:[34,6,1362],t:7,e:"ui-button",a:{action:"bind",params:['{"category": "',{t:2,r:"type",p:[34,53,1409]},'"}']},f:["Unbind ",{t:3,r:"bound",p:[34,72,1428]}]}],n:50,r:"bound",p:[33,5,1342]},{t:4,n:51,f:[{p:[36,6,1472],t:7,e:"ui-button",a:{action:"bind",params:['{"category": "',{t:2,r:"type",p:[36,53,1519]},'"}']},f:["Quickbind"]}],r:"bound"}],n:50,r:"quickbind",p:[32,6,1319]}," ",{t:3,r:"name",p:[39,6,1586]}," ",{t:3,r:"descname",p:[39,17,1597]}," ",{t:3,r:"invokers",p:[39,32,1612]}]}],n:52,r:"data.scripture",p:[30,3,1143]}]}]}],r:"data.recollection"}]},e.exports=a.extend(r.exports)},{205:205}],243:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Codex Gigas"},f:[{p:[2,2,35],t:7,e:"ui-section",f:[{t:2,r:"data.name",p:[3,3,51]}]}," ",{p:[5,5,86],t:7,e:"ui-section",a:{label:"Prefix"},f:[{p:[6,3,117],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[6,22,136]}],action:"Dark "},f:["Dark"]}," ",{p:[7,3,221],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[7,22,240]}],action:"Hellish "},f:["Hellish"]}," ",{p:[8,3,331],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[8,22,350]}],action:"Fallen "},f:["Fallen"]}," ",{p:[9,3,439],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[9,22,458]}],action:"Fiery "},f:["Fiery"]}," ",{p:[10,3,545],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[10,22,564]}],action:"Sinful "},f:["Sinful"]}," ",{p:[11,3,653],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[11,22,672]}],action:"Blood "},f:["Blood"]}," ",{p:[12,3,759],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[12,22,778]}],action:"Fluffy "},f:["Fluffy"]}]}," ",{p:[14,5,888],t:7,e:"ui-section",a:{label:"Title"},f:[{p:[15,3,918],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[15,22,937]}],action:"Lord "},f:["Lord"]}," ",{p:[16,3,1022],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[16,22,1041]}],action:"Prelate "},f:["Prelate"]}," ",{p:[17,3,1132],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[17,22,1151]}],action:"Count "},f:["Count"]}," ",{p:[18,3,1238],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[18,22,1257]}],action:"Viscount "},f:["Viscount"]}," ",{p:[19,3,1350],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[19,22,1369]}],action:"Vizier "},f:["Vizier"]}," ",{p:[20,3,1458],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[20,22,1477]}],action:"Elder "},f:["Elder"]}," ",{p:[21,3,1564],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[21,22,1583]}],action:"Adept "},f:["Adept"]}]}," ",{p:[23,5,1691],t:7,e:"ui-section",a:{label:"Name"},f:[{p:[24,3,1720],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[24,22,1739]}],action:"hal"},f:["hal"]}," ",{p:[25,3,1821],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[25,22,1840]}],action:"ve"},f:["ve"]}," ",{p:[26,3,1920],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[26,22,1939]}],action:"odr"},f:["odr"]}," ",{p:[27,3,2021],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[27,22,2040]}],action:"neit"},f:["neit"]}," ",{p:[28,3,2124],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[28,22,2143]}],action:"ci"},f:["ci"]}," ",{p:[29,3,2223],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[29,22,2242]}],action:"quon"},f:["quon"]}," ",{p:[30,3,2326],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[30,22,2345]}],action:"mya"},f:["mya"]}," ",{p:[31,3,2427],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[31,22,2446]}],action:"folth"},f:["folth"]}," ",{p:[32,3,2532],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[32,22,2551]}],action:"wren"},f:["wren"]}," ",{p:[33,3,2635],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[33,22,2654]}],action:"geyr"},f:["geyr"]}," ",{p:[34,3,2738],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[34,22,2757]}],action:"hil"},f:["hil"]}," ",{p:[35,3,2839],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[35,22,2858]}],action:"niet"},f:["niet"]}," ",{p:[36,3,2942],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[36,22,2961]}],action:"twou"},f:["twou"]}," ",{p:[37,3,3045],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[37,22,3064]}],action:"phi"},f:["phi"]}," ",{p:[38,3,3146],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[38,22,3165]}],action:"coa"},f:["coa"]}]}," ",{p:[40,5,3268],t:7,e:"ui-section",a:{label:"suffix"},f:[{p:[41,3,3299],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[41,22,3318]}],action:" the Red"},f:["the Red"]}," ",{p:[42,3,3409],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[42,22,3428]}],action:" the Soulless"},f:["the Soulless"]}," ",{p:[43,3,3529],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[43,22,3548]}],action:" the Master"},f:["the Master"]}," ",{p:[44,3,3645],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[44,22,3664]}],action:", the Lord of all things"},f:["the Lord of all things"]}," ",{p:[45,3,3786],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[45,22,3805]}],action:", Jr."},f:["jr"]}]}," ",{p:[47,5,3909],t:7,e:"ui-section",a:{label:"submit"},f:[{p:[48,3,3941],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0>=4?null:"disabled"'},p:[48,21,3959]}],action:"search"},f:["search"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],244:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[2,1,2],t:7,e:"ui-button",a:{icon:"circle",action:"clean_order"},f:["Clear Order"]},{p:[2,70,71],t:7,e:"br"},{p:[2,74,75],t:7,e:"br"}," ",{p:[3,1,81],t:7,e:"i",f:["Your new computer device you always dreamed of is just four steps away..."]},{p:[3,81,161],t:7,e:"hr"}," ",{t:4,f:[" ",{p:[5,1,223],t:7,e:"div",a:{"class":"item"},f:[{p:[6,2,244],t:7,e:"h2",f:["Step 1: Select your device type"]}," ",{p:[7,2,287],t:7,e:"ui-button",a:{icon:"calc",action:"pick_device",params:'{"pick" : "1"}'},f:["Laptop"]}," ",{p:[8,2,377],t:7,e:"ui-button",a:{icon:"calc",action:"pick_device",params:'{"pick" : "2"}'},f:["LTablet"]}]}],n:50,x:{r:["data.state"],s:"_0==0"},p:[4,1,167]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.state"],s:"_0==1"},f:[{p:[11,1,502],t:7,e:"div",a:{"class":"item"},f:[{p:[12,2,523],t:7,e:"h2",f:["Step 2: Personalise your device"]}," ",{p:[13,2,566],t:7,e:"table",f:[{p:[14,3,577],t:7,e:"tr",f:[{p:[15,4,586],t:7,e:"td",f:[{p:[15,8,590],t:7,e:"b",f:["Current Price:"]}]},{p:[16,4,616],t:7,e:"td",f:[{t:2,r:"data.totalprice",p:[16,8,620]},"C"]}]}," ",{p:[18,3,653],t:7,e:"tr",f:[{p:[19,4,663],t:7,e:"td",f:[{p:[19,8,667],t:7,e:"b",f:["Battery:"]}]},{p:[20,4,687],t:7,e:"td",f:[{p:[20,8,691],t:7,e:"ui-button",a:{action:"hw_battery",params:'{"battery" : "1"}',state:[{t:2,x:{r:["data.hw_battery"],s:'_0==1?"selected":null'},p:[20,73,756]}]},f:["Standard"]}]},{p:[21,4,827],t:7,e:"td",f:[{p:[21,8,831],t:7,e:"ui-button",a:{action:"hw_battery",params:'{"battery" : "2"}',state:[{t:2,x:{r:["data.hw_battery"],s:'_0==2?"selected":null'},p:[21,73,896]}]},f:["Upgraded"]}]},{p:[22,4,967],t:7,e:"td",f:[{p:[22,8,971],t:7,e:"ui-button",a:{action:"hw_battery",params:'{"battery" : "3"}',state:[{t:2,x:{r:["data.hw_battery"],s:'_0==3?"selected":null'},p:[22,73,1036]}]},f:["Advanced"]}]}]}," ",{p:[24,3,1115],t:7,e:"tr",f:[{p:[25,4,1124],t:7,e:"td",f:[{p:[25,8,1128],t:7,e:"b",f:["Hard Drive:"]}]},{p:[26,4,1151],t:7,e:"td",f:[{p:[26,8,1155],t:7,e:"ui-button",a:{action:"hw_disk",params:'{"disk" : "1"}',state:[{t:2,x:{r:["data.hw_disk"],s:'_0==1?"selected":null'},p:[26,67,1214]}]},f:["Standard"]}]},{p:[27,4,1282],t:7,e:"td",f:[{p:[27,8,1286],t:7,e:"ui-button",a:{action:"hw_disk",params:'{"disk" : "2"}',state:[{t:2,x:{r:["data.hw_disk"],s:'_0==2?"selected":null'},p:[27,67,1345]}]},f:["Upgraded"]}]},{p:[28,4,1413],t:7,e:"td",f:[{p:[28,8,1417],t:7,e:"ui-button",a:{action:"hw_disk",params:'{"disk" : "3"}',state:[{t:2,x:{r:["data.hw_disk"],s:'_0==3?"selected":null'},p:[28,67,1476]}]},f:["Advanced"]}]}]}," ",{p:[30,3,1552],t:7,e:"tr",f:[{p:[31,4,1561],t:7,e:"td",f:[{p:[31,8,1565],t:7,e:"b",f:["Network Card:"]}]},{p:[32,4,1590],t:7,e:"td",f:[{p:[32,8,1594],t:7,e:"ui-button",a:{action:"hw_netcard",params:'{"netcard" : "0"}',state:[{t:2,x:{r:["data.hw_netcard"],s:'_0==0?"selected":null'},p:[32,73,1659]}]},f:["None"]}]},{p:[33,4,1726],t:7,e:"td",f:[{p:[33,8,1730],t:7,e:"ui-button",a:{action:"hw_netcard",params:'{"netcard" : "1"}',state:[{t:2,x:{r:["data.hw_netcard"],s:'_0==1?"selected":null'},p:[33,73,1795]}]},f:["Standard"]}]},{p:[34,4,1866],t:7,e:"td",f:[{p:[34,8,1870],t:7,e:"ui-button",a:{action:"hw_netcard",params:'{"netcard" : "2"}',state:[{t:2,x:{r:["data.hw_netcard"],s:'_0==2?"selected":null'},p:[34,73,1935]}]},f:["Advanced"]}]}]}," ",{p:[36,3,2014],t:7,e:"tr",f:[{p:[37,4,2023],t:7,e:"td",f:[{p:[37,8,2027],t:7,e:"b",f:["Nano Printer:"]}]},{p:[38,4,2052],t:7,e:"td",f:[{p:[38,8,2056],t:7,e:"ui-button",a:{action:"hw_nanoprint",params:'{"print" : "0"}',state:[{t:2,x:{r:["data.hw_nanoprint"],s:'_0==0?"selected":null'},p:[38,73,2121]}]},f:["None"]}]},{p:[39,4,2190],t:7,e:"td",f:[{p:[39,8,2194],t:7,e:"ui-button",a:{action:"hw_nanoprint",params:'{"print" : "1"}',state:[{t:2,x:{r:["data.hw_nanoprint"],s:'_0==1?"selected":null'},p:[39,73,2259]}]},f:["Standard"]}]}]}," ",{p:[41,3,2340],t:7,e:"tr",f:[{p:[42,4,2349],t:7,e:"td",f:[{p:[42,8,2353],t:7,e:"b",f:["Card Reader:"]}]},{p:[43,4,2377],t:7,e:"td",f:[{p:[43,8,2381],t:7,e:"ui-button",a:{action:"hw_card",params:'{"card" : "0"}',state:[{t:2,x:{r:["data.hw_card"],s:'_0==0?"selected":null'},p:[43,67,2440]}]},f:["None"]}]},{p:[44,4,2504],t:7,e:"td",f:[{p:[44,8,2508],t:7,e:"ui-button",a:{action:"hw_card",params:'{"card" : "1"}',state:[{t:2,x:{r:["data.hw_card"],s:'_0==1?"selected":null'},p:[44,67,2567]}]},f:["Standard"]}]}]}]}," ",{t:4,f:[" ",{p:[49,4,2706],t:7,e:"table",f:[{p:[50,5,2719],t:7,e:"tr",f:[{p:[51,6,2730],t:7,e:"td",f:[{p:[51,10,2734],t:7,e:"b",f:["Processor Unit:"]}]},{p:[52,6,2763],t:7,e:"td",f:[{p:[52,10,2767],t:7,e:"ui-button",a:{action:"hw_cpu",params:'{"cpu" : "1"}',state:[{t:2,x:{r:["data.hw_cpu"],s:'_0==1?"selected":null'},p:[52,67,2824]}]},f:["Standard"]}]},{p:[53,6,2893],t:7,e:"td",f:[{p:[53,10,2897],t:7,e:"ui-button",a:{action:"hw_cpu",params:'{"cpu" : "2"}',state:[{t:2,x:{r:["data.hw_cpu"],s:'_0==2?"selected":null'},p:[53,67,2954]}]},f:["Advanced"]}]}]}," ",{p:[55,5,3033],t:7,e:"tr",f:[{p:[56,6,3044],t:7,e:"td",f:[{p:[56,10,3048],t:7,e:"b",f:["Tesla Relay:"]}]},{p:[57,6,3074],t:7,e:"td",f:[{p:[57,10,3078],t:7,e:"ui-button",a:{action:"hw_tesla",params:'{"tesla" : "0"}',state:[{t:2,x:{r:["data.hw_tesla"],s:'_0==0?"selected":null'},p:[57,71,3139]}]},f:["None"]}]},{p:[58,6,3206],t:7,e:"td",f:[{p:[58,10,3210],t:7,e:"ui-button",a:{action:"hw_tesla",params:'{"tesla" : "1"}',state:[{t:2,x:{r:["data.hw_tesla"],s:'_0==1?"selected":null'},p:[58,71,3271]}]},f:["Standard"]}]}]}]}],n:50,x:{r:["data.devtype"],s:"_0!=2"},p:[48,3,2659]}," ",{p:[62,3,3374],t:7,e:"table",f:[{p:[63,4,3386],t:7,e:"tr",f:[{p:[64,5,3396],t:7,e:"td",f:[{p:[64,9,3400],t:7,e:"b",f:["Confirm Order:"]}]},{p:[65,5,3427],t:7,e:"td",f:[{p:[65,9,3431],t:7,e:"ui-button",a:{action:"confirm_order"},f:["CONFIRM"]}]}]}]}," ",{p:[69,2,3512],t:7,e:"hr"}," ",{p:[70,2,3519],t:7,e:"b",f:["Battery"]}," allows your device to operate without external utility power source. Advanced batteries increase battery life.",{p:[70,127,3644],t:7,e:"br"}," ",{p:[71,2,3651],t:7,e:"b",f:["Hard Drive"]}," stores file on your device. Advanced drives can store more files, but use more power, shortening battery life.",{p:[71,130,3779],t:7,e:"br"}," ",{p:[72,2,3786],t:7,e:"b",f:["Network Card"]}," allows your device to wirelessly connect to stationwide NTNet network. Basic cards are limited to on-station use, while advanced cards can operate anywhere near the station, which includes the asteroid outposts.",{p:[72,233,4017],t:7,e:"br"}," ",{p:[73,2,4024],t:7,e:"b",f:["Processor Unit"]}," is critical for your device's functionality. It allows you to run programs from your hard drive. Advanced CPUs use more power, but allow you to run more programs on background at once.",{p:[73,208,4230],t:7,e:"br"}," ",{p:[74,2,4237],t:7,e:"b",f:["Tesla Relay"]}," is an advanced wireless power relay that allows your device to connect to nearby area power controller to provide alternative power source. This component is currently unavailable on tablet computers due to size restrictions.",{p:[74,246,4481],t:7,e:"br"}," ",{p:[75,2,4488],t:7,e:"b",f:["Nano Printer"]}," is device that allows for various paperwork manipulations, such as, scanning of documents or printing new ones. This device was certified EcoFriendlyPlus and is capable of recycling existing paper for printing purposes.",{p:[75,241,4727],t:7,e:"br"}," ",{p:[76,2,4734],t:7,e:"b",f:["Card Reader"]}," adds a slot that allows you to manipulate RFID cards. Please note that this is not necessary to allow the device to read your identification, it is just necessary to manipulate other cards."]}]},{t:4,n:50,x:{r:["data.state"],s:"(!(_0==1))&&(_0==2)"},f:[" ",{p:[79,2,4981],t:7,e:"h2",f:["Step 3: Payment"]}," ",{p:[80,2,5008],t:7,e:"b",f:["Your device is now ready for fabrication.."]},{p:[80,51,5057],t:7,e:"br"}," ",{p:[81,2,5064],t:7,e:"i",f:["Please ensure the required amount of credits are in the machine, then press purchase."]},{p:[81,94,5156],t:7,e:"br"}," ",{p:[82,2,5163],t:7,e:"i",f:["Current credits: ",{p:[82,22,5183],t:7,e:"b",f:[{t:2,r:"data.credits",p:[82,25,5186]},"C"]}]},{p:[82,50,5211],t:7,e:"br"}," ",{p:[83,2,5218],t:7,e:"i",f:["Total price: ",{p:[83,18,5234],t:7,e:"b",f:[{t:2,r:"data.totalprice",p:[83,21,5237]},"C"]}]},{p:[83,49,5265],t:7,e:"br"},{p:[83,53,5269],t:7,e:"br"}," ",{p:[84,2,5276],t:7,e:"ui-button",a:{action:"purchase",state:[{t:2,x:{r:["data.credits","data.totalprice"],s:'_0>=_1?null:"disabled"'},p:[84,38,5312]}]},f:["PURCHASE"]}]},{t:4,n:50,x:{r:["data.state"],s:"(!(_0==1))&&((!(_0==2))&&(_0==3))"},f:[" ",{p:[87,2,5423],t:7,e:"h2",f:["Step 4: Thank you for your purchase"]},{p:[87,46,5467],t:7,e:"br"}," ",{p:[88,2,5474],t:7,e:"b",f:["Should you experience any issues with your new device, contact your local network admin for assistance."]}]}],x:{r:["data.state"],s:"_0==0"}}]},e.exports=a.extend(r.exports)},{205:205}],245:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,1,22],t:7,e:"ui-display",f:[{p:[3,2,37],t:7,e:"ui-section",a:{label:"Cap"},f:[{p:[4,3,65],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.is_capped"],s:'_0?"power-off":"close"'},p:[4,20,82]}],style:[{t:2,x:{r:["data.is_capped"],s:'_0?null:"selected"'},p:[4,71,133]}],action:"toggle_cap"},f:[{t:2,x:{r:["data.is_capped"],s:'_0?"On":"Off"'},p:[6,4,202]}]}]}]}],n:50,r:"data.has_cap",p:[1,1,0]},{p:[10,1,288],t:7,e:"ui-display",f:[{t:4,f:[{p:[14,2,419],t:7,e:"ui-section",f:[{p:[15,3,435],t:7,e:"ui-button",a:{action:"select_colour"},f:["Select New Colour"]}]}],n:50,r:"data.can_change_colour",p:[13,1,386]}]}," ",{p:[19,1,540],t:7,e:"ui-display",a:{title:"Stencil"},f:[{t:4,f:[{p:[21,2,599],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[21,21,618]}]},f:[{t:4,f:[{p:[23,7,655],t:7,e:"ui-button",a:{action:"select_stencil",params:['{"item":"',{t:2,r:"item",p:[23,59,707]},'"}'],style:[{t:2,x:{r:["item","data.selected_stencil"],s:'_0==_1?"selected":null'},p:[24,12,731]}]},f:[{t:2,r:"item",p:[25,4,791]}]}],n:52,r:"items",p:[22,3,632]}]}],n:52,r:"data.drawables",p:[20,3,572]}]}," ",{p:[31,1,874],t:7,e:"ui-display",a:{title:"Text Mode"},f:[{p:[32,2,907],t:7,e:"ui-section",a:{label:"Current Buffer"},f:[{t:2,r:"text_buffer",p:[32,37,942]}]}," ",{p:[34,2,976],t:7,e:"ui-section",f:[{p:[34,14,988],t:7,e:"ui-button",a:{action:"enter_text"},f:["New Text"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],246:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Occupant"},f:[{p:[2,3,33],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[3,3,66],t:7,e:"span",f:[{t:2,x:{r:["data.occupant.name"],s:'_0?_0:"No Occupant"'},p:[3,9,72]}]}]}," ",{t:4,f:[{p:[6,5,189],t:7,e:"ui-section",a:{label:"State"},f:[{p:[7,7,223],t:7,e:"span",a:{"class":[{t:2,r:"data.occupant.statstate",p:[7,20,236]}]},f:[{t:2,r:"data.occupant.stat",p:[7,49,265]}]}]}," ",{p:[9,4,317],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[10,6,356],t:7,e:"span",a:{"class":[{t:2,r:"data.occupant.temperaturestatus",p:[10,19,369]}]},f:[{t:2,r:"data.occupant.bodyTemperature",p:[10,56,406]}," K"]}]}," ",{p:[12,5,472],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[13,7,507],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.occupant.minHealth",p:[13,20,520]}],max:[{t:2,r:"data.occupant.maxHealth",p:[13,54,554]}],value:[{t:2,r:"data.occupant.health",p:[13,90,590]}],state:[{t:2,x:{r:["data.occupant.health"],s:'_0>=0?"good":"average"'},p:[14,16,632]}]},f:[{t:2,r:"data.occupant.health",p:[14,68,684]}]}]}," ",{t:4,f:[{p:[17,7,908],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[17,26,927]}]},f:[{p:[18,9,948],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.occupant.maxHealth",p:[18,30,969]}],value:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[18,66,1005]}],state:"bad"},f:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[18,103,1042]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Respiratory",type:"oxyLoss"},{label:"Toxin",type:"toxLoss"},{label:"Burn",type:"fireLoss"}]'},p:[16,5,742]}],n:50,r:"data.hasOccupant",p:[5,3,159]}]}," ",{p:[23,1,1138],t:7,e:"ui-display",a:{title:"Cell"},f:[{p:[24,3,1167],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[25,5,1199],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isOperating"],s:'_0?"power-off":"close"'},p:[25,22,1216]}],style:[{t:2,x:{r:["data.isOperating"],s:'_0?"selected":null'},p:[26,14,1276]}],state:[{t:2,x:{r:["data.isOpen"],s:'_0?"disabled":null'},p:[27,14,1332]}],action:"power"},f:[{t:2,x:{r:["data.isOperating"],s:'_0?"On":"Off"'},p:[28,22,1391]}]}]}," ",{p:[30,3,1459],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[31,3,1495],t:7,e:"span",a:{"class":[{t:2,r:"data.temperaturestatus",p:[31,16,1508]}]},f:[{t:2,r:"data.cellTemperature",p:[31,44,1536]}," K"]}]}," ",{p:[33,2,1588],t:7,e:"ui-section",a:{label:"Door"},f:[{p:[34,5,1619],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isOpen"],s:'_0?"unlock":"lock"'},p:[34,22,1636]}],action:"door"},f:[{t:2,x:{r:["data.isOpen"],s:'_0?"Open":"Closed"'},p:[34,73,1687]}]}," ",{p:[35,5,1740],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.autoEject"],s:'_0?"sign-out":"sign-in"'},p:[35,22,1757]}],action:"autoeject"},f:[{t:2,x:{r:["data.autoEject"],s:'_0?"Auto":"Manual"'},p:[35,86,1821]}]}]}]}," ",{p:{button:[{p:[40,5,1967],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[40,36,1998]}],action:"ejectbeaker"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{p:[42,3,2101],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{t:4,f:[{p:[45,9,2211],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,r:"volume",p:[45,52,2254]}," units of ",{t:2,r:"name",p:[45,72,2274]}]},{p:[45,87,2289],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[44,7,2171]},{t:4,n:51,f:[{p:[47,9,2320],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[43,5,2136]},{t:4,n:51,f:[{p:[50,7,2396],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],247:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,2,15],t:7,e:"ui-section",a:{label:"State"},f:[{t:4,f:[{p:[4,4,76],t:7,e:"span",a:{"class":"good"},f:["Ready"]}],n:50,r:"data.full_pressure",p:[3,3,45]},{t:4,n:51,f:[{t:4,f:[{p:[7,5,153],t:7,e:"span",a:{"class":"bad"},f:["Power Disabled"]}],n:50,r:"data.panel_open",p:[6,4,124]},{t:4,n:51,f:[{t:4,f:[{p:[10,6,248],t:7,e:"span",a:{"class":"average"},f:["Pressurizing"]}],n:50,r:"data.pressure_charging",p:[9,5,211]},{t:4,n:51,f:[{p:[12,6,310],t:7,e:"span",a:{"class":"bad"},f:["Off"]}],r:"data.pressure_charging"}],r:"data.panel_open"}],r:"data.full_pressure"}]}," ",{p:[17,2,393],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[18,3,426],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.per",p:[18,36,459]}],state:"good"},f:[{t:2,r:"data.per",p:[18,63,486]},"%"]}]}," ",{p:[20,5,530],t:7,e:"ui-section",a:{label:"Handle"},f:[{p:[21,9,567],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.flush"],s:'_0?"toggle-on":"toggle-off"'},p:[22,10,589]}],state:[{t:2,x:{r:["data.isai","data.panel_open"],s:'_0||_1?"disabled":null'},p:[23,11,647]}],action:[{t:2,x:{r:["data.flush"],s:'_0?"handle-0":"handle-1"'},p:[24,12,714]}]},f:[{t:2,x:{r:["data.flush"],s:'_0?"Disengage":"Engage"'},p:[25,5,763]}]}]}," ",{p:[27,2,837],t:7,e:"ui-section",a:{label:"Eject"},f:[{p:[28,3,867],t:7,e:"ui-button",a:{icon:"sign-out",state:[{t:2,x:{r:["data.isai"],s:'_0?"disabled":null'},p:[28,37,901]}],action:"eject"},f:["Eject Contents"]},{p:[28,114,978],t:7,e:"br"}]}," ",{p:[30,2,1002],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[31,3,1032],t:7,e:"ui-button",a:{icon:"power-off",state:[{t:2,x:{r:["data.panel_open"],s:'_0?"disabled":null'},p:[31,38,1067]}],action:[{t:2,x:{r:["data.pressure_charging"],s:'_0?"pump-0":"pump-1"'},p:[31,87,1116]}],style:[{t:2,x:{r:["data.pressure_charging"],s:'_0?"selected":null'},p:[31,145,1174]}]}},{p:[31,206,1235],t:7,e:"br"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],248:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"DNA Vault Database"},f:[{p:[2,3,43],t:7,e:"ui-section",a:{label:"Human DNA"},f:[{p:[3,7,81],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.dna_max",p:[3,28,102]}],value:[{t:2,r:"data.dna",p:[3,53,127]}]},f:[{t:2,r:"data.dna",p:[3,67,141]},"/",{t:2,r:"data.dna_max",p:[3,80,154]}," Samples"]}]}," ",{p:[5,3,208],t:7,e:"ui-section",a:{label:"Plant Data"},f:[{p:[6,5,245],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.plants_max",p:[6,26,266]}],value:[{t:2,r:"data.plants",p:[6,54,294]}]},f:[{t:2,r:"data.plants",p:[6,71,311]},"/",{t:2,r:"data.plants_max",p:[6,87,327]}," Samples"]}]}," ",{p:[8,3,384],t:7,e:"ui-section",a:{label:"Animal Data"},f:[{p:[9,5,422],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.animals_max",p:[9,26,443]}],value:[{t:2,r:"data.animals",p:[9,55,472]}]},f:[{t:2,r:"data.animals",p:[9,73,490]},"/",{t:2,r:"data.animals_max",p:[9,90,507]}," Samples"]}]}]}," ",{t:4,f:[{p:[13,1,616],t:7,e:"ui-display",a:{title:"Personal Gene Therapy"},f:[{p:[14,3,663],t:7,e:"ui-section",f:[{p:[15,2,678],t:7,e:"span",f:["Applicable gene therapy treatments:"]}]}," ",{p:[17,3,747],t:7,e:"ui-section",f:[{p:[18,2,762],t:7,e:"ui-button",a:{action:"gene",params:['{"choice": "',{t:2,r:"data.choiceA",p:[18,47,807]},'"}']},f:[{t:2,r:"data.choiceA",p:[18,67,827]}]}," ",{p:[19,2,858],t:7,e:"ui-button",a:{action:"gene",params:['{"choice": "',{t:2,r:"data.choiceB",p:[19,47,903]},'"}']},f:[{t:2,r:"data.choiceB",p:[19,67,923]}]}]}]}],n:50,x:{r:["data.completed","data.used"],s:"_0&&!_1"},p:[12,1,578]}]},e.exports=a.extend(r.exports)},{205:205}],249:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Occupant"},f:[{p:[2,3,33],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[3,3,66],t:7,e:"span",f:[{t:2,x:{r:["data.occupant.name"],s:'_0?_0:"No Occupant"'},p:[3,9,72]}]}]}," ",{t:4,f:[{p:[6,5,183],t:7,e:"ui-section",a:{label:"Items in storage"},f:[{p:[7,4,225],t:7,e:"span",f:[{t:2,r:"data.items",p:[7,10,231]}]}]}],n:50,r:"data.items",p:[5,3,159]}," ",{t:4,f:[{p:[11,5,310],t:7,e:"ui-section",a:{label:"State"},f:[{p:[12,7,344],t:7,e:"span",a:{"class":[{t:2,r:"data.occupant.statstate",p:[12,20,357]}]},f:[{t:2,r:"data.occupant.stat",p:[12,49,386]}]}]}," ",{p:[14,5,439],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[15,7,474],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.occupant.minHealth",p:[15,20,487]}],max:[{t:2,r:"data.occupant.maxHealth",p:[15,54,521]}],value:[{t:2,r:"data.occupant.health",p:[15,90,557]}],state:[{t:2,x:{r:["data.occupant.health"],s:'_0>=0?"good":"average"'},p:[16,16,599]}]},f:[{t:2,x:{r:["adata.occupant.health"],s:"Math.round(_0)"},p:[16,68,651]}]}]}," ",{t:4,f:[{p:[19,7,888],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[19,26,907]}]},f:[{p:[20,9,928],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.occupant.maxHealth",p:[20,30,949]}],value:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[20,66,985]}],state:"bad"},f:[{t:2,x:{r:["type","adata.occupant"],s:"Math.round(_1[_0])"},p:[20,103,1022]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Respiratory",type:"oxyLoss"},{label:"Toxin",type:"toxLoss"},{label:"Burn",type:"fireLoss"}]'},p:[18,5,722]}," ",{p:[23,5,1109],t:7,e:"ui-section",a:{label:"Cells"},f:[{p:[24,9,1145],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"bad":"good"'},p:[24,22,1158]}]},f:[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"Damaged":"Healthy"'},p:[24,68,1204]}]}]}," ",{p:[26,5,1287],t:7,e:"ui-section",a:{label:"Brain"},f:[{p:[27,9,1323],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"bad":"good"'},p:[27,22,1336]}]},f:[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"Abnormal":"Healthy"'},p:[27,68,1382]}]}]}," ",{p:[29,5,1466],t:7,e:"ui-section",a:{label:"Bloodstream"},f:[{t:4,f:[{p:[31,11,1553],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,1)"},p:[31,54,1596]}," units of ",{t:2,r:"name",p:[31,89,1631]}]},{p:[31,104,1646],t:7,e:"br"}],n:52,r:"adata.occupant.reagents",p:[30,9,1508]},{t:4,n:51,f:[{p:[33,11,1681],t:7,e:"span",a:{"class":"good"},f:["Pure"]}],r:"adata.occupant.reagents"}]}],n:50,r:"data.occupied",p:[10,3,283]}]}," ",{p:[38,1,1777],t:7,e:"ui-display",a:{title:"Operations"},f:[{p:[39,3,1812],t:7,e:"ui-section",a:{label:"Inject"},f:[{t:4,f:[{p:[41,7,1872],t:7,e:"ui-button",a:{icon:"flask",state:[{t:2,x:{r:["data.occupied"],s:'_0?null:"disabled"'},p:[41,38,1903]}],action:"inject",params:['{"chem": "',{t:2,r:"id",p:[41,111,1976]},'"}']},f:[{t:2,r:"name",p:[41,121,1986]}]},{p:[41,141,2006],t:7,e:"br"}],n:52,r:"data.chem",p:[40,5,1845]}]}," ",{p:[44,2,2046],t:7,e:"ui-section",a:{label:"Eject"},f:[{p:[45,6,2079],t:7,e:"ui-button",a:{icon:"sign-out",action:"eject"},f:["Eject Contents"]}]}," ",{p:[47,2,2166],t:7,e:"ui-section",a:{label:"Self Cleaning"},f:[{p:[48,3,2204],t:7,e:"ui-button",a:{icon:"recycle",action:"cleaning"},f:["Self-Clean Cycle"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],250:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,24],t:7,e:"ui-display",a:{title:[{t:2,r:"data.question",p:[2,21,42]}]},f:[{p:[3,5,66],t:7,e:"ui-section",f:[{t:4,f:[{p:[5,9,118],t:7,e:"ui-button",a:{action:"vote",params:['{"answer": "',{t:2,r:"answer",p:[6,45,174]},'"}'],style:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[7,18,206]}]},f:[{t:2,r:"answer",p:[7,53,241]}," (",{t:2,r:"amount",p:[7,65,253]},")"]}],n:52,r:"data.answers",p:[4,7,86]}]}]}],n:50,r:"data.shaking",p:[1,1,0]},{t:4,n:51,f:[{p:[13,3,353],t:7,e:"ui-notice",f:["The eightball is not currently being shaken."]}],r:"data.shaking"}]},e.exports=a.extend(r.exports)},{205:205}],251:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,5,17],t:7,e:"span",f:["Time Until Launch: ",{t:2,r:"data.timer_str",p:[2,30,42]}]}]}," ",{p:[4,1,83],t:7,e:"ui-notice",f:[{p:[5,3,98],t:7,e:"span",f:["Engines: ",{t:2,x:{r:["data.engines_started"],s:'_0?"Online":"Idle"'},p:[5,18,113]}]}]}," ",{p:[7,1,180],t:7,e:"ui-display",a:{title:"Early Launch"},f:[{p:[8,2,216],t:7,e:"span",f:["Authorizations Remaining: ",{t:2,x:{r:["data.emagged","data.authorizations_remaining"],s:'_0?"ERROR":_1'},p:[9,2,250]}]}," ",{p:[10,2,318],t:7,e:"ui-button",a:{icon:"exclamation-triangle",action:"authorize",style:"danger",state:[{t:2,x:{r:["data.enabled"],s:'_0?null:"disabled"'},p:[12,10,404]}]},f:["AUTHORIZE"]}," ",{p:[15,2,473],t:7,e:"ui-button",a:{icon:"minus",action:"repeal",state:[{t:2,x:{r:["data.enabled"],s:'_0?null:"disabled"'},p:[16,10,523]}]},f:["Repeal"]}," ",{p:[19,2,589],t:7,e:"ui-button",a:{icon:"close",action:"abort",state:[{t:2,x:{r:["data.enabled"],s:'_0?null:"disabled"'},p:[20,10,638]}]},f:["Repeal All"]}]}," ",{p:[24,1,722],t:7,e:"ui-display",a:{title:"Authorizations" +},f:[{t:4,f:[{p:[26,3,793],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{t:2,r:"name",p:[26,34,824]}," (",{t:2,r:"job",p:[26,44,834]},")"]}],n:52,r:"data.authorizations",p:[25,2,760]},{t:4,n:51,f:[{p:[28,3,870],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:["No authorizations."]}],r:"data.authorizations"}]}]},e.exports=a.extend(r.exports)},{205:205}],252:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-section",a:{label:"Message"},f:[{t:2,r:"data.hidden_message",p:[3,5,50]}]}," ",{p:[5,3,94],t:7,e:"ui-section",a:{label:"Created On"},f:[{t:2,r:"data.realdate",p:[6,5,131]}]}," ",{p:[8,3,169],t:7,e:"ui-section",a:{label:"Approval"},f:[{p:[9,5,204],t:7,e:"ui-button",a:{icon:"arrow-up",state:[{t:2,x:{r:["data.is_creator","data.has_liked"],s:'_0?"disabled":_1?"selected":null'},p:[11,14,252]}],action:"like"},f:[{t:2,r:"data.num_likes",p:[12,21,344]}]}," ",{p:[13,5,380],t:7,e:"ui-button",a:{icon:"circle",state:[{t:2,x:{r:["data.is_creator","data.has_liked","data.has_disliked"],s:'_0?"disabled":!_1&&!_2?"selected":null'},p:[15,14,426]}],action:"neutral"}}," ",{p:[17,5,562],t:7,e:"ui-button",a:{icon:"arrow-down",state:[{t:2,x:{r:["data.is_creator","data.has_disliked"],s:'_0?"disabled":_1?"selected":null'},p:[19,14,612]}],action:"dislike"},f:[{t:2,r:"data.num_dislikes",p:[20,24,710]}]}]}]}," ",{t:4,f:[{p:[24,3,805],t:7,e:"ui-display",a:{title:"Admin Panel"},f:[{p:[25,5,843],t:7,e:"ui-section",a:{label:"Creator Ckey"},f:[{t:2,r:"data.creator_key",p:[25,38,876]}]}," ",{p:[26,5,915],t:7,e:"ui-section",a:{label:"Creator Character Name"},f:[{t:2,r:"data.creator_name",p:[26,48,958]}]}," ",{p:[27,5,998],t:7,e:"ui-button",a:{icon:"remove",action:"delete",style:"danger"},f:["Delete"]}]}],n:50,r:"data.admin_mode",p:[23,1,778]}]},e.exports=a.extend(r.exports)},{205:205}],253:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,3,15],t:7,e:"span",f:["The requested interface (",{t:2,r:"config.interface",p:[2,34,46]},") was not found. Does it exist?"]}]}]},e.exports=a.extend(r.exports)},{205:205}],254:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,20],t:7,e:"ui-notice",f:["Currently syncing with the database"]}],n:50,r:"data.sync",p:[1,1,0]},{t:4,n:51,f:[{p:{button:[{p:[8,4,163],t:7,e:"ui-button",a:{icon:"eject",action:"eject_all"},f:["Eject all"]}," ",{p:[9,4,232],t:7,e:"ui-button",a:{icon:["toggle-",{t:2,x:{r:["data.show_materials"],s:'_0?"off":"on"'},p:[9,28,256]}],action:"toggle_materials_visibility"},f:[{t:2,x:{r:["data.show_materials"],s:'_0?"Hide":"Show"'},p:[10,5,339]}]}]},t:7,e:"ui-display",a:{title:"Materials",button:0},f:[" ",{t:4,f:[{p:[14,4,449],t:7,e:"div",a:{"class":"display tabular"},f:[{p:[15,5,484],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[16,6,520],t:7,e:"section",a:{"class":"cell"}}," ",{p:[17,6,559],t:7,e:"section",a:{"class":"cell"},f:["Mineral"]}," ",{p:[20,6,620],t:7,e:"section",a:{"class":"cell"},f:["Amount"]}," ",{p:[23,6,680],t:7,e:"section",a:{"class":"cell"}}," ",{p:[24,6,719],t:7,e:"section",a:{"class":"cell"}}]}," ",{t:4,f:[{p:[27,6,808],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[28,7,845],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[29,8,876]}]}," ",{p:[31,7,910],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"amount",p:[32,8,941]}]}," ",{p:[34,7,977],t:7,e:"section",a:{"class":"cell"},f:[{p:[35,8,1008],t:7,e:"ui-button",a:{icon:"eject"},f:["Release amount"]}]}," ",{p:[37,7,1084],t:7,e:"section",a:{"class":"cell",style:"width: 40px;"},f:[{p:[38,8,1136],t:7,e:"ui-button",a:{icon:"eject"},f:["Release all"]}]}]}],n:52,r:"data.all_materials",p:[26,5,773]}]}],n:50,r:"data.show_materials",p:[13,3,417]}]}," ",{p:[45,2,1274],t:7,e:"ui-display",a:{title:"Categories"},f:[{t:4,f:[{p:[47,4,1334],t:7,e:"ui-button",f:[{t:2,r:".",p:[47,15,1345]}]}],r:"data.categories",p:[46,3,1309]}]}],r:"data.sync"}]},e.exports=a.extend(r.exports)},{205:205}],255:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[3,5,49],t:7,e:"ui-button",a:{action:"toggle_power",style:[{t:2,x:{r:["data.toggle"],s:'_0?"selected":null'},p:[5,18,111]}]},f:["Turn ",{t:2,x:{r:["data.toggle"],s:'_0?"off":"on"'},p:[6,16,166]}]}]}," ",{p:[9,3,235],t:7,e:"ui-display",a:{title:"Logging"},f:[{t:4,f:[{p:[11,3,292],t:7,e:"ui-section",a:{label:">"},f:[{t:2,r:".",p:[11,25,314]},{p:[11,30,319],t:7,e:"ui-section",f:[]}]}],n:52,r:"data.logs",p:[10,5,269]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],256:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{seclevelState:function(){switch(this.get("data.seclevel")){case"blue":return"average";case"red":return"bad";case"delta":return"bad bold";default:return"good"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[16,1,323],t:7,e:"ui-display",f:[{p:[17,5,341],t:7,e:"ui-section",a:{label:"Alert Level"},f:[{p:[18,9,383],t:7,e:"span",a:{"class":[{t:2,r:"seclevelState",p:[18,22,396]}]},f:[{t:2,x:{r:["text","data.seclevel"],s:"_0.titleCase(_1)"},p:[18,41,415]}]}]}," ",{p:[20,5,480],t:7,e:"ui-section",a:{label:"Controls"},f:[{p:[21,9,519],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.alarm"],s:'_0?"close":"bell-o"'},p:[21,26,536]}],action:[{t:2,x:{r:["data.alarm"],s:'_0?"reset":"alarm"'},p:[21,71,581]}]},f:[{t:2,x:{r:["data.alarm"],s:'_0?"Reset":"Activate"'},p:[22,13,631]}]}]}," ",{t:4,f:[{p:[25,7,733],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[26,9,771],t:7,e:"span",a:{"class":"bad bold"},f:["Safety measures offline. Device may exhibit abnormal behavior."]}]}],n:50,r:"data.emagged",p:[24,5,705]}]}]},e.exports=a.extend(r.exports)},{205:205}],257:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[2,1,31],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,2,60],t:7,e:"ui-button",a:{icon:"power-off",style:[{t:2,x:{r:["data.power"],s:'_0?"selected":"danger"'},p:[3,37,95]}],action:"power"},f:[{t:2,x:{r:["data.power"],s:'_0?"Enabled":"Disabled"'},p:[3,92,150]}]}]}," ",{p:[5,1,218],t:7,e:"ui-section",a:{label:"Tag"},f:[{p:[6,2,245],t:7,e:"ui-button",a:{icon:"pencil",action:"rename"},f:[{t:2,r:"data.tag",p:[6,43,286]}]}]}," ",{p:[8,1,327],t:7,e:"ui-section",a:{label:"Scanning mode"},f:[{p:[9,2,364],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.updating"],s:'_0?"unlock":"lock"'},p:[9,18,380]}],style:[{t:2,x:{r:["data.updating"],s:'_0?null:"danger"'},p:[9,63,425]}],action:"updating",tooltip:"Toggle between automatic scanning or scan only when a button is pressed.","tooltip-side":"right"},f:[{t:2,x:{r:["data.updating"],s:'_0?"AUTO":"MANUAL"'},p:[9,221,583]}]}]}," ",{p:[11,1,649],t:7,e:"ui-section",a:{label:"Detection range"},f:[{p:[12,2,688],t:7,e:"ui-button",a:{icon:"refresh",style:[{t:2,x:{r:["data.globalmode"],s:'_0?null:"selected"'},p:[12,35,721]}],action:"globalmode",tooltip:"Local sector or whole region scanning.","tooltip-side":"right"},f:[{t:2,x:{r:["data.globalmode"],s:'_0?"MAXIMUM":"LOCAL"'},p:[12,165,851]}]}]}]}," ",{t:4,f:[{p:[16,2,957],t:7,e:"ui-display",a:{title:"Current Location"},f:[{p:[17,3,998],t:7,e:"span",f:[{t:2,r:"data.current",p:[17,9,1004]}]}]}," ",{p:[20,2,1048],t:7,e:"ui-display",a:{title:"Detected Signals"},f:[{t:4,f:[{p:[22,3,1114],t:7,e:"ui-section",a:{label:[{t:2,r:"entrytag",p:[22,21,1132]}]},f:[{p:[23,3,1149],t:7,e:"span",f:[{t:2,r:"area",p:[23,9,1155]}," (",{t:2,r:"coord",p:[23,19,1165]},")"]}," ",{t:4,f:[{p:[25,4,1209],t:7,e:"span",f:["Dist: ",{t:2,r:"dist",p:[25,16,1221]},"m Dir: ",{t:2,r:"degrees",p:[25,31,1236]},"° (",{t:2,r:"direction",p:[25,45,1250]},")"]}],n:50,r:"direction",p:[24,3,1187]}]}],n:52,r:"data.signals",p:[21,2,1088]}]}],n:50,r:"data.power",p:[15,1,936]}]},e.exports=a.extend(r.exports)},{205:205}],258:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Labor Camp Teleporter"},f:[{p:[2,2,45],t:7,e:"ui-section",a:{label:"Teleporter Status"},f:[{p:[3,3,87],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.teleporter"],s:'_0?"good":"bad"'},p:[3,16,100]}]},f:[{t:2,x:{r:["data.teleporter"],s:'_0?"Connected":"Not connected"'},p:[3,54,138]}]}]}," ",{t:4,f:[{p:[6,4,244],t:7,e:"ui-section",a:{label:"Location"},f:[{p:[7,5,279],t:7,e:"span",f:[{t:2,r:"data.teleporter_location",p:[7,11,285]}]}]}," ",{p:[9,4,343],t:7,e:"ui-section",a:{label:"Locked status"},f:[{p:[10,5,383],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.teleporter_lock"],s:'_0?"lock":"unlock"'},p:[10,22,400]}],action:"teleporter_lock"},f:[{t:2,x:{r:["data.teleporter_lock"],s:'_0?"Locked":"Unlocked"'},p:[10,93,471]}]}," ",{p:[11,5,537],t:7,e:"ui-button",a:{action:"toggle_open"},f:[{t:2,x:{r:["data.teleporter_state_open"],s:'_0?"Open":"Closed"'},p:[11,37,569]}]}]}],n:50,r:"data.teleporter",p:[5,3,216]},{t:4,n:51,f:[{p:[14,4,666],t:7,e:"span",f:[{p:[14,10,672],t:7,e:"ui-button",a:{action:"scan_teleporter"},f:["Scan Teleporter"]}]}],r:"data.teleporter"}]}," ",{p:[17,1,770],t:7,e:"ui-display",a:{title:"Labor Camp Beacon"},f:[{p:[18,2,811],t:7,e:"ui-section",a:{label:"Beacon Status"},f:[{p:[19,3,849],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.beacon"],s:'_0?"good":"bad"'},p:[19,16,862]}]},f:[{t:2,x:{r:["data.beacon"],s:'_0?"Connected":"Not connected"'},p:[19,50,896]}]}]}," ",{t:4,f:[{p:[22,3,992],t:7,e:"ui-section",a:{label:"Location"},f:[{p:[23,4,1026],t:7,e:"span",f:[{t:2,r:"data.beacon_location",p:[23,10,1032]}]}]}],n:50,r:"data.beacon",p:[21,2,969]},{t:4,n:51,f:[{p:[26,4,1097],t:7,e:"span",f:[{p:[26,10,1103],t:7,e:"ui-button",a:{action:"scan_beacon"},f:["Scan Beacon"]}]}],r:"data.beacon"}]}," ",{p:[29,1,1193],t:7,e:"ui-display",a:{title:"Prisoner details"},f:[{p:[30,2,1233],t:7,e:"ui-section",a:{label:"Prisoner ID"},f:[{p:[31,3,1269],t:7,e:"ui-button",a:{action:"handle_id"},f:[{t:2,x:{r:["data.id","data.id_name"],s:'_0?_1:"-------------"'},p:[31,33,1299]}]}]}," ",{t:4,f:[{p:[34,2,1392],t:7,e:"ui-section",a:{label:"Set ID goal"},f:[{p:[35,4,1429],t:7,e:"ui-button",a:{action:"set_goal"},f:[{t:2,r:"data.goal",p:[35,33,1458]}]}]}],n:50,r:"data.id",p:[33,2,1374]}," ",{p:[38,2,1512],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[39,3,1545],t:7,e:"span",f:[{t:2,x:{r:["data.prisoner.name"],s:'_0?_0:"No Occupant"'},p:[39,9,1551]}]}]}," ",{t:4,f:[{p:[42,3,1661],t:7,e:"ui-section",a:{label:"Criminal Status"},f:[{p:[43,4,1702],t:7,e:"span",f:[{t:2,r:"data.prisoner.crimstat",p:[43,10,1708]}]}]}],n:50,r:"data.prisoner",p:[41,2,1636]}]}," ",{p:[47,1,1785],t:7,e:"ui-display",f:[{p:[48,2,1800],t:7,e:"center",f:[{p:[48,10,1808],t:7,e:"ui-button",a:{action:"teleport",state:[{t:2,x:{r:["data.can_teleport"],s:'_0?null:"disabled"'},p:[48,45,1843]}]},f:["Process Prisoner"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],259:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,2,15],t:7,e:"center",f:[{p:[2,10,23],t:7,e:"ui-button",a:{action:"handle_id"},f:[{t:2,x:{r:["data.id","data.id_name"],s:'_0?_1:"-------------"'},p:[2,40,53]}]}]}]}," ",{p:[4,1,135],t:7,e:"ui-display",a:{title:"Stored Items"},f:[{t:4,f:[{p:[6,3,194],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[6,22,213]}]},f:[{p:[7,4,228],t:7,e:"ui-button",a:{action:"release_items",params:['{"mobref":',{t:2,r:"mob",p:[7,56,280]},"}"],state:[{t:2,x:{r:["data.can_reclaim"],s:'_0?null:"disabled"'},p:[7,72,296]}]},f:["Drop Items"]}]}],n:52,r:"data.mobs",p:[5,2,171]}]}]},e.exports=a.extend(r.exports)},{205:205}],260:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{p:[3,3,70],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.emagged"],s:'_0?"un":null'},p:[3,20,87]},"lock"],state:[{t:2,x:{r:["data.can_toggle_safety"],s:'_0?null:"disabled"'},p:[3,63,130]}],action:"safety"},f:["Safeties: ",{p:[4,14,209],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.emagged"],s:'_0?"bad":"good"'},p:[4,27,222]}]},f:[{t:2,x:{r:["data.emagged"],s:'_0?"OFF":"ON"'},p:[4,62,257]}]}]}]},t:7,e:"ui-display",a:{title:"Default Programs",button:0},f:[" ",{t:4,f:[{p:[8,2,363],t:7,e:"ui-button",a:{action:"load_program",params:['{"type": ',{t:2,r:"type",p:[8,52,413]},"}"],style:[{t:2,x:{r:["data.program","type"],s:'_0==_1?"selected":null'},p:[8,70,431]}]},f:[{t:2,r:"name",p:[9,5,483]}," "]},{p:[10,14,506],t:7,e:"br"}],n:52,r:"data.default_programs",p:[7,2,329]}]}," ",{t:4,f:[{p:[14,2,562],t:7,e:"ui-display",a:{title:"Dangerous Programs"},f:[{t:4,f:[{p:[16,4,638],t:7,e:"ui-button",a:{icon:"warning",action:"load_program",params:['{"type": ',{t:2,r:"type",p:[16,69,703]},"}"],style:[{t:2,x:{r:["data.program","type"],s:'_0==_1?"selected":null'},p:[16,87,721]}]},f:[{t:2,r:"name",p:[17,5,773]}," "]},{p:[18,16,798],t:7,e:"br"}],n:52,r:"data.emag_programs",p:[15,3,605]}]}],n:50,r:"data.emagged",p:[13,1,539]}]},e.exports=a.extend(r.exports)},{205:205}],261:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{occupantStatState:function(){switch(this.get("data.occupant.stat")){case 0:return"good";case 1:return"average";default:return"bad"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[15,1,280],t:7,e:"ui-display",a:{title:"Occupant"},f:[{p:[16,3,313],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[17,3,346],t:7,e:"span",f:[{t:2,x:{r:["data.occupant.name"],s:'_0?_0:"No Occupant"'},p:[17,9,352]}]}]}," ",{t:4,f:[{p:[20,5,466],t:7,e:"ui-section",a:{label:"State"},f:[{p:[21,7,500],t:7,e:"span",a:{"class":[{t:2,r:"occupantStatState",p:[21,20,513]}]},f:[{t:2,x:{r:["data.occupant.stat"],s:'_0==0?"Conscious":_0==1?"Unconcious":"Dead"'},p:[21,43,536]}]}]}],n:50,r:"data.occupied",p:[19,3,439]}]}," ",{p:[25,1,680],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[26,2,712],t:7,e:"ui-section",a:{label:"Door"},f:[{p:[27,5,743],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.open"],s:'_0?"unlock":"lock"'},p:[27,22,760]}],action:"door"},f:[{t:2,x:{r:["data.open"],s:'_0?"Open":"Closed"'},p:[27,71,809]}]}]}," ",{p:[29,3,874],t:7,e:"ui-section",a:{label:"Uses"},f:[{t:2,r:"data.ready_implants",p:[30,5,905]}," ",{t:4,f:[{p:[32,7,969],t:7,e:"span",a:{"class":"fa fa-cog fa-spin"}}],n:50,r:"data.replenishing",p:[31,5,936]}]}," ",{p:[35,3,1036],t:7,e:"ui-section",a:{label:"Activate"},f:[{p:[36,7,1073],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.occupied","data.ready_implants","data.ready"],s:'_0&&_1>0&&_2?null:"disabled"'},p:[36,25,1091]}],action:"implant"},f:[{t:2,x:{r:["data.ready","data.special_name"],s:'_0?(_1?_1:"Implant"):"Recharging"'},p:[37,9,1198]}," "]},{p:[38,19,1302],t:7,e:"br"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],262:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{healthState:function(){var t=this.get("data.health");return t>70?"good":t>50?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[15,3,296],t:7,e:"ui-notice",f:[{p:[16,5,313],t:7,e:"span",f:["Wipe in progress!"]}]}],n:50,r:"data.wiping",p:[14,1,273]},{p:{button:[{t:4,f:[{p:[22,7,479],t:7,e:"ui-button",a:{icon:"trash",state:[{t:2,x:{r:["data.isDead"],s:'_0?"disabled":null'},p:[22,38,510]}],action:"wipe"},f:[{t:2,x:{r:["data.wiping"],s:'_0?"Stop Wiping":"Wipe"'},p:[22,89,561]}," AI"]}],n:50,r:"data.name",p:[21,5,454]}]},t:7,e:"ui-display",a:{title:[{t:2,x:{r:["data.name"],s:'_0||"Empty Card"'},p:[19,19,388]}],button:0},f:[" ",{t:4,f:[{p:[26,5,672],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[27,9,709],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.isDead","data.isBraindead"],s:'_0||_1?"bad":"good"'},p:[27,22,722]}]},f:[{t:2,x:{r:["data.isDead","data.isBraindead"],s:'_0||_1?"Offline":"Operational"'},p:[27,76,776]}]}]}," ",{p:[29,5,871],t:7,e:"ui-section",a:{label:"Software Integrity"},f:[{p:[30,7,918],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.health",p:[30,40,951]}],state:[{t:2,r:"healthState",p:[30,64,975]}]},f:[{t:2,x:{r:["adata.health"],s:"Math.round(_0)"},p:[30,81,992]},"%"]}]}," ",{p:[32,5,1055],t:7,e:"ui-section",a:{label:"Laws"},f:[{t:4,f:[{p:[34,9,1117],t:7,e:"span",a:{"class":"highlight"},f:[{t:2,r:".",p:[34,33,1141]}]},{p:[34,45,1153],t:7,e:"br"}],n:52,r:"data.laws",p:[33,7,1088]}]}," ",{p:[37,5,1200],t:7,e:"ui-section",a:{label:"Settings"},f:[{p:[38,7,1237],t:7,e:"ui-button",a:{icon:"signal",style:[{t:2,x:{r:["data.wireless"],s:'_0?"selected":null'},p:[38,39,1269]}],action:"wireless"},f:["Wireless Activity"]}," ",{p:[39,7,1363],t:7,e:"ui-button",a:{icon:"microphone",style:[{t:2,x:{r:["data.radio"],s:'_0?"selected":null'},p:[39,43,1399]}],action:"radio"},f:["Subspace Radio"]}]}],n:50,r:"data.name",p:[25,3,649]}]}]},e.exports=a.extend(r.exports)},{205:205}],263:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,23],t:7,e:"ui-notice",f:[{p:[3,3,38],t:7,e:"span",f:["Waiting for another device to confirm your request..."]}]}],n:50,r:"data.waiting",p:[1,1,0]},{t:4,n:51,f:[{p:[6,2,132],t:7,e:"ui-display",f:[{p:[7,3,148],t:7,e:"ui-section",f:[{t:4,f:[{p:[9,5,197],t:7,e:"ui-button",a:{icon:"check",action:"auth_swipe"},f:["Authorize ",{t:2,r:"data.auth_required",p:[9,59,251]}]}],n:50,r:"data.auth_required",p:[8,4,165]},{t:4,n:51,f:[{p:[11,5,304],t:7,e:"ui-button",a:{icon:"warning",state:[{t:2,x:{r:["data.red_alert"],s:'_0?"disabled":null'},p:[11,38,337]}],action:"red_alert"},f:["Red Alert"]}," ",{p:[12,5,423],t:7,e:"ui-button",a:{icon:"wrench",state:[{t:2,x:{r:["data.emergency_maint"],s:'_0?"disabled":null'},p:[12,37,455]}],action:"emergency_maint"},f:["Emergency Maintenance Access"]}," ",{p:[13,5,572],t:7,e:"ui-button",a:{icon:"warning",state:"null",action:"bsa_unlock"},f:["Bluespace Artillery Unlock"]}],r:"data.auth_required"}]}]}],r:"data.waiting"}]},e.exports=a.extend(r.exports)},{205:205}],264:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Ore values"},f:[{t:4,f:[{p:[3,3,57],t:7,e:"ui-section",a:{label:[{t:2,r:"ore",p:[3,22,76]}]},f:[{p:[4,4,90],t:7,e:"span",f:[{t:2,r:"value",p:[4,10,96]}]}]}],n:52,r:"data.ores",p:[2,2,34]}]}," ",{p:[8,1,158],t:7,e:"ui-display",a:{title:"Points"},f:[{p:[9,2,188],t:7,e:"ui-section",a:{label:"ID"},f:[{p:[10,3,215],t:7,e:"ui-button",a:{action:"handle_id"},f:[{t:2,x:{r:["data.id","data.id_name"],s:'_0?_1:"-------------"'},p:[10,33,245]}]}]}," ",{t:4,f:[{p:[13,3,339],t:7,e:"ui-section",a:{label:"Points collected"},f:[{p:[14,4,381],t:7,e:"span",f:[{t:2,r:"data.points",p:[14,10,387]}]}]}," ",{p:[16,3,430],t:7,e:"ui-section",a:{label:"Goal"},f:[{p:[17,4,460],t:7,e:"span",f:[{t:2,r:"data.goal",p:[17,10,466]}]}]}," ",{p:[19,3,507],t:7,e:"ui-section",a:{label:"Unclaimed points"},f:[{p:[20,4,549],t:7,e:"span",f:[{t:2,r:"data.unclaimed_points",p:[20,10,555]}]}," ",{p:[21,4,592],t:7,e:"ui-button",a:{action:"claim_points",state:[{t:2,x:{r:["data.unclaimed_points"],s:'_0?null:"disabled"'},p:[21,43,631]}]},f:["Claim points"]}]}],n:50,r:"data.id",p:[12,2,320]}]}," ",{p:[25,1,745],t:7,e:"ui-display",f:[{p:[26,2,760],t:7,e:"center",f:[{p:[27,3,772],t:7,e:"ui-button",a:{action:"move_shuttle",state:[{t:2,x:{r:["data.can_go_home"],s:'_0?null:"disabled"'},p:[27,42,811]}]},f:["Move shuttle"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],265:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Known Languages"},f:[{t:4,f:[{p:[3,5,70],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[3,23,88]}]},f:[{p:[4,7,105],t:7,e:"span",f:[{t:2,r:"desc",p:[4,13,111]}]}," ",{p:[5,7,134],t:7,e:"span",f:["Key: ,",{t:2,r:"key",p:[5,19,146]}]}," ",{t:4,f:[{p:[7,9,192],t:7,e:"span",f:["(gained from mob)"]}],n:50,r:"shadow",p:[6,7,168]}," ",{p:[9,7,245],t:7,e:"span",f:[{t:2,x:{r:["can_speak"],s:'_0?"Can Speak":"Cannot Speak"'},p:[9,13,251]}]}," ",{t:4,f:[{p:[11,9,342],t:7,e:"ui-button",a:{action:"select_default",params:['{"language_name":"',{t:2,r:"name",p:[13,37,425]},'"}'],style:[{t:2,x:{r:["is_default","can_speak"],s:'_0?"selected":_1?null:"disabled"'},p:[14,18,455]}]},f:[{t:2,x:{r:["is_default"],s:'_0?"Default Language":"Select as Default"'},p:[15,10,526]}]}],n:50,r:"data.is_living",p:[10,7,310]}," ",{t:4,f:[{t:4,f:[{p:[20,11,685],t:7,e:"ui-button",a:{action:"grant_language",params:['{"language_name":"',{t:2,r:"name",p:[20,72,746]},'"}']},f:["Grant"]}],n:50,r:"shadow",p:[19,9,659]},{t:4,n:51,f:[{p:[22,11,805],t:7,e:"ui-button",a:{action:"remove_language",params:['{"language_name":"',{t:2,r:"name",p:[22,73,867]},'"}']},f:["Remove"]}],r:"shadow"}],n:50,r:"data.admin_mode",p:[18,7,626]}]}],n:52,r:"data.languages",p:[2,3,40]}]}," ",{t:4,f:[{t:4,f:[{p:[30,5,1033],t:7,e:"ui-button",a:{action:"toggle_omnitongue",style:[{t:2,x:{r:["data.omnitongue"],s:'_0?"selected":null'},p:[32,14,1092]}]},f:["Omnitongue ",{t:2,x:{r:["data.omnitongue"],s:'_0?"Enabled":"Disabled"'},p:[33,19,1152]}]}],n:50,r:"data.is_living",p:[29,3,1005]}," ",{p:[36,3,1231],t:7,e:"ui-display",a:{title:"Unknown Languages"},f:[{t:4,f:[{p:[38,7,1315],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[38,25,1333]}]},f:[{p:[39,9,1352],t:7,e:"span",f:[{t:2,r:"desc",p:[39,15,1358]}]}," ",{p:[40,9,1383],t:7,e:"span",f:["Key: ,",{t:2,r:"key",p:[40,21,1395]}]}," ",{p:[41,9,1419],t:7,e:"ui-button",a:{action:"grant_language",params:['{"language_name":"',{t:2,r:"name",p:[43,37,1502]},'"}']},f:["Grant"]}]}],n:52,r:"data.unknown_languages",p:[37,5,1275]}]}],n:50,r:"data.admin_mode",p:[28,1,978]}]},e.exports=a.extend(r.exports)},{205:205}],266:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Controls"},f:[{t:4,f:[{t:4,f:[{p:[4,4,84],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[5,5,118],t:7,e:"span",f:["Launchpad closed."]}]}],n:50,r:"data.pad_closed",p:[3,3,56]},{t:4,n:51,f:[{p:[8,4,183],t:7,e:"ui-section",a:{label:"Launchpad"},f:[{p:[9,4,218],t:7,e:"span",f:[{p:[9,10,224],t:7,e:"b",f:[{t:2,r:"data.pad_name",p:[9,13,227]}]}]},{p:[9,41,255],t:7,e:"br"}," ",{p:[10,4,264],t:7,e:"ui-button",a:{icon:"pencil",action:"rename"},f:["Rename"]}," ",{p:[11,4,328],t:7,e:"ui-button",a:{icon:"remove",style:"danger",action:"remove"},f:["Remove"]}]}," ",{p:[14,4,427],t:7,e:"ui-section",a:{label:"Set Target"},f:[{p:[15,4,463],t:7,e:"table",f:[{p:[16,4,475],t:7,e:"tr",f:[{p:[17,5,485],t:7,e:"td",a:{style:"width:25px!important"},f:[{p:[17,38,518],t:7,e:"ui-button",a:{action:"up-left"},f:["↖"]}]}," ",{p:[18,5,570],t:7,e:"td",a:{style:"width:25px!important; text-align:center"},f:[{p:[18,57,622],t:7,e:"ui-button",a:{action:"up"},f:["↑"]}]}," ",{p:[19,5,669],t:7,e:"td",a:{style:"width:25px!important; text-align:right"},f:[{p:[19,56,720],t:7,e:"ui-button",a:{action:"up-right"},f:["↗"]}]}]}," ",{p:[21,4,782],t:7,e:"tr",f:[{p:[22,5,792],t:7,e:"td",a:{style:"width:25px!important"},f:[{p:[22,38,825],t:7,e:"ui-button",a:{action:"left",style:"width:35px!important"},f:["←"]}]}," ",{p:[23,5,903],t:7,e:"td",a:{style:"width:25px!important; text-align:center"},f:[{p:[23,57,955],t:7,e:"ui-button",a:{action:"reset"},f:["R"]}]}," ",{p:[24,5,1005],t:7,e:"td",a:{style:"width:25px!important; text-align:right"},f:[{p:[24,56,1056],t:7,e:"ui-button",a:{action:"right"},f:["→"]}]}]}," ",{p:[26,4,1115],t:7,e:"tr",f:[{p:[27,5,1125],t:7,e:"td",a:{style:"width:25px!important"},f:[{p:[27,38,1158],t:7,e:"ui-button",a:{action:"down-left"},f:["↙"]}]}," ",{p:[28,5,1212],t:7,e:"td",a:{style:"width:25px!important; text-align:center"},f:[{p:[28,57,1264],t:7,e:"ui-button",a:{action:"down"},f:["↓"]}]}," ",{p:[29,5,1313],t:7,e:"td",a:{style:"width:25px!important; text-align:right"},f:[{p:[29,56,1364],t:7,e:"ui-button",a:{action:"down-right"},f:["↘"]}]}]}]}]}," ",{p:[33,4,1459],t:7,e:"ui-section",a:{label:"Current Target"},f:[{p:[34,5,1500],t:7,e:"span",f:[{t:2,r:"data.abs_y",p:[34,11,1506]}," ",{t:2,r:"data.north_south",p:[34,26,1521]}]},{p:[34,53,1548],t:7,e:"br"}," ",{p:[35,5,1558],t:7,e:"span",f:[{t:2,r:"data.abs_x",p:[35,11,1564]}," ",{t:2,r:"data.east_west",p:[35,26,1579]}]}]}," ",{p:[37,4,1627],t:7,e:"ui-section",a:{label:"Activate"},f:[{p:[38,5,1662],t:7,e:"ui-button",a:{action:"launch",tooltip:"Teleport everything on the pad to the target.","tooltip-side":"down"},f:["Launch"]}," ",{p:[39,5,1789],t:7,e:"ui-button",a:{action:"pull",tooltip:"Teleport everything from the target to the pad.","tooltip-side":"down"},f:["Pull"]}]}],r:"data.pad_closed"}],n:50,r:"data.has_pad",p:[2,2,32]},{t:4,n:51,f:[{p:[45,3,1956],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[46,4,1989],t:7,e:"span",f:["No launchpad found. Link the remote to a launchpad."]}]}],r:"data.has_pad"}]}]},e.exports=a.extend(r.exports)},{205:205}],267:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{mechChargeState:function(t){var e=this.get("data.recharge_port.mech.cell.maxcharge");return t>=e/1.5?"good":t>=e/3?"average":"bad"},mechHealthState:function(t){var e=this.get("data.recharge_port.mech.maxhealth");return t>e/1.5?"good":t>e/3?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[20,1,545],t:7,e:"ui-display",a:{title:"Mech Status"},f:[{t:4,f:[{t:4,f:[{p:[23,4,646],t:7,e:"ui-section",a:{label:"Integrity"},f:[{p:[24,6,683],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.recharge_port.mech.maxhealth",p:[24,27,704]}],value:[{t:2,r:"adata.recharge_port.mech.health",p:[24,74,751]}],state:[{t:2,x:{r:["mechHealthState","adata.recharge_port.mech.health"],s:"_0(_1)"},p:[24,117,794]}]},f:[{t:2,x:{r:["adata.recharge_port.mech.health"],s:"Math.round(_0)"},p:[24,171,848]},"/",{t:2,r:"adata.recharge_port.mech.maxhealth",p:[24,219,896]}]}]}," ",{t:4,f:[{t:4,f:[{p:[28,5,1061],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[28,31,1087],t:7,e:"span",a:{"class":"bad"},f:["Cell Critical Failure"]}]}],n:50,r:"data.recharge_port.mech.cell.critfail",p:[27,3,1010]},{t:4,n:51,f:[{p:[30,11,1170],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[31,13,1210],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.recharge_port.mech.cell.maxcharge",p:[31,34,1231]}],value:[{t:2,r:"adata.recharge_port.mech.cell.charge",p:[31,86,1283]}],state:[{t:2,x:{r:["mechChargeState","adata.recharge_port.mech.cell.charge"],s:"_0(_1)"},p:[31,134,1331]}]},f:[{t:2,x:{r:["adata.recharge_port.mech.cell.charge"],s:"Math.round(_0)"},p:[31,193,1390]},"/",{t:2,x:{r:["adata.recharge_port.mech.cell.maxcharge"],s:"Math.round(_0)"},p:[31,246,1443]}]}]}],r:"data.recharge_port.mech.cell.critfail"}],n:50,r:"data.recharge_port.mech.cell",p:[26,4,970]},{t:4,n:51,f:[{p:[35,3,1558],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[35,29,1584],t:7,e:"span",a:{"class":"bad"},f:["Cell Missing"]}]}],r:"data.recharge_port.mech.cell"}],n:50,r:"data.recharge_port.mech",p:[22,2,610]},{t:4,n:51,f:[{p:[38,4,1662],t:7,e:"ui-section",f:["Mech Not Found"]}],r:"data.recharge_port.mech"}],n:50,r:"data.recharge_port",p:[21,3,581]},{t:4,n:51,f:[{p:[41,5,1729],t:7,e:"ui-section",f:["Recharging Port Not Found"]}," ",{p:[42,2,1782],t:7,e:"ui-button",a:{icon:"refresh",action:"reconnect"},f:["Reconnect"]}],r:"data.recharge_port"}]}]},e.exports=a.extend(r.exports)},{205:205}],268:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{t:4,f:[{p:[3,5,45],t:7,e:"ui-section",a:{label:"Interface Lock"},f:[{p:[4,7,88],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"lock":"unlock"'},p:[4,24,105]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Engaged":"Disengaged"'},p:[4,75,156]}]}]}],n:50,r:"data.siliconUser",p:[2,3,15]},{t:4,n:51,f:[{p:[7,5,247],t:7,e:"span",f:["Swipe an ID card to ",{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[7,31,273]}," this interface."]}],r:"data.siliconUser"}]}," ",{p:[10,1,358],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[11,3,389],t:7,e:"ui-section",a:{label:"Power"},f:[{t:4,f:[{p:[13,7,470],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[13,24,487]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[13,68,531]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[13,116,579]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"},p:[12,5,421]},{t:4,n:51,f:[{p:[15,7,639],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.on"],s:'_0?"good":"bad"'},p:[15,20,652]}],state:[{t:2,x:{r:["data.cell"],s:'_0?null:"disabled"'},p:[15,57,689]}]},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[15,92,724]}]}],x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"}}]}," ",{p:[18,3,791],t:7,e:"ui-section",a:{label:"Cell"},f:[{p:[19,5,822],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.cell"],s:'_0?null:"bad"'},p:[19,18,835]}]},f:[{t:2,x:{r:["data.cell","data.cellPercent"],s:'_0?_1+"%":"No Cell"'},p:[19,48,865]}]}]}," ",{p:[21,3,943],t:7,e:"ui-section",a:{label:"Mode"},f:[{p:[22,5,974],t:7,e:"span",a:{"class":[{t:2,r:"data.modeStatus",p:[22,18,987]}]},f:[{t:2,r:"data.mode",p:[22,39,1008]}]}]}," ",{p:[24,3,1049],t:7,e:"ui-section",a:{label:"Load"},f:[{p:[25,5,1080],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.load"],s:'_0?"good":"average"'},p:[25,18,1093]}]},f:[{t:2,x:{r:["data.load"],s:'_0?_0:"None"'},p:[25,54,1129]}]}]}," ",{p:[27,3,1191],t:7,e:"ui-section",a:{label:"Destination"},f:[{p:[28,5,1229],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.destination"],s:'_0?"good":"average"'},p:[28,18,1242]}]},f:[{t:2,x:{r:["data.destination"],s:'_0?_0:"None"'},p:[28,60,1284]}]}]}]}," ",{t:4,f:[{p:{button:[{t:4,f:[{p:[35,9,1513],t:7,e:"ui-button",a:{icon:"eject",action:"unload"},f:["Unload"]}],n:50,r:"data.load",p:[34,7,1486]}," ",{t:4,f:[{p:[38,9,1623],t:7,e:"ui-button",a:{icon:"eject",action:"ejectpai"},f:["Eject PAI"]}],n:50,r:"data.haspai",p:[37,7,1594]}," ",{p:[40,7,1709],t:7,e:"ui-button",a:{icon:"pencil",action:"setid"},f:["Set ID"]}]},t:7,e:"ui-display",a:{title:"Controls",button:0},f:[" ",{p:[42,5,1791],t:7,e:"ui-section",a:{label:"Destination"},f:[{p:[43,7,1831],t:7,e:"ui-button",a:{icon:"pencil",action:"destination"},f:["Set Destination"]}," ",{p:[44,7,1912],t:7,e:"ui-button",a:{icon:"stop",action:"stop"},f:["Stop"]}," ",{p:[45,7,1973],t:7,e:"ui-button",a:{icon:"play",action:"go"},f:["Go"]}]}," ",{p:[47,5,2047],t:7,e:"ui-section",a:{label:"Home"},f:[{p:[48,7,2080],t:7,e:"ui-button",a:{icon:"home",action:"home"},f:["Go Home"]}," ",{p:[49,7,2144],t:7,e:"ui-button",a:{icon:"pencil",action:"sethome"},f:["Set Home"]}]}," ",{p:[51,5,2231],t:7,e:"ui-section",a:{label:"Settings"},f:[{p:[52,7,2268],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.autoReturn"],s:'_0?"check-square-o":"square-o"'},p:[52,24,2285]}],style:[{t:2,x:{r:["data.autoReturn"],s:'_0?"selected":null'},p:[52,84,2345]}],action:"autoret"},f:["Auto-Return Home"]}," ",{p:[54,7,2449],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.autoPickup"],s:'_0?"check-square-o":"square-o"'},p:[54,24,2466]}],style:[{t:2,x:{r:["data.autoPickup"],s:'_0?"selected":null'},p:[54,84,2526]}],action:"autopick"},f:["Auto-Pickup Crate"]}," ",{p:[56,7,2632],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.reportDelivery"],s:'_0?"check-square-o":"square-o"'},p:[56,24,2649]}],style:[{t:2,x:{r:["data.reportDelivery"],s:'_0?"selected":null'},p:[56,88,2713]}],action:"report"},f:["Report Deliveries"]}]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"},p:[31,1,1373]}]},e.exports=a.extend(r.exports)},{205:205}],269:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Relay"},f:[{t:4,f:[{p:[3,3,57],t:7,e:"h2",f:["NETWORK BUFFERS OVERLOADED"]}," ",{p:[4,3,96],t:7,e:"h3",f:["Overload Recovery Mode"]}," ",{p:[5,3,131],t:7,e:"i",f:["This system is suffering temporary outage due to overflow of traffic buffers. Until buffered traffic is processed, all further requests will be dropped. Frequent occurences of this error may indicate insufficient hardware capacity of your network. Please contact your network planning department for instructions on how to resolve this issue."]}," ",{p:[6,3,484],t:7,e:"h3",f:["ADMINISTRATIVE OVERRIDE"]}," ",{p:[7,3,520],t:7,e:"b",f:["CAUTION - Data loss may occur"]}," ",{p:[8,3,562],t:7,e:"ui-button",a:{icon:"signal",action:"restart"},f:["Purge buffered traffic"]}],n:50,r:"data.dos_crashed",p:[2,2,29]},{t:4,n:51,f:[{p:[12,3,663],t:7,e:"ui-section", +a:{label:"Relay status"},f:[{p:[13,4,701],t:7,e:"ui-button",a:{icon:"power-off",action:"toggle"},f:[{t:2,x:{r:["data.enabled"],s:'_0?"ENABLED":"DISABLED"'},p:[14,6,752]}]}]}," ",{p:[18,3,836],t:7,e:"ui-section",a:{label:"Network buffer status"},f:[{t:2,r:"data.dos_overload",p:[19,4,883]}," / ",{t:2,r:"data.dos_capacity",p:[19,28,907]}," GQ"]}],r:"data.dos_crashed"}]}]},e.exports=a.extend(r.exports)},{205:205}],270:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{healthState:function(){var t=this.get("data.health");return t>70?"good":t>50?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[15,1,320],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[18,3,363],t:7,e:"ui-notice",f:[{p:[19,5,380],t:7,e:"span",f:["Reconstruction in progress!"]}]}],n:50,r:"data.restoring",p:[17,1,337]},{p:[24,1,451],t:7,e:"ui-display",f:[{p:[26,1,467],t:7,e:"div",a:{"class":"item"},f:[{p:[27,3,489],t:7,e:"div",a:{"class":"itemLabel"},f:["Inserted AI:"]}," ",{p:[30,3,541],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[31,2,569],t:7,e:"ui-button",a:{icon:"eject",action:"PRG_eject",state:[{t:2,x:{r:["data.nocard"],s:'_0?"disabled":null'},p:[31,52,619]}]},f:[{t:2,x:{r:["data.name"],s:'_0?_0:"---"'},p:[31,89,656]}]}]}]}," ",{t:4,f:[{p:[36,2,744],t:7,e:"b",f:["ERROR: ",{t:2,r:"data.error",p:[36,12,754]}]}],n:50,r:"data.error",p:[35,1,723]},{t:4,n:51,f:[{p:[38,2,785],t:7,e:"h2",f:["System Status"]}," ",{p:[39,2,810],t:7,e:"div",a:{"class":"item"},f:[{p:[40,3,832],t:7,e:"div",a:{"class":"itemLabel"},f:["Current AI:"]}," ",{p:[43,3,885],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.name",p:[44,4,915]}]}," ",{p:[46,3,942],t:7,e:"div",a:{"class":"itemLabel"},f:["Status:"]}," ",{p:[49,3,991],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:["Nonfunctional"],n:50,r:"data.isDead",p:[50,4,1021]},{t:4,n:51,f:["Functional"],r:"data.isDead"}]}," ",{p:[56,3,1114],t:7,e:"div",a:{"class":"itemLabel"},f:["System Integrity:"]}," ",{p:[59,3,1173],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[60,4,1203],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.health",p:[60,37,1236]}],state:[{t:2,r:"healthState",p:[61,11,1264]}]},f:[{t:2,x:{r:["adata.health"],s:"Math.round(_0)"},p:[61,28,1281]},"%"]}]}," ",{p:[63,3,1336],t:7,e:"div",a:{"class":"itemLabel"},f:["Active Laws:"]}," ",{p:[66,3,1390],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[67,4,1420],t:7,e:"table",f:[{t:4,f:[{p:[69,6,1462],t:7,e:"tr",f:[{p:[69,10,1466],t:7,e:"td",f:[{p:[69,14,1470],t:7,e:"span",a:{"class":"highlight"},f:[{t:2,r:".",p:[69,38,1494]}]}]}]}],n:52,r:"data.ai_laws",p:[68,5,1433]}]}]}," ",{p:[73,2,1547],t:7,e:"ui-section",a:{label:"Operations"},f:[{p:[74,3,1582],t:7,e:"ui-button",a:{icon:"plus",style:[{t:2,x:{r:["data.restoring"],s:'_0?"disabled":null'},p:[74,33,1612]}],action:"PRG_beginReconstruction"},f:["Begin Reconstruction"]}]}]}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],271:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[5,1,91],t:7,e:"ui-button",a:{action:"PRG_switchm",icon:"home",params:'{"target" : "mod"}',state:[{t:2,x:{r:["data.mmode"],s:'_0==1?"disabled":null'},p:[5,80,170]}]},f:["Access Modification"]}],n:50,r:"data.have_id_slot",p:[4,1,64]},{p:[7,1,253],t:7,e:"ui-button",a:{action:"PRG_switchm",icon:"folder-open",params:'{"target" : "manage"}',state:[{t:2,x:{r:["data.mmode"],s:'_0==2?"disabled":null'},p:[7,90,342]}]},f:["Job Management"]}," ",{p:[8,1,411],t:7,e:"ui-button",a:{action:"PRG_switchm",icon:"folder-open",params:'{"target" : "manifest"}',state:[{t:2,x:{r:["data.mmode"],s:'!_0?"disabled":null'},p:[8,92,502]}]},f:["Crew Manifest"]}," ",{t:4,f:[{p:[10,1,593],t:7,e:"ui-button",a:{action:"PRG_print",icon:"print",state:[{t:2,x:{r:["data.has_id","data.mmode"],s:'!_1||_0&&_1==1?null:"disabled"'},p:[10,51,643]}]},f:["Print"]}],n:50,r:"data.have_printer",p:[9,1,566]},{t:4,f:[{p:[14,1,766],t:7,e:"div",a:{"class":"item"},f:[{p:[15,3,788],t:7,e:"h2",f:["Crew Manifest"]}," ",{p:[16,3,814],t:7,e:"br"},"Please use security record computer to modify entries.",{p:[16,61,872],t:7,e:"br"},{p:[16,65,876],t:7,e:"br"}]}," ",{t:4,f:[{p:[19,2,916],t:7,e:"div",a:{"class":"item"},f:[{t:2,r:"name",p:[20,2,937]}," - ",{t:2,r:"rank",p:[20,13,948]}]}],n:52,r:"data.manifest",p:[18,1,890]}],n:50,x:{r:["data.mmode"],s:"!_0"},p:[13,1,745]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.mmode"],s:"_0==2"},f:[{p:[25,1,1008],t:7,e:"div",a:{"class":"item"},f:[{p:[26,3,1030],t:7,e:"h2",f:["Job Management"]}]}," ",{p:[28,1,1063],t:7,e:"table",f:[{p:[29,1,1072],t:7,e:"tr",f:[{p:[29,5,1076],t:7,e:"td",a:{style:"width:25%"},f:[{p:[29,27,1098],t:7,e:"b",f:["Job"]}]},{p:[29,42,1113],t:7,e:"td",a:{style:"width:25%"},f:[{p:[29,64,1135],t:7,e:"b",f:["Slots"]}]},{p:[29,81,1152],t:7,e:"td",a:{style:"width:25%"},f:[{p:[29,103,1174],t:7,e:"b",f:["Open job"]}]},{p:[29,123,1194],t:7,e:"td",a:{style:"width:25%"},f:[{p:[29,145,1216],t:7,e:"b",f:["Close job"]}]}]}," ",{t:4,f:[{p:[32,2,1269],t:7,e:"tr",f:[{p:[32,6,1273],t:7,e:"td",f:[{t:2,r:"title",p:[32,10,1277]}]},{p:[32,24,1291],t:7,e:"td",f:[{t:2,r:"current",p:[32,28,1295]},"/",{t:2,r:"total",p:[32,40,1307]}]},{p:[32,54,1321],t:7,e:"td",f:[{p:[32,58,1325],t:7,e:"ui-button",a:{action:"PRG_open_job",params:['{"target" : "',{t:2,r:"title",p:[32,112,1379]},'"}'],state:[{t:2,x:{r:["status_open"],s:'_0?null:"disabled"'},p:[32,132,1399]}]},f:[{t:2,r:"desc_open",p:[32,169,1436]}]},{p:[32,194,1461],t:7,e:"br"}]},{p:[32,203,1470],t:7,e:"td",f:[{p:[32,207,1474],t:7,e:"ui-button",a:{action:"PRG_close_job",params:['{"target" : "',{t:2,r:"title",p:[32,262,1529]},'"}'],state:[{t:2,x:{r:["status_close"],s:'_0?null:"disabled"'},p:[32,282,1549]}]},f:[{t:2,r:"desc_close",p:[32,320,1587]}]}]}]}],n:52,r:"data.slots",p:[30,1,1244]}]}]},{t:4,n:50,x:{r:["data.mmode"],s:"!(_0==2)"},f:[" ",{p:[40,1,1665],t:7,e:"div",a:{"class":"item"},f:[{p:[41,3,1687],t:7,e:"h2",f:["Access Modification"]}]}," ",{t:4,f:[{p:[45,3,1751],t:7,e:"span",a:{"class":"alert"},f:[{p:[45,23,1771],t:7,e:"i",f:["Please insert the ID into the terminal to proceed."]}]},{p:[45,87,1835],t:7,e:"br"}],n:50,x:{r:["data.has_id"],s:"!_0"},p:[44,1,1727]},{p:[48,1,1852],t:7,e:"div",a:{"class":"item"},f:[{p:[49,3,1874],t:7,e:"div",a:{"class":"itemLabel"},f:["Target Identity:"]}," ",{p:[52,3,1930],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[53,2,1958],t:7,e:"ui-button",a:{icon:"eject",action:"PRG_eject",params:'{"target" : "id"}'},f:[{t:2,r:"data.id_name",p:[53,72,2028]}]}]}]}," ",{p:[56,1,2076],t:7,e:"div",a:{"class":"item"},f:[{p:[57,3,2098],t:7,e:"div",a:{"class":"itemLabel"},f:["Auth Identity:"]}," ",{p:[60,3,2152],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[61,2,2180],t:7,e:"ui-button",a:{icon:"eject",action:"PRG_eject",params:'{"target" : "auth"}'},f:[{t:2,r:"data.auth_name",p:[61,74,2252]}]}]}]}," ",{p:[64,1,2302],t:7,e:"hr"}," ",{t:4,f:[{t:4,f:[{p:[68,2,2362],t:7,e:"div",a:{"class":"item"},f:[{p:[69,4,2385],t:7,e:"h2",f:["Details"]}]}," ",{t:4,f:[{p:[73,2,2436],t:7,e:"div",a:{"class":"item"},f:[{p:[74,4,2459],t:7,e:"div",a:{"class":"itemLabel"},f:["Registered Name:"]}," ",{p:[77,4,2518],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.id_owner",p:[78,3,2547]}]}]}," ",{p:[81,2,2587],t:7,e:"div",a:{"class":"item"},f:[{p:[82,4,2610],t:7,e:"div",a:{"class":"itemLabel"},f:["Rank:"]}," ",{p:[85,4,2658],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.id_rank",p:[86,3,2687]}]}]}," ",{p:[89,2,2726],t:7,e:"div",a:{"class":"item"},f:[{p:[90,4,2749],t:7,e:"div",a:{"class":"itemLabel"},f:["Demote:"]}," ",{p:[93,4,2799],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[94,3,2828],t:7,e:"ui-button",a:{action:"PRG_terminate",icon:"gear",state:[{t:2,x:{r:["data.id_rank"],s:'_0=="Unassigned"?"disabled":null'},p:[94,56,2881]}]},f:["Demote ",{t:2,r:"data.id_owner",p:[94,117,2942]}]}]}]}],n:50,r:"data.minor",p:[72,2,2415]},{t:4,n:51,f:[{p:[99,2,3007],t:7,e:"div",a:{"class":"item"},f:[{p:[100,4,3030],t:7,e:"div",a:{"class":"itemLabel"},f:["Registered Name:"]}," ",{p:[103,4,3089],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[104,3,3118],t:7,e:"ui-button",a:{action:"PRG_edit",icon:"pencil",params:'{"name" : "1"}'},f:[{t:2,r:"data.id_owner",p:[104,70,3185]}]}]}]}," ",{p:[108,2,3239],t:7,e:"div",a:{"class":"item"},f:[{p:[109,4,3262],t:7,e:"h2",f:["Assignment"]}]}," ",{p:[111,3,3294],t:7,e:"ui-button",a:{action:"PRG_togglea",icon:"gear"},f:[{t:2,x:{r:["data.assignments"],s:'_0?"Hide assignments":"Show assignments"'},p:[111,47,3338]}]}," ",{p:[112,2,3415],t:7,e:"div",a:{"class":"item"},f:[{p:[113,4,3438],t:7,e:"span",a:{id:"allvalue.jobsslot"},f:[]}]}," ",{p:[117,2,3495],t:7,e:"div",a:{"class":"item"},f:[{t:4,f:[{p:[119,4,3547],t:7,e:"div",a:{id:"all-value.jobs"},f:[{p:[120,3,3576],t:7,e:"table",f:[{p:[121,5,3589],t:7,e:"tr",f:[{p:[122,4,3598],t:7,e:"th",f:["Command"]}," ",{p:[123,4,3619],t:7,e:"td",f:[{p:[124,6,3630],t:7,e:"ui-button",a:{action:"PRG_assign",params:'{"assign_target" : "Captain"}',state:[{t:2,x:{r:["data.id_rank"],s:'_0=="Captain"?"selected":null'},p:[124,83,3707]}]},f:["Captain"]}]}]}," ",{p:[127,5,3804],t:7,e:"tr",f:[{p:[128,4,3813],t:7,e:"th",f:["Special"]}," ",{p:[129,4,3834],t:7,e:"td",f:[{p:[130,6,3845],t:7,e:"ui-button",a:{action:"PRG_assign",params:'{"assign_target" : "Custom"}'},f:["Custom"]}]}]}," ",{p:[133,5,3959],t:7,e:"tr",f:[{p:[134,4,3968],t:7,e:"th",a:{style:"color: '#FFA500';"},f:["Engineering"]}," ",{p:[135,4,4019],t:7,e:"td",f:[{t:4,f:[{p:[137,5,4067],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[137,64,4126]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[137,82,4144]}]},f:[{t:2,r:"display_name",p:[137,127,4189]}]}],n:52,r:"data.engineering_jobs",p:[136,6,4030]}]}]}," ",{p:[141,5,4260],t:7,e:"tr",f:[{p:[142,4,4269],t:7,e:"th",a:{style:"color: '#008000';"},f:["Medical"]}," ",{p:[143,4,4316],t:7,e:"td",f:[{t:4,f:[{p:[145,5,4360],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[145,64,4419]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[145,82,4437]}]},f:[{t:2,r:"display_name",p:[145,127,4482]}]}],n:52,r:"data.medical_jobs",p:[144,6,4327]}]}]}," ",{p:[149,5,4553],t:7,e:"tr",f:[{p:[150,4,4562],t:7,e:"th",a:{style:"color: '#800080';"},f:["Science"]}," ",{p:[151,4,4609],t:7,e:"td",f:[{t:4,f:[{p:[153,5,4653],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[153,64,4712]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[153,82,4730]}]},f:[{t:2,r:"display_name",p:[153,127,4775]}]}],n:52,r:"data.science_jobs",p:[152,6,4620]}]}]}," ",{p:[157,5,4846],t:7,e:"tr",f:[{p:[158,4,4855],t:7,e:"th",a:{style:"color: '#DD0000';"},f:["Security"]}," ",{p:[159,4,4903],t:7,e:"td",f:[{t:4,f:[{p:[161,5,4948],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[161,64,5007]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[161,82,5025]}]},f:[{t:2,r:"display_name",p:[161,127,5070]}]}],n:52,r:"data.security_jobs",p:[160,6,4914]}]}]}," ",{p:[165,5,5141],t:7,e:"tr",f:[{p:[166,4,5150],t:7,e:"th",a:{style:"color: '#cc6600';"},f:["Cargo"]}," ",{p:[167,4,5195],t:7,e:"td",f:[{t:4,f:[{p:[169,5,5237],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[169,64,5296]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[169,82,5314]}]},f:[{t:2,r:"display_name",p:[169,127,5359]}]}],n:52,r:"data.cargo_jobs",p:[168,6,5206]}]}]}," ",{p:[173,5,5430],t:7,e:"tr",f:[{p:[174,4,5439],t:7,e:"th",a:{style:"color: '#808080';"},f:["Civilian"]}," ",{p:[175,4,5487],t:7,e:"td",f:[{t:4,f:[{p:[177,5,5532],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[177,64,5591]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[177,82,5609]}]},f:[{t:2,r:"display_name",p:[177,127,5654]}]}],n:52,r:"data.civilian_jobs",p:[176,6,5498]}]}]}," ",{t:4,f:[{p:[182,4,5757],t:7,e:"tr",f:[{p:[183,6,5768],t:7,e:"th",a:{style:"color: '#A52A2A';"},f:["CentCom"]}," ",{p:[184,6,5817],t:7,e:"td",f:[{t:4,f:[{p:[186,7,5862],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[186,66,5921]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[186,84,5939]}]},f:[{t:2,r:"display_name",p:[186,129,5984]}]}],n:52,r:"data.centcom_jobs",p:[185,5,5827]}]}]}],n:50,r:"data.centcom_access",p:[181,5,5725]}]}]}],n:50,r:"data.assignments",p:[118,4,3518]}]}],r:"data.minor"}," ",{t:4,f:[{p:[198,4,6153],t:7,e:"div",a:{"class":"item"},f:[{p:[199,3,6175],t:7,e:"h2",f:["Central Command"]}]}," ",{p:[201,4,6215],t:7,e:"div",a:{"class":"item",style:"width: 100%"},f:[{t:4,f:[{p:[203,5,6296],t:7,e:"div",a:{"class":"itemContentWide"},f:[{p:[204,5,6331],t:7,e:"ui-button",a:{action:"PRG_access",params:['{"access_target" : "',{t:2,r:"ref",p:[204,64,6390]},'", "allowed" : "',{t:2,r:"allowed",p:[204,87,6413]},'"}'],state:[{t:2,x:{r:["allowed"],s:'_0?"toggle":null'},p:[204,109,6435]}]},f:[{t:2,r:"desc",p:[204,140,6466]}]}]}],n:52,r:"data.all_centcom_access",p:[202,3,6257]}]}],n:50,r:"data.centcom_access",p:[197,2,6121]},{t:4,n:51,f:[{p:[209,4,6538],t:7,e:"div",a:{"class":"item"},f:[{p:[210,3,6560],t:7,e:"h2",f:[{t:2,r:"data.station_name",p:[210,7,6564]}]}]}," ",{p:[212,4,6606],t:7,e:"div",a:{"class":"item",style:"width: 100%"},f:[{t:4,f:[{p:[214,5,6676],t:7,e:"div",a:{style:"float: left; width: 175px; min-height: 250px"},f:[{p:[215,4,6739],t:7,e:"div",a:{"class":"average"},f:[{p:[215,25,6760],t:7,e:"ui-button",a:{action:"PRG_regsel",state:[{t:2,x:{r:["selected"],s:'_0?"toggle":null'},p:[215,63,6798]}],params:['{"region" : "',{t:2,r:"regid",p:[215,116,6851]},'"}']},f:[{p:[215,129,6864],t:7,e:"b",f:[{t:2,r:"name",p:[215,132,6867]}]}]}]}," ",{p:[216,4,6902],t:7,e:"br"}," ",{t:4,f:[{p:[218,6,6938],t:7,e:"div",a:{"class":"itemContentWide"},f:[{p:[219,5,6973],t:7,e:"ui-button",a:{action:"PRG_access",params:['{"access_target" : "',{t:2,r:"ref",p:[219,64,7032]},'", "allowed" : "',{t:2,r:"allowed",p:[219,87,7055]},'"}'],state:[{t:2,x:{r:["allowed"],s:'_0?"toggle":null'},p:[219,109,7077]}]},f:[{t:2,r:"desc",p:[219,140,7108]}]}]}],n:52,r:"accesses",p:[217,6,6913]}]}],n:52,r:"data.regions",p:[213,3,6648]}]}],r:"data.centcom_access"}],n:50,r:"data.has_id",p:[67,3,2340]}],n:50,r:"data.authenticated",p:[66,1,2310]}]}],x:{r:["data.mmode"],s:"!_0"}}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],272:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{chargeState:function(t){var e=this.get("data.battery.max");return t>e/2?"good":t>e/4?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[15,1,311],t:7,e:"ntosheader"}," ",{p:[17,1,328],t:7,e:"ui-display",f:[{p:[18,2,343],t:7,e:"i",f:["Welcome to computer configuration utility. Please consult your system administrator if you have any questions about your device."]},{p:[18,137,478],t:7,e:"hr"}," ",{p:[19,2,485],t:7,e:"ui-display",a:{title:"Power Supply"},f:[{p:[20,3,522],t:7,e:"ui-section",a:{label:"Power Usage"},f:[{t:2,r:"data.power_usage",p:[21,4,559]},"W"]}," ",{t:4,f:[{p:[25,4,630],t:7,e:"ui-section",a:{label:"Battery Status"},f:["Active"]}," ",{p:[28,4,701],t:7,e:"ui-section",a:{label:"Battery Rating"},f:[{t:2,r:"data.battery.max",p:[29,5,742]}]}," ",{p:[31,4,785],t:7,e:"ui-section",a:{label:"Battery Charge"},f:[{p:[32,5,826],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.battery.max",p:[32,26,847]}],value:[{t:2,r:"adata.battery.charge",p:[32,56,877]}],state:[{t:2,x:{r:["chargeState","adata.battery.charge"],s:"_0(_1)"},p:[32,89,910]}]},f:[{t:2,x:{r:["adata.battery.charge"],s:"Math.round(_0)"},p:[32,128,949]},"/",{t:2,r:"adata.battery.max",p:[32,165,986]}]}]}],n:50,r:"data.battery",p:[24,3,605]},{t:4,n:51,f:[{p:[35,4,1051],t:7,e:"ui-section",a:{label:"Battery Status"},f:["Not Available"]}],r:"data.battery"}]}," ",{p:[41,2,1156],t:7,e:"ui-display",a:{title:"File System"},f:[{p:[42,3,1192],t:7,e:"ui-section",a:{label:"Used Capacity"},f:[{p:[43,4,1231],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.disk_size",p:[43,25,1252]}],value:[{t:2,r:"adata.disk_used",p:[43,53,1280]}],state:"good"},f:[{t:2,x:{r:["adata.disk_used"],s:"Math.round(_0)"},p:[43,87,1314]},"GQ / ",{t:2,r:"adata.disk_size",p:[43,123,1350]},"GQ"]}]}]}," ",{p:[47,2,1419],t:7,e:"ui-display",a:{title:"Computer Components"},f:[{t:4,f:[{p:[49,4,1491],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"name",p:[49,26,1513]}]},f:[{p:[50,5,1529],t:7,e:"div",a:{style:"display: table-caption; margin-left: 3px"},f:[{t:2,r:"desc",p:[50,59,1583]}]}," ",{p:[52,5,1605],t:7,e:"ui-section",a:{label:"State"},f:[{p:[53,6,1638],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["critical"],s:'_0?"disabled":null'},p:[53,24,1656]}],action:"PC_toggle_component",params:['{"name": "',{t:2,r:"name",p:[53,105,1737]},'"}']},f:[{t:2,x:{r:["enabled"],s:'_0?"Enabled":"Disabled"'},p:[54,7,1757]}]}]}," ",{t:4,f:[{p:[59,6,1868],t:7,e:"ui-section",a:{label:"Power Usage"},f:[{t:2,r:"powerusage",p:[60,7,1908]},"W"]}],n:50,r:"powerusage",p:[58,5,1843]}]}," ",{p:[64,4,1985],t:7,e:"br"}],n:52,r:"data.hardware",p:[48,3,1463]}]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],273:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:[{p:[7,3,103],t:7,e:"h2",f:["An error has occurred and this program can not continue."]}," Additional information: ",{t:2,r:"data.error",p:[8,27,196]},{p:[8,41,210],t:7,e:"br"}," ",{p:[9,3,218],t:7,e:"i",f:["Please try again. If the problem persists contact your system administrator for assistance."]}," ",{p:[10,3,320],t:7,e:"ui-button",a:{action:"PRG_closefile"},f:["Restart program"]}],n:50,r:"data.error",p:[6,2,81]},{t:4,n:51,f:[{t:4,f:[{p:[13,4,422],t:7,e:"h2",f:["Viewing file ",{t:2,r:"data.filename",p:[13,21,439]}]}," ",{p:[14,4,466],t:7,e:"div",a:{"class":"item"},f:[{p:[15,4,489],t:7,e:"ui-button",a:{action:"PRG_closefile"},f:["CLOSE"]}," ",{p:[16,4,545],t:7,e:"ui-button",a:{action:"PRG_edit"},f:["EDIT"]}," ",{p:[17,4,595],t:7,e:"ui-button",a:{action:"PRG_printfile"},f:["PRINT"]}," "]},{p:[18,10,657],t:7,e:"hr"}," ",{t:3,r:"data.filedata",p:[19,4,666]}],n:50,r:"data.filename",p:[12,3,396]},{t:4,n:51,f:[{p:[21,4,702],t:7,e:"h2",f:["Available files (local):"]}," ",{p:[22,4,740],t:7,e:"table",f:[{p:[23,5,753],t:7,e:"tr",f:[{p:[24,6,764],t:7,e:"th",f:["File name"]}," ",{p:[25,6,789],t:7,e:"th",f:["File type"]}," ",{p:[26,6,814],t:7,e:"th",f:["File size (GQ)"]}," ",{p:[27,6,844],t:7,e:"th",f:["Operations"]}]}," ",{t:4,f:[{p:[30,6,907],t:7,e:"tr",f:[{p:[31,7,919],t:7,e:"td",f:[{t:2,r:"name",p:[31,11,923]}]}," ",{p:[32,7,944],t:7,e:"td",f:[".",{t:2,r:"type",p:[32,12,949]}]}," ",{p:[33,7,970],t:7,e:"td",f:[{t:2,r:"size",p:[33,11,974]},"GQ"]}," ",{p:[34,7,997],t:7,e:"td",f:[{p:[35,8,1010],t:7,e:"ui-button",a:{action:"PRG_openfile",params:['{"name": "',{t:2,r:"name",p:[35,59,1061]},'"}']},f:["VIEW"]}," ",{p:[36,8,1098],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[36,26,1116]}],action:"PRG_deletefile",params:['{"name": "',{t:2,r:"name",p:[36,105,1195]},'"}']},f:["DELETE"]}," ",{p:[37,8,1234],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[37,26,1252]}],action:"PRG_rename",params:['{"name": "',{t:2,r:"name",p:[37,101,1327]},'"}']},f:["RENAME"]}," ",{p:[38,8,1366],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[38,26,1384]}],action:"PRG_clone",params:['{"name": "',{t:2,r:"name",p:[38,100,1458]},'"}']},f:["CLONE"]}," ",{t:4,f:[{p:[40,9,1531],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[40,27,1549]}],action:"PRG_copytousb",params:['{"name": "',{t:2,r:"name",p:[40,105,1627]},'"}']},f:["EXPORT"]}],n:50,r:"data.usbconnected",p:[39,8,1496]}]}]}],n:52,r:"data.files",p:[29,5,880]}]}," ",{t:4,f:[{p:[47,4,1761],t:7,e:"h2",f:["Available files (portable device):"]}," ",{p:[48,4,1809],t:7,e:"table",f:[{p:[49,5,1822],t:7,e:"tr",f:[{p:[50,6,1833],t:7,e:"th",f:["File name"]}," ",{p:[51,6,1858],t:7,e:"th",f:["File type"]}," ",{p:[52,6,1883],t:7,e:"th",f:["File size (GQ)"]}," ",{p:[53,6,1913],t:7,e:"th",f:["Operations"]}]}," ",{t:4,f:[{p:[56,6,1979],t:7,e:"tr",f:[{p:[57,7,1991],t:7,e:"td",f:[{t:2,r:"name",p:[57,11,1995]}]}," ",{p:[58,7,2016],t:7,e:"td",f:[".",{t:2,r:"type",p:[58,12,2021]}]}," ",{p:[59,7,2042],t:7,e:"td",f:[{t:2,r:"size",p:[59,11,2046]},"GQ"]}," ",{p:[60,7,2069],t:7,e:"td",f:[{p:[61,8,2082],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[61,26,2100]}],action:"PRG_usbdeletefile",params:['{"name": "',{t:2,r:"name",p:[61,108,2182]},'"}']},f:["DELETE"]}," ",{t:4,f:[{p:[63,9,2256],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[63,27,2274]}],action:"PRG_copyfromusb",params:['{"name": "',{t:2,r:"name",p:[63,107,2354]},'"}']},f:["IMPORT"]}],n:50,r:"data.usbconnected",p:[62,8,2221]}]}]}],n:52,r:"data.usbfiles",p:[55,5,1949]}]}],n:50,r:"data.usbconnected",p:[46,4,1731]}," ",{p:[70,4,2470],t:7,e:"ui-button",a:{action:"PRG_newtextfile"},f:["NEW DATA FILE"]}],r:"data.filename"}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],274:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[5,2,79],t:7,e:"i",f:["No program loaded. Please select program from list below."]}," ",{p:[6,2,146],t:7,e:"table",f:[{t:4,f:[{p:[8,4,185],t:7,e:"tr",f:[{p:[8,8,189],t:7,e:"td",f:[{p:[8,12,193],t:7,e:"ui-button",a:{action:"PC_runprogram",params:['{"name": "',{t:2,r:"name",p:[8,64,245]},'"}']},f:[{t:2,r:"desc",p:[9,5,263]}]}]},{p:[11,4,293],t:7,e:"td",f:[{p:[11,8,297],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["running"],s:'_0?null:"disabled"'},p:[11,26,315]}],icon:"close",action:"PC_killprogram",params:['{"name": "',{t:2,r:"name",p:[11,114,403]},'"}']}}]}]}],n:52,r:"data.programs",p:[7,3,157]}]}," ",{p:[14,2,454],t:7,e:"br"},{p:[14,6,458],t:7,e:"br"}," ",{t:4,f:[{p:[16,3,491],t:7,e:"ui-button",a:{action:"PC_toggle_light",style:[{t:2,x:{r:["data.light_on"],s:'_0?"selected":null'},p:[16,46,534]}]},f:["Toggle Flashlight"]},{p:[16,114,602],t:7,e:"br"}," ",{p:[17,3,610],t:7,e:"ui-button",a:{action:"PC_light_color"},f:["Change Flashlight Color ",{p:[17,62,669],t:7,e:"span",a:{style:["border:1px solid #161616; background-color: ",{t:2,r:"data.comp_light_color",p:[17,119,726]},";"]},f:["   "]}]}],n:50,r:"data.has_light",p:[15,2,465]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],275:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:[{p:[6,3,105],t:7,e:"h1",f:["ADMINISTRATIVE MODE"]}],n:50,r:"data.adminmode",p:[5,2,79]}," ",{t:4,f:[{p:[10,3,170],t:7,e:"div",a:{"class":"itemLabel"},f:["Current channel:"]}," ",{p:[13,3,229],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.title",p:[14,4,259]}]}," ",{p:[16,3,287],t:7,e:"div",a:{"class":"itemLabel"},f:["Operator access:"]}," ",{p:[19,3,346],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:[{p:[21,5,406],t:7,e:"b",f:["Enabled"]}],n:50,r:"data.is_operator",p:[20,4,376]},{t:4,n:51,f:[{p:[23,5,439],t:7,e:"b",f:["Disabled"]}],r:"data.is_operator"}]}," ",{p:[26,3,480],t:7,e:"div",a:{"class":"itemLabel"},f:["Controls:"]}," ",{p:[29,3,532],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[30,4,562],t:7,e:"table",f:[{p:[31,5,575],t:7,e:"tr",f:[{p:[31,9,579],t:7,e:"td",f:[{p:[31,13,583],t:7,e:"ui-button",a:{action:"PRG_speak"},f:["Send message"]}]}]},{p:[32,5,643],t:7,e:"tr",f:[{p:[32,9,647],t:7,e:"td",f:[{p:[32,13,651],t:7,e:"ui-button",a:{action:"PRG_changename"},f:["Change nickname"]}]}]},{p:[33,5,719],t:7,e:"tr",f:[{p:[33,9,723],t:7,e:"td",f:[{p:[33,13,727],t:7,e:"ui-button",a:{action:"PRG_toggleadmin"},f:["Toggle administration mode"]}]}]},{p:[34,5,807],t:7,e:"tr",f:[{p:[34,9,811],t:7,e:"td",f:[{p:[34,13,815],t:7,e:"ui-button",a:{action:"PRG_leavechannel"},f:["Leave channel"]}]}]},{p:[35,5,883],t:7,e:"tr",f:[{p:[35,9,887],t:7,e:"td",f:[{p:[35,13,891],t:7,e:"ui-button",a:{action:"PRG_savelog"},f:["Save log to local drive"]}," ",{t:4,f:[{p:[37,6,995],t:7,e:"tr",f:[{p:[37,10,999],t:7,e:"td",f:[{p:[37,14,1003],t:7,e:"ui-button",a:{action:"PRG_renamechannel"},f:["Rename channel"]}]}]},{p:[38,6,1074],t:7,e:"tr",f:[{p:[38,10,1078],t:7,e:"td",f:[{p:[38,14,1082],t:7,e:"ui-button",a:{action:"PRG_setpassword"},f:["Set password"]}]}]},{p:[39,6,1149],t:7,e:"tr",f:[{p:[39,10,1153],t:7,e:"td",f:[{p:[39,14,1157],t:7,e:"ui-button",a:{action:"PRG_deletechannel"},f:["Delete channel"]}]}]}],n:50,r:"data.is_operator",p:[36,5,964]}]}]}]}]}," ",{p:[43,3,1263],t:7,e:"b",f:["Chat Window"]}," ",{p:[44,4,1286],t:7,e:"div",a:{"class":"statusDisplay",style:"overflow: auto;"},f:[{p:[45,4,1342],t:7,e:"div",a:{"class":"item"},f:[{p:[46,5,1366],t:7,e:"div",a:{"class":"itemContent",style:"width: 100%;"},f:[{t:4,f:[{t:2,r:"msg",p:[48,7,1450]},{p:[48,14,1457],t:7,e:"br"}],n:52,r:"data.messages",p:[47,6,1419]}]}]}]}," ",{p:[53,3,1516],t:7,e:"b",f:["Connected Users"]},{p:[53,25,1538],t:7,e:"br"}," ",{t:4,f:[{t:2,r:"name",p:[55,4,1573]},{p:[55,12,1581],t:7,e:"br"}],n:52,r:"data.clients",p:[54,3,1546]}],n:50,r:"data.title",p:[9,2,148]},{t:4,n:51,f:[{p:[58,3,1613],t:7,e:"b",f:["Controls:"]}," ",{p:[59,3,1633],t:7,e:"table",f:[{p:[60,4,1645],t:7,e:"tr",f:[{p:[60,8,1649],t:7,e:"td",f:[{p:[60,12,1653],t:7,e:"ui-button",a:{action:"PRG_changename"},f:["Change nickname"]}]}]},{p:[61,4,1720],t:7,e:"tr",f:[{p:[61,8,1724],t:7,e:"td",f:[{p:[61,12,1728],t:7,e:"ui-button",a:{action:"PRG_newchannel"},f:["New Channel"]}]}]},{p:[62,4,1791],t:7,e:"tr",f:[{p:[62,8,1795],t:7,e:"td",f:[{p:[62,12,1799],t:7,e:"ui-button",a:{action:"PRG_toggleadmin"},f:["Toggle administration mode"]}]}]}]}," ",{p:[64,3,1889],t:7,e:"b",f:["Available channels:"]}," ",{p:[65,3,1919],t:7,e:"table",f:[{t:4,f:[{p:[67,4,1964],t:7,e:"tr",f:[{p:[67,8,1968],t:7,e:"td",f:[{p:[67,12,1972],t:7,e:"ui-button",a:{action:"PRG_joinchannel",params:['{"id": "',{t:2,r:"id",p:[67,64,2024]},'"}']},f:[{t:2,r:"chan",p:[67,74,2034]}]},{p:[67,94,2054],t:7,e:"br"}]}]}],n:52,r:"data.all_channels",p:[66,3,1930]}]}],r:"data.title"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],276:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:["##SYSTEM ERROR: ",{t:2,r:"data.error",p:[6,19,117]},{p:[6,33,131],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["RESET"]}],n:50,r:"data.error",p:[5,2,79]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.target"],s:"_0"},f:["##DoS traffic generator active. Tx: ",{t:2,r:"data.speed",p:[8,39,243]},"GQ/s",{p:[8,57,261],t:7,e:"br"}," ",{t:4,f:[{t:2,r:"nums",p:[10,4,300]},{p:[10,12,308],t:7,e:"br"}],n:52,r:"data.dos_strings",p:[9,3,269]}," ",{p:[12,3,329],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["ABORT"]}]},{t:4,n:50,x:{r:["data.target"],s:"!(_0)"},f:[" ##DoS traffic generator ready. Select target device.",{p:[14,55,443],t:7,e:"br"}," ",{t:4,f:["Targeted device ID: ",{t:2,r:"data.focus",p:[16,24,494]}],n:50,r:"data.focus",p:[15,3,451]},{t:4,n:51,f:["Targeted device ID: None"],r:"data.focus"}," ",{p:[20,3,564],t:7,e:"ui-button",a:{action:"PRG_execute"},f:["EXECUTE"]},{p:[20,54,615],t:7,e:"div",a:{style:"clear:both"}}," Detected devices on network:",{p:[21,31,677],t:7,e:"br"}," ",{t:4,f:[{p:[23,4,711],t:7,e:"ui-button",a:{action:"PRG_target_relay",params:['{"targid": "',{t:2,r:"id",p:[23,61,768]},'"}']},f:[{t:2,r:"id",p:[23,71,778]}]}],n:52,r:"data.relays",p:[22,3,685]}]}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],277:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[5,2,79],t:7,e:"i",f:["Welcome to software download utility. Please select which software you wish to download."]},{p:[5,97,174],t:7,e:"hr"}," ",{t:4,f:[{p:[7,3,203],t:7,e:"ui-display",a:{title:"Download Error"},f:[{p:[8,4,243],t:7,e:"ui-section",a:{label:"Information"},f:[{t:2,r:"data.error",p:[9,5,281]}]}," ",{p:[11,4,318],t:7,e:"ui-section",a:{label:"Reset Program"},f:[{p:[12,5,358],t:7,e:"ui-button",a:{icon:"times",action:"PRG_reseterror"},f:["RESET"]}]}]}],n:50,r:"data.error",p:[6,2,181]},{t:4,n:51,f:[{t:4,f:[{p:[19,4,516],t:7,e:"ui-display",a:{title:"Download Running"},f:[{p:[20,5,559],t:7,e:"i",f:["Please wait..."]}," ",{p:[21,5,586],t:7,e:"ui-section",a:{label:"File name"},f:[{t:2,r:"data.downloadname",p:[22,6,623]}]}," ",{p:[24,5,669],t:7,e:"ui-section",a:{label:"File description"},f:[{t:2,r:"data.downloaddesc",p:[25,6,713]}]}," ",{p:[27,5,759],t:7,e:"ui-section",a:{label:"File size"},f:[{t:2,r:"data.downloadsize",p:[28,6,796]},"GQ"]}," ",{p:[30,5,844],t:7,e:"ui-section",a:{label:"Transfer Rate"},f:[{t:2,r:"data.downloadspeed",p:[31,6,885]}," GQ/s"]}," ",{p:[33,5,937],t:7,e:"ui-section",a:{label:"Download progress"},f:[{p:[34,6,982],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.downloadsize",p:[34,27,1003]}],value:[{t:2,r:"adata.downloadcompletion",p:[34,58,1034]}],state:"good"},f:[{t:2,x:{r:["adata.downloadcompletion"],s:"Math.round(_0)"},p:[34,101,1077]},"GQ / ",{t:2,r:"adata.downloadsize",p:[34,146,1122]},"GQ"]}]}]}],n:50,r:"data.downloadname",p:[18,3,486]}],r:"data.error"}," ",{t:4,f:[{t:4,f:[{p:[41,4,1270],t:7,e:"ui-display",a:{title:"File System"},f:[{p:[42,5,1308],t:7,e:"ui-section",a:{label:"Used Capacity"},f:[{p:[43,6,1349],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.disk_size",p:[43,27,1370]}],value:[{t:2,r:"adata.disk_used",p:[43,55,1398]}],state:"good"},f:[{t:2,x:{r:["adata.disk_used"],s:"Math.round(_0)"},p:[43,89,1432]},"GQ / ",{t:2,r:"adata.disk_size",p:[43,125,1468]},"GQ"]}]}]}," ",{p:[47,4,1545],t:7,e:"ui-display",a:{title:"Primary Software Repository"},f:[{t:4,f:[{p:[49,6,1642],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"filedesc",p:[49,28,1664]}]},f:[{p:[50,7,1686],t:7,e:"div",a:{style:"display: table-caption; margin-left: 3px"},f:[{t:2,r:"fileinfo",p:[50,61,1740]}]}," ",{p:[52,7,1774],t:7,e:"ui-section",a:{label:"File name"},f:[{t:2,r:"filename",p:[53,8,1813]}," (",{t:2,r:"size",p:[53,22,1827]}," GQ)"]}," ",{p:[55,7,1868],t:7,e:"ui-section",a:{label:"Compatibility"},f:[{t:2,r:"compatibility",p:[56,8,1911]}]}," ",{p:[58,7,1957],t:7,e:"ui-button",a:{icon:"signal",action:"PRG_downloadfile",params:['{"filename": "',{t:2,r:"filename",p:[58,80,2030]},'"}']},f:["DOWNLOAD"]}]}," ",{p:[62,6,2113],t:7,e:"br"}],n:52,r:"data.downloadable_programs",p:[48,5,1599]}]}," ",{t:4,f:[{p:[67,5,2194],t:7,e:"ui-display",a:{title:"UNKNOWN Software Repository"},f:[{p:[68,6,2249],t:7,e:"i",f:["Please note that Nanotrasen does not recommend download of software from non-official servers."]}," ",{t:4,f:[{p:[70,7,2395],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"filedesc",p:[70,29,2417]}]},f:[{p:[71,8,2440],t:7,e:"div",a:{style:"display: table-caption; margin-left: 3px" +},f:[{t:2,r:"fileinfo",p:[71,62,2494]}]}," ",{p:[73,8,2530],t:7,e:"ui-section",a:{label:"File name"},f:[{t:2,r:"filename",p:[74,9,2570]}," (",{t:2,r:"size",p:[74,23,2584]}," GQ)"]}," ",{p:[76,8,2627],t:7,e:"ui-section",a:{label:"Compatibility"},f:[{t:2,r:"compatibility",p:[77,9,2671]}]}," ",{p:[79,8,2719],t:7,e:"ui-button",a:{icon:"signal",action:"PRG_downloadfile",params:['{"filename": "',{t:2,r:"filename",p:[79,81,2792]},'"}']},f:["DOWNLOAD"]}]}," ",{p:[83,7,2879],t:7,e:"br"}],n:52,r:"data.hacked_programs",p:[69,6,2357]}]}],n:50,r:"data.hackedavailable",p:[66,4,2160]}],n:50,x:{r:["data.error"],s:"!_0"},p:[40,3,1246]}],n:50,x:{r:["data.downloadname"],s:"!_0"},p:[39,2,1216]}," ",{p:[89,2,2954],t:7,e:"br"},{p:[89,6,2958],t:7,e:"br"},{p:[89,10,2962],t:7,e:"hr"},{p:[89,14,2966],t:7,e:"i",f:["NTOS v2.0.4b Copyright Nanotrasen 2557 - 2559"]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],278:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[6,2,81],t:7,e:"ui-display",a:{title:"WIRELESS CONNECTIVITY"},f:[{p:[8,3,129],t:7,e:"ui-section",a:{label:"Active NTNetRelays"},f:[{p:[9,4,173],t:7,e:"b",f:[{t:2,r:"data.ntnetrelays",p:[9,7,176]}]}]}," ",{t:4,f:[{p:[12,4,250],t:7,e:"ui-section",a:{label:"System status"},f:[{p:[13,6,291],t:7,e:"b",f:[{t:2,x:{r:["data.ntnetstatus"],s:'_0?"ENABLED":"DISABLED"'},p:[13,9,294]}]}]}," ",{p:[15,4,366],t:7,e:"ui-section",a:{label:"Control"},f:[{p:[17,4,401],t:7,e:"ui-button",a:{icon:"plus",action:"toggleWireless"},f:["TOGGLE"]}]}," ",{p:[21,4,500],t:7,e:"br"},{p:[21,8,504],t:7,e:"br"}," ",{p:[22,4,513],t:7,e:"i",f:["Caution - Disabling wireless transmitters when using wireless device may prevent you from re-enabling them again!"]}],n:50,r:"data.ntnetrelays",p:[11,3,221]},{t:4,n:51,f:[{p:[24,4,650],t:7,e:"br"},{p:[24,8,654],t:7,e:"p",f:["Wireless coverage unavailable, no relays are connected."]}],r:"data.ntnetrelays"}]}," ",{p:[29,2,750],t:7,e:"ui-display",a:{title:"FIREWALL CONFIGURATION"},f:[{p:[31,2,798],t:7,e:"table",f:[{p:[32,3,809],t:7,e:"tr",f:[{p:[33,4,818],t:7,e:"th",f:["PROTOCOL"]},{p:[34,4,835],t:7,e:"th",f:["STATUS"]},{p:[35,4,850],t:7,e:"th",f:["CONTROL"]}]},{p:[36,3,865],t:7,e:"tr",f:[" ",{p:[37,4,874],t:7,e:"td",f:["Software Downloads"]},{p:[38,4,901],t:7,e:"td",f:[{t:2,x:{r:["data.config_softwaredownload"],s:'_0?"ENABLED":"DISABLED"'},p:[38,8,905]}]},{p:[39,4,967],t:7,e:"td",f:[" ",{p:[39,9,972],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "1"}'},f:["TOGGLE"]}]}]},{p:[40,3,1051],t:7,e:"tr",f:[" ",{p:[41,4,1060],t:7,e:"td",f:["Peer to Peer Traffic"]},{p:[42,4,1089],t:7,e:"td",f:[{t:2,x:{r:["data.config_peertopeer"],s:'_0?"ENABLED":"DISABLED"'},p:[42,8,1093]}]},{p:[43,4,1149],t:7,e:"td",f:[{p:[43,8,1153],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "2"}'},f:["TOGGLE"]}]}]},{p:[44,3,1232],t:7,e:"tr",f:[" ",{p:[45,4,1241],t:7,e:"td",f:["Communication Systems"]},{p:[46,4,1271],t:7,e:"td",f:[{t:2,x:{r:["data.config_communication"],s:'_0?"ENABLED":"DISABLED"'},p:[46,8,1275]}]},{p:[47,4,1334],t:7,e:"td",f:[{p:[47,8,1338],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "3"}'},f:["TOGGLE"]}]}]},{p:[48,3,1417],t:7,e:"tr",f:[" ",{p:[49,4,1426],t:7,e:"td",f:["Remote System Control"]},{p:[50,4,1456],t:7,e:"td",f:[{t:2,x:{r:["data.config_systemcontrol"],s:'_0?"ENABLED":"DISABLED"'},p:[50,8,1460]}]},{p:[51,4,1519],t:7,e:"td",f:[{p:[51,8,1523],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "4"}'},f:["TOGGLE"]}]}]}]}]}," ",{p:[55,2,1630],t:7,e:"ui-display",a:{title:"SECURITY SYSTEMS"},f:[{t:4,f:[{p:[58,4,1699],t:7,e:"ui-notice",f:[{p:[59,5,1716],t:7,e:"h1",f:["NETWORK INCURSION DETECTED"]}]}," ",{p:[61,5,1774],t:7,e:"i",f:["An abnormal activity has been detected in the network. Please verify system logs for more information"]}],n:50,r:"data.idsalarm",p:[57,3,1673]}," ",{p:[64,3,1902],t:7,e:"ui-section",a:{label:"Intrusion Detection System"},f:[{p:[65,4,1954],t:7,e:"b",f:[{t:2,x:{r:["data.idsstatus"],s:'_0?"ENABLED":"DISABLED"'},p:[65,7,1957]}]}]}," ",{p:[68,3,2029],t:7,e:"ui-section",a:{label:"Maximal Log Count"},f:[{p:[69,4,2072],t:7,e:"b",f:[{t:2,r:"data.ntnetmaxlogs",p:[69,7,2075]}]}]}," ",{p:[72,3,2125],t:7,e:"ui-section",a:{label:"Controls"},f:[]}," ",{p:[74,4,2176],t:7,e:"table",f:[{p:[75,4,2188],t:7,e:"tr",f:[{p:[75,8,2192],t:7,e:"td",f:[{p:[75,12,2196],t:7,e:"ui-button",a:{action:"resetIDS"},f:["RESET IDS"]}]}]},{p:[76,4,2251],t:7,e:"tr",f:[{p:[76,8,2255],t:7,e:"td",f:[{p:[76,12,2259],t:7,e:"ui-button",a:{action:"toggleIDS"},f:["TOGGLE IDS"]}]}]},{p:[77,4,2316],t:7,e:"tr",f:[{p:[77,8,2320],t:7,e:"td",f:[{p:[77,12,2324],t:7,e:"ui-button",a:{action:"updatemaxlogs"},f:["SET LOG LIMIT"]}]}]},{p:[78,4,2388],t:7,e:"tr",f:[{p:[78,8,2392],t:7,e:"td",f:[{p:[78,12,2396],t:7,e:"ui-button",a:{action:"purgelogs"},f:["PURGE LOGS"]}]}]}]}," ",{p:[81,3,2467],t:7,e:"ui-subdisplay",a:{title:"System Logs"},f:[{p:[82,3,2506],t:7,e:"div",a:{"class":"statusDisplay",style:"overflow: auto;"},f:[{p:[83,3,2561],t:7,e:"div",a:{"class":"item"},f:[{p:[84,4,2584],t:7,e:"div",a:{"class":"itemContent",style:"width: 100%;"},f:[{t:4,f:[{t:2,r:"entry",p:[86,6,2667]},{p:[86,15,2676],t:7,e:"br"}],n:52,r:"data.ntnetlogs",p:[85,5,2636]}]}]}]}]}]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],279:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:[{p:[7,2,102],t:7,e:"div",a:{"class":"item"},f:[{p:[8,3,124],t:7,e:"h2",f:["An error has occurred during operation..."]}," ",{p:[9,3,178],t:7,e:"b",f:["Additional information:"]},{t:2,r:"data.error",p:[9,34,209]},{p:[9,48,223],t:7,e:"br"}," ",{p:[10,3,231],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Clear"]}]}],n:50,r:"data.error",p:[6,2,81]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.downloading"],s:"_0"},f:[{p:[13,3,321],t:7,e:"h2",f:["Download in progress..."]}," ",{p:[14,3,357],t:7,e:"div",a:{"class":"itemLabel"},f:["Downloaded file:"]}," ",{p:[17,3,416],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.download_name",p:[18,4,446]}]}," ",{p:[20,3,483],t:7,e:"div",a:{"class":"itemLabel"},f:["Download progress:"]}," ",{p:[23,3,544],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.download_progress",p:[24,4,574]}," / ",{t:2,r:"data.download_size",p:[24,33,603]}," GQ"]}," ",{p:[26,3,642],t:7,e:"div",a:{"class":"itemLabel"},f:["Transfer speed:"]}," ",{p:[29,3,700],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.download_netspeed",p:[30,4,730]},"GQ/s"]}," ",{p:[32,3,774],t:7,e:"div",a:{"class":"itemLabel"},f:["Controls:"]}," ",{p:[35,3,826],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[36,4,856],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Abort download"]}]}]},{t:4,n:50,x:{r:["data.downloading","data.uploading"],s:"(!(_0))&&(_1)"},f:[" ",{p:[39,3,954],t:7,e:"h2",f:["Server enabled"]}," ",{p:[40,3,981],t:7,e:"div",a:{"class":"itemLabel"},f:["Connected clients:"]}," ",{p:[43,3,1042],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.upload_clients",p:[44,4,1072]}]}," ",{p:[46,3,1109],t:7,e:"div",a:{"class":"itemLabel"},f:["Provided file:"]}," ",{p:[49,3,1166],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.upload_filename",p:[50,4,1196]}]}," ",{p:[52,3,1234],t:7,e:"div",a:{"class":"itemLabel"},f:["Server password:"]}," ",{p:[55,3,1293],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:["ENABLED"],n:50,r:"data.upload_haspassword",p:[56,4,1323]},{t:4,n:51,f:["DISABLED"],r:"data.upload_haspassword"}]}," ",{p:[62,3,1420],t:7,e:"div",a:{"class":"itemLabel"},f:["Commands:"]}," ",{p:[65,3,1472],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[66,4,1502],t:7,e:"ui-button",a:{action:"PRG_setpassword"},f:["Set password"]}," ",{p:[67,4,1567],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Exit server"]}]}]},{t:4,n:50,x:{r:["data.downloading","data.uploading","data.upload_filelist"],s:"(!(_0))&&((!(_1))&&(_2))"},f:[" ",{p:[70,3,1668],t:7,e:"h2",f:["File transfer server ready. Select file to upload:"]}," ",{p:[71,3,1732],t:7,e:"table",f:[{p:[72,3,1743],t:7,e:"tr",f:[{p:[72,7,1747],t:7,e:"th",f:["File name"]},{p:[72,20,1760],t:7,e:"th",f:["File size"]},{p:[72,33,1773],t:7,e:"th",f:["Controls ",{t:4,f:[{p:[74,4,1824],t:7,e:"tr",f:[{p:[74,8,1828],t:7,e:"td",f:[{t:2,r:"filename",p:[74,12,1832]}]},{p:[75,4,1849],t:7,e:"td",f:[{t:2,r:"size",p:[75,8,1853]},"GQ"]},{p:[76,4,1868],t:7,e:"td",f:[{p:[76,8,1872],t:7,e:"ui-button",a:{action:"PRG_uploadfile",params:['{"id": "',{t:2,r:"uid",p:[76,59,1923]},'"}']},f:["Select"]}]}]}],n:52,r:"data.upload_filelist",p:[73,3,1789]}]}]}]}," ",{p:[79,3,1981],t:7,e:"hr"}," ",{p:[80,3,1989],t:7,e:"ui-button",a:{action:"PRG_setpassword"},f:["Set password"]}," ",{p:[81,3,2053],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Return"]}]},{t:4,n:50,x:{r:["data.downloading","data.uploading","data.upload_filelist"],s:"(!(_0))&&((!(_1))&&(!(_2)))"},f:[" ",{p:[83,3,2116],t:7,e:"h2",f:["Available files:"]}," ",{p:[84,3,2145],t:7,e:"table",a:{border:"1",style:"border-collapse: collapse"},f:[{p:[84,55,2197],t:7,e:"tr",f:[{p:[84,59,2201],t:7,e:"th",f:["Server UID"]},{p:[84,73,2215],t:7,e:"th",f:["File Name"]},{p:[84,86,2228],t:7,e:"th",f:["File Size"]},{p:[84,99,2241],t:7,e:"th",f:["Password Protection"]},{p:[84,122,2264],t:7,e:"th",f:["Operations ",{t:4,f:[{p:[86,5,2311],t:7,e:"tr",f:[{p:[86,9,2315],t:7,e:"td",f:[{t:2,r:"uid",p:[86,13,2319]}]},{p:[87,5,2332],t:7,e:"td",f:[{t:2,r:"filename",p:[87,9,2336]}]},{p:[88,5,2354],t:7,e:"td",f:[{t:2,r:"size",p:[88,9,2358]},"GQ ",{t:4,f:[{p:[90,6,2400],t:7,e:"td",f:["Enabled"]}],n:50,r:"haspassword",p:[89,5,2374]}," ",{t:4,f:[{p:[93,6,2457],t:7,e:"td",f:["Disabled"]}],n:50,x:{r:["haspassword"],s:"!_0"},p:[92,5,2430]}]},{p:[96,5,2494],t:7,e:"td",f:[{p:[96,9,2498],t:7,e:"ui-button",a:{action:"PRG_downloadfile",params:['{"id": "',{t:2,r:"uid",p:[96,62,2551]},'"}']},f:["Download"]}]}]}],n:52,r:"data.servers",p:[85,4,2283]}]}]}]}," ",{p:[99,3,2612],t:7,e:"hr"}," ",{p:[100,3,2620],t:7,e:"ui-button",a:{action:"PRG_uploadmenu"},f:["Send file"]}]}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],280:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{chargingState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}},chargingMode:function(t){return 2==t?"Full":1==t?"Charging":"Draining"},channelState:function(t){return t>=2?"good":"bad"},channelPower:function(t){return t>=2?"On":"Off"},channelMode:function(t){return 1==t||3==t?"Auto":"Manual"}},computed:{graphData:function(){var t=this.get("data.history");return Object.keys(t).map(function(e){return t[e].map(function(t,e){return{x:e,y:t}})})}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[43,1,1082],t:7,e:"ntosheader"}," ",{p:[45,1,1099],t:7,e:"ui-display",a:{title:"Network"},f:[{t:4,f:[{p:[47,5,1157],t:7,e:"ui-linegraph",a:{points:[{t:2,r:"graphData",p:[47,27,1179]}],height:"500",legend:'["Available", "Load"]',colors:'["rgb(0, 102, 0)", "rgb(153, 0, 0)"]',xunit:"seconds ago",xfactor:[{t:2,r:"data.interval",p:[49,38,1331]}],yunit:"W",yfactor:"1",xinc:[{t:2,x:{r:["data.stored"],s:"_0/10"},p:[50,15,1387]}],yinc:"9"}}],n:50,r:"config.fancy",p:[46,3,1131]},{t:4,n:51,f:[{p:[52,5,1437],t:7,e:"ui-section",a:{label:"Available"},f:[{p:[53,7,1475],t:7,e:"span",f:[{t:2,r:"data.supply",p:[53,13,1481]}]}]}," ",{p:[55,5,1528],t:7,e:"ui-section",a:{label:"Load"},f:[{p:[56,9,1563],t:7,e:"span",f:[{t:2,r:"data.demand",p:[56,15,1569]}]}]}],r:"config.fancy"}]}," ",{p:[60,1,1638],t:7,e:"ui-display",a:{title:"Areas"},f:[{p:[61,3,1668],t:7,e:"ui-section",a:{nowrap:0},f:[{p:[62,5,1693],t:7,e:"div",a:{"class":"content"},f:["Area"]}," ",{p:[63,5,1730],t:7,e:"div",a:{"class":"content"},f:["Charge"]}," ",{p:[64,5,1769],t:7,e:"div",a:{"class":"content"},f:["Load"]}," ",{p:[65,5,1806],t:7,e:"div",a:{"class":"content"},f:["Status"]}," ",{p:[66,5,1845],t:7,e:"div",a:{"class":"content"},f:["Equipment"]}," ",{p:[67,5,1887],t:7,e:"div",a:{"class":"content"},f:["Lighting"]}," ",{p:[68,5,1928],t:7,e:"div",a:{"class":"content"},f:["Environment"]}]}," ",{t:4,f:[{p:[71,5,2013],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[71,24,2032]}],nowrap:0},f:[{p:[72,7,2057],t:7,e:"div",a:{"class":"content"},f:[{t:2,x:{r:["@index","adata.areas"],s:"Math.round(_1[_0].charge)"},p:[72,28,2078]}," %"]}," ",{p:[73,7,2136],t:7,e:"div",a:{"class":"content"},f:[{t:2,rx:{r:"adata.areas",m:[{t:30,n:"@index"},"load"]},p:[73,28,2157]}]}," ",{p:[74,7,2199],t:7,e:"div",a:{"class":"content"},f:[{p:[74,28,2220],t:7,e:"span",a:{"class":[{t:2,x:{r:["chargingState","charging"],s:"_0(_1)"},p:[74,41,2233]}]},f:[{t:2,x:{r:["chargingMode","charging"],s:"_0(_1)"},p:[74,70,2262]}]}]}," ",{p:[75,7,2309],t:7,e:"div",a:{"class":"content"},f:[{p:[75,28,2330],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","eqp"],s:"_0(_1)"},p:[75,41,2343]}]},f:[{t:2,x:{r:["channelPower","eqp"],s:"_0(_1)"},p:[75,64,2366]}," [",{p:[75,87,2389],t:7,e:"span",f:[{t:2,x:{r:["channelMode","eqp"],s:"_0(_1)"},p:[75,93,2395]}]},"]"]}]}," ",{p:[76,7,2444],t:7,e:"div",a:{"class":"content"},f:[{p:[76,28,2465],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","lgt"],s:"_0(_1)"},p:[76,41,2478]}]},f:[{t:2,x:{r:["channelPower","lgt"],s:"_0(_1)"},p:[76,64,2501]}," [",{p:[76,87,2524],t:7,e:"span",f:[{t:2,x:{r:["channelMode","lgt"],s:"_0(_1)"},p:[76,93,2530]}]},"]"]}]}," ",{p:[77,7,2579],t:7,e:"div",a:{"class":"content"},f:[{p:[77,28,2600],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","env"],s:"_0(_1)"},p:[77,41,2613]}]},f:[{t:2,x:{r:["channelPower","env"],s:"_0(_1)"},p:[77,64,2636]}," [",{p:[77,87,2659],t:7,e:"span",f:[{t:2,x:{r:["channelMode","env"],s:"_0(_1)"},p:[77,93,2665]}]},"]"]}]}]}],n:52,r:"data.areas",p:[70,3,1987]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],281:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[5,2,79],t:7,e:"div",a:{"class":"item"},f:[{p:[6,3,101],t:7,e:"div",a:{"class":"itemLabel"},f:["Payload status:"]}," ",{p:[9,3,158],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:["ARMED"],n:50,r:"data.armed",p:[10,4,188]},{t:4,n:51,f:["DISARMED"],r:"data.armed"}]}," ",{p:[16,3,270],t:7,e:"div",a:{"class":"itemLabel"},f:["Controls:"]}," ",{p:[19,3,321],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[20,4,351],t:7,e:"table",f:[{p:[21,4,363],t:7,e:"tr",f:[{p:[21,8,367],t:7,e:"td",f:[{p:[21,12,371],t:7,e:"ui-button",a:{action:"PRG_obfuscate"},f:["OBFUSCATE PROGRAM NAME"]}]}]},{p:[22,4,444],t:7,e:"tr",f:[{p:[22,8,448],t:7,e:"td",f:[{p:[22,12,452],t:7,e:"ui-button",a:{action:"PRG_arm",state:[{t:2,x:{r:["data.armed"],s:'_0?"danger":null'},p:[22,47,487]}]},f:[{t:2,x:{r:["data.armed"],s:'_0?"DISARM":"ARM"'},p:[22,81,521]}]}," ",{p:[23,4,571],t:7,e:"ui-button",a:{icon:"radiation",state:[{t:2,x:{r:["data.armed"],s:'_0?null:"disabled"'},p:[23,39,606]}],action:"PRG_activate"},f:["ACTIVATE"]}]}]}]}]}]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],282:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[5,3,95],t:7,e:"ui-display",a:{title:[{t:2,r:"class",p:[5,22,114]}," Alarms"]},f:[{p:[6,5,138],t:7,e:"ul",f:[{t:4,f:[{p:[8,9,171],t:7,e:"li",f:[{t:2,r:".",p:[8,13,175]}]}],n:52,r:".",p:[7,7,150]},{t:4,n:51,f:[{p:[10,9,211],t:7,e:"li",f:["System Nominal"]}],r:"."}]}]}],n:52,i:"class",r:"data.alarms",p:[4,1,64]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],283:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{integState:function(t){var e=100;return t==e?"good":t>e/2?"average":"bad"},bigState:function(t,e,n){return charge>n?"bad":t>e?"average":"good"}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[23,1,421],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[27,2,462],t:7,e:"ui-button",a:{action:"PRG_clear"},f:["Back to Menu"]},{p:[27,56,516],t:7,e:"br"}," ",{p:[28,3,524],t:7,e:"ui-display",a:{title:"Supermatter Status:"},f:[{p:[29,3,568],t:7,e:"ui-section",a:{label:"Core Integrity"},f:[{p:[30,5,609],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"adata.SM_integrity",p:[30,38,642]}],state:[{t:2,x:{r:["integState","adata.SM_integrity"],s:"_0(_1)"},p:[30,69,673]}]},f:[{t:2,r:"data.SM_integrity",p:[30,105,709]},"%"]}]}," ",{p:[32,3,761],t:7,e:"ui-section",a:{label:"Relative EER"},f:[{p:[33,5,800],t:7,e:"span",a:{"class":[{t:2,x:{r:["bigState","data.SM_power"],s:"_0(_1,150,300)"},p:[33,18,813]}]},f:[{t:2,r:"data.SM_power",p:[33,55,850]}," MeV/cm3"]}]}," ",{p:[35,3,903],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[36,5,941],t:7,e:"span",a:{"class":[{t:2,x:{r:["bigState","data.SM_ambienttemp"],s:"_0(_1,4000,5000)"},p:[36,18,954]}]},f:[{t:2,r:"data.SM_ambienttemp",p:[36,63,999]}," K"]}]}," ",{p:[38,3,1052],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[39,5,1087],t:7,e:"span",a:{"class":[{t:2,x:{r:["bigState","data.SM_ambientpressure"],s:"_0(_1,5000,10000)"},p:[39,18,1100]}]},f:[{t:2,r:"data.SM_ambientpressure",p:[39,68,1150]}," kPa"]}]}]}," ",{p:[42,3,1227],t:7,e:"hr"},{p:[42,7,1231],t:7,e:"br"}," ",{p:[43,3,1239],t:7,e:"ui-display",a:{title:"Gas Composition:"},f:[{t:4,f:[{p:[45,5,1307],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[45,24,1326]}]},f:[{t:2,r:"amount",p:[46,6,1343]}," %"]}],n:52,r:"data.gases",p:[44,4,1281]}]}],n:50,r:"data.active",p:[26,1,440]},{t:4,n:51,f:[{p:[51,2,1418],t:7,e:"ui-button",a:{action:"PRG_refresh"},f:["Refresh"]},{p:[51,53,1469],t:7,e:"br"}," ",{p:[52,2,1476],t:7,e:"ui-display",a:{title:"Detected Supermatters"},f:[{t:4,f:[{p:[54,3,1552],t:7,e:"ui-section",a:{label:"Area"},f:[{t:2,r:"area_name",p:[55,5,1583]}," - (#",{t:2,r:"uid",p:[55,23,1601]},")"]}," ",{p:[57,3,1630],t:7,e:"ui-section",a:{label:"Integrity"},f:[{t:2,r:"integrity",p:[58,5,1666]}," %"]}," ",{p:[60,3,1702],t:7,e:"ui-section",a:{label:"Options"},f:[{p:[61,5,1736],t:7,e:"ui-button",a:{action:"PRG_set",params:['{"target" : "',{t:2,r:"uid",p:[61,54,1785]},'"}']},f:["View Details"]}]}],n:52,r:"data.supermatters",p:[53,2,1521]}]}],r:"data.active"}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(284)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,284:284}],284:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"div",a:{"class":"item",style:"float: left"},f:[{p:[2,2,41],t:7,e:"table",f:[{p:[2,9,48],t:7,e:"tr",f:[{t:4,f:[{p:[4,3,113],t:7,e:"td",f:[{p:[4,7,117],t:7,e:"img",a:{src:[{t:2,r:"data.PC_batteryicon",p:[4,17,127]}]}}]}],n:50,x:{r:["data.PC_batteryicon","data.PC_showbatteryicon"],s:"_0&&_1"},p:[3,2,55]}," ",{t:4,f:[{p:[7,3,226],t:7,e:"td",f:[{p:[7,7,230],t:7,e:"b",f:[{t:2,r:"data.PC_batterypercent",p:[7,10,233]}]}]}],n:50,x:{r:["data.PC_batterypercent","data.PC_showbatteryicon"],s:"_0&&_1"},p:[6,2,165]}," ",{t:4,f:[{p:[10,3,305],t:7,e:"td",f:[{p:[10,7,309],t:7,e:"img",a:{src:[{t:2,r:"data.PC_ntneticon",p:[10,17,319]}]}}]}],n:50,r:"data.PC_ntneticon",p:[9,2,276]}," ",{t:4,f:[{p:[13,3,386],t:7,e:"td",f:[{p:[13,7,390],t:7,e:"img",a:{src:[{t:2,r:"data.PC_apclinkicon",p:[13,17,400]}]}}]}],n:50,r:"data.PC_apclinkicon",p:[12,2,355]}," ",{t:4,f:[{p:[16,3,469],t:7,e:"td",f:[{p:[16,7,473],t:7,e:"b",f:[{t:2,r:"data.PC_stationtime",p:[16,10,476]}]}]}],n:50,r:"data.PC_stationtime",p:[15,2,438]}," ",{t:4,f:[{p:[19,3,552],t:7,e:"td",f:[{p:[19,7,556],t:7,e:"img",a:{src:[{t:2,r:"icon",p:[19,17,566]}]}}]}],n:52,r:"data.PC_programheaders",p:[18,2,516]}]}]}]}," ",{p:[23,1,609],t:7,e:"div",a:{style:"float: right; margin-top: 5px"},f:[{p:[24,2,655],t:7,e:"ui-button",a:{action:"PC_shutdown"},f:["Shutdown"]}," ",{t:4,f:[{p:[26,3,745],t:7,e:"ui-button",a:{action:"PC_exit"},f:["EXIT PROGRAM"]}," ",{p:[27,3,801],t:7,e:"ui-button",a:{action:"PC_minimize"},f:["Minimize Program"]}],n:50,r:"data.PC_showexitprogram",p:[25,2,710]}]}," ",{p:[30,1,881],t:7,e:"div",a:{style:"clear: both"}}]},e.exports=a.extend(r.exports)},{205:205}],285:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Auth. Disk:"},f:[{t:4,f:[{p:[3,7,69],t:7,e:"ui-button",a:{icon:"eject",style:"selected",action:"eject_disk"},f:["++++++++++"]}],n:50,r:"data.disk_present",p:[2,3,36]},{t:4,n:51,f:[{p:[5,7,172],t:7,e:"ui-button",a:{icon:"plus",action:"insert_disk"},f:["----------"]}],r:"data.disk_present"}]}," ",{p:[8,1,266],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[9,3,297],t:7,e:"span",f:[{t:2,r:"data.status1",p:[9,9,303]},"-",{t:2,r:"data.status2",p:[9,26,320]}]}]}," ",{p:[11,1,360],t:7,e:"ui-display",a:{title:"Timer"},f:[{p:[12,3,390],t:7,e:"ui-section",a:{label:"Time to Detonation"},f:[{p:[13,5,435],t:7,e:"span",f:[{t:2,x:{r:["data.timing","data.time_left","data.timer_set"],s:"_0?_1:_2"},p:[13,11,441]}]}]}," ",{t:4,f:[{p:[16,5,540],t:7,e:"ui-section",a:{label:"Adjust Timer"},f:[{p:[17,7,581],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.timer_is_not_default"],s:'_0&&_1&&_2?null:"disabled"'},p:[17,40,614]}],action:"timer",params:'{"change": "reset"}'},f:["Reset"]}," ",{p:[19,7,786],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.timer_is_not_min"],s:'_0&&_1&&_2?null:"disabled"'},p:[19,38,817]}],action:"timer",params:'{"change": "decrease"}'},f:["Decrease"]}," ",{p:[21,7,991],t:7,e:"ui-button",a:{icon:"pencil",state:[{t:2,x:{r:["data.disk_present","data.code_approved"],s:'_0&&_1?null:"disabled"'},p:[21,39,1023]}],action:"timer",params:'{"change": "input"}'},f:["Set"]}," ",{p:[22,7,1155],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.timer_is_not_max"],s:'_0&&_1&&_2?null:"disabled"'},p:[22,37,1185]}],action:"timer",params:'{"change": "increase"}'},f:["Increase"]}]}],n:51,r:"data.timing",p:[15,3,518]}," ",{p:[26,3,1394],t:7,e:"ui-section",a:{label:"Timer"},f:[{p:[27,5,1426],t:7,e:"ui-button",a:{icon:"clock-o",style:[{t:2,x:{r:["data.timing"],s:'_0?"danger":"caution"'},p:[27,38,1459]}],action:"toggle_timer",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.safety"],s:'_0&&_1&&!_2?null:"disabled"'},p:[29,14,1542]}]},f:[{t:2,x:{r:["data.timing"],s:'_0?"On":"Off"'},p:[30,7,1631]}]}]}]}," ",{p:[34,1,1713],t:7,e:"ui-display",a:{title:"Anchoring"},f:[{p:[35,3,1747],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.disk_present","data.code_approved"],s:'_0&&_1?null:"disabled"'},p:[36,12,1770]}],icon:[{t:2,x:{r:["data.anchored"],s:'_0?"lock":"unlock"'},p:[37,11,1846]}],style:[{t:2,x:{r:["data.anchored"],s:'_0?null:"caution"'},p:[38,12,1897]}],action:"anchor"},f:[{t:2,x:{r:["data.anchored"],s:'_0?"Engaged":"Off"'},p:[39,21,1956]}]}]}," ",{p:[41,1,2022],t:7,e:"ui-display",a:{title:"Safety"},f:[{p:[42,3,2053],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.disk_present","data.code_approved"],s:'_0&&_1?null:"disabled"'},p:[43,12,2076]}],icon:[{t:2,x:{r:["data.safety"],s:'_0?"lock":"unlock"'},p:[44,11,2152]}],action:"safety",style:[{t:2,x:{r:["data.safety"],s:'_0?"caution":"danger"'},p:[45,12,2217]}]},f:[{p:[46,7,2265],t:7,e:"span",f:[{t:2,x:{r:["data.safety"],s:'_0?"On":"Off"'},p:[46,13,2271]}]}]}]}," ",{p:[49,1,2341],t:7,e:"ui-display",a:{title:"Code"},f:[{p:[50,3,2370],t:7,e:"ui-section",a:{label:"Message"},f:[{t:2,r:"data.message",p:[50,31,2398]}]}," ",{p:[51,3,2431],t:7,e:"ui-section",a:{label:"Keypad"},f:[{p:[52,5,2464],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[52,39,2498]}],params:'{"digit":"1"}'},f:["1"]}," ",{p:[53,5,2583],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[53,39,2617]}],params:'{"digit":"2"}'},f:["2"]}," ",{p:[54,5,2702],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[54,39,2736]}],params:'{"digit":"3"}'},f:["3"]}," ",{p:[55,5,2821],t:7,e:"br"}," ",{p:[56,5,2831],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[56,39,2865]}],params:'{"digit":"4"}'},f:["4"]}," ",{p:[57,5,2950],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[57,39,2984]}],params:'{"digit":"5"}'},f:["5"]}," ",{p:[58,5,3069],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[58,39,3103]}],params:'{"digit":"6"}'},f:["6"]}," ",{p:[59,5,3188],t:7,e:"br"}," ",{p:[60,5,3198],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[60,39,3232]}],params:'{"digit":"7"}'},f:["7"]}," ",{p:[61,5,3317],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[61,39,3351]}],params:'{"digit":"8"}'},f:["8"]}," ",{p:[62,5,3436],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[62,39,3470]}],params:'{"digit":"9"}'},f:["9"]}," ",{p:[63,5,3555],t:7,e:"br"}," ",{p:[64,5,3565],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[64,39,3599]}],params:'{"digit":"R"}'},f:["R"]}," ",{p:[65,5,3684],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[65,39,3718]}],params:'{"digit":"0"}'},f:["0"]}," ",{p:[66,5,3803],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[66,39,3837]}],params:'{"digit":"E"}'},f:["E"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],286:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,25],t:7,e:"ui-notice",f:["No table detected!"]}],n:51,r:"data.table",p:[1,1,0]},{p:[6,1,88],t:7,e:"ui-display",f:[{p:[7,2,103],t:7,e:"ui-display",a:{title:"Patient State"},f:[{t:4,f:[{p:[9,4,166],t:7,e:"ui-section",a:{label:"State"},f:[{p:[10,5,198],t:7,e:"span",a:{"class":[{t:2,r:"data.patient.statstate",p:[10,18,211]}]},f:[{t:2,r:"data.patient.stat",p:[10,46,239]}]}]}," ",{p:[12,4,290],t:7,e:"ui-section",a:{label:"Blood Type"},f:[{p:[13,5,327],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.patient.blood_type",p:[13,27,349]}]}]}," ",{p:[15,4,406],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[16,5,439],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.patient.minHealth",p:[16,18,452]}],max:[{t:2,r:"data.patient.maxHealth",p:[16,51,485]}],value:[{t:2,r:"data.patient.health",p:[16,86,520]}],state:[{t:2,x:{r:["data.patient.health"],s:'_0>=0?"good":"average"'},p:[17,12,557]}]},f:[{t:2,x:{r:["adata.patient.health"],s:"Math.round(_0)"},p:[17,63,608]}]}]}," ",{t:4,f:[{p:[20,5,840],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[20,24,859]}]},f:[{p:[21,6,877],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.patient.maxHealth",p:[21,27,898]}],value:[{t:2,rx:{r:"data.patient",m:[{t:30,n:"type"}]},p:[21,62,933]}],state:"bad"},f:[{t:2,x:{r:["type","adata.patient"],s:"Math.round(_1[_0])"},p:[21,98,969]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Burn",type:"fireLoss"},{label:"Toxin",type:"toxLoss"},{label:"Respiratory",type:"oxyLoss"}]'},p:[19,4,676]}],n:50,r:"data.patient",p:[8,3,141]},{t:4,n:51,f:["No patient detected."],r:"data.patient"}]}," ",{p:[28,2,1113],t:7,e:"ui-display",a:{title:"Initiated Procedures"},f:[{t:4,f:[{t:4,f:[{p:[31,5,1217],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"name",p:[31,27,1239]}]},f:[{p:[32,6,1256],t:7,e:"ui-section",a:{label:"Next Step"},f:[{p:[33,7,1294],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"next_step",p:[33,29,1316]}]}]}," ",{t:4,f:[{p:[36,7,1395],t:7,e:"ui-section",a:{label:"Alternative Step"},f:[{p:[37,8,1441],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"alternative_step",p:[37,30,1463]}]}]}],n:50,r:"alternative_step",p:[35,6,1363]}]}],n:52,r:"data.procedures",p:[30,4,1186]}],n:50,r:"data.procedures",p:[29,3,1158]},{t:4,n:51,f:["No active procedures."],r:"data.procedures"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],287:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,2,15],t:7,e:"ui-section",f:["This machine only accepts ore. Gibtonite and Slag are not accepted."]}," ",{p:[5,2,117],t:7,e:"ui-section",f:["Current unclaimed points: ",{t:2,r:"data.unclaimedPoints",p:[6,29,159]}," ",{t:4,f:[{p:[8,4,220],t:7,e:"ui-button",a:{action:"Claim"},f:["Claim Points"]}],n:50,r:"data.unclaimedPoints",p:[7,3,187]}]}," ",{p:[13,2,311],t:7,e:"ui-section",f:[{t:4,f:[{p:[15,4,350],t:7,e:"ui-button",a:{action:"Eject"},f:["Eject ID"]}," You have ",{t:2,r:"data.claimedPoints",p:[18,13,421]}," mining points collected."],n:50,r:"data.hasID",p:[14,3,327]},{t:4,n:51,f:[{p:[20,4,485],t:7,e:"ui-button",a:{action:"Insert"},f:["Insert ID"]}],r:"data.hasID"}]}]}," ",{p:[26,1,588],t:7,e:"ui-display",f:[{t:4,f:[{p:[28,3,627],t:7,e:"ui-section",f:[{p:[29,4,644],t:7,e:"ui-button",a:{action:"diskEject",icon:"eject"},f:["Eject Disk"]}]}," ",{t:4,f:[{p:[34,4,772],t:7,e:"ui-section",a:{"class":"candystripe"},f:[{p:[35,5,808],t:7,e:"ui-button",a:{action:"diskUpload",state:[{t:2,x:{r:["canupload"],s:'(_0)?null:"disabled"'},p:[35,42,845]}],icon:"upload",align:"right",params:['{ "design" : "',{t:2,r:"index",p:[35,129,932]},'" }']},f:["Upload"]}," File ",{t:2,r:"index",p:[38,10,988]},": ",{t:2,r:"name",p:[38,21,999]}]}],n:52,r:"data.diskDesigns",p:[33,3,741]}],n:50,r:"data.hasDisk",p:[27,2,603]},{t:4,n:51,f:[{p:[42,3,1053],t:7,e:"ui-section",f:[{p:[43,4,1070],t:7,e:"ui-button",a:{action:"diskInsert",icon:"floppy-o"},f:["Insert Disk"]}]}],r:"data.hasDisk"}]}," ",{p:[49,1,1195],t:7,e:"div",a:{"class":"display tabular"},f:[{p:[50,2,1227],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[51,4,1261],t:7,e:"section",a:{"class":"cell"},f:["Mineral"]}," ",{p:[54,4,1316],t:7,e:"section",a:{"class":"cell"},f:["Sheets"]}," ",{p:[57,4,1370],t:7,e:"section",a:{"class":"cell"},f:[]}," ",{p:[59,4,1412],t:7,e:"section",a:{"class":"cell"},f:[{p:[60,5,1440],t:7,e:"ui-button",a:{"class":"center mineral",grid:0,action:"Release",params:'{"id" : "all"}'},f:["Release All"]}]}," ",{p:[64,4,1576],t:7,e:"section",a:{"class":"cell"},f:["Ore Value"]}]}," ",{t:4,f:[{p:[69,3,1673],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[70,4,1707],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[71,5,1735]}]}," ",{p:[73,4,1763],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"amount",p:[74,5,1805]}]}," ",{p:[76,4,1835],t:7,e:"section",a:{"class":"cell"},f:[{p:[77,5,1863],t:7,e:"input",a:{value:[{t:2,r:"sheets",p:[77,18,1876]}],placeholder:"###","class":"number"}}]}," ",{p:[79,4,1941],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{p:[80,5,1983],t:7,e:"ui-button",a:{"class":"center",grid:0,action:"Release",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[80,59,2037]}],params:['{ "id" : ',{t:2,r:"id",p:[80,114,2092]},', "sheets" : ',{t:2,r:"sheets",p:[80,133,2111]}," }"]},f:["Release"]}]}," ",{p:[84,4,2178],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"value",p:[85,5,2220]}]}]}],n:52,r:"data.materials",p:[68,2,1645]}," ",{t:4,f:[{p:[90,3,2298],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[91,4,2332],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[92,5,2360] +}]}," ",{p:[94,4,2388],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"amount",p:[95,5,2430]}]}," ",{p:[97,4,2460],t:7,e:"section",a:{"class":"cell"},f:[{p:[98,5,2488],t:7,e:"input",a:{value:[{t:2,r:"sheets",p:[98,18,2501]}],placeholder:"###","class":"number"}}]}," ",{p:[100,4,2566],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{p:[101,5,2608],t:7,e:"ui-button",a:{"class":"center",grid:0,action:"Smelt",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[101,57,2660]}],params:['{ "id" : ',{t:2,r:"id",p:[101,113,2716]},', "sheets" : ',{t:2,r:"sheets",p:[101,132,2735]}," }"]},f:["Smelt"]}]}," ",{p:[105,4,2799],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{p:[106,5,2841],t:7,e:"ui-button",a:{"class":"center",grid:0,action:"SmeltAll",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[106,60,2896]}],params:['{ "id" : ',{t:2,r:"id",p:[106,116,2952]}," }"]},f:["Smelt All"]}]}]}],n:52,r:"data.alloys",p:[89,2,2273]}]}]},e.exports=a.extend(r.exports)},{205:205}],288:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:{button:[{p:[4,4,87],t:7,e:"ui-button",a:{icon:"remove",state:[{t:2,x:{r:["data.has_beaker"],s:'_0?null:"disabled"'},p:[4,36,119]}],action:"empty_eject_beaker"},f:["Empty and eject"]}," ",{p:[7,4,231],t:7,e:"ui-button",a:{icon:"trash",state:[{t:2,x:{r:["data.has_beaker"],s:'_0?null:"disabled"'},p:[7,35,262]}],action:"empty_beaker"},f:["Empty"]}," ",{p:[10,4,358],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.has_beaker"],s:'_0?null:"disabled"'},p:[10,35,389]}],action:"eject_beaker"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{t:4,f:[{p:[15,4,528],t:7,e:"ui-section",f:[{t:4,f:[{p:[17,6,578],t:7,e:"span",a:{"class":"bad"},f:["The beaker is empty!"]}],n:50,r:"data.beaker_empty",p:[16,5,546]},{t:4,n:51,f:[{p:[19,6,644],t:7,e:"ui-subdisplay",a:{title:"Blood"},f:[{t:4,f:[{p:[21,8,712],t:7,e:"ui-section",a:{label:"Blood DNA"},f:[{t:2,r:"data.blood.dna",p:[21,38,742]}]}," ",{p:[22,8,782],t:7,e:"ui-section",a:{label:"Blood type"},f:[{t:2,r:"data.blood.type",p:[22,39,813]}]}],n:50,r:"data.has_blood",p:[20,7,681]},{t:4,n:51,f:[{p:[24,8,870],t:7,e:"ui-section",f:[{p:[25,9,892],t:7,e:"span",a:{"class":"average"},f:["No blood sample detected."]}]}],r:"data.has_blood"}]}],r:"data.beaker_empty"}]}],n:50,r:"data.has_beaker",p:[14,3,500]},{t:4,n:51,f:[{p:[32,4,1054],t:7,e:"ui-section",f:[{p:[33,5,1072],t:7,e:"span",a:{"class":"bad"},f:["No beaker loaded."]}]}],r:"data.has_beaker"}]}," ",{t:4,f:[{p:[38,3,1188],t:7,e:"ui-display",a:{title:"Diseases"},f:[{t:4,f:[{p:{button:[{t:4,f:[{p:[43,8,1343],t:7,e:"ui-button",a:{icon:"pencil",action:"rename_disease",state:[{t:2,x:{r:["can_rename"],s:'_0?"":"disabled"'},p:[43,64,1399]}],params:['{"index": ',{t:2,r:"index",p:[43,116,1451]},"}"]},f:["Name advanced disease"]}],n:50,r:"is_adv",p:[42,7,1320]}," ",{p:[47,7,1538],t:7,e:"ui-button",a:{icon:"flask",action:"create_culture_bottle",state:[{t:2,x:{r:["data.is_ready"],s:'_0?"":"disabled"'},p:[47,69,1600]}],params:['{"index": ',{t:2,r:"index",p:[47,124,1655]},"}"]},f:["Create virus culture bottle"]}]},t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[40,24,1269]}],button:0},f:[" ",{p:[51,6,1749],t:7,e:"ui-section",a:{label:"Disease agent"},f:[{t:2,r:"agent",p:[51,40,1783]}]}," ",{p:[52,6,1812],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"description",p:[52,38,1844]}]}," ",{p:[53,6,1879],t:7,e:"ui-section",a:{label:"Spread"},f:[{t:2,r:"spread",p:[53,33,1906]}]}," ",{p:[54,6,1936],t:7,e:"ui-section",a:{label:"Possible cure"},f:[{t:2,r:"cure",p:[54,40,1970]}]}," ",{t:4,f:[{p:[56,7,2021],t:7,e:"ui-section",a:{label:"Symptoms"},f:[{t:4,f:[{p:[58,9,2087],t:7,e:"ui-button",a:{action:"symptom_details",state:"",params:['{"picked_symptom": ',{t:2,r:"sym_index",p:[58,81,2159]},', "index": ',{t:2,r:"index",p:[58,105,2183]},"}"]},f:[{t:2,r:"name",p:[59,10,2206]}," "]},{p:[60,21,2236],t:7,e:"br"}],n:52,r:"symptoms",p:[57,8,2059]}]}," ",{p:[63,7,2289],t:7,e:"ui-section",a:{label:"Resistance"},f:[{t:2,r:"resistance",p:[63,38,2320]}]}," ",{p:[64,7,2355],t:7,e:"ui-section",a:{label:"Stealth"},f:[{t:2,r:"stealth",p:[64,35,2383]}]}," ",{p:[65,7,2415],t:7,e:"ui-section",a:{label:"Stage speed"},f:[{t:2,r:"stage_speed",p:[65,39,2447]}]}," ",{p:[66,7,2483],t:7,e:"ui-section",a:{label:"Transmittability"},f:[{t:2,r:"transmission",p:[66,44,2520]}]}],n:50,r:"is_adv",p:[55,6,1999]}]}],n:52,r:"data.viruses",p:[39,4,1222]},{t:4,n:51,f:[{p:[70,5,2601],t:7,e:"ui-section",f:[{p:[71,6,2620],t:7,e:"span",a:{"class":"average"},f:["No detectable virus in the blood sample."]}]}],r:"data.viruses"}]}," ",{p:[75,3,2743],t:7,e:"ui-display",a:{title:"Antibodies"},f:[{t:4,f:[{p:[77,5,2811],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[77,24,2830]}]},f:[{p:[78,7,2848],t:7,e:"ui-button",a:{icon:"eyedropper",state:[{t:2,x:{r:["data.is_ready"],s:'_0?"":"disabled"'},p:[78,43,2884]}],action:"create_vaccine_bottle",params:['{"index": ',{t:2,r:"id",p:[78,129,2970]},"}"]},f:["Create vaccine bottle"]}]}],n:52,r:"data.resistances",p:[76,4,2779]},{t:4,n:51,f:[{p:[83,5,3067],t:7,e:"ui-section",f:[{p:[84,6,3086],t:7,e:"span",a:{"class":"average"},f:["No antibodies detected in the blood sample."]}]}],r:"data.resistances"}]}],n:50,r:"data.has_blood",p:[37,2,1162]}],n:50,x:{r:["data.mode"],s:"_0==1"},p:[1,1,0]},{t:4,n:51,f:[{p:[90,2,3231],t:7,e:"ui-button",a:{icon:"undo",state:"",action:"back"},f:["Back"]}," ",{t:4,f:[{p:[94,4,3330],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[94,23,3349]}]},f:[{p:[95,4,3364],t:7,e:"ui-section",f:[{t:2,r:"desc",p:[96,5,3382]}," ",{t:4,f:[{p:[98,5,3417],t:7,e:"br"}," ",{p:[99,5,3428],t:7,e:"b",f:["This symptom has been neutered, and has no effect. It will still affect the virus' statistics."]}],n:50,r:"neutered",p:[97,4,3395]}]}," ",{p:[102,4,3564],t:7,e:"ui-section",f:[{p:[103,5,3582],t:7,e:"ui-section",a:{label:"Level"},f:[{t:2,r:"level",p:[103,31,3608]}]}," ",{p:[104,5,3636],t:7,e:"ui-section",a:{label:"Resistance"},f:[{t:2,r:"resistance",p:[104,36,3667]}]}," ",{p:[105,5,3700],t:7,e:"ui-section",a:{label:"Stealth"},f:[{t:2,r:"stealth",p:[105,33,3728]}]}," ",{p:[106,5,3758],t:7,e:"ui-section",a:{label:"Stage speed"},f:[{t:2,r:"stage_speed",p:[106,37,3790]}]}," ",{p:[107,5,3824],t:7,e:"ui-section",a:{label:"Transmittability"},f:[{t:2,r:"transmission",p:[107,42,3861]}]}]}," ",{p:[109,4,3913],t:7,e:"ui-subdisplay",a:{title:"Effect Thresholds"},f:[{p:[110,5,3960],t:7,e:"ui-section",f:[{t:3,r:"threshold_desc",p:[110,17,3972]}]}]}]}],n:53,r:"data.symptom",p:[93,2,3303]}],x:{r:["data.mode"],s:"_0==1"}}]},e.exports=a.extend(r.exports)},{205:205}],289:[function(t,e,n){var a=t(205),r={exports:{}};!function(e){"use strict";var n=t(327);e.exports={data:{filter:"",tooltiptext:function(t,e,n){var a="";return t&&(a+="REQUIREMENTS: "+t+" "),e&&(a+="CATALYSTS: "+e+" "),n&&(a+="TOOLS: "+n),a}},oninit:function(){var t=this;this.on({hover:function(t){this.set("hovered",t.context.params)},unhover:function(t){this.set("hovered")}}),this.observe("filter",function(e,a,r){var i=null;i=t.get("data.display_compact")?t.findAll(".section"):t.findAll(".display:not(:first-child)"),(0,n.filterMulti)(i,t.get("filter").toLowerCase())},{init:!1})}}}(r),r.exports.template={v:3,t:[" ",{p:[48,1,1342],t:7,e:"ui-display",a:{title:[{t:2,r:"data.category",p:[48,20,1361]},{t:4,f:[" : ",{t:2,r:"data.subcategory",p:[48,64,1405]}],n:50,r:"data.subcategory",p:[48,37,1378]}]},f:[{t:4,f:[{p:[50,3,1459],t:7,e:"ui-section",f:["Crafting... ",{p:[51,16,1488],t:7,e:"i",a:{"class":"fa-spin fa fa-spinner"}}]}],n:50,r:"data.busy",p:[49,2,1438]},{t:4,n:51,f:[{p:[54,3,1557],t:7,e:"ui-section",f:[{p:[55,4,1574],t:7,e:"table",a:{style:"width:100%"},f:[{p:[56,5,1606],t:7,e:"tr",f:[{p:[57,6,1617],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[58,7,1659],t:7,e:"ui-button",a:{icon:"arrow-left",action:"backwardCat"},f:[{t:2,r:"data.prev_cat",p:[59,8,1718]}]}]}," ",{p:[62,6,1774],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[63,7,1816],t:7,e:"ui-button",a:{icon:"arrow-right",action:"forwardCat"},f:[{t:2,r:"data.next_cat",p:[64,7,1874]}]}]}," ",{p:[67,6,1930],t:7,e:"td",a:{style:"float:right!important"},f:[{t:4,f:[{p:[69,7,2014],t:7,e:"ui-button",a:{icon:"lock",action:"toggle_recipes"},f:["Showing Craftable Recipes"]}],n:50,r:"data.display_craftable_only",p:[68,6,1971]},{t:4,n:51,f:[{p:[73,7,2138],t:7,e:"ui-button",a:{icon:"unlock",action:"toggle_recipes"},f:["Showing All Recipes"]}],r:"data.display_craftable_only"}]}," ",{p:[78,6,2268],t:7,e:"td",a:{style:"float:right!important"},f:[{p:[79,7,2310],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.display_compact"],s:'_0?"check-square-o":"square-o"'},p:[79,24,2327]}],action:"toggle_compact"},f:["Compact"]}]}]}," ",{p:[84,5,2474],t:7,e:"tr",f:[{t:4,f:[{p:[86,6,2515],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[87,7,2557],t:7,e:"ui-button",a:{icon:"arrow-left",action:"backwardSubCat"},f:[{t:2,r:"data.prev_subcat",p:[88,8,2619]}]}]}," ",{p:[91,6,2678],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[92,7,2720],t:7,e:"ui-button",a:{icon:"arrow-right",action:"forwardSubCat"},f:[{t:2,r:"data.next_subcat",p:[93,8,2782]}]}]}],n:50,r:"data.subcategory",p:[85,5,2484]}]}]}," ",{t:4,f:[{t:4,f:[" ",{p:[101,6,2992],t:7,e:"ui-input",a:{value:[{t:2,r:"filter",p:[101,23,3009]}],placeholder:"Filter.."}}],n:51,r:"data.display_compact",p:[100,5,2902]}],n:50,r:"config.fancy",p:[99,4,2876]}]}," ",{t:4,f:[{p:[106,5,3144],t:7,e:"ui-display",f:[{t:4,f:[{p:[108,6,3193],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[108,25,3212]}]},f:[{p:[109,7,3230],t:7,e:"ui-button",a:{tooltip:[{t:2,x:{r:["tooltiptext","req_text","catalyst_text","tool_text"],s:"_0(_1,_2,_3)"},p:[109,27,3250]}],"tooltip-side":"right",action:"make",params:['{"recipe": "',{t:2,r:"ref",p:[109,135,3358]},'"}'],icon:"gears"},v:{hover:"hover",unhover:"unhover"},f:["Craft"]}]}],n:52,r:"data.can_craft",p:[107,5,3162]}," ",{t:4,f:[{t:4,f:[{p:[116,7,3567],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[116,26,3586]}]},f:[{p:[117,8,3605],t:7,e:"ui-button",a:{tooltip:[{t:2,x:{r:["tooltiptext","req_text","catalyst_text","tool_text"],s:"_0(_1,_2,_3)"},p:[117,28,3625]}],"tooltip-side":"right",state:"disabled",icon:"gears"},v:{hover:"hover",unhover:"unhover"},f:["Craft"]}]}],n:52,r:"data.cant_craft",p:[115,6,3534]}],n:51,r:"data.display_craftable_only",p:[114,5,3495]}]}],n:50,r:"data.display_compact",p:[105,4,3110]},{t:4,n:51,f:[{t:4,f:[{p:[126,6,3947],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[126,25,3966]}]},f:[{t:4,f:[{p:[128,8,4009],t:7,e:"ui-section",a:{label:"Requirements"},f:[{t:2,r:"req_text",p:[129,9,4052]}]}],n:50,r:"req_text",p:[127,7,3984]}," ",{t:4,f:[{p:[133,8,4139],t:7,e:"ui-section",a:{label:"Catalysts"},f:[{t:2,r:"catalyst_text",p:[134,9,4179]}]}],n:50,r:"catalyst_text",p:[132,7,4109]}," ",{t:4,f:[{p:[138,8,4267],t:7,e:"ui-section",a:{label:"Tools"},f:[{t:2,r:"tool_text",p:[139,9,4303]}]}],n:50,r:"tool_text",p:[137,7,4241]}," ",{p:[142,7,4361],t:7,e:"ui-section",f:[{p:[143,8,4382],t:7,e:"ui-button",a:{icon:"gears",action:"make",params:['{"recipe": "',{t:2,r:"ref",p:[143,66,4440]},'"}']},f:["Craft"]}]}]}],n:52,r:"data.can_craft",p:[125,5,3916]}," ",{t:4,f:[{t:4,f:[{p:[151,7,4621],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[151,26,4640]}]},f:[{t:4,f:[{p:[153,9,4685],t:7,e:"ui-section",a:{label:"Requirements"},f:[{t:2,r:"req_text",p:[154,10,4729]}]}],n:50,r:"req_text",p:[152,8,4659]}," ",{t:4,f:[{p:[158,9,4820],t:7,e:"ui-section",a:{label:"Catalysts"},f:[{t:2,r:"catalyst_text",p:[159,10,4861]}]}],n:50,r:"catalyst_text",p:[157,8,4789]}," ",{t:4,f:[{p:[163,9,4953],t:7,e:"ui-section",a:{label:"Tools"},f:[{t:2,r:"tool_text",p:[164,10,4990]}]}],n:50,r:"tool_text",p:[162,8,4926]}]}],n:52,r:"data.cant_craft",p:[150,6,4588]}],n:51,r:"data.display_craftable_only",p:[149,5,4549]}],r:"data.display_compact"}],r:"data.busy"}]}]},e.exports=a.extend(r.exports)},{205:205,327:327}],290:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,3,15],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.holding"],s:'_0?"is":"is not"'},p:[2,23,35]}," connected to a tank."]}]}," ",{p:[4,1,113],t:7,e:"ui-display",a:{title:"Status",button:0},f:[{p:[5,3,151],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[6,5,186],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[6,11,192]}," kPa"]}]}," ",{p:[8,3,254],t:7,e:"ui-section",a:{label:"Port"},f:[{p:[9,5,285],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected"],s:'_0?"good":"average"'},p:[9,18,298]}]},f:[{t:2,x:{r:["data.connected"],s:'_0?"Connected":"Not Connected"'},p:[9,59,339]}]}]}]}," ",{p:[12,1,430],t:7,e:"ui-display",a:{title:"Pump"},f:[{p:[13,3,459],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[14,5,491],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[14,22,508]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":"null"'},p:[15,14,559]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[16,22,616]}]}]}," ",{p:[18,3,675],t:7,e:"ui-section",a:{label:"Direction"},f:[{p:[19,5,711],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.direction"],s:'_0=="out"?"sign-out":"sign-in"'},p:[19,22,728]}],action:"direction"},f:[{t:2,x:{r:["data.direction"],s:'_0=="out"?"Out":"In"'},p:[20,26,808]}]}]}," ",{p:[22,3,883],t:7,e:"ui-section",a:{label:"Target Pressure"},f:[{p:[23,5,925],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.min_pressure",p:[23,18,938]}],max:[{t:2,r:"data.max_pressure",p:[23,46,966]}],value:[{t:2,r:"data.target_pressure",p:[24,14,1003]}]},f:[{t:2,x:{r:["adata.target_pressure"],s:"Math.round(_0)"},p:[24,40,1029]}," kPa"]}]}," ",{p:[26,3,1100],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[27,5,1145],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.target_pressure","data.default_pressure"],s:'_0!=_1?null:"disabled"'},p:[27,38,1178]}],action:"pressure",params:'{"pressure": "reset"}'},f:["Reset"]}," ",{p:[29,5,1328],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.target_pressure","data.min_pressure"],s:'_0>_1?null:"disabled"'},p:[29,36,1359]}],action:"pressure",params:'{"pressure": "min"}'},f:["Min"]}," ",{p:[31,5,1500],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[32,5,1595],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.target_pressure","data.max_pressure"],s:'_0<_1?null:"disabled"'},p:[32,35,1625]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}]}]}," ",{p:{button:[{t:4,f:[{p:[39,7,1891],t:7,e:"ui-button",a:{icon:"eject",style:[{t:2,x:{r:["data.on"],s:'_0?"danger":null'},p:[39,38,1922]}],action:"eject"},f:["Eject"]}],n:50,r:"data.holding",p:[38,5,1863]}]},t:7,e:"ui-display",a:{title:"Holding Tank",button:0},f:[" ",{t:4,f:[{p:[43,3,2042],t:7,e:"ui-section",a:{label:"Label"},f:[{t:2,r:"data.holding.name",p:[44,4,2073]}]}," ",{p:[46,3,2115],t:7,e:"ui-section",a:{label:"Pressure"},f:[{t:2,x:{r:["adata.holding.pressure"],s:"Math.round(_0)"},p:[47,4,2149]}," kPa"]}],n:50,r:"data.holding",p:[42,3,2018]},{t:4,n:51,f:[{p:[50,3,2223],t:7,e:"ui-section",f:[{p:[51,4,2240],t:7,e:"span",a:{"class":"average"},f:["No Holding Tank"]}]}],r:"data.holding"}]}]},e.exports=a.extend(r.exports)},{205:205}],291:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[3,1,69],t:7,e:"ui-notice",f:[{p:[4,3,84],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.holding"],s:'_0?"is":"is not"'},p:[4,23,104]}," connected to a tank."]}]}," ",{p:[6,1,182],t:7,e:"ui-display",a:{title:"Status",button:0},f:[{p:[7,3,220],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[8,5,255],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[8,11,261]}," kPa"]}]}," ",{p:[10,3,323],t:7,e:"ui-section",a:{label:"Port"},f:[{p:[11,5,354],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected"],s:'_0?"good":"average"'},p:[11,18,367]}]},f:[{t:2,x:{r:["data.connected"],s:'_0?"Connected":"Not Connected"'},p:[11,59,408]}]}]}]}," ",{p:[14,1,499],t:7,e:"ui-display",a:{title:"Filter"},f:[{p:[15,3,530],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[16,5,562],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[16,22,579]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":"null"'},p:[17,14,630]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[18,22,687]}]}]}]}," ",{p:{button:[{t:4,f:[{p:[24,7,856],t:7,e:"ui-button",a:{icon:"eject",style:[{t:2,x:{r:["data.on"],s:'_0?"danger":null'},p:[24,38,887]}],action:"eject"},f:["Eject"]}],n:50,r:"data.holding",p:[23,5,828]}]},t:7,e:"ui-display",a:{title:"Holding Tank",button:0},f:[" ",{t:4,f:[{p:[28,3,1007],t:7,e:"ui-section",a:{label:"Label"},f:[{t:2,r:"data.holding.name",p:[29,4,1038]}]}," ",{p:[31,3,1080],t:7,e:"ui-section",a:{label:"Pressure"},f:[{t:2,x:{r:["adata.holding.pressure"],s:"Math.round(_0)"},p:[32,4,1114]}," kPa"]}],n:50,r:"data.holding",p:[27,3,983]},{t:4,n:51,f:[{p:[35,3,1188],t:7,e:"ui-section",f:[{p:[36,4,1205],t:7,e:"span",a:{"class":"average"},f:["No Holding Tank"]}]}],r:"data.holding"}]}," ",{p:[40,1,1293],t:7,e:"ui-display",a:{title:"Filters"},f:[{t:4,f:[{p:[42,5,1345],t:7,e:"filters"}],n:53,r:"data",p:[41,3,1325]}]}]},r.exports.components=r.exports.components||{};var i={filters:t(299)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,299:299}],292:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{chargingState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}},chargingMode:function(t){return 2==t?"Full":1==t?"Charging":"Draining"},channelState:function(t){return t>=2?"good":"bad"},channelPower:function(t){return t>=2?"On":"Off"},channelMode:function(t){return 1==t||3==t?"Auto":"Manual"}},computed:{graphData:function(){var t=this.get("data.history");return Object.keys(t).map(function(e){return t[e].map(function(t,e){return{x:e,y:t}})})}}}}(r),r.exports.template={v:3,t:[" ",{p:[42,1,1035],t:7,e:"ui-display",a:{title:"Network"},f:[{t:4,f:[{p:[44,5,1093],t:7,e:"ui-linegraph",a:{points:[{t:2,r:"graphData",p:[44,27,1115]}],height:"500",legend:'["Available", "Load"]',colors:'["rgb(0, 102, 0)", "rgb(153, 0, 0)"]',xunit:"seconds ago",xfactor:[{t:2,r:"data.interval",p:[46,38,1267]}],yunit:"W",yfactor:"1",xinc:[{t:2,x:{r:["data.stored"],s:"_0/10"},p:[47,15,1323]}],yinc:"9"}}],n:50,r:"config.fancy",p:[43,3,1067]},{t:4,n:51,f:[{p:[49,5,1373],t:7,e:"ui-section",a:{label:"Available"},f:[{p:[50,7,1411],t:7,e:"span",f:[{t:2,r:"data.supply",p:[50,13,1417]}]}]}," ",{p:[52,5,1464],t:7,e:"ui-section",a:{label:"Load"},f:[{p:[53,9,1499],t:7,e:"span",f:[{t:2,r:"data.demand",p:[53,15,1505]}]}]}],r:"config.fancy"}]}," ",{p:[57,1,1574],t:7,e:"ui-display",a:{title:"Areas"},f:[{p:[58,3,1604],t:7,e:"ui-section",a:{nowrap:0},f:[{p:[59,5,1629],t:7,e:"div",a:{"class":"content"},f:["Area"]}," ",{p:[60,5,1666],t:7,e:"div",a:{"class":"content"},f:["Charge"]}," ",{p:[61,5,1705],t:7,e:"div",a:{"class":"content"},f:["Load"]}," ",{p:[62,5,1742],t:7,e:"div",a:{"class":"content"},f:["Status"]}," ",{p:[63,5,1781],t:7,e:"div",a:{"class":"content"},f:["Equipment"]}," ",{p:[64,5,1823],t:7,e:"div",a:{"class":"content"},f:["Lighting"]}," ",{p:[65,5,1864],t:7,e:"div",a:{"class":"content"},f:["Environment"]}]}," ",{t:4,f:[{p:[68,5,1949],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[68,24,1968]}],nowrap:0},f:[{p:[69,7,1993],t:7,e:"div",a:{"class":"content"},f:[{t:2,x:{r:["@index","adata.areas"],s:"Math.round(_1[_0].charge)"},p:[69,28,2014]}," %"]}," ",{p:[70,7,2072],t:7,e:"div",a:{"class":"content"},f:[{t:2,rx:{r:"adata.areas",m:[{t:30,n:"@index"},"load"]},p:[70,28,2093]}]}," ",{p:[71,7,2135],t:7,e:"div",a:{"class":"content"},f:[{p:[71,28,2156],t:7,e:"span",a:{"class":[{t:2,x:{r:["chargingState","charging"],s:"_0(_1)"},p:[71,41,2169]}]},f:[{t:2,x:{r:["chargingMode","charging"],s:"_0(_1)"},p:[71,70,2198]}]}]}," ",{p:[72,7,2245],t:7,e:"div",a:{"class":"content"},f:[{p:[72,28,2266],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","eqp"],s:"_0(_1)"},p:[72,41,2279]}]},f:[{t:2,x:{r:["channelPower","eqp"],s:"_0(_1)"},p:[72,64,2302]}," [",{p:[72,87,2325],t:7,e:"span",f:[{t:2,x:{r:["channelMode","eqp"],s:"_0(_1)"},p:[72,93,2331]}]},"]"]}]}," ",{p:[73,7,2380],t:7,e:"div",a:{"class":"content"},f:[{p:[73,28,2401],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","lgt"],s:"_0(_1)"},p:[73,41,2414]}]},f:[{t:2,x:{r:["channelPower","lgt"],s:"_0(_1)"},p:[73,64,2437]}," [",{p:[73,87,2460],t:7,e:"span",f:[{t:2,x:{r:["channelMode","lgt"],s:"_0(_1)"},p:[73,93,2466]}]},"]"]}]}," ",{p:[74,7,2515],t:7,e:"div",a:{"class":"content"},f:[{p:[74,28,2536],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","env"],s:"_0(_1)"},p:[74,41,2549]}]},f:[{t:2,x:{r:["channelPower","env"],s:"_0(_1)"},p:[74,64,2572]}," [",{p:[74,87,2595],t:7,e:"span",f:[{t:2,x:{r:["channelMode","env"],s:"_0(_1)"},p:[74,93,2601]}]},"]"]}]}]}],n:52,r:"data.areas",p:[67,3,1923]}]}]},e.exports=a.extend(r.exports)},{205:205}],293:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{readableFrequency:function(){return Math.round(this.get("adata.frequency"))/10}}}}(r),r.exports.template={v:3,t:[" ",{p:[11,1,177],t:7,e:"ui-display",a:{title:"Settings"},f:[{t:4,f:[{p:[13,5,236],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[14,7,270],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.listening"],s:'_0?"power-off":"close"'},p:[14,24,287]}],style:[{t:2,x:{r:["data.listening"],s:'_0?"selected":null'},p:[14,75,338]}],action:"listen"},f:[{t:2,x:{r:["data.listening"],s:'_0?"On":"Off"'},p:[16,9,413]}]}]}],n:50,r:"data.headset",p:[12,3,210]},{t:4,n:51,f:[{p:[19,5,494],t:7,e:"ui-section",a:{label:"Microphone"},f:[{p:[20,7,533],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.broadcasting"],s:'_0?"power-off":"close"'},p:[20,24,550]}],style:[{t:2,x:{r:["data.broadcasting"],s:'_0?"selected":null'},p:[20,78,604]}],action:"broadcast"},f:[{t:2,x:{r:["data.broadcasting"],s:'_0?"Engaged":"Disengaged"'},p:[22,9,685]}]}]}," ",{p:[24,5,769],t:7,e:"ui-section",a:{label:"Speaker"},f:[{p:[25,7,805],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.listening"],s:'_0?"power-off":"close"'},p:[25,24,822]}],style:[{t:2,x:{r:["data.listening"],s:'_0?"selected":null'},p:[25,75,873]}],action:"listen"},f:[{t:2,x:{r:["data.listening"],s:'_0?"Engaged":"Disengaged"'},p:[27,9,948]}]}]}],r:"data.headset"}," ",{t:4,f:[{p:[31,5,1064],t:7,e:"ui-section",a:{label:"High Volume"},f:[{p:[32,7,1104],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.useCommand"],s:'_0?"power-off":"close"'},p:[32,24,1121]}],style:[{t:2,x:{r:["data.useCommand"],s:'_0?"selected":null'},p:[32,76,1173]}],action:"command"},f:[{t:2,x:{r:["data.useCommand"],s:'_0?"On":"Off"'},p:[34,9,1250]}]}]}],n:50,r:"data.command",p:[30,3,1038]}]}," ",{p:[38,1,1342],t:7,e:"ui-display",a:{title:"Channel"},f:[{p:[39,3,1374],t:7,e:"ui-section",a:{label:"Frequency"},f:[{t:4,f:[{p:[41,7,1439],t:7,e:"span",f:[{t:2,r:"readableFrequency",p:[41,13,1445]}]}],n:50,r:"data.freqlock",p:[40,5,1410]},{t:4,n:51,f:[{p:[43,7,1495],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.frequency","data.minFrequency"],s:'_0==_1?"disabled":null'},p:[43,46,1534]}],action:"frequency",params:'{"adjust": -1}'}}," ",{p:[44,7,1646],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.frequency","data.minFrequency"],s:'_0==_1?"disabled":null'},p:[44,41,1680]}],action:"frequency",params:'{"adjust": -.2}'}}," ",{p:[45,7,1793],t:7,e:"ui-button",a:{icon:"pencil",action:"frequency",params:'{"tune": "input"}'},f:[{t:2,r:"readableFrequency",p:[45,78,1864]}]}," ",{p:[46,7,1905],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.frequency","data.maxFrequency"],s:'_0==_1?"disabled":null'},p:[46,40,1938]}],action:"frequency",params:'{"adjust": .2}'}}," ",{p:[47,7,2050],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.frequency","data.maxFrequency"],s:'_0==_1?"disabled":null'},p:[47,45,2088]}],action:"frequency",params:'{"adjust": 1}'}}],r:"data.freqlock"}]}," ",{t:4,f:[{p:[51,5,2262],t:7,e:"ui-section",a:{label:"Subspace Transmission"},f:[{p:[52,7,2312],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.subspace"],s:'_0?"power-off":"close"'},p:[52,24,2329]}],style:[{t:2,x:{r:["data.subspace"],s:'_0?"selected":null'},p:[52,74,2379]}],action:"subspace"},f:[{t:2,x:{r:["data.subspace"],s:'_0?"Active":"Inactive"'},p:[53,29,2447]}]}]}],n:50,r:"data.subspaceSwitchable",p:[50,3,2225]}," ",{t:4,f:[{p:[57,5,2578],t:7,e:"ui-section",a:{label:"Channels"},f:[{t:4,f:[{p:[59,9,2656],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["."],s:'_0?"check-square-o":"square-o"'},p:[59,26,2673]}],style:[{t:2,x:{r:["."],s:'_0?"selected":null'},p:[60,18,2730]}],action:"channel",params:['{"channel": "',{t:2,r:"channel",p:[61,49,2806]},'"}']},f:[{t:2,r:"channel",p:[62,11,2833]}]},{p:[62,34,2856],t:7,e:"br"}],n:52,i:"channel",r:"data.channels",p:[58,7,2615]}]}],n:50,x:{r:["data.subspace","data.channels"],s:"_0&&_1"},p:[56,3,2534]}]}]},e.exports=a.extend(r.exports)},{205:205}],294:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,1,25],t:7,e:"ui-notice",f:[{p:[3,3,40],t:7,e:"span",f:["The grinder is currently processing and cannot be used."]}]}],n:50,r:"data.processing",p:[1,1,0]},{p:{button:[{p:[8,5,208],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.operating","data.contents"],s:'(_0==0)&&_1?null:"disabled"'},p:[8,36,239]}],action:"eject"},f:["Eject Contents"]}]},t:7,e:"ui-display",a:{title:"Processing Chamber",button:0},f:[" ",{p:[10,3,364],t:7,e:"ui-section",a:{label:"Grinding"},f:[{p:[11,5,399],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.operating"],s:'_0?"average":"good"'},p:[11,18,412]}]},f:[{t:2,x:{r:["data.operating"],s:'_0?"Busy":"Ready"'},p:[11,59,453]}]}," ",{p:[12,2,500],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.operating","data.contents"],s:'(_0==0)&&_1?null:"disabled"'},p:[12,35,533]}],action:"grind"},f:["Activate"]}]}," ",{p:[14,3,653],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{t:4,f:[{p:[17,9,755],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:["The ",{t:2,r:"name",p:[17,56,802]}]},{p:[17,71,817],t:7,e:"br"}],n:52,r:"adata.contentslist",p:[16,7,717]},{t:4,n:51,f:[{p:[19,9,848],t:7,e:"span",f:["No Contents"]}],r:"adata.contentslist"}],n:50,r:"data.contents",p:[15,5,688]},{t:4,n:51,f:[{p:[22,7,911],t:7,e:"span",f:["No Contents"]}],r:"data.contents"}]}]}," ",{p:{button:[{p:[28,5,1047],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.operating","data.isBeakerLoaded"],s:'(_0==0)&&_1?null:"disabled"'},p:[28,36,1078]}],action:"detach"},f:["Detach"]}]},t:7,e:"ui-display",a:{title:"Container",button:0},f:[" ",{p:[30,3,1202],t:7,e:"ui-section",a:{label:"Reagents"},f:[{t:4,f:[{p:[32,7,1272],t:7,e:"span",f:[{t:2,x:{r:["adata.beakerCurrentVolume"],s:"Math.round(_0)"},p:[32,13,1278]},"/",{t:2,r:"data.beakerMaxVolume",p:[32,55,1320]}," Units"]}," ",{p:[33,7,1365],t:7,e:"br"}," ",{t:4,f:[{p:[35,9,1418],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[35,52,1461]}," units of ",{t:2,r:"name",p:[35,87,1496]}]},{p:[35,102,1511],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[34,7,1378]},{t:4,n:51,f:[{p:[37,9,1542],t:7,e:"span",a:{"class":"bad"},f:["Container Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[31,5,1237]},{t:4,n:51,f:[{p:[40,7,1621],t:7,e:"span",a:{"class":"average"},f:["No Container"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],295:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" "," ",{t:4,f:[{p:[5,2,123],t:7,e:"dirsel"}],n:50,x:{r:["data.mode"],s:"_0>=0"},p:[4,1,98]},{t:4,f:[{p:[8,2,187],t:7,e:"colorsel"}],n:50,x:{r:["data.mode"],s:"_0==-2||_0==0"},p:[7,1,143]},{p:[10,1,209],t:7,e:"ui-display",a:{title:"Utilities"},f:[{p:[11,2,242],t:7,e:"ui-section",f:[{p:[12,3,258],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0>=0?"check-square-o":"square-o"'},p:[12,20,275]}],state:[{t:2,x:{r:["data.mode"],s:'_0>=0?"selected":null'},p:[12,79,334]}],action:"mode",params:['{"mode": ',{t:2,r:"data.screen",p:[13,35,409]},"}"]},f:["Lay Pipes"]}]}," ",{p:[15,2,467],t:7,e:"ui-section",f:[{p:[16,3,483],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0==-1?"check-square-o":"square-o"'},p:[16,20,500]}],state:[{t:2,x:{r:["data.mode"],s:'_0==-1?"selected":null'},p:[16,80,560]}],action:"mode",params:'{"mode": -1}'},f:["Eat Pipes"]}]}," ",{p:[19,2,681],t:7,e:"ui-section",f:[{p:[20,3,697],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0==-2?"check-square-o":"square-o"'},p:[20,20,714]}],state:[{t:2,x:{r:["data.mode"],s:'_0==-2?"selected":null'},p:[20,80,774]}],action:"mode",params:'{"mode": -2}'},f:["Paint Pipes"]}]}]}," ",{p:[24,1,911],t:7,e:"ui-display",a:{title:"Category"},f:[{p:[25,2,943],t:7,e:"ui-section",f:[{p:[26,3,959],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.screen"],s:'_0==0?"check-square-o":"square-o"'},p:[26,20,976]}],state:[{t:2,x:{r:["data.screen"],s:'_0==0?"selected":null'},p:[26,81,1037]}],action:"screen",params:'{"screen": 0}'},f:["Atmospherics"]}," ",{p:[28,3,1150],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.screen"],s:'_0==2?"check-square-o":"square-o"'},p:[28,20,1167]}],state:[{t:2,x:{r:["data.screen"],s:'_0==2?"selected":null'},p:[28,81,1228]}],action:"screen",params:'{"screen": 2}'},f:["Disposals"]}]}," ",{t:4,f:[{p:[32,3,1381],t:7,e:"ui-section",a:{label:"Piping Layer"},f:[{p:[33,4,1419],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.piping_layer"],s:'_0==1?"selected":null'},p:[33,22,1437]}],action:"piping_layer",params:'{"piping_layer": 1}'},f:["1"]}," ",{p:[35,4,1559],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.piping_layer"],s:'_0==2?"selected":null'},p:[35,22,1577]}],action:"piping_layer",params:'{"piping_layer": 2}'},f:["2"]}," ",{p:[37,4,1699],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.piping_layer"],s:'_0==3?"selected":null'},p:[37,22,1717]}],action:"piping_layer",params:'{"piping_layer": 3}'},f:["3"]}]}],n:50,x:{r:["data.screen"],s:"_0==0"},p:[31,2,1353]}]}," ",{t:4,f:[{p:[43,2,1906],t:7,e:"ui-display",a:{title:[{t:2,r:"cat_name",p:[43,21,1925]}]},f:[{t:4,f:[{p:[45,4,1965],t:7,e:"ui-section",f:[{p:[46,5,1983],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[46,23,2001]}],action:"pipe_type",params:['{"pipe_type": ',{t:2,r:"pipe_index",p:[47,28,2082]},', "category": ',{t:2,r:"cat_name",p:[47,56,2110]},"}"]},f:[{t:2,r:"pipe_name",p:[47,71,2125]}]}]}],n:52,r:"recipes",p:[44,3,1943]}]}],n:52,r:"data.categories",p:[42,1,1878]}]},r.exports.components=r.exports.components||{};var i={colorsel:t(296),dirsel:t(297)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,296:296,297:297}],296:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Color"},f:[{t:4,f:[{p:[3,3,60],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[3,21,78]}],action:"color",params:['{"paint_color": ',{t:2,r:"color_name",p:[4,28,155]},"}"]},f:[{t:2,r:"color_name",p:[4,45,172]}]}],n:52,r:"data.paint_colors",p:[2,2,29]}]}]},e.exports=a.extend(r.exports)},{205:205}],297:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Direction"},f:[{t:4,f:[{p:[3,3,64],t:7,e:"ui-section",f:[{t:4,f:[{p:[5,5,105],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[5,23,123]}],action:"setdir",params:['{"dir": ',{t:2,r:"dir",p:[6,22,195]},', "flipped": ',{t:2,r:"flipped",p:[6,42,215]},"}"]},f:[{p:[6,56,229],t:7,e:"img",a:{src:["pipe.",{t:2,r:"dir",p:[6,71,244]},".",{t:2,r:"icon_state",p:[6,79,252]},".png"],title:[{t:2,r:"dir_name",p:[6,106,279]}]}}]}],n:52,r:"previews",p:[4,4,81]}]}],n:52,r:"data.preview_rows",p:[2,2,33]}]}]},e.exports=a.extend(r.exports)},{205:205}],298:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,23],t:7,e:"ui-notice",f:[{t:2,r:"data.notice",p:[3,5,40]}]}],n:50,r:"data.notice",p:[1,1,0]},{p:[6,1,82], +t:7,e:"ui-display",a:{title:"Satellite Network Control",button:0},f:[{t:4,f:[{p:[8,4,168],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{p:[9,9,209],t:7,e:"div",a:{"class":"content"},f:["#",{t:2,r:"id",p:[9,31,231]}]}," ",{p:[10,9,253],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"mode",p:[10,30,274]}]}," ",{p:[11,9,298],t:7,e:"div",a:{"class":"content"},f:[{p:[12,11,331],t:7,e:"ui-button",a:{action:"toggle",params:['{"id": "',{t:2,r:"id",p:[12,54,374]},'"}']},f:[{t:2,x:{r:["active"],s:'_0?"Deactivate":"Activate"'},p:[12,64,384]}]}]}]}],n:52,r:"data.satellites",p:[7,2,138]}]}," ",{t:4,f:[{p:[18,1,528],t:7,e:"ui-display",a:{title:"Station Shield Coverage"},f:[{p:[19,3,576],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.meteor_shield_coverage_max",p:[19,24,597]}],value:[{t:2,r:"data.meteor_shield_coverage",p:[19,68,641]}]},f:[{t:2,x:{r:["data.meteor_shield_coverage","data.meteor_shield_coverage_max"],s:"100*_0/_1"},p:[19,101,674]}," %"]}," ",{p:[20,1,758],t:7,e:"ui-display",f:[]}]}],n:50,r:"data.meteor_shield",p:[17,1,500]}]},e.exports=a.extend(r.exports)},{205:205}],299:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,26],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["enabled"],s:'_0?"check-square-o":"square-o"'},p:[2,20,43]}],style:[{t:2,x:{r:["enabled"],s:'_0?"selected":null'},p:[2,72,95]}],action:"toggle_filter",params:['{"id_tag": "',{t:2,r:"id_tag",p:[3,48,176]},'", "val": ',{t:2,r:"gas_id",p:[3,68,196]},"}"]},f:[{t:2,r:"gas_name",p:[3,81,209]}]}],n:52,r:"filter_types",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{205:205}],300:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" "," "," ",{p:[5,1,200],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.tabs",p:[5,16,215]}]},f:[{p:[6,2,233],t:7,e:"tab",a:{name:"Status"},f:[{p:[7,3,256],t:7,e:"status"}]}," ",{p:[9,2,277],t:7,e:"tab",a:{name:"Templates"},f:[{p:[10,3,303],t:7,e:"templates"}]}," ",{p:[12,2,327],t:7,e:"tab",a:{name:"Modification"},f:[{t:4,f:[{p:[14,3,381],t:7,e:"modification"}],n:50,r:"data.selected",p:[13,3,356]}," ",{t:4,f:[{p:[17,3,437],t:7,e:"span",a:{"class":"bad"},f:["No shuttle selected."]}],n:50,x:{r:["data.selected"],s:"!_0"},p:[16,3,411]}]}]}]},r.exports.components=r.exports.components||{};var i={modification:t(301),templates:t(303),status:t(302)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,301:301,302:302,303:303}],301:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:["Selected: ",{t:2,r:"data.selected.name",p:[1,30,29]}]},f:[{t:4,f:[{p:[3,5,96],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"data.selected.description",p:[3,37,128]}]}],n:50,r:"data.selected.description",p:[2,3,57]}," ",{t:4,f:[{p:[6,5,224],t:7,e:"ui-section",a:{label:"Admin Notes"},f:[{t:2,r:"data.selected.admin_notes",p:[6,37,256]}]}],n:50,r:"data.selected.admin_notes",p:[5,3,185]}]}," ",{t:4,f:[{p:[11,3,361],t:7,e:"ui-display",a:{title:["Existing Shuttle: ",{t:2,r:"data.existing_shuttle.name",p:[11,40,398]}]},f:["Status: ",{t:2,r:"data.existing_shuttle.status",p:[12,13,444]}," ",{t:4,f:["(",{t:2,r:"data.existing_shuttle.timeleft",p:[14,8,526]},")"],n:50,r:"data.existing_shuttle.timer",p:[13,5,482]}," ",{p:[16,5,580],t:7,e:"ui-button",a:{action:"jump_to",params:['{"type": "mobile", "id": "',{t:2,r:"data.existing_shuttle.id",p:[17,41,649]},'"}']},f:["Jump To"]}]}],n:50,r:"data.existing_shuttle",p:[10,1,328]},{t:4,f:[{p:[24,3,778],t:7,e:"ui-display",a:{title:"Existing Shuttle: None"}}],n:50,x:{r:["data.existing_shuttle"],s:"!_0"},p:[23,1,744]},{p:[27,1,847],t:7,e:"ui-button",a:{action:"preview",params:['{"shuttle_id": "',{t:2,r:"data.selected.shuttle_id",p:[28,27,902]},'"}']},f:["Preview"]}," ",{p:[31,1,961],t:7,e:"ui-button",a:{action:"load",params:['{"shuttle_id": "',{t:2,r:"data.selected.shuttle_id",p:[32,27,1013]},'"}'],style:"danger"},f:["Load"]}," ",{p:[37,1,1089],t:7,e:"ui-display",a:{title:"Status"},f:[]}]},e.exports=a.extend(r.exports)},{205:205}],302:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,27],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[2,22,46]}," (",{t:2,r:"id",p:[2,32,56]},")"]},f:[{t:2,r:"status",p:[3,5,71]}," ",{t:4,f:["(",{t:2,r:"timeleft",p:[5,8,109]},")"],n:50,r:"timer",p:[4,5,87]}," ",{p:[7,5,141],t:7,e:"ui-button",a:{action:"jump_to",params:['{"type": "mobile", "id": "',{t:2,r:"id",p:[7,67,203]},'"}']},f:["Jump To"]}," ",{p:[10,5,252],t:7,e:"ui-button",a:{action:"fast_travel",params:['{"id": "',{t:2,r:"id",p:[10,53,300]},'"}'],state:[{t:2,x:{r:["can_fast_travel"],s:'_0?null:"disabled"'},p:[10,70,317]}]},f:["Fast Travel"]}]}],n:52,r:"data.shuttles",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{205:205}],303:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.templates_tabs",p:[1,16,15]}]},f:[{t:4,f:[{p:[3,5,74],t:7,e:"tab",a:{name:[{t:2,r:"port_id",p:[3,16,85]}]},f:[{t:4,f:[{p:[5,9,135],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[5,28,154]}]},f:[{t:4,f:[{p:[7,13,209],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"description",p:[7,45,241]}]}],n:50,r:"description",p:[6,11,176]}," ",{t:4,f:[{p:[10,13,333],t:7,e:"ui-section",a:{label:"Admin Notes"},f:[{t:2,r:"admin_notes",p:[10,45,365]}]}],n:50,r:"admin_notes",p:[9,11,300]}," ",{p:[13,11,426],t:7,e:"ui-button",a:{action:"select_template",params:['{"shuttle_id": "',{t:2,r:"shuttle_id",p:[14,37,499]},'"}'],state:[{t:2,x:{r:["data.selected.shuttle_id","shuttle_id"],s:'_0==_1?"selected":null'},p:[15,20,537]}]},f:[{t:2,x:{r:["data.selected.shuttle_id","shuttle_id"],s:'_0==_1?"Selected":"Select"'},p:[17,13,630]}]}]}],n:52,r:"templates",p:[4,7,106]}]}],n:52,r:"data.templates",p:[2,3,44]}]}]},e.exports=a.extend(r.exports)},{205:205}],304:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Occupant"},f:[{p:[2,3,33],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[3,3,66],t:7,e:"span",f:[{t:2,x:{r:["data.occupant.name"],s:'_0?_0:"No Occupant"'},p:[3,9,72]}]}]}," ",{t:4,f:[{p:[6,5,186],t:7,e:"ui-section",a:{label:"State"},f:[{p:[7,7,220],t:7,e:"span",a:{"class":[{t:2,r:"data.occupant.statstate",p:[7,20,233]}]},f:[{t:2,r:"data.occupant.stat",p:[7,49,262]}]}]}," ",{p:[9,5,315],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[10,7,350],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.occupant.minHealth",p:[10,20,363]}],max:[{t:2,r:"data.occupant.maxHealth",p:[10,54,397]}],value:[{t:2,r:"data.occupant.health",p:[10,90,433]}],state:[{t:2,x:{r:["data.occupant.health"],s:'_0>=0?"good":"average"'},p:[11,16,475]}]},f:[{t:2,x:{r:["adata.occupant.health"],s:"Math.round(_0)"},p:[11,68,527]}]}]}," ",{t:4,f:[{p:[14,7,764],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[14,26,783]}]},f:[{p:[15,9,804],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.occupant.maxHealth",p:[15,30,825]}],value:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[15,66,861]}],state:"bad"},f:[{t:2,x:{r:["type","adata.occupant"],s:"Math.round(_1[_0])"},p:[15,103,898]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Respiratory",type:"oxyLoss"},{label:"Toxin",type:"toxLoss"},{label:"Burn",type:"fireLoss"}]'},p:[13,5,598]}," ",{p:[18,5,985],t:7,e:"ui-section",a:{label:"Cells"},f:[{p:[19,9,1021],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"bad":"good"'},p:[19,22,1034]}]},f:[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"Damaged":"Healthy"'},p:[19,68,1080]}]}]}," ",{p:[21,5,1163],t:7,e:"ui-section",a:{label:"Brain"},f:[{p:[22,9,1199],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"bad":"good"'},p:[22,22,1212]}]},f:[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"Abnormal":"Healthy"'},p:[22,68,1258]}]}]}," ",{p:[24,5,1342],t:7,e:"ui-section",a:{label:"Bloodstream"},f:[{t:4,f:[{p:[26,11,1429],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,1)"},p:[26,54,1472]}," units of ",{t:2,r:"name",p:[26,89,1507]}]},{p:[26,104,1522],t:7,e:"br"}],n:52,r:"adata.occupant.reagents",p:[25,9,1384]},{t:4,n:51,f:[{p:[28,11,1557],t:7,e:"span",a:{"class":"good"},f:["Pure"]}],r:"adata.occupant.reagents"}]}],n:50,r:"data.occupied",p:[5,3,159]}]}," ",{p:[33,1,1653],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[34,2,1685],t:7,e:"ui-section",a:{label:"Door"},f:[{p:[35,5,1716],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.open"],s:'_0?"unlock":"lock"'},p:[35,22,1733]}],action:"door"},f:[{t:2,x:{r:["data.open"],s:'_0?"Open":"Closed"'},p:[35,71,1782]}]}]}," ",{p:[37,3,1847],t:7,e:"ui-section",a:{label:"Inject"},f:[{t:4,f:[{p:[39,7,1908],t:7,e:"ui-button",a:{icon:"flask",state:[{t:2,x:{r:["data.occupied","allowed"],s:'_0&&_1?null:"disabled"'},p:[39,38,1939]}],action:"inject",params:['{"chem": "',{t:2,r:"id",p:[39,122,2023]},'"}']},f:[{t:2,r:"name",p:[39,132,2033]}]},{p:[39,152,2053],t:7,e:"br"}],n:52,r:"data.chems",p:[38,5,1880]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],305:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,25],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[2,22,44]}],labelcolor:[{t:2,r:"htmlcolor",p:[2,44,66]}],candystripe:0,right:0},f:[{p:[3,5,105],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[3,32,132],t:7,e:"span",a:{"class":[{t:2,x:{r:["status"],s:'_0=="Dead"?"bad bold":_0=="Unconscious"?"average bold":"good"'},p:[3,45,145]}]},f:[{t:2,r:"status",p:[3,132,232]}]}]}," ",{p:[4,5,268],t:7,e:"ui-section",a:{label:"Jelly"},f:[{t:2,r:"exoticblood",p:[4,31,294]}]}," ",{p:[5,5,328],t:7,e:"ui-section",a:{label:"Location"},f:[{t:2,r:"area",p:[5,34,357]}]}," ",{p:[7,5,386],t:7,e:"ui-button",a:{state:[{t:2,r:"swap_button_state",p:[8,14,411]}],action:"swap",params:['{"ref": "',{t:2,r:"ref",p:[9,38,472]},'"}']},f:[{t:2,x:{r:["is_current"],s:'_0?"You Are Here":"Swap"'},p:[10,7,491]}]}]}],n:52,r:"data.bodies",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{205:205}],306:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{t:4,f:[{p:[4,23,82],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.drying"],s:'_0?"stop":"tint"'},p:[4,40,99]}],action:"Dry"},f:[{t:2,x:{r:["data.drying"],s:'_0?"Stop drying":"Dry"'},p:[4,88,147]}]}],n:50,r:"data.isdryer",p:[4,3,62]}]},t:7,e:"ui-display",a:{title:"Storage",button:0},f:[" ",{t:4,f:[{p:[7,3,258],t:7,e:"ui-notice",f:[{p:[8,5,275],t:7,e:"span",f:["Unfortunately, this ",{t:2,r:"data.name",p:[8,31,301]}," is empty."]}]}],n:50,x:{r:["data.contents.length"],s:"_0==0"},p:[6,1,221]},{t:4,n:51,f:[{p:[11,1,359],t:7,e:"div",a:{"class":"display tabular"},f:[{p:[12,2,391],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[13,4,425],t:7,e:"section",a:{"class":"cell bold"},f:["Item"]}," ",{p:[16,4,482],t:7,e:"section",a:{"class":"cell bold"},f:["Quantity"]}," ",{p:[19,4,543],t:7,e:"section",a:{"class":"cell bold",align:"center"},f:[{t:4,f:[{t:2,r:"data.verb",p:[20,22,608]}],n:50,r:"data.verb",p:[20,5,591]},{t:4,n:51,f:["Dispense"],r:"data.verb"}]}]}," ",{t:4,f:[{p:[24,3,703],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[25,4,737],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[26,5,765]}]}," ",{p:[28,4,793],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"amount",p:[29,5,835]}]}," ",{p:[31,4,865],t:7,e:"section",a:{"class":"table",alight:"right"},f:[{p:[32,5,909],t:7,e:"section",a:{"class":"cell"}}," ",{p:[33,5,947],t:7,e:"section",a:{"class":"cell"},f:[{p:[34,6,976],t:7,e:"ui-button",a:{grid:0,action:"Release",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[34,45,1015]}],params:['{ "name" : ',{t:2,r:"name",p:[34,102,1072]},', "amount" : 1 }']},f:["One"]}]}," ",{p:[38,5,1151],t:7,e:"section",a:{"class":"cell"},f:[{p:[39,6,1180],t:7,e:"ui-button",a:{grid:0,action:"Release",state:[{t:2,x:{r:["amount"],s:'(_0>1)?null:"disabled"'},p:[39,45,1219]}],params:['{ "name" : ',{t:2,r:"name",p:[39,101,1275]}," }"]},f:["Many"]}]}]}]}],n:52,r:"data.contents",p:[23,2,676]}]}],x:{r:["data.contents.length"],s:"_0==0"}}]}]},e.exports=a.extend(r.exports)},{205:205}],307:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{capacityPercentState:function(){var t=this.get("data.capacityPercent");return t>50?"good":t>15?"average":"bad"},inputState:function(){return this.get("data.capacityPercent")>=100?"good":this.get("data.inputting")?"average":"bad"},outputState:function(){return this.get("data.outputting")?"good":this.get("data.charge")>0?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[24,1,663],t:7,e:"ui-display",a:{title:"Storage"},f:[{p:[25,3,695],t:7,e:"ui-section",a:{label:"Stored Energy"},f:[{p:[26,5,735],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.capacityPercent",p:[26,38,768]}],state:[{t:2,r:"capacityPercentState",p:[26,71,801]}]},f:[{t:2,x:{r:["adata.capacityPercent"],s:"Math.fixed(_0)"},p:[26,97,827]},"%"]}]}]}," ",{p:[29,1,908],t:7,e:"ui-display",a:{title:"Input"},f:[{p:[30,3,938],t:7,e:"ui-section",a:{label:"Charge Mode"},f:[{p:[31,5,976],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"refresh":"close"'},p:[31,22,993]}],style:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"selected":null'},p:[31,74,1045]}],action:"tryinput"},f:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"Auto":"Off"'},p:[32,25,1113]}]},"   [",{p:[34,6,1182],t:7,e:"span",a:{"class":[{t:2,r:"inputState",p:[34,19,1195]}]},f:[{t:2,x:{r:["data.capacityPercent","data.inputting"],s:'_0>=100?"Fully Charged":_1?"Charging":"Not Charging"'},p:[34,35,1211]}]},"]"]}," ",{p:[36,3,1335],t:7,e:"ui-section",a:{label:"Target Input"},f:[{p:[37,5,1374],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.inputLevelMax",p:[37,26,1395]}],value:[{t:2,r:"data.inputLevel",p:[37,57,1426]}]},f:[{t:2,r:"adata.inputLevel_text",p:[37,78,1447]}]}]}," ",{p:[39,3,1501],t:7,e:"ui-section",a:{label:"Adjust Input"},f:[{p:[40,5,1540],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.inputLevel"],s:'_0==0?"disabled":null'},p:[40,44,1579]}],action:"input",params:'{"target": "min"}'}}," ",{p:[41,5,1674],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.inputLevel"],s:'_0==0?"disabled":null'},p:[41,39,1708]}],action:"input",params:'{"adjust": -10000}'}}," ",{p:[42,5,1804],t:7,e:"ui-button",a:{icon:"pencil",action:"input",params:'{"target": "input"}'},f:["Set"]}," ",{p:[43,5,1894],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.inputLevel","data.inputLevelMax"],s:'_0==_1?"disabled":null'},p:[43,38,1927]}],action:"input",params:'{"adjust": 10000}'}}," ",{p:[44,5,2039],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.inputLevel","data.inputLevelMax"],s:'_0==_1?"disabled":null'},p:[44,43,2077]}],action:"input",params:'{"target": "max"}'}}]}," ",{p:[46,3,2204],t:7,e:"ui-section",a:{label:"Available"},f:[{p:[47,3,2238],t:7,e:"span",f:[{t:2,r:"adata.inputAvailable",p:[47,9,2244]}]}]}]}," ",{p:[50,1,2308],t:7,e:"ui-display",a:{title:"Output"},f:[{p:[51,3,2339],t:7,e:"ui-section",a:{label:"Output Mode"},f:[{p:[52,5,2377],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"power-off":"close"'},p:[52,22,2394]}],style:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"selected":null'},p:[52,77,2449]}],action:"tryoutput"},f:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"On":"Off"'},p:[53,26,2519]}]},"   [",{p:[55,6,2587],t:7,e:"span",a:{"class":[{t:2,r:"outputState",p:[55,19,2600]}]},f:[{t:2,x:{r:["data.outputting","data.charge"],s:'_0?"Sending":_1>0?"Not Sending":"No Charge"'},p:[55,36,2617]}]},"]"]}," ",{p:[57,3,2724],t:7,e:"ui-section",a:{label:"Target Output"},f:[{p:[58,5,2764],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.outputLevelMax",p:[58,26,2785]}],value:[{t:2,r:"data.outputLevel",p:[58,58,2817]}]},f:[{t:2,r:"adata.outputLevel_text",p:[58,80,2839]}]}]}," ",{p:[60,3,2894],t:7,e:"ui-section",a:{label:"Adjust Output"},f:[{p:[61,5,2934],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.outputLevel"],s:'_0==0?"disabled":null'},p:[61,44,2973]}],action:"output",params:'{"target": "min"}'}}," ",{p:[62,5,3070],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.outputLevel"],s:'_0==0?"disabled":null'},p:[62,39,3104]}],action:"output",params:'{"adjust": -10000}'}}," ",{p:[63,5,3202],t:7,e:"ui-button",a:{icon:"pencil",action:"output",params:'{"target": "input"}'},f:["Set"]}," ",{p:[64,5,3293],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.outputLevel","data.outputLevelMax"],s:'_0==_1?"disabled":null'},p:[64,38,3326]}],action:"output",params:'{"adjust": 10000}'}}," ",{p:[65,5,3441],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.outputLevel","data.outputLevelMax"],s:'_0==_1?"disabled":null'},p:[65,43,3479]}],action:"output",params:'{"target": "max"}'}}]}," ",{p:[67,3,3609],t:7,e:"ui-section",a:{label:"Outputting"},f:[{p:[68,3,3644],t:7,e:"span",f:[{t:2,r:"adata.outputUsed",p:[68,9,3650]}]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],308:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:["\ufeff",{t:4,f:[" ",{p:[2,2,33],t:7,e:"ui-display",a:{title:"Dispersal Tank"},f:[{p:[3,2,72],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[4,6,105],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.active"],s:'_0?"power-off":"close"'},p:[4,23,122]}],style:[{t:2,x:{r:["data.active"],s:'_0?"selected":null'},p:[5,11,174]}],state:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?null:"disabled"'},p:[6,11,222]}],action:"power"},f:[{t:2,x:{r:["data.active"],s:'_0?"On":"Off"'},p:[7,19,284]}]}]}," ",{p:[10,2,349],t:7,e:"ui-section",a:{label:"Smoke Radius Setting"},f:[{p:[11,4,395],t:7,e:"div",a:{"class":"content",style:"float:left"},f:[{p:[12,5,441],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.setting"],s:'_0==3?"selected":null'},p:[12,35,471]}],action:"setting",params:'{"amount": 3}'},f:["3"]}," ",{p:[13,5,573],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.setting"],s:'_0==6?"selected":null'},p:[13,35,603]}],action:"setting",params:'{"amount": 6}'},f:["6"]}," ",{p:[14,5,705],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.setting"],s:'_0==9?"selected":null'},p:[14,35,735]}],action:"setting",params:'{"amount": 9}'},f:["9"]}," ",{p:[15,5,837],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.setting"],s:'_0==12?"selected":null'},p:[15,35,867]}],action:"setting",params:'{"amount": 12}'},f:["12"]}," ",{p:[16,5,972],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.setting"],s:'_0==15?"selected":null'},p:[16,35,1002]}],action:"setting",params:'{"amount": 15}'},f:["15"]}]}]}," ",{p:[19,5,1139],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{p:[21,10,1212],t:7,e:"span",f:[{t:2,x:{r:["adata.TankCurrentVolume"],s:"Math.round(_0)"},p:[21,16,1218]},"/",{t:2,r:"data.TankMaxVolume",p:[21,56,1258]}," Units"]}," ",{p:[22,10,1304],t:7,e:"br"}," ",{p:[23,5,1315],t:7,e:"br"}," ",{t:4,f:[{p:[25,13,1374],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[25,56,1417]}," units of ",{t:2,r:"name",p:[25,91,1452]}]},{p:[25,106,1467],t:7,e:"br"}],n:52,r:"adata.TankContents",p:[24,11,1332]}],n:50,r:"data.isTankLoaded",p:[20,7,1176]},{t:4,n:51,f:[{p:[28,12,1519],t:7,e:"span",a:{"class":"bad"},f:["Tank Empty"]}],r:"data.isTankLoaded"}," ",{p:[30,4,1571],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?"Eject":"Close"'},p:[30,21,1588]}],style:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?"selected":null'},p:[31,12,1643]}],state:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?null:"disabled"'},p:[32,12,1698]}],action:"purge"},f:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?"Purge Contents":"No chemicals detected"'},p:[33,20,1761]}]}]}]}],n:50,x:{r:["data.screen"],s:'_0=="home"'},p:[1,2,1]}]},e.exports=a.extend(r.exports)},{205:205}],309:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[2,3,31],t:7,e:"ui-section",a:{label:"Generated Power"},f:[{t:2,x:{r:["adata.generated"],s:"Math.round(_0)"},p:[3,5,73]},"W"]}," ",{p:[5,3,126],t:7,e:"ui-section",a:{label:"Orientation"},f:[{p:[6,5,164],t:7,e:"span",f:[{t:2,x:{r:["adata.angle"],s:"Math.round(_0)"},p:[6,11,170]},"° (",{t:2,r:"data.direction",p:[6,45,204]},")"]}]}," ",{p:[8,3,251],t:7,e:"ui-section",a:{label:"Adjust Angle"},f:[{p:[9,5,290],t:7,e:"ui-button",a:{icon:"step-backward",action:"angle",params:'{"adjust": -15}'},f:["15°"]}," ",{p:[10,5,387],t:7,e:"ui-button",a:{icon:"backward",action:"angle",params:'{"adjust": -5}'},f:["5°"]}," ",{p:[11,5,477],t:7,e:"ui-button",a:{icon:"forward",action:"angle",params:'{"adjust": 5}'},f:["5°"]}," ",{p:[12,5,565],t:7,e:"ui-button",a:{icon:"step-forward",action:"angle",params:'{"adjust": 15}'},f:["15°"]}]}]}," ",{p:[15,1,687],t:7,e:"ui-display",a:{title:"Tracking"},f:[{p:[16,3,720],t:7,e:"ui-section",a:{label:"Tracker Mode"},f:[{p:[17,5,759],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["data.tracking_state"],s:'_0==0?"selected":null'},p:[17,36,790]}],action:"tracking",params:'{"mode": 0}'},f:["Off"]}," ",{p:[19,5,907],t:7,e:"ui-button",a:{icon:"clock-o",state:[{t:2,x:{r:["data.tracking_state"],s:'_0==1?"selected":null'},p:[19,38,940]}],action:"tracking",params:'{"mode": 1}'},f:["Timed"]}," ",{p:[21,5,1059],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.connected_tracker","data.tracking_state"],s:'_0?_1==2?"selected":null:"disabled"'},p:[21,38,1092]}],action:"tracking",params:'{"mode": 2}'},f:["Auto"]}]}," ",{p:[24,3,1262],t:7,e:"ui-section",a:{label:"Tracking Rate"},f:[{p:[25,3,1300],t:7,e:"span",f:[{t:2,x:{r:["adata.tracking_rate"],s:"Math.round(_0)"},p:[25,9,1306]},"°/h (",{t:2,r:"data.rotating_way",p:[25,53,1350]},")"]}]}," ",{p:[27,3,1399],t:7,e:"ui-section",a:{label:"Adjust Rate"},f:[{p:[28,5,1437],t:7,e:"ui-button",a:{icon:"fast-backward",action:"rate",params:'{"adjust": -180}'},f:["180°"]}," ",{p:[29,5,1535],t:7,e:"ui-button",a:{icon:"step-backward",action:"rate",params:'{"adjust": -30}'},f:["30°"]}," ",{p:[30,5,1631],t:7,e:"ui-button",a:{icon:"backward",action:"rate",params:'{"adjust": -5}'},f:["5°"]}," ",{p:[31,5,1720],t:7,e:"ui-button",a:{icon:"forward",action:"rate",params:'{"adjust": 5}'},f:["5°"]}," ",{p:[32,5,1807],t:7,e:"ui-button",a:{icon:"step-forward",action:"rate",params:'{"adjust": 30}'},f:["30°"]}," ",{p:[33,5,1901],t:7,e:"ui-button",a:{icon:"fast-forward",action:"rate",params:'{"adjust": 180}'},f:["180°"]}]}]}," ",{p:{button:[{p:[38,5,2088],t:7,e:"ui-button",a:{icon:"refresh",action:"refresh"},f:["Refresh"]}]},t:7,e:"ui-display",a:{title:"Devices",button:0},f:[" ",{p:[40,2,2169],t:7,e:"ui-section",a:{label:"Solar Tracker"},f:[{p:[41,5,2209],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected_tracker"],s:'_0?"good":"bad"'},p:[41,18,2222]}]},f:[{t:2,x:{r:["data.connected_tracker"],s:'_0?"":"Not "'},p:[41,63,2267]},"Found"]}]}," ",{p:[43,2,2338],t:7,e:"ui-section",a:{label:"Solar Panels"},f:[{p:[44,3,2375],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected_panels"],s:'_0?"good":"bad"'},p:[44,16,2388]}]},f:[{t:2,x:{r:["adata.connected_panels"],s:"Math.round(_0)"},p:[44,60,2432]}," Panels Connected"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],310:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{t:4,f:[{p:[4,7,87],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.hasPowercell"],s:'_0?null:"disabled"'},p:[4,38,118]}],action:"eject"},f:["Eject"]}],n:50,r:"data.open",p:[3,5,62]}]},t:7,e:"ui-display",a:{title:"Power",button:0},f:[" ",{p:[7,3,226],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[8,5,258],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[8,22,275]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[9,14,326]}],state:[{t:2,x:{r:["data.hasPowercell"],s:'_0?null:"disabled"'},p:[9,54,366]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[10,22,431]}]}]}," ",{p:[12,3,490],t:7,e:"ui-section",a:{label:"Cell"},f:[{t:4,f:[{p:[14,7,554],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.powerLevel",p:[14,40,587]}]},f:[{t:2,x:{r:["adata.powerLevel"],s:"Math.fixed(_0)"},p:[14,61,608]},"%"]}],n:50,r:"data.hasPowercell",p:[13,5,521]},{t:4,n:51,f:[{p:[16,4,667],t:7,e:"span",a:{"class":"bad"},f:["No Cell"]}],r:"data.hasPowercell"}]}]}," ",{p:[20,1,744],t:7,e:"ui-display",a:{title:"Thermostat"},f:[{p:[21,3,779],t:7,e:"ui-section",a:{label:"Current Temperature"},f:[{p:[22,3,823],t:7,e:"span",f:[{t:2,x:{r:["adata.currentTemp"],s:"Math.round(_0)"},p:[22,9,829]},"°C"]}]}," ",{p:[24,2,894],t:7,e:"ui-section",a:{label:"Target Temperature"},f:[{p:[25,3,937],t:7,e:"span",f:[{t:2,x:{r:["adata.targetTemp"],s:"Math.round(_0)"},p:[25,9,943]},"°C"]}]}," ",{t:4,f:[{p:[28,5,1031],t:7,e:"ui-section",a:{label:"Adjust Target"},f:[{p:[29,7,1073],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.targetTemp","data.minTemp"],s:'_0>_1?null:"disabled"'},p:[29,46,1112]}],action:"target",params:'{"adjust": -20}'}}," ",{p:[30,7,1218],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.targetTemp","data.minTemp"],s:'_0>_1?null:"disabled"'},p:[30,41,1252]}],action:"target",params:'{"adjust": -5}'}}," ",{p:[31,7,1357],t:7,e:"ui-button",a:{icon:"pencil",action:"target",params:'{"target": "input"}'},f:["Set"]}," ",{p:[32,7,1450],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.targetTemp","data.maxTemp"],s:'_0<_1?null:"disabled"'},p:[32,40,1483]}],action:"target",params:'{"adjust": 5}'}}," ",{p:[33,7,1587],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.targetTemp","data.maxTemp"],s:'_0<_1?null:"disabled"'},p:[33,45,1625]}],action:"target",params:'{"adjust": 20}'}}]}],n:50,r:"data.open",p:[27,3,1008]}," ",{p:[36,3,1754],t:7,e:"ui-section",a:{label:"Mode"},f:[{t:4,f:[{p:[38,7,1808],t:7,e:"ui-button",a:{icon:"long-arrow-up",state:[{t:2,x:{r:["data.mode"],s:'_0=="heat"?"selected":null'},p:[38,46,1847]}],action:"mode",params:'{"mode": "heat"}'},f:["Heat"]}," ",{p:[39,7,1956],t:7,e:"ui-button",a:{icon:"long-arrow-down",state:[{t:2,x:{r:["data.mode"],s:'_0=="cool"?"selected":null'},p:[39,48,1997]}],action:"mode",params:'{"mode": "cool"}'},f:["Cool"]}," ",{p:[40,7,2106],t:7,e:"ui-button",a:{icon:"arrows-v",state:[{t:2,x:{r:["data.mode"],s:'_0=="auto"?"selected":null'},p:[40,41,2140]}],action:"mode",params:'{"mode": "auto"}'},f:["Auto"]}],n:50,r:"data.open",p:[37,3,1783]},{t:4,n:51,f:[{p:[42,4,2258],t:7,e:"span",f:[{t:2,x:{r:["text","data.mode"],s:"_0.titleCase(_1)"},p:[42,10,2264]}]}],r:"data.open"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],311:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:{button:[{p:[4,8,97],t:7,e:"ui-button",a:{action:"jump",params:['{"name" : ',{t:2,r:"name",p:[4,51,140]},"}"]},f:["Jump"]}," ",{p:[7,9,195],t:7,e:"ui-button",a:{action:"spawn",params:['{"name" : ',{t:2,r:"name",p:[7,53,239]},"}"]},f:["Spawn"]}]},t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[2,22,46]}],button:0},f:[" ",{p:[11,3,308],t:7,e:"ui-section",a:{label:"Description"},f:[{p:[12,5,346],t:7,e:"span",f:[{t:3,r:"desc",p:[12,11,352]}]}]}," ",{p:[14,3,390],t:7,e:"ui-section",a:{label:"Spawners left"},f:[{p:[15,5,430],t:7,e:"span",f:[{t:2,r:"amount_left",p:[15,11,436]}]}]}]}],n:52,r:"data.spawners",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{205:205}],312:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,31],t:7,e:"ui-display",a:{title:[{t:2,r:"class",p:[2,22,50]}," Alarms"]},f:[{p:[3,5,74],t:7,e:"ul",f:[{t:4,f:[{p:[5,9,107],t:7,e:"li",f:[{t:2,r:".",p:[5,13,111]}]}],n:52,r:".",p:[4,7,86]},{t:4,n:51,f:[{p:[7,9,147],t:7,e:"li",f:["System Nominal"]}],r:"."}]}]}],n:52,i:"class",r:"data.alarms",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{205:205}],313:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,42],t:7,e:"ui-notice",f:[{p:[3,5,59],t:7,e:"span",f:["Biological entity detected in contents. Please remove."]}]}],n:50,x:{r:["data.occupied","data.safeties"],s:"_0&&_1"},p:[1,1,0]},{t:4,f:[{p:[7,3,179],t:7,e:"ui-notice",f:[{p:[8,5,196],t:7,e:"span",f:["Contents are being disinfected. Please wait."]}]}],n:50,r:"data.uv_active",p:[6,1,153]},{t:4,n:51,f:[{p:{button:[{t:4,f:[{p:[13,25,369],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[13,42,386]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Unlock":"Lock"'},p:[13,93,437]}]}],n:50,x:{r:["data.open"],s:"!_0"},p:[13,7,351]}," ",{t:4,f:[{p:[14,27,519],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.open"],s:'_0?"sign-out":"sign-in"'},p:[14,44,536]}],action:"door"},f:[{t:2,x:{r:["data.open"],s:'_0?"Close":"Open"'},p:[14,98,590]}]}],n:50,x:{r:["data.locked"],s:"!_0"},p:[14,7,499]}]},t:7,e:"ui-display",a:{title:"Storage",button:0},f:[" ",{t:4,f:[{p:[17,7,692],t:7,e:"ui-notice",f:[{p:[18,9,713],t:7,e:"span",f:["Unit Locked"]}]}],n:50,r:"data.locked",p:[16,5,665]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.open"],s:"_0"},f:[{p:[21,9,793],t:7,e:"ui-section",a:{label:"Helmet"},f:[{p:[22,11,832],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.helmet"],s:'_0?"square":"square-o"'},p:[22,28,849]}],state:[{t:2,x:{r:["data.helmet"],s:'_0?null:"disabled"'},p:[22,75,896]}],action:"dispense",params:'{"item": "helmet"}'},f:[{t:2,x:{r:["data.helmet"],s:'_0||"Empty"'},p:[23,59,992]}]}]}," ",{p:[25,9,1063],t:7,e:"ui-section",a:{label:"Suit"},f:[{p:[26,11,1100],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.suit"],s:'_0?"square":"square-o"'},p:[26,28,1117]}],state:[{t:2,x:{r:["data.suit"],s:'_0?null:"disabled"'},p:[26,74,1163]}],action:"dispense",params:'{"item": "suit"}'},f:[{t:2,x:{r:["data.suit"],s:'_0||"Empty"'},p:[27,57,1255]}]}]}," ",{p:[29,9,1324],t:7,e:"ui-section",a:{label:"Mask"},f:[{p:[30,11,1361],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mask"],s:'_0?"square":"square-o"'},p:[30,28,1378]}],state:[{t:2,x:{r:["data.mask"],s:'_0?null:"disabled"'},p:[30,74,1424]}],action:"dispense",params:'{"item": "mask"}'},f:[{t:2,x:{r:["data.mask"],s:'_0||"Empty"'},p:[31,57,1516]}]}]}," ",{p:[33,9,1585],t:7,e:"ui-section",a:{label:"Storage"},f:[{p:[34,11,1625],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.storage"],s:'_0?"square":"square-o"'},p:[34,28,1642]}],state:[{t:2,x:{r:["data.storage"],s:'_0?null:"disabled"'},p:[34,77,1691]}],action:"dispense",params:'{"item": "storage"}'},f:[{t:2,x:{r:["data.storage"],s:'_0||"Empty"'},p:[35,60,1789]}]}]}]},{t:4,n:50,x:{r:["data.open"],s:"!(_0)"},f:[" ",{p:[38,7,1873],t:7,e:"ui-button",a:{icon:"recycle",state:[{t:2,x:{r:["data.occupied","data.safeties"],s:'_0&&_1?"disabled":null'},p:[38,40,1906]}],action:"uv"},f:["Disinfect"]}]}],r:"data.locked"}]}],r:"data.uv_active"}]},e.exports=a.extend(r.exports)},{205:205}],314:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,5,18],t:7,e:"ui-section",a:{label:"Dispense"},f:[{p:[3,9,57],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.plasma"],s:'_0?"square":"square-o"'},p:[3,26,74]}],state:[{t:2,x:{r:["data.plasma"],s:'_0?null:"disabled"'},p:[3,74,122]}],action:"plasma"},f:["Plasma (",{t:2,x:{r:["adata.plasma"],s:"Math.round(_0)"},p:[4,37,196]},")"]}," ",{p:[5,9,247],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.oxygen"],s:'_0?"square":"square-o"'},p:[5,26,264]}],state:[{t:2,x:{r:["data.oxygen"],s:'_0?null:"disabled"'},p:[5,74,312]}],action:"oxygen"},f:["Oxygen (",{t:2,x:{r:["adata.oxygen"],s:"Math.round(_0)"},p:[6,37,386]},")"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],315:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{tankPressureState:function(){var t=this.get("data.tankPressure");return t>=200?"good":t>=100?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[14,1,295],t:7,e:"ui-notice",f:[{p:[15,3,310],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.connected"],s:'_0?"is":"is not"'},p:[15,23,330]}," connected to a mask."]}]}," ",{p:[17,1,409],t:7,e:"ui-display",f:[{p:[18,3,425],t:7,e:"ui-section",a:{label:"Tank Pressure"},f:[{p:[19,7,467],t:7,e:"ui-bar",a:{min:"0",max:"1013",value:[{t:2,r:"data.tankPressure",p:[19,41,501]}],state:[{t:2,r:"tankPressureState",p:[20,16,540]}]},f:[{t:2,x:{r:["adata.tankPressure"], +s:"Math.round(_0)"},p:[20,39,563]}," kPa"]}]}," ",{p:[22,3,631],t:7,e:"ui-section",a:{label:"Release Pressure"},f:[{p:[23,5,674],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.minReleasePressure",p:[23,18,687]}],max:[{t:2,r:"data.maxReleasePressure",p:[23,52,721]}],value:[{t:2,r:"data.releasePressure",p:[24,14,764]}]},f:[{t:2,x:{r:["adata.releasePressure"],s:"Math.round(_0)"},p:[24,40,790]}," kPa"]}]}," ",{p:[26,3,861],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[27,5,906],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.releasePressure","data.defaultReleasePressure"],s:'_0!=_1?null:"disabled"'},p:[27,38,939]}],action:"pressure",params:'{"pressure": "reset"}'},f:["Reset"]}," ",{p:[29,5,1095],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.releasePressure","data.minReleasePressure"],s:'_0>_1?null:"disabled"'},p:[29,36,1126]}],action:"pressure",params:'{"pressure": "min"}'},f:["Min"]}," ",{p:[31,5,1273],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[32,5,1368],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.releasePressure","data.maxReleasePressure"],s:'_0<_1?null:"disabled"'},p:[32,35,1398]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],316:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[2,5,33],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[3,9,75],t:7,e:"span",f:[{t:2,x:{r:["adata.temperature"],s:"Math.fixed(_0,2)"},p:[3,15,81]}," K"]}]}," ",{p:[5,5,151],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[6,9,190],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.fixed(_0,2)"},p:[6,15,196]}," kPa"]}]}]}," ",{p:[9,1,276],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[10,5,311],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[11,9,347],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[11,26,364]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[11,70,408]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[12,28,469]}]}]}," ",{p:[14,5,531],t:7,e:"ui-section",a:{label:"Target Temperature"},f:[{p:[15,9,580],t:7,e:"ui-button",a:{icon:"fast-backward",style:[{t:2,x:{r:["data.target","data.min"],s:'_0==_1?"disabled":null'},p:[15,48,619]}],action:"target",params:'{"adjust": -20}'}}," ",{p:[17,9,733],t:7,e:"ui-button",a:{icon:"backward",style:[{t:2,x:{r:["data.target","data.min"],s:'_0==_1?"disabled":null'},p:[17,43,767]}],action:"target",params:'{"adjust": -5}'}}," ",{p:[19,9,880],t:7,e:"ui-button",a:{icon:"pencil",action:"target",params:'{"target": "input"}'},f:[{t:2,x:{r:["adata.target"],s:"Math.fixed(_0,2)"},p:[19,79,950]}]}," ",{p:[20,9,1003],t:7,e:"ui-button",a:{icon:"forward",style:[{t:2,x:{r:["data.target","data.max"],s:'_0==_1?"disabled":null'},p:[20,42,1036]}],action:"target",params:'{"adjust": 5}'}}," ",{p:[22,9,1148],t:7,e:"ui-button",a:{icon:"fast-forward",style:[{t:2,x:{r:["data.target","data.max"],s:'_0==_1?"disabled":null'},p:[22,47,1186]}],action:"target",params:'{"adjust": 20}'}}]}]}]},e.exports=a.extend(r.exports)},{205:205}],317:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{powerState:function(t){switch(t){case 1:return"good";default:return"bad"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[13,1,173],t:7,e:"ui-notice",f:[{p:[14,2,187],t:7,e:"ui-section",a:{label:"Reconnect"},f:[{p:[15,3,221],t:7,e:"div",a:{style:"float:right"},f:[{p:[16,4,251],t:7,e:"ui-button",a:{icon:"refresh",action:"reconnect"},f:["Reconnect"]}]}]}]}," ",{p:[20,1,359],t:7,e:"ui-display",a:{title:"Turbine Controller"},f:[{p:[21,2,401],t:7,e:"ui-section",a:{label:"Status"},f:[{t:4,f:[{p:[23,4,456],t:7,e:"span",a:{"class":"bad"},f:["Broken"]}],n:50,r:"data.broken",p:[22,3,432]},{t:4,n:51,f:[{p:[25,4,504],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.online"],s:"_0(_1)"},p:[25,17,517]}]},f:[{t:2,x:{r:["data.online","data.compressor_broke","data.turbine_broke"],s:'_0&&!(_1||_2)?"Online":"Offline"'},p:[25,46,546]}]}],r:"data.broken"}," ",{p:[27,3,656],t:7,e:"div",a:{style:"float:right"},f:[{p:[28,4,686],t:7,e:"ui-button",a:{icon:"power-off",action:"power-on",state:[{t:2,r:"data.broken",p:[28,57,739]}],style:[{t:2,x:{r:["data.online"],s:'_0?"selected":""'},p:[28,81,763]}]},f:["On"]}," ",{p:[29,4,817],t:7,e:"ui-button",a:{icon:"close",action:"power-off",state:[{t:2,r:"data.broken",p:[29,54,867]}],style:[{t:2,x:{r:["data.online"],s:'_0?"":"selected"'},p:[29,78,891]}]},f:["Off"]}]}," ",{t:4,f:[{p:[32,4,989],t:7,e:"br"}," [ ",{p:[33,6,1e3],t:7,e:"span",a:{"class":"bad"},f:["Compressor is inoperable"]}," ]"],n:50,r:"data.compressor_broke",p:[31,3,955]}," ",{t:4,f:[{p:[36,4,1097],t:7,e:"br"}," [ ",{p:[37,6,1108],t:7,e:"span",a:{"class":"bad"},f:["Turbine is inoperable"]}," ]"],n:50,r:"data.turbine_broke",p:[35,3,1066]}]}]}," ",{p:[41,1,1200],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[42,2,1230],t:7,e:"ui-section",a:{label:"Turbine Speed"},f:[{p:[43,3,1268],t:7,e:"span",f:[{t:2,x:{r:["data.broken","data.rpm"],s:'_0?"--":_1'},p:[43,9,1274]}," RPM"]}]}," ",{p:[45,2,1337],t:7,e:"ui-section",a:{label:"Internal Temp"},f:[{p:[46,3,1375],t:7,e:"span",f:[{t:2,x:{r:["data.broken","data.temp"],s:'_0?"--":_1'},p:[46,9,1381]}," K"]}]}," ",{p:[48,2,1443],t:7,e:"ui-section",a:{label:"Generated Power"},f:[{p:[49,3,1483],t:7,e:"span",f:[{t:2,x:{r:["data.broken","data.power"],s:'_0?"--":_1'},p:[49,9,1489]}]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],318:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{},oninit:function(){this.on({hover:function(t){var e=this.get("data.telecrystals");e>=t.context.params.cost&&this.set("hovered",t.context.params)},unhover:function(t){this.set("hovered")}})}}}(r),r.exports.template={v:3,t:[" ",{p:{button:[{t:4,f:[{p:[23,7,482],t:7,e:"ui-button",a:{icon:"lock",action:"lock"},f:["Lock"]}],n:50,r:"data.lockable",p:[22,5,453]}]},t:7,e:"ui-display",a:{title:"Uplink",button:0},f:[" ",{p:[26,3,568],t:7,e:"ui-section",a:{label:"Telecrystals",right:0},f:[{p:[27,5,613],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.telecrystals"],s:'_0>0?"good":"bad"'},p:[27,18,626]}]},f:[{t:2,r:"data.telecrystals",p:[27,62,670]}," TC"]}]}]}," ",{t:4,f:[{p:[31,3,764],t:7,e:"ui-display",f:[{p:[32,2,779],t:7,e:"ui-button",a:{action:"select",params:['{"category": "',{t:2,r:"name",p:[32,51,828]},'"}']},f:[{t:2,r:"name",p:[32,63,840]}]}," ",{t:4,f:[{p:[34,4,883],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[34,23,902]}],candystripe:0,right:0},f:[{p:[35,3,934],t:7,e:"ui-button",a:{tooltip:[{t:2,r:"name",p:[35,23,954]},": ",{t:2,r:"desc",p:[35,33,964]}],"tooltip-side":"left",state:[{t:2,x:{r:["data.telecrystals","hovered.cost","cost","hovered.item","name"],s:'_0<_2||(_0-_1<_2&&_3!=_4)?"disabled":null'},p:[36,12,1006]}],action:"buy",params:['{"category": "',{t:2,r:"category",p:[37,40,1165]},'", "item": ',{t:2,r:"name",p:[37,63,1188]},', "cost": ',{t:2,r:"cost",p:[37,81,1206]},"}"]},v:{hover:"hover",unhover:"unhover"},f:[{t:2,r:"cost",p:[38,43,1260]}," TC"]}]}],n:52,r:"items",p:[33,2,863]}]}],n:52,r:"data.categories",p:[30,1,735]}]},e.exports=a.extend(r.exports)},{205:205}],319:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Products"},f:[{t:4,f:[{p:[3,2,58],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[3,21,77]}],labelcolor:[{t:2,r:"color",p:[3,43,99]}],candystripe:0,right:0},f:[{p:[4,3,132],t:7,e:"span",f:[{p:[4,9,138],t:7,e:"b",f:[{t:2,r:"amount",p:[4,12,141]}]}]}," ",{p:[5,3,166],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["amount"],s:'(_0>0)?null:"disabled"'},p:[5,22,185]}],icon:[{t:2,x:{r:["amount"],s:'(_0>0)?"cart-arrow-down":"ban"'},p:[5,66,229]}],action:"vend",params:['{"key": ',{t:2,r:"key",p:[5,142,305]},"}"]},f:[{t:2,x:{r:["amount"],s:'(_0>0)?"Vend":"Sold Out"'},p:[5,152,315]}]}]}],n:52,r:"data.products",p:[2,2,32]}]}," ",{t:4,f:[{p:[10,2,434],t:7,e:"ui-display",a:{title:"Coin Slot"},f:[{p:[11,3,468],t:7,e:"ui-section",a:{label:"Coin"},f:[{p:[12,3,497],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.coin"],s:'_0?"bold":null'},p:[12,16,510]}]},f:[{t:2,x:{r:["data.coin"],s:'_0?_0:"No Coin"'},p:[12,47,541]}]}," ",{p:[13,4,590],t:7,e:"ui-button",a:{icon:"arrow-circle-up",state:[{t:2,x:{r:["data.coin","data.canvend"],s:'_0&&_1?null:"disabled"'},p:[13,45,631]}],action:"eject"},f:["Eject Coin"]}]}]}],n:50,r:"data.coinslot",p:[9,1,410]}]},e.exports=a.extend(r.exports)},{205:205}],320:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{healthState:function(t){var e=this.get("data.vr_avatar.maxhealth");return t>e/1.5?"good":t>e/3?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[14,1,292],t:7,e:"ui-display",f:[{t:4,f:[{p:[16,3,333],t:7,e:"ui-display",a:{title:"Virtual Avatar"},f:[{p:[17,4,373],t:7,e:"ui-section",a:{label:"Name"},f:[{t:2,r:"data.vr_avatar.name",p:[18,5,404]}]}," ",{p:[20,4,450],t:7,e:"ui-section",a:{label:"Status"},f:[{t:2,r:"data.vr_avatar.status",p:[21,5,483]}]}," ",{p:[23,4,531],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[24,5,564],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.vr_avatar.maxhealth",p:[24,26,585]}],value:[{t:2,r:"adata.vr_avatar.health",p:[24,64,623]}],state:[{t:2,x:{r:["healthState","adata.vr_avatar.health"],s:"_0(_1)"},p:[24,99,658]}]},f:[{t:2,x:{r:["adata.vr_avatar.health"],s:"Math.round(_0)"},p:[24,140,699]},"/",{t:2,r:"adata.vr_avatar.maxhealth",p:[24,179,738]}]}]}]}],n:50,r:"data.vr_avatar",p:[15,2,307]},{t:4,n:51,f:[{p:[28,3,826],t:7,e:"ui-display",a:{title:"Virtual Avatar"},f:["No Virtual Avatar detected"]}],r:"data.vr_avatar"}," ",{p:[32,2,922],t:7,e:"ui-display",a:{title:"VR Commands"},f:[{p:[33,3,958],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.toggle_open"],s:'_0?"times":"plus"'},p:[33,20,975]}],action:"toggle_open"},f:[{t:2,x:{r:["data.toggle_open"],s:'_0?"Close":"Open"'},p:[34,4,1042]}," the VR Sleeper"]}," ",{t:4,f:[{p:[37,4,1144],t:7,e:"ui-button",a:{icon:"signal",action:"vr_connect"},f:["Connect to VR"]}],n:50,r:"data.isoccupant",p:[36,3,1116]}," ",{t:4,f:[{p:[42,4,1267],t:7,e:"ui-button",a:{icon:"ban",action:"delete_avatar"},f:["Delete Virtual Avatar"]}],n:50,r:"data.vr_avatar",p:[41,3,1240]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],321:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{t:4,f:[{p:[3,5,42],t:7,e:"ui-section",a:{label:[{t:2,r:"color",p:[3,24,61]},{t:2,x:{r:["wire"],s:'_0?" ("+_0+")":""'},p:[3,33,70]}],labelcolor:[{t:2,r:"color",p:[3,80,117]}],candystripe:0,right:0},f:[{p:[4,7,154],t:7,e:"ui-button",a:{action:"cut",params:['{"wire":"',{t:2,r:"color",p:[4,48,195]},'"}']},f:[{t:2,x:{r:["cut"],s:'_0?"Mend":"Cut"'},p:[4,61,208]}]}," ",{p:[5,7,252],t:7,e:"ui-button",a:{action:"pulse",params:['{"wire":"',{t:2,r:"color",p:[5,50,295]},'"}']},f:["Pulse"]}," ",{p:[6,7,333],t:7,e:"ui-button",a:{action:"attach",params:['{"wire":"',{t:2,r:"color",p:[6,51,377]},'"}']},f:[{t:2,x:{r:["attached"],s:'_0?"Detach":"Attach"'},p:[6,64,390]}]}]}],n:52,r:"data.wires",p:[2,3,16]}]}," ",{t:4,f:[{p:[11,3,508],t:7,e:"ui-display",f:[{t:4,f:[{p:[13,7,555],t:7,e:"ui-section",f:[{t:2,r:".",p:[13,19,567]}]}],n:52,r:"data.status",p:[12,5,526]}]}],n:50,r:"data.status",p:[10,1,485]}]},e.exports=a.extend(r.exports)},{205:205}],322:[function(t,e,n){(function(e){"use strict";var n=t(205),a=e.interopRequireDefault(n);t(194),t(1),t(190),t(193);var r=t(323),i=e.interopRequireDefault(r),o=t(324),s=t(191),p=t(192),u=e.interopRequireDefault(p);a["default"].DEBUG=/minified/.test(function(){}),Object.assign(Math,t(328)),window.initialize=function(e){window.tgui=window.tgui||new i["default"]({el:"#container",data:function(){var n=JSON.parse(e);return{constants:t(325),text:t(329),config:n.config,data:n.data,adata:n.data}}})};var c=document.getElementById("data"),l=c.textContent,d=c.getAttribute("data-ref");"{}"!==l&&(window.initialize(l),c.remove()),(0,o.act)(d,"tgui:initialize"),(0,s.loadCSS)("font-awesome.min.css");var f=new u["default"]("FontAwesome");f.check("").then(function(){return document.body.classList.add("icons")})["catch"](function(){return document.body.classList.add("no-icons")})}).call(this,t("babel/external-helpers"))},{1:1,190:190,191:191,192:192,193:193,194:194,205:205,323:323,324:324,325:325,328:328,329:329,"babel/external-helpers":"babel/external-helpers"}],323:[function(t,e,n){var a=t(205),r={exports:{}};!function(e){"use strict";var n=t(324),a=t(326);e.exports={components:{"ui-bar":t(206),"ui-button":t(207),"ui-display":t(208),"ui-input":t(209),"ui-linegraph":t(210),"ui-notice":t(211),"ui-section":t(213),"ui-subdisplay":t(214),"ui-tabs":t(215)},events:{enter:t(203).enter,space:t(203).space},transitions:{fade:t(204)},onconfig:function(){var e=this.get("config.interface"),n={ai_airlock:t(219),airalarm:t(220),"airalarm/back":t(221),"airalarm/modes":t(222),"airalarm/scrubbers":t(223),"airalarm/status":t(224),"airalarm/thresholds":t(225),"airalarm/vents":t(226),airlock_electronics:t(227),apc:t(228),atmos_alert:t(229),atmos_control:t(230),atmos_filter:t(231),atmos_mixer:t(232),atmos_pump:t(233),brig_timer:t(234),bsa:t(235),canister:t(236),cargo:t(237),cellular_emporium:t(238),chem_dispenser:t(239),chem_heater:t(240),chem_master:t(241),clockwork_slab:t(242),codex_gigas:t(243),computer_fabricator:t(244),crayon:t(245),cryo:t(246),disposal_unit:t(247),dna_vault:t(248),dogborg_sleeper:t(249),eightball:t(250),emergency_shuttle_console:t(251),engraved_message:t(252),error:t(253),"exofab - Copia":t(254),exonet_node:t(255),firealarm:t(256),gps:t(257),gulag_console:t(258),gulag_item_reclaimer:t(259),holodeck:t(260),implantchair:t(261),intellicard:t(262),keycard_auth:t(263),labor_claim_console:t(264),language_menu:t(265),launchpad_remote:t(266),mech_bay_power_console:t(267),mulebot:t(268),ntnet_relay:t(269),ntos_ai_restorer:t(270),ntos_card:t(271),ntos_configuration:t(272),ntos_file_manager:t(273),ntos_main:t(274),ntos_net_chat:t(275),ntos_net_dos:t(276),ntos_net_downloader:t(277),ntos_net_monitor:t(278),ntos_net_transfer:t(279),ntos_power_monitor:t(280),ntos_revelation:t(281),ntos_station_alert:t(282),ntos_supermatter_monitor:t(283),ntosheader:t(284),nuclear_bomb:t(285),operating_computer:t(286),ore_redemption_machine:t(287),pandemic:t(288),personal_crafting:t(289),portable_pump:t(290),portable_scrubber:t(291),power_monitor:t(292),radio:t(293),reagentgrinder:t(294),rpd:t(295),"rpd/colorsel":t(296),"rpd/dirsel":t(297),sat_control:t(298),scrubbing_types:t(299),shuttle_manipulator:t(300),"shuttle_manipulator/modification":t(301),"shuttle_manipulator/status":t(302),"shuttle_manipulator/templates":t(303),sleeper:t(304),slime_swap_body:t(305),smartvend:t(306),smes:t(307),smoke_machine:t(308),solar_control:t(309),space_heater:t(310),spawners_menu:t(311),station_alert:t(312),suit_storage_unit:t(313),tank_dispenser:t(314),tanks:t(315),thermomachine:t(316),turbine_computer:t(317),uplink:t(318),vending:t(319),vr_sleeper:t(320),wires:t(321)};e in n?this.components["interface"]=n[e]:this.components["interface"]=n.error},oninit:function(){this.observe("config.style",function(t,e,n){t&&document.body.classList.add(t),e&&document.body.classList.remove(e)})},oncomplete:function(){if(this.get("config.locked")){var t=(0,a.lock)(window.screenLeft,window.screenTop),e=t.x,r=t.y;(0,n.winset)(this.get("config.window"),"pos",e+","+r)}(0,n.winset)("mapwindow.map","focus",!0)}}}(r),r.exports.template={v:3,t:[" "," "," "," ",{p:[56,1,1874],t:7,e:"titlebar",f:[{t:3,r:"config.title",p:[56,11,1884]}]}," ",{p:[57,1,1915],t:7,e:"main",f:[{p:[58,3,1925],t:7,e:"warnings"}," ",{p:[59,3,1940],t:7,e:"interface"}]}," ",{t:4,f:[{p:[62,3,1990],t:7,e:"resize"}],n:50,r:"config.titlebar",p:[61,1,1963]}]},r.exports.components=r.exports.components||{};var i={warnings:t(218),titlebar:t(217),resize:t(212)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{203:203,204:204,205:205,206:206,207:207,208:208,209:209,210:210,211:211,212:212,213:213,214:214,215:215,217:217,218:218,219:219,220:220,221:221,222:222,223:223,224:224,225:225,226:226,227:227,228:228,229:229,230:230,231:231,232:232,233:233,234:234,235:235,236:236,237:237,238:238,239:239,240:240,241:241,242:242,243:243,244:244,245:245,246:246,247:247,248:248,249:249,250:250,251:251,252:252,253:253,254:254,255:255,256:256,257:257,258:258,259:259,260:260,261:261,262:262,263:263,264:264,265:265,266:266,267:267,268:268,269:269,270:270,271:271,272:272,273:273,274:274,275:275,276:276,277:277,278:278,279:279,280:280,281:281,282:282,283:283,284:284,285:285,286:286,287:287,288:288,289:289,290:290,291:291,292:292,293:293,294:294,295:295,296:296,297:297,298:298,299:299,300:300,301:301,302:302,303:303,304:304,305:305,306:306,307:307,308:308,309:309,310:310,311:311,312:312,313:313,314:314,315:315,316:316,317:317,318:318,319:319,320:320,321:321,324:324,326:326}],324:[function(t,e,n){"use strict";function a(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return"byond://"+e+"?"+Object.keys(t).map(function(e){return o(e)+"="+o(t[e])}).join("&")}function r(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};window.location.href=a(Object.assign({src:t,action:e},n))}function i(t,e,n){var r;window.location.href=a((r={},r[t+"."+e]=n,r),"winset")}n.__esModule=!0,n.href=a,n.act=r,n.winset=i;var o=encodeURIComponent},{}],325:[function(t,e,n){"use strict";n.__esModule=!0;n.UI_INTERACTIVE=2,n.UI_UPDATE=1,n.UI_DISABLED=0,n.UI_CLOSE=-1},{}],326:[function(t,e,n){"use strict";function a(t,e){return 0>t?t=0:t+window.innerWidth>window.screen.availWidth&&(t=window.screen.availWidth-window.innerWidth),0>e?e=0:e+window.innerHeight>window.screen.availHeight&&(e=window.screen.availHeight-window.innerHeight),{x:t,y:e}}function r(t){if(t.preventDefault(),this.get("drag")){if(this.get("x")){var e=t.screenX-this.get("x")+window.screenLeft,n=t.screenY-this.get("y")+window.screenTop;if(this.get("config.locked")){var r=a(e,n);e=r.x,n=r.y}(0,s.winset)(this.get("config.window"),"pos",e+","+n)}this.set({x:t.screenX,y:t.screenY})}}function i(t,e){return t=Math.clamp(100,window.screen.width,t),e=Math.clamp(100,window.screen.height,e),{x:t,y:e}}function o(t){if(t.preventDefault(),this.get("resize")){if(this.get("x")){var e=t.screenX-this.get("x")+window.innerWidth,n=t.screenY-this.get("y")+window.innerHeight,a=i(e,n);e=a.x,n=a.y,(0,s.winset)(this.get("config.window"),"size",e+","+n)}this.set({x:t.screenX,y:t.screenY})}}n.__esModule=!0,n.lock=a,n.drag=r,n.sane=i,n.resize=o;var s=t(324)},{324:324}],327:[function(t,e,n){"use strict";function a(t,e){for(var n=t,a=Array.isArray(n),i=0,n=a?n:n[Symbol.iterator]();;){var o;if(a){if(i>=n.length)break;o=n[i++]}else{if(i=n.next(),i.done)break;o=i.value}var s=o;s.textContent.toLowerCase().includes(e)?(s.style.display="",r(s,e)):s.style.display="none"}}function r(t,e){for(var n=t.queryAll("section"),a=t.query("header").textContent.toLowerCase().includes(e),r=n,i=Array.isArray(r),o=0,r=i?r:r[Symbol.iterator]();;){var s;if(i){if(o>=r.length)break;s=r[o++]}else{if(o=r.next(),o.done)break;s=o.value}var p=s;a||p.textContent.toLowerCase().includes(e)?p.style.display="":p.style.display="none"}}n.__esModule=!0,n.filterMulti=a,n.filter=r},{}],328:[function(t,e,n){"use strict";function a(t,e,n){return Math.max(t,Math.min(n,e))}function r(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;return+(Math.round(t+"e"+e)+"e-"+e)}n.__esModule=!0,n.clamp=a,n.fixed=r},{}],329:[function(t,e,n){"use strict";function a(t){return t[0].toUpperCase()+t.slice(1).toLowerCase()}function r(t){return t.replace(/\w\S*/g,a)}function i(t,e){for(t=""+t;t.length1){for(var p=Array(o),u=0;o>u;u++)p[u]=arguments[u+3];n.children=p}return{$$typeof:t,type:e,key:void 0===a?null:""+a,ref:null,props:n,_owner:null}}}(),e.asyncIterator=function(t){if("function"==typeof Symbol){if(Symbol.asyncIterator){var e=t[Symbol.asyncIterator];if(null!=e)return e.call(t)}if(Symbol.iterator)return t[Symbol.iterator]()}throw new TypeError("Object is not async iterable")},e.asyncGenerator=function(){function t(t){this.value=t}function e(e){function n(t,e){return new Promise(function(n,r){var s={key:t,arg:e,resolve:n,reject:r,next:null};o?o=o.next=s:(i=o=s,a(t,e))})}function a(n,i){try{var o=e[n](i),s=o.value;s instanceof t?Promise.resolve(s.value).then(function(t){a("next",t)},function(t){a("throw",t)}):r(o.done?"return":"normal",o.value)}catch(p){r("throw",p)}}function r(t,e){switch(t){case"return":i.resolve({value:e,done:!0});break;case"throw":i.reject(e);break;default:i.resolve({value:e,done:!1})}i=i.next,i?a(i.key,i.arg):o=null}var i,o;this._invoke=n,"function"!=typeof e["return"]&&(this["return"]=void 0)}return"function"==typeof Symbol&&Symbol.asyncIterator&&(e.prototype[Symbol.asyncIterator]=function(){return this}),e.prototype.next=function(t){return this._invoke("next",t)},e.prototype["throw"]=function(t){return this._invoke("throw",t)},e.prototype["return"]=function(t){return this._invoke("return",t)},{wrap:function(t){return function(){return new e(t.apply(this,arguments))}},await:function(e){return new t(e)}}}(),e.asyncGeneratorDelegate=function(t,e){function n(n,a){return r=!0,a=new Promise(function(e){e(t[n](a))}),{done:!1,value:e(a)}}var a={},r=!1;return"function"==typeof Symbol&&Symbol.iterator&&(a[Symbol.iterator]=function(){return this}),a.next=function(t){return r?(r=!1,t):n("next",t)},"function"==typeof t["throw"]&&(a["throw"]=function(t){if(r)throw r=!1,t;return n("throw",t)}),"function"==typeof t["return"]&&(a["return"]=function(t){return n("return",t)}),a},e.asyncToGenerator=function(t){return function(){var e=t.apply(this,arguments);return new Promise(function(t,n){function a(r,i){try{var o=e[r](i),s=o.value}catch(p){return void n(p)}return o.done?void t(s):Promise.resolve(s).then(function(t){a("next",t)},function(t){a("throw",t)})}return a("next")})}},e.classCallCheck=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},e.createClass=function(){function t(t,e){for(var n=0;n=0||Object.prototype.hasOwnProperty.call(t,a)&&(n[a]=t[a]);return n},e.possibleConstructorReturn=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e},e.selfGlobal=void 0===t?self:t,e.set=function a(t,e,n,r){var i=Object.getOwnPropertyDescriptor(t,e);if(void 0===i){var o=Object.getPrototypeOf(t);null!==o&&a(o,e,n,r)}else if("value"in i&&i.writable)i.value=n;else{var s=i.set;void 0!==s&&s.call(r,n)}return n},e.slicedToArray=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(p){r=!0,i=p}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),e.slicedToArrayLoose=function(t,e){if(Array.isArray(t))return t;if(Symbol.iterator in Object(t)){for(var n,a=[],r=t[Symbol.iterator]();!(n=r.next()).done&&(a.push(n.value),!e||a.length!==e););return a}throw new TypeError("Invalid attempt to destructure non-iterable instance")},e.taggedTemplateLiteral=function(t,e){return Object.freeze(Object.defineProperties(t,{raw:{value:Object.freeze(e)}}))},e.taggedTemplateLiteralLoose=function(t,e){return t.raw=e,t},e.temporalRef=function(t,e,n){if(t===n)throw new ReferenceError(e+" is not defined - temporal dead zone");return t},e.temporalUndefined={},e.toArray=function(t){return Array.isArray(t)?t:Array.from(t)},e.toConsumableArray=function(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);e {{/if}} + + + {{#if data.locked && !data.siliconUser}} + {{data.emergencyLights ? "Enabled" : "Disabled"}} + {{else}} + {{data.emergencyLights ? "Enabled" : "Disabled"}} + {{/if}} + + {{#if data.locked && !data.siliconUser}} diff --git a/tgui/src/interfaces/clockwork_slab.ract b/tgui/src/interfaces/clockwork_slab.ract index af429cc904..48f6ae02f6 100644 --- a/tgui/src/interfaces/clockwork_slab.ract +++ b/tgui/src/interfaces/clockwork_slab.ract @@ -22,6 +22,9 @@ Scripts Applications
    {{{data.tier_info}}} +
    + + {{{data.scripturecolors}}}
    {{#each data.scripture}} diff --git a/tgui/src/interfaces/rdconsole.ract b/tgui/src/interfaces/rdconsole.ract new file mode 100644 index 0000000000..acba78c90e --- /dev/null +++ b/tgui/src/interfaces/rdconsole.ract @@ -0,0 +1,47 @@ + + + + + + + + + + + +{{#if data.locked}} + + Unlock + +{{/if}} +{{#if !data.locked}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{{/if}} \ No newline at end of file diff --git a/tgui/src/interfaces/rdconsole/circuit.ract b/tgui/src/interfaces/rdconsole/circuit.ract new file mode 100644 index 0000000000..c8df6c139c --- /dev/null +++ b/tgui/src/interfaces/rdconsole/circuit.ract @@ -0,0 +1,57 @@ +{{#if data.circuit_linked}} + {{#if data.circuitbusy}} + + {{else}} + + Search Available Designs: + + Search + + Materials: {{data.circuitmats}} / {{data.circuitmaxmats}} + Reagents: {{data.circuitchems}} / {{data.circuitmaxchems}} + + + + + {{#each data.circuitcats}} + {{name}} + {{/each}} + + + {{#each data.circuitdes}} + {{name}}{{matstring}} + Print + + {{/each}} + + + {{#each data.circuitmatch}} + {{name}}{{matstring}} + Print + + {{/each}} + + + {{#each data.circuitmat_list}} + {{name}} : {{amount}} cm3 - + {{#if sheets > 0}} + + Release + {{/if}} + + {{/each}} + + + {{#each data.circuitchem_list}} + {{name}} : {{amount}} - + Purge + + {{/each}} + + + + {{/if}} +{{else}} + +{{/if}} + diff --git a/tgui/src/interfaces/rdconsole/designview.ract b/tgui/src/interfaces/rdconsole/designview.ract new file mode 100644 index 0000000000..1ec2d92a95 --- /dev/null +++ b/tgui/src/interfaces/rdconsole/designview.ract @@ -0,0 +1,48 @@ +{{#if data.design_selected}} + + {{data.sdesign_desc}} + + + {{#if (data.sdesign_buildtype & 1)}} + + {{/if}} + {{#if (data.sdesign_buildtype & 2)}} + + {{/if}} + {{#if (data.sdesign_buildtype & 4)}} + + {{/if}} + {{#if (data.sdesign_buildtype & 8)}} + + {{/if}} + {{#if (data.sdesign_buildtype & 16)}} + + {{/if}} + {{#if (data.sdesign_buildtype & 32)}} + + {{/if}} + {{#if (data.sdesign_buildtype & 64)}} + + {{/if}} + {{#if (data.sdesign_buildtype & 128)}} + + {{/if}} + + + {{#each data.sdesign_materials}} + {{matamt}} cm^3 + {{/each}} + +{{/if}} +{{#if !data.design_selected}} + +{{/if}} + + + + + + + + + diff --git a/tgui/src/interfaces/rdconsole/destruct.ract b/tgui/src/interfaces/rdconsole/destruct.ract new file mode 100644 index 0000000000..c17e183704 --- /dev/null +++ b/tgui/src/interfaces/rdconsole/destruct.ract @@ -0,0 +1,25 @@ + +{{#if data.destroy_linked}} + {{#if data.destroybusy}} + + {{else}} + {{#if !data.destroy_loaded}} + + {{else}} + + {{data.destroy_name}} + + + {{#each data.boost_paths}} + + Deconstruct and Boost + + {{/each}} + + Eject Item + {{/if}} + {{/if}} +{{else}} + +{{/if}} + diff --git a/tgui/src/interfaces/rdconsole/diskopsdesign.ract b/tgui/src/interfaces/rdconsole/diskopsdesign.ract new file mode 100644 index 0000000000..ce949b3fb6 --- /dev/null +++ b/tgui/src/interfaces/rdconsole/diskopsdesign.ract @@ -0,0 +1,34 @@ + +{{#if !data.ddisk}} + +{{else}} + {{#if data.ddisk_update}} + + {{else}} + {{#if !data.ddisk_upload}} + + Disk Capacity: {{data.ddisk_size}} blueprints. + Upload all designs + WIPE ALL DATA + Eject Disk + + + {{#each data.ddisk_designs}} + #{{pos}}: + {{#if id == "null"}} + Upload to Empty Slot + {{else}} + {{name}} + Delete Slot + {{/if}} + + {{/each}} + + {{else}} + Available Designs: + {{#each data.ddisk_possible_designs}} + {{name}} + {{/each}} + {{/if}} + {{/if}} +{{/if}} diff --git a/tgui/src/interfaces/rdconsole/diskopstech.ract b/tgui/src/interfaces/rdconsole/diskopstech.ract new file mode 100644 index 0000000000..de05a67a91 --- /dev/null +++ b/tgui/src/interfaces/rdconsole/diskopstech.ract @@ -0,0 +1,19 @@ + +{{#if !data.tdisk}} + +{{else}} + {{#if data.tdisk_update}} + + {{else}} + + Download Research to DiskUpload Research from Disk + WIPE ALL DATA + Eject Disk + + + {{#each data.tdisk_nodes}} + {{display_name}} + {{/each}} + + {{/if}} +{{/if}} diff --git a/tgui/src/interfaces/rdconsole/nodeview.ract b/tgui/src/interfaces/rdconsole/nodeview.ract new file mode 100644 index 0000000000..929c6f1787 --- /dev/null +++ b/tgui/src/interfaces/rdconsole/nodeview.ract @@ -0,0 +1,26 @@ +{{#if data.node_selected}} + + Description: {{data.snode_desc}} + Point Cost: {{data.snode_cost}} + Export Price: {{data.snode_export}} + {{data.snode_researched? "Researched" : "Research Node"}} + + + {{#each data.node_prereqs}} + {{display_name}} + {{/each}} + + + {{#each data.node_unlocks}} + {{display_name}} + {{/each}} + + + {{#each data.node_designs}} + {{name}} + {{/each}} + +{{/if}} +{{#if !data.node_selected}} + +{{/if}} diff --git a/tgui/src/interfaces/rdconsole/protolathe.ract b/tgui/src/interfaces/rdconsole/protolathe.ract new file mode 100644 index 0000000000..a3a0486643 --- /dev/null +++ b/tgui/src/interfaces/rdconsole/protolathe.ract @@ -0,0 +1,62 @@ +{{#if data.protolathe_linked}} + {{#if data.protobusy}} + + {{else}} + + Search Available Designs: + + Search + + Materials: {{data.protomats}} / {{data.protomaxmats}} + Reagents: {{data.protochems}} / {{data.protomaxchems}} + + + + + {{#each data.protocats}} + {{name}} + {{/each}} + + + {{#each data.protodes}} + {{name}}{{matstring}} + {{#if canprint > 1}} + + {{/if}} + Print + + {{/each}} + + + {{#each data.protomatch}} + {{name}}{{matstring}} + {{#if canprint > 1}} + + {{/if}} + Print + + {{/each}} + + + {{#each data.protomat_list}} + {{name}} : {{amount}} cm3 - + {{#if sheets > 0}} + + Release + {{/if}} + + {{/each}} + + + {{#each data.protochem_list}} + {{name}} : {{amount}} - + Purge + + {{/each}} + + + + {{/if}} +{{else}} + +{{/if}} diff --git a/tgui/src/interfaces/rdconsole/rdheader.ract b/tgui/src/interfaces/rdconsole/rdheader.ract new file mode 100644 index 0000000000..1a053a5bde --- /dev/null +++ b/tgui/src/interfaces/rdconsole/rdheader.ract @@ -0,0 +1,7 @@ + +NanoTrasen R&D Console
    +Available Points: {{data.research_points_stored}} + +Select Page: [Go] + +
    diff --git a/tgui/src/interfaces/rdconsole/settings.ract b/tgui/src/interfaces/rdconsole/settings.ract new file mode 100644 index 0000000000..84ab3e8786 --- /dev/null +++ b/tgui/src/interfaces/rdconsole/settings.ract @@ -0,0 +1,6 @@ +Settings

    +RESYNC MACHINERY
    +LOCK +Disconnect Destructive Analyzer +Disconnect Protolathe +Disconnect Circuit Imprinter diff --git a/tgui/src/interfaces/rdconsole/techweb.ract b/tgui/src/interfaces/rdconsole/techweb.ract new file mode 100644 index 0000000000..6f78698db7 --- /dev/null +++ b/tgui/src/interfaces/rdconsole/techweb.ract @@ -0,0 +1,15 @@ + + {{#each data.techweb_avail}} + {{display_name}} + {{/each}} + + + {{#each data.techweb_locked}} + {{display_name}} + {{/each}} + + + {{#each data.techweb_researched}} + {{display_name}} + {{/each}} + diff --git a/tgui/src/interfaces/smoke_machine.ract b/tgui/src/interfaces/smoke_machine.ract index 9f21240430..983e04bce2 100644 --- a/tgui/src/interfaces/smoke_machine.ract +++ b/tgui/src/interfaces/smoke_machine.ract @@ -1,31 +1,31 @@ {{#if data.screen == "home"}} - - {{data.active ? "On" : "Off"}} - - - -
    - 3 - 6 - 9 - 12 - 15 -
    -
    - - {{#if data.isTankLoaded}} - {{Math.round(adata.TankCurrentVolume)}}/{{data.TankMaxVolume}} Units -
    + + {{data.active ? "On" : "Off"}} + + + +
    + 3 + 6 + 9 + 12 + 15 +
    +
    + + {{#if data.isTankLoaded}} + {{Math.round(adata.TankCurrentVolume)}}/{{data.TankMaxVolume}} Units +

    - {{#each adata.TankContents}} - {{Math.fixed(volume, 2)}} units of {{name}}
    - {{/each}} + {{#each adata.TankContents}} + {{Math.fixed(volume, 2)}} units of {{name}}
    + {{/each}} {{else}} - Tank Empty + Tank Empty {{/if}}
    - Reconnect + Reconnect
    - {{#if data.working}} - {{data.online && !(data.compressor_broke || data.turbine_broke) ? "Online" : "Offline"}} - {{else}} + {{#if data.broken}} Broken + {{else}} + {{data.online && !(data.compressor_broke || data.turbine_broke) ? "Online" : "Offline"}} {{/if}}
    - On - Off + On + Off
    {{#if data.compressor_broke}}
    @@ -40,12 +40,12 @@ component.exports = {
    - {{data.working ? data.rpm : "--"}} RPM + {{data.broken ? "--" : data.rpm}} RPM - {{data.working ? data.temp : "--"}} K + {{data.broken ? "--" : data.temp}} K - {{data.working ? data.power : "--"}} + {{data.broken ? "--" : data.power}} diff --git a/tools/Runtime Condenser/Main.cpp b/tools/Runtime Condenser/Main.cpp index 732318269b..3f8678992b 100644 --- a/tools/Runtime Condenser/Main.cpp +++ b/tools/Runtime Condenser/Main.cpp @@ -1,3 +1,4 @@ +<<<<<<< HEAD /* Runtime Condenser by Nodrak * Cleaned up and refactored by MrStonedOne * This will sum up identical runtimes into one, giving a total of how many times it occured. The first occurance @@ -387,3 +388,421 @@ int main() { return 0; } +======= +/* Runtime Condenser by Nodrak + * Cleaned up and refactored by MrStonedOne + * This will sum up identical runtimes into one, giving a total of how many times it occured. The first occurance + * of the runtime will log the source, usr and src, the rest will just add to the total. Infinite loops will + * also be caught and displayed (if any) above the list of runtimes. + * + * How to use: + * 1) Copy and paste your list of runtimes from Dream Daemon into input.exe + * 2) Run RuntimeCondenser.exe + * 3) Open output.txt for a condensed report of the runtimes + * + * How to compile: + * Requires visual c++ compiler 2012 or any linux compiler with c++11 support. + * Windows: + * Normal: cl.exe /EHsc /Ox /Qpar Main.cpp + * Debug: cl.exe /EHsc /Zi Main.cpp + * Linux: + * Normal: g++ -O3 -std=c++11 Main.cpp -o rc + * Debug: g++ -g -Og -std=c++11 Main.cpp -o rc + * Any Compile errors most likely indicate lack of c++11 support. Google how to upgrade or nag coderbus for help.. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define PROGRESS_FPS 10 +#define PROGRESS_BAR_INNER_WIDTH 50 +#define LINEBUFFER (32*1024) //32KiB + +using namespace std; + +struct runtime { + string text; + string proc; + string source; + string usr; + string src; + string loc; + unsigned int count; +}; +struct harddel { + string type; + unsigned int count; +}; +//What we use to read input +string * lastLine = new string(); +string * currentLine = new string(); +string * nextLine = new string(); + +//Stores lines we want to keep to print out +unordered_map storedRuntime; +unordered_map storedInfiniteLoop; +unordered_map storedHardDel; + +//Stat tracking stuff for output +unsigned int totalRuntimes = 0; +unsigned int totalInfiniteLoops = 0; +unsigned int totalHardDels = 0; + + +bool endofbuffer = false; +//like substr, but returns an empty string if the string is smaller then start, rather then an exception. +inline string safe_substr(string * S, size_t start = 0, size_t end = string::npos) { + if (start > S->length()) + start = S->length(); + return S->substr(start, end); +} +//getline() is slow as fucking balls. this is quicker because we prefill a buffer rather then read 1 byte at a time searching for newlines, lowering on i/o calls and overhead. (110MB/s vs 40MB/s on a 1.8GB file pre-filled into the disk cache) +//if i wanted to make it even faster, I'd use a reading thread, a new line searching thread, another thread or four for searching for runtimes in the list to see if they are unique, and finally the main thread for displaying the progress bar. but fuck that noise. +inline string * readline(FILE * f) { + static char buf[LINEBUFFER]; + static size_t pos = 0; + static size_t size = 0; + + for (size_t i = pos; i < LINEBUFFER; i++) { + char c = buf[i]; + if (i >= size && (pos || i < LINEBUFFER-1)) { + if (feof(f) || ferror(f)) + break; + if (size && pos) { //move current stuff to start of buffer + size -= pos; + i -= pos; + memmove(buf, &buf[pos], size); + } + //fill remaining buffer + size += fread(&buf[i], 1, LINEBUFFER-size-1, f); + pos = 0; + c = buf[i]; + } + if (c == '\n') { + //trim off any newlines from the start + while (i > pos && (buf[pos] == '\r' || buf[pos] == '\n')) + pos++; + string * s = new string(&buf[pos], i-pos); + pos = i+1; + return s; + } + + } + string * s = new string(&buf[pos], size-pos); + pos = 0; + size = 0; + endofbuffer = true; + return s; +} + +inline void forward_progress(FILE * inputFile) { + delete(lastLine); + lastLine = currentLine; + currentLine = nextLine; + nextLine = readline(inputFile); + //strip out any timestamps. + if (nextLine->length() >= 10) { + if ((*nextLine)[0] == '[' && (*nextLine)[3] == ':' && (*nextLine)[6] == ':' && (*nextLine)[9] == ']') + nextLine->erase(0, 10); + } +} +//deallocates to, copys from to to. +inline void string_send(string * &from, string * &to) { + delete(to); + to = new string(*from); +} +inline void printprogressbar(unsigned short progress /*as percent*/) { + double const modifer = 100.0L/(double)PROGRESS_BAR_INNER_WIDTH; + size_t bars = (double)progress/modifer; + cerr << "\r[" << string(bars, '=') << ((progress < 100) ? ">" : "") << string(PROGRESS_BAR_INNER_WIDTH-(bars+((progress < 100) ? 1 : 0)), ' ') << "] " << progress << "%"; + cerr.flush(); +} + +bool readFromFile(bool isstdin) { + //Open file to read + FILE * inputFile = stdin; + if (!isstdin) + inputFile = fopen("Input.txt", "r"); + + if (ferror(inputFile)) + return false; + long long fileLength = 0; + clock_t nextupdate = 0; + if (!isstdin) { + fseek(inputFile, 0, SEEK_END); + fileLength = ftell(inputFile); + fseek(inputFile, 0, SEEK_SET); + nextupdate = clock(); + } + + if (feof(inputFile)) + return false; //empty file + do { + //Update our lines + forward_progress(inputFile); + //progress bar + + if (!isstdin && clock() >= nextupdate) { + int dProgress = (int)(((long double)ftell(inputFile) / (long double)fileLength) * 100.0L); + printprogressbar(dProgress); + nextupdate = clock() + (CLOCKS_PER_SEC/PROGRESS_FPS); + } + //Found a runtime! + if (safe_substr(currentLine, 0, 14) == "runtime error:") { + if (currentLine->length() <= 17) { //empty runtime, check next line. + //runtime is on the line before this one. (byond bug) + if (nextLine->length() < 2) { + string_send(lastLine, nextLine); + } + forward_progress(inputFile); + string * tmp = new string("runtime error: " + *currentLine); + string_send(tmp, currentLine); + delete(tmp); + } + //we assign this to the right container in a moment. + unordered_map * storage_container; + + //runtime is actually an infinite loop + if (safe_substr(currentLine, 15, 23) == "Infinite loop suspected" || safe_substr(currentLine, 15, 31) == "Maximum recursion level reached") { + //use our infinite loop container. + storage_container = &storedInfiniteLoop; + totalInfiniteLoops++; + // skip the line about world.loop_checks + forward_progress(inputFile); + string_send(lastLine, currentLine); + } else { + //use the runtime container + storage_container = &storedRuntime; + totalRuntimes++; + } + + string key = *currentLine; + bool procfound = false; //so other things don't have to bother checking for this again. + if (safe_substr(nextLine, 0, 10) == "proc name:") { + key += *nextLine; + procfound = true; + } + + //(get the address of a runtime from (a pointer to a container of runtimes)) to then store in a pointer to a runtime. + //(and who said pointers were hard.) + runtime* R = &((*storage_container)[key]); + + //new + if (R->text != *currentLine) { + R->text = *currentLine; + if (procfound) { + R->proc = *nextLine; + forward_progress(inputFile); + } + R->count = 1; + + //search for source file info + if (safe_substr(nextLine, 2, 12) == "source file:") { + R->source = *nextLine; + //skip again + forward_progress(inputFile); + } + //If we find this, we have new stuff to store + if (safe_substr(nextLine, 2, 4) == "usr:") { + forward_progress(inputFile); + forward_progress(inputFile); + //Store more info + R->usr = *lastLine; + R->src = *currentLine; + if (safe_substr(nextLine, 2, 8) == "src.loc:") { + R->loc = *nextLine; + forward_progress(inputFile); + } + } + + } else { //existed already + R->count++; + if (procfound) + forward_progress(inputFile); + } + + } else if (safe_substr(currentLine, 0, 7) == "Path : ") { + string deltype = safe_substr(currentLine, 7); + if (deltype.substr(deltype.size()-1,1) == " ") //some times they have a single trailing space. + deltype = deltype.substr(0, deltype.size()-1); + + unsigned int failures = strtoul(safe_substr(nextLine, 11).c_str(), NULL, 10); + if (failures <= 0) + continue; + + totalHardDels += failures; + harddel* D = &storedHardDel[deltype]; + if (D->type != deltype) { + D->type = deltype; + D->count = failures; + } else { + D->count += failures; + } + } + } while (!feof(inputFile) || !endofbuffer); //Until end of file + if (!isstdin) + printprogressbar(100); + cerr << endl; + return true; +} + +bool runtimeComp(const runtime &a, const runtime &b) { + return a.count > b.count; +} + +bool hardDelComp(const harddel &a, const harddel &b) { + return a.count > b.count; +} + +bool writeToFile(bool usestdio) { + //Open and clear the file + ostream * output = &cout; + ofstream * outputFile; + if (!usestdio) + output = outputFile = new ofstream("Output.txt", ios::trunc); + + + if(usestdio || outputFile->is_open()) { + *output << "Note: The source file, src and usr are all from the FIRST of the identical runtimes. Everything else is cropped.\n\n"; + if(storedInfiniteLoop.size() > 0) + *output << "Total unique infinite loops: " << storedInfiniteLoop.size() << endl; + + if(totalInfiniteLoops > 0) + *output << "Total infinite loops: " << totalInfiniteLoops << endl << endl; + + *output << "Total unique runtimes: " << storedRuntime.size() << endl; + *output << "Total runtimes: " << totalRuntimes << endl << endl; + if(storedHardDel.size() > 0) + *output << "Total unique hard deletions: " << storedHardDel.size() << endl; + + if(totalHardDels > 0) + *output << "Total hard deletions: " << totalHardDels << endl << endl; + + + //If we have infinite loops, display them first. + if(storedInfiniteLoop.size() > 0) { + vector infiniteLoops; + infiniteLoops.reserve(storedInfiniteLoop.size()); + for (unordered_map::iterator it=storedInfiniteLoop.begin(); it != storedInfiniteLoop.end(); it++) + infiniteLoops.push_back(it->second); + storedInfiniteLoop.clear(); + sort(infiniteLoops.begin(), infiniteLoops.end(), runtimeComp); + *output << "** Infinite loops **"; + for (int i=0; i < infiniteLoops.size(); i++) { + runtime* R = &infiniteLoops[i]; + *output << endl << endl << "The following infinite loop has occurred " << R->count << " time(s).\n"; + *output << R->text << endl; + if(R->proc.length()) + *output << R->proc << endl; + if(R->source.length()) + *output << R->source << endl; + if(R->usr.length()) + *output << R->usr << endl; + if(R->src.length()) + *output << R->src << endl; + if(R->loc.length()) + *output << R->loc << endl; + } + *output << endl << endl; //For spacing + } + + + //Do runtimes next + *output << "** Runtimes **"; + vector runtimes; + runtimes.reserve(storedRuntime.size()); + for (unordered_map::iterator it=storedRuntime.begin(); it != storedRuntime.end(); it++) + runtimes.push_back(it->second); + storedRuntime.clear(); + sort(runtimes.begin(), runtimes.end(), runtimeComp); + for (int i=0; i < runtimes.size(); i++) { + runtime* R = &runtimes[i]; + *output << endl << endl << "The following runtime has occurred " << R->count << " time(s).\n"; + *output << R->text << endl; + if(R->proc.length()) + *output << R->proc << endl; + if(R->source.length()) + *output << R->source << endl; + if(R->usr.length()) + *output << R->usr << endl; + if(R->src.length()) + *output << R->src << endl; + if(R->loc.length()) + *output << R->loc << endl; + } + *output << endl << endl; //For spacing + + //and finally, hard deletes + if(totalHardDels > 0) { + *output << endl << "** Hard deletions **"; + vector hardDels; + hardDels.reserve(storedHardDel.size()); + for (unordered_map::iterator it=storedHardDel.begin(); it != storedHardDel.end(); it++) + hardDels.push_back(it->second); + storedHardDel.clear(); + sort(hardDels.begin(), hardDels.end(), hardDelComp); + for(int i=0; i < hardDels.size(); i++) { + harddel* D = &hardDels[i]; + *output << endl << D->type << " - " << D->count << " time(s).\n"; + } + } + if (!usestdio) { + outputFile->close(); + delete outputFile; + } + } else { + return false; + } + return true; +} + +int main(int argc, const char * argv[]) { + ios_base::sync_with_stdio(false); + ios::sync_with_stdio(false); + bool usestdio = false; + if (argc >= 2 && !strcmp(argv[1], "-s")) + usestdio = true; + + char exit; //Used to stop the program from immediately exiting + cerr << "Reading input.\n"; + if(readFromFile(usestdio)) { + cerr << "Input read successfully!\n"; + } else { + cerr << "Input failed to open, shutting down.\n"; + if (!usestdio) { + cerr << "\nEnter any letter to quit.\n"; + exit = cin.get(); + } + return 1; + } + + + cerr << "Writing output.\n"; + if(writeToFile(usestdio)) { + cerr << "Output was successful!\n"; + if (!usestdio) { + cerr << "\nEnter any letter to quit.\n"; + exit = cin.get(); + } + return 0; + } else { + cerr << "The output file could not be opened, shutting down.\n"; + if (!usestdio) { + cerr << "\nEnter any letter to quit.\n"; + exit = cin.get(); + } + return 1; + } + + return 0; +} +>>>>>>> dbccf52... Merge pull request #33702 from MrStonedOne/rc-the-unix-way diff --git a/tools/Runtime Condenser/RuntimeCondenser.exe b/tools/Runtime Condenser/RuntimeCondenser.exe index e53102f219..642efd09f0 100644 Binary files a/tools/Runtime Condenser/RuntimeCondenser.exe and b/tools/Runtime Condenser/RuntimeCondenser.exe differ diff --git a/tools/json_verifier.py b/tools/json_verifier.py new file mode 100644 index 0000000000..04c8670705 --- /dev/null +++ b/tools/json_verifier.py @@ -0,0 +1,19 @@ +import sys +import json + +if len(sys.argv) <= 1: + exit(1) + +files = filter(len, sys.argv[1].split('\n')) +msg = [] +for file in files: + with open(file, encoding="ISO-8859-1") as f: + try: + json.load(f) + except ValueError as exception: + msg.append("JSON synxtax error on file: {}".format(file)) + msg.append(str(exception)) +if msg: + print("\n".join(msg)) + exit(1) +exit(0) diff --git a/tools/travis/build_tools.sh b/tools/travis/build_tools.sh index 193ad261a6..525b45f124 100755 --- a/tools/travis/build_tools.sh +++ b/tools/travis/build_tools.sh @@ -10,5 +10,7 @@ then phpenv global 5.6 php -l tools/WebhookProcessor/github_webhook_processor.php; php -l tools/TGUICompiler.php; + echo "Checking for JSON errors"; + find . -name "*.json" -not -path "./tgui/node_modules/*" | xargs -0 python3 ./tools/json_verifier.py; python tools/ss13_genchangelog.py html/changelog.html html/changelogs; fi;