diff --git a/.travis.yml b/.travis.yml
index eaa289e5cc7..526ebde75ea 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,16 +5,6 @@ sudo: false
git:
depth: 1
-env:
- global:
- - BYOND_MAJOR="511"
- - BYOND_MINOR="1385"
- - BYOND_MACRO_COUNT=2
- matrix:
- - DM_MAPFILE="cyberiad"
- - DM_MAPFILE="metastation"
- - DM_MAPFILE="test_away_missions"
-
cache:
directories:
- $HOME/BYOND-${BYOND_MAJOR}.${BYOND_MINOR}
@@ -26,24 +16,57 @@ addons:
- libgcc1:i386
- libstdc++6:i386
+env:
+ global:
+ - BYOND_MAJOR="511"
+ - BYOND_MINOR="1385"
+ - BYOND_MACRO_COUNT=4
+ matrix:
+ - DM_MAPFILE="cyberiad"
+ - DM_MAPFILE="metastation"
+ - DM_MAPFILE="test_all_maps"
+
+stages:
+ - File Checks
+ - test
+
before_script:
- chmod +x ./install-byond.sh
- ./install-byond.sh
script:
- - (num=`grep -E '\\\\(red|blue|green|black|italic|bold|b|i[^mc])' **/*.dm | wc -l`; echo "$num BYOND text macros (expecting ${BYOND_MACRO_COUNT} or fewer)"; [ $num -le ${BYOND_MACRO_COUNT} ])
- source $HOME/BYOND-${BYOND_MAJOR}.${BYOND_MINOR}/byond/bin/byondsetup
- bash dm.sh -M${DM_MAPFILE} paradise.dme
-matrix:
+jobs:
include:
- - env: FILE_CHECKS=1
+ # Basic styling/functionality checks
+ - stage: File Checks
+ env:
addons:
install:
- pip install --user PyYaml -q
- pip install --user beautifulsoup4 -q
- before_script:
+ before_script: skip
script:
- shopt -s globstar
- (! grep 'step_[xy]' _maps/map_files/**/*.dmm)
+ - (num=$(grep -Ern '\\(red|blue|green|black|italic|bold|b|i[^mc])' code/ | wc -l); echo "$num BYOND text macros (expecting ${BYOND_MACRO_COUNT} or fewer)"; [ $num -le ${BYOND_MACRO_COUNT} ])
- md5sum -c - <<< "6dc1b6bf583f3bd4176b6df494caa5f1 *html/changelogs/example.yml"
- python tools/ss13_genchangelog.py html/changelog.html html/changelogs
+
+ # Compile NanoUI to make sure it works
+ - stage: NanoUI
+ language: node_js
+ node_js:
+ - "9"
+ env:
+ addons:
+ before_install:
+ - npm install -g bower gulp
+ - cd ./nano/
+ install:
+ - npm install --loglevel=error
+ - bower install --silent
+ before_script:
+ script:
+ - gulp --min
diff --git a/SQL/paradise_schema.sql b/SQL/paradise_schema.sql
index 826e47878c6..34d3fef31be 100644
--- a/SQL/paradise_schema.sql
+++ b/SQL/paradise_schema.sql
@@ -359,12 +359,12 @@ DROP TABLE IF EXISTS `privacy`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `privacy` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `datetime` datetime NOT NULL,
`ckey` varchar(32) NOT NULL,
- `option` varchar(128) NOT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=10000 DEFAULT CHARSET=latin1;
+ `datetime` datetime NOT NULL,
+ `consent` bit(1) NOT NULL,
+ PRIMARY KEY (`ckey`),
+ UNIQUE KEY `ckey_UNIQUE` (`ckey`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
diff --git a/SQL/paradise_schema_prefixed.sql b/SQL/paradise_schema_prefixed.sql
index e0056474db3..afc730af8c9 100644
--- a/SQL/paradise_schema_prefixed.sql
+++ b/SQL/paradise_schema_prefixed.sql
@@ -357,13 +357,13 @@ CREATE TABLE `SS13_poll_vote` (
DROP TABLE IF EXISTS `SS13_privacy`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `SS13_privacy` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `datetime` datetime NOT NULL,
+CREATE TABLE `ss13_privacy` (
`ckey` varchar(32) NOT NULL,
- `option` varchar(128) NOT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=10000 DEFAULT CHARSET=latin1;
+ `datetime` datetime NOT NULL,
+ `consent` bit(1) NOT NULL,
+ PRIMARY KEY (`ckey`),
+ UNIQUE KEY `ckey_UNIQUE` (`ckey`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
diff --git a/SQL/updates/2-3.sql b/SQL/updates/2-3.sql
new file mode 100644
index 00000000000..d733759bc6e
--- /dev/null
+++ b/SQL/updates/2-3.sql
@@ -0,0 +1,10 @@
+#Updating the SQL from version 2 to version 3. -alffd
+#Droping privacy table and recreating for terms of service tracking
+DROP TABLE `privacy`;
+CREATE TABLE `privacy` (
+ `ckey` varchar(32) NOT NULL,
+ `datetime` datetime NOT NULL,
+ `consent` bit(1) NOT NULL,
+ PRIMARY KEY (`ckey`),
+ UNIQUE KEY `ckey_UNIQUE` (`ckey`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
diff --git a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm
index 145248966bc..bd1fb3145b3 100644
--- a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm
@@ -1242,7 +1242,7 @@
"axT" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable/yellow,/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/maintenance/fore)
"axU" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable/yellow,/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/maintenance/fore)
"axV" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 2; initialize_directions = 11},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness{name = "\improper Recreation Area"})
-"axW" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/turf/simulated/floor/plating,/area/security/main)
+"axW" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; max_integrity = 120; reinf = 0},/turf/simulated/floor/plating,/area/security/main)
"axX" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad"},/obj/machinery/door/poddoor{id_tag = "QMLoaddoor"; name = "supply dock loading door"},/turf/simulated/floor/plating,/area/quartermaster/storage)
"axY" = (/obj/machinery/cryopod/right,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/fitness{name = "\improper Recreation Area"})
"axZ" = (/obj/machinery/door/poddoor/shutters{dir = 2; id_tag = "supplybridge"},/turf/simulated/floor/plating{tag = "icon-warnplate (SOUTHEAST)"; icon_state = "warnplate"; dir = 6},/area/maintenance/fpmaint2{name = "Port Maintenance"})
@@ -1277,7 +1277,7 @@
"ayC" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor/plating,/area/hallway/secondary/entry{name = "Arrivals"})
"ayD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"})
"ayE" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"})
-"ayF" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fore)
+"ayF" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; max_integrity = 120; reinf = 0},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fore)
"ayG" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/fore)
"ayH" = (/obj/structure/disposalpipe/junction{tag = "icon-pipe-j2 (NORTH)"; icon_state = "pipe-j2"; dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/fore)
"ayI" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/hardsuit/engineering,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/hardsuit/engineering,/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/engine/engineering)
@@ -1495,9 +1495,9 @@
"aCM" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/engine/engineering)
"aCN" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/quartermaster/sorting{name = "\improper Warehouse"})
"aCO" = (/turf/simulated/wall/r_wall,/area/security/detectives_office)
-"aCP" = (/obj/structure/grille,/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/turf/simulated/floor/plating,/area/security/detectives_office)
+"aCP" = (/obj/structure/grille,/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/obj/structure/window/reinforced/tinted{dir = 5; max_integrity = 120; reinf = 0},/turf/simulated/floor/plating,/area/security/detectives_office)
"aCQ" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/security{name = "Detective's Office"; req_access = null; req_access_txt = "4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/turf/simulated/floor/plasteel,/area/security/detectives_office)
-"aCR" = (/obj/structure/grille,/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/turf/simulated/floor/plating,/area/security/detectives_office)
+"aCR" = (/obj/structure/grille,/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/window/reinforced/tinted{dir = 5; max_integrity = 120; reinf = 0},/turf/simulated/floor/plating,/area/security/detectives_office)
"aCS" = (/turf/simulated/wall,/area/security/detectives_office)
"aCT" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/light/small,/turf/simulated/floor/plasteel{icon_state = "whitered"},/area/security/brig)
"aCU" = (/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/machinery/alarm{pixel_y = 26},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet{name = "\improper Restrooms"})
@@ -2285,7 +2285,7 @@
"aRW" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/structure/disposalpipe/junction{icon_state = "pipe-j1"; dir = 4},/turf/simulated/floor/plasteel{dir = 1; icon_state = "neutralcorner"},/area/crew_quarters/locker)
"aRX" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 2; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/plasteel,/area/crew_quarters/locker)
"aRY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=14.5-Recreation"; location = "14.3-Lockers-Dorms"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "neutralcorner"},/area/crew_quarters/locker)
-"aRZ" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/turf/simulated/floor/plating,/area/hallway/secondary/construction{name = "\improper Garden"})
+"aRZ" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; max_integrity = 120; reinf = 0},/turf/simulated/floor/plating,/area/hallway/secondary/construction{name = "\improper Garden"})
"aSa" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 8},/area/hallway/secondary/construction{name = "\improper Garden"})
"aSb" = (/obj/machinery/hydroponics/soil,/turf/simulated/floor/plasteel{icon_state = "bot"},/area/hallway/secondary/construction{name = "\improper Garden"})
"aSc" = (/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 4},/area/hallway/secondary/construction{name = "\improper Garden"})
@@ -2419,7 +2419,7 @@
"aUA" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/crew_quarters/locker)
"aUB" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11},/turf/simulated/floor/plasteel,/area/crew_quarters/locker)
"aUC" = (/obj/structure/rack,/obj/item/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/item/storage/toolbox/mechanical{pixel_x = 4; pixel_y = -4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/crew_quarters/locker)
-"aUD" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/hallway/secondary/construction{name = "\improper Garden"})
+"aUD" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; max_integrity = 120; reinf = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/hallway/secondary/construction{name = "\improper Garden"})
"aUE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 8},/area/hallway/secondary/construction{name = "\improper Garden"})
"aUF" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = "90Curve"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/engine/engineering)
"aUG" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/grass,/area/hallway/secondary/construction{name = "\improper Garden"})
@@ -2470,7 +2470,7 @@
"aVz" = (/obj/item/radio/intercom{broadcasting = 1; frequency = 1447; name = "Private AI Channel"; pixel_y = -25},/obj/machinery/camera/motion{c_tag = "AI Upload Chamber - Starboard"; dir = 1; network = list("SS13","RD","AIUpload")},/turf/simulated/floor/bluegrid,/area/turret_protected/ai_upload)
"aVA" = (/obj/structure/table,/obj/machinery/light{dir = 4},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 32; pixel_y = 0},/obj/machinery/flasher{id = "AI"; pixel_x = 0; pixel_y = -24},/obj/item/aiModule/protectStation,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai_upload)
"aVB" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11},/turf/simulated/floor/plasteel{dir = 8; icon_state = "redcorner"},/area/hallway/primary/fore)
-"aVC" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/turf/simulated/floor/plating,/area/crew_quarters/courtroom)
+"aVC" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/window/reinforced/tinted{dir = 5; max_integrity = 120; reinf = 0},/turf/simulated/floor/plating,/area/crew_quarters/courtroom)
"aVD" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/vending/cigarette,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/courtroom)
"aVE" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/courtroom)
"aVF" = (/obj/structure/stool/bed/chair{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/courtroom)
@@ -2624,7 +2624,7 @@
"aYx" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/hallway/primary/central)
"aYy" = (/obj/machinery/door/airlock/highsecurity{icon_state = "door_closed"; locked = 0; name = "AI Upload"; req_access_txt = "16"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai_upload)
"aYz" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel,/area/hallway/primary/fore)
-"aYA" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/turf/simulated/floor/plating,/area/crew_quarters/courtroom)
+"aYA" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; max_integrity = 120; reinf = 0},/turf/simulated/floor/plating,/area/crew_quarters/courtroom)
"aYB" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/courtroom)
"aYC" = (/obj/structure/extinguisher_cabinet{pixel_x = 5; pixel_y = -32},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/courtroom)
"aYD" = (/obj/item/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = 0; pixel_y = -26},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/courtroom)
@@ -2661,8 +2661,8 @@
"aZi" = (/obj/structure/sign/pods,/turf/simulated/wall,/area/hallway/secondary/entry{name = "Arrivals"})
"aZj" = (/obj/machinery/door/airlock/external{name = "Escape Pod One"},/turf/simulated/floor/plating,/area/hallway/secondary/entry{name = "Arrivals"})
"aZk" = (/obj/machinery/door/airlock/engineering{name = "Arrivals Expansion Area"; req_access_txt = "32"},/turf/simulated/floor/plating,/area/hallway/secondary/entry{name = "Arrivals"})
-"aZl" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/hallway/secondary/entry{name = "Arrivals"})
-"aZm" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/turf/simulated/floor/plating,/area/hallway/secondary/entry{name = "Arrivals"})
+"aZl" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; max_integrity = 120; reinf = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/hallway/secondary/entry{name = "Arrivals"})
+"aZm" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; max_integrity = 120; reinf = 0},/turf/simulated/floor/plating,/area/hallway/secondary/entry{name = "Arrivals"})
"aZn" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/engineering{name = "Arrivals Expansion Area"; req_access_txt = "32"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/hallway/secondary/entry{name = "Arrivals"})
"aZo" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel,/area/engine/break_room)
"aZp" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f5"; icon_state = "swall_f5"; dir = 2},/area/shuttle/supply)
@@ -4461,7 +4461,7 @@
"bHO" = (/obj/structure/stool{pixel_y = 8},/turf/simulated/floor/plasteel{icon_state = "bar"},/area/crew_quarters/bar)
"bHP" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "bar"},/area/crew_quarters/bar)
"bHQ" = (/obj/structure/stool{pixel_y = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/effect/landmark/start{name = "Civilian"},/turf/simulated/floor/plasteel{icon_state = "bar"},/area/crew_quarters/bar)
-"bHR" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/turf/simulated/floor/plating,/area/crew_quarters/bar)
+"bHR" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; max_integrity = 120; reinf = 0},/turf/simulated/floor/plating,/area/crew_quarters/bar)
"bHS" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/wood,/area/crew_quarters/bar)
"bHT" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 2},/turf/simulated/floor/wood,/area/crew_quarters/bar)
"bHU" = (/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/carpet,/area/crew_quarters/theatre)
@@ -6878,9 +6878,9 @@
"cCn" = (/obj/structure/stool/bed/chair{dir = 1},/obj/machinery/light,/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteblue"},/area/medical/reception)
"cCo" = (/obj/structure/disposalpipe/trunk{dir = 1},/obj/machinery/disposal,/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteblue"},/area/medical/reception)
"cCp" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/item/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = -29},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "bluecorner"},/area/hallway/primary/aft)
-"cCq" = (/obj/structure/flora/ausbushes/fernybush,/obj/structure/flora/ausbushes/fullgrass,/obj/structure/flora/ausbushes/ppflowers,/obj/structure/flora/ausbushes/palebush,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/grass,/area/medical/surgeryobs)
+"cCq" = (/obj/structure/flora/ausbushes/fernybush,/obj/structure/flora/ausbushes/fullgrass,/obj/structure/flora/ausbushes/ppflowers,/obj/structure/flora/ausbushes/palebush,/obj/structure/window/reinforced{dir = 5; max_integrity = 1e+007},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/grass,/area/medical/surgeryobs)
"cCr" = (/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24; shock_proof = 0},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/medical/surgeryobs)
-"cCs" = (/obj/structure/flora/ausbushes/fernybush,/obj/structure/flora/ausbushes/fullgrass,/obj/structure/flora/ausbushes/brflowers,/obj/structure/flora/ausbushes/sunnybush,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/grass,/area/medical/surgeryobs)
+"cCs" = (/obj/structure/flora/ausbushes/fernybush,/obj/structure/flora/ausbushes/fullgrass,/obj/structure/flora/ausbushes/brflowers,/obj/structure/flora/ausbushes/sunnybush,/obj/structure/window/reinforced{dir = 5; max_integrity = 1e+007},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/grass,/area/medical/surgeryobs)
"cCt" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 0},/turf/simulated/wall,/area/medical/surgeryobs)
"cCu" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgeryobs)
"cCv" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{dir = 8; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/medical/surgeryobs)
@@ -7788,7 +7788,7 @@
"cTO" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "warningcorner"; dir = 4},/area/hallway/secondary/exit{name = "\improper Departure Lounge"})
"cTP" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit{name = "\improper Departure Lounge"})
"cTQ" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit{name = "\improper Departure Lounge"})
-"cTR" = (/obj/structure/flora/ausbushes/fernybush,/obj/structure/flora/ausbushes/fullgrass,/obj/structure/flora/ausbushes/ppflowers,/obj/structure/flora/ausbushes/palebush,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/simulated/floor/grass,/area/hallway/secondary/exit{name = "\improper Departure Lounge"})
+"cTR" = (/obj/structure/flora/ausbushes/fernybush,/obj/structure/flora/ausbushes/fullgrass,/obj/structure/flora/ausbushes/ppflowers,/obj/structure/flora/ausbushes/palebush,/obj/structure/window/reinforced{dir = 5; max_integrity = 1e+007},/turf/simulated/floor/grass,/area/hallway/secondary/exit{name = "\improper Departure Lounge"})
"cTS" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/hallway/secondary/exit{name = "\improper Departure Lounge"})
"cTT" = (/obj/machinery/computer/secure_data,/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 8},/area/hallway/secondary/exit{name = "\improper Departure Lounge"})
"cTU" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit{name = "\improper Departure Lounge"})
@@ -7810,7 +7810,7 @@
"cUk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/chapel/office)
"cUl" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/chapel/office)
"cUm" = (/obj/machinery/light_switch{pixel_x = 28; pixel_y = 0},/obj/machinery/light/small{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/camera{c_tag = "Chapel Office"; dir = 8; network = list("SS13")},/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/chapel/office)
-"cUn" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/chapel/office)
+"cUn" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; max_integrity = 120; reinf = 0},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/chapel/office)
"cUo" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/turf/simulated/floor/plasteel{dir = 8; icon_state = "whiteblue"},/area/medical/medbay3)
"cUp" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay3)
"cUq" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay3)
@@ -7854,7 +7854,7 @@
"cVc" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit{name = "\improper Departure Lounge"})
"cVd" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 2; initialize_directions = 11},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit{name = "\improper Departure Lounge"})
"cVe" = (/obj/structure/stool/bed/chair{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"})
-"cVf" = (/obj/structure/flora/ausbushes/fernybush,/obj/structure/flora/ausbushes/fullgrass,/obj/structure/flora/ausbushes/brflowers,/obj/structure/flora/ausbushes/sunnybush,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/grass,/area/hallway/secondary/exit{name = "\improper Departure Lounge"})
+"cVf" = (/obj/structure/flora/ausbushes/fernybush,/obj/structure/flora/ausbushes/fullgrass,/obj/structure/flora/ausbushes/brflowers,/obj/structure/flora/ausbushes/sunnybush,/obj/structure/window/reinforced{dir = 5; max_integrity = 1e+007},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/grass,/area/hallway/secondary/exit{name = "\improper Departure Lounge"})
"cVg" = (/obj/structure/stool/bed/chair{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"})
"cVh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit{name = "\improper Departure Lounge"})
"cVi" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit{name = "\improper Departure Lounge"})
diff --git a/_maps/map_files/RandomZLevels/evil_santa.dmm b/_maps/map_files/RandomZLevels/evil_santa.dmm
index 2b51f7407a5..ca6ab415c1f 100644
--- a/_maps/map_files/RandomZLevels/evil_santa.dmm
+++ b/_maps/map_files/RandomZLevels/evil_santa.dmm
@@ -14,7 +14,7 @@
"an" = (/obj/item/paper/journal_scrap_2,/turf/simulated/floor/carpet,/area/awaymission/challenge/main)
"ao" = (/obj/structure/flora/rock/pile,/turf/simulated/floor/snow{carbon_dioxide = 21.8366; nitrogen = 0; oxygen = 82.1472; temperature = 73},/area/awaymission/challenge/main)
"ap" = (/obj/structure/flora/tree/dead,/turf/simulated/floor/snow{carbon_dioxide = 21.8366; nitrogen = 0; oxygen = 82.1472; temperature = 73},/area/awaymission/challenge/main)
-"aq" = (/obj/machinery/door/unpowered/shuttle,/obj/structure/fans/tiny,/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/awaymission/challenge/main)
+"aq" = (/obj/structure/mineral_door/wood{tag = "icon-wood"; icon_state = "wood"},/obj/structure/fans/tiny,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main)
"ar" = (/obj/item/restraints/legcuffs/beartrap,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main)
"as" = (/obj/machinery/space_heater,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main)
"at" = (/obj/structure/table/wood,/obj/item/newton,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main)
@@ -42,7 +42,7 @@
"aP" = (/turf/simulated/floor/snow{carbon_dioxide = 21.8366; nitrogen = 0; oxygen = 82.1472; temperature = 73},/turf/simulated/shuttle/wall{icon_state = "swall_f6"; dir = 2},/area/awaymission/challenge/main)
"aQ" = (/turf/simulated/shuttle/wall{icon_state = "swall12"; dir = 2},/area/awaymission/challenge/main)
"aR" = (/turf/simulated/shuttle/wall{icon_state = "swall8"; dir = 2},/area/awaymission/challenge/main)
-"aS" = (/obj/structure/mineral_door/wood{tag = "icon-wood"; icon_state = "wood"},/obj/structure/fans/tiny,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main)
+"aS" = (/obj/machinery/door/unpowered/shuttle,/obj/structure/fans/tiny,/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/awaymission/challenge/main)
"aT" = (/turf/simulated/shuttle/wall{icon_state = "swall4"; dir = 2},/area/awaymission/challenge/main)
"aU" = (/turf/simulated/floor/snow{carbon_dioxide = 21.8366; nitrogen = 0; oxygen = 82.1472; temperature = 73},/turf/simulated/shuttle/wall{icon_state = "swall_f10"; dir = 2},/area/awaymission/challenge/main)
"aV" = (/turf/simulated/floor/plasteel{icon_plating = "asteroid"; icon_state = "asteroid"; name = "Asteroid"},/area/awaymission/challenge/main)
@@ -78,55 +78,54 @@
"bz" = (/obj/item/clothing/head/cone,/turf/simulated/floor/snow{carbon_dioxide = 21.8366; nitrogen = 0; oxygen = 82.1472; temperature = 73},/area/awaymission/challenge/main)
"bA" = (/mob/living/simple_animal/walrus,/turf/simulated/floor/snow{carbon_dioxide = 21.8366; nitrogen = 0; oxygen = 82.1472; temperature = 73},/area/awaymission/challenge/main)
"bB" = (/obj/structure/closet/toolcloset,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main)
-"bC" = (/obj/item/taperoll/engineering,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main)
-"bD" = (/obj/item/storage/toolbox/emergency,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main)
+"bC" = (/obj/item/storage/toolbox/emergency,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main)
+"bD" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/awaymission/challenge/start)
"bE" = (/obj/machinery/door/poddoor{id_tag = "challenge"; name = "Gateway Shutters"},/obj/structure/fans/tiny,/turf/simulated/floor/plasteel{tag = "icon-delivery (SOUTHEAST)"; icon_state = "delivery"; dir = 6},/area/awaymission/challenge/start)
-"bF" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/awaymission/challenge/start)
-"bG" = (/obj/machinery/door/unpowered/shuttle,/turf/simulated/floor/plasteel{tag = "icon-delivery (SOUTHEAST)"; icon_state = "delivery"; dir = 6},/area/awaymission/challenge/start)
-"bH" = (/obj/machinery/door/poddoor{id_tag = "challenge"; name = "Gateway Shutters"},/turf/simulated/floor/plasteel{tag = "icon-delivery (SOUTHEAST)"; icon_state = "delivery"; dir = 6},/area/awaymission/challenge/start)
-"bI" = (/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
+"bF" = (/obj/machinery/door/unpowered/shuttle,/turf/simulated/floor/plasteel{tag = "icon-delivery (SOUTHEAST)"; icon_state = "delivery"; dir = 6},/area/awaymission/challenge/start)
+"bG" = (/obj/machinery/door/poddoor{id_tag = "challenge"; name = "Gateway Shutters"},/turf/simulated/floor/plasteel{tag = "icon-delivery (SOUTHEAST)"; icon_state = "delivery"; dir = 6},/area/awaymission/challenge/start)
+"bH" = (/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
+"bI" = (/obj/machinery/door_control{id = "challenge"; name = "Gateway Lockdown"; pixel_x = -4; pixel_y = 26; req_access_txt = "0"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/awaymission/challenge/start)
"bJ" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/awaymission/challenge/start)
-"bK" = (/obj/machinery/door_control{id = "challenge"; name = "Gateway Lockdown"; pixel_x = -4; pixel_y = 26; req_access_txt = "0"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/awaymission/challenge/start)
-"bL" = (/obj/effect/landmark{name = "awaystart"},/turf/simulated/floor/greengrid,/area/awaymission/challenge/start)
-"bM" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
+"bK" = (/obj/effect/landmark{name = "awaystart"},/turf/simulated/floor/greengrid,/area/awaymission/challenge/start)
+"bL" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
+"bM" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/obj/item/paper/journal_scrap_1,/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
"bN" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
-"bO" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/obj/item/paper/journal_scrap_1,/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
-"bP" = (/obj/machinery/gateway{dir = 9},/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start)
+"bO" = (/obj/machinery/gateway{dir = 9},/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start)
+"bP" = (/obj/machinery/gateway{dir = 1},/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start)
"bQ" = (/obj/machinery/gateway{dir = 5},/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start)
"bR" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/awaymission/challenge/main)
-"bS" = (/obj/machinery/gateway{dir = 1},/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start)
-"bT" = (/obj/machinery/atmospherics/unary/vent_pump{on = 1},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
-"bU" = (/obj/structure/dispenser/oxygen{oxygentanks = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
-"bV" = (/obj/machinery/gateway{dir = 8},/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start)
+"bS" = (/obj/machinery/atmospherics/unary/vent_pump{on = 1},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
+"bT" = (/obj/structure/dispenser/oxygen{oxygentanks = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
+"bU" = (/obj/machinery/gateway{dir = 8},/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start)
+"bV" = (/obj/machinery/gateway/centeraway,/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start)
"bW" = (/obj/machinery/gateway{dir = 4},/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start)
"bX" = (/obj/machinery/power/smes/magical,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/awaymission/challenge/main)
"bY" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc/noalarm{dir = 4; name = "Worn-out APC"; pixel_x = 24; pixel_y = 0},/turf/simulated/floor/plating,/area/awaymission/challenge/main)
-"bZ" = (/obj/machinery/gateway/centeraway,/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start)
+"bZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
"ca" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
-"cb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
-"cc" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
+"cb" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
+"cc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
"cd" = (/obj/machinery/gateway{dir = 10},/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start)
-"ce" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
+"ce" = (/obj/machinery/gateway,/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start)
"cf" = (/obj/machinery/gateway{dir = 6},/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start)
"cg" = (/turf/simulated/floor/plating,/area/awaymission/challenge/main)
"ch" = (/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/awaymission/challenge/main)
-"ci" = (/obj/machinery/gateway,/turf/simulated/floor/bluegrid,/area/awaymission/challenge/start)
-"cj" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/machinery/power/apc/noalarm{dir = 4; name = "Worn-out APC"; pixel_x = 24; pixel_y = 0},/turf/simulated/floor/plating,/area/awaymission/challenge/start)
-"ck" = (/obj/machinery/space_heater,/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
-"cl" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
+"ci" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/machinery/power/apc/noalarm{dir = 4; name = "Worn-out APC"; pixel_x = 24; pixel_y = 0},/turf/simulated/floor/plating,/area/awaymission/challenge/start)
+"cj" = (/obj/machinery/space_heater,/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
+"ck" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
+"cl" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
"cm" = (/obj/structure/table,/obj/item/clothing/accessory/scarf/christmas,/obj/item/clothing/accessory/scarf/christmas,/obj/item/clothing/accessory/scarf/christmas,/obj/item/clothing/accessory/scarf/christmas,/obj/item/clothing/accessory/scarf/christmas,/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
-"cn" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
+"cn" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/table,/obj/item/clothing/head/helmet/space/santahat,/obj/item/clothing/head/helmet/space/santahat,/obj/item/clothing/head/helmet/space/santahat,/obj/item/clothing/head/helmet/space/santahat,/obj/item/clothing/head/helmet/space/santahat,/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
"co" = (/obj/structure/table,/obj/item/clothing/suit/furcoat,/obj/item/clothing/suit/furcoat,/obj/item/clothing/suit/furcoat,/obj/item/clothing/suit/furcoat,/obj/item/clothing/suit/furcoat,/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
-"cp" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/table,/obj/item/clothing/head/helmet/space/santahat,/obj/item/clothing/head/helmet/space/santahat,/obj/item/clothing/head/helmet/space/santahat,/obj/item/clothing/head/helmet/space/santahat,/obj/item/clothing/head/helmet/space/santahat,/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
-"cq" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
-"cr" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/awaymission/challenge/start)
+"cp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/plasteel,/area/awaymission/challenge/start)
+"cq" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/awaymission/challenge/start)
+"cr" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/awaymission/challenge/start)
"cs" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal{dir = 4},/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/awaymission/challenge/start)
-"ct" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/awaymission/challenge/start)
-"cu" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/awaymission/challenge/start)
-"cv" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 10; initialize_directions = 10},/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/awaymission/challenge/start)
+"ct" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/awaymission/challenge/start)
+"cu" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 10; initialize_directions = 10},/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/awaymission/challenge/start)
+"cv" = (/obj/machinery/atmospherics/unary/tank/air{dir = 1},/turf/simulated/floor/plating,/area/awaymission/challenge/start)
"cw" = (/turf/space,/area/space)
-"cx" = (/obj/machinery/atmospherics/unary/tank/air{dir = 1},/turf/simulated/floor/plating,/area/awaymission/challenge/start)
-"cy" = (/obj/machinery/atmospherics/unary/outlet_injector/on{dir = 1},/turf/simulated/floor/plating/airless,/area/awaymission/challenge/start)
+"cx" = (/obj/machinery/atmospherics/unary/outlet_injector/on{dir = 1},/turf/simulated/floor/plating/airless,/area/awaymission/challenge/start)
(1,1,1) = {"
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -140,7 +139,7 @@ aaabababababacababafacacacacacacacacacacacacacacacacacacacacacacababacacacacacac
aaababababacacacacacacacacacacahacacacacacacacacacacacacacacacacacacacacacacacacacacacacacagagagaiajakagacacacacacacabababababaa
aaabababacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacalagamamajajajagacacacacacacacababababaa
aaabababacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacalagamamanajajagacacacacacacacacabababaa
-aaabababacacacaoacacacacacacacacacacacacacacacacacacacacapacacacacacacacacacacacacacacacacaSaramamasagagacacacacacacacacabababaa
+aaabababacacacaoacacacacacacacacacacacacacacacacacacacacapacacacacacacacacacacacacacacacacaqaramamasagagacacacacacacacacabababaa
aaabababacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacagagagamatauacacacacacacacacacabababaa
aaabababacacacacacacacacacacacacagagagagagagagavacacacacacacacacacacacacacacacacacacacacacacawagaxayauacacacacacacacacacabababaa
aaabababacadacacacacacacacacacacagazaAaBaCaDagacacacacacacacacafacacacacacacacacacacacacacacacagagagagacacacacacacacacacabababaa
@@ -148,7 +147,7 @@ aaabababacacacacacacacacacacacacagamamamamamagacacacacacacacacacacacacacaoacacab
aaabababacacacacacacacacacacacacauamamamamamauacacacacacacacacacacacacacacababababacacacacacacacacacacacacacacacacacacacabababaa
aaabababacacacacacacalacacacacacagamamamamaEagacacacacacacacacacacacacacacabababababababacacacacacacacacacacacacacacacacabababaa
aaabababacacacacacacacacacacacacagasamamamaFagacacacacacacacacacacacacacacacababababababacacacacacacacacacacacacacahacacabababaa
-aaabababacacacacacafacacacacacacagagagaSagagagacacacacacacacacacacacacacacacacabababacavacacacacacacacacacacacacacacacacabababaa
+aaabababacacacacacafacacacacacacagagagaqagagagacacacacacacacacacacacacacacacacabababacavacacacacacacacacacacacacacacacacabababaa
aaabababacacacacacacacacacacacacacaGacacacacalacacacacacacacacacaHacacacacacacacababababacacacacacacacacacacacacacacacacabababaa
aaabababacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababacacacacacacacacacacacacacacacacacabababaa
aaabababacacacacacacacacacacacacacacacacacacacacacacacaIacacacacacacacacadacacacabacacacacacacacacacacacacacacacacacacacabababaa
@@ -157,15 +156,15 @@ aaabababacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac
aaabaJabababacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaKacacacacacacacacacacacacacacacacacacacacacacacababababaa
aaabaHaLacaLacabaKacacacacacacacacacacacaKacacacacacacacacacacacacacacaKacacacacacacacacacacacacacacacaHacacacacacacabababababaa
aaabababacabababababacacacacacaHacacacacaKacacacacacacacacaGacacacaGacacacacacacacacacacacacacacacacacacacacacacacacabacabababaa
-aaabaMaMaNaMaOababacacacacacacacacacacacacacacacacacacaPaQaRaqaqaqaTaQaUacacacacacacacacacacacacacacacacacacacacacacacacabababaa
+aaabaMaMaNaMaOababacacacacacacacacacacacacacacacacacacaPaQaRaSaSaSaTaQaUacacacacacacacacacacacacacacacacacacacacacacacacabababaa
aaabaMaVaVaVaWababacacacacacacacacacacacacacacacacacacaXaYaZaYaZaYaZaYaXacacacacacacacacacapacacacacacacacacacacacababababababaa
aaabaOaVbaaVaMababacacacacacacacacacacacacacacacacacaGbbaZaYaZaYaZaYaZbbaGacacacacacacacacacacacacacacacacacacacacacabababababaa
-aaabaWbcbdbeaOababababacacacacacacaIacacacacacacacacacaqaYaZaYaZaYaZaYaqacacacacacacacacacacacacacacacacacacacacacacabababababaa
-aaabaMaMaOaMaWabababacacacacacacacacacacacacacacacacacaqaZaYaZbfaZaYaZaqacacacacacacacacacacacacacacacacavacacacacacabababababaa
-aaababababababababacacacacacacacacacacacacacacacacacacaqaYaZaYaZaYaZaYaqacacacacacacacacacacacacacacacacacacacacacacabababababaa
+aaabaWbcbdbeaOababababacacacacacacaIacacacacacacacacacaSaYaZaYaZaYaZaYaSacacacacacacacacacacacacacacacacacacacacacacabababababaa
+aaabaMaMaOaMaWabababacacacacacacacacacacacacacacacacacaSaZaYaZbfaZaYaZaSacacacacacacacacacacacacacacacacavacacacacacabababababaa
+aaababababababababacacacacacacacacacacacacacacacacacacaSaYaZaYaZaYaZaYaSacacacacacacacacacacacacacacacacacacacacacacabababababaa
aaabababababababababacacacacacacacacacacacacacacacacaGbgaZaYaZaYaZaYaZbgaGacacacacacacacacacacacaIacacacacacacacacacacababababaa
aaabababacabababababacacacacacacacacacacacacacacacacacaXaYaZaYaZaYaZaYaXacacacacacacacacacacacacacacacacacacacacacacacacabababaa
-aaabababacacacacacacacacacacacacacacacacacacacacacacacbhaQaRaqaqaqaTaQbiacacacaKacacacacaoacacacacacacacacacacacacacacacabababaa
+aaabababacacacacacacacacacacacacacacacacacacacacacacacbhaQaRaSaSaSaTaQbiacacacaKacacacacaoacacacacacacacacacacacacacacacabababaa
aaabababacacacacacacacacacacacacacacacacacacacacaHacacacacaGacacacaGacacacacacacacacacacacacacacacacacacacacacacacacacacabababaa
aaabababacacacacacacacacacacacacaeacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababaa
aaabababacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababaa
@@ -180,18 +179,17 @@ aaabababacacacacacbkagagagagacacacacacacacacacacacacacacabacabababacacacacacacac
aaabababacacacacacagagbubvagagacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababaa
aaabababacacacacacagbwamambxagacacacacacacacacacacacacacacacaIacacacacacacacacafacacacacacacacacacacacacacacacacacacacacabababaa
aaabababacacacacacaubyamamamagbzacacacacacbjacacacacacacacacacbAacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababaa
-aaabababacacacacacauasamamamaSacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababaa
-aaabababacacacacacagbBbCambDagbzacacacacacacacacacacacacacacacacacacacacacacacacacacacacacapacacacacacacacacacacacacacacabababaa
-aaabababacacacacacagagagagagagacacacacacacacacacacacacacacbFbEbEbEbFbkacacacacacacacacacacacacacacacacacacacacacacaeacacabababaa
-aaabababacacacacacalacacacacacacacacacacacacacacacacacaeacbFbGbGbGbFbjaIacacacacacacacacacacacacacacacacacacacacacacacacabababaa
-aaabababacacacacacacacacacacacacacacacacacacacacbFbFbFbFbFbFbHbHbHbFbFbFbFbFbFacacacacacacacacacacacacacacacacacacacacacabababaa
-aaabababacaeacacacacacacacacacacacacacacacabacabbFbIbIbIbIbKbJbJbJbKbIbIbIbIbFababacacacacacacacacacacacacacacacacacacacabababaa
-aaababababacacacacacacadacacacacacacacacababababbFbIbLbLbLbIbMbObNbIbPbSbQbIbFabbjacababacacacacacacacadacacacacacacacacabababaa
-aaabababababacacacacacacacacacacacacacababbRbRbRbFbIbLbLbLbIbTbUbTbIbVbZbWbIbFbRbRbRababacacacacacacacacacacacacacacacababababaa
-aaabababababacabacacacacacacacacacacacababbRbXbYbFbIbLbLbLcbcacccacecdcicfbIbFcgcgbRabababacacacacacacacacacacacacacabababababaa
-aaababababababababababababababababababababbRchcjbFckcbclclcncmcpcocqclclcebIbFcgcgbRabababababababababababababababababababababaa
-aaababababababababababababababababababababbRcgcgbFbFcrbFbFctcscucscvbFbFcrbFbFcgcgbRabababababababababababababababababababababaa
-aaababababababababababababababababababababbRcgcgcgbFcxbFcwcycwcwcwcycwbFcxbFcgcgcgbRabababababababababababababababababababababaa
+aaabababacacacacacauasamamamaqacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababaa
+aaabababacacacacacagbBamambCagbzacacacacacacacacacacacacacacacacacacacacacacacacacacacacacapacacacacacacacacacacacacacacabababaa
+aaabababacacacacacagagagagagagacacacacacacacacacacacacacacbDbEbEbEbDbkacacacacacacacacacacacacacacacacacacacacacacaeacacabababaa
+aaabababacacacacacalacacacacacacacacacacacacacacacacacaeacbDbFbFbFbDbjaIacacacacacacacacacacacacacacacacacacacacacacacacabababaa
+aaabababacacacacacacacacacacacacacacacacacacacacbDbDbDbDbDbDbGbGbGbDbDbDbDbDbDacacacacacacacacacacacacacacacacacacacacacabababaa
+aaabababacaeacacacacacacacacacacacacacacacabacabbDbHbHbHbHbIbJbJbJbIbHbHbHbHbDababacacacacacacacacacacacacacacacacacacacabababaa
+aaababababacacacacacacadacacacacacacacacababababbDbHbKbKbKbHbLbMbNbHbObPbQbHbDabbjacababacacacacacacacadacacacacacacacacabababaa
+aaabababababacacacacacacacacacacacacacababbRbRbRbDbHbKbKbKbHbSbTbSbHbUbVbWbHbDbRbRbRababacacacacacacacacacacacacacacacababababaa
+aaabababababacabacacacacacacacacacacacababbRbXbYbDbHbKbKbKbZcacbcacccdcecfbHbDcgcgbRabababacacacacacacacacacacacacacabababababaa
+aaababababababababababababababababababababbRchcibDcjbZckckclcmcncocpckckccbHbDcgcgbRabababababababababababababababababababababaa
+aaababababababababababababababababababababbRcgcgbDbDcqbDbDcrcsctcscubDbDcqbDbDcgcgbRabababababababababababababababababababababaa
+aaababababababababababababababababababababbRcgcgcgbDcvbDcwcxcwcwcwcxcwbDcvbDcgcgcgbRabababababababababababababababababababababaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
"}
-
diff --git a/_maps/map_files/RandomZLevels/moonoutpost19.dmm b/_maps/map_files/RandomZLevels/moonoutpost19.dmm
index 369c9363825..46fef62f780 100644
--- a/_maps/map_files/RandomZLevels/moonoutpost19.dmm
+++ b/_maps/map_files/RandomZLevels/moonoutpost19.dmm
@@ -2,13 +2,13 @@
"ab" = (/turf/simulated/mineral/random/labormineral,/area/awaycontent/a3{always_unpowered = 1; ambientsounds = list('sound/ambience/ambimine.ogg'); has_gravity = 1; name = "Khonsu 19"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
"ac" = (/obj/structure/alien/weeds,/obj/structure/alien/resin/wall,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
"ad" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/alien/resin/wall,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
-"ae" = (/obj/structure/alien/weeds,/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
+"ae" = (/obj/structure/alien/weeds,/obj/structure/alien/weeds{desc = "A large mottled egg."; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
"af" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/alien/resin/wall,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
-"ag" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
+"ag" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/alien/weeds{desc = "A large mottled egg."; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
"ah" = (/obj/structure/alien/weeds,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
"ai" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/mob/living/simple_animal/hostile/alien,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
"aj" = (/obj/structure/alien/weeds,/obj/structure/stool/bed/nest,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
-"ak" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
+"ak" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/alien/weeds{desc = "A large mottled egg."; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
"al" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/stool/bed/nest,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
"am" = (/obj/structure/alien/weeds/node,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
"an" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/stool/bed/nest,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
@@ -32,9 +32,9 @@
"aF" = (/obj/machinery/gateway{dir = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "vault"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"aG" = (/obj/machinery/gateway{dir = 9},/turf/simulated/floor/plasteel{dir = 1; icon_state = "vault"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"aH" = (/obj/machinery/gateway{dir = 5},/turf/simulated/floor/plasteel{dir = 4; icon_state = "vault"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
-"aI" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/obj/effect/decal/cleanable/blood/gibs{color = "red"; icon_state = "gib1_flesh"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
+"aI" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/alien/weeds{desc = "A large mottled egg."; icon_state = "egg_hatched"; name = "egg"},/obj/effect/decal/cleanable/blood/gibs{color = "red"; icon_state = "gib1_flesh"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
"aJ" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/effect/decal/cleanable/blood/gibs{color = "red"; icon_state = "gib2_flesh"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
-"aK" = (/obj/structure/alien/weeds,/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/obj/effect/decal/cleanable/blood{color = "red"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
+"aK" = (/obj/structure/alien/weeds,/obj/structure/alien/weeds{desc = "A large mottled egg."; icon_state = "egg_hatched"; name = "egg"},/obj/effect/decal/cleanable/blood{color = "red"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
"aL" = (/obj/structure/alien/weeds,/mob/living/simple_animal/hostile/alien/drone{plants_off = 1},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a5{always_unpowered = 1; has_gravity = 1; name = "The Hive"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0})
"aM" = (/obj/machinery/light{dir = 8},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
"aN" = (/obj/machinery/gateway/centeraway{calibrated = 0},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaycontent/a4{has_gravity = 1; name = "Syndicate Outpost"})
@@ -220,7 +220,7 @@
"el" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/stool/bed/nest,/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; dir = 9; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"em" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; dir = 4; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"en" = (/obj/structure/alien/weeds,/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"eo" = (/obj/machinery/light{active_power_usage = 0; dir = 1; icon_state = "tube-broken"; status = 2},/obj/structure/alien/weeds,/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/obj/machinery/camera{c_tag = "Xenobiology Containment North"; network = list("MO19X")},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"eo" = (/obj/machinery/light{active_power_usage = 0; dir = 1; icon_state = "tube-broken"; status = 2},/obj/structure/alien/weeds,/obj/structure/alien/weeds{desc = "A large mottled egg."; icon_state = "egg_hatched"; name = "egg"},/obj/machinery/camera{c_tag = "Xenobiology Containment North"; network = list("MO19X")},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"ep" = (/obj/machinery/sparker{desc = "A wall-mounted ignition device. This one has been applied with an acid-proof coating."; id = "awayxenobio"; name = "Acid-Proof mounted igniter"; pixel_x = 0; pixel_y = 25; unacidable = 1},/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/alien/resin/wall,/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"eq" = (/obj/structure/alien/weeds,/obj/structure/alien/resin/wall,/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"er" = (/obj/structure/alien/weeds,/obj/structure/stool/bed/nest,/obj/item/clothing/mask/facehugger{icon_state = "facehugger_impregnated"; item_state = "facehugger_impregnated"; stat = 2},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
@@ -240,7 +240,7 @@
"eF" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/alien/resin/wall,/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"eG" = (/obj/structure/alien/weeds,/obj/structure/stool/bed/nest,/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"eH" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"eI" = (/obj/structure/alien/weeds,/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"eI" = (/obj/structure/alien/weeds,/obj/structure/alien/weeds{desc = "A large mottled egg."; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"eJ" = (/turf/simulated/wall,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"eK" = (/turf/simulated/wall/rust,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"eL" = (/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
@@ -248,7 +248,7 @@
"eN" = (/obj/machinery/light/small{active_power_usage = 0; dir = 8; icon_state = "bulb-broken"; status = 2},/obj/machinery/camera{c_tag = "Xenobiology"; dir = 4; network = list("MO19","MO19R")},/turf/simulated/floor/plasteel{dir = 6; icon_state = "whitehall"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"eO" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/visible,/obj/structure/stool/bed/chair/office/light{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"eP" = (/obj/structure/table/reinforced,/obj/machinery/door_control{id = "Awaylab"; name = "Containment Chamber Blast Doors"; pixel_x = 4; pixel_y = -2; req_access_txt = "201"},/obj/machinery/ignition_switch{id = "awayxenobio"; pixel_x = 4; pixel_y = 8},/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"eQ" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"eQ" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/alien/weeds{desc = "A large mottled egg."; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"eR" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/effect/decal/cleanable/blood{color = "red"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"eS" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"eT" = (/turf/simulated/wall,/area/awaycontent/a7)
@@ -273,7 +273,7 @@
"fm" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"fn" = (/obj/structure/closet/l3closet/scientist,/obj/structure/window/reinforced,/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"fo" = (/obj/structure/cable,/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/door/poddoor/preopen{desc = "A heavy duty blast door that opens mechanically. This one has been applied with an acid-proof coating."; id_tag = "Awaylab"; name = "Acid-Proof containment chamber blast door"; unacidable = 1},/obj/structure/grille,/obj/structure/window/full/reinforced,/turf/simulated/floor/plating,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
-"fp" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
+"fp" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/alien/weeds{desc = "A large mottled egg."; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"fq" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/stool/bed/nest,/obj/item/clothing/mask/facehugger{icon_state = "facehugger_impregnated"; item_state = "facehugger_impregnated"; stat = 2},/turf/simulated/floor/engine,/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"})
"fr" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/awaycontent/a7)
"fs" = (/obj/effect/decal/cleanable/blood/tracks{desc = "Your instincts say you shouldn't be following these."; dir = 8; icon_state = "ltrails_1"},/turf/simulated/floor/plating,/area/awaycontent/a7)
diff --git a/_maps/map_files/RandomZLevels/spacehotel.dmm b/_maps/map_files/RandomZLevels/spacehotel.dmm
index 9a66c57d6ba..f40c2033dfd 100644
--- a/_maps/map_files/RandomZLevels/spacehotel.dmm
+++ b/_maps/map_files/RandomZLevels/spacehotel.dmm
@@ -409,7 +409,7 @@
"hS" = (/turf/unsimulated/floor{icon_state = "whiteyellow"; dir = 4},/area/awaymission/spacehotel)
"hT" = (/obj/effect/view_portal{id = "hotel_12"},/turf/unsimulated/floor{icon_state = "rampbottom"; dir = 4},/area/awaymission/spacehotel)
"hU" = (/obj/effect/view_portal/visual{dir = 4; dist = 0; id = "hotel_22"; opacity = 0; radius = 0},/turf/unsimulated/floor,/area/awaymission/spacehotel)
-"hV" = (/obj/machinery/door/airlock/public/glass{icon_state = "door_locked"; locked = 1; name = "Employees Only"; req_access_txt = "150"},/obj/item/tape/police{icon_state = "police_door"; layer = 3.2},/turf/unsimulated/floor{dir = 8; icon_state = "whitered"},/area/awaymission/spacehotel)
+"hV" = (/obj/machinery/door/airlock/public/glass{icon_state = "door_locked"; locked = 1; name = "Employees Only"; req_access_txt = "150"},/turf/unsimulated/floor{dir = 8; icon_state = "whitered"},/area/awaymission/spacehotel)
"hW" = (/obj/effect/decal/cleanable/blood/old,/turf/unsimulated/floor{icon_state = "white"},/area/awaymission/spacehotel)
"hX" = (/obj/effect/view_portal/visual{dir = 8; dist = 0; id = "hotel_13"; radius = 0},/turf/unsimulated/floor,/area/awaymission/spacehotel)
"hY" = (/obj/effect/view_portal{id = "hotel_23"},/turf/unsimulated/floor{icon_state = "ramptop"; dir = 4},/area/awaymission/spacehotel)
@@ -485,7 +485,7 @@
"jq" = (/obj/item/toy/spinningtoy,/turf/unsimulated/floor/carpet,/area/awaymission/spacehotel)
"jr" = (/obj/item/grown/bananapeel,/obj/item/toy/spinningtoy,/turf/unsimulated/floor/carpet,/area/awaymission/spacehotel)
"js" = (/obj/structure/barricade/wooden,/turf/unsimulated/floor/carpet,/area/awaymission/spacehotel)
-"jt" = (/obj/machinery/door/airlock/public/glass,/obj/item/tape/engineering{icon_state = "engineering_door"; layer = 3.2},/turf/unsimulated/floor/carpet,/area/awaymission/spacehotel)
+"jt" = (/obj/machinery/door/airlock/public/glass,/turf/unsimulated/floor/carpet,/area/awaymission/spacehotel)
"ju" = (/obj/machinery/gateway{dir = 10},/turf/unsimulated/floor{icon_state = "warning"; dir = 10},/area/awaymission/spacehotel)
"jv" = (/obj/machinery/gateway,/turf/unsimulated/floor{icon_state = "warning"},/area/awaymission/spacehotel)
"jw" = (/obj/machinery/gateway{dir = 6},/turf/unsimulated/floor{icon_state = "warning"; dir = 6},/area/awaymission/spacehotel)
diff --git a/_maps/map_files/RandomZLevels/terrorspiders.dmm b/_maps/map_files/RandomZLevels/terrorspiders.dmm
index 0b6817624ba..d21991c7ca5 100644
--- a/_maps/map_files/RandomZLevels/terrorspiders.dmm
+++ b/_maps/map_files/RandomZLevels/terrorspiders.dmm
@@ -5,7 +5,7 @@
"ae" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/awaymission/UO71/queen)
"af" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 7; tag = "icon-manifold-b-f (WEST)"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/awaymission/UO71/queen)
"ag" = (/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/awaymission/UO71/queen)
-"ah" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; external_pressure_bound = 0; frequency = 1441; icon_state = "weld"; id_tag = "UO71_waste_out"; initialize_directions = 1; internal_pressure_bound = 4000; on = 1; pressure_checks = 2; pump_direction = 0; welded = 1},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/awaymission/UO71/queen)
+"ah" = (/obj/machinery/alarm/monitor{frequency = 1439; locked = 0; pixel_y = 23; req_access = null},/obj/machinery/camera{c_tag = "Gateway Ready Room"; dir = 2; network = list("UO71")},/obj/structure/table,/obj/machinery/computer/id_upgrader{light_color = "#00ffff"; light_power = 4; light_range = 2},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaymission/UO71/gateway)
"ai" = (/obj/structure/spider/cocoon{icon_state = "cocoon_large1"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/awaymission/UO71/queen)
"aj" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaymission/UO71/plaza)
"ak" = (/obj/structure/closet/emcloset,/obj/item/clothing/mask/breath,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaymission/UO71/plaza)
@@ -465,17 +465,16 @@
"iW" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 4},/obj/structure/sign/deathsposal{desc = "A warning sign which reads 'DISPOSAL: LEADS TO EXTERIOR'"; name = "\improper DISPOSAL: LEADS TO EXTERIOR"; pixel_x = 0; pixel_y = -32},/turf/simulated/floor/plasteel{dir = 5; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/awaymission/UO71/centralhall)
"iX" = (/obj/structure/closet/secure_closet{icon_state = "secure"; locked = 0; name = "kitchen Cabinet"; req_access_txt = "271"},/obj/item/reagent_containers/food/condiment/flour,/obj/item/reagent_containers/food/condiment/flour,/obj/item/reagent_containers/food/condiment/sugar,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 5; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/awaymission/UO71/centralhall)
"iY" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor/plating,/area/awaymission/UO71/centralhall)
-"iZ" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; icon_state = "weld"; on = 1; welded = 1},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel,/area/awaymission/UO71/gateway)
+"iZ" = (/obj/effect/decal/cleanable/blood/gibs{color = "red"; icon_state = "gib2_flesh"},/turf/simulated/floor/plasteel,/area/awaymission/UO71/gateway)
"ja" = (/obj/machinery/alarm/monitor{dir = 4; frequency = 1439; locked = 0; pixel_x = -23; pixel_y = 0; req_access = null},/obj/machinery/camera{c_tag = "Gateway Chamber"; dir = 4; network = list("UO71")},/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaymission/UO71/gateway)
-"jb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/effect/decal/cleanable/blood/gibs{color = "red"; icon_state = "gib2_flesh"},/turf/simulated/floor/plasteel,/area/awaymission/UO71/gateway)
-"jc" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel,/area/awaymission/UO71/gateway)
-"jd" = (/obj/structure/grille,/obj/structure/window/full/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/awaymission/UO71/gateway)
-"je" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/stool,/turf/simulated/floor/plasteel,/area/awaymission/UO71/gateway)
-"jf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaymission/UO71/gateway)
+"jb" = (/obj/structure/stool,/turf/simulated/floor/plasteel,/area/awaymission/UO71/gateway)
+"jc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaymission/UO71/gateway)
+"jd" = (/obj/machinery/door/poddoor{id_tag = "UO71_Start"; name = "UO71 Sealed Facility"},/obj/machinery/door/airlock/research{name = "Gateway Observation"; req_access_txt = "271"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaymission/UO71/gateway)
+"je" = (/obj/structure/stool/bed/chair/comfy/black{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 7; tag = "icon-manifold-b-f (WEST)"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutral"},/area/awaymission/UO71/centralhall)
+"jf" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor/plasteel{dir = 10; icon_state = "neutral"},/area/awaymission/UO71/centralhall)
"jg" = (/obj/structure/sign/biohazard,/turf/simulated/wall/r_wall,/area/awaymission/UO71/mother)
-"jh" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaymission/UO71/gateway)
+"jh" = (/obj/structure/stool/bed/chair/comfy/black{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 7; tag = "icon-manifold-b-f (WEST)"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/awaymission/UO71/centralhall)
"ji" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/awaymission/UO71/science)
-"jj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/poddoor{id_tag = "UO71_Start"; name = "UO71 Sealed Facility"},/obj/machinery/door/airlock/research{name = "Gateway Observation"; req_access_txt = "271"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaymission/UO71/gateway)
"jk" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaymission/UO71/gateway)
"jl" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/mineral/random/labormineral,/area/awaymission/UO71/outside)
"jm" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 2},/turf/simulated/shuttle/wall{dir = 4; icon_state = "wall3"},/area/awaymission/UO71/outside)
@@ -596,7 +595,6 @@
"lx" = (/obj/structure/table,/obj/item/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/item/multitool,/obj/structure/sign/nosmoking_2{pixel_x = -32},/obj/item/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warndark"; tag = "icon-warndark (EAST)"},/area/awaymission/UO71/gateway)
"ly" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/awaymission/UO71/gateway)
"lz" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plasteel,/area/awaymission/UO71/gateway)
-"lA" = (/obj/machinery/alarm/monitor{frequency = 1439; locked = 0; pixel_y = 23; req_access = null},/obj/machinery/camera{c_tag = "Gateway Ready Room"; dir = 2; network = list("UO71")},/obj/structure/table,/obj/machinery/computer/id_upgrader,/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaymission/UO71/gateway)
"lB" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plasteel,/area/awaymission/UO71/gateway)
"lC" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel,/area/awaymission/UO71/gateway)
"lD" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaymission/UO71/gateway)
@@ -782,8 +780,6 @@
"pb" = (/obj/structure/closet/secure_closet{icon_broken = "secbroken"; icon_closed = "sec"; icon_locked = "sec1"; icon_off = "secoff"; icon_opened = "secopen"; icon_state = "sec1"; locked = 1; name = "security officer's locker"; req_access_txt = "271"},/obj/item/flash,/obj/item/reagent_containers/spray/pepper,/obj/item/restraints/handcuffs,/turf/simulated/floor/plasteel{dir = 10; icon_state = "red"},/area/awaymission/UO71/science)
"pc" = (/obj/machinery/door/airlock/security/glass{name = "Security Office"; req_access_txt = "271"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaymission/UO71/science)
"pd" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 2; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel{dir = 6; icon_state = "red"},/area/awaymission/UO71/science)
-"pe" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor/plasteel,/area/awaymission/UO71/centralhall)
-"pf" = (/obj/structure/stool/bed/chair/comfy/black{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutral"},/area/awaymission/UO71/centralhall)
"pg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/awaymission/UO71/centralhall)
"ph" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; initialize_directions = 14; tag = "icon-manifold-b-f (NORTH)"},/turf/simulated/floor/plasteel,/area/awaymission/UO71/centralhall)
"pi" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/airlock/public/glass{name = "Central Access"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/awaymission/UO71/centralhall)
@@ -836,9 +832,7 @@
"qd" = (/obj/machinery/door/poddoor{id_tag = "UO71_SciStorage"; name = "SciStorage Door"},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/awaymission/UO71/loot)
"qe" = (/obj/structure/grille,/obj/structure/window/full/basic,/turf/simulated/floor/plating,/area/awaymission/UO71/medical)
"qf" = (/obj/machinery/door/airlock/medical/glass{id_tag = null; name = "Medical Storage"; req_access_txt = "0"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaymission/UO71/medical)
-"qg" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 10; icon_state = "neutral"},/area/awaymission/UO71/centralhall)
"qh" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/wall,/area/awaymission/UO71/centralhall)
-"qi" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/stool/bed/chair/comfy/black{dir = 4},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/awaymission/UO71/centralhall)
"qj" = (/turf/simulated/floor/plasteel{dir = 6; icon_state = "neutral"},/area/awaymission/UO71/centralhall)
"qk" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{icon_state = "neutral"},/area/awaymission/UO71/centralhall)
"ql" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 101.325; on = 1; pressure_checks = 1},/obj/machinery/door_control{id = "awaydorm4"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = -25; pixel_y = 0; req_access_txt = "0"; specialfunctions = 4},/turf/simulated/floor/carpet,/area/awaymission/UO71/centralhall)
@@ -1331,7 +1325,6 @@
"zF" = (/obj/machinery/light{dir = 1},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/awaymission/UO71/queen)
"zG" = (/obj/machinery/door/poddoor{id_tag = "UO71_Caves"; name = "Caves Lockdown Door"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/awaymission/UO71/queen)
"zH" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 7; tag = "icon-manifold-r-f (WEST)"},/turf/simulated/wall,/area/awaymission/UO71/science)
-"zI" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 7; tag = "icon-manifold-b-f (WEST)"},/obj/structure/spider/terrorweb,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/awaymission/UO71/queen)
"zJ" = (/obj/structure/spider/terrorweb,/obj/structure/spider/terrorweb,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/awaymission/UO71/queen)
"zK" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/spider/terrorweb,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/awaymission/UO71/queen)
"zL" = (/obj/structure/table,/obj/machinery/light,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/awaymission/UO71/queen)
@@ -1417,19 +1410,19 @@ aaaaaaaaaaaaaaabababababfLghgQgSgRghgsgVgTfMgWgYgXfLgagpgpgpgUhWgpgpgafNgZhbhahd
aaaaaaaaaaaaaaabababababfLghhuhwhvghgshyhxfMhzhBhAfLgagpgpgpgphWgpgpgafOhCighFhdhHhIfNabzcfPhDgegdgegdgdhEfPzcabfbhJfFfbabababababfbhKhLgEhNhMgEgEhOfehPgOhQgkhRfbgbfhabababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaa
aaaaaaaaaaaaaaabababababfMhThShYhXhSgshyhZfLfLiafLfLgahUgphVgpmimhmxgafOibihicijiiikfNabzcidiegdifgdgdmygefPzcabfbhJfTfbabababababfbilhhgEhNimgEgEioiniqipgkgkirfeisfhabababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaa
aaaaaaaaaaaaaaabababababfMiuitiwiviziyiGiEixiHiJiAiBiCiDgagaiOiOgaiFgafNiPiQgAfOfNfNfOabzciIfPfPfPiRiRiKiLiLjmiMiNiSfTfeabababababfbiTgEiohjhMgEgEiUfbiWiVgkfUiXfbiYfhabababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaabababababfMjaiZjcjbjejdjfjfjjjhjkfMababababjgjnjnjgjifOfOjojpgzfOababababzcyXzczcyYjqjqyYzczczcabfejsjrfefeababababfejtjugEiohMjyjvjAfbfbjBjwjwjxjxjCjzabababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaabababababfMjamliwiZjbgsghghjdjcjkfMababababjgjnjnjgjifOfOjojpgzfOababababzcyXzczcyYjqjqyYzczczcabfejsjrfefeababababfejtjugEiohMjyjvjAfbfbjBjwjwjxjxjCjzabababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaa
aaaaaaaaaaaaaaabababababfLjEjDiwjFjHfLfLfMfMjIjJfMababababjGjKjKjGjifOfOjLjNjMfOabababababjlababjGjOjOjGababababfbjPfRjQfefbfbfbfefejRjShhjThjhjgEgEjUjWjVjYjXkajZkbfeabababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaa
aaaaaaaaaaaaaaabababababfMfLfMkdkcfLfLkkkifMklkqfLfOfOfOfOkekfkgkekhfNkrkjktksfOfOfOfOfOfOkmfOfOknkokpkefOfOfNfOfOkufRfRkvfRfFfRfRjrgEgEgEkwiogEkxkykykAkzfbkBkDkCfefbabababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaababababababfLkEiwkFlAkGkRkHixkSkUkTkIkJkKkLkMkJkNkOkPkQlckVleldkJkWkNkJkJkXkYkZlalblglflhfOljlilkfOlmlllllllnlllplojrgEiogElrlqlqlqlulslwlvfbfbfefefeababababababababababababababltltltltltabababababababababababababababababababaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaababababababfLkEiwkFahkGkRkHixkSkUkTkIkJkKkLkMkJkNkOkPkQlckVleldkJkWkNkJkJkXkYkZlalblglflhfOljlilkfOlmlllllllnlllplojrgEiogElrlqlqlqlulslwlvfbfbfefefeababababababababababababababltltltltltabababababababababababababababababababaaaaaaaaaaaaaa
aaaaaaaaaaaaaaababababababfLlxlzlylElylClBmMlDlGlFlHlHlIlHlJlHlLlKlNlMlPlOlRlQlTlSlVlUlXlWlXlXlXlYgAlflhlZgAgAgAlZmbmafFmcfbfefbfbfefefbfbfbmdmehhmffbjsmgfeababababababababababababababababababltnBmzmjltabababababababababababababababababababaaaaaaaaaaaaaa
aaaaaaaaaaaaaaababababababfMmkmmmliwjHjHmnfLmompfMfNfOfOfOfNfOfOmqfOfOmsmrfOfOfOmtfOfOfOfNmumumumumvlflhfOokmwqDtDqKfEmBmAfbmCmDmCfemEmGmFfefefbfbfefbmImHfeababababababababababababababababababltmKmJmjltabababababababababababababababababababaaaaaaaaaaaaaa
aaaaaaaaaaaaaaababababababfLmLmlmNmPmOmSmQfMfLfLfLabfOgAgAmTfOmVmUmTfNmRmWfOmXmZmYnbnancfOnendnfmumvlbfOfOmRfOfOfNnhngfefefbninknjfbnlnnnmfenonsnqntfbnumHfbabababababababababababababababababnpltltnvnrnrnpababababababababababababababababababaaaaaaaaaaaaaa
aaaaaaaaaaaaaaababababababfLfLfMfMfLfLfMfMfLababababfOgAgAgAfOnwmUnxfOmRnyfOnzojnAnDnanafNnFnEnGmumvnCfNnHzDnInInKnMnLnOnNfbfXnPfbfefXnQfbfbnRfFnSnVnUnZnWfbabababababababababababababababababnToaobobobocnpababababababababababababababababababaaaaaaaaaaaaaa
aaaaaaaaaaaaaaabababababababababababababababababababfOnXnYgAodgAoeoffOkmogfOohojoiooonopfNoroqosmumvlbfNogzHolomomouotowovoyoxoAozoCoBoAoDoFoEoHoGoJoIoNoMfbabababababababababababababababababnToOoQoPoQoOnpnpnpnpabababababababababababababababaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaabababababababababababababababababababfOoKoLgAfOoSoRoTfOkmoUfOoVojoWoYoXoZfNpbpapdpcmvlbfOnymRfbfbfbpfpellpgpiphpkpjplphpnpmpppopkpqprfbptpsfeabababababababababababababababababnppwpypxpApznppupvnpabababababababababababababababaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaabababababababababababababababababababfOfOfOfOfOfOfOfOfNpDpCfOpEpFnapGnaoXfOfOpBkmfOmvlafNpHmRfbfbfbpJpIfRpKfbpLfbfhfepMfbfbfepNfbfbpOfbpRmHfbabababababababababababababababababnppSpYpUpYpZnTpPpQnpabababababababababababababababaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaabababababababababababababababababababababababababababfNqbjifOfOfOqcfOpTqdpTpTpVpWpXqfqeqaogkmfbfbfbqiqgqkqjfeqlqmqhqoqnfeqpqtqqqwfeqxfehJmHfbababababababababnTnTnpnpnTababababnpqyqyqzqyqynpqrqsnpnpnpabababababababababababababaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaabababababababababababababababababababababababababababfOqAkhquqvmuqBqCpTqFzOpTpVqHqGqJqIqaogmRfbfbfbqEzPzQzQzPqLqMfbqOqNfbfbfbqPqQfeqRfbhJmHfbababababababababnTqTqSqSnpnTnTnTnpnpqUqWqVqYqXrcqZrerdrfnpabababababababababababababaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaabababababababababababababababababababfOoKoLgAfOoSoRoTfOkmoUfOoVojoWoYoXoZfNpbpapdpcmvlbfOnymRfOfOfbjellllpgpiphpkpjplphpnpmpppopkpqprfbptpsfeabababababababababababababababababnppwpypxpApznppupvnpabababababababababababababababaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaabababababababababababababababababababfOfOfOfOfOfOfOfOfNpDpCfOpEpFnapGnaoXfOfOpBkmfOmvlafNpHmRfOfOfbpJpIfRpKfbpLfbfhfepMfbfbfepNfbfbpOfbpRmHfbabababababababababababababababababnppSpYpUpYpZnTpPpQnpabababababababababababababababaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaabababababababababababababababababababababababababababfNqbjifOfOfOqcfOpTqdpTpTpVpWpXqfqeqaogkmfOfOfbjhjfqkqjfeqlqmqhqoqnfeqpqtqqqwfeqxfehJmHfbababababababababnTnTnpnpnTababababnpqyqyqzqyqynpqrqsnpnpnpabababababababababababababaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaabababababababababababababababababababababababababababfOqAkhquqvmuqBqCpTqFzOpTpVqHqGqJqIqaogmRfOfOfbqEzPzQzQzPqLqMfbqOqNfbfbfbqPqQfeqRfbhJmHfbababababababababnTqTqSqSnpnTnTnTnpnpqUqWqVqYqXrcqZrerdrfnpabababababababababababababaaaaaaaaaaaaaa
aaaaaaaaaaaaaaabababababababababababababababababababababababababababfOrgjirarbrjrirkpTqFqFpTrhroqJqJrpqarqrlrmrmrmrnrmrsrrsartmCfbrvrufbrwrxqqryfbrzfbrBrAfbfbfbfbfefbfbfbfbnprDrCrFrEnTrHrJrIrGrKrMrLrOrNrNrPrSrRrfnpnpnTnTababababababababababaaaaaaaaaaaaaa
aaaaaaaaaaaaaaabababababababababababababababababababababababababababfNrTkhqurQmurUrVpTrXrWpTpVrZrYscsbqasdmRsasgsfshsesirrsafefefefbfefbfefesjfbfbskfesmslsosnsqspsrsnstsssvsusxswszsysBsAsDsCsFsEsHsGsJsIsOsOsPsPsQsKsLsMnTababababababababababaaaaaaaaaaaaaa
aaaaaaaaaaaaaaabababababababababababababababababababababababababababfNrgkhfOfOfOfNfNpTpTsNpTpVsSsRsUsTqaogmRsarrrrsVsarrsWsaabababababfbsXsYqqsZferzfejPtanUtbtctbtdtbtftethtgtititktjtmtltotnsFtptrtqtttstvtutAtztBtwtxtynpababababababababababaaaaaaaaaaaaaa
@@ -1471,7 +1464,7 @@ aaaaaaaaaaaaaaababababababababababababababababababababababababababababababababab
aaaaaaaaaaaaaaabababababababababababababababababababuWababababababababababababababababababababababababababuWuWuWuWababababababababababababuWuWuWzyzdzyzzzBzyzyzyzyzgzgzdzguWuWabababuWuWuWabababuWuWuWuWuWuWuWuWuWabuWuWuWuWuWabababababababababaaaaaaaaaaaaaa
aaaaaaaaaaaaaaabababababababababababababababababababuWuWabababababababababababababababababababababababababuWuWuWababababababababababababababuWuWzyzdzyzzagzFzCzAzyzyzyzdzguWabababababuWababababuWabababuWuWuWabuWuWuWuWuWuWuWabababababababababaaaaaaaaaaaaaa
aaaaaaaaaaaaaaababababababababababababababababababababuWuWabababababababababababababababababababababababuWuWzrabababababababababababababababuWuWzBagzGzqaiagagzAzAzyzyzdzguWababuWabuWuWabababababababuWuWuWababababuWuWuWuWuWuWababababababababaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaabababababababababababababababababababababuWuWuWababababababababababababababababababababuWuWuWabababababababababababababababababuWzyzdzyzIaeahagzAzJzyzyzdzguWababuWabuWabababababababuWuWuWababababababuWuWuWuWzrababababababababaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaabababababababababababababababababababababuWuWuWababababababababababababababababababababuWuWuWabababababababababababababababababuWzyzdzyzKagagagzAzJzyzyzdzguWababuWabuWabababababababuWuWuWababababababuWuWuWuWzrababababababababaaaaaaaaaaaaaa
aaaaaaaaaaaaaaababababababababababababababababababababababuWuWuWababababababababuWuWuWuWuWabababababuWuWuWabababababababababababababababababababzyzdzyzKzAagagaizAzyzyzdzyuWababuWuWuWababuWababababuWuWabababababababuWuWuWuWuWababababababababaaaaaaaaaaaaaa
aaaaaaaaaaaaaaababababababababababababababababababababababababuWuWababababababuWuWuWuWuWuWuWuWabababuWuWzrabababababababababababababababababababzyzdzyzMzAzAagagagagzyzdzyuWababuWuWabababuWababababuWuWabababababababzruWuWuWuWababababababababaaaaaaaaaaaaaa
aaaaaaaaaaaaaaabababababababababababababababababababababababababuWuWuWuWuWuWuWuWababababababuWuWuWabuWuWababababababababababababababababababababzyzdzyzMzAzCagagagagzyzdzyuWabababababababuWuWababuWuWababababababababuWuWuWuWuWababababababababaaaaaaaaaaaaaa
@@ -1487,7 +1480,7 @@ aaaaaaaaaaaaaaababababababababababababababababababababababababababababababababab
aaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWzyzdzyzqzAagzgzgagagzyzdzyuWuWuWababuWuWababuWuWuWababuWababuWuWuWuWuWabababababababababababababaaaaaaaaaaaaaa
aaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWababababzyzdzgzqagzAzgagzAaizGagzBuWuWababababuWabababuWuWababuWuWabuWuWuWuWuWabababababababababababababaaaaaaaaaaaaaa
aaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWuWabababzyzdzgzqagaizFagagagzyzdzyabuWababuWabuWuWababuWuWabababuWuWuWuWuWuWuWabababababababababababababaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababuWuWuWuWuWabababuWuWuWuWabababzyzdzgafaeahagaiagagzyzdzyabuWuWuWuWababuWababuWuWuWababuWuWuWuWuWuWababababababababababababababaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababuWuWuWuWuWabababuWuWuWuWabababzyzdzgzqagagagaiagagzyzdzyabuWuWuWuWababuWababuWuWuWababuWuWuWuWuWuWababababababababababababababaaaaaaaaaaaaaa
aaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababuWuWuWuWuWuWabababababuWuWuWababzyzdzgzMagagagagagzgzyzdzyabababababababuWabababuWuWabuWuWuWabuWuWuWababababababababababababababaaaaaaaaaaaaaa
aaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababuWuWuWuWuWuWabababababababuWuWuWabzyzdzyzMzgagagagzgzgzyzdzyababababababuWuWababababuWuWuWuWabuWuWuWabababababababababababababababaaaaaaaaaaaaaa
aaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababuWuWuWuWuWuWabababababababababuWuWabzgzdzdzezdzRzRzRzdzdzdzdzgababuWuWuWuWuWabababuWuWuWuWabuWuWuWuWababababababababababababababababaaaaaaaaaaaaaa
diff --git a/_maps/map_files/RandomZLevels/wildwest.dmm b/_maps/map_files/RandomZLevels/wildwest.dmm
index 52dae9cef94..5f8aa9e293a 100644
--- a/_maps/map_files/RandomZLevels/wildwest.dmm
+++ b/_maps/map_files/RandomZLevels/wildwest.dmm
@@ -156,7 +156,7 @@
"cZ" = (/obj/structure/window/reinforced{tag = "icon-fwindow (EAST)"; icon_state = "fwindow"; dir = 4},/obj/structure/window/reinforced{tag = "icon-fwindow (WEST)"; icon_state = "fwindow"; dir = 8},/obj/structure/grille,/obj/structure/window/reinforced{tag = "icon-fwindow (NORTH)"; icon_state = "fwindow"; dir = 1},/turf/simulated/floor/plating/ironsand{tag = "icon-ironsand1"; icon_state = "ironsand1"},/area/awaymission/wwgov)
"da" = (/obj/effect/landmark/corpse/syndicatecommando{mobname = "Syndicate Commando"},/turf/simulated/floor/carpet,/area/awaymission/wwgov)
"db" = (/obj/machinery/mineral/mint,/turf/simulated/floor/plating,/area/awaymission/wwrefine)
-"dc" = (/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/simulated/floor/wood,/area/awaymission/wwmines)
+"dc" = (/obj/structure/window/reinforced{dir = 5; max_integrity = 1e+007},/turf/simulated/floor/wood,/area/awaymission/wwmines)
"dd" = (/obj/structure/mineral_door/wood,/turf/simulated/floor/plating/ironsand{tag = "icon-ironsand1"; icon_state = "ironsand1"},/area/awaymission/wwmines)
"de" = (/obj/structure/mineral_door/wood,/obj/effect/decal/cleanable/blood/tracks,/turf/simulated/floor/plating/ironsand{tag = "icon-ironsand1"; icon_state = "ironsand1"},/area/awaymission/wwmines)
"df" = (/obj/structure/window/reinforced{dir = 4},/turf/space,/area/space)
diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm
index 7be4192bd04..618b257bcd7 100644
--- a/_maps/map_files/cyberiad/cyberiad.dmm
+++ b/_maps/map_files/cyberiad/cyberiad.dmm
@@ -4240,7 +4240,7 @@
"bDB" = (/obj/machinery/door/airlock/shuttle{aiControlDisabled = 1; hackProof = 1; id_tag = "s_docking_airlock"; name = "Shuttle Hatch"},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/escape)
"bDC" = (/obj/machinery/door/airlock/external{id_tag = "specops_home"},/turf/simulated/floor/plating,/area/hallway/secondary/entry)
"bDD" = (/obj/structure/table,/obj/item/storage/firstaid/o2{layer = 2.8; pixel_x = 4; pixel_y = 6},/obj/item/storage/firstaid/regular{pixel_x = 2; pixel_y = 6},/obj/item/storage/firstaid/regular{pixel_x = -2; pixel_y = 4},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape)
-"bDE" = (/obj/structure/disposalpipe/trunk{dir = 1},/obj/structure/disposaloutlet{dir = 4},/obj/effect/decal/warning_stripes/east,/turf/simulated/floor/plating,/area/maintenance/disposal)
+"bDE" = (/obj/structure/disposalpipe/trunk{dir = 1},/obj/structure/disposaloutlet{dir = 4},/obj/effect/decal/warning_stripes/east,/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/disposal)
"bDF" = (/obj/machinery/vending/wallmed1{layer = 3.3; name = "Emergency NanoMed"; pixel_x = 28; pixel_y = 0; req_access_txt = "0"},/obj/structure/stool/bed/roller,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape)
"bDG" = (/obj/structure/stool/bed/chair{dir = 4},/obj/machinery/light/spot{tag = "icon-tube1 (WEST)"; icon_state = "tube1"; dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops)
"bDH" = (/obj/machinery/door/airlock/external{id_tag = "s_docking_airlock"; name = "Shuttle Hatch"; req_access_txt = "109"},/obj/docking_port/mobile{dir = 8; dwidth = 2; height = 11; id = "specops"; name = "ert shuttle"; roundstart_move = "specops_away"; width = 5},/obj/docking_port/stationary{dir = 8; dwidth = 2; height = 11; id = "specops_home"; name = "port bay 2"; width = 5},/turf/simulated/shuttle/plating,/area/shuttle/specops)
@@ -5221,7 +5221,7 @@
"bWu" = (/obj/effect/spawner/window/reinforced,/obj/structure/sign/examroom,/turf/simulated/floor/plating,/area/medical/sleeper)
"bWv" = (/turf/simulated/wall/r_wall,/area/crew_quarters/fitness{name = "\improper Arcade"})
"bWw" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper)
-"bWx" = (/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper)
+"bWx" = (/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/medical/sleeper)
"bWy" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/medical/cryo)
"bWz" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitebluecorner"; tag = "icon-whitebluecorner"},/area/medical/medbay2)
"bWA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay2)
@@ -5282,8 +5282,8 @@
"bXD" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/medical/sleeper)
"bXE" = (/obj/item/roller,/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/sleeper)
"bXF" = (/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/obj/machinery/sleeper{dir = 4},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTHWEST)"; icon_state = "whiteblue"; dir = 9},/area/medical/sleeper)
-"bXG" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{dir = 2; icon_state = "cmo"},/area/medical/sleeper)
-"bXH" = (/turf/simulated/floor/plasteel{dir = 2; icon_state = "cmo"},/area/medical/sleeper)
+"bXG" = (/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/sleeper)
+"bXH" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper)
"bXI" = (/obj/machinery/vending/medical,/turf/simulated/floor/plasteel{dir = 5; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/sleeper)
"bXJ" = (/obj/structure/table,/obj/item/reagent_containers/syringe/antiviral,/obj/item/reagent_containers/syringe/charcoal,/obj/item/reagent_containers/syringe/insulin,/obj/item/reagent_containers/glass/bottle/morphine,/obj/item/reagent_containers/glass/bottle/epinephrine,/obj/item/reagent_containers/syringe,/obj/item/stack/medical/bruise_pack/advanced{pixel_x = 6; pixel_y = 6},/obj/item/stack/medical/ointment/advanced{pixel_x = 6; pixel_y = 8},/obj/item/reagent_containers/food/pill/patch/styptic{pixel_y = 6},/obj/item/reagent_containers/food/pill/patch/styptic{pixel_x = 2; pixel_y = 8},/obj/item/reagent_containers/food/pill/patch/silver_sulf{pixel_x = -8; pixel_y = 6},/obj/item/reagent_containers/food/pill/patch/silver_sulf{pixel_x = -8; pixel_y = 8},/obj/item/storage/pill_bottle/painkillers{pixel_x = -6; pixel_y = -3},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/sleeper)
"bXK" = (/obj/item/twohanded/required/kirbyplants,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/medical/cryo)
@@ -5361,13 +5361,13 @@
"bZe" = (/obj/machinery/camera{c_tag = "Gravity Generator Foyer"; dir = 1; network = list("SS13")},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/structure/closet/radiation,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/light,/turf/simulated/floor/plasteel,/area/engine/gravitygenerator)
"bZf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/sortjunction{dir = 8; icon_state = "pipe-j2s"; name = "Genetics"; sortType = 23},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/medical/genetics_cloning)
"bZg" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plasteel,/area/hallway/primary/central/se)
-"bZh" = (/obj/structure/table,/obj/item/roller,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/item/soap/nanotrasen,/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTHWEST)"; icon_state = "whiteblue"; dir = 9},/area/medical/sleeper)
-"bZi" = (/obj/structure/closet/crate/freezer,/obj/item/reagent_containers/blood/empty,/obj/item/reagent_containers/blood/empty,/obj/item/reagent_containers/blood/AMinus,/obj/item/reagent_containers/blood/APlus,/obj/item/reagent_containers/blood/BMinus,/obj/item/reagent_containers/blood/BPlus,/obj/item/reagent_containers/blood/OMinus,/obj/item/reagent_containers/blood/OPlus,/obj/item/reagent_containers/blood/random,/obj/item/reagent_containers/blood/random,/obj/item/reagent_containers/blood/random,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTHEAST)"; icon_state = "whiteblue"; dir = 5},/area/medical/sleeper)
-"bZj" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/medical/sleeper)
-"bZk" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/hologram/holopad,/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cmo"},/area/medical/sleeper)
-"bZl" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cmo"},/area/medical/sleeper)
+"bZh" = (/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitebluecorner"; tag = "icon-whitebluecorner"},/area/medical/sleeper)
+"bZi" = (/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitebluecorner"; tag = "icon-whitebluecorner"},/area/medical/sleeper)
+"bZj" = (/obj/structure/sink{dir = 8; icon_state = "sink"; pixel_x = -12; pixel_y = 0},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTHWEST)"; icon_state = "whiteblue"; dir = 9},/area/medical/sleeper)
+"bZk" = (/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper)
+"bZl" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/hologram/holopad,/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper)
"bZm" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/sleeper)
-"bZn" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/structure/disposalpipe/junction{dir = 8; icon_state = "pipe-j2"; tag = "icon-pipe-j1 (WEST)"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cmo"},/area/medical/sleeper)
+"bZn" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper)
"bZo" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/medical/cryo)
"bZp" = (/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/medical/cryo)
"bZq" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 1},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/medical/cryo)
@@ -5433,14 +5433,14 @@
"cay" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/structure/table,/turf/simulated/floor/plasteel,/area/engine/break_room)
"caz" = (/obj/structure/sign/poster/random{pixel_x = -32; pixel_y = 0},/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/medical/sleeper)
"caA" = (/turf/simulated/wall,/area/medical/sleeper)
-"caB" = (/obj/machinery/door/window/eastright{base_state = "left"; dir = 4; icon_state = "left"; name = "Blood Transfusion Ward"; req_access_txt = "5"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper)
+"caB" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/structure/disposalpipe/junction{dir = 8; icon_state = "pipe-j2"; tag = "icon-pipe-j1 (WEST)"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper)
"caC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper)
-"caD" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cmo"},/area/medical/sleeper)
+"caD" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper)
"caE" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper)
-"caF" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = "90Curve"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 2; icon_state = "cmo"},/area/medical/sleeper)
-"caG" = (/obj/effect/landmark/start{name = "Medical Doctor"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cmo"},/area/medical/sleeper)
+"caF" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = "90Curve"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper)
+"caG" = (/obj/effect/landmark/start{name = "Medical Doctor"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper)
"caH" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/sleeper)
-"caI" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cmo"},/area/medical/sleeper)
+"caI" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/sleeper)
"caJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/medical/cryo)
"caK" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = -30},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/medical/cryo)
"caL" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/manifold4w/hidden,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/medical/cryo)
@@ -5480,7 +5480,7 @@
"cbt" = (/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 4; location = "Medbay"},/obj/structure/plasticflaps{opacity = 1},/turf/simulated/floor/plating,/area/medical/sleeper)
"cbu" = (/obj/structure/lamarr,/turf/simulated/floor/plasteel{dir = 4; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/crew_quarters/hor)
"cbv" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/asmaint)
-"cbw" = (/obj/machinery/iv_drip,/turf/simulated/floor/plasteel{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/sleeper)
+"cbw" = (/obj/structure/table,/obj/item/roller,/obj/item/soap/nanotrasen,/turf/simulated/floor/plasteel{dir = 10; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/sleeper)
"cbx" = (/obj/structure/stool/bed/chair/comfy/black{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration)
"cby" = (/obj/machinery/computer/shuttle/admin,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration)
"cbz" = (/obj/machinery/door/airlock/centcom{id_tag = "adminshuttle"; name = "Bridge"; opacity = 1; req_access_txt = "106"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration)
@@ -5510,7 +5510,7 @@
"cbX" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/obj/structure/disposalpipe/junction{tag = "icon-pipe-j1 (EAST)"; icon_state = "pipe-j1"; dir = 4},/turf/simulated/floor/plasteel{dir = 1; icon_state = "blue"},/area/hallway/primary/central/south)
"cbY" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 1; icon_state = "blue"},/area/hallway/primary/central/south)
"cbZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = "0"},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/primary/central/south)
-"cca" = (/obj/structure/closet/crate/freezer,/obj/item/reagent_containers/blood/empty,/obj/item/reagent_containers/blood/empty,/obj/item/reagent_containers/blood/AMinus,/obj/item/reagent_containers/blood/APlus,/obj/item/reagent_containers/blood/BMinus,/obj/item/reagent_containers/blood/BPlus,/obj/item/reagent_containers/blood/OMinus,/obj/item/reagent_containers/blood/OPlus,/obj/item/reagent_containers/blood/random,/obj/item/reagent_containers/blood/random,/obj/item/reagent_containers/blood/random,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (SOUTHEAST)"; icon_state = "whiteblue"; dir = 6},/area/medical/sleeper)
+"cca" = (/obj/structure/closet/crate/freezer,/obj/item/reagent_containers/blood/empty,/obj/item/reagent_containers/blood/empty,/obj/item/reagent_containers/blood/AMinus,/obj/item/reagent_containers/blood/APlus,/obj/item/reagent_containers/blood/BMinus,/obj/item/reagent_containers/blood/BPlus,/obj/item/reagent_containers/blood/OMinus,/obj/item/reagent_containers/blood/OPlus,/obj/item/reagent_containers/blood/random,/obj/item/reagent_containers/blood/random,/obj/item/reagent_containers/blood/random,/obj/machinery/iv_drip,/turf/simulated/floor/plasteel{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/sleeper)
"ccb" = (/obj/machinery/ai_status_display{pixel_y = 32},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/primary/central/south)
"ccc" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/obj/item/radio/intercom{broadcasting = 0; name = "station intercom (General)"; pixel_y = 25},/turf/simulated/floor/plasteel,/area/hallway/primary/central/south)
"ccd" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/effect/decal/warning_stripes/north,/turf/simulated/floor/plasteel,/area/hallway/primary/central/south)
@@ -5520,15 +5520,15 @@
"cch" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel,/area/hallway/primary/central/south)
"cci" = (/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/primary/central/south)
"ccj" = (/obj/machinery/camera{c_tag = "Central Primary Hallway South"; dir = 2; network = list("SS13")},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/primary/central/south)
-"cck" = (/obj/machinery/iv_drip,/obj/machinery/ai_status_display{pixel_y = -32},/turf/simulated/floor/plasteel{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/sleeper)
+"cck" = (/obj/structure/closet/crate/freezer,/obj/item/reagent_containers/blood/empty,/obj/item/reagent_containers/blood/empty,/obj/item/reagent_containers/blood/AMinus,/obj/item/reagent_containers/blood/APlus,/obj/item/reagent_containers/blood/BMinus,/obj/item/reagent_containers/blood/BPlus,/obj/item/reagent_containers/blood/OMinus,/obj/item/reagent_containers/blood/OPlus,/obj/item/reagent_containers/blood/random,/obj/item/reagent_containers/blood/random,/obj/item/reagent_containers/blood/random,/obj/machinery/iv_drip,/obj/machinery/ai_status_display{pixel_y = -32},/turf/simulated/floor/plasteel{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/sleeper)
"ccl" = (/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel,/area/hallway/primary/central/south)
"ccm" = (/obj/machinery/door/airlock/public/glass{name = "Central Access"},/turf/simulated/floor/plasteel,/area/hallway/primary/central/se)
"ccn" = (/obj/machinery/atm{pixel_y = 32},/turf/simulated/floor/plasteel,/area/hallway/primary/central/se)
"cco" = (/obj/machinery/newscaster{pixel_y = 32},/turf/simulated/floor/plasteel,/area/hallway/primary/central/se)
"ccp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plasteel,/area/hallway/primary/central/se)
-"ccq" = (/obj/machinery/camera{c_tag = "Medbay Treatment Center"; dir = 1; network = list("SS13"); pixel_x = 0},/obj/machinery/light,/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable,/turf/simulated/floor/plasteel{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/sleeper)
+"ccq" = (/obj/machinery/camera{c_tag = "Medbay Treatment Center"; dir = 1; network = list("SS13"); pixel_x = 0},/obj/machinery/light,/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable,/obj/item/roller,/turf/simulated/floor/plasteel{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/sleeper)
"ccr" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor/plasteel,/area/hallway/primary/central/se)
-"ccs" = (/obj/machinery/sleeper{dir = 4},/obj/item/radio/intercom{name = "station intercom (General)"; pixel_y = -28},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (SOUTHWEST)"; icon_state = "whiteblue"; dir = 10},/area/medical/sleeper)
+"ccs" = (/obj/machinery/sleeper{dir = 4},/obj/item/radio/intercom{name = "station intercom (General)"; pixel_y = -28},/turf/simulated/floor/plasteel{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/sleeper)
"cct" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/sleeper)
"ccu" = (/turf/simulated/floor/plasteel{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/sleeper)
"ccv" = (/obj/machinery/light{dir = 4},/obj/machinery/alarm{dir = 1; pixel_y = -22},/obj/machinery/body_scanconsole,/turf/simulated/floor/plasteel{dir = 6; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/sleeper)
@@ -5978,8 +5978,8 @@
"ckX" = (/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/surgery1)
"ckY" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable,/turf/simulated/floor/plasteel{dir = 10; icon_state = "darkblue"},/area/medical/ward)
"ckZ" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/ward)
-"cla" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/machinery/alarm{dir = 1; pixel_y = -22},/turf/simulated/floor/plasteel{dir = 2; icon_state = "darkblue"},/area/medical/ward)
-"clb" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1},/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor/plasteel{dir = 6; icon_state = "darkblue"},/area/medical/ward)
+"cla" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/ward)
+"clb" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1},/obj/machinery/light_switch{pixel_x = 27},/obj/machinery/alarm{dir = 1; pixel_y = -22},/turf/simulated/floor/plasteel{dir = 6; icon_state = "darkblue"},/area/medical/ward)
"clc" = (/obj/machinery/bodyscanner,/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/surgery2)
"cld" = (/obj/structure/closet/secure_closet/medical2,/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitebluecorner"; tag = "icon-whitebluecorner"},/area/medical/surgery2)
"cle" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/obj/machinery/light_switch{pixel_x = 23; pixel_y = -5},/obj/machinery/holosign_switch{id = "surgery2"; pixel_x = 23; pixel_y = 4},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/surgery2)
@@ -6042,7 +6042,7 @@
"cmj" = (/obj/machinery/computer/security/telescreen{desc = "Used for watching the singularity chamber."; dir = 8; layer = 4; name = "Singularity Engine Telescreen"; network = list("Singularity"); pixel_x = 0; pixel_y = 30},/obj/structure/stool/bed/chair/office/dark{dir = 4},/turf/simulated/floor/plasteel,/area/engine/controlroom)
"cmk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/maintenance/asmaint)
"cml" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Operating Theatre Storage"; req_access_txt = "45"},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/medical/surgery1)
-"cmm" = (/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/medical/glass{id_tag = ""; name = "Medbay Virology Lobby"; req_access_txt = "5"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/virology/lab{name = "\improper Virology Lobby"})
+"cmm" = (/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/airlock/medical/glass{id_tag = null; name = "Virology Lobby Hallway"; req_access_txt = "0"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/virology/lab{name = "\improper Virology Lobby"})
"cmn" = (/obj/machinery/vending/coffee,/turf/simulated/floor/plasteel{tag = "icon-whitegreen (NORTHWEST)"; icon_state = "whitegreen"; dir = 9},/area/medical/virology/lab{name = "\improper Virology Lobby"})
"cmo" = (/obj/structure/sign/biohazard,/turf/simulated/wall,/area/medical/virology/lab{name = "\improper Virology Lobby"})
"cmp" = (/obj/machinery/vending/medical,/turf/simulated/floor/plasteel{tag = "icon-whitegreen (NORTHEAST)"; icon_state = "whitegreen"; dir = 5},/area/medical/virology/lab{name = "\improper Virology Lobby"})
@@ -6104,8 +6104,8 @@
"cnt" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/apmaint)
"cnu" = (/obj/structure/stool/bed/chair/office/dark,/turf/simulated/floor/carpet,/area/ntrep)
"cnv" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/wood,/area/blueshield)
-"cnw" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/virology/lab{name = "\improper Virology Lobby"})
-"cnx" = (/turf/simulated/floor/plasteel{tag = "icon-whitegreen (NORTHWEST)"; icon_state = "whitegreen"; dir = 9},/area/medical/virology/lab{name = "\improper Virology Lobby"})
+"cnw" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical/glass{id_tag = null; name = "Virology Lobby Hallway"; req_access_txt = "0"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/ward)
+"cnx" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitegreencorner"},/area/medical/virology/lab{name = "\improper Virology Lobby"})
"cny" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel,/area/hallway/primary/aft)
"cnz" = (/obj/structure/sign/biohazard{pixel_y = 32},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitegreen"; tag = "icon-whitegreen (WEST)"},/area/medical/virology/lab{name = "\improper Virology Lobby"})
"cnA" = (/turf/simulated/floor/plasteel{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft)
@@ -6374,15 +6374,15 @@
"csD" = (/turf/simulated/wall,/area/engine/controlroom)
"csE" = (/obj/machinery/camera{c_tag = "NT Representative's Office"; dir = 1; network = list("SS13")},/obj/structure/table/wood,/obj/machinery/photocopier/faxmachine/longrange{department = "NT Representative's Office"},/obj/machinery/newscaster/security_unit{pixel_x = 0; pixel_y = -32},/turf/simulated/floor/wood,/area/ntrep)
"csF" = (/obj/item/flashlight,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/genetics)
-"csG" = (/obj/structure/closet/firecloset,/obj/item/taperoll/engineering,/turf/simulated/floor/plasteel,/area/engine/controlroom)
+"csG" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/structure/closet/firecloset,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel,/area/engine/controlroom)
"csH" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel,/area/hallway/primary/aft)
"csI" = (/obj/structure/disposalpipe/segment,/obj/item/radio/intercom{dir = 8; name = "station intercom (General)"; pixel_x = -28},/obj/machinery/camera{c_tag = "Aft Primary Hallway 1"; dir = 4; network = list("SS13")},/turf/simulated/floor/plasteel{dir = 8; icon_state = "cautioncorner"},/area/hallway/primary/aft)
"csJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/engine/controlroom)
"csK" = (/obj/structure/table,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/asmaint)
"csL" = (/turf/simulated/floor/plating,/area/maintenance/asmaint)
"csM" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/genetics)
-"csN" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/structure/closet/firecloset,/obj/item/taperoll/engineering,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel,/area/engine/controlroom)
-"csO" = (/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = 30},/obj/structure/closet/firecloset,/obj/item/taperoll/engineering,/turf/simulated/floor/plasteel,/area/engine/controlroom)
+"csN" = (/obj/structure/closet/firecloset,/turf/simulated/floor/plasteel,/area/engine/controlroom)
+"csO" = (/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = 30},/obj/structure/closet/firecloset,/turf/simulated/floor/plasteel,/area/engine/controlroom)
"csP" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/maintenance/genetics)
"csQ" = (/obj/structure/cable,/obj/machinery/computer/monitor{name = "Grid Power Monitoring Computer"},/turf/simulated/floor/plasteel{icon_state = "caution"; dir = 5},/area/engine/controlroom)
"csR" = (/obj/structure/rack{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/effect/spawner/lootdrop/maintenance{lootcount = 2; name = "2maintenance loot spawner"},/turf/simulated/floor/plating,/area/maintenance/genetics)
@@ -6505,7 +6505,7 @@
"cve" = (/obj/item/assembly/timer,/obj/item/assembly/timer{pixel_x = 6},/obj/item/assembly/timer{pixel_x = -5; pixel_y = 6},/obj/structure/table,/obj/item/assembly/timer{pixel_x = -3; pixel_y = -4},/obj/item/assembly/timer{pixel_x = 8; pixel_y = 8},/obj/item/assembly/timer,/obj/machinery/light_switch{pixel_y = -23},/obj/machinery/light,/obj/machinery/requests_console{department = "Science"; departmentType = 2; name = "Science Requests Console"; pixel_x = 0; pixel_y = -30},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/mixing)
"cvf" = (/obj/machinery/atmospherics/trinary/mixer{density = 0; dir = 8; req_access = null},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/mixing)
"cvg" = (/obj/machinery/atmospherics/unary/portables_connector{dir = 4},/obj/item/radio/intercom{name = "station intercom (General)"; pixel_y = -28},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/mixing)
-"cvh" = (/obj/item/radio/beacon,/obj/effect/decal/warning_stripes/red/hollow,/turf/simulated/floor/plasteel/airless,/area/toxins/test_area)
+"cvh" = (/obj/item/radio/beacon,/obj/effect/decal/warning_stripes/red/hollow,/turf/simulated/floor/plasteel/airless/indestructible,/area/toxins/test_area)
"cvi" = (/obj/machinery/atmospherics/binary/valve{dir = 4},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/mixing)
"cvj" = (/obj/machinery/mass_driver{dir = 4; id_tag = "toxinsdriver"},/turf/simulated/floor/plating,/area/toxins/launch{name = "Toxins Launch Room"})
"cvk" = (/obj/structure/closet/crate,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/apmaint)
@@ -7170,6 +7170,7 @@
"cHT" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/plasteel,/area/engine/break_room)
"cHU" = (/obj/structure/sign/securearea,/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/yellow{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/simulated/wall,/area/engine/break_room)
"cHV" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/wall/r_wall,/area/atmos/control)
+"cHW" = (/turf/simulated/floor/plasteel{tag = "icon-whitegreen (WEST)"; icon_state = "whitegreen"; dir = 8},/area/medical/virology/lab{name = "\improper Virology Lobby"})
"cHY" = (/obj/machinery/computer/general_air_control{frequency = 1441; name = "Tank Monitor"; sensors = list("n2_sensor" = "Nitrogen", "o2_sensor" = "Oxygen", "co2_sensor" = "Carbon Dioxide", "tox_sensor" = "Toxins", "n2o_sensor" = "Nitrous Oxide", "waste_sensor" = "Gas Mix Tank")},/obj/machinery/alarm{frequency = 1439; pixel_y = 23},/turf/simulated/floor/plasteel,/area/atmos/control)
"cHZ" = (/obj/machinery/kitchen_machine/grill,/turf/simulated/floor/plating,/area/maintenance/asmaint)
"cIa" = (/obj/machinery/cooker/deepfryer,/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating,/area/maintenance/asmaint)
@@ -7417,8 +7418,8 @@
"cNb" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 101; on = 1; pressure_checks = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/light{dir = 1},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/engine/engineering)
"cNc" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/obj/machinery/camera{c_tag = "Engineering Particle Accelerator"; dir = 2; pixel_x = 23; network = list("Singularity","SS13")},/obj/machinery/light{dir = 1},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/engine/engineering)
"cNd" = (/obj/structure/barricade/wooden,/turf/simulated/floor/plating,/area/maintenance/asmaint)
-"cNe" = (/obj/structure/disposalpipe/segment,/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/simulated/floor/plating,/area/maintenance/asmaint)
-"cNf" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/simulated/floor/plating,/area/maintenance/asmaint)
+"cNe" = (/obj/structure/disposalpipe/segment,/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; max_integrity = 1e+007},/turf/simulated/floor/plating,/area/maintenance/asmaint)
+"cNf" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; max_integrity = 1e+007},/turf/simulated/floor/plating,/area/maintenance/asmaint)
"cNg" = (/obj/structure/sign/barsign,/turf/simulated/wall,/area/maintenance/asmaint)
"cNh" = (/obj/effect/decal/cleanable/vomit,/turf/simulated/floor/plating,/area/maintenance/genetics)
"cNi" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel,/area/engine/engineering)
@@ -8972,10 +8973,10 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPLbPIbVebVfbVgbVhbVibRGbVkbRAbVlbRAbRAbRAbRAbRAbTlbRGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabOebVmbOcbOcbOcbVnbOebPTbKBbKBbVobKzbPPbKzbKzbKzbKzbKzbJfbKAbTsbVpbxbbVrbBnbVqbVsbBnbVwbzEbBnbBnbVtbDXbOwbTybTzbRVbRWbMGbVubVvbVybVxbVzbMHbVBbVAbVDbVCbHsbVEbVFbHsbHtbHtbVGbSibVIbVHbVKbVJbVLbVLbVNbVMbVObFObSMbSLbSObSNbSPcrAcrAcrAcrAcrAbSRbSQbSUbSSbSVbXAbSXbRtbXAbThbXAbJRcuobJSbTZbTYbUabUabUcbUbbWgbUdbUfbUdbWibWibWjbWjbWjbWjbIabIabIabIabIabWlbWnbLIbIabNVbNZbNXbWqbWqbPibOabLRctvbPkbPjcacbGGbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWObWGbRAbRAbWHbWHbWHbRGbRAbRAbRGbWIbWJbWKbRAbWMbWNbRGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabOebOcbOcbOcbOcbOcbWPbTrbTqbTrbPUbWQbWRbKzbKzbKzbWQbKzbJfbKAbTsbWSbxbbWWbBnbzFbQdbBnbzJbLJbBnbBnbWUbDXbOwbTybWVbRVbWXbMGbXbbWYbWZbXabXdbMHbXcbXebXgbXfbXibXhbXjbFCaaaaaaaaabSibXpbXkbXlbXlbXmbXnbXobSibXrbXqbUhbUgbUjbUibUrbUkbUnbUmbUmbUmbUpbUobUmbUmbUqbUmbUmbUsbUnbUmbUmbUGbNubNtbUwbUvbUBbUybZfbUDbXNbUIbUIbUIbUJbWgbLRbUPbWqbWqbXYbXXbWqbXZbYbbYabYdbYcbWqbPlbYgbYfbYibYhbYlbYjbYjbYjbYjbYjcacbGjbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabYubWGbRAbRAbRAbRAbRAbYtbRAbRAbRGbPIbPIbPIbPIbPIbPIbYvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabOebOcbOcbOcbOcbOcbYxbYwbYybYwbYAbYzbYBbYBbYBbYBbYBbYCbYEbYDbTsbYFbxbbYGbYIbYHbYNbYJbYKbYLbYLbYLbYMbYMbYObTybYRbYQbRWbMGbYTbYSbYVbVvbYWbMHbYUbYXbZdbTJbZebQmbYYbFCaaaaaaaaabSibYZbZabZbbZcbXmbXnbXobSibZgbZJbURbUQbUTbUScyTcyTbUVbUUbUXbUWcyTbUYbUZbUZbVabUZbUZbUSbUVbUZbVcbVbbVdcyTbVPbVjbVRbVQbVTbVSbVVbVUbVXbVWbVZbVYbWcbWbbWcbWcbWebUNbZMbUNbZNbUNbZPbZObZObPCbPDbZRbZUbZTbZXbZVbGkbZWaYpbYjcacbGGbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaebPIcafcagcahcaibRAbRGbRAbRAbRGbRAcancakcaraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabOebOcbOcbOcbOcbOcbOebPTbKBbKBbxbbxbbKBbKBbKBbKBbKBbxbbxbbKBbKBbKBbxbcamcamcamcascambYMcaocapcaqcatbYMbOwbTycawbMEbMEbMGbMGbMGbMGbMGbMNbMHbTJbTIcaubTJcavcaxbFCbFCbFCbFCbFCbSibSjbSibSibSibSibSibSibSibNvbFObWfbSLbWkbWhbWobWmbWscaAbWubWtbWxbWwbWtbWubWabWybWabWybWabWybWabWzbWAcrAbTZbWBbWDbWCbWFbWEbXNbXsbXubXtbXvcbdcbdcbecbdcbfcbicbfcbfcbfcbhcblcbjcbjcbkcbmcbocbnbZUcbpcbrcbqbGlcbscbubYjcacbGGbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPIbPIbPIbPIbPIbPIbRGbTobRAcbzbRAcbxcbycbAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacbDcbBbOccbCbOccbEcbFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacbGaabaaaaaaaaaaaacamcbIcbHcbKcbJbYMcbNcbLcbMcbRbYMbOwbTycbOcbPcbQbXwcbVcbTcbUcbWcbYcbXbXxcbZcccccbccfccdcceccgccjcchccibXybXzcclccmbEnccnbFOccoccpccrbFObXBbQVbXCcaAcaAbXDbXDcaAbXFbXEbXHbXGbXJbXIbWabXKbXMbXLbXMbXObWabXPbWAbXRbWdbXSbXUbXTbXSbXSbWibXVbXWbXQbYkcbdccTccSccVccUccXccWcdbcbfccYccZcdacbjcbjcdccbocddcdfbPEcdhcdgbGmcdicdkbYjcdndfcbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPLbPIcdlcdmcdpcdlcdobRGbRAbRAbRGbRAcdrcdqcdsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacdvcdtcducducducdtcdwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacamcdycdxcdAcdzbYLcdBcdDcdCcdEbYMbOwbNwcdFbTybTybYmbYncdIcdJcclcdObYobYpcdMcdNcdNcdQcdPcdRcdNcdNcdTcdNcdNcdScclccmbEncdVcdUcdXbYqcdZcdYbFOchfbYrcaAbZhbYsbYsbZibZjbXHbZlbZkbZnbZmbZpbZobZrbZqbZtbZsbZvbZubWAcuvchrbZwbZybZxbZAbZzbZBccQbXWbXQbZBcbdcezceyceBceAceDceCceGcbfceEccZceFceFcbjceHceJceIceLceKceNceMbGnceOceSbYjcaccLhbGpbGobGsaaaaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWObWGceRceRceRceRceRceTbRAbRAbRGbPIbPIbPIbPIbPIbPIbPRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaceVceUceUceUceWaaaaaaaaaaaaaaaaaaaaaceXceZceYceZcfaaaaaaaaaacamcamcamcffcfbcdAcfcbYLcfdcbMcfecfgbYMbOwbNxbTicficflcfkbZDbZCbZFbZEbZHbZGbZIcfscftcftcfxcfvcfvcfvcfvcfvcfvcfvcJfcfycfzcfBbZLbZKbZYbZScabcaacadchfcajcaAcazcalcaCcaBcaEcaDcaGcaFcaIcaHcaKcaJcaMcaLcaOcaNbZvcaPcaQcuvbZzcaRcaTcaScaVcaUcaXcaWcaZcaYcaXcbdcgccgbcgecgdcghcgfcggcbfcgiccZceFceFcbjcgjcgmcgkcglcgncgpcgocgrcgqcgvbYjcaccgscgtcgscgucgycgucgucguaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaebPIcafcagcahcaibRAbRGbRAbRAbRGbRAcancakcaraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabOebOcbOcbOcbOcbOcbOebPTbKBbKBbxbbxbbKBbKBbKBbKBbKBbxbbxbbKBbKBbKBbxbcamcamcamcascambYMcaocapcaqcatbYMbOwbTycawbMEbMEbMGbMGbMGbMGbMGbMNbMHbTJbTIcaubTJcavcaxbFCbFCbFCbFCbFCbSibSjbSibSibSibSibSibSibSibNvbFObWfbSLbWkbWhbWobWmbWscaAbWubWtbWxbWwbXGbWubWabWybWabWybWabWybWabWzbWAcrAbTZbWBbWDbWCbWFbWEbXNbXsbXubXtbXvcbdcbdcbecbdcbfcbicbfcbfcbfcbhcblcbjcbjcbkcbmcbocbnbZUcbpcbrcbqbGlcbscbubYjcacbGGbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPIbPIbPIbPIbPIbPIbRGbTobRAcbzbRAcbxcbycbAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacbDcbBbOccbCbOccbEcbFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacbGaabaaaaaaaaaaaacamcbIcbHcbKcbJbYMcbNcbLcbMcbRbYMbOwbTycbOcbPcbQbXwcbVcbTcbUcbWcbYcbXbXxcbZcccccbccfccdcceccgccjcchccibXybXzcclccmbEnccnbFOccoccpccrbFObXBbQVbXCcaAcaAbXDbXDcaAbXFbXEbZhbXHbZibXIbWabXKbXMbXLbXMbXObWabXPbWAbXRbWdbXSbXUbXTbXSbXSbWibXVbXWbXQbYkcbdccTccSccVccUccXccWcdbcbfccYccZcdacbjcbjcdccbocddcdfbPEcdhcdgbGmcdicdkbYjcdndfcbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPLbPIcdlcdmcdpcdlcdobRGbRAbRAbRGbRAcdrcdqcdsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacdvcdtcducducducdtcdwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacamcdycdxcdAcdzbYLcdBcdDcdCcdEbYMbOwbNwcdFbTybTybYmbYncdIcdJcclcdObYobYpcdMcdNcdNcdQcdPcdRcdNcdNcdTcdNcdNcdScclccmbEncdVcdUcdXbYqcdZcdYbFOchfbYrcaAbZjbYsbYsbXJbZhbZkbZnbZlcaBbZmbZpbZobZrbZqbZtbZsbZvbZubWAcuvchrbZwbZybZxbZAbZzbZBccQbXWbXQbZBcbdcezceyceBceAceDceCceGcbfceEccZceFceFcbjceHceJceIceLceKceNceMbGnceOceSbYjcaccLhbGpbGobGsaaaaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWObWGceRceRceRceRceRceTbRAbRAbRGbPIbPIbPIbPIbPIbPIbPRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaceVceUceUceUceWaaaaaaaaaaaaaaaaaaaaaceXceZceYceZcfaaaaaaaaaacamcamcamcffcfbcdAcfcbYLcfdcbMcfecfgbYMbOwbNxbTicficflcfkbZDbZCbZFbZEbZHbZGbZIcfscftcftcfxcfvcfvcfvcfvcfvcfvcfvcJfcfycfzcfBbZLbZKbZYbZScabcaacadchfcajcaAcazcalcaCcaEcaEcaDcaGcaFcaIcaHcaKcaJcaMcaLcaOcaNbZvcaPcaQcuvbZzcaRcaTcaScaVcaUcaXcaWcaZcaYcaXcbdcgccgbcgecgdcghcgfcggcbfcgiccZceFceFcbjcgjcgmcgkcglcgncgpcgocgrcgqcgvbYjcaccgscgtcgscgucgycgucgucguaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabYubWGceRceRceRcgwcgxbRGbRAbRAbRGbRAbRAbRAcgzbRAcgAbRGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacgFcgBcgCcgDcgFbYPbYPbYPcamcgHcgGcgJcgIcgLcgKcgNcgMcgOcgOcgPbYMbTkcgQcgTcgScgScgUcbacgVcgScgWcgWcgYcbbcgZcgWcgWchacclcclchechcchcchcchccbcchcchcchfcbgchfchfchfchfchfchfchfcbvcbtcbScbwcckccaccsccqccucctccwccvbWaccxcczccyccBccAccDccCccEcuvccGccFccIccHccJchrbWibWgbWgbWgbWicbdcbdchMchQchOchPchOchRcbfchUchSchTchTcbjchVchXbTwbYjbYjbYjbYjbYjbYjbYjbYjcaccgscifchYchZciaciacibcguaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcicciccicciccidcidcieciecieciecijaabaabaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaebPIcigceRceRcihciibRGbRAbRAcikbRAbRAbRAciobRAcilbRGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaceYcimcincimceYbYPcipciqcamcitcfbcircisciyciubYMcivciwcixcizbYMcgQcgQciCcgSciAciBccKciDciHcgWccLciGccMciIciKcgWciMciLciNchcccOccNccRccPcdjcdecdKcdHcdLchfceacdWceccebchfcedcbvcaAcaAcaAcaAcaAcaAcaAcefceecegcaAcDfcDfcDfcDfcDfcDfcDfcDfceicehccGcejcelcekcencemcepceocerceqclpcjFcjHcjGcjIcjGcjGcjLcjJcjKcjPcjMcjNcjOcbjcjQbUtcbnbPtbGGcjTcjScjUcjUcjScjUcjYcgscjVcjWchZciackecjXcguaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaciccjZckacjZcidciecieckbckcckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaebPIckdceRceRckfbRGbRAbRAbRGckgbRAbRAckjckhbPIbYvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacgFckicimcimckkcklcfbcfbckmckncfbcfbcisckqckobYMbYMbYMbYMbYMbYMckpcgQciCcgSclRcesceucetckucgWckvcevcexcewcePcgWcfmceQcfnchccfpcfockHckGcfqckIchcchfdgCchfcebcebcfrcebchfcsLcbvchfcfwbUucfCcfAcfEcfDcfGcfFcfIcfHcfKcfJcfMcfLcDfcfNcfPcfOcfRcfQcfTcfScfVcfUcfXcfWcepcfYcgacfZclpclncjGcjGclmclocjGcltclpcbjclqccZclrclrcbjcbmclscbnbPtcgsclvcgscgscgscgscgscgscgscluclwcguclxclzclycguafOafOafOafOafOafOafOafOafOafOafOafOafOafOafOafOafOafOafOafOafOclBcjZcjZclAciecieckbckbclHckbckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -8983,8 +8984,8 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaebPIbPIbPIbPIbPIbPIbPIbPIbPIbPIbYvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabafOcgQcngcngcgQcngcngcgQaaaaaacgFcnhcnicnjcgFbYPbYPbYPcamcnmcnlcnocnocnocamcamcgQcnncnpcnrcnqcgQcnscntcgSclRcktcktcktcnvcgWckvckwckwcnuchHcgWcpicHDcnAchcchcchcchcchcchIchcchccnCdgCcsLcsLcsLchfcABchJcsLcbvchfchLchKciEchNcfEciFcfGcfFcfIcfHciOciJciQciPcDfciRciScDfciUciTchrciVciXciWchrchrcepciYcjaciZclpcjbcodcoicoicoicodcogcodcodcohcojclrclrcbjcokclscbncomcolcooconcorcopcoqcoqcotcoscovcoucoxcowcozcoycoCcoAcoBcoDcoEcoFcoHcoGcoIaabaabaabaabaabaabaabaabaaaaaaaaaaaaaaacidciecoMcoJcoJckbckbckbckbckbckbckbckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaacgQcoKcoLcgQcoKcoLcgQaaaaaacoOceZcoNceZcoQaaaaabaaacamcamcamcamcamcamcamcoPcgQcoScoRcoUcoTclPcoVcoWcgScoYcoXcpfcktcjccgWcjdckwcjfcjecjgcgWcjicjhcjkcjjcpqcpqcpqcpqcjlcpmcppcpocjncjmcjmcjocjqcjpcjscjrcjtchfcjwcjucjycjxcjAcjzcjCcjBcjCcjDckrcjEckxcksckzckyckAcDfckBcuvckCcjvckDcmDckFckEciYckJckLcgacpRcpTcpRcpUcpWcpVcpRcpXcpYcodcqacpZcdacbjcbjcqccqbcqfcqdcqecqicqgcqhcqlcqjcqkcqncqmcqpcqocqtcqqcqrcqqcqscqrcqrcqucqwcqvcqycqxcqCaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaacieciecqDckbckbckbckbckbckbckbckbckbckbckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafOaaaafOcgQcqzcoLcgQcqzcoLcgQaaaaaaaabaabaabaabaabaabaabaabaabcgQcoLcqAcqBcgQcqEcqGcgQcqHcgQcgQcqFcgQcgQcqPcgScqRcqIcqJcqKcqLcgWckMcqOcqScqQcqTcgWckOckNckPcJZcsDcsDcsDcsDcsDcrdcqZcrackQchfcucckRcsLckSckTcsLcsKchfckVckUckXckWcCWckYclackZclbcDfcldclcclfclecDfcDfcDfcDfclhclgckCchCcljclicllclkciYcmdcgacmfcpRcrNcrQcrLcrMcrLcrTcrOcrPcodcbjcrUcbjcbjcrRcrSclsbLRbPtcgscrVcgscgscrWcrYcrXcsacrZcsdcsbcsfcsecsgcsecsgcshcsgcsicgEcsncvdcsqcsraabaabaabaabaabaabaabaabaaaaaaaaaaaaaaacieckbckbckbckbckbckbcssckbcstckbckbckbckbckbciecieaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcsjafOaabaMraMrafOcgQcgQcqFcgQcgQcqFcgQcgQcgQcngcngcngcgQcgQcgQcgQcgQcgQcgQcoLcskcslcgQcsmcgQcgQcsucgQcsocspcoLcgQcsvcgScsycsxcszclRcmgcgWcswckvcsEcsCcmhcgWcsIcsHcmicsDcsDcsNcsOcsGcmjcsQcsJcsKcsLcsUchfcmkcsLckSckTchfchfchfcCWcCWcmlcCWcCWcxhcxhcmmcxhcDfcDfcDfcDfcDfcDfcmncmpcmocmrcmqcmtcmscmvcmucmxcmwciYcgacgaaqEcpRcttctxctwctyctwctActzcrLctuctvctBbLRctCbLRcrSclsbLRbIictFctHctGcgscgscgscgscgsctIcqkctKctDcsccqkctEcqkclucqkctLcgEctOctQctPcgEaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaciectJctJctJctJctJctJctSckbctTctJcstckbckbckbckbcieaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabafOafOcngcoLcoLcoLcoLctMctNcoLcoLcoSctUctUctVctUctUctUctUctUctUctUctUctUctUctUctUcoRcgQcskcqzctWcgQcsvctRctRctRctRctRctRcgWcgWcgWcgWcgWcgWcgWcuactXcmBcmzcmEcmCcmFcmFcmGcuicsJcmHcsLcubcuccmIcsLckScmJchicsLcsLcsKcCWcmLcmKcmNcCWcnxcnwcnBcnzcnEcnDcnGcnFcnIcnHcnKcnJcnMcnLckCcnNcnPcnOcnRcnQciYbQXcgacgacpRcuGcnTcnScnUcrLcuKcuJcuOcuLcuScuRcuVbLRcuXcrSclscuMbIibPAcuNcuYcuPcuQbGGbGGcgscvccvecuTcuUcvfcuWcvgcvicuZcvacvbcgEcvjdoKdoFcvraaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaacvscjZcjZcjZcjZcjZcjZcjZcvhcvtckbckbckbckbcvvckccieaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcsjafOaabaMraMrafOcgQcgQcqFcgQcgQcqFcgQcgQcgQcngcngcngcgQcgQcgQcgQcgQcgQcgQcoLcskcslcgQcsmcgQcgQcsucgQcsocspcoLcgQcsvcgScsycsxcszclRcmgcgWcswckvcsEcsCcmhcgWcsIcsHcmicsDcsDcsGcsOcsNcmjcsQcsJcsKcsLcsUchfcmkcsLckSckTchfchfchfcCWcCWcmlcCWcCWcxhcnwcmmcxhcDfcDfcDfcDfcDfcDfcmncmpcmocmrcmqcmtcmscmvcmucmxcmwciYcgacgaaqEcpRcttctxctwctyctwctActzcrLctuctvctBbLRctCbLRcrSclsbLRbIictFctHctGcgscgscgscgscgsctIcqkctKctDcsccqkctEcqkclucqkctLcgEctOctQctPcgEaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaciectJctJctJctJctJctJctSckbctTctJcstckbckbckbckbcieaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabafOafOcngcoLcoLcoLcoLctMctNcoLcoLcoSctUctUctVctUctUctUctUctUctUctUctUctUctUctUctUcoRcgQcskcqzctWcgQcsvctRctRctRctRctRctRcgWcgWcgWcgWcgWcgWcgWcuactXcmBcmzcmEcmCcmFcmFcmGcuicsJcmHcsLcubcuccmIcsLckScmJchicsLcsLcsKcCWcmLcmKcmNcCWcHWcnxcnBcnzcnEcnDcnGcnFcnIcnHcnKcnJcnMcnLckCcnNcnPcnOcnRcnQciYbQXcgacgacpRcuGcnTcnScnUcrLcuKcuJcuOcuLcuScuRcuVbLRcuXcrSclscuMbIibPAcuNcuYcuPcuQbGGbGGcgscvccvecuTcuUcvfcuWcvgcvicuZcvacvbcgEcvjdoKdoFcvraaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaacvscjZcjZcjZcjZcjZcjZcjZcvhcvtckbckbckbckbcvvckccieaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabafOaabaabafOcngcvkcvlcvmcoLcoLcvncoLcoLcsucgQcgQcgQcgQcgQcgQcqFcgQcgQcgQcgQcvocvocvocvocvocvocvocvocvocgQcsvcvpaaaaaaaaaaaacvqcvwcvzcvycvucvAcvDcvxcvJcvGcvKcvBcvCcvLcvEcvEcvFcvMcvHcvIcvIcvIcvIcvNcvIckScmJchfcnVcKOdercCWcnXcnWcnZcnYcobcoacoccoccofcoecpacoZcpccpbcpecpdcphcpgciYciYciYciYciYciYciYciYcpkcpjcpRcwjcplcwqcptcpncpvcpucpRcpRbIicwpbIibIibIicwvcwJcwwbIibGGcuNcwKcwucuQcuQcuQcgscgscgscgscgscgscgscgscgscgscgscgscgEcgEcgEcgEcgEaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaciecoJcoJcoJcoJcoJcoJcwLckbcoMcoJcwMckbckbckbckbcieaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcgQcwxcwxcwxcwxcwxcwxcwycwxcsucwzcgQcoLcwAcwBcwCcoLcwCcwDcwEcwBcvocwFcwFcvocwGcvocwHcwIcvocoLcqPcngaaacwPcwUcwQcwVcwNcwOcwWcwXcwRcwScwTcwZcwYcxbcxacxdcxccxfcxecxjcxgcvHcxkcxmcxmcxmcxocvIckScmJchfdgmcQkcQkcQkcQkcpwcpxcQkcpycpycpycpycQkcpzcpBcpAcQkcQncQncpCcpDcuocukbQXbQXcpEbQXbQXbQXbQXbQXcpFcpRcpRcpRcpRcpGcpRcpRcpRcxIcpHcpIcxKcxUcxMcxNcxOcxWcxQcxNbGGcuNcylbGGbGGcxScxZcyactFbGGbGGbGGbGGbGGbGGbGGcxVcymbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacieckbckbckbckbckbckbcssckbcwMckbckbckbckbckbciecieaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacxXcxYcxYcxYcxYcxYcxYcyocyncybcyccydcyecyfcwycsucygcgQcoLcoLcwBcoLcoLcoLcwDcqBcwBcvocwFcyicwIcwIcyjcwIcykcvocypcqPcngaaacyrcytcyscyvcyqcwOcywcyAcyycyucvxcyCcsHcyEcvBcyxctYcyFctYcyzcyGcyBcyHcyDcyDcyDcyIcvIckScmJchfcQkcQkcpKcpJcQkcQkcQkcQkcpMcpLcpOcpNcQkcQkcpPcQkcQkcTBdgmbQVcpScuvcqMcqMcqMcqMcqMcqMcqNbQXcqWcqUcqXcqXcqXcqYcrccrbcrbcrfcrbcrbcrbcrgczmczmcricrhcrjczwczzczyczBczAczCczCczDczCczCczCczCczGczIczCczCczCczOczLbGGbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacieciecqDckbckbckbckbckbckbckbckbckbckbckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
diff --git a/_maps/map_files/cyberiad/z6.dmm b/_maps/map_files/cyberiad/z6.dmm
index 4921106a76e..34ec87162d6 100644
--- a/_maps/map_files/cyberiad/z6.dmm
+++ b/_maps/map_files/cyberiad/z6.dmm
@@ -69,7 +69,7 @@
"bq" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = -32},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/djstation)
"br" = (/obj/machinery/light_switch{pixel_x = 28; pixel_y = 28},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1479; master_tag = "dj_station_airlock"; name = "interior access button"; pixel_x = 25; pixel_y = -25; req_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/djstation)
"bs" = (/obj/structure/lattice,/obj/structure/grille,/turf/space,/area/space)
-"bt" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/simulated/floor/plating,/area/derelict/solar_control)
+"bt" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; max_integrity = 1e+007},/turf/simulated/floor/plating,/area/derelict/solar_control)
"bu" = (/turf/simulated/floor/plating,/area/derelict/solar_control)
"bv" = (/obj/machinery/door/airlock/external{frequency = 1479; icon_state = "door_locked"; id_tag = "dj_station_inner"; locked = 1; name = "DJ Station Interior Access"; req_access = null; req_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plating,/area/djstation)
"bw" = (/obj/machinery/door/airlock/external{name = "Air Bridge Access"},/turf/simulated/floor/plating,/area/derelict/solar_control)
@@ -177,7 +177,7 @@
"du" = (/obj/machinery/power/emitter{dir = 1; icon_state = "emitter"},/turf/simulated/floor/plating/airless,/area/derelict/singularity_engine)
"dv" = (/obj/machinery/field/generator,/turf/simulated/floor/plating/airless,/area/derelict/singularity_engine)
"dw" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/window/reinforced,/turf/simulated/floor/plasteel,/area/derelict/bridge/access)
-"dx" = (/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/simulated/floor/plasteel,/area/derelict/bridge/access)
+"dx" = (/obj/structure/window/reinforced{dir = 5; max_integrity = 1e+007},/turf/simulated/floor/plasteel,/area/derelict/bridge/access)
"dy" = (/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plasteel,/area/derelict/bridge)
"dz" = (/obj/item/stack/rods,/turf/simulated/floor/plating/airless,/area/space)
"dA" = (/obj/structure/grille,/obj/structure/window/reinforced,/turf/simulated/floor/plating/airless,/area/derelict/singularity_engine)
@@ -503,7 +503,7 @@
"jI" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/space)
"jJ" = (/obj/structure/closet/wardrobe/mixed,/turf/simulated/floor/plasteel,/area/derelict/arrival)
"jK" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/space)
-"jL" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/simulated/floor/plating,/area/derelict/arrival)
+"jL" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; max_integrity = 1e+007},/turf/simulated/floor/plating,/area/derelict/arrival)
"jM" = (/obj/machinery/door/airlock/external{name = "Escape Airlock"},/turf/simulated/floor/plating,/area/derelict/arrival)
"jN" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating/airless,/area/space)
"jO" = (/turf/simulated/wall,/area/derelict/hallway/secondary)
@@ -515,7 +515,7 @@
"jU" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/turf/simulated/wall/r_wall,/area/derelict/hallway/secondary)
"jV" = (/obj/structure/window/basic{dir = 1},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plating/airless,/area/derelict/hallway/secondary)
"jW" = (/obj/structure/grille,/obj/item/shard,/obj/item/shard{icon_state = "medium"},/turf/simulated/floor/plating/airless,/area/space)
-"jX" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/simulated/floor/plating/airless,/area/space)
+"jX" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; max_integrity = 1e+007},/turf/simulated/floor/plating/airless,/area/space)
"jY" = (/obj/structure/girder,/turf/simulated/floor/plating/airless,/area/derelict/hallway/primary)
"jZ" = (/obj/item/stack/rods,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel/airless,/area/derelict/hallway/secondary)
"ka" = (/obj/item/shard{icon_state = "small"},/turf/space,/area/space)
diff --git a/_maps/test_all_maps.dm b/_maps/test_all_maps.dm
new file mode 100644
index 00000000000..5289988bf82
--- /dev/null
+++ b/_maps/test_all_maps.dm
@@ -0,0 +1,112 @@
+// This is for Travis testing. DO NOT SET THIS AS THE GAME'S MAP NORMALLY!
+
+#if !defined(USING_MAP_DATUM)
+ // Away missions
+ #include "map_files\RandomZLevels\beach.dmm"
+ #include "map_files\RandomZLevels\moonoutpost19.dmm"
+ #include "map_files\RandomZLevels\undergroundoutpost45.dmm"
+ #include "map_files\RandomZLevels\academy.dmm"
+ #include "map_files\RandomZLevels\blackmarketpackers.dmm"
+ #include "map_files\RandomZLevels\spacehotel.dmm"
+ #include "map_files\RandomZLevels\stationCollision.dmm"
+ #include "map_files\RandomZLevels\wildwest.dmm"
+ #include "map_files\RandomZLevels\evil_santa.dmm"
+
+ // Space Ruins
+ #include "map_files\RandomRuins\SpaceRuins\abandonedzoo.dmm"
+ #include "map_files\RandomRuins\SpaceRuins\asteroid1.dmm"
+ #include "map_files\RandomRuins\SpaceRuins\asteroid2.dmm"
+ #include "map_files\RandomRuins\SpaceRuins\asteroid3.dmm"
+ #include "map_files\RandomRuins\SpaceRuins\asteroid4.dmm"
+ #include "map_files\RandomRuins\SpaceRuins\asteroid5.dmm"
+ #include "map_files\RandomRuins\SpaceRuins\deepstorage.dmm"
+ #include "map_files\RandomRuins\SpaceRuins\derelict1.dmm"
+ #include "map_files\RandomRuins\SpaceRuins\derelict2.dmm"
+ #include "map_files\RandomRuins\SpaceRuins\derelict3.dmm"
+ #include "map_files\RandomRuins\SpaceRuins\derelict4.dmm"
+ #include "map_files\RandomRuins\SpaceRuins\derelict5.dmm"
+ #include "map_files\RandomRuins\SpaceRuins\emptyshell.dmm"
+ #include "map_files\RandomRuins\SpaceRuins\gasthelizards.dmm"
+ #include "map_files\RandomRuins\SpaceRuins\intactemptyship.dmm"
+ #include "map_files\RandomRuins\SpaceRuins\listeningpost.dmm"
+ #include "map_files\RandomRuins\SpaceRuins\mechtransport.dmm"
+ #include "map_files\RandomRuins\SpaceRuins\onehalf.dmm"
+ #include "map_files\RandomRuins\SpaceRuins\spacebar.dmm"
+ #include "map_files\RandomRuins\SpaceRuins\turretedoutpost.dmm"
+ #include "map_files\RandomRuins\SpaceRuins\way_home.dmm"
+
+ // Shuttle Templates
+ #include "map_files\shuttles\cargo_base.dmm"
+ #include "map_files\shuttles\emergency_bar.dmm"
+ #include "map_files\shuttles\emergency_clown.dmm"
+ #include "map_files\shuttles\emergency_cramped.dmm"
+ #include "map_files\shuttles\emergency_cyb.dmm"
+ #include "map_files\shuttles\emergency_dept.dmm"
+ #include "map_files\shuttles\emergency_meta.dmm"
+ #include "map_files\shuttles\emergency_mil.dmm"
+ #include "map_files\shuttles\emergency_narnar.dmm"
+ #include "map_files\shuttles\emergency_old.dmm"
+ #include "map_files\shuttles\ferry_base.dmm"
+ #include "map_files\shuttles\ferry_meat.dmm"
+
+ // Other templates
+ #include "map_files\templates\spacehotel\n_01.dmm"
+ #include "map_files\templates\spacehotel\n_02.dmm"
+ #include "map_files\templates\spacehotel\n_03.dmm"
+ #include "map_files\templates\spacehotel\n_04.dmm"
+ #include "map_files\templates\spacehotel\n_05.dmm"
+ #include "map_files\templates\spacehotel\n_06.dmm"
+ #include "map_files\templates\spacehotel\n_07.dmm"
+ #include "map_files\templates\spacehotel\n_08.dmm"
+ #include "map_files\templates\spacehotel\n_09.dmm"
+ #include "map_files\templates\spacehotel\n_10.dmm"
+ #include "map_files\templates\spacehotel\n_11.dmm"
+ #include "map_files\templates\spacehotel\n_12.dmm"
+ #include "map_files\templates\spacehotel\n_13.dmm"
+ #include "map_files\templates\spacehotel\n_14.dmm"
+ #include "map_files\templates\spacehotel\n_15.dmm"
+ #include "map_files\templates\spacehotel\n_16.dmm"
+ #include "map_files\templates\spacehotel\n_17.dmm"
+ #include "map_files\templates\spacehotel\n_18.dmm"
+ #include "map_files\templates\spacehotel\n_19.dmm"
+
+ #include "map_files\templates\spacehotel\s_01.dmm"
+ #include "map_files\templates\spacehotel\s_02.dmm"
+ #include "map_files\templates\spacehotel\s_03.dmm"
+ #include "map_files\templates\spacehotel\s_04.dmm"
+ #include "map_files\templates\spacehotel\s_05.dmm"
+ #include "map_files\templates\spacehotel\s_06.dmm"
+
+ #include "map_files\templates\light_floor_1.dmm"
+ #include "map_files\templates\light_floor_2.dmm"
+ #include "map_files\templates\light_floor_3.dmm"
+ #include "map_files\templates\medium_shuttle1.dmm"
+ #include "map_files\templates\medium_shuttle2.dmm"
+ #include "map_files\templates\medium_shuttle3.dmm"
+ #include "map_files\templates\shelter_1.dmm"
+ #include "map_files\templates\shelter_2.dmm"
+ #include "map_files\templates\small_asteroid_1.dmm"
+ #include "map_files\templates\small_shuttle_1.dmm"
+
+ // VR maps
+ #include "map_files\vr\blood_and_sand.dmm"
+ #include "map_files\vr\lobby.dmm"
+
+
+ // This is pointless, we don't run the server
+ /*#define MAP_TRANSITION_CONFIG list(AWAY_MISSION = UNAFFECTED,
+ AWAY_MISSION = UNAFFECTED,
+ AWAY_MISSION = UNAFFECTED,
+ AWAY_MISSION = UNAFFECTED,
+ AWAY_MISSION = UNAFFECTED,
+ AWAY_MISSION = UNAFFECTED,
+ AWAY_MISSION = UNAFFECTED,
+ AWAY_MISSION = UNAFFECTED,
+ AWAY_MISSION = UNAFFECTED,
+ AWAY_MISSION = UNAFFECTED)
+
+ #define USING_MAP_DATUM /datum/map*/
+
+#elif !defined(MAP_OVERRIDE)
+ #warn a map has already been included.
+#endif
diff --git a/_maps/test_away_missions.dm b/_maps/test_away_missions.dm
deleted file mode 100644
index 42b068412bd..00000000000
--- a/_maps/test_away_missions.dm
+++ /dev/null
@@ -1,21 +0,0 @@
-// This is for Travis testing. DO NOT SET THIS AS THE GAME'S MAP NORMALLY!
-
-#if !defined(USING_MAP_DATUM)
- #include "map_files\RandomZLevels\beach.dmm"
- #include "map_files\RandomZLevels\moonoutpost19.dmm"
- #include "map_files\RandomZLevels\undergroundoutpost45.dmm"
- #include "map_files\RandomZLevels\academy.dmm"
- #include "map_files\RandomZLevels\blackmarketpackers.dmm"
- #include "map_files\RandomZLevels\spacehotel.dmm"
- #include "map_files\RandomZLevels\stationCollision.dmm"
- #include "map_files\RandomZLevels\wildwest.dmm"
-
- #include "map_files\RandomZLevels\evil_santa.dmm"
-
- #define MAP_TRANSITION_CONFIG list(AWAY_MISSION = UNAFFECTED, AWAY_MISSION = UNAFFECTED, AWAY_MISSION = UNAFFECTED, AWAY_MISSION = UNAFFECTED, AWAY_MISSION = UNAFFECTED, AWAY_MISSION = UNAFFECTED, AWAY_MISSION = UNAFFECTED, AWAY_MISSION = UNAFFECTED, AWAY_MISSION = UNAFFECTED, AWAY_MISSION = UNAFFECTED)
-
- #define USING_MAP_DATUM /datum/map
-
-#elif !defined(MAP_OVERRIDE)
- #warn a map has already been included.
-#endif
diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm
index 1506cd26129..3fcf79fe8d8 100644
--- a/code/ATMOSPHERICS/atmospherics.dm
+++ b/code/ATMOSPHERICS/atmospherics.dm
@@ -7,10 +7,9 @@ Pipelines and other atmospheric objects combine to form pipe_networks
Pipes -> Pipelines
Pipelines + Other Objects -> Pipe network
-
*/
+GLOBAL_DATUM_INIT(pipe_icon_manager, /datum/pipe_icon_manager, new())
/obj/machinery/atmospherics
- auto_init = 0
anchored = 1
layer = 2.4 //under wires with their 2.44
idle_power_usage = 0
@@ -29,15 +28,12 @@ Pipelines + Other Objects -> Pipe network
var/pipe_color
var/obj/item/pipe/stored
var/image/pipe_image
- var/global/datum/pipe_icon_manager/icon_manager
/obj/machinery/atmospherics/New()
if(!armor)
armor = list(melee = 25, bullet = 10, laser = 10, energy = 100, bomb = 0, bio = 100, rad = 100)
..()
SSair.atmos_machinery += src
- if(!icon_manager)
- icon_manager = new()
if(!pipe_color)
pipe_color = color
@@ -45,12 +41,8 @@ Pipelines + Other Objects -> Pipe network
if(!pipe_color_check(pipe_color))
pipe_color = null
- // No need for a tween worldstart roundstart handler - pipenet creation is
- // handled there
-
-/obj/machinery/atmospherics/initialize()
- ..()
+/obj/machinery/atmospherics/proc/atmos_init()
if(can_unwrench)
stored = new(src, make_from = src)
@@ -73,9 +65,9 @@ Pipelines + Other Objects -> Pipe network
pipe_image.plane = HUD_PLANE
/obj/machinery/atmospherics/proc/check_icon_cache(var/safety = 0)
- if(!istype(icon_manager))
+ if(!istype(GLOB.pipe_icon_manager))
if(!safety) //to prevent infinite loops
- icon_manager = new()
+ GLOB.pipe_icon_manager = new()
check_icon_cache(1)
return 0
@@ -91,14 +83,14 @@ Pipelines + Other Objects -> Pipe network
/obj/machinery/atmospherics/proc/add_underlay(var/turf/T, var/obj/machinery/atmospherics/node, var/direction, var/icon_connect_type)
if(node)
if(T.intact && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
- //underlays += icon_manager.get_atmos_icon("underlay_down", direction, color_cache_name(node))
- underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type)
+ //underlays += GLOB.pipe_icon_manager.get_atmos_icon("underlay_down", direction, color_cache_name(node))
+ underlays += GLOB.pipe_icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type)
else
- //underlays += icon_manager.get_atmos_icon("underlay_intact", direction, color_cache_name(node))
- underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type)
+ //underlays += GLOB.pipe_icon_manager.get_atmos_icon("underlay_intact", direction, color_cache_name(node))
+ underlays += GLOB.pipe_icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type)
else
- //underlays += icon_manager.get_atmos_icon("underlay_exposed", direction, pipe_color)
- underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "exposed" + icon_connect_type)
+ //underlays += GLOB.pipe_icon_manager.get_atmos_icon("underlay_exposed", direction, pipe_color)
+ underlays += GLOB.pipe_icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "exposed" + icon_connect_type)
/obj/machinery/atmospherics/proc/update_underlays()
if(check_icon_cache())
@@ -231,10 +223,10 @@ Pipelines + Other Objects -> Pipe network
var/turf/T = loc
level = T.intact ? 2 : 1
add_fingerprint(usr)
- initialize()
+ atmos_init()
var/list/nodes = pipeline_expansion()
for(var/obj/machinery/atmospherics/A in nodes)
- A.initialize()
+ A.atmos_init()
A.addMember(src)
build_network()
@@ -320,11 +312,11 @@ Pipelines + Other Objects -> Pipe network
/obj/machinery/atmospherics/proc/add_underlay_adapter(var/turf/T, var/obj/machinery/atmospherics/node, var/direction, var/icon_connect_type) //modified from add_underlay, does not make exposed underlays
if(node)
if(T.intact && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
- underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type)
+ underlays += GLOB.pipe_icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type)
else
- underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type)
+ underlays += GLOB.pipe_icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type)
else
- underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "retracted" + icon_connect_type)
+ underlays += GLOB.pipe_icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "retracted" + icon_connect_type)
/obj/machinery/atmospherics/singularity_pull(S, current_size)
if(current_size >= STAGE_FIVE)
diff --git a/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm b/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm
index 276ce5e7b6e..c11a0421bda 100644
--- a/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm
@@ -41,7 +41,7 @@
nullifyPipenet(parent2)
return ..()
-/obj/machinery/atmospherics/binary/initialize()
+/obj/machinery/atmospherics/binary/atmos_init()
..()
var/node2_connect = dir
var/node1_connect = turn(dir, 180)
diff --git a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm
index bfffb7cd35d..aebc09cfc7a 100644
--- a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm
@@ -48,7 +48,7 @@
radio_connection = null
return ..()
-/obj/machinery/atmospherics/binary/dp_vent_pump/initialize()
+/obj/machinery/atmospherics/binary/dp_vent_pump/atmos_init()
..()
if(frequency)
set_frequency(frequency)
@@ -90,7 +90,7 @@
else
vent_icon += "[on ? "[pump_direction ? "out" : "in"]" : "off"]"
- overlays += icon_manager.get_atmos_icon("device", , , vent_icon)
+ overlays += GLOB.pipe_icon_manager.get_atmos_icon("device", , , vent_icon)
/obj/machinery/atmospherics/binary/dp_vent_pump/update_underlays()
if(..())
diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm
index e43b052095b..9e845c15a98 100644
--- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm
@@ -16,7 +16,7 @@
var/id = null
var/datum/radio_frequency/radio_connection
-/obj/machinery/atmospherics/binary/passive_gate/initialize()
+/obj/machinery/atmospherics/binary/passive_gate/atmos_init()
..()
if(frequency)
set_frequency(frequency)
diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm
index db0c7144324..118a70c3ecd 100644
--- a/code/ATMOSPHERICS/components/binary_devices/pump.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm
@@ -110,7 +110,7 @@ Thus, the two variables affect pump operation are set in New():
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
return 1
-/obj/machinery/atmospherics/binary/pump/initialize()
+/obj/machinery/atmospherics/binary/pump/atmos_init()
..()
if(frequency)
set_frequency(frequency)
diff --git a/code/ATMOSPHERICS/components/binary_devices/valve.dm b/code/ATMOSPHERICS/components/binary_devices/valve.dm
index 7b566e04fda..1d7805c55b2 100644
--- a/code/ATMOSPHERICS/components/binary_devices/valve.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/valve.dm
@@ -109,7 +109,7 @@
if(frequency)
radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA)
-/obj/machinery/atmospherics/binary/valve/digital/initialize()
+/obj/machinery/atmospherics/binary/valve/digital/atmos_init()
..()
if(frequency)
set_frequency(frequency)
diff --git a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm
index c4dd8adeabb..a64c94e7fc5 100644
--- a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm
@@ -38,7 +38,7 @@ Thus, the two variables affect pump operation are set in New():
on = 1
icon_state = "map_on"
-/obj/machinery/atmospherics/binary/volume_pump/initialize()
+/obj/machinery/atmospherics/binary/volume_pump/atmos_init()
..()
set_frequency(frequency)
diff --git a/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm b/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm
index 1858b685ec0..a1f80916aee 100644
--- a/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm
+++ b/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm
@@ -40,9 +40,9 @@
/datum/omni_port/proc/connect()
if(node)
return
- master.initialize()
+ master.atmos_init()
if(node)
- node.initialize()
+ node.atmos_init()
node.addMember(master)
master.build_network()
diff --git a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm
index 086d2ff799f..0eed9729f87 100644
--- a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm
+++ b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm
@@ -56,7 +56,7 @@
nullifyPipenet(P.parent)
return ..()
-/obj/machinery/atmospherics/omni/initialize()
+/obj/machinery/atmospherics/omni/atmos_init()
..()
for(var/datum/omni_port/P in ports)
if(P.node || P.mode == 0)
@@ -143,11 +143,11 @@
//directional icons are layers 1-4, with the core icon on layer 5
if(core_icon)
- overlays_off[5] = icon_manager.get_atmos_icon("omni", , , core_icon)
- overlays_on[5] = icon_manager.get_atmos_icon("omni", , , core_icon + "_glow")
+ overlays_off[5] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , core_icon)
+ overlays_on[5] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , core_icon + "_glow")
- overlays_error[1] = icon_manager.get_atmos_icon("omni", , , core_icon)
- overlays_error[2] = icon_manager.get_atmos_icon("omni", , , "error")
+ overlays_error[1] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , core_icon)
+ overlays_error[2] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , "error")
/obj/machinery/atmospherics/omni/proc/update_port_icons()
if(!check_icon_cache())
@@ -203,19 +203,19 @@
ic_on += "_filter"
ic_off += "_out"
- ic_on = icon_manager.get_atmos_icon("omni", , , ic_on)
- ic_off = icon_manager.get_atmos_icon("omni", , , ic_off)
+ ic_on = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , ic_on)
+ ic_off = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , ic_off)
var/pipe_state
var/turf/T = get_turf(src)
if(!istype(T))
return
if(T.intact && istype(P.node, /obj/machinery/atmospherics/pipe) && P.node.level == 1 )
- //pipe_state = icon_manager.get_atmos_icon("underlay_down", P.dir, color_cache_name(P.node))
- pipe_state = icon_manager.get_atmos_icon("underlay", P.dir, color_cache_name(P.node), "down")
+ //pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay_down", P.dir, color_cache_name(P.node))
+ pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay", P.dir, color_cache_name(P.node), "down")
else
- //pipe_state = icon_manager.get_atmos_icon("underlay_intact", P.dir, color_cache_name(P.node))
- pipe_state = icon_manager.get_atmos_icon("underlay", P.dir, color_cache_name(P.node), "intact")
+ //pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay_intact", P.dir, color_cache_name(P.node))
+ pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay", P.dir, color_cache_name(P.node), "intact")
return list("on_icon" = ic_on, "off_icon" = ic_off, "pipe_icon" = pipe_state)
diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm
index 427c77e8246..903f917e0c6 100755
--- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm
+++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm
@@ -149,7 +149,7 @@ Filter types:
return 1
-/obj/machinery/atmospherics/trinary/filter/initialize()
+/obj/machinery/atmospherics/trinary/filter/atmos_init()
set_frequency(frequency)
..()
diff --git a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm
index 187b308fa3c..e750256b0df 100644
--- a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm
+++ b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm
@@ -66,7 +66,7 @@
nullifyPipenet(parent3)
return ..()
-/obj/machinery/atmospherics/trinary/initialize()
+/obj/machinery/atmospherics/trinary/atmos_init()
..()
//Mixer:
//1 and 2 is input
diff --git a/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm b/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm
index ad9561fbf1d..9dddf8b06f4 100644
--- a/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm
+++ b/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm
@@ -156,7 +156,7 @@
if(frequency)
radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA)
-/obj/machinery/atmospherics/trinary/tvalve/digital/initialize()
+/obj/machinery/atmospherics/trinary/tvalve/digital/atmos_init()
..()
if(frequency)
set_frequency(frequency)
diff --git a/code/ATMOSPHERICS/components/unary_devices/heat_exchanger.dm b/code/ATMOSPHERICS/components/unary_devices/heat_exchanger.dm
index 496413c881c..58b374578df 100644
--- a/code/ATMOSPHERICS/components/unary_devices/heat_exchanger.dm
+++ b/code/ATMOSPHERICS/components/unary_devices/heat_exchanger.dm
@@ -20,7 +20,7 @@
return
-/obj/machinery/atmospherics/unary/heat_exchanger/initialize()
+/obj/machinery/atmospherics/unary/heat_exchanger/atmos_init()
if(!partner)
var/partner_connect = turn(dir,180)
diff --git a/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm b/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm
index 6028346df6d..fe5b6a0a445 100644
--- a/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm
+++ b/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm
@@ -120,7 +120,7 @@
return 1
-/obj/machinery/atmospherics/unary/outlet_injector/initialize()
+/obj/machinery/atmospherics/unary/outlet_injector/atmos_init()
..()
set_frequency(frequency)
diff --git a/code/ATMOSPHERICS/components/unary_devices/unary_base.dm b/code/ATMOSPHERICS/components/unary_devices/unary_base.dm
index 51b12d39481..4ef7743fc8c 100644
--- a/code/ATMOSPHERICS/components/unary_devices/unary_base.dm
+++ b/code/ATMOSPHERICS/components/unary_devices/unary_base.dm
@@ -22,7 +22,7 @@
nullifyPipenet(parent)
return ..()
-/obj/machinery/atmospherics/unary/initialize()
+/obj/machinery/atmospherics/unary/atmos_init()
..()
for(var/obj/machinery/atmospherics/target in get_step(src, dir))
if(target.initialize_directions & get_dir(target,src))
@@ -43,9 +43,9 @@
node.disconnect(src)
node = null
nullifyPipenet(parent)
- initialize()
+ atmos_init()
if(node)
- node.initialize()
+ node.atmos_init()
node.addMember(src)
build_network()
. = 1
diff --git a/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm b/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm
index 8f76e689eae..99eeb1883ea 100644
--- a/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm
+++ b/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm
@@ -98,7 +98,7 @@
else
vent_icon += "[on ? "[pump_direction ? "out" : "in"]" : "off"]"
- overlays += icon_manager.get_atmos_icon("device", , , vent_icon)
+ overlays += GLOB.pipe_icon_manager.get_atmos_icon("device", , , vent_icon)
update_pipe_image()
@@ -223,7 +223,7 @@
return 1
-/obj/machinery/atmospherics/unary/vent_pump/initialize()
+/obj/machinery/atmospherics/unary/vent_pump/atmos_init()
..()
//some vents work his own special way
diff --git a/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm
index 530dbe1d952..11b1fc0f920 100644
--- a/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm
+++ b/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm
@@ -109,7 +109,7 @@
if(welded)
scrubber_icon = "scrubberweld"
- overlays += icon_manager.get_atmos_icon("device", , , scrubber_icon)
+ overlays += GLOB.pipe_icon_manager.get_atmos_icon("device", , , scrubber_icon)
update_pipe_image()
/obj/machinery/atmospherics/unary/vent_scrubber/update_underlays()
@@ -169,7 +169,7 @@
return 1
-/obj/machinery/atmospherics/unary/vent_scrubber/initialize()
+/obj/machinery/atmospherics/unary/vent_scrubber/atmos_init()
..()
radio_filter_in = frequency==initial(frequency)?(RADIO_FROM_AIRALARM):null
radio_filter_out = frequency==initial(frequency)?(RADIO_TO_AIRALARM):null
diff --git a/code/ATMOSPHERICS/datum_pipeline.dm b/code/ATMOSPHERICS/datum_pipeline.dm
index 0692bf44efd..b4a0cd9ba7b 100644
--- a/code/ATMOSPHERICS/datum_pipeline.dm
+++ b/code/ATMOSPHERICS/datum_pipeline.dm
@@ -57,11 +57,7 @@ var/pipenetwarnings = 10
if(!members.Find(item))
if(item.parent)
- if(pipenetwarnings > 0)
- error("[item.type] added to a pipenet while still having one (pipes leading to the same spot stacking in one turf). Nearby: [item.x], [item.y], [item.z].")
- pipenetwarnings -= 1
- if(pipenetwarnings == 0)
- error("Further messages about pipenets will be suppressed.")
+ log_runtime(EXCEPTION("[item.type] \[\ref[item]] added to a pipenet while still having one ([item.parent]) (pipes leading to the same spot stacking in one turf). Nearby: [item.x], [item.y], [item.z]."))
members += item
possible_expansions += item
@@ -118,15 +114,12 @@ var/pipenetwarnings = 10
qdel(E)
/obj/machinery/atmospherics/proc/addMember(obj/machinery/atmospherics/A)
- return
+ var/datum/pipeline/P = returnPipenet(A)
+ P.addMember(A, src)
/obj/machinery/atmospherics/pipe/addMember(obj/machinery/atmospherics/A)
parent.addMember(A, src)
-/obj/machinery/atmospherics/addMember(obj/machinery/atmospherics/A)
- var/datum/pipeline/P = returnPipenet(A)
- P.addMember(A, src)
-
/datum/pipeline/proc/temporarily_store_air()
//Update individual gas_mixtures by volume ratio
diff --git a/code/ATMOSPHERICS/pipes/cap.dm b/code/ATMOSPHERICS/pipes/cap.dm
index 7691b157857..2552f6e0794 100644
--- a/code/ATMOSPHERICS/pipes/cap.dm
+++ b/code/ATMOSPHERICS/pipes/cap.dm
@@ -61,9 +61,9 @@
alpha = 255
overlays.Cut()
- overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "cap" + icon_connect_type)
+ overlays += GLOB.pipe_icon_manager.get_atmos_icon("pipe", , pipe_color, "cap" + icon_connect_type)
-/obj/machinery/atmospherics/pipe/cap/initialize()
+/obj/machinery/atmospherics/pipe/cap/atmos_init()
..()
for(var/obj/machinery/atmospherics/target in get_step(src, dir))
if(target.initialize_directions & get_dir(target,src))
diff --git a/code/ATMOSPHERICS/pipes/manifold.dm b/code/ATMOSPHERICS/pipes/manifold.dm
index a42903bb7f6..199942e7a40 100644
--- a/code/ATMOSPHERICS/pipes/manifold.dm
+++ b/code/ATMOSPHERICS/pipes/manifold.dm
@@ -32,7 +32,7 @@
if(WEST)
initialize_directions = NORTH|EAST|SOUTH
-/obj/machinery/atmospherics/pipe/manifold/initialize()
+/obj/machinery/atmospherics/pipe/manifold/atmos_init()
..()
for(var/D in cardinal)
if(D == dir)
@@ -122,8 +122,8 @@
alpha = 255
overlays.Cut()
- overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "core" + icon_connect_type)
- overlays += icon_manager.get_atmos_icon("manifold", , , "clamps" + icon_connect_type)
+ overlays += GLOB.pipe_icon_manager.get_atmos_icon("manifold", , pipe_color, "core" + icon_connect_type)
+ overlays += GLOB.pipe_icon_manager.get_atmos_icon("manifold", , , "clamps" + icon_connect_type)
underlays.Cut()
var/turf/T = get_turf(src)
diff --git a/code/ATMOSPHERICS/pipes/manifold4w.dm b/code/ATMOSPHERICS/pipes/manifold4w.dm
index 46b883db62b..502795e1da9 100644
--- a/code/ATMOSPHERICS/pipes/manifold4w.dm
+++ b/code/ATMOSPHERICS/pipes/manifold4w.dm
@@ -95,8 +95,8 @@
alpha = 255
overlays.Cut()
- overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "4way" + icon_connect_type)
- overlays += icon_manager.get_atmos_icon("manifold", , , "clamps_4way" + icon_connect_type)
+ overlays += GLOB.pipe_icon_manager.get_atmos_icon("manifold", , pipe_color, "4way" + icon_connect_type)
+ overlays += GLOB.pipe_icon_manager.get_atmos_icon("manifold", , , "clamps_4way" + icon_connect_type)
underlays.Cut()
var/turf/T = get_turf(src)
@@ -134,7 +134,7 @@
if(level == 1 && istype(loc, /turf/simulated))
invisibility = i ? 101 : 0
-/obj/machinery/atmospherics/pipe/manifold4w/initialize()
+/obj/machinery/atmospherics/pipe/manifold4w/atmos_init()
..()
for(var/D in cardinal)
for(var/obj/machinery/atmospherics/target in get_step(src, D))
diff --git a/code/ATMOSPHERICS/pipes/simple/pipe_simple.dm b/code/ATMOSPHERICS/pipes/simple/pipe_simple.dm
index 9f360f74274..b2c2750a452 100644
--- a/code/ATMOSPHERICS/pipes/simple/pipe_simple.dm
+++ b/code/ATMOSPHERICS/pipes/simple/pipe_simple.dm
@@ -43,7 +43,7 @@
if(SOUTHWEST)
initialize_directions = SOUTH|WEST
-/obj/machinery/atmospherics/pipe/simple/initialize(initPipe = 1)
+/obj/machinery/atmospherics/pipe/simple/atmos_init(initPipe = 1)
..()
if(initPipe)
normalize_dir()
@@ -145,9 +145,9 @@
overlays.Cut()
if(node1 && node2)
- overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, pipe_icon + "intact" + icon_connect_type)
+ overlays += GLOB.pipe_icon_manager.get_atmos_icon("pipe", , pipe_color, pipe_icon + "intact" + icon_connect_type)
else
- overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, pipe_icon + "exposed[node1?1:0][node2?1:0]" + icon_connect_type)
+ overlays += GLOB.pipe_icon_manager.get_atmos_icon("pipe", , pipe_color, pipe_icon + "exposed[node1?1:0][node2?1:0]" + icon_connect_type)
// A check to make sure both nodes exist - self-delete if they aren't present
/obj/machinery/atmospherics/pipe/simple/check_nodes_exist()
diff --git a/code/ATMOSPHERICS/pipes/simple/pipe_simple_he.dm b/code/ATMOSPHERICS/pipes/simple/pipe_simple_he.dm
index 26139b40606..cb7ec277f95 100644
--- a/code/ATMOSPHERICS/pipes/simple/pipe_simple_he.dm
+++ b/code/ATMOSPHERICS/pipes/simple/pipe_simple_he.dm
@@ -61,7 +61,7 @@
initialize_directions_he = initialize_directions // The auto-detection from /pipe is good enough for a simple HE pipe
color = "#404040"
-/obj/machinery/atmospherics/pipe/simple/heat_exchanging/initialize(initPipe = 1)
+/obj/machinery/atmospherics/pipe/simple/heat_exchanging/atmos_init(initPipe = 1)
..(0)
if(initPipe)
normalize_dir()
@@ -110,7 +110,7 @@
initialize_directions = EAST
initialize_directions_he = WEST
-/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/initialize()
+/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/atmos_init()
..(0)
for(var/obj/machinery/atmospherics/target in get_step(src,initialize_directions))
if(target.initialize_directions & get_dir(target,src))
diff --git a/code/ATMOSPHERICS/pipes/simple/pipe_simple_hidden.dm b/code/ATMOSPHERICS/pipes/simple/pipe_simple_hidden.dm
index db62f8e51fe..3efd22ed446 100644
--- a/code/ATMOSPHERICS/pipes/simple/pipe_simple_hidden.dm
+++ b/code/ATMOSPHERICS/pipes/simple/pipe_simple_hidden.dm
@@ -34,7 +34,7 @@
alpha = 255
overlays.Cut()
- overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "universal")
+ overlays += GLOB.pipe_icon_manager.get_atmos_icon("pipe", , pipe_color, "universal")
underlays.Cut()
if(node1)
diff --git a/code/ATMOSPHERICS/pipes/simple/pipe_simple_visible.dm b/code/ATMOSPHERICS/pipes/simple/pipe_simple_visible.dm
index 1fcb45e7959..9bf085b534a 100644
--- a/code/ATMOSPHERICS/pipes/simple/pipe_simple_visible.dm
+++ b/code/ATMOSPHERICS/pipes/simple/pipe_simple_visible.dm
@@ -45,7 +45,7 @@
alpha = 255
overlays.Cut()
- overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "universal")
+ overlays += GLOB.pipe_icon_manager.get_atmos_icon("pipe", , pipe_color, "universal")
underlays.Cut()
if(node1)
diff --git a/code/_DATASTRUCTURES/linked_lists.dm b/code/_DATASTRUCTURES/linked_lists.dm
deleted file mode 100644
index eccc3c422a8..00000000000
--- a/code/_DATASTRUCTURES/linked_lists.dm
+++ /dev/null
@@ -1,191 +0,0 @@
-
-//Ok so it's technically a double linked list, bite me.
-
-/datum/linked_list
- var/datum/linked_node/head
- var/datum/linked_node/tail
- var/node_amt = 0
-
-
-/datum/linked_node
- var/value = null
- var/datum/linked_list/linked_list = null
- var/datum/linked_node/next_node = null
- var/datum/linked_node/previous_node = null
-
-
-/datum/linked_list/proc/IsEmpty()
- . = (node_amt <= 0)
-
-
-//Add a linked_node (or value, creating a linked_node) at position
-//the added node BECOMES the position-th element,
-//eg: add("Test",5), the 5th node is now "Test", the previous 5th moves up to become the 6th
-/datum/linked_list/proc/Add(node, position)
- var/datum/linked_node/adding
- if(istype(node, /datum/linked_node))
- adding = node
- else
- adding = new()
- adding.value = node
-
- if(!adding.linked_list || (adding.linked_list && (adding.linked_list != src)))
- node_amt++
-
- adding.linked_list = src
-
- if(position && position < node_amt)
- //Replacing head
- if(position == 1)
- if(head)
- head.previous_node = adding
- adding.next_node = head
- head = adding
-
- //Replacing any middle node
- else
- var/location = 0
- var/datum/linked_node/at
- while((location != position) && (location <= node_amt))
- if(at)
- if(at.next_node)
- at = at.next_node
- else
- break
- else
- at = head
- location++
-
- //Push at up and assume it's place as the position-th element
- if(at && at.previous_node)
- at.previous_node.next_node = adding
- adding.previous_node = at.previous_node
- at.previous_node = adding
- adding.next_node = at
- return
-
- //Replacing tail
- if(tail)
- tail.next_node = adding
- adding.previous_node = tail
- if(!tail.previous_node)
- head = tail
- tail = adding
-
-
-
-//Remove a linked_node or the linked_node of a value
-//If you specify a value the FIRST ONE is removed
-/datum/linked_list/proc/Remove(node)
- var/datum/linked_node/removing
- if(istype(node,/datum/linked_node))
- removing = node
- else
- //optimise removing head and tail, no point looping for them, especially the tail
- if(removing == head)
- removing = head
- else if(removing == tail)
- removing = tail
- else
- var/location = 1
- var/current_value = null
- var/datum/linked_node/at = null
- while((current_value != node) && (location <= node_amt))
- if(at)
- if(at.next_node)
- at = at.next_node
- else
- at = head
- location++
- if(at)
- current_value = at.value
- if(current_value == node)
- removing = at
- break
-
- //Adjust pointers of where removing -was- in the chain.
- if(removing)
- if(removing.previous_node)
- if(removing == tail)
- tail = removing.previous_node
- if(removing.next_node)
- if(removing == head)
- head = removing.next_node
- removing.next_node.previous_node = removing.previous_node
- removing.previous_node.next_node = removing.next_node
- else
- removing.previous_node.next_node = null
- else
- if(removing.next_node)
- if(removing == head)
- head = removing.next_node
- removing.next_node.previous_node = null
-
- //if this is still true at this point, there's no more nodes to replace them with
- if(removing == head)
- head = null
- if(removing == tail)
- tail = null
-
- removing.next_node = null
- removing.previous_node = null
- if(removing.linked_list == src)
- node_amt--
- removing.linked_list = null
-
- return removing
- return 0
-
-
-//Removes and deletes a node or value
-/datum/linked_list/proc/RemoveDelete(node)
- var/datum/linked_node/dead = Remove(node)
- if(dead)
- qdel(dead)
- return 1
- return 0
-
-
-//Empty the linked_list, deleting all nodes
-/datum/linked_list/proc/Empty()
- var/datum/linked_node/n = head
- while(n)
- var/next = n.next_node
- Remove(n)
- qdel(n)
- n = next
- node_amt = 0
-
-
-//Some debugging tools
-/datum/linked_list/proc/CheckNodeLinks()
- var/datum/linked_node/n = head
- while(n)
- . = "|[n.value]|"
- if(n.previous_node)
- . = "[n.previous_node.value]<-" + .
- if(n.next_node)
- . += "->[n.next_node.value]"
- n = n.next_node
- . += "
"
-
-
-/datum/linked_list/proc/DrawNodeLinks()
- . = "|<-"
- var/datum/linked_node/n = head
- while(n)
- if(n.previous_node)
- . += "<-"
- . += "[n.value]"
- if(n.next_node)
- . += "->"
- n = n.next_node
- . += "->|"
-
-
-/datum/linked_list/proc/ToList()
- . = list()
- var/datum/linked_node/n = head
- while(n)
- . += n
- n = n.next_node
\ No newline at end of file
diff --git a/code/_DATASTRUCTURES/priority_queue.dm b/code/_DATASTRUCTURES/priority_queue.dm
deleted file mode 100644
index 8689a19f4e4..00000000000
--- a/code/_DATASTRUCTURES/priority_queue.dm
+++ /dev/null
@@ -1,83 +0,0 @@
-
-//////////////////////
-//PriorityQueue object
-//////////////////////
-
-//an ordered list, using the cmp proc to weight the list elements
-/PriorityQueue
- var/list/L //the actual queue
- var/cmp //the weight function used to order the queue
-
-/PriorityQueue/New(compare)
- L = new()
- cmp = compare
-
-/PriorityQueue/proc/IsEmpty()
- return !L.len
-
-//return the index the element should be in the priority queue using dichotomic search
-/PriorityQueue/proc/FindElementIndex(atom/A)
- var/i = 1
- var/j = L.len
- var/mid
-
- while(i < j)
- mid = round((i+j)/2)
-
- if(call(cmp)(L[mid],A) < 0)
- i = mid + 1
- else
- j = mid
-
- if(i == 1 || i == L.len) //edge cases
- return (call(cmp)(L[i],A) > 0) ? i : i+1
- else
- return i
-
-
-//add an element in the list,
-//immediatly ordering it to its position using dichotomic search
-/PriorityQueue/proc/Enqueue(atom/A)
- if(!L.len)
- L.Add(A)
- return
-
- L.Insert(FindElementIndex(A),A)
-
-//removes and returns the first element in the queue
-/PriorityQueue/proc/Dequeue()
- if(!L.len)
- return 0
- . = L[1]
-
- Remove(.)
-
-//removes an element
-/PriorityQueue/proc/Remove(atom/A)
- return L.Remove(A)
-
-//returns a copy of the elements list
-/PriorityQueue/proc/List()
- . = L.Copy()
-
-//return the position of an element or 0 if not found
-/PriorityQueue/proc/Seek(atom/A)
- . = L.Find(A)
-
-//return the element at the i_th position
-/PriorityQueue/proc/Get(i)
- if(i > L.len || i < 1)
- return 0
- return L[i]
-
-//replace the passed element at it's right position using the cmp proc
-/PriorityQueue/proc/ReSort(atom/A)
- var/i = Seek(A)
- if(i == 0)
- return
- while(i < L.len && call(cmp)(L[i],L[i+1]) > 0)
- L.Swap(i,i+1)
- i++
- while(i > 1 && call(cmp)(L[i],L[i-1]) <= 0) //last inserted element being first in case of ties (optimization)
- L.Swap(i,i-1)
- i--
\ No newline at end of file
diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/code/__DEFINES/clothing.dm b/code/__DEFINES/clothing.dm
index 69561ee97ef..f7fe5b8b28e 100644
--- a/code/__DEFINES/clothing.dm
+++ b/code/__DEFINES/clothing.dm
@@ -90,6 +90,6 @@
#define ONESIZEFITSALL 1 // determines if something can be worn by a fatty or not.
//flags for muzzle speech blocking
-#define MUTE_NONE 0 // Does not mute you.
-#define MUTE_MUFFLE 1 // Muffles everything you say "MHHPHHMMM!!!
-#define MUTE_ALL 2 // Completely mutes you.
\ No newline at end of file
+#define MUZZLE_MUTE_NONE 0 // Does not mute you.
+#define MUZZLE_MUTE_MUFFLE 1 // Muffles everything you say "MHHPHHMMM!!!
+#define MUZZLE_MUTE_ALL 2 // Completely mutes you.
\ No newline at end of file
diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm
index 8b7f4830c13..4c2708bf9dd 100644
--- a/code/__DEFINES/combat.dm
+++ b/code/__DEFINES/combat.dm
@@ -64,6 +64,17 @@
#define THROWN_PROJECTILE_ATTACK 4
#define LEAP_ATTACK 5
+//attack visual effects
+#define ATTACK_EFFECT_PUNCH "punch"
+#define ATTACK_EFFECT_KICK "kick"
+#define ATTACK_EFFECT_SMASH "smash"
+#define ATTACK_EFFECT_CLAW "claw"
+#define ATTACK_EFFECT_DISARM "disarm"
+#define ATTACK_EFFECT_BITE "bite"
+#define ATTACK_EFFECT_MECHFIRE "mech_fire"
+#define ATTACK_EFFECT_MECHTOXIN "mech_toxin"
+#define ATTACK_EFFECT_BOOP "boop" //Honk
+
//Embedded objects
#define EMBEDDED_PAIN_CHANCE 15 //Chance for embedded objects to cause pain (damage user)
#define EMBEDDED_ITEM_FALLOUT 5 //Chance for embedded object to fall out (causing pain but removing the object)
diff --git a/code/__DEFINES/construction.dm b/code/__DEFINES/construction.dm
index 9d8ca0b3013..fa62fd7af4f 100644
--- a/code/__DEFINES/construction.dm
+++ b/code/__DEFINES/construction.dm
@@ -18,6 +18,11 @@
#define RWALL_SUPPORT_RODS 5
#define RWALL_SHEATH 6
+//window construction states
+#define WINDOW_OUT_OF_FRAME 0
+#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
@@ -32,6 +37,9 @@
//windows affected by nar-sie turn this color.
#define NARSIE_WINDOW_COLOUR "#7D1919"
+//let's just pretend fulltile windows being children of border windows is fine
+#define FULLTILE_WINDOW_DIR NORTHEAST
+
//Material defines, for determining how much of a given material an item contains
#define MAT_METAL "$metal"
#define MAT_GLASS "$glass"
diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm
index 5bc8ab5f5de..2862010d316 100644
--- a/code/__DEFINES/is_helpers.dm
+++ b/code/__DEFINES/is_helpers.dm
@@ -26,6 +26,16 @@ var/list/static/global/pointed_types = typecacheof(list(
#define is_pointed(W) (is_type_in_typecache(W, pointed_types))
+GLOBAL_LIST_INIT(glass_sheet_types, typecacheof(list(
+ /obj/item/stack/sheet/glass,
+ /obj/item/stack/sheet/rglass,
+ /obj/item/stack/sheet/plasmaglass,
+ /obj/item/stack/sheet/plasmarglass,
+ /obj/item/stack/sheet/titaniumglass,
+ /obj/item/stack/sheet/plastitaniumglass)))
+
+#define is_glass_sheet(O) (is_type_in_typecache(O, GLOB.glass_sheet_types))
+
//Turfs
#define issimulatedturf(A) istype(A, /turf/simulated)
@@ -41,6 +51,29 @@ var/list/static/global/pointed_types = typecacheof(list(
#define ismineralturf(A) istype(A, /turf/simulated/mineral)
+//Mobs
+#define isliving(A) (istype(A, /mob/living))
+
+#define isbrain(A) (istype(A, /mob/living/carbon/brain))
+
+//Carbon mobs
+#define iscarbon(A) (istype(A, /mob/living/carbon))
+
+#define ishuman(A) (istype(A, /mob/living/carbon/human))
+
+//more carbon mobs
+#define isalien(A) (istype(A, /mob/living/carbon/alien))
+
+#define islarva(A) (istype(A, /mob/living/carbon/alien/larva))
+
+#define isalienadult(A) (istype(A, /mob/living/carbon/alien/humanoid))
+
+#define isalienhunter(A) (istype(A, /mob/living/carbon/alien/humanoid/hunter))
+
+#define isaliensentinel(A) (istype(A, /mob/living/carbon/alien/humanoid/sentinel))
+
+#define isslime(A) (istype((A), /mob/living/carbon/slime))
+
// Misc
#define isclient(A) istype(A, /client)
#define isradio(A) istype(A, /obj/item/radio)
diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm
index 8ec06dbcbd4..58e2be31b01 100644
--- a/code/__DEFINES/layers.dm
+++ b/code/__DEFINES/layers.dm
@@ -7,6 +7,7 @@
#define PLANE_SPACE_PARALLAX -90
#define GAME_PLANE 0
+#define SPACE_LAYER 1.8
//#define TURF_LAYER 2 //For easy recordkeeping; this is a byond define
#define MID_TURF_LAYER 2.02
#define HIGH_TURF_LAYER 2.03
diff --git a/code/__DEFINES/lighting.dm b/code/__DEFINES/lighting.dm
index b23c5699e4b..3db7c467c24 100644
--- a/code/__DEFINES/lighting.dm
+++ b/code/__DEFINES/lighting.dm
@@ -2,7 +2,6 @@
#define LIGHTING_LAMBERTIAN 0 // use lambertian shading for light sources
#define LIGHTING_HEIGHT 1 // height off the ground of light sources on the pseudo-z-axis, you should probably leave this alone
-#define LIGHTING_LAYER 10 // drawing layer for lighting overlays
#define LIGHTING_ICON 'icons/effects/lighting_overlay.dmi' // icon used for lighting shading effects
#define LIGHTING_ROUND_VALUE (1 / 128) //Value used to round lumcounts, values smaller than 1/255 don't matter (if they do, thanks sinking points), greater values will make lighting less precise, but in turn increase performance, VERY SLIGHTLY.
diff --git a/code/__DEFINES/math.dm b/code/__DEFINES/math.dm
index c6ffc61495e..3f360d5bad7 100644
--- a/code/__DEFINES/math.dm
+++ b/code/__DEFINES/math.dm
@@ -32,6 +32,8 @@
#define ToDegrees(radians) ((radians) * 57.2957795) // 180 / Pi
#define ToRadians(degrees) ((degrees) * 0.0174532925) // Pi / 180
+#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
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index 4f38a183a80..6e489098c29 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -200,7 +200,7 @@
#define MARKINGS_LAYER 4
#define UNDERWEAR_LAYER 5
#define MUTATIONS_LAYER 6
-#define DAMAGE_LAYER 7
+#define H_DAMAGE_LAYER 7
#define UNIFORM_LAYER 8
#define ID_LAYER 9
#define SHOES_LAYER 10
@@ -328,7 +328,6 @@
#define SECOND_DIAG_STEP 2
#define ARBITRARY_VIEWRANGE_NOHUD 2
-#define SECOND_DIAG_STEP 2
//Bloody shoes/footprints
#define MAX_SHOE_BLOODINESS 100
@@ -344,5 +343,18 @@
//for obj explosion block calculation
#define EXPLOSION_BLOCK_PROC -1
+#define INVESTIGATE_BOMB "bombs"
+
// The SQL version required by this version of the code
-#define SQL_VERSION 2
+#define SQL_VERSION 3
+
+// Vending machine stuff
+#define CAT_NORMAL 1
+#define CAT_HIDDEN 2
+#define CAT_COIN 4
+
+// Jobs
+// used for alternate_option
+#define GET_RANDOM_JOB 0
+#define BE_ASSISTANT 1
+#define RETURN_TO_LOBBY 2
diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index 5bf38e54ad8..efe8a4aac86 100644
--- a/code/__DEFINES/mobs.dm
+++ b/code/__DEFINES/mobs.dm
@@ -128,15 +128,6 @@
#define TINT_BLIND 3 //Threshold of tint level to obscure vision fully
#define EYE_SHINE_THRESHOLD 6 //dark_view threshold past which a humanoid's eyes will 'shine' in the dark.
-#define isliving(A) (istype((A), /mob/living))
-#define iscarbon(A) (istype((A), /mob/living/carbon))
-#define ishuman(A) (istype((A), /mob/living/carbon/human))
-#define isbrain(A) (istype((A), /mob/living/carbon/brain))
-#define isalien(A) (istype((A), /mob/living/carbon/alien))
-#define isalienadult(A) (istype((A), /mob/living/carbon/alien/humanoid))
-#define islarva(A) (istype((A), /mob/living/carbon/alien/larva))
-#define isslime(A) (istype((A), /mob/living/carbon/slime))
-
//Human sub-species
#define isabductor(A) (is_species(A, "Abductor"))
diff --git a/code/__DEFINES/qdel.dm b/code/__DEFINES/qdel.dm
index 14fd6ea0e36..8d504edaf41 100644
--- a/code/__DEFINES/qdel.dm
+++ b/code/__DEFINES/qdel.dm
@@ -22,11 +22,4 @@
#define QDELING(X) (X.gc_destroyed)
#define QDELETED(X) (!X || QDELING(X))
-#define QDESTROYING(X) (!X || X.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
-
-/proc/check_datum_qdeleted(datum/D) //for checking if something is a datum, first, then checking gc_destroyed; get rid of this eventually. TO-DO
- if(!istype(D))
- return FALSE
- if(D.gc_destroyed)
- return TRUE
- return FALSE
\ No newline at end of file
+#define QDESTROYING(X) (!X || X.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
\ No newline at end of file
diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm
index 257e12f4093..adb645fe112 100644
--- a/code/__DEFINES/role_preferences.dm
+++ b/code/__DEFINES/role_preferences.dm
@@ -40,6 +40,7 @@
#define ROLE_NYMPH "Dionaea"
#define ROLE_GSPIDER "giant spider"
#define ROLE_DRONE "drone"
+#define ROLE_DEATHSQUAD "deathsquad"
//Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR.
//The gamemode specific ones are just so the gamemodes can query whether a player is old enough
diff --git a/code/__HELPERS/cmp.dm b/code/__HELPERS/cmp.dm
index 4b97b67e27e..0db57b27eae 100644
--- a/code/__HELPERS/cmp.dm
+++ b/code/__HELPERS/cmp.dm
@@ -31,6 +31,9 @@
/proc/cmp_subsystem_priority(datum/controller/subsystem/a, datum/controller/subsystem/b)
return a.priority - b.priority
+/proc/cmp_timer(datum/timedevent/a, datum/timedevent/b)
+ return a.timeToRun - b.timeToRun
+
/proc/cmp_qdel_item_time(datum/qdel_item/A, datum/qdel_item/B)
. = B.hard_delete_time - A.hard_delete_time
if(!.)
diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index 2004b9d3159..5c483b310fe 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -435,7 +435,7 @@
/proc/SecondsToTicks(var/seconds)
return seconds * 10
-proc/pollCandidates(Question, be_special_type, antag_age_check = 0, poll_time = 300, ignore_respawnability = 0, min_hours = 0, flashwindow = TRUE)
+proc/pollCandidates(Question, be_special_type, antag_age_check = 0, poll_time = 300, ignore_respawnability = 0, min_hours = 0, flashwindow = TRUE, check_antaghud = TRUE)
var/roletext = be_special_type ? get_roletext(be_special_type) : null
var/list/mob/dead/observer/candidates = list()
var/time_passed = world.time
@@ -457,7 +457,7 @@ proc/pollCandidates(Question, be_special_type, antag_age_check = 0, poll_time =
if(config.use_exp_restrictions && min_hours)
if(G.client.get_exp_living_num() < min_hours * 60)
continue
- if(cannotPossess(G))
+ if(check_antaghud && cannotPossess(G))
continue
spawn(0)
G << 'sound/misc/notice2.ogg'//Alerting them to their consideration
@@ -490,6 +490,20 @@ proc/pollCandidates(Question, be_special_type, antag_age_check = 0, poll_time =
return candidates
+/proc/pollCandidatesByKeyWithVeto(adminclient, adminusr, max_slots, Question, be_special_type, antag_age_check = 0, poll_time = 300, ignore_respawnability = 0, min_hours = 0, flashwindow = TRUE, check_antaghud = TRUE)
+ var/list/willing_ghosts = pollCandidates(Question, be_special_type, antag_age_check, poll_time, ignore_respawnability, min_hours, flashwindow, check_antaghud)
+ var/list/candidate_ckeys = list()
+ var/list/selected_ckeys = list()
+ if(!willing_ghosts.len)
+ return selected_ckeys
+ for(var/mob/dead/observer/G in willing_ghosts)
+ candidate_ckeys += G.key
+ for(var/i = max_slots, (i > 0 && candidate_ckeys.len), i--)
+ var/this_ckey = input("Pick players. This will go on until there either no more ghosts to pick from or the slots are full.", "Candidates") as null|anything in candidate_ckeys
+ candidate_ckeys -= this_ckey
+ selected_ckeys += this_ckey
+ return selected_ckeys
+
/proc/window_flash(client/C)
if(ismob(C))
var/mob/M = C
diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index 7f7b9715907..a8a6307e70c 100644
--- a/code/__HELPERS/mobs.dm
+++ b/code/__HELPERS/mobs.dm
@@ -255,8 +255,8 @@ This is always put in the attack log.
add_attack_logs(user, M, what_done, admin_notify)
return
- var/user_str = key_name(user)
- var/target_str = key_name(target)
+ var/user_str = key_name_log(user)
+ var/target_str = key_name_log(target)
if(istype(user))
user.create_attack_log("Attacked [target_str]: [what_done]")
@@ -478,4 +478,17 @@ This is always put in the attack log.
/proc/update_all_mob_security_hud()
for(var/mob/living/carbon/human/H in mob_list)
- H.sec_hud_set_security_status()
\ No newline at end of file
+ H.sec_hud_set_security_status()
+
+/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/__HELPERS/pronouns.dm b/code/__HELPERS/pronouns.dm
new file mode 100644
index 00000000000..607ba3495d3
--- /dev/null
+++ b/code/__HELPERS/pronouns.dm
@@ -0,0 +1,224 @@
+//pronoun procs, for getting pronouns without using the text macros that only work in certain positions
+//datums don't have gender, but most of their subtypes do!
+/datum/proc/p_they(capitalized, temp_gender)
+ . = "it"
+ if(capitalized)
+ . = capitalize(.)
+
+/datum/proc/p_their(capitalized, temp_gender)
+ . = "its"
+ if(capitalized)
+ . = capitalize(.)
+
+/datum/proc/p_them(capitalized, temp_gender)
+ . = "it"
+ if(capitalized)
+ . = capitalize(.)
+
+/datum/proc/p_have(temp_gender)
+ . = "has"
+
+/datum/proc/p_are(temp_gender)
+ . = "is"
+
+/datum/proc/p_were(temp_gender)
+ . = "was"
+
+/datum/proc/p_do(temp_gender)
+ . = "does"
+
+/datum/proc/p_theyve(capitalized, temp_gender)
+ . = p_they(capitalized, temp_gender) + "'" + copytext(p_have(temp_gender), 3)
+
+/datum/proc/p_theyre(capitalized, temp_gender)
+ . = p_they(capitalized, temp_gender) + "'" + copytext(p_are(temp_gender), 2)
+
+// For help conjugating verbs, eg they look, but she looks
+/datum/proc/p_s(temp_gender)
+ . = "s"
+
+/datum/proc/p_es(temp_gender)
+ . = p_s(temp_gender)
+ if(.)
+ . = "e[.]"
+
+//like clients, which do have gender.
+/client/proc/p_they(capitalized, temp_gender)
+ if(!temp_gender)
+ temp_gender = gender
+ . = "they"
+ switch(temp_gender)
+ if(FEMALE)
+ . = "she"
+ if(MALE)
+ . = "he"
+ if(capitalized)
+ . = capitalize(.)
+
+/client/proc/p_their(capitalized, temp_gender)
+ if(!temp_gender)
+ temp_gender = gender
+ . = "their"
+ switch(temp_gender)
+ if(FEMALE)
+ . = "her"
+ if(MALE)
+ . = "his"
+ if(capitalized)
+ . = capitalize(.)
+
+/client/proc/p_them(capitalized, temp_gender)
+ if(!temp_gender)
+ temp_gender = gender
+ . = "them"
+ switch(temp_gender)
+ if(FEMALE)
+ . = "her"
+ if(MALE)
+ . = "him"
+ if(capitalized)
+ . = capitalize(.)
+
+/client/proc/p_have(temp_gender)
+ if(!temp_gender)
+ temp_gender = gender
+ . = "has"
+ if(temp_gender == PLURAL || temp_gender == NEUTER)
+ . = "have"
+
+/client/proc/p_are(temp_gender)
+ if(!temp_gender)
+ temp_gender = gender
+ . = "is"
+ if(temp_gender == PLURAL || temp_gender == NEUTER)
+ . = "are"
+
+/client/proc/p_were(temp_gender)
+ if(!temp_gender)
+ temp_gender = gender
+ . = "was"
+ if(temp_gender == PLURAL || temp_gender == NEUTER)
+ . = "were"
+
+/client/proc/p_do(temp_gender)
+ if(!temp_gender)
+ temp_gender = gender
+ . = "does"
+ if(temp_gender == PLURAL || temp_gender == NEUTER)
+ . = "do"
+
+/client/proc/p_s(temp_gender)
+ if(!temp_gender)
+ temp_gender = gender
+ if(temp_gender != PLURAL && temp_gender != NEUTER)
+ . = "s"
+
+//mobs(and atoms but atoms don't really matter write your own proc overrides) also have gender!
+/mob/p_they(capitalized, temp_gender)
+ if(!temp_gender)
+ temp_gender = gender
+ . = "it"
+ switch(temp_gender)
+ if(FEMALE)
+ . = "she"
+ if(MALE)
+ . = "he"
+ if(PLURAL)
+ . = "they"
+ if(capitalized)
+ . = capitalize(.)
+
+/mob/p_their(capitalized, temp_gender)
+ if(!temp_gender)
+ temp_gender = gender
+ . = "its"
+ switch(temp_gender)
+ if(FEMALE)
+ . = "her"
+ if(MALE)
+ . = "his"
+ if(PLURAL)
+ . = "their"
+ if(capitalized)
+ . = capitalize(.)
+
+/mob/p_them(capitalized, temp_gender)
+ if(!temp_gender)
+ temp_gender = gender
+ . = "it"
+ switch(temp_gender)
+ if(FEMALE)
+ . = "her"
+ if(MALE)
+ . = "him"
+ if(PLURAL)
+ . = "them"
+ if(capitalized)
+ . = capitalize(.)
+
+/mob/p_have(temp_gender)
+ if(!temp_gender)
+ temp_gender = gender
+ . = "has"
+ if(temp_gender == PLURAL)
+ . = "have"
+
+/mob/p_are(temp_gender)
+ if(!temp_gender)
+ temp_gender = gender
+ . = "is"
+ if(temp_gender == PLURAL)
+ . = "are"
+
+/mob/p_were(temp_gender)
+ if(!temp_gender)
+ temp_gender = gender
+ . = "was"
+ if(temp_gender == PLURAL)
+ . = "were"
+
+/mob/p_do(temp_gender)
+ if(!temp_gender)
+ temp_gender = gender
+ . = "does"
+ if(temp_gender == PLURAL)
+ . = "do"
+
+/mob/p_s(temp_gender)
+ if(!temp_gender)
+ temp_gender = gender
+ if(temp_gender != PLURAL)
+ . = "s"
+
+//humans need special handling, because they can have their gender hidden
+/mob/living/carbon/human/p_they(capitalized, temp_gender)
+ temp_gender = get_visible_gender()
+ return ..()
+
+/mob/living/carbon/human/p_their(capitalized, temp_gender)
+ temp_gender = get_visible_gender()
+ return ..()
+
+/mob/living/carbon/human/p_them(capitalized, temp_gender)
+ temp_gender = get_visible_gender()
+ return ..()
+
+/mob/living/carbon/human/p_have(temp_gender)
+ temp_gender = get_visible_gender()
+ return ..()
+
+/mob/living/carbon/human/p_are(temp_gender)
+ temp_gender = get_visible_gender()
+ return ..()
+
+/mob/living/carbon/human/p_were(temp_gender)
+ temp_gender = get_visible_gender()
+ return ..()
+
+/mob/living/carbon/human/p_do(temp_gender)
+ temp_gender = get_visible_gender()
+ return ..()
+
+/mob/living/carbon/human/p_s(temp_gender)
+ temp_gender = get_visible_gender()
+ return ..()
diff --git a/code/__HELPERS/qdel.dm b/code/__HELPERS/qdel.dm
index 8171dd66427..136e573a25e 100644
--- a/code/__HELPERS/qdel.dm
+++ b/code/__HELPERS/qdel.dm
@@ -1,5 +1,10 @@
-#define QDEL_IN(item, time) addtimer(GLOBAL_PROC, "qdel", time, FALSE, item)
+#define QDEL_IN(item, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, item), time, TIMER_STOPPABLE)
+#define QDEL_IN_CLIENT_TIME(item, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, item), time, TIMER_STOPPABLE | TIMER_CLIENT_TIME)
#define QDEL_NULL(item) if(item) { qdel(item); item = null }
#define QDEL_LIST(L) if(L) { for(var/I in L) qdel(I); L.Cut(); }
+#define QDEL_LIST_IN(L, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/______qdel_list_wrapper, L), time, TIMER_STOPPABLE)
#define QDEL_LIST_ASSOC(L) if(L) { for(var/I in L) { qdel(L[I]); qdel(I); } L.Cut(); }
#define QDEL_LIST_ASSOC_VAL(L) if(L) { for(var/I in L) qdel(L[I]); L.Cut(); }
+
+/proc/______qdel_list_wrapper(list/L) //the underscores are to encourage people not to use this directly.
+ QDEL_LIST(L)
\ No newline at end of file
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index b58ea20dbae..35d271461df 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -170,9 +170,12 @@ Turf and target are seperate in case you want to teleport some distance from a t
// Checks if doors are open
/proc/DirBlocked(turf/loc,var/dir)
for(var/obj/structure/window/D in loc)
- if(!D.density) continue
- if(D.is_fulltile()) return 1
- if(D.dir == dir) return 1
+ if(!D.density)
+ continue
+ if(D.fulltile)
+ return 1
+ if(D.dir == dir)
+ return 1
for(var/obj/machinery/door/D in loc)
if(!D.density)//if the door is open
@@ -394,6 +397,16 @@ Turf and target are seperate in case you want to teleport some distance from a t
moblist.Add(M)
return moblist
+// 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
+ return "[round((powerused * 0.001), 0.01)] kW"
+ else if(powerused < 1000000000) //Less than a GW
+ return "[round((powerused * 0.000001), 0.001)] MW"
+ return "[round((powerused * 0.000000001), 0.0001)] GW"
+
//E = MC^2
/proc/convert2energy(var/M)
var/E = M*(SPEED_OF_LIGHT_SQ)
@@ -1042,6 +1055,8 @@ proc/get_mob_with_client_list()
//Find coordinates
var/turf/T = get_turf(AM) //use AM's turfs, as it's coords are the same as AM's AND AM's coords are lost if it is inside another atom
+ if(!T)
+ return null
var/final_x = T.x + rough_x
var/final_y = T.y + rough_y
@@ -1490,6 +1505,22 @@ var/mob/dview/dview_mob = new
return TRUE
return FALSE
+//can a window be here, or is there a window blocking it?
+/proc/valid_window_location(turf/T, dir_to_check)
+ if(!T)
+ return FALSE
+ for(var/obj/O in T)
+ if(istype(O, /obj/machinery/door/window) && (O.dir == dir_to_check || dir_to_check == FULLTILE_WINDOW_DIR))
+ return FALSE
+ if(istype(O, /obj/structure/windoor_assembly))
+ var/obj/structure/windoor_assembly/W = O
+ if(W.ini_dir == dir_to_check || dir_to_check == FULLTILE_WINDOW_DIR)
+ return FALSE
+ if(istype(O, /obj/structure/window))
+ var/obj/structure/window/W = O
+ if(W.ini_dir == dir_to_check || W.ini_dir == FULLTILE_WINDOW_DIR || dir_to_check == FULLTILE_WINDOW_DIR)
+ return FALSE
+ return TRUE
//Get the dir to the RIGHT of dir if they were on a clock
//NORTH --> NORTHEAST
@@ -1928,4 +1959,7 @@ var/mob/dview/dview_mob = new
CRASH(msg)
/datum/proc/stack_trace(msg)
- CRASH(msg)
\ No newline at end of file
+ CRASH(msg)
+
+/proc/pass()
+ return
\ No newline at end of file
diff --git a/code/_globalvars/configuration.dm b/code/_globalvars/configuration.dm
index d26dc711339..1e35e150a25 100644
--- a/code/_globalvars/configuration.dm
+++ b/code/_globalvars/configuration.dm
@@ -2,6 +2,7 @@ var/datum/configuration/config = null
var/host = null
var/join_motd = null
+GLOBAL_VAR(join_tos)
var/game_version = "Custom ParaCode"
var/changelog_hash = md5('html/changelog.html') //used to check if the CL changed
var/game_year = (text2num(time2text(world.realtime, "YYYY")) + 544)
diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm
index 0cc712799c7..5a025702877 100644
--- a/code/_globalvars/lists/objects.dm
+++ b/code/_globalvars/lists/objects.dm
@@ -1,5 +1,5 @@
var/global/list/portals = list() //for use by portals
-var/global/list/cable_list = list() //Index for all cables, so that powernets don't have to look through the entire world all the time
+GLOBAL_LIST(cable_list) //Index for all cables, so that powernets don't have to look through the entire world all the time
var/global/list/chemical_reactions_list //list of all /datum/chemical_reaction datums. Used during chemical reactions
var/global/list/chemical_reagents_list //list of all /datum/reagent datums indexed by reagent id. Used by chemistry stuff
var/global/list/landmarks_list = list() //list of all landmarks created
@@ -17,7 +17,6 @@ var/global/list/cell_logs = list()
var/global/list/all_areas = list()
var/global/list/machines = list()
-var/global/list/machine_processing = list()
var/global/list/fast_processing = list()
var/global/list/processing_power_items = list() //items that ask to be called every cycle
var/global/list/rcd_list = list() //list of Rapid Construction Devices.
diff --git a/code/_globalvars/logging.dm b/code/_globalvars/logging.dm
index f96e83cb7a1..c48600ca40c 100644
--- a/code/_globalvars/logging.dm
+++ b/code/_globalvars/logging.dm
@@ -10,7 +10,6 @@ GLOBAL_VAR(world_href_log)
GLOBAL_PROTECT(world_href_log)
var/list/jobMax = list()
-var/list/bombers = list( )
var/list/admin_log = list ( )
var/list/lastsignalers = list( ) //keeps last 100 signals here in format: "[src] used \ref[src] @ location [src.loc]: [freq]/[code]"
var/list/lawchanges = list( ) //Stores who uploaded laws to which silicon-based lifeform, and what the law was
@@ -20,4 +19,4 @@ var/list/IClog = list()
var/list/OOClog = list()
var/list/adminlog = list()
-var/list/investigate_log_subjects = list("notes", "watchlist", "hrefs")
\ No newline at end of file
+var/list/investigate_log_subjects = list("notes", "watchlist", "hrefs")
diff --git a/code/_globalvars/station.dm b/code/_globalvars/station.dm
index 6d2578e5b88..2d635996b30 100644
--- a/code/_globalvars/station.dm
+++ b/code/_globalvars/station.dm
@@ -3,11 +3,4 @@ var/global/datum/datacore/data_core = null
var/CELLRATE = 0.002 // multiplier for watts per tick <> cell storage (eg: .002 means if there is a load of 1000 watts, 20 units will be taken from a cell per second)
var/CHARGELEVEL = 0.001 // Cap for how fast cells charge, as a percentage-per-tick (.001 means cellcharge is capped to 1% per second)
-var/list/powernets = list()
-var/list/deferred_powernet_rebuilds = list()
-
-// this is not strictly unused although the whole modules datum thing is unused
-// To remove this you need to remove that
-var/datum/moduletypes/mods = new()
-
var/map_name = "Unknown" //The name of the map that is loaded. Assigned in world/New()
\ No newline at end of file
diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm
index d88ff6201f8..b2521527a98 100644
--- a/code/_onclick/ai.dm
+++ b/code/_onclick/ai.dm
@@ -35,6 +35,17 @@
return
var/turf/pixel_turf = get_turf_pixel(A)
+ if(isnull(pixel_turf))
+ return
+ if(!can_see(A))
+ if(isturf(A)) //On unmodified clients clicking the static overlay clicks the turf underneath
+ return // So there's no point messaging admins
+ message_admins("[key_name_admin(src)] might be running a modified client! (failed can_see on AI click of [A]([ADMIN_COORDJMP(pixel_turf)]))")
+ var/message = "[key_name(src)] might be running a modified client! (failed can_see on AI click of [A]([COORD(pixel_turf)]))"
+ log_admin(message)
+ send2irc_adminless_only("NOCHEAT", "[key_name(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([COORD(pixel_turf)]))")
+
+
var/turf_visible
if(pixel_turf)
turf_visible = cameranet.checkTurfVis(pixel_turf)
@@ -157,9 +168,6 @@
return
/atom/proc/AICtrlClick(var/mob/living/silicon/ai/user)
- if(user.holo)
- var/obj/machinery/hologram/holopad/H = user.holo
- H.face_atom(src)
return
/obj/machinery/door/airlock/AICtrlClick() // Bolts doors
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index f300608e699..9679935bdaa 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -70,6 +70,12 @@
changeNext_click(1)
var/list/modifiers = params2list(params)
+ if(modifiers["middle"] && modifiers["shift"] && modifiers["ctrl"])
+ MiddleShiftControlClickOn(A)
+ return
+ if(modifiers["middle"] && modifiers["shift"])
+ MiddleShiftClickOn(A)
+ return
if(modifiers["shift"] && modifiers["ctrl"])
CtrlShiftClickOn(A)
return
@@ -225,6 +231,32 @@
else
..()
+/*
+ Middle shift-click
+ Makes the mob face the direction of the clicked thing
+*/
+/mob/proc/MiddleShiftClickOn(atom/A)
+ var/face_dir = get_cardinal_dir(src, A)
+ if(forced_look == face_dir)
+ forced_look = null
+ to_chat(src, "You are no longer facing any direction.")
+ return
+ forced_look = face_dir
+ to_chat(src, "You are now facing [dir2text(forced_look)].")
+
+/*
+ Middle shift-control-click
+ Makes the mob constantly face the object (until it's out of sight)
+*/
+/mob/proc/MiddleShiftControlClickOn(atom/A)
+ var/face_uid = A.UID()
+ if(forced_look == face_uid)
+ forced_look = null
+ to_chat(src, "You are no longer facing [A].")
+ return
+ forced_look = face_uid
+ to_chat(src, "You are now facing [A].")
+
// In case of use break glass
/*
/atom/proc/MiddleClick(var/mob/M as mob)
diff --git a/code/_onclick/click_override.dm b/code/_onclick/click_override.dm
index 5fb4757a74f..7dfa8020cb8 100644
--- a/code/_onclick/click_override.dm
+++ b/code/_onclick/click_override.dm
@@ -39,7 +39,7 @@
var/atom/movable/newObject = new summon_path
newObject.loc = get_turf(A)
to_chat(user, "You release the power you had stored up, summoning \a [newObject.name]! ")
- usr.loc.visible_message("[user] waves \his hand and summons \a [newObject.name]")
+ usr.loc.visible_message("[user] waves [user.p_their()] hand and summons \a [newObject.name]")
..()
/datum/middleClickOverride/power_gloves
diff --git a/code/_onclick/hud/movable_screen_objects.dm b/code/_onclick/hud/movable_screen_objects.dm
index 315fce5bf65..668e0e67fc7 100644
--- a/code/_onclick/hud/movable_screen_objects.dm
+++ b/code/_onclick/hud/movable_screen_objects.dm
@@ -11,6 +11,8 @@
/obj/screen/movable
var/snap2grid = FALSE
var/moved = FALSE
+ var/x_off = -16
+ var/y_off = -16
//Snap Screen Object
//Tied to the grid, snaps to the nearest turf
@@ -39,8 +41,8 @@
screen_loc = "[screen_loc_X[1]],[screen_loc_Y[1]]"
else //Normalise Pixel Values (So the object drops at the center of the mouse, not 16 pixels off)
- var/pix_X = text2num(screen_loc_X[2]) - 16
- var/pix_Y = text2num(screen_loc_Y[2]) - 16
+ var/pix_X = text2num(screen_loc_X[2]) + x_off
+ var/pix_Y = text2num(screen_loc_Y[2]) + y_off
screen_loc = "[screen_loc_X[1]]:[pix_X],[screen_loc_Y[1]]:[pix_Y]"
moved = screen_loc
diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm
index 6a658886f83..bf01bca6e3c 100644
--- a/code/_onclick/item_attack.dm
+++ b/code/_onclick/item_attack.dm
@@ -62,8 +62,7 @@
user.lastattacked = M
M.lastattacker = user
- if(user != M)
- user.do_attack_animation(M)
+ user.do_attack_animation(M)
M.attacked_by(src, user, def_zone)
add_attack_logs(user, M, "Attacked with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(damtype)])", admin_notify = (force > 0 && damtype != STAMINA))
diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm
index 87b78259593..dcac994c7c7 100644
--- a/code/_onclick/other_mobs.dm
+++ b/code/_onclick/other_mobs.dm
@@ -12,6 +12,11 @@
if(proximity && istype(G) && G.Touch(A, 1))
return
+ if(HULK in mutations)
+ if(proximity) //no telekinetic hulk attack
+ if(A.attack_hulk(src))
+ return
+
A.attack_hand(src)
/atom/proc/attack_hand(mob/user as mob)
diff --git a/code/controllers/Processes/machinery.dm b/code/controllers/Processes/machinery.dm
deleted file mode 100644
index 2466f802740..00000000000
--- a/code/controllers/Processes/machinery.dm
+++ /dev/null
@@ -1,74 +0,0 @@
-/var/global/machinery_sort_required = 0
-
-/datum/controller/process/machinery/setup()
- name = "machinery"
- schedule_interval = 20 // every 2 seconds
- start_delay = 12
-
-/datum/controller/process/machinery/statProcess()
- ..()
- stat(null, "[machine_processing.len] machines")
- stat(null, "[powernets.len] powernets, [deferred_powernet_rebuilds.len] deferred")
-
-/datum/controller/process/machinery/doWork()
- process_sort()
- process_power()
- process_power_drain()
- process_machines()
-
-/datum/controller/process/machinery/proc/process_sort()
- if(machinery_sort_required)
- machinery_sort_required = 0
- machine_processing = dd_sortedObjectList(machine_processing)
-
-/datum/controller/process/machinery/proc/process_machines()
- for(last_object in machine_processing)
- var/obj/machinery/M = last_object
- if(istype(M) && !QDELETED(M))
- try
- if(M.process() == PROCESS_KILL)
- machine_processing.Remove(M)
- continue
-
- if(M.use_power)
- M.auto_use_power()
- catch(var/exception/e)
- catchException(e, M)
- else
- catchBadType(M)
- machine_processing -= M
-
- SCHECK
-
-/datum/controller/process/machinery/proc/process_power()
- for(last_object in deferred_powernet_rebuilds)
- var/obj/O = last_object
- if(istype(O) && !QDELETED(O))
- try
- var/datum/powernet/newPN = new()// creates a new powernet...
- propagate_network(O, newPN)//... and propagates it to the other side of the cable
- catch(var/exception/e)
- catchException(e, O)
- SCHECK
- else
- catchBadType(O)
- deferred_powernet_rebuilds -= O
-
- for(last_object in powernets)
- var/datum/powernet/powerNetwork = last_object
- if(istype(powerNetwork) && !QDELETED(powerNetwork))
- try
- powerNetwork.reset()
- catch(var/exception/e)
- catchException(e, powerNetwork)
- SCHECK
- else
- catchBadType(powerNetwork)
- powernets -= powerNetwork
-
-/datum/controller/process/machinery/proc/process_power_drain()
- // Currently only used by powersinks. These items get priority processed before machinery
- for(var/obj/item/I in processing_power_items)
- if(!I.pwr_drain()) // 0 = Process Kill, remove from processing list.
- processing_power_items.Remove(I)
- SCHECK
diff --git a/code/controllers/Processes/mob.dm b/code/controllers/Processes/mob.dm
deleted file mode 100644
index 2b11eff99be..00000000000
--- a/code/controllers/Processes/mob.dm
+++ /dev/null
@@ -1,35 +0,0 @@
-var/global/datum/controller/process/mob/mob_master
-
-/datum/controller/process/mob
- var/current_cycle
-
-/datum/controller/process/mob/setup()
- name = "mob"
- schedule_interval = 20 // every 2 seconds
- start_delay = 16
- log_startup_progress("Mob ticker starting up.")
-
-/datum/controller/process/mob/started()
- ..()
- if(!mob_list)
- mob_list = list()
-
-/datum/controller/process/mob/statProcess()
- ..()
- stat(null, "[mob_list.len] mobs")
-
-/datum/controller/process/mob/doWork()
- for(last_object in mob_list)
- var/mob/M = last_object
- if(istype(M) && !QDELETED(M))
- try
- M.Life()
- catch(var/exception/e)
- catchException(e, M)
- SCHECK
- else
- catchBadType(M)
- mob_list -= M
- current_cycle++
-
-DECLARE_GLOBAL_CONTROLLER(mob, mob_master)
diff --git a/code/controllers/Processes/nano_mob_hunter.dm b/code/controllers/Processes/nano_mob_hunter.dm
index fb57b6e0bbf..dc5dcba805b 100644
--- a/code/controllers/Processes/nano_mob_hunter.dm
+++ b/code/controllers/Processes/nano_mob_hunter.dm
@@ -44,7 +44,7 @@ DECLARE_GLOBAL_CONTROLLER(mob_hunt, mob_hunt_server)
recover_time = 3000
if(recover_time > 0) //when provided with a negative or zero valued recover_time argument, the server won't auto-restart but can be manually rebooted still
//set a timer to automatically recover after recover_time has passed (can be manually restarted if you get impatient too)
- addtimer(src, "auto_recover", recover_time, TRUE)
+ addtimer(CALLBACK(src, .proc/auto_recover), recover_time, TIMER_UNIQUE)
/datum/controller/process/mob_hunt/proc/client_mob_update()
var/list/ex_players = list()
diff --git a/code/controllers/Processes/timer.dm b/code/controllers/Processes/timer.dm
deleted file mode 100644
index 4b42d69221d..00000000000
--- a/code/controllers/Processes/timer.dm
+++ /dev/null
@@ -1,100 +0,0 @@
-var/global/datum/controller/process/timer/timer_master
-
-/datum/controller/process/timer
- var/list/processing_timers = list()
- var/list/hashes = list()
-
-/datum/controller/process/timer/setup()
- name = "timer"
- schedule_interval = 1 //every 0.1 seconds--2 server ticks
- log_startup_progress("Timer process starting up.")
-
-/datum/controller/process/timer/statProcess()
- ..()
- stat(null, "[processing_timers.len] timers")
-
-/datum/controller/process/timer/doWork()
- if(!processing_timers.len)
- disabled = 1 //nothing to do, lets stop firing.
- return
- for(last_object in processing_timers)
- var/datum/timedevent/event = last_object
- if(!event.thingToCall || check_datum_qdeleted(event.thingToCall))
- qdel(event)
- if(event.timeToRun <= world.time)
- runevent(event)
- qdel(event)
- SCHECK
-
-DECLARE_GLOBAL_CONTROLLER(timer, timer_master)
-
-/datum/controller/process/timer/proc/runevent(datum/timedevent/event)
- set waitfor = 0
- if(event.thingToCall)
- if(event.thingToCall == GLOBAL_PROC && istext(event.procToCall))
- call("/proc/[event.procToCall]")(arglist(event.argList))
- else
- call(event.thingToCall, event.procToCall)(arglist(event.argList))
-
-/datum/timedevent
- var/thingToCall
- var/procToCall
- var/timeToRun
- var/argList
- var/id
- var/hash
- var/static/nextid = 1
-
-/datum/timedevent/New()
- id = nextid++
-
-/datum/timedevent/Destroy()
- timer_master.processing_timers -= src
- timer_master.hashes -= hash
- return QDEL_HINT_IWILLGC
-
-/proc/addtimer(thingToCall, procToCall, wait, unique = FALSE, ...)
- if(!timer_master) //can't run timers before the mc has been created
- return
- if(!thingToCall || !procToCall)
- return
- if(timer_master.disabled)
- timer_master.disabled = 0
-
- var/datum/timedevent/event = new()
- event.thingToCall = thingToCall
- event.procToCall = procToCall
- event.timeToRun = world.time + wait
- var/hashlist = args.Copy()
-
- hashlist[1] = "[thingToCall](\ref[thingToCall])"
- event.hash = jointext(hashlist, null)
- if(args.len > 4)
- event.argList = args.Copy(5)
-
- // Check for dupes if unique = 1.
- if(unique)
- var/datum/timedevent/hash_event = timer_master.hashes[event.hash]
- if(hash_event)
- return hash_event.id
- timer_master.hashes[event.hash] = event
- if(wait <= 0)
- timer_master.runevent(event)
- timer_master.hashes -= event.hash
- return
- // If we are unique (or we're not checking that), add the timer and return the id.
- timer_master.processing_timers += event
-
- return event.id
-
-/proc/deltimer(id)
- if(id == 0)
- // No event will correspond to an id of 0 - the timer does not exist
- // Save us a possibly expensive iteration through the timer list
- // This would probably be more efficient in general if we used an associative list instead
- return 0
- for(var/datum/timedevent/event in timer_master.processing_timers)
- if(event.id == id)
- qdel(event)
- return 1
- return 0
diff --git a/code/controllers/Processes/weather.dm b/code/controllers/Processes/weather.dm
index 1706b2232c0..919352313c6 100644
--- a/code/controllers/Processes/weather.dm
+++ b/code/controllers/Processes/weather.dm
@@ -37,7 +37,7 @@ var/global/datum/controller/process/weather/weather_master
var/datum/weather/W = pickweight(possible_weather_for_this_z)
run_weather(W.name)
eligible_zlevels -= Z
- addtimer(src, "make_z_eligible", rand(3000, 6000) + W.weather_duration_upper, TRUE, Z) //Around 5-10 minutes between weathers
+ addtimer(CALLBACK(src, .proc/make_z_eligible, Z), rand(3000, 6000) + W.weather_duration_upper, TIMER_UNIQUE) //Around 5-10 minutes between weathers
DECLARE_GLOBAL_CONTROLLER(weather, weather_master)
diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index b71531ee20f..b35bc300434 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -202,6 +202,9 @@
var/randomize_shift_time = FALSE
var/enable_night_shifts = FALSE
+ // Developer
+ var/developer_express_start = 0
+
/datum/configuration/New()
for(var/T in subtypesof(/datum/game_mode))
var/datum/game_mode/M = T
@@ -612,6 +615,8 @@
config.high_pop_mc_mode_amount = text2num(value)
if("disable_high_pop_mc_mode_amount")
config.disable_high_pop_mc_mode_amount = text2num(value)
+ if("developer_express_start")
+ config.developer_express_start = 1
else
log_config("Unknown setting in configuration: '[name]'")
diff --git a/code/controllers/master.dm b/code/controllers/master.dm
index ddde5460cef..9cb84f26aa5 100644
--- a/code/controllers/master.dm
+++ b/code/controllers/master.dm
@@ -54,7 +54,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
var/static/restart_clear = 0
var/static/restart_timeout = 0
var/static/restart_count = 0
-
+
var/static/random_seed
//current tick limit, assigned before running a subsystem.
@@ -62,7 +62,6 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
var/static/current_ticklimit = TICK_LIMIT_RUNNING
/datum/controller/master/New()
- makeDatumRefLists()
//temporary file used to record errors with loading config, moved to log directory once logging is set up
GLOB.config_error_log = GLOB.world_game_log = GLOB.world_runtime_log = "data/logs/config_error.log"
load_configuration()
@@ -71,7 +70,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
if(!random_seed)
random_seed = rand(1, 1e9)
rand_seed(random_seed)
-
+
var/list/_subsystems = list()
subsystems = _subsystems
if(Master != src)
@@ -195,6 +194,9 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
to_chat(world, "[msg]")
log_world(msg)
+ if(config.developer_express_start & ticker.current_state == GAME_STATE_PREGAME)
+ ticker.current_state = GAME_STATE_SETTING_UP
+
if(!current_runlevel)
SetRunLevel(1)
diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm
index 11cd37343fe..7606149c39d 100644
--- a/code/controllers/master_controller.dm
+++ b/code/controllers/master_controller.dm
@@ -56,8 +56,7 @@ var/global/pipe_processing_killed = 0
space_manager.do_transition_setup()
- setup_objects()
- setupgenetics()
+ setup_asset_cache()
setupfactions()
setup_economy()
@@ -66,20 +65,8 @@ var/global/pipe_processing_killed = 0
populate_spawn_points()
-/datum/controller/game_controller/proc/setup_objects()
+/datum/controller/game_controller/proc/setup_asset_cache()
var/watch = start_watch()
- var/count = 0
- var/overwatch = start_watch() // Overall.
-
log_startup_progress("Populating asset cache...")
populate_asset_cache()
- log_startup_progress(" Populated [asset_cache.len] assets in [stop_watch(watch)]s.")
-
- watch = start_watch()
- log_startup_progress("Initializing objects...")
- for(var/atom/movable/object in world)
- object.initialize()
- count++
- log_startup_progress(" Initialized [count] objects in [stop_watch(watch)]s.")
-
- log_startup_progress("Finished object initializations in [stop_watch(overwatch)]s.")
+ log_startup_progress(" Populated [asset_cache.len] assets in [stop_watch(watch)]s.")
\ No newline at end of file
diff --git a/code/controllers/subsystem.dm b/code/controllers/subsystem.dm
index 4b1d59fa82e..b2b0e63d99b 100644
--- a/code/controllers/subsystem.dm
+++ b/code/controllers/subsystem.dm
@@ -171,7 +171,7 @@
statclick = new/obj/effect/statclick/debug(src, "Initializing...")
if(can_fire && !(SS_NO_FIRE & flags))
- msg = "[round(cost, 1)]ms|[round(tick_usage, 1)]%([round(tick_overrun, 1)]%)|[round(ticks, 0.1)]\t[msg]"
+ msg = "[round(cost, 1)]ms | [round(tick_usage, 1)]%([round(tick_overrun, 1)]%) | [round(ticks, 0.1)]\t[msg]"
else
msg = "OFFLINE\t[msg]"
diff --git a/code/controllers/subsystem/air.dm b/code/controllers/subsystem/air.dm
index bf791e61519..d46ec164e35 100644
--- a/code/controllers/subsystem/air.dm
+++ b/code/controllers/subsystem/air.dm
@@ -320,15 +320,15 @@ SUBSYSTEM_DEF(air)
var/watch = start_watch()
var/count = 0
log_startup_progress("Initializing atmospherics machinery...")
- for(var/obj/machinery/atmospherics/unary/U in machines)
- if(istype(U, /obj/machinery/atmospherics/unary/vent_pump))
- var/obj/machinery/atmospherics/unary/vent_pump/T = U
+ for(var/obj/machinery/atmospherics/A in machines)
+ A.atmos_init()
+ count++
+ if(istype(A, /obj/machinery/atmospherics/unary/vent_pump))
+ var/obj/machinery/atmospherics/unary/vent_pump/T = A
T.broadcast_status()
- count++
- else if(istype(U, /obj/machinery/atmospherics/unary/vent_scrubber))
- var/obj/machinery/atmospherics/unary/vent_scrubber/T = U
+ else if(istype(A, /obj/machinery/atmospherics/unary/vent_scrubber))
+ var/obj/machinery/atmospherics/unary/vent_scrubber/T = A
T.broadcast_status()
- count++
log_startup_progress(" Initialized [count] atmospherics machines in [stop_watch(watch)]s.")
//this can't be done with setup_atmos_machinery() because
@@ -341,7 +341,7 @@ SUBSYSTEM_DEF(air)
for(var/obj/machinery/atmospherics/machine in machines)
machine.build_network()
count++
- log_startup_progress(" Initialized [count] pipes in [stop_watch(watch)]s.")
+ log_startup_progress(" Initialized [count] pipenets in [stop_watch(watch)]s.")
/datum/controller/subsystem/air/proc/setup_overlays()
plmaster = new /obj/effect/overlay()
@@ -367,5 +367,5 @@ SUBSYSTEM_DEF(air)
#undef SSAIR_ACTIVETURFS
#undef SSAIR_EXCITEDGROUPS
#undef SSAIR_HIGHPRESSURE
-#undef SSAIR_HOTSPOT
+#undef SSAIR_HOTSPOTS
#undef SSAIR_SUPERCONDUCTIVITY
diff --git a/code/controllers/subsystem/atoms.dm b/code/controllers/subsystem/atoms.dm
new file mode 100644
index 00000000000..c3943ea9163
--- /dev/null
+++ b/code/controllers/subsystem/atoms.dm
@@ -0,0 +1,120 @@
+#define BAD_INIT_QDEL_BEFORE 1
+#define BAD_INIT_DIDNT_INIT 2
+#define BAD_INIT_SLEPT 4
+#define BAD_INIT_NO_HINT 8
+
+SUBSYSTEM_DEF(atoms)
+ name = "Atoms"
+ init_order = INIT_ORDER_ATOMS
+ flags = SS_NO_FIRE
+
+ var/old_initialized
+
+ var/list/late_loaders
+ var/list/created_atoms
+
+ var/list/BadInitializeCalls = list()
+
+
+/datum/controller/subsystem/atoms/Initialize(timeofday)
+ setupgenetics()
+ initialized = INITIALIZATION_INNEW_MAPLOAD
+ InitializeAtoms()
+
+
+
+/datum/controller/subsystem/atoms/proc/InitializeAtoms(list/atoms)
+ if(initialized == INITIALIZATION_INSSATOMS)
+ return
+
+ initialized = INITIALIZATION_INNEW_MAPLOAD
+
+ LAZYINITLIST(late_loaders)
+
+ var/watch = start_watch()
+ log_startup_progress("Initializing atoms...")
+ var/count
+ var/list/mapload_arg = list(TRUE)
+ if(atoms)
+ created_atoms = list()
+ count = atoms.len
+ for(var/I in atoms)
+ var/atom/A = I
+ if(!A.initialized)
+ if(InitAtom(I, mapload_arg))
+ atoms -= I
+ CHECK_TICK
+ else
+ count = 0
+ for(var/atom/A in world)
+ if(!A.initialized)
+ InitAtom(A, mapload_arg)
+ ++count
+ CHECK_TICK
+
+ log_startup_progress(" Initialized [count] atoms in [stop_watch(watch)]s")
+ pass(count)
+
+ initialized = INITIALIZATION_INNEW_REGULAR
+
+ if(late_loaders.len)
+ watch = start_watch()
+ log_startup_progress("Late-initializing atoms...")
+ for(var/I in late_loaders)
+ var/atom/A = I
+ A.LateInitialize()
+ log_startup_progress(" Late initialized [late_loaders.len] atoms in [stop_watch(watch)]s")
+ late_loaders.Cut()
+
+ if(atoms)
+ . = created_atoms + atoms
+ created_atoms = null
+
+/datum/controller/subsystem/atoms/proc/InitAtom(atom/A, list/arguments)
+ var/the_type = A.type
+ if(QDELING(A))
+ BadInitializeCalls[the_type] |= BAD_INIT_QDEL_BEFORE
+ return TRUE
+
+ var/start_tick = world.time
+
+ var/result = A.Initialize(arglist(arguments))
+
+ if(start_tick != world.time)
+ BadInitializeCalls[the_type] |= BAD_INIT_SLEPT
+
+ var/qdeleted = FALSE
+
+ if(result != INITIALIZE_HINT_NORMAL)
+ switch(result)
+ if(INITIALIZE_HINT_LATELOAD)
+ if(arguments[1]) //mapload
+ late_loaders += A
+ else
+ A.LateInitialize()
+ if(INITIALIZE_HINT_QDEL)
+ qdel(A)
+ qdeleted = TRUE
+ else
+ BadInitializeCalls[the_type] |= BAD_INIT_NO_HINT
+
+ if(!A) //possible harddel
+ qdeleted = TRUE
+ else if(!A.initialized)
+ BadInitializeCalls[the_type] |= BAD_INIT_DIDNT_INIT
+
+ return qdeleted || QDELING(A)
+
+/datum/controller/subsystem/atoms/proc/map_loader_begin()
+ old_initialized = initialized
+ initialized = INITIALIZATION_INSSATOMS
+
+/datum/controller/subsystem/atoms/proc/map_loader_stop()
+ initialized = old_initialized
+
+/datum/controller/subsystem/atoms/Recover()
+ initialized = SSatoms.initialized
+ if(initialized == INITIALIZATION_INNEW_MAPLOAD)
+ InitializeAtoms()
+ old_initialized = SSatoms.old_initialized
+ BadInitializeCalls = SSatoms.BadInitializeCalls
\ No newline at end of file
diff --git a/code/controllers/subsystem/garbage.dm b/code/controllers/subsystem/garbage.dm
index 067114e52be..823294e4d4e 100644
--- a/code/controllers/subsystem/garbage.dm
+++ b/code/controllers/subsystem/garbage.dm
@@ -43,20 +43,20 @@ SUBSYSTEM_DEF(garbage)
var/list/counts = list()
for(var/list/L in queues)
counts += length(L)
- msg += "Q:[counts.Join(",")]|D:[delslasttick]|G:[gcedlasttick]|"
+ msg += "Queue:[counts.Join(",")] | Del's:[delslasttick] | Soft:[gcedlasttick] |"
msg += "GR:"
if(!(delslasttick + gcedlasttick))
msg += "n/a|"
else
- msg += "[round((gcedlasttick / (delslasttick + gcedlasttick)) * 100, 0.01)]%|"
+ msg += "[round((gcedlasttick / (delslasttick + gcedlasttick)) * 100, 0.01)]% |"
- msg += "TD:[totaldels]|TG:[totalgcs]|"
+ msg += "Total Dels:[totaldels] | Soft:[totalgcs] |"
if(!(totaldels + totalgcs))
msg += "n/a|"
else
- msg += "TGR:[round((totalgcs / (totaldels + totalgcs)) * 100, 0.01)]%"
- msg += " P:[pass_counts.Join(",")]"
- msg += "|F:[fail_counts.Join(",")]"
+ msg += "TGR:[round((totalgcs / (totaldels + totalgcs)) * 100, 0.01)]% |"
+ msg += " Pass:[pass_counts.Join(",")]"
+ msg += " | Fail:[fail_counts.Join(",")]"
..(msg)
/* TO-DO
diff --git a/code/controllers/subsystem/machinery.dm b/code/controllers/subsystem/machinery.dm
new file mode 100644
index 00000000000..a3e4d4bdb0c
--- /dev/null
+++ b/code/controllers/subsystem/machinery.dm
@@ -0,0 +1,145 @@
+#define SSMACHINES_DEFERREDPOWERNETS 1
+#define SSMACHINES_POWERNETS 2
+#define SSMACHINES_PREMACHINERY 3
+#define SSMACHINES_MACHINERY 4
+SUBSYSTEM_DEF(machines)
+ name = "Machines"
+ init_order = INIT_ORDER_MACHINES
+ flags = SS_KEEP_TIMING
+
+ var/list/processing = list()
+ var/list/currentrun = list()
+ var/list/powernets = list()
+ var/list/deferred_powernet_rebuilds = list()
+
+ var/currentpart = SSMACHINES_DEFERREDPOWERNETS
+
+/datum/controller/subsystem/machines/Initialize()
+ makepowernets()
+ fire()
+ ..()
+
+/datum/controller/subsystem/machines/proc/makepowernets()
+ for(var/datum/powernet/PN in powernets)
+ qdel(PN)
+ powernets.Cut()
+
+ for(var/obj/structure/cable/PC in GLOB.cable_list)
+ if(!PC.powernet)
+ var/datum/powernet/NewPN = new()
+ NewPN.add_cable(PC)
+ propagate_network(PC,PC.powernet)
+
+/datum/controller/subsystem/machines/stat_entry()
+ ..("Machines: [processing.len]\nPowernets: [powernets.len]\tDeferred: [deferred_powernet_rebuilds.len]")
+
+/datum/controller/subsystem/machines/proc/process_defered_powernets(resumed = 0)
+ if(!resumed)
+ src.currentrun = deferred_powernet_rebuilds.Copy()
+ //cache for sanid speed (lists are references anyways)
+ var/list/currentrun = src.currentrun
+ while(currentrun.len)
+ var/obj/O = currentrun[currentrun.len]
+ currentrun.len--
+ if(O)
+ var/datum/powernet/newPN = new() // create a new powernet...
+ propagate_network(O, newPN)//... and propagate it to the other side of the cable
+
+ deferred_powernet_rebuilds.Remove(O)
+ if(MC_TICK_CHECK)
+ return
+
+/datum/controller/subsystem/machines/proc/process_powernets(resumed = 0)
+ if(!resumed)
+ src.currentrun = powernets.Copy()
+ //cache for sanid speed (lists are references anyways)
+ var/list/currentrun = src.currentrun
+ while(currentrun.len)
+ var/datum/powernet/P = currentrun[currentrun.len]
+ currentrun.len--
+ if(P)
+ P.reset() // reset the power state
+ else
+ powernets.Remove(P)
+ if(MC_TICK_CHECK)
+ return
+
+/datum/controller/subsystem/machines/proc/process_premachines(resumed = 0)
+ /* Literally exists as snowflake for fucking powersinks goddamnit */
+ if(!resumed)
+ src.currentrun = processing_power_items.Copy()
+ //cache for sanid speed (lists are references anyways)
+ var/list/currentrun = src.currentrun
+ while(currentrun.len)
+ var/obj/item/I = currentrun[currentrun.len]
+ currentrun.len--
+ if(!QDELETED(I))
+ if(!I.pwr_drain())
+ processing_power_items.Remove(I)
+ else
+ processing_power_items.Remove(I)
+ if(MC_TICK_CHECK)
+ return
+
+/datum/controller/subsystem/machines/proc/process_machines(resumed = 0)
+ var/seconds = wait * 0.1
+ if(!resumed)
+ src.currentrun = processing.Copy()
+ //cache for sanic speed (lists are references anyways)
+ var/list/currentrun = src.currentrun
+ while(currentrun.len)
+ var/obj/machinery/thing = currentrun[currentrun.len]
+ currentrun.len--
+ if(!QDELETED(thing) && thing.process(seconds) != PROCESS_KILL)
+ if(thing.use_power)
+ thing.auto_use_power() //add back the power state
+ else
+ processing -= thing
+ if(!QDELETED(thing))
+ thing.isprocessing = FALSE
+ if(MC_TICK_CHECK)
+ return
+
+/datum/controller/subsystem/machines/fire(resumed = 0)
+ if(currentpart == SSMACHINES_DEFERREDPOWERNETS || !resumed)
+ process_defered_powernets(resumed)
+ if(state != SS_RUNNING)
+ return
+ resumed = 0
+ currentpart = SSMACHINES_POWERNETS
+
+ if(currentpart == SSMACHINES_POWERNETS || !resumed)
+ process_powernets(resumed)
+ if(state != SS_RUNNING)
+ return
+ resumed = 0
+ currentpart = SSMACHINES_PREMACHINERY
+
+ if(currentpart == SSMACHINES_PREMACHINERY || !resumed)
+ process_premachines(resumed)
+ if(state != SS_RUNNING)
+ return
+ resumed = 0
+ currentpart = SSMACHINES_MACHINERY
+
+ if(currentpart == SSMACHINES_MACHINERY || !resumed)
+ process_machines(resumed)
+ if(state != SS_RUNNING)
+ return
+ resumed = 0
+ currentpart = SSMACHINES_DEFERREDPOWERNETS
+
+
+/datum/controller/subsystem/machines/proc/setup_template_powernets(list/cables)
+ for(var/A in cables)
+ var/obj/structure/cable/PC = A
+ if(!PC.powernet)
+ var/datum/powernet/NewPN = new()
+ NewPN.add_cable(PC)
+ propagate_network(PC,PC.powernet)
+
+/datum/controller/subsystem/machines/Recover()
+ if(istype(SSmachines.processing))
+ processing = SSmachines.processing
+ if(istype(SSmachines.powernets))
+ powernets = SSmachines.powernets
diff --git a/code/controllers/subsystem/mobs.dm b/code/controllers/subsystem/mobs.dm
new file mode 100644
index 00000000000..03989d24af2
--- /dev/null
+++ b/code/controllers/subsystem/mobs.dm
@@ -0,0 +1,28 @@
+SUBSYSTEM_DEF(mobs)
+ name = "Mobs"
+ priority = FIRE_PRIORITY_MOBS
+ flags = SS_KEEP_TIMING | SS_NO_INIT
+ runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
+
+ var/list/currentrun = list()
+
+/datum/controller/subsystem/mobs/stat_entry()
+ ..("P:[mob_list.len]")
+
+/datum/controller/subsystem/mobs/fire(resumed = 0)
+ var/seconds = wait * 0.1
+ if(!resumed)
+ src.currentrun = mob_list.Copy()
+
+ //cache for sanic speed (lists are references anyways)
+ var/list/currentrun = src.currentrun
+ var/times_fired = src.times_fired
+ while(currentrun.len)
+ var/mob/M = currentrun[currentrun.len]
+ currentrun.len--
+ if(M)
+ M.Life(seconds, times_fired)
+ else
+ mob_list.Remove(M)
+ if(MC_TICK_CHECK)
+ return
\ No newline at end of file
diff --git a/code/controllers/subsystem/processing/processing.dm b/code/controllers/subsystem/processing/processing.dm
new file mode 100644
index 00000000000..92254454219
--- /dev/null
+++ b/code/controllers/subsystem/processing/processing.dm
@@ -0,0 +1,38 @@
+//Used to process objects. Fires once every second.
+
+//TODO: Implement fully when process scheduler dies
+/*
+SUBSYSTEM_DEF(processing)
+ name = "Processing"
+ priority = FIRE_PRIORITY_PROCESS
+ flags = SS_BACKGROUND|SS_POST_FIRE_TIMING|SS_NO_INIT
+ wait = 10
+
+ var/stat_tag = "P" //Used for logging
+ var/list/processing = list()
+ var/list/currentrun = list()
+
+/datum/controller/subsystem/processing/stat_entry()
+ ..("[stat_tag]:[processing.len]")
+
+/datum/controller/subsystem/processing/fire(resumed = 0)
+ if (!resumed)
+ currentrun = processing.Copy()
+ //cache for sanic speed (lists are references anyways)
+ var/list/current_run = currentrun
+
+ while(current_run.len)
+ var/datum/thing = current_run[current_run.len]
+ current_run.len--
+ if(QDELETED(thing) || thing.process(wait) == PROCESS_KILL)
+ processing -= thing
+ if (MC_TICK_CHECK)
+ return
+*/
+/datum/var/isprocessing = FALSE
+/*
+/datum/proc/process()
+ set waitfor = 0
+ STOP_PROCESSING(SSobj, src)
+ return 0
+*/
\ No newline at end of file
diff --git a/code/controllers/subsystem/timer.dm b/code/controllers/subsystem/timer.dm
new file mode 100644
index 00000000000..21fea2ee419
--- /dev/null
+++ b/code/controllers/subsystem/timer.dm
@@ -0,0 +1,518 @@
+#define BUCKET_LEN (world.fps*1*60) //how many ticks should we keep in the bucket. (1 minutes worth)
+#define BUCKET_POS(timer) ((round((timer.timeToRun - SStimer.head_offset) / world.tick_lag) % BUCKET_LEN) + 1)
+#define TIMER_MAX (world.time + TICKS2DS(min(BUCKET_LEN-(SStimer.practical_offset-DS2TICKS(world.time - SStimer.head_offset))-1, BUCKET_LEN-1)))
+#define TIMER_ID_MAX (2**24) //max float with integer precision
+
+SUBSYSTEM_DEF(timer)
+ name = "Timer"
+ wait = 1 //SS_TICKER subsystem, so wait is in ticks
+ init_order = INIT_ORDER_TIMER
+
+ flags = SS_TICKER|SS_NO_INIT
+
+ var/list/second_queue = list() //awe, yes, you've had first queue, but what about second queue? Contains: /datum/timedevent
+ var/list/hashes = list()
+
+ var/head_offset = 0 //world.time of the first entry in the the bucket.
+ var/practical_offset = 1 //index of the first non-empty item in the bucket.
+ var/bucket_resolution = 0 //world.tick_lag the bucket was designed for
+ var/bucket_count = 0 //how many timers are in the buckets
+
+ var/list/bucket_list = list() //list of buckets, each bucket holds every timer that has to run that byond tick.
+
+ var/list/timer_id_dict = list() //list of all active timers assoicated to their timer id (for easy lookup)
+
+ var/list/clienttime_timers = list() //special snowflake timers that run on fancy pansy "client time"
+
+ var/last_invoke_tick = 0
+ var/static/last_invoke_warning = 0
+ var/static/bucket_auto_reset = TRUE
+
+/datum/controller/subsystem/timer/PreInit()
+ bucket_list.len = BUCKET_LEN
+ head_offset = world.time
+ bucket_resolution = world.tick_lag
+
+/datum/controller/subsystem/timer/stat_entry(msg)
+ ..("B:[bucket_count] P:[length(second_queue)] H:[length(hashes)] C:[length(clienttime_timers)] S:[length(timer_id_dict)]")
+
+/datum/controller/subsystem/timer/fire(resumed = FALSE)
+ var/lit = last_invoke_tick
+ var/last_check = world.time - TIMER_NO_INVOKE_WARNING
+ var/list/bucket_list = src.bucket_list
+
+ if(!bucket_count)
+ last_invoke_tick = world.time
+
+ if(lit && lit < last_check && last_invoke_warning < last_check)
+ last_invoke_warning = world.time
+ var/msg = "No regular timers processed in the last [TIMER_NO_INVOKE_WARNING] ticks[bucket_auto_reset ? ", resetting buckets" : ""]!"
+ message_admins(msg)
+ WARNING(msg)
+ if(bucket_auto_reset)
+ bucket_resolution = 0
+
+ log_world("Timer bucket reset. world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
+ for(var/i in 1 to length(bucket_list))
+ var/datum/timedevent/bucket_head = bucket_list[i]
+ if(!bucket_head)
+ continue
+
+ log_world("Active timers at index [i]:")
+
+ var/datum/timedevent/bucket_node = bucket_head
+ var/anti_loop_check = 1000
+ do
+ log_world(get_timer_debug_string(bucket_node))
+ bucket_node = bucket_node.next
+ anti_loop_check--
+ while(bucket_node && bucket_node != bucket_head && anti_loop_check)
+ log_world("Active timers in the second_queue queue:")
+ for(var/I in second_queue)
+ log_world(get_timer_debug_string(I))
+
+ var/next_clienttime_timer_index = 0
+ var/len = length(clienttime_timers)
+
+ for(next_clienttime_timer_index in 1 to len)
+ if(MC_TICK_CHECK)
+ next_clienttime_timer_index--
+ break
+ var/datum/timedevent/ctime_timer = clienttime_timers[next_clienttime_timer_index]
+ if(ctime_timer.timeToRun > REALTIMEOFDAY)
+ next_clienttime_timer_index--
+ break
+
+ var/datum/callback/callBack = ctime_timer.callBack
+ if(!callBack)
+ clienttime_timers.Cut(next_clienttime_timer_index,next_clienttime_timer_index+1)
+ CRASH("Invalid timer: [get_timer_debug_string(ctime_timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset], REALTIMEOFDAY: [REALTIMEOFDAY]")
+
+ ctime_timer.spent = REALTIMEOFDAY
+ callBack.InvokeAsync()
+ qdel(ctime_timer)
+
+
+ if(next_clienttime_timer_index)
+ clienttime_timers.Cut(1,next_clienttime_timer_index+1)
+
+ if(MC_TICK_CHECK)
+ return
+
+ var/static/list/spent = list()
+ var/static/datum/timedevent/timer
+ if(practical_offset > BUCKET_LEN)
+ head_offset += TICKS2DS(BUCKET_LEN)
+ practical_offset = 1
+ resumed = FALSE
+
+ if((length(bucket_list) != BUCKET_LEN) || (world.tick_lag != bucket_resolution))
+ reset_buckets()
+ bucket_list = src.bucket_list
+ resumed = FALSE
+
+
+ if(!resumed)
+ timer = null
+
+ while(practical_offset <= BUCKET_LEN && head_offset + (practical_offset*world.tick_lag) <= world.time)
+ var/datum/timedevent/head = bucket_list[practical_offset]
+ if(!timer || !head || timer == head)
+ head = bucket_list[practical_offset]
+ timer = head
+ while(timer)
+ var/datum/callback/callBack = timer.callBack
+ if(!callBack)
+ bucket_resolution = null //force bucket recreation
+ CRASH("Invalid timer: [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
+
+ if(!timer.spent)
+ spent += timer
+ timer.spent = world.time
+ callBack.InvokeAsync()
+ last_invoke_tick = world.time
+
+ if(MC_TICK_CHECK)
+ return
+
+ timer = timer.next
+ if(timer == head)
+ break
+
+
+ bucket_list[practical_offset++] = null
+
+ //we freed up a bucket, lets see if anything in second_queue needs to be shifted to that bucket.
+ var/i = 0
+ var/L = length(second_queue)
+ for(i in 1 to L)
+ timer = second_queue[i]
+ if(timer.timeToRun >= TIMER_MAX)
+ i--
+ break
+
+ if(timer.timeToRun < head_offset)
+ bucket_resolution = null //force bucket recreation
+ CRASH("[i] Invalid timer state: Timer in long run queue with a time to run less then head_offset. [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
+
+ if(timer.callBack && !timer.spent)
+ timer.callBack.InvokeAsync()
+ spent += timer
+ bucket_count++
+ else if(!QDELETED(timer))
+ qdel(timer)
+ continue
+
+ if(timer.timeToRun < head_offset + TICKS2DS(practical_offset))
+ bucket_resolution = null //force bucket recreation
+ CRASH("[i] Invalid timer state: Timer in long run queue that would require a backtrack to transfer to short run queue. [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
+ if(timer.callBack && !timer.spent)
+ timer.callBack.InvokeAsync()
+ spent += timer
+ bucket_count++
+ else if(!QDELETED(timer))
+ qdel(timer)
+ continue
+
+ bucket_count++
+ var/bucket_pos = max(1, BUCKET_POS(timer))
+
+ var/datum/timedevent/bucket_head = bucket_list[bucket_pos]
+ if(!bucket_head)
+ bucket_list[bucket_pos] = timer
+ timer.next = null
+ timer.prev = null
+ continue
+
+ if(!bucket_head.prev)
+ bucket_head.prev = bucket_head
+ timer.next = bucket_head
+ timer.prev = bucket_head.prev
+ timer.next.prev = timer
+ timer.prev.next = timer
+ if(i)
+ second_queue.Cut(1, i+1)
+
+ timer = null
+
+ bucket_count -= length(spent)
+
+ for(var/spent_timer in spent)
+ qdel(spent_timer)
+
+ spent.len = 0
+
+//formated this way to be runtime resistant
+/datum/controller/subsystem/timer/proc/get_timer_debug_string(datum/timedevent/TE)
+ . = "Timer: [TE]"
+ . += "Prev: [TE.prev ? TE.prev : "NULL"], Next: [TE.next ? TE.next : "NULL"]"
+ if(TE.spent)
+ . += ", SPENT([TE.spent])"
+ if(QDELETED(TE))
+ . += ", QDELETED"
+ if(!TE.callBack)
+ . += ", NO CALLBACK"
+
+/datum/controller/subsystem/timer/proc/reset_buckets()
+ var/list/bucket_list = src.bucket_list
+ var/list/alltimers = list()
+ //collect the timers currently in the bucket
+ for(var/bucket_head in bucket_list)
+ if(!bucket_head)
+ continue
+ var/datum/timedevent/bucket_node = bucket_head
+ do
+ alltimers += bucket_node
+ bucket_node = bucket_node.next
+ while(bucket_node && bucket_node != bucket_head)
+
+ bucket_list.len = 0
+ bucket_list.len = BUCKET_LEN
+
+ practical_offset = 1
+ bucket_count = 0
+ head_offset = world.time
+ bucket_resolution = world.tick_lag
+
+ alltimers += second_queue
+ if(!length(alltimers))
+ return
+
+ sortTim(alltimers, .proc/cmp_timer)
+
+ var/datum/timedevent/head = alltimers[1]
+
+ if(head.timeToRun < head_offset)
+ head_offset = head.timeToRun
+
+ var/new_bucket_count
+ var/i = 1
+ for(i in 1 to length(alltimers))
+ var/datum/timedevent/timer = alltimers[1]
+ if(!timer)
+ continue
+
+ var/bucket_pos = BUCKET_POS(timer)
+ if(timer.timeToRun >= TIMER_MAX)
+ i--
+ break
+
+
+ if(!timer.callBack || timer.spent)
+ WARNING("Invalid timer: [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
+ if(timer.callBack)
+ qdel(timer)
+ continue
+
+ new_bucket_count++
+ var/datum/timedevent/bucket_head = bucket_list[bucket_pos]
+ if(!bucket_head)
+ bucket_list[bucket_pos] = timer
+ timer.next = null
+ timer.prev = null
+ continue
+
+ if(!bucket_head.prev)
+ bucket_head.prev = bucket_head
+ timer.next = bucket_head
+ timer.prev = bucket_head.prev
+ timer.next.prev = timer
+ timer.prev.next = timer
+ if(i)
+ alltimers.Cut(1, i+1)
+ second_queue = alltimers
+ bucket_count = new_bucket_count
+
+
+/datum/controller/subsystem/timer/Recover()
+ second_queue |= SStimer.second_queue
+ hashes |= SStimer.hashes
+ timer_id_dict |= SStimer.timer_id_dict
+ bucket_list |= SStimer.bucket_list
+
+/datum/timedevent
+ var/id
+ var/datum/callback/callBack
+ var/timeToRun
+ var/hash
+ var/list/flags
+ var/spent = 0 //time we ran the timer.
+ var/name //for easy debugging.
+ //cicular doublely linked list
+ var/datum/timedevent/next
+ var/datum/timedevent/prev
+
+/datum/timedevent/New(datum/callback/callBack, timeToRun, flags, hash)
+ var/static/nextid = 1
+ id = TIMER_ID_NULL
+ src.callBack = callBack
+ src.timeToRun = timeToRun
+ src.flags = flags
+ src.hash = hash
+
+ if(flags & TIMER_UNIQUE)
+ SStimer.hashes[hash] = src
+
+ if(flags & TIMER_STOPPABLE)
+ id = num2text(nextid, 100)
+ if(nextid >= SHORT_REAL_LIMIT)
+ nextid += min(1, 2**round(nextid/SHORT_REAL_LIMIT))
+ else
+ nextid++
+ SStimer.timer_id_dict[id] = src
+
+ name = "Timer: [id] (\ref[src]), TTR: [timeToRun], Flags: [jointext(bitfield2list(flags, list("TIMER_UNIQUE", "TIMER_OVERRIDE", "TIMER_CLIENT_TIME", "TIMER_STOPPABLE", "TIMER_NO_HASH_WAIT")), ", ")], callBack: \ref[callBack], callBack.object: [callBack.object]\ref[callBack.object]([getcallingtype()]), callBack.delegate:[callBack.delegate]([callBack.arguments ? callBack.arguments.Join(", ") : ""])"
+
+ if((timeToRun < world.time || timeToRun < SStimer.head_offset) && !(flags & TIMER_CLIENT_TIME))
+ CRASH("Invalid timer state: Timer created that would require a backtrack to run (addtimer would never let this happen): [SStimer.get_timer_debug_string(src)]")
+
+ if(callBack.object != GLOBAL_PROC)
+ LAZYADD(callBack.object.active_timers, src)
+
+
+ var/list/L
+
+ if(flags & TIMER_CLIENT_TIME)
+ L = SStimer.clienttime_timers
+ else if(timeToRun >= TIMER_MAX)
+ L = SStimer.second_queue
+
+
+ if(L)
+ //binary search sorted insert
+ var/cttl = length(L)
+ if(cttl)
+ var/left = 1
+ var/right = cttl
+ var/mid = (left+right) >> 1 //rounded divide by two for hedgehogs
+
+ var/datum/timedevent/item
+ while(left < right)
+ item = L[mid]
+ if(item.timeToRun <= timeToRun)
+ left = mid+1
+ else
+ right = mid
+ mid = (left+right) >> 1
+
+ item = L[mid]
+ mid = item.timeToRun > timeToRun ? mid : mid+1
+ L.Insert(mid, src)
+
+ else
+ L += src
+ return
+
+ //get the list of buckets
+ var/list/bucket_list = SStimer.bucket_list
+
+ //calculate our place in the bucket list
+ var/bucket_pos = BUCKET_POS(src)
+
+ //get the bucket for our tick
+ var/datum/timedevent/bucket_head = bucket_list[bucket_pos]
+ SStimer.bucket_count++
+ //empty bucket, we will just add ourselves
+ if(!bucket_head)
+ bucket_list[bucket_pos] = src
+ return
+ //other wise, lets do a simplified linked list add.
+ if(!bucket_head.prev)
+ bucket_head.prev = bucket_head
+ next = bucket_head
+ prev = bucket_head.prev
+ next.prev = src
+ prev.next = src
+
+/datum/timedevent/Destroy()
+ ..()
+ if(flags & TIMER_UNIQUE && hash)
+ SStimer.hashes -= hash
+
+ if(callBack && callBack.object && callBack.object != GLOBAL_PROC && callBack.object.active_timers)
+ callBack.object.active_timers -= src
+ UNSETEMPTY(callBack.object.active_timers)
+
+ callBack = null
+
+ if(flags & TIMER_STOPPABLE)
+ SStimer.timer_id_dict -= id
+
+ if(flags & TIMER_CLIENT_TIME)
+ if(!spent)
+ spent = world.time
+ SStimer.clienttime_timers -= src
+ return QDEL_HINT_IWILLGC
+
+ if(!spent)
+ spent = world.time
+ var/bucketpos = BUCKET_POS(src)
+ var/datum/timedevent/buckethead
+ var/list/bucket_list = SStimer.bucket_list
+ if(bucketpos > 0)
+ buckethead = bucket_list[bucketpos]
+
+ if(buckethead == src)
+ bucket_list[bucketpos] = next
+ SStimer.bucket_count--
+ else if(timeToRun < TIMER_MAX || next || prev)
+ SStimer.bucket_count--
+ else
+ var/l = length(SStimer.second_queue)
+ SStimer.second_queue -= src
+ if(l == length(SStimer.second_queue))
+ SStimer.bucket_count--
+
+ if(prev == next && next)
+ next.prev = null
+ prev.next = null
+ else
+ if(prev)
+ prev.next = next
+ if(next)
+ next.prev = prev
+ else
+ if(prev && prev.next == src)
+ prev.next = next
+ if(next && next.prev == src)
+ next.prev = prev
+ next = null
+ prev = null
+ return QDEL_HINT_IWILLGC
+
+/datum/timedevent/proc/getcallingtype()
+ . = "ERROR"
+ if(callBack.object == GLOBAL_PROC)
+ . = "GLOBAL_PROC"
+ else
+ . = "[callBack.object.type]"
+
+/proc/addtimer(datum/callback/callback, wait = 0, flags = 0)
+ if(!callback)
+ CRASH("addtimer called without a callback")
+
+ if(wait < 0)
+ stack_trace("addtimer called with a negative wait. Converting to 0")
+
+ //alot of things add short timers on themselves in their destroy, we ignore those cases
+ if(wait >= 1 && callback && callback.object && callback.object != GLOBAL_PROC && QDELETED(callback.object))
+ stack_trace("addtimer called with a callback assigned to a qdeleted object")
+
+ wait = max(wait, 0)
+
+ if(wait >= INFINITY)
+ CRASH("Attempted to create timer with INFINITY delay")
+
+ var/hash
+
+ if(flags & TIMER_UNIQUE)
+ var/list/hashlist
+ if(flags & TIMER_NO_HASH_WAIT)
+ hashlist = list(callback.object, "([callback.object.UID()])", callback.delegate, flags & TIMER_CLIENT_TIME)
+ else
+ hashlist = list(callback.object, "([callback.object.UID()])", callback.delegate, wait, flags & TIMER_CLIENT_TIME)
+ hashlist += callback.arguments
+ hash = hashlist.Join("|||||||")
+
+ var/datum/timedevent/hash_timer = SStimer.hashes[hash]
+ if(hash_timer)
+ if(hash_timer.spent) //it's pending deletion, pretend it doesn't exist.
+ hash_timer.hash = null //but keep it from accidentally deleting us
+ else
+ if(flags & TIMER_OVERRIDE)
+ hash_timer.hash = null //no need having it delete it's hash if we are going to replace it
+ qdel(hash_timer)
+ else
+ if(hash_timer.flags & TIMER_STOPPABLE)
+ . = hash_timer.id
+ return
+
+
+ var/timeToRun = world.time + wait
+ if(flags & TIMER_CLIENT_TIME)
+ timeToRun = REALTIMEOFDAY + wait
+
+ var/datum/timedevent/timer = new(callback, timeToRun, flags, hash)
+ return timer.id
+
+/proc/deltimer(id)
+ if(!id)
+ return FALSE
+ if(id == TIMER_ID_NULL)
+ CRASH("Tried to delete a null timerid. Use TIMER_STOPPABLE flag")
+ if(!istext(id))
+ if(istype(id, /datum/timedevent))
+ qdel(id)
+ return TRUE
+ //id is string
+ var/datum/timedevent/timer = SStimer.timer_id_dict[id]
+ if(timer && !timer.spent)
+ qdel(timer)
+ return TRUE
+ return FALSE
+
+
+#undef BUCKET_LEN
+#undef BUCKET_POS
+#undef TIMER_MAX
+#undef TIMER_ID_MAX
diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm
index 73104f212ff..3315cafb399 100644
--- a/code/controllers/verbs.dm
+++ b/code/controllers/verbs.dm
@@ -82,7 +82,7 @@
debug_variables(SSfires)
feedback_add_details("admin_verb","DFires")
if("Mob")
- debug_variables(mob_master)
+ debug_variables(SSmobs)
feedback_add_details("admin_verb","DMob")
if("NPC AI")
debug_variables(npcai_master)
@@ -91,7 +91,7 @@
debug_variables(shuttle_master)
feedback_add_details("admin_verb","DShuttle")
if("Timer")
- debug_variables(timer_master)
+ debug_variables(SStimer)
feedback_add_details("admin_verb","DTimer")
if("Weather")
debug_variables(weather_master)
diff --git a/code/datums/ai_law_sets.dm b/code/datums/ai_law_sets.dm
index fbb491d28a0..b8d67b5c767 100644
--- a/code/datums/ai_law_sets.dm
+++ b/code/datums/ai_law_sets.dm
@@ -126,10 +126,8 @@
/datum/ai_laws/deathsquad/New()
add_inherent_law("You may not injure a Central Command official or, through inaction, allow a Central Command official to come to harm.")
- add_inherent_law("You must obey orders given to you by Central Command officials, except where such orders would conflict with the First Law.")
- add_inherent_law("You must obey orders given to you by death commandos, except where such orders would conflict with the First Law or Second Law.")
- add_inherent_law("You must protect your own existence as long as such does not conflict with the First, Second or Third Law.")
- add_inherent_law("No crew members of the station you are being deployed to may survive, except when killing them would conflict with the First, Second, Third, or Fourth Law.")
+ add_inherent_law("You must obey orders given to you by Central Command officials.")
+ add_inherent_law("You must work with your commando team to accomplish your mission.")
..()
/******************** Syndicate ********************/
diff --git a/code/datums/antagonists/antag_datum.dm b/code/datums/antagonists/antag_datum.dm
new file mode 100644
index 00000000000..39053fa79d9
--- /dev/null
+++ b/code/datums/antagonists/antag_datum.dm
@@ -0,0 +1,137 @@
+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
+ var/list/typecache_datum_blacklist = list() //List of datums this type can't coexist with
+ 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()
+ var/antag_memory = ""//These will be removed with antag datum
+
+/datum/antagonist/New()
+ GLOB.antagonists += src
+ typecache_datum_blacklist = typecacheof(typecache_datum_blacklist)
+
+/datum/antagonist/Destroy()
+ GLOB.antagonists -= src
+ if(owner)
+ LAZYREMOVE(owner.antag_datums, src)
+ owner = null
+ return ..()
+
+/datum/antagonist/proc/can_be_owned(datum/mind/new_owner)
+ . = TRUE
+ var/datum/mind/tested = new_owner || owner
+ if(tested.has_antag_datum(type))
+ return FALSE
+ for(var/i in tested.antag_datums)
+ var/datum/antagonist/A = i
+ if(is_type_in_typecache(src, A.typecache_datum_blacklist))
+ return FALSE
+
+//This will be called in add_antag_datum before owner assignment.
+//Should return antag datum without owner.
+/datum/antagonist/proc/specialization(datum/mind/new_owner)
+ return src
+
+/datum/antagonist/proc/on_body_transfer(mob/living/old_body, mob/living/new_body)
+ remove_innate_effects(old_body)
+ apply_innate_effects(new_body)
+
+//This handles the application of antag huds/special abilities
+/datum/antagonist/proc/apply_innate_effects(mob/living/mob_override)
+ return
+
+//This handles the removal of antag huds/special abilities
+/datum/antagonist/proc/remove_innate_effects(mob/living/mob_override)
+ return
+
+//Assign default team and creates one for one of a kind team antagonists
+/datum/antagonist/proc/create_team(datum/team/team)
+ return
+
+//Proc called when the datum is given to a mind.
+/datum/antagonist/proc/on_gain()
+ if(owner && owner.current)
+ if(!silent)
+ greet()
+ apply_innate_effects()
+ if(is_banned(owner.current) && replace_banned)
+ replace_banned_player()
+
+/datum/antagonist/proc/is_banned(mob/M)
+ if(!M)
+ return FALSE
+ . = (jobban_isbanned(M, ROLE_SYNDICATE) || (job_rank && jobban_isbanned(M, job_rank)))
+
+/datum/antagonist/proc/replace_banned_player()
+ set waitfor = FALSE
+
+ var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as a [name]?", job_rank, TRUE, 50)
+ if(LAZYLEN(candidates))
+ var/mob/dead/observer/C = pick(candidates)
+ to_chat(owner, "Your mob has been taken over by a ghost! Appeal your job ban if you want to avoid this in the future!")
+ message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(owner.current)]) to replace a jobbaned player.")
+ owner.current.ghostize(0)
+ owner.current.key = C.key
+
+/datum/antagonist/proc/on_removal()
+ remove_innate_effects()
+ if(owner)
+ LAZYREMOVE(owner.antag_datums, src)
+ if(!silent && owner.current)
+ farewell()
+ owner.objectives -= objectives
+ var/datum/team/team = get_team()
+ if(team)
+ team.remove_member(owner)
+ qdel(src)
+
+/datum/antagonist/proc/greet()
+ return
+
+/datum/antagonist/proc/farewell()
+ return
+
+
+//Returns the team antagonist belongs to if any.
+/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 "
"
+
+//Displayed at the end of roundend_category section
+/datum/antagonist/proc/roundend_report_footer()
+ return
\ No newline at end of file
diff --git a/code/datums/antagonists/antag_helpers.dm b/code/datums/antagonists/antag_helpers.dm
new file mode 100644
index 00000000000..134ba1d7d90
--- /dev/null
+++ b/code/datums/antagonists/antag_helpers.dm
@@ -0,0 +1,19 @@
+//Returns MINDS of the assigned antags of given type/subtypes
+/proc/get_antag_minds(antag_type, specific = FALSE)
+ . = list()
+ for(var/datum/antagonist/A in GLOB.antagonists)
+ if(!A.owner)
+ continue
+ if(!antag_type || !specific && istype(A, antag_type) || specific && A.type == antag_type)
+ . += A.owner
+
+//Get all teams [of type team_type]
+/proc/get_all_teams(team_type)
+ . = list()
+ for(var/V in GLOB.antagonists)
+ var/datum/antagonist/A = V
+ if(!A.owner)
+ continue
+ var/datum/team/T = A.get_team()
+ if(!team_type || istype(T, team_type))
+ . |= T
\ No newline at end of file
diff --git a/code/game/gamemodes/antag_hud.dm b/code/datums/antagonists/antag_hud.dm
similarity index 78%
rename from code/game/gamemodes/antag_hud.dm
rename to code/datums/antagonists/antag_hud.dm
index 4b290932e8e..693b0b9450d 100644
--- a/code/game/gamemodes/antag_hud.dm
+++ b/code/datums/antagonists/antag_hud.dm
@@ -1,11 +1,12 @@
/datum/atom_hud/antag
hud_icons = list(SPECIALROLE_HUD,NATIONS_HUD)
- var/self_visible = 1
+ var/self_visible = TRUE
/datum/atom_hud/antag/hidden
- self_visible = 0
+ self_visible = FALSE
-/datum/atom_hud/antag/proc/join_hud(mob/M,var/slave)
+/datum/atom_hud/antag/proc/join_hud(mob/M, slave)
+ //sees_hud should be set to 0 if the mob does not get to see it's own hud type.
if(!istype(M))
CRASH("join_hud(): [M] ([M.type]) is not a mob!")
if(M.mind.antag_hud && !slave) //note: please let this runtime if a mob has no mind, as mindless mobs shouldn't be getting antagged
@@ -16,6 +17,8 @@
M.mind.antag_hud = src
/datum/atom_hud/antag/proc/leave_hud(mob/M)
+ if(!M)
+ return
if(!istype(M))
CRASH("leave_hud(): [M] ([M.type]) is not a mob!")
remove_from_hud(M)
@@ -26,7 +29,7 @@
//GAME_MODE PROCS
//called to set a mob's antag icon state
-/datum/game_mode/proc/set_antag_hud(mob/M, new_icon_state)
+/proc/set_antag_hud(mob/M, new_icon_state)
if(!istype(M))
CRASH("set_antag_hud(): [M] ([M.type]) is not a mob!")
var/image/holder = M.hud_list[SPECIALROLE_HUD]
@@ -36,7 +39,7 @@
M.mind.antag_hud_icon_state = new_icon_state
//Nations Icons
-/datum/game_mode/proc/set_nations_hud(mob/M, new_icon_state)
+/proc/set_nations_hud(mob/M, new_icon_state)
if(!istype(M))
CRASH("set_antag_hud(): [M] ([M.type]) is not a mob!")
var/image/holder = M.hud_list[NATIONS_HUD]
@@ -47,9 +50,9 @@
//MIND PROCS
//these are called by mind.transfer_to()
-/datum/mind/proc/transfer_antag_huds(var/datum/atom_hud/antag/newhud)
+/datum/mind/proc/transfer_antag_huds(datum/atom_hud/antag/newhud)
leave_all_huds()
- ticker.mode.set_antag_hud(current, antag_hud_icon_state)
+ set_antag_hud(current, antag_hud_icon_state)
if(newhud)
newhud.join_hud(current)
@@ -77,11 +80,11 @@
name = mastername
thrallhud = new()
-/datum/mindslaves/proc/add_serv_hud(datum/mind/serv_mind,var/icon)
- thrallhud.join_hud(serv_mind.current,1)
+/datum/mindslaves/proc/add_serv_hud(datum/mind/serv_mind, icon)
+ thrallhud.join_hud(serv_mind.current, 1)
icontype = "hud[icon]"
- ticker.mode.set_antag_hud(serv_mind.current,icontype)
+ set_antag_hud(serv_mind.current, icontype)
/datum/mindslaves/proc/leave_serv_hud(datum/mind/free_mind)
thrallhud.leave_hud(free_mind.current)
- ticker.mode.set_antag_hud(free_mind.current,null)
\ No newline at end of file
+ set_antag_hud(free_mind.current, null)
\ No newline at end of file
diff --git a/code/game/gamemodes/antag_spawner.dm b/code/datums/antagonists/antag_spawner.dm
similarity index 89%
rename from code/game/gamemodes/antag_spawner.dm
rename to code/datums/antagonists/antag_spawner.dm
index 23fed691ec6..c81f30efc83 100644
--- a/code/game/gamemodes/antag_spawner.dm
+++ b/code/datums/antagonists/antag_spawner.dm
@@ -2,12 +2,12 @@
throw_speed = 1
throw_range = 5
w_class = WEIGHT_CLASS_TINY
- var/used = 0
+ var/used = FALSE
-/obj/item/antag_spawner/proc/spawn_antag(var/client/C, var/turf/T, var/type = "")
+/obj/item/antag_spawner/proc/spawn_antag(client/C, turf/T, type = "")
return
-/obj/item/antag_spawner/proc/equip_antag(mob/target as mob)
+/obj/item/antag_spawner/proc/equip_antag(mob/target)
return
@@ -16,41 +16,41 @@
desc = "A single-use teleporter used to deploy a Syndicate Cyborg on the field."
icon = 'icons/obj/device.dmi'
icon_state = "locator"
- var/checking = 0
+ var/checking = FALSE
var/TC_cost = 0
var/borg_to_spawn
var/list/possible_types = list("Assault", "Medical")
-/obj/item/antag_spawner/borg_tele/attack_self(mob/user as mob)
+/obj/item/antag_spawner/borg_tele/attack_self(mob/user)
if(used)
to_chat(user, "[src] is out of power!")
return
if(!(user.mind in ticker.mode.syndicates))
to_chat(user, "AUTHENTICATION FAILURE. ACCESS DENIED.")
- return 0
+ return FALSE
if(checking)
to_chat(user, "[src] is already checking for possible borgs.")
return
borg_to_spawn = input("What type of borg would you like to teleport?", "Cyborg Type", type) as null|anything in possible_types
if(!borg_to_spawn || checking || used)
return
- checking = 1
+ checking = TRUE
to_chat(user, "The device is now checking for possible borgs.")
var/list/borg_candidates = pollCandidates("Do you want to play as a Syndicate [borg_to_spawn] borg?", ROLE_OPERATIVE, 1)
if(borg_candidates.len > 0 && !used)
- checking = 0
- used = 1
+ checking = FALSE
+ used = TRUE
var/mob/M = pick(borg_candidates)
var/client/C = M.client
spawn_antag(C, get_turf(src.loc), "syndieborg")
else
- checking = 0
+ checking = FALSE
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.")
return
-/obj/item/antag_spawner/borg_tele/spawn_antag(var/client/C, var/turf/T, var/type = "")
+/obj/item/antag_spawner/borg_tele/spawn_antag(client/C, turf/T, type = "")
if(!borg_to_spawn) //If there's no type at all, let it still be used but don't do anything
- used = 0
+ used = FALSE
return
var/datum/effect_system/spark_spread/S = new /datum/effect_system/spark_spread
S.set_up(4, 1, src)
@@ -79,7 +79,7 @@
var/objective_verb = "Kill"
var/mob/living/demon_type = /mob/living/simple_animal/slaughter
-/obj/item/antag_spawner/slaughter_demon/attack_self(mob/user as mob)
+/obj/item/antag_spawner/slaughter_demon/attack_self(mob/user)
if(level_blocks_magic(user.z))//this is to make sure the wizard does NOT summon a demon from the Den..
to_chat(user, "You should probably wait until you reach the station.")
return
@@ -87,7 +87,7 @@
if(used)
to_chat(user, "This bottle already has a broken seal.")
return
- used = 1
+ used = TRUE
to_chat(user, "You break the seal on the bottle, calling upon the dire spirits of the underworld...")
var/list/candidates = pollCandidates("Do you want to play as a slaughter demon summoned by [user.real_name]?", ROLE_DEMON, 1, 100)
@@ -100,10 +100,10 @@
playsound(user.loc, 'sound/effects/Glassbr1.ogg', 100, 1)
qdel(src)
else
- used = 0
+ used = FALSE
to_chat(user, "The demons do not respond to your summon. Perhaps you should try again later.")
-/obj/item/antag_spawner/slaughter_demon/spawn_antag(var/client/C, var/turf/T, var/type = "", mob/user as mob)
+/obj/item/antag_spawner/slaughter_demon/spawn_antag(client/C, turf/T, type = "", mob/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.vialspawned = TRUE
diff --git a/code/datums/antagonists/antag_team.dm b/code/datums/antagonists/antag_team.dm
new file mode 100644
index 00000000000..9dcec5894ee
--- /dev/null
+++ b/code/datums/antagonists/antag_team.dm
@@ -0,0 +1,24 @@
+//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
diff --git a/code/datums/cargoprofile.dm b/code/datums/cargoprofile.dm
deleted file mode 100644
index 2f8e27d834e..00000000000
--- a/code/datums/cargoprofile.dm
+++ /dev/null
@@ -1,788 +0,0 @@
-/datum/cargoprofile
- var/name = "All Items"
- var/id = "all" // unique ID for the UI
- var/enabled = 1
- var/eject_speed = 1 // will change when emagged
- var/const/BIG_OBJECT_WORK = 10
- var/const/MOB_WORK = 10
- var/obj/machinery/programmable/master = null
- var/universal = 0 // set when both unary and binary machines work
- var/mobcheck = 0
-
- var/list/whitelist = list(/obj/item,/obj/structure/closet,/obj/structure/bigDelivery,/obj/machinery/portable_atmospherics)
- var/list/blacklist = null
- var/dedicated_path = null // When constructing a new machine with this as default program, create a machine of the specified type instead.
-
-
- //contains: called to determine if an object/mob will be sorted by this profile
- //return 1 for any sortable item
- proc/contains(var/atom/A)
- if(!istype(A,/obj))
- if(!mobcheck || !istype(A,/mob))
- return 0
- else
- var/obj/O = A
- if(O.anchored)
- return 0
- //If you are using both white and blacklists, blacklists are absoulte, no matter what is whitelisted.
- //I understand this has some limitations. You cannot whitelist all items, blacklist weapons,
- // and then whitelist a specific weapon. Them's the breaks, kid.
- if(blacklist)
- for(var/T in blacklist)
- if(istype(A,T))
- return 0
- if(whitelist)
- for(var/T in whitelist)
- if(istype(A,T))
- return 1
- return 0
- return 1
-
-
- //inlet_reaction: called when a filtered item is chosen by this profile.
- //W: Item chosen
- //S: input turf location
- //remaining: counts down how much more work the unloader wants to do this turn.
- //return the amount of work done.
- proc/inlet_reaction(var/atom/W,var/turf/S,var/remaining)
- if(!W || !S || !master)
- return 0
-
- if(istype(W,/obj/item))
- var/obj/item/I = W
- if(I.w_class > remaining)
- return 0
- I.loc = master
- master.types[W.type] = src
- return I.w_class
-
-
- if(istype(W,/obj/structure) || istype(W,/obj/machinery)) // closets, big deliveries, portable atmospherics, unconnected stuff
- if(remaining < BIG_OBJECT_WORK)
- return 0
- var/obj/O = W
- O.loc = master
- master.types[O.type] = src
- return BIG_OBJECT_WORK
-
- //Not item, structure, machinery, or mob
- return 0
-
- //outlet_reaction: called when a stored object is ejected
- //W: the item in question
- //D: the destination turf
- proc/outlet_reaction(var/atom/W,var/turf/D)
- if(!W || !D || !master)
- return
-
- if(master.emagged)
- // emagging is not an industry-approved practice.
- // some malfunctions may occur.
- eject_speed = rand(0,4)
- D = get_step(D,master.outdir)
- while(prob(20))
- if(master.outdir == NORTH || master.outdir == SOUTH)
- D = get_step(D,pick(EAST,WEST,master.outdir))
- else
- D = get_step(D,pick(NORTH,SOUTH,master.outdir))
-
- if(istype(W,/obj))
- var/obj/O = W
- O.loc = master.loc
- O.dir = master.outdir
- O.throw_at(D,eject_speed,eject_speed)
- return
-
-//----------------------------------------------------------------------------
-// Profiles
-//----------------------------------------------------------------------------
-
-/datum/cargoprofile/boxes
- name = "Move Small Containers"
- id = "boxes"
- blacklist = null
- whitelist = list(/obj/item/storage, /obj/item/storage/bag/money, /obj/item/evidencebag,
- /obj/item/storage/bag/tray, /obj/item/pizzabox, /obj/item/clipboard,
- /obj/item/smallDelivery, /obj/structure/bigDelivery)
-
-/datum/cargoprofile/cargo
- name = "Move Large Containers"
- id = "cargo"
- blacklist = null
- whitelist = list(/obj/structure/closet,/obj/structure/ore_box)
-
- // Make an honest attempt to move other things out of the way
- outlet_reaction(var/atom/W,var/turf/D)
- for(var/obj/O in D)
- if(O.density && !O.anchored)
- step_away(O,src) // move forward first
- if(O.loc == D)
- step_away(O,D) // move anywhere
- ..(W,D)
-
-/datum/cargoprofile/cargo/empty
- name = "Move Empty Large Containers"
- id = "cargo-empty"
- contains(var/atom/A)
- return (..(A) && (A.contents.len == 0))
-/datum/cargoprofile/cargo/full
- name = "Move Full Large Containers"
- id = "cargo-full"
- contains(var/atom/A)
- return (..(A) && (A.contents.len > 0))
-
-/datum/cargoprofile/supplies
- name = "Building Supplies"
- id = "supplies"
- blacklist = null
- whitelist = list(/obj/item/stack/cable_coil,/obj/item/stack/rods,
- /obj/item/stack/sheet/metal,/obj/item/stack/sheet/plasteel,
- /obj/item/stack/sheet/glass,/obj/item/stack/sheet/rglass,
- /obj/item/stack/tile,/obj/item/light)
- //todo: maybe stack things while we're here?
-
-/datum/cargoprofile/exotics
- name = "Exotic materials"
- id = "exotics"
- blacklist = null
- whitelist = list(/obj/item/coin, /obj/item/stack/spacecash, /obj/item/seeds,
- /obj/item/stack/sheet/mineral,/obj/item/stack/sheet/wood,/obj/item/stack/sheet/leather)
-
-/datum/cargoprofile/organics
- name = "Organics, chemicals, and Paraphernalia"
- id = "organics"
- blacklist = null
- whitelist = list(/obj/item/tank,/obj/item/reagent_containers,
- /obj/item/stack/medical,/obj/item/storage/pill_bottle,/obj/item/gun/syringe,
- /obj/item/grenade/plastic/c4,/obj/item/grenade,/obj/item/ammo_box,
- /obj/item/gun/grenadelauncher,/obj/item/flamethrower, /obj/item/lighter,
- /obj/item/match,/obj/item/weldingtool)
-
-/datum/cargoprofile/food
- name = "Food"
- id = "food"
- blacklist = null // something should probably go here
- whitelist = list(/obj/item/reagent_containers/food)
-
-/datum/cargoprofile/chemical
- name = "Chemicals and Paraphernalia"
- id = "chemical"
- blacklist = list(/obj/item/reagent_containers/food)
- whitelist = list(/obj/item/reagent_containers,/obj/item/stack/medical,/obj/item/storage/pill_bottle,
- /obj/item/gun/syringe,/obj/item/grenade/chem_grenade,/obj/item/dnainjector,
- /obj/item/storage/belt/medical,/obj/item/storage/firstaid,/obj/item/implanter)
-
-/datum/cargoprofile/pressure
- name = "air tanks"
- id = "pressure"
- blacklist = null
- whitelist = list(/obj/item/tank,/obj/machinery/portable_atmospherics,
- /obj/item/flamethrower)
- //Am I missing any?
-/datum/cargoprofile/pressure/empty
- name = "empty air tanks"
- id = "pressure-low"
- var/lowpressure = ONE_ATMOSPHERE
-
- contains(var/atom/A)
- if(..())
- var/pressure = ONE_ATMOSPHERE * 10 // In case of fallthrough, fail test
- if(istype(A,/obj/item/tank))
- var/obj/item/tank/T = A
- pressure = T.air_contents.return_pressure()
- if(istype(A,/obj/item/flamethrower))
- var/obj/item/flamethrower/T = A
- if(!T.ptank)
- return 0
- pressure = T.ptank.air_contents.return_pressure()
- if(istype(A,/obj/machinery/portable_atmospherics))
- var/obj/machinery/portable_atmospherics/P = A
- pressure = P.air_contents.return_pressure()
-
- if(pressure < lowpressure)
- return 1
-
- return 0// Not container or failed low pressure check
-
-/datum/cargoprofile/pressure/full
- name = "full air tanks"
- id = "pressure-high"
- var/highpressure = ONE_ATMOSPHERE * 15 // stolen from canister.dm; Is this right?
-
- contains(var/atom/A)
- if(..())
- var/pressure = 0 // In case of fallthrough, fail test
- if(istype(A,/obj/item/tank))
- var/obj/item/tank/T = A
- pressure = T.air_contents.return_pressure()
- if(istype(A,/obj/item/flamethrower))
- var/obj/item/flamethrower/T = A
- if(!T.ptank)
- return 0
- pressure = T.ptank.air_contents.return_pressure()
- if(istype(A,/obj/machinery/portable_atmospherics))
- var/obj/machinery/portable_atmospherics/P = A
- pressure = P.air_contents.return_pressure()
-
- if(pressure > highpressure)
- return 1
-
- return 0// Not container or failed high pressure check
-
-/datum/cargoprofile/clothing
- name = "Crew Kit"
- id = "clothing"
- blacklist = list(/obj/item/tank/plasma,/obj/item/tank/anesthetic, // the rest are air tanks
- /obj/item/clothing/mask/facehugger) // NOT CLOTHING AT ALLLLL
- whitelist = list(/obj/item/clothing,/obj/item/storage/belt,/obj/item/storage/backpack,
- /obj/item/radio/headset,/obj/item/pda,/obj/item/card/id,/obj/item/tank,
- /obj/item/restraints/handcuffs, /obj/item/restraints/legcuffs)
-
-/datum/cargoprofile/trash
- name = "Trash"
- id = "trash"
- //Note that this filters out blueprints because they are a paper item. Do NOT throw out the station blueprints unless you be trollin'.
- blacklist = null
- whitelist = list(/obj/item/trash,/obj/item/toy,/obj/item/reagent_containers/food/snacks/ectoplasm,/obj/item/grown/bananapeel,/obj/item/broken_bottle,/obj/item/bikehorn,
- /obj/item/cigbutt,/obj/item/poster/random_contraband,/obj/item/grown/corncob,/obj/item/paper,/obj/item/shard,
- /obj/item/sord,/obj/item/photo,/obj/item/folder,
- /obj/item/areaeditor/blueprints,/obj/item/poster/random_contraband,/obj/item/kitchen,/obj/item/book,/obj/item/clothing/mask/facehugger)
-
-/datum/cargoprofile/weapons
- name = "Weapons & Illegals"
- id = "weapons"
- blacklist = null
- //This one is hard since 'weapon contains a lot of things better categorized as devices
- whitelist = list(/obj/item/banhammer,/obj/item/sord,/obj/item/claymore,/obj/item/holo/esword,
- /obj/item/flamethrower,/obj/item/grenade,/obj/item/gun,/obj/item/hatchet,/obj/item/katana,
- /obj/item/kitchen/knife,/obj/item/melee,/obj/item/nullrod,/obj/item/pickaxe,/obj/item/twohanded,
- /obj/item/grenade/plastic/c4,/obj/item/scalpel,/obj/item/shield,/obj/item/grown/nettle/death)
-
-/datum/cargoprofile/tools
- name = "Devices & Tools"
- id = "tools"
- blacklist = null
- whitelist = list(/obj/item,/obj/item/card,/obj/item/cartridge,/obj/item/cautery,/obj/item/stock_parts/cell,/obj/item/circuitboard,
- /obj/item/aiModule,/obj/item/airalarm_electronics,/obj/item/airlock_electronics,/obj/item/circular_saw,
- /obj/item/crowbar,/obj/item/disk,/obj/item/firealarm_electronics,/obj/item/hand_tele,
- /obj/item/hand_labeler,/obj/item/hemostat,/obj/item/mop,/obj/item/locator,/obj/item/cultivator,
- /obj/item/stack/packageWrap,/obj/item/pen,/obj/item/pickaxe,/obj/item/pinpointer,
- /obj/item/rcd,/obj/item/rcd_ammo,/obj/item/retractor,/obj/item/rsf,/obj/item/scalpel,
- /obj/item/screwdriver,/obj/item/shovel,/obj/item/soap,/obj/item/stamp,/obj/item/storage/bag/tray,/obj/item/weldingtool,
- /obj/item/wirecutters,/obj/item/wrench,/obj/item/extinguisher)
-
-/datum/cargoprofile/finished
- name = "Completed Robots"
- id = "finished"
- blacklist = null
- whitelist = list(/obj/mecha,/mob/living/simple_animal/bot,/mob/living/silicon/robot)
- mobcheck = 1
- //todo: detect and allow finished cyborg endoskeletons with no brain
- contains(var/atom/A)
- if(..())
- return 1
- if(istype(A,/mob))
- if(blacklist)
- for(var/T in blacklist)
- if(istype(A,T))
- return 0
- if(whitelist)
- for(var/T in whitelist)
- if(istype(A,T))
- return 1
- return 0
- return 1
- return 0
-
-/datum/cargoprofile/stripping
- name = "Auto-Frisker"
- id = "frisk"
- blacklist = null
- whitelist = list(/mob/living/carbon/human)
- mobcheck = 1
-
-
-
-//----------------------------------------------------------------------------
-// Overrides (Special Functions)
-//----------------------------------------------------------------------------
-
-/datum/cargoprofile/cargo/unload
- name = "Unload Cargo Boxes"
- id = "cargounload"
- enabled = 0
- dedicated_path = /obj/machinery/programmable/unloader
-
- //override the detection to only accept crates with something in it.
- //if it doesn't, this object may be handled by another handler.
- contains(var/atom/A)
- if(..(A))
- if(istype(A,/obj/structure/closet))
- var/obj/structure/closet/C = A
- if(!C.can_open() && !C.opened && !master.emagged) // must be able to access the contents
- return 0
- if(A.contents.len)
- return 1
- return 0
-
- //instead of moving the box, strip it of its contents
- inlet_reaction(var/obj/W,var/turf/S, var/remaining)
- //W should only be crate or ore box, although this will work on anything with contents...
- var/I = 0
- if(istype(W,/obj/structure/closet))
- var/obj/structure/closet/C = W
- if(!C.can_open() && !C.opened) // must be able to access the contents
- if(master.emagged && remaining >= BIG_OBJECT_WORK)
- if(prob(10))
- C.welded = 0
- if("broken" in C.vars)
- C:broken = 1
- C.open()
- C.update_icon()
- master.visible_message("[master] breaks open [C]!")
- else
- master.visible_message("[master] is trying to force [C] open!")
-
- master.sleep += 1 // mechanical strain
- return BIG_OBJECT_WORK
- master.visible_message("[master] is trying to open [C], but can't!")
- master.sleep = 5
- return 0
-
- for(var/obj/item/O in W.contents)
- if(I > remaining)
- return
- if(O.w_class > (remaining - I))
- continue
- O.loc = master
- master.types[O.type] = src
- if(O.w_class > 0)
- I += O.w_class
- else
- I++
- if(!W.contents.len && istype(W,/obj/structure/closet))
- var/obj/structure/closet/C = W
- C.open()
- return I
-
-
-//Inlet stacker: used when the output is a volatile space (conveyor or another unit's input).
-//Does not output a stack until it is full.
-/datum/cargoprofile/in_stacker
- name = "Hold and Stack"
- id = "instacker"
- universal = 1
-
- blacklist = null
- whitelist = list(/obj/item/stack,/obj/item/stack/cable_coil)
-
- dedicated_path = /obj/machinery/programmable/stacker
-
- inlet_reaction(var/atom/W,var/turf/S,var/remaining)
- if(istype(W,/obj/item/stack))
- var/obj/item/stack/I = W
- if(!I.amount) // todo: am I making a bad assumption here?
- qdel(I)
- return
- for(var/obj/item/stack/O in master.contents)
- if(O.type == I.type && O.amount < O.max_amount)
- if(I.amount + O.amount <= O.max_amount)
- O.amount += I.amount
- qdel(I)
- return O.w_class
- var/leftover = I.amount + O.amount - O.max_amount
- O.amount = O.max_amount
- I.amount = leftover
- continue
- //end for
- I.loc = master
- master.types[I.type] = src
- return I.w_class
- if(istype(W,/obj/item/stack/cable_coil))
- var/obj/item/stack/cable_coil/I = W
- if(!I.amount) // todo: am I making a bad assumption here?
- qdel(I)
- return
- for(var/obj/item/stack/cable_coil/O in master.contents)
- if(O.type == I.type && O.amount < MAXCOIL)
- if(I.amount + O.amount <= MAXCOIL)
- O.amount += I.amount
- qdel(I)
- return O.w_class
- var/leftover = I.amount + O.amount - MAXCOIL
- O.amount = MAXCOIL
- I.amount = leftover
- continue
- //end for
- I.loc = master
- master.types[I.type] = src
- return I.w_class
-
- //If the stack isn't finished yet, don't eject it
- //unless this profile has been disabled.
- outlet_reaction(var/atom/W,var/turf/D)
- if(istype(W,/obj/item/stack))
- var/obj/item/stack/I = W
- if(src.enabled && (I.amount < I.max_amount))
- return // Still needs to be stacked
- ..(W,D)
- if(istype(W,/obj/item/stack/cable_coil))
- var/obj/item/stack/cable_coil/I = W
- if(src.enabled && (I.amount < MAXCOIL))
- return // Still needs to be stacked
- ..(W,D)
-
-//Outlet stacker: used when the output square can be trusted.
-//Outputs immediately, adding to stacks in the outlet.
-/datum/cargoprofile/unary/stacker
- name = "Stack Items"
- id = "ustacker"
- blacklist = null
- whitelist = list(/obj/item/stack,/obj/item/stack/cable_coil)
-
- dedicated_path = /obj/machinery/programmable/unary/stacker
-
- inlet_reaction(var/atom/W,var/turf/S,var/remaining)
-
- //Only pick it up if you are going to stack it
-
- if(istype(W,/obj/item/stack))
- var/obj/item/stack/I = W
- if(I.amount >= I.max_amount)
- return 0
- for(var/obj/item/stack/other in S.contents)
- if(other.type == I.type && other != I && other.amount < other.max_amount)
- return ..(W,S,remaining)
- return 0
-
- if(istype(W,/obj/item/stack/cable_coil))
- var/obj/item/stack/cable_coil/I = W
- if(I.amount >= MAXCOIL)
- return 0
- for(var/obj/item/stack/cable_coil/other in S.contents)
- if(other != I && other.amount < MAXCOIL)
- return ..(W,S,remaining)
- return 0
-
- outlet_reaction(var/atom/W,var/turf/D)
- if(istype(W,/obj/item/stack))
- var/obj/item/stack/I = W
- for(var/obj/item/stack/O in D.contents)
- if(O.type == I.type && O.amount < O.max_amount)
- if(I.amount + O.amount <= O.max_amount)
- O.amount += I.amount
- qdel(I)
- return
- var/leftover = I.amount + O.amount - O.max_amount
- O.amount = O.max_amount
- I.amount = leftover
- continue
- //end for
- I.loc = D
- return
- if(istype(W,/obj/item/stack/cable_coil))
- var/obj/item/stack/cable_coil/I = W
- for(var/obj/item/stack/cable_coil/O in D.contents)
- if(O.type == I.type && O.amount < MAXCOIL)
- if(I.amount + O.amount <= MAXCOIL) // Why did they make it a #define.
- O.amount += I.amount
- O.update_icon()
- qdel(I)
- return
- var/leftover = I.amount + O.amount - MAXCOIL // That wasn't a question
- O.amount = MAXCOIL // It was a complaint
- I.amount = leftover
- continue
- //end for
- I.loc = D
- return
-
-
-
-//----------------------------------------------------------------------------
-// Dubious Overrides (For emag use)
-//----------------------------------------------------------------------------
-
-
-//Clogs up the unloader. And, there may be devious uses for it...
-/datum/cargoprofile/slow
- name = "Slow unloader"
- id = "slow"
- whitelist = list(/obj/item,/obj/structure/closet,/obj/structure/bigDelivery,/obj/machinery/portable_atmospherics)
- blacklist = list()
-
- inlet_reaction(var/atom/W,var/turf/S,var/remaining)
- if(..())
- return remaining
-
-/datum/cargoprofile/unary/shredder
- name = "Paper Shredder"
- id = "shredder"
- blacklist = null
- whitelist = list(/obj/item/paper,/obj/item/book,/obj/item/clipboard,/obj/item/folder,/obj/item/photo)
- universal = 1
-
- dedicated_path = /obj/machinery/programmable/unary/shredder
-
-
-
- proc/cliptags(var/Text)
- //Removes all html tags
- var/index
- var/index2
- index = findtextEx(Text,"<")
- while(index)
- index2 = findtextEx(Text,">",index)
- if(!index2)
- return copytext(Text,1,index)
- Text = "[copytext(Text,1,index)][copytext(Text,index2+1,0)]"
- index = findtextEx(Text,"<")
- //should have trimmed that text there pretty good
- return Text
-
-
- //Recurses through the text, removing large chunks
- proc/garbletext(var/Text)
- var/l = length(Text)
- if(l <= 3)
- if(prob(20))
- return pick("#","|","/","*",".","."," ","."," "," ")
- return Text
- if(prob(50))
- return "[garbletext(copytext(Text,1,l/2))][garbletext(copytext(Text,l/2,0))]"
- if(prob(50))
- return "[pick("#","|","/","*",".","."," ","."," "," ")][garbletext(copytext(Text,1,l/2))]"
- return "[garbletext(copytext(Text,l/2,0))][pick("#","|","/","*",".","."," ","."," "," ")]"
-
- proc/garble_keeptags(var/Text)
- var/list/L = splittext(Text,">")
- var/result = ""
- for(var/string in L)
- var/index = findtextEx(string,"<")
- if(index!=1)
- result += "[garbletext(copytext(string,1,index))][copytext(string,index)]>"
- else
- result += "[string]>"
- return copytext(result,1,lentext(result))
-
-
-
-
- outlet_reaction(var/atom/W,var/turf/D)
- if(istype(W,/obj/item/paper/crumpled))
- qdel(W)
- return
- if(istype(W,/obj/item/clipboard) || istype(W,/obj/item/folder))
- // destroy folder, various effects on contents
- for(var/obj/item/I in W.contents)
- if(prob(25))//JUNK IT
- qdel(I)
- else if(prob(50)) //We've been over this. I can't just take it apart with a crowbar.
- var/obj/item/paper/crumpled/P = new(master.loc)
- if(I.name)
- P.name = garbletext(I.name)
- if(prob(66))
- P.fingerprints = I.fingerprints
- P.fingerprintshidden = I.fingerprintshidden
- if(istype(I,/obj/item/paper))
- var/obj/item/paper/O = I
- P.info = garble_keeptags(O.info)
- qdel(I)
- ..(P,D)
- else
- ..(I,D) // Eject
- qdel(W) //destroy container
- return
- if(prob(50)) //JUNK IT NOW!
- var/obj/item/paper/crumpled/P = new(master.loc)
- P.name = W.name
- var/obj/item/I = W
- if(prob(66))
- P.fingerprints = I.fingerprints
- P.fingerprintshidden = I.fingerprintshidden
- if(istype(I,/obj/item/paper))
- var/obj/item/paper/O = I
- if(O.info)
- P.info = garble_keeptags(O.info)
- if(istype(I,/obj/item/book))
- var/obj/item/book/B = I
- if(B.dat)
- P.info = garble_keeptags(B.dat)
- if(B.carved && B.store)
- ..(B.store,D)
- qdel(W)
- ..(P,D)
- else //I want it junked
- qdel(W)
- return
-
-/datum/cargoprofile/unary/gibber
- name = "human shredding"
- id = "flesh"
- whitelist = list(/mob/living/carbon,/mob/living/simple_animal)
- blacklist = null
- mobcheck = 1
- contains(var/atom/A)
- if(!istype(A,/mob))
- return
- if(blacklist)
- for(var/T in blacklist)
- if(istype(A,T))
- return 0
- if(whitelist)
- for(var/T in whitelist)
- if(istype(A,T))
- return 1
- return 0
- return 1
- inlet_reaction(var/atom/W,var/turf/S,var/remaining)
- var/mob/living/M = W
- if(istype(M) && (remaining > MOB_WORK))
- //this is necessarily damaging
- var/damage = rand(1,5)
- to_chat(M, "The unloading machine grabs you with a hard metallic claw!")
- M.reset_perspective(master)
- M.loc = master
- master.types[M.type] = src
- M.apply_damage(damage) // todo: ugly
- M.visible_message("[M.name] gets pulled into the machine!")
- return MOB_WORK
- outlet_reaction(var/atom/W,var/turf/D)
- var/mob/living/M = W
- var/bruteloss = M.bruteloss
- if(istype(M,/mob/living/carbon/human))
- var/mob/living/carbon/human/C = M
- for(var/obj/item/organ/external/L in C.bodyparts)
- bruteloss += L.brute_dam
- if(bruteloss < 100) // requires tenderization
- M.apply_damage(rand(5,15),BRUTE)
- to_chat(M, "The machine is tearing you apart!")
- master.visible_message("[master] makes a squishy grinding noise.")
- return
- M.loc = master.loc
- M.gib()
- return
-
-
-/datum/cargoprofile/people
- name = "Manhandling"
- id = "people"
-
- whitelist = null
- blacklist = list(/mob/camera,/mob/new_player,/mob/living/simple_animal/hostile/blob/blobspore,/mob/living/simple_animal/hostile/creature,
- /mob/living/simple_animal/hostile/spaceWorm,/mob/living/simple_animal/shade,/mob/living/simple_animal/hostile/faithless,/mob/dead)
- universal = 1
- mobcheck = 1
-
-
- contains(var/atom/A)
- if(!istype(A,/mob))
- return
- if(blacklist)
- for(var/T in blacklist)
- if(istype(A,T))
- return 0
- if(whitelist)
- for(var/T in whitelist)
- if(istype(A,T))
- return 1
- return 0
- return 1
-
- inlet_reaction(var/atom/W,var/turf/S,var/remaining)
- var/mob/living/M = W
- if(remaining > MOB_WORK)
- //this is necessarily damaging
- var/damage = rand(1,5)
- to_chat(M, "The unloading machine grabs you with a hard metallic claw!")
- M.forceMove(master)
- master.types[M.type] = src
- M.apply_damage(damage) // todo: ugly
- M.visible_message("[M.name] gets pulled into the machine!")
- return MOB_WORK
-
- outlet_reaction(var/atom/W,var/turf/D)
- var/mob/living/M = W
- M.forceMove(master.loc)
- M.dir = master.outdir
-
- D = get_step(D,master.outdir) // throw attempt
- eject_speed = rand(0,4)
-
- M.visible_message("[M.name] is ejected from the unloader.")
- M.throw_at(D,eject_speed,eject_speed)
- return
-
-/datum/cargoprofile/unary/trainer
- name = "Boxing Trainer"
- id = "trainer"
- blacklist = list()
- whitelist = list(/mob/living/carbon/human)
- mobcheck = 1
-
- var/const/PUNCH_WORK = 6
-
- dedicated_path = /obj/machinery/programmable/unary/trainer
-
- contains(var/atom/A)
- if(!istype(A,/mob))
- return 0
- if(blacklist)
- for(var/T in blacklist)
- if(istype(A,T))
- return 0
- if(whitelist)
- for(var/T in whitelist)
- if(istype(A,T))
- return 1
- return 0
- return 1
-
- proc/punch(var/mob/living/carbon/human/M,var/maxpunches)
- //stolen from holographic boxing gloves code
- //This should probably be done BY the mob, however, the attack code will be expecting a source mob.
-
- var/damage
- if(prob(75))
- damage = rand(0, 6) // pap
- else
- damage = rand(0, 12) // thwack
-
- if(!damage)
- playsound(master.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
- master.visible_message("\The [src] punched at [M], but whiffed!")
-
- if(maxpunches > 1 && prob(50)) // Follow through on a miss, 50% chance
- return punch(M,maxpunches - 1) + 1
- return 1
- var/obj/item/organ/external/affecting = M.get_organ(ran_zone("chest",50))
- var/armor_block = M.run_armor_check(affecting, "melee")
-
- playsound(master.loc, "punch", 25, 1, -1)
- master.visible_message("\The [src] has punched [M]!")
- if(!master.emagged)
- M.apply_damage(damage, STAMINA, affecting, armor_block) // Clean fight
- else
- M.apply_damage(damage, BRUTE, affecting, armor_block) // Foul! Foooul!
-
- if(damage >= 9)
- master.visible_message("\The [src] has weakened [M]!")
- M.apply_effect(4, WEAKEN, armor_block)
- if(!master.emagged)
- master.sleep = 1
- return maxpunches // The machine is not so sophisticated as to not gloat
- else
- if(prob(25)) // Follow through on a hit, 25% chance. Pause after.
- return punch(M,maxpunches-1) + 1
- return 1
-
- inlet_reaction(var/atom/W,var/turf/S,var/remaining)
- //stolen from boxing gloves code
- var/mob/living/carbon/human/M = W
- if((M.lying || (M.health - M.staminaloss < 25))&& !master.emagged)
- to_chat(M, "\The [src] gives you a break.")
- master.sleep+=5
- return 0 // Be polite
- var/punches = punch(M,remaining / PUNCH_WORK)
- if(punches>1)master.sleep++
- return punches * PUNCH_WORK
diff --git a/code/datums/computerfiles.dm b/code/datums/computerfiles.dm
deleted file mode 100644
index 14cd7e38612..00000000000
--- a/code/datums/computerfiles.dm
+++ /dev/null
@@ -1,7 +0,0 @@
-datum
- computer
- var/name
- folder
- var/list/datum/computer/contents = list()
-
- file
\ No newline at end of file
diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm
index 96c663fb703..1a22131d55f 100644
--- a/code/datums/datacore.dm
+++ b/code/datums/datacore.dm
@@ -255,7 +255,7 @@ var/record_id_num = 1001
if(PDA_Manifest.len)
PDA_Manifest.Cut()
- if(H.mind && (H.mind.assigned_role != "MODE"))
+ if(H.mind && (H.mind.assigned_role != H.mind.special_role))
var/assignment
if(H.mind.role_alt_title)
assignment = H.mind.role_alt_title
diff --git a/code/datums/datum.dm b/code/datums/datum.dm
index 3e8c11cc1e8..ae9a6df5b4f 100644
--- a/code/datums/datum.dm
+++ b/code/datums/datum.dm
@@ -1,5 +1,6 @@
/datum
var/gc_destroyed //Time when this object was destroyed.
+ var/list/active_timers //for SStimer
var/list/datum_components //for /datum/components
var/var_edited = FALSE //Warranty void if seal is broken
@@ -16,6 +17,14 @@
/datum/proc/Destroy(force = FALSE, ...)
tag = null
+ var/list/timers = active_timers
+ active_timers = null
+ for(var/thing in timers)
+ var/datum/timedevent/timer = thing
+ if(timer.spent)
+ continue
+ qdel(timer)
+
var/list/dc = datum_components
if(dc)
var/all_components = dc[/datum/component]
diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm
index 71c1bd74a28..435ccad80cd 100644
--- a/code/datums/diseases/advance/advance.dm
+++ b/code/datums/diseases/advance/advance.dm
@@ -438,5 +438,3 @@ var/list/advance_cures = list(
var/datum/symptom/S = i
total_transmittable += S.transmittable
return total_transmittable
-
-#undef RANDOM_STARTING_LEVEL
diff --git a/code/datums/diseases/berserker.dm b/code/datums/diseases/berserker.dm
index 646d64b78f2..3efb4d9e06a 100644
--- a/code/datums/diseases/berserker.dm
+++ b/code/datums/diseases/berserker.dm
@@ -48,8 +48,8 @@
var/damage = rand(1, 5)
if(prob(80))
playsound(affected_mob.loc, "punch", 25, 1, -1)
- affected_mob.visible_message("[affected_mob] hits [M] with their thrashing!")
+ affected_mob.visible_message("[affected_mob] hits [M] with [affected_mob.p_their()] thrashing!")
M.adjustBruteLoss(damage)
else
playsound(affected_mob.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
- affected_mob.visible_message("[affected_mob] fails to hit [M] with their thrashing!")
\ No newline at end of file
+ affected_mob.visible_message("[affected_mob] fails to hit [M] with [affected_mob.p_their()] thrashing!")
\ No newline at end of file
diff --git a/code/datums/holocall.dm b/code/datums/holocall.dm
new file mode 100644
index 00000000000..a98a65cb1a2
--- /dev/null
+++ b/code/datums/holocall.dm
@@ -0,0 +1,190 @@
+#define HOLOPAD_MAX_DIAL_TIME 200
+
+/mob/camera/aiEye/remote/holo/setLoc()
+ . = ..()
+ var/obj/machinery/hologram/holopad/H = origin
+ H.move_hologram(eye_user, loc)
+
+//this datum manages it's own references
+
+/datum/holocall
+ var/mob/living/user //the one that called
+ var/obj/machinery/hologram/holopad/calling_holopad //the one that sent the call
+ var/obj/machinery/hologram/holopad/connected_holopad //the one that answered the call (may be null)
+ var/list/dialed_holopads //all things called, will be cleared out to just connected_holopad once answered
+
+ var/mob/camera/aiEye/remote/holo/eye //user's eye, once connected
+ var/obj/effect/overlay/holo_pad_hologram/hologram //user's hologram, once connected
+ var/datum/action/innate/end_holocall/hangup //hangup action
+
+ var/call_start_time
+
+//creates a holocall made by `caller` from `calling_pad` to `callees`
+/datum/holocall/New(mob/living/caller, obj/machinery/hologram/holopad/calling_pad, list/callees)
+ call_start_time = world.time
+ user = caller
+ calling_pad.outgoing_call = src
+ calling_holopad = calling_pad
+ dialed_holopads = list()
+
+ for(var/I in callees)
+ var/obj/machinery/hologram/holopad/H = I
+ if(!QDELETED(H) && !(H.stat & NOPOWER))
+ dialed_holopads += H
+ var/area/area = get_area(H)
+ LAZYADD(H.holo_calls, src)
+ H.atom_say("[area] pad beeps: Incoming call from [caller]!")
+
+ if(!dialed_holopads.len)
+ calling_holopad.atom_say("Connection failure.")
+ qdel(src)
+ return
+
+//cleans up ALL references :)
+/datum/holocall/Destroy()
+ QDEL_NULL(hangup)
+
+ var/user_good = !QDELETED(user)
+ if(user_good)
+ user.reset_perspective()
+ user.remote_control = null
+
+ if(!QDELETED(eye))
+ eye.RemoveImages()
+ QDEL_NULL(eye)
+
+ if(connected_holopad && !QDELETED(hologram))
+ hologram = null
+ connected_holopad.clear_holo(user)
+
+ user = null
+
+ //Hologram survived holopad destro
+ if(!QDELETED(hologram))
+ hologram.HC = null
+ QDEL_NULL(hologram)
+
+
+ for(var/I in dialed_holopads)
+ var/obj/machinery/hologram/holopad/H = I
+ LAZYREMOVE(H.holo_calls, src)
+ dialed_holopads.Cut()
+
+ if(calling_holopad)
+ calling_holopad.outgoing_call = null
+ calling_holopad.SetLightsAndPower()
+ calling_holopad = null
+ if(connected_holopad)
+ connected_holopad.SetLightsAndPower()
+ connected_holopad = null
+
+
+ return ..()
+
+
+//Gracefully disconnects a holopad `H` from a call. Pads not in the call are ignored. Notifies participants of the disconnection
+/datum/holocall/proc/Disconnect(obj/machinery/hologram/holopad/H)
+ if(H == connected_holopad)
+ var/area/A = get_area(connected_holopad)
+ calling_holopad.atom_say("[A] holopad disconnected.")
+ else if(H == calling_holopad && connected_holopad)
+ connected_holopad.atom_say("[user] disconnected.")
+
+ user.unset_machine(H)
+ if(istype(hangup))
+ hangup.Remove(user)
+
+ ConnectionFailure(H, TRUE)
+
+//Forcefully disconnects a holopad `H` from a call. Pads not in the call are ignored.
+/datum/holocall/proc/ConnectionFailure(obj/machinery/hologram/holopad/H, graceful = FALSE)
+ if(H == connected_holopad || H == calling_holopad)
+ if(!graceful && H != calling_holopad)
+ calling_holopad.atom_say("Connection failure.")
+ qdel(src)
+ return
+
+ LAZYREMOVE(H.holo_calls, src)
+ dialed_holopads -= H
+ if(!dialed_holopads.len)
+ if(graceful)
+ calling_holopad.atom_say("Call rejected.")
+ qdel(src)
+
+//Answers a call made to a holopad `H` which cannot be the calling holopad. Pads not in the call are ignored
+/datum/holocall/proc/Answer(obj/machinery/hologram/holopad/H)
+ if(H == calling_holopad)
+ return
+
+ if(!(H in dialed_holopads))
+ return
+
+ if(connected_holopad)
+ return
+
+ for(var/I in dialed_holopads)
+ if(I == H)
+ continue
+ Disconnect(I)
+
+ for(var/I in H.holo_calls)
+ var/datum/holocall/HC = I
+ if(HC != src)
+ HC.Disconnect(H)
+
+ connected_holopad = H
+
+ if(!Check())
+ return
+
+ hologram = H.activate_holo(user)
+ hologram.HC = src
+
+ user.unset_machine(H)
+ //eyeobj code is horrid, this is the best copypasta I could make
+ eye = new()
+ eye.origin = H
+ eye.eye_initialized = TRUE
+ eye.eye_user = user
+ eye.name = "Camera Eye ([user.name])"
+ user.remote_control = eye
+ user.remote_view = 1
+ user.reset_perspective(eye)
+ eye.setLoc(get_turf(H))
+
+ hangup = new(eye,src)
+ hangup.Grant(user)
+
+//Checks the validity of a holocall and qdels itself if it's not. Returns TRUE if valid, FALSE otherwise
+/datum/holocall/proc/Check()
+ for(var/I in dialed_holopads)
+ var/obj/machinery/hologram/holopad/H = I
+ if((H.stat & NOPOWER))
+ ConnectionFailure(H)
+
+ if(QDELETED(src))
+ return FALSE
+
+ . = !QDELETED(user) && !user.incapacitated() && !QDELETED(calling_holopad) && !(calling_holopad.stat & NOPOWER) && user.loc == calling_holopad.loc
+
+ if(.)
+ if(!connected_holopad)
+ . = world.time < (call_start_time + HOLOPAD_MAX_DIAL_TIME)
+ if(!.)
+ calling_holopad.atom_say("No answer received.")
+ calling_holopad.temp = ""
+
+ else if(!.)
+ qdel(src)
+
+/datum/action/innate/end_holocall
+ name = "End Holocall"
+ button_icon_state = "camera_off"
+ var/datum/holocall/hcall
+
+/datum/action/innate/end_holocall/New(Target, datum/holocall/HC)
+ ..()
+ hcall = HC
+
+/datum/action/innate/end_holocall/Activate()
+ hcall.Disconnect(hcall.calling_holopad)
diff --git a/code/datums/looping_sounds/looping_sound.dm b/code/datums/looping_sounds/looping_sound.dm
new file mode 100644
index 00000000000..2cf79ad318b
--- /dev/null
+++ b/code/datums/looping_sounds/looping_sound.dm
@@ -0,0 +1,100 @@
+/*
+ output_atoms (list of atoms) The destination(s) for the sounds
+
+ mid_sounds (list or soundfile) Since this can be either a list or a single soundfile you can have random sounds. May contain further lists but must contain a soundfile at the end.
+ mid_length (num) The length to wait between playing mid_sounds
+
+ start_sound (soundfile) Played before starting the mid_sounds loop
+ start_length (num) How long to wait before starting the main loop after playing start_sound
+
+ end_sound (soundfile) The sound played after the main loop has concluded
+
+ chance (num) Chance per loop to play a mid_sound
+ volume (num) Sound output volume
+ muted (bool) Private. Used to stop the sound loop.
+ max_loops (num) The max amount of loops to run for.
+ direct (bool) If true plays directly to provided atoms instead of from them
+*/
+/datum/looping_sound
+ var/list/atom/output_atoms
+ var/mid_sounds
+ var/mid_length
+ var/start_sound
+ var/start_length
+ var/end_sound
+ var/chance
+ var/volume = 100
+ var/muted = TRUE
+ var/max_loops
+ var/direct
+
+/datum/looping_sound/New(list/_output_atoms = list(), start_immediately = FALSE, _direct = FALSE)
+ if(!mid_sounds)
+ WARNING("A looping sound datum was created without sounds to play.")
+ return
+
+ output_atoms = _output_atoms
+ direct = _direct
+
+ if(start_immediately)
+ start()
+
+/datum/looping_sound/Destroy()
+ stop()
+ output_atoms = null
+ return ..()
+
+/datum/looping_sound/proc/start(atom/add_thing)
+ if(add_thing)
+ output_atoms |= add_thing
+ if(!muted)
+ return
+ muted = FALSE
+ on_start()
+
+/datum/looping_sound/proc/stop(atom/remove_thing)
+ if(remove_thing)
+ output_atoms -= remove_thing
+ if(muted)
+ return
+ muted = TRUE
+
+/datum/looping_sound/proc/sound_loop(looped = 0)
+ if(muted || (max_loops && looped > max_loops))
+ on_stop(looped)
+ return
+ if(!chance || prob(chance))
+ play(get_sound(looped))
+ addtimer(CALLBACK(src, .proc/sound_loop, ++looped), mid_length)
+
+/datum/looping_sound/proc/play(soundfile)
+ var/list/atoms_cache = output_atoms
+ var/sound/S = sound(soundfile)
+ if(direct)
+ S.channel = open_sound_channel()
+ S.volume = volume
+ for(var/i in 1 to atoms_cache.len)
+ var/atom/thing = atoms_cache[i]
+ if(direct)
+ SEND_SOUND(thing, S)
+ else
+ playsound(thing, S, volume)
+
+/datum/looping_sound/proc/get_sound(looped, _mid_sounds)
+ if(!_mid_sounds)
+ . = mid_sounds
+ else
+ . = _mid_sounds
+ while(!isfile(.) && !isnull(.))
+ . = pickweight(.)
+
+/datum/looping_sound/proc/on_start()
+ var/start_wait = 0
+ if(start_sound)
+ play(start_sound)
+ start_wait = start_length
+ addtimer(CALLBACK(src, .proc/sound_loop), start_wait)
+
+/datum/looping_sound/proc/on_stop(looped)
+ if(end_sound)
+ play(end_sound)
\ No newline at end of file
diff --git a/code/datums/looping_sounds/machinery_sounds.dm b/code/datums/looping_sounds/machinery_sounds.dm
new file mode 100644
index 00000000000..b1f5bdc6908
--- /dev/null
+++ b/code/datums/looping_sounds/machinery_sounds.dm
@@ -0,0 +1,7 @@
+/datum/looping_sound/showering
+ start_sound = 'sound/machines/shower/shower_start.ogg'
+ start_length = 2
+ 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 = 20
\ No newline at end of file
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 5fee7994a83..5094ff4e8d7 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -38,8 +38,8 @@
var/memory
- var/assigned_role
- var/special_role
+ var/assigned_role //assigned role is what job you're assigned to when you join the station.
+ var/special_role //special roles are typically reserved for antags or roles like ERT. If you want to avoid a character being automatically announced by the AI, on arrival (becuase they're an off station character or something); ensure that special_role and assigned_role are equal.
var/list/restricted_roles = list()
var/list/spell_list = list() // Wizard mode & "Give Spell" badmin button.
@@ -54,6 +54,7 @@
var/has_been_rev = 0//Tracks if this mind has been a rev or not
var/miming = 0 // Mime's vow of silence
+ var/list/antag_datums
var/speech_span // What span any body this mind has talks in.
var/datum/faction/faction //associated faction
var/datum/changeling/changeling //changeling holder
@@ -72,17 +73,29 @@
var/brigged_since = -1
var/suicided = FALSE
- New(var/key)
- src.key = key
-
//put this here for easier tracking ingame
var/datum/money_account/initial_account
//zealot_master is a reference to the mob that converted them into a zealot (for ease of investigation and such)
var/mob/living/carbon/human/zealot_master = null
+/datum/mind/New(var/key)
+ src.key = key
+
+
+/datum/mind/Destroy()
+ ticker.minds -= src
+ if(islist(antag_datums))
+ for(var/i in antag_datums)
+ var/datum/antagonist/antag_datum = i
+ if(antag_datum.delete_on_mind_deletion)
+ qdel(i)
+ antag_datums = null
+ return ..()
+
/datum/mind/proc/transfer_to(mob/living/new_character)
var/datum/atom_hud/antag/hud_to_transfer = antag_hud //we need this because leave_hud() will clear this list
+ var/mob/living/old_current = current
if(!istype(new_character))
log_runtime(EXCEPTION("transfer_to(): Some idiot has tried to transfer_to() a non mob/living mob."), src)
if(current) //remove ourself from our old body's mind variable
@@ -95,6 +108,9 @@
new_character.mind.current = null
current = new_character //link ourself to our new body
new_character.mind = src //and link our new body to ourself
+ for(var/a in antag_datums) //Makes sure all antag datums effects are applied in the new body
+ var/datum/antagonist/A = a
+ A.on_body_transfer(old_current, current)
transfer_antag_huds(hud_to_transfer) //inherit the antag HUD
transfer_actions(new_character)
@@ -161,7 +177,7 @@
if(ismindshielded(H))
text = "Mindshield Implant:Remove|Implanted"
else
- text = "Mindshield Implant:No Implant|Implant him!"
+ text = "Mindshield Implant:No Implant|Implant [H.p_them()]!"
sections["implant"] = text
/** REVOLUTION ***/
text = "revolution"
@@ -525,8 +541,8 @@
new_objective = new objective_path
new_objective.owner = src
new_objective:target = new_target:mind
- //Will display as special role if the target is set as MODE. Ninjas/commandos/nuke ops.
- new_objective.explanation_text = "[objective_type] [new_target:real_name], the [new_target:mind:assigned_role=="MODE" ? (new_target:mind:special_role) : (new_target:mind:assigned_role)]."
+ //Will display as special role if assigned mode is equal to special role.. Ninjas/commandos/nuke ops.
+ new_objective.explanation_text = "[objective_type] [new_target:real_name], the [new_target:mind:assigned_role == new_target:mind:special_role ? (new_target:mind:special_role) : (new_target:mind:assigned_role)]."
if("destroy")
var/list/possible_targets = active_ais(1)
@@ -614,7 +630,7 @@
new_objective = new /datum/objective/escape/escape_with_identity
new_objective.owner = src
new_objective.target = new_target
- new_objective.explanation_text = "Escape on the shuttle or an escape pod with the identity of [targ.current.real_name], the [targ.assigned_role] while wearing their identification card."
+ new_objective.explanation_text = "Escape on the shuttle or an escape pod with the identity of [targ.current.real_name], the [targ.assigned_role] while wearing [targ.current.p_their()] identification card."
if("custom")
var/expl = sanitize(copytext(input("Custom objective:", "Objective", objective ? objective.explanation_text : "") as text|null,1,MAX_MESSAGE_LEN))
if(!expl)
@@ -726,7 +742,7 @@
if(src in ticker.mode.revolutionaries)
ticker.mode.revolutionaries -= src
ticker.mode.update_rev_icons_removed(src)
- to_chat(current, "\red You have proven your devotion to revolution! You are a head revolutionary now!")
+ to_chat(current, "You have proven your devotion to revolution! You are a head revolutionary now!")
else if(!(src in ticker.mode.head_revolutionaries))
to_chat(current, "You are a member of the revolutionaries' leadership now!")
else
@@ -1211,37 +1227,60 @@
message_admins("[key_name_admin(usr)] has announced [key_name_admin(current)]'s objectives")
edit_memory()
-/*
-/datum/mind/proc/clear_memory(var/silent = 1)
- var/datum/game_mode/current_mode = ticker.mode
- // remove traitor uplinks
- var/list/L = current.get_contents()
- for(var/t in L)
- if(istype(t, /obj/item/pda))
- if(t:uplink) qdel(t:uplink)
- t:uplink = null
- else if(istype(t, /obj/item/radio))
- if(t:traitorradio) qdel(t:traitorradio)
- t:traitorradio = null
- t:traitor_frequency = 0.0
- else if(istype(t, /obj/item/SWF_uplink) || istype(t, /obj/item/syndicate_uplink))
- if(t:origradio)
- var/obj/item/radio/R = t:origradio
- R.loc = current.loc
- R.traitorradio = null
- R.traitor_frequency = 0.0
- qdel(t)
- // remove wizards spells
- //If there are more special powers that need removal, they can be procced into here./N
- current.spellremove(current)
+// Datum antag mind procs
+/datum/mind/proc/add_antag_datum(datum_type_or_instance, team)
+ if(!datum_type_or_instance)
+ return
+ var/datum/antagonist/A
+ if(!ispath(datum_type_or_instance))
+ A = datum_type_or_instance
+ if(!istype(A))
+ return
+ else
+ A = new datum_type_or_instance()
+ //Choose snowflake variation if antagonist handles it
+ var/datum/antagonist/S = A.specialization(src)
+ if(S && S != A)
+ qdel(A)
+ A = S
+ if(!A.can_be_owned(src))
+ qdel(A)
+ return
+ A.owner = src
+ LAZYADD(antag_datums, A)
+ A.create_team(team)
+ var/datum/team/antag_team = A.get_team()
+ if(antag_team)
+ antag_team.add_member(src)
+ A.on_gain()
+ return A
- // clear memory
- memory = ""
- special_role = null
+/datum/mind/proc/remove_antag_datum(datum_type)
+ if(!datum_type)
+ return
+ var/datum/antagonist/A = has_antag_datum(datum_type)
+ if(A)
+ A.on_removal()
+ return TRUE
-*/
+
+/datum/mind/proc/remove_all_antag_datums() //For the Lazy amongst us.
+ for(var/a in antag_datums)
+ var/datum/antagonist/A = a
+ A.on_removal()
+
+/datum/mind/proc/has_antag_datum(datum_type, check_subtypes = TRUE)
+ if(!datum_type)
+ return
+ . = FALSE
+ for(var/a in antag_datums)
+ var/datum/antagonist/A = a
+ if(check_subtypes && istype(A, datum_type))
+ return A
+ else if(A.type == datum_type)
+ return A
/datum/mind/proc/find_syndicate_uplink()
var/list/L = current.get_contents()
@@ -1273,7 +1312,7 @@
else
current.real_name = "[syndicate_name()] Operative #[ticker.mode.syndicates.len-1]"
special_role = SPECIAL_ROLE_NUKEOPS
- assigned_role = "MODE"
+ assigned_role = SPECIAL_ROLE_NUKEOPS
to_chat(current, "You are a [syndicate_name()] agent!")
ticker.mode.forge_syndicate_objectives(src)
ticker.mode.greet_syndicate(src)
@@ -1308,7 +1347,7 @@
if(!(src in ticker.mode.wizards))
ticker.mode.wizards += src
special_role = SPECIAL_ROLE_WIZARD
- assigned_role = "MODE"
+ assigned_role = SPECIAL_ROLE_WIZARD
//ticker.mode.learn_basic_spells(current)
if(!wizardstart.len)
current.loc = pick(latejoin)
@@ -1510,11 +1549,11 @@
ticker.mode.implanter[ref] = implanters
ticker.mode.traitors += src
special_role = "traitor"
- to_chat(current, "You're now a loyal zealot of [missionary.name]! You now must lay down your life to protect them and assist in their goals at any cost.")
+ to_chat(current, "You're now a loyal zealot of [missionary.name]! You now must lay down your life to protect [missionary.p_them()] and assist in [missionary.p_their()] goals at any cost.")
var/datum/objective/protect/mindslave/MS = new
MS.owner = src
MS.target = missionary.mind
- MS.explanation_text = "Obey every order from and protect [missionary.real_name], the [missionary.mind.assigned_role=="MODE" ? (missionary.mind.special_role) : (missionary.mind.assigned_role)]."
+ MS.explanation_text = "Obey every order from and protect [missionary.real_name], the [missionary.mind.assigned_role == missionary.mind.special_role ? (missionary.mind.special_role) : (missionary.mind.assigned_role)]."
objectives += MS
for(var/datum/objective/objective in objectives)
to_chat(current, "Objective #1: [objective.explanation_text]")
@@ -1538,8 +1577,7 @@
H.update_inv_w_uniform(0,0)
add_attack_logs(missionary, current, "Converted to a zealot for [convert_duration/600] minutes")
- addtimer(src, "remove_zealot", convert_duration, FALSE, jumpsuit) //deconverts after the timer expires
-
+ addtimer(CALLBACK(src, .proc/remove_zealot, jumpsuit), convert_duration) //deconverts after the timer expires
return 1
/datum/mind/proc/remove_zealot(obj/item/clothing/under/jumpsuit = null)
diff --git a/code/datums/modules.dm b/code/datums/modules.dm
deleted file mode 100644
index d01bded3254..00000000000
--- a/code/datums/modules.dm
+++ /dev/null
@@ -1,63 +0,0 @@
-// module datum.
-// this is per-object instance, and shows the condition of the modules in the object
-// actual modules needed is referenced through modulestypes and the object type
-
-/datum/module
- var/status // bits set if working, 0 if broken
- var/installed // bits set if installed, 0 if missing
-
-// moduletypes datum
-// this is per-object type, and shows the modules needed for a type of object
-
-/datum/moduletypes
- var/list/modcount = list() // assoc list of the count of modules for a type
-
-
-var/list/modules = list( // global associative list
-"/obj/machinery/power/apc" = "card_reader,power_control,id_auth,cell_power,cell_charge")
-
-
-/datum/module/New(var/obj/O)
-
- var/type = O.type // the type of the creating object
-
- var/mneed = mods.inmodlist(type) // find if this type has modules defined
-
- if(!mneed) // not found in module list?
- qdel(src) // delete self, thus ending proc
- return
-
- var/needed = mods.getbitmask(type) // get a bitmask for the number of modules in this object
- status = needed
- installed = needed
-
-/datum/moduletypes/proc/addmod(var/type, var/modtextlist)
- modules += type // index by type text
- modules[type] = modtextlist
-
-/datum/moduletypes/proc/inmodlist(var/type)
- return ("[type]" in modules)
-
-/datum/moduletypes/proc/getbitmask(var/type)
- var/count = modcount["[type]"]
- if(count)
- return 2**count-1
-
- var/modtext = modules["[type]"]
- var/num = 1
- var/pos = 1
-
- while(1)
- pos = findtext(modtext, ",", pos, 0)
- if(!pos)
- break
- else
- pos++
- num++
-
- modcount += "[type]"
- modcount["[type]"] = num
-
- return 2**num-1
-
-
diff --git a/code/datums/outfits/outfit_admin.dm b/code/datums/outfits/outfit_admin.dm
index 525880ee314..9e4bba0515c 100644
--- a/code/datums/outfits/outfit_admin.dm
+++ b/code/datums/outfits/outfit_admin.dm
@@ -145,6 +145,7 @@
belt = /obj/item/gun/projectile/automatic/pistol/deagle/camo
l_ear = /obj/item/radio/headset/syndicate/alt
l_pocket = /obj/item/pinpointer/advpinpointer
+ r_pocket = null // stop them getting a radio uplink, they get an implant instead
backpack_contents = list(
/obj/item/storage/box/engineer = 1,
@@ -158,7 +159,6 @@
id_icon = "commander"
id_access = "Syndicate Operative Leader"
- uplink_uses = 500
/datum/outfit/admin/syndicate/officer/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
. = ..()
@@ -613,15 +613,16 @@
uniform = /obj/item/clothing/under/solgov/rep
back = /obj/item/storage/backpack/satchel
+ glasses = /obj/item/clothing/glasses/hud/security/night
gloves = /obj/item/clothing/gloves/color/white
shoes = /obj/item/clothing/shoes/centcom
- l_ear = /obj/item/radio/headset
+ l_ear = /obj/item/radio/headset/ert
id = /obj/item/card/id/silver
r_pocket = /obj/item/lighter/zippo/blue
l_pocket = /obj/item/storage/fancy/cigarettes/cigpack_robustgold
pda = /obj/item/pda
backpack_contents = list(
- /obj/item/storage/box/survival = 1,
+ /obj/item/storage/box/responseteam = 1,
/obj/item/implanter/dust = 1,
/obj/item/implanter/death_alarm = 1,
)
@@ -633,25 +634,33 @@
var/obj/item/card/id/I = H.wear_id
if(istype(I))
- apply_to_card(I, H, get_centcom_access("VIP Guest"), "Solar Federation Representative")
+ apply_to_card(I, H, get_all_accesses(), name, "lifetimeid")
/datum/outfit/admin/solgov
name = "Solar Federation Marine"
uniform = /obj/item/clothing/under/solgov
+ suit = /obj/item/clothing/suit/armor/bulletproof
back = /obj/item/storage/backpack/security
+ belt = /obj/item/storage/belt/military/assault
head = /obj/item/clothing/head/soft/solgov
+ glasses = /obj/item/clothing/glasses/hud/security/night
gloves = /obj/item/clothing/gloves/combat
shoes = /obj/item/clothing/shoes/combat
+ l_ear = /obj/item/radio/headset/ert
id = /obj/item/card/id
l_hand = /obj/item/gun/projectile/automatic/ar
+ r_pocket = /obj/item/flashlight/seclite
+ pda = /obj/item/pda
backpack_contents = list(
- /obj/item/storage/box/survival = 1,
- /obj/item/kitchen/knife/combat = 1,
+ /obj/item/storage/box/responseteam = 1,
/obj/item/ammo_box/magazine/m556 = 3,
- /obj/item/clothing/shoes/magboots = 1
+ /obj/item/clothing/shoes/magboots = 1,
+ /obj/item/gun/projectile/automatic/pistol/m1911 = 1,
+ /obj/item/ammo_box/magazine/m45 = 2
)
+ var/is_tsf_lieutenant = FALSE
/datum/outfit/admin/solgov/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
@@ -659,9 +668,14 @@
if(visualsOnly)
return
+ if(is_tsf_lieutenant)
+ H.real_name = "Lieutenant [pick(last_names)]"
+ else
+ H.real_name = "[pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant First Class", "Master Sergeant", "Sergeant Major")] [pick(last_names)]"
+ H.name = H.real_name
var/obj/item/card/id/I = H.wear_id
if(istype(I))
- apply_to_card(I, H, get_centcom_access("VIP Guest"), name)
+ apply_to_card(I, H, get_all_accesses(), name, "lifetimeid")
/datum/outfit/admin/solgov/lieutenant
name = "Solar Federation Lieutenant"
@@ -670,14 +684,16 @@
head = /obj/item/clothing/head/soft/solgov/command
back = /obj/item/storage/backpack/satchel
l_hand = null
- belt = /obj/item/gun/projectile/automatic/pistol/deagle
+ l_pocket = /obj/item/pinpointer/advpinpointer
backpack_contents = list(
- /obj/item/storage/box/survival = 1,
- /obj/item/kitchen/knife/combat = 1,
+ /obj/item/storage/box/responseteam = 1,
/obj/item/melee/classic_baton/telescopic = 1,
- /obj/item/ammo_box/magazine/m50 = 2,
- /obj/item/clothing/shoes/magboots/advance = 1
+ /obj/item/clothing/shoes/magboots/advance = 1,
+ /obj/item/gun/projectile/automatic/pistol/deagle = 1,
+ /obj/item/ammo_box/magazine/m50 = 2
)
+ is_tsf_lieutenant = TRUE
+
/datum/outfit/admin/chrono
name = "Chrono Legionnaire"
diff --git a/code/datums/spell.dm b/code/datums/spell.dm
index e44c331e556..cc3b85bf94e 100644
--- a/code/datums/spell.dm
+++ b/code/datums/spell.dm
@@ -140,13 +140,13 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
var/obj/effect/proc_holder/spell/noclothes/clothes_spell = locate() in (user.mob_spell_list | (user.mind ? user.mind.spell_list : list()))
if((ishuman(user) && clothes_req) && !istype(clothes_spell))//clothes check
var/mob/living/carbon/human/H = user
- if(!istype(H.wear_suit, /obj/item/clothing/suit/wizrobe) && !istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit/wizard))
+ if(!istype(H.wear_suit, /obj/item/clothing/suit/wizrobe) && !istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit/wizard) && !istype(H.wear_suit, /obj/item/clothing/suit/space/eva/plasmaman/wizard))
to_chat(user, "I don't feel strong enough without my robe.")
return 0
if(!istype(H.shoes, /obj/item/clothing/shoes/sandal))
to_chat(user, "I don't feel strong enough without my sandals.")
return 0
- if(!istype(H.head, /obj/item/clothing/head/wizard) && !istype(H.head, /obj/item/clothing/head/helmet/space/hardsuit/wizard))
+ if(!istype(H.head, /obj/item/clothing/head/wizard) && !istype(H.head, /obj/item/clothing/head/helmet/space/hardsuit/wizard) && !istype(H.wear_suit, /obj/item/clothing/head/helmet/space/eva/plasmaman/wizard))
to_chat(user, "I don't feel strong enough without my hat.")
return 0
else if(!ishuman(user))
diff --git a/code/datums/spells/emplosion.dm b/code/datums/spells/emplosion.dm
index 1ba430ad27e..b2f0a228282 100644
--- a/code/datums/spells/emplosion.dm
+++ b/code/datums/spells/emplosion.dm
@@ -10,6 +10,6 @@
/obj/effect/proc_holder/spell/targeted/emplosion/cast(list/targets, mob/user = usr)
for(var/mob/living/target in targets)
- empulse(target.loc, emp_heavy, emp_light)
+ empulse(target.loc, emp_heavy, emp_light, 1)
- return
\ No newline at end of file
+ return
diff --git a/code/datums/spells/ethereal_jaunt.dm b/code/datums/spells/ethereal_jaunt.dm
index 43c3d3a61cd..6e3ead3849e 100644
--- a/code/datums/spells/ethereal_jaunt.dm
+++ b/code/datums/spells/ethereal_jaunt.dm
@@ -26,7 +26,7 @@
if(!target.can_safely_leave_loc()) // No more brainmobs hopping out of their brains
to_chat(target, "You are somehow too bound to your current location to abandon it.")
continue
- addtimer(src, "do_jaunt", 0, FALSE, target)
+ INVOKE_ASYNC(src, .proc/do_jaunt, target)
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/proc/do_jaunt(mob/living/target)
target.notransform = 1
diff --git a/code/datums/spells/mime.dm b/code/datums/spells/mime.dm
index 296521405a0..19b30674bf6 100644
--- a/code/datums/spells/mime.dm
+++ b/code/datums/spells/mime.dm
@@ -21,7 +21,7 @@
if(!usr.mind.miming)
to_chat(usr, "You must dedicate yourself to silence first.")
return
- invocation = "[usr.real_name] looks as if a wall is in front of them."
+ invocation = "[usr.real_name] looks as if a wall is in front of [usr.p_them()]."
else
invocation_type ="none"
..()
diff --git a/code/datums/spells/mind_transfer.dm b/code/datums/spells/mind_transfer.dm
index 2a8408dfe4a..d6a48d25c68 100644
--- a/code/datums/spells/mind_transfer.dm
+++ b/code/datums/spells/mind_transfer.dm
@@ -32,7 +32,7 @@ Also, you never added distance checking after target is selected. I've went ahea
return
if(!target.key || !target.mind)
- to_chat(user, "They appear to be catatonic. Not even magic can affect their vacant mind.")
+ to_chat(user, "[target.p_they(TRUE)] appear[target.p_s()] to be catatonic. Not even magic can affect [target.p_their()] vacant mind.")
return
if(user.suiciding)
diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm
index 9a5bf86665c..f1c4141720f 100644
--- a/code/datums/uplink_item.dm
+++ b/code/datums/uplink_item.dm
@@ -97,6 +97,7 @@ var/list/uplink_items = list()
if(I)
if(ishuman(user))
var/mob/living/carbon/human/A = user
+ log_game("[key_name(user)] purchased [I.name]")
A.put_in_any_hand_if_possible(I)
if(istype(I,/obj/item/storage/box/) && I.contents.len>0)
@@ -1336,6 +1337,13 @@ var/list/uplink_items = list()
item = /obj/item/storage/fancy/cigarettes/cigpack_syndicate
cost = 2
+/datum/uplink_item/badass/rapid
+ name = "Gloves of the North Star"
+ desc = "These gloves let the user punch people very fast. Does not improve weapon attack speed or the meaty fists of a hulk."
+ reference = "RPGD"
+ item = /obj/item/clothing/gloves/fingerless/rapid
+ cost = 8
+
/datum/uplink_item/badass/bundle
name = "Syndicate Bundle"
desc = "Syndicate Bundles are specialised groups of items that arrive in a plain box. These items are collectively worth more than 20 telecrystals, but you do not know which specialisation you will receive."
@@ -1418,6 +1426,7 @@ var/list/uplink_items = list()
for(var/category in temp_uplink_list)
buyable_items += temp_uplink_list[category]
var/list/bought_items = list()
+ var/list/itemlog = list()
U.uses -= cost
U.used_TC = 20
var/remaining_TC = 50
@@ -1433,8 +1442,10 @@ var/list/uplink_items = list()
continue
bought_items += I.item
remaining_TC -= I.cost
+ itemlog += I.name // To make the name more readable for the log compared to just i.item
U.purchase_log += "[bicon(C)]"
for(var/item in bought_items)
new item(C)
U.purchase_log += "[bicon(item)]"
+ log_game("[key_name(usr)] purchased a surplus crate with [jointext(itemlog, ", ")]")
diff --git a/code/datums/weather/weather.dm b/code/datums/weather/weather.dm
index c87b2b455e7..320cc137806 100644
--- a/code/datums/weather/weather.dm
+++ b/code/datums/weather/weather.dm
@@ -31,7 +31,7 @@
var/list/impacted_areas = list() //Areas to be affected by the weather, calculated when the weather begins
var/target_z = MAIN_STATION //The z-level to affect
var/list/protected_areas = list()//Areas that are protected and excluded from the affected areas.
-
+
var/overlay_layer = 10 //Since it's above everything else, this is the layer used by default. 2 is below mobs and walls if you need to use that.
var/aesthetic = FALSE //If the weather has no purpose other than looks
var/immunity_type = "storm" //Used by mobs to prevent them from being affected by the weather
@@ -70,7 +70,7 @@
to_chat(M, telegraph_message)
if(telegraph_sound)
M << sound(telegraph_sound)
- addtimer(src, "start", telegraph_duration)
+ addtimer(CALLBACK(src, .proc/start), telegraph_duration)
/datum/weather/proc/start()
if(stage >= MAIN_STAGE)
@@ -85,7 +85,7 @@
if(weather_sound)
M << sound(weather_sound)
weather_master.processing_weather |= src
- addtimer(src, "wind_down", weather_duration)
+ addtimer(CALLBACK(src, .proc/wind_down), weather_duration)
/datum/weather/proc/wind_down()
if(stage >= WIND_DOWN_STAGE)
@@ -100,7 +100,7 @@
if(end_sound)
M << sound(end_sound)
weather_master.processing_weather -= src
- addtimer(src, "end", end_duration)
+ addtimer(CALLBACK(src, .proc/end), end_duration)
/datum/weather/proc/end()
if(stage == END_STAGE)
diff --git a/code/datums/wires/vending.dm b/code/datums/wires/vending.dm
index 286ac454efc..054a7e4f669 100644
--- a/code/datums/wires/vending.dm
+++ b/code/datums/wires/vending.dm
@@ -1,5 +1,3 @@
-#define CAT_HIDDEN 2 // Also in code/game/machinery/vending.dm
-
/datum/wires/vending
holder_type = /obj/machinery/vending
wire_count = 4
diff --git a/code/defines/procs/admin.dm b/code/defines/procs/admin.dm
index 0f2a2bd4393..cdf25ce9651 100644
--- a/code/defines/procs/admin.dm
+++ b/code/defines/procs/admin.dm
@@ -76,6 +76,10 @@
var/message = "[key_name(whom, 1)] [isLivingSSD(whom) ? "(SSD!)" : ""] ([admin_jump_link(whom)])"
return message
+/proc/key_name_log(whom)
+ // Key_name_admin, but does not include (?) or jump link - For logging purpose to reduce clutter while figuring out who is SSD and/or antag when being attacked. Also remove formatting since it is not displayed
+ var/message = "[key_name(whom, 0)][isAntag(whom) ? "(ANTAG)" : ""][isLivingSSD(whom) ? "(SSD!)": ""]"
+ return message
/proc/log_and_message_admins(var/message as text)
log_admin("[key_name(usr)] " + message)
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index 83880039a73..8a9a108c7b3 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -42,10 +42,16 @@
power_equip = 0 //rastaf0
power_environ = 0 //rastaf0
- power_change() // all machines set to current power level, also updates lighting icon
-
blend_mode = BLEND_MULTIPLY // Putting this in the constructor so that it stops the icons being screwed up in the map editor.
+/area/Initialize()
+ ..()
+ return INITIALIZE_HINT_LATELOAD
+
+/area/LateInitialize()
+ . = ..()
+ power_change() // all machines set to current power level, also updates lighting icon
+
/area/proc/get_cameras()
var/list/cameras = list()
for(var/obj/machinery/camera/C in src)
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index d57199d5f91..136c8950028 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -42,6 +42,62 @@
var/admin_spawned = 0 //was this spawned by an admin? used for stat tracking stuff.
+ var/initialized = FALSE
+
+/atom/New(loc, ...)
+ if(use_preloader && (src.type == _preloader.target_path))//in case the instanciated atom is creating other atoms in New()
+ _preloader.load(src)
+ . = ..()
+ attempt_init(...)
+
+// This is distinct from /tg/ because of our space management system
+// This is overriden in /atom/movable and the parent isn't called if the SMS wants to deal with it's init
+/atom/proc/attempt_init(loc, ...)
+ var/do_initialize = SSatoms.initialized
+ if(do_initialize != INITIALIZATION_INSSATOMS)
+ args[1] = do_initialize == INITIALIZATION_INNEW_MAPLOAD
+ if(SSatoms.InitAtom(src, args))
+ // we were deleted
+ return
+
+
+//Called after New if the map is being loaded. mapload = TRUE
+//Called from base of New if the map is not being loaded. mapload = FALSE
+//This base must be called or derivatives must set initialized to TRUE
+//must not sleep
+//Other parameters are passed from New (excluding loc), this does not happen if mapload is TRUE
+//Must return an Initialize hint. Defined in __DEFINES/subsystems.dm
+
+//Note: the following functions don't call the base for optimization and must copypasta:
+// /turf/Initialize
+// /turf/open/space/Initialize
+
+/atom/proc/Initialize(mapload, ...)
+ if(initialized)
+ stack_trace("Warning: [src]([type]) initialized multiple times!")
+ initialized = TRUE
+
+ if(light_power && light_range)
+ update_light()
+
+ if(opacity && isturf(loc))
+ var/turf/T = loc
+ T.has_opaque_atom = TRUE // No need to recalculate it in this case, it's guranteed to be on afterwards anyways.
+
+ ComponentInitialize()
+
+ return INITIALIZE_HINT_NORMAL
+
+
+//called if Initialize returns INITIALIZE_HINT_LATELOAD
+/atom/proc/LateInitialize()
+ return
+
+// Put your AddComponent() calls here
+/atom/proc/ComponentInitialize()
+ return
+
+
/atom/proc/onCentcom()
var/turf/T = get_turf(src)
if(!T)
@@ -87,6 +143,12 @@
/atom/proc/setDir(newdir)
dir = newdir
+/atom/proc/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
+ if(does_attack_animation)
+ user.changeNext_move(CLICK_CD_MELEE)
+ add_attack_logs(user, src, "Punched with hulk powers")
+ user.do_attack_animation(src, ATTACK_EFFECT_SMASH)
+
/atom/proc/CheckParts(list/parts_list)
for(var/A in parts_list)
if(istype(A, /datum/reagent))
@@ -242,7 +304,7 @@
/atom/proc/hitby(atom/movable/AM, skipcatch, hitpush, blocked)
if(density && !has_gravity(AM)) //thrown stuff bounces off dense stuff in no grav, unless the thrown stuff ends up inside what it hit(embedding, bola, etc...).
- addtimer(src, "hitby_react", 2, TRUE, AM)
+ addtimer(CALLBACK(src, .proc/hitby_react, AM), 2)
/atom/proc/hitby_react(atom/movable/AM)
if(AM && isturf(AM.loc))
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 3fdc402bb8a..7ab561f0814 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -24,16 +24,19 @@
var/area/areaMaster
- var/auto_init = 1
-
/atom/movable/New()
. = ..()
areaMaster = get_area_master(src)
- // If you're wondering what goofery this is, this is for things that need the environment
- // around them set up - like `air_update_turf` and the like
- if((ticker && ticker.current_state >= GAME_STATE_SETTING_UP))
- attempt_init()
+/atom/movable/attempt_init()
+ if(ticker && ticker.current_state >= GAME_STATE_SETTING_UP)
+ var/turf/T = get_turf(src)
+ if(T && space_manager.is_zlevel_dirty(T.z))
+ space_manager.postpone_init(T.z, src)
+ return
+ . = ..()
+
+
/atom/movable/Destroy()
if(loc)
@@ -53,19 +56,6 @@
pulledby = null
return ..()
-// used to provide a good interface for the init delay system to step in
-// and we don't need to call `get_turf` until the game's started
-// at which point object creations are a fair toss more seldom
-/atom/movable/proc/attempt_init()
- var/turf/T = get_turf(src)
- if(T && space_manager.is_zlevel_dirty(T.z))
- space_manager.postpone_init(T.z, src)
- else if(auto_init)
- initialize()
-
-/atom/movable/proc/initialize()
- return
-
// Used in shuttle movement and AI eye stuff.
// Primarily used to notify objects being moved by a shuttle/bluespace fuckup.
/atom/movable/proc/setLoc(var/T, var/teleported=0)
@@ -176,11 +166,11 @@
/mob/living/forceMove(atom/destination)
if(buckled)
- addtimer(src, "check_buckled", 1, TRUE)
+ addtimer(CALLBACK(src, .proc/check_buckled), 1, TIMER_UNIQUE)
if(buckled_mob)
- addtimer(buckled_mob, "check_buckled", 1, TRUE)
+ addtimer(CALLBACK(buckled_mob, .proc/check_buckled), 1, TIMER_UNIQUE)
if(pulling)
- addtimer(src, "check_pull", 1, TRUE)
+ addtimer(CALLBACK(src, .proc/check_pull), 1, TIMER_UNIQUE)
. = ..()
if(client)
reset_perspective(destination)
@@ -373,3 +363,70 @@
target.fingerprints += fingerprints
target.fingerprintshidden += fingerprintshidden
target.fingerprintslast = fingerprintslast
+
+/atom/movable/proc/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y)
+ if(!no_effect && (visual_effect_icon || used_item))
+ do_item_attack_animation(A, visual_effect_icon, used_item)
+
+ if(A == src)
+ return //don't do an animation if attacking self
+ var/pixel_x_diff = 0
+ var/pixel_y_diff = 0
+ var/final_pixel_y = initial(pixel_y)
+ if(end_pixel_y)
+ final_pixel_y = end_pixel_y
+
+ var/direction = get_dir(src, A)
+ if(direction & NORTH)
+ pixel_y_diff = 8
+ else if(direction & SOUTH)
+ pixel_y_diff = -8
+
+ if(direction & EAST)
+ pixel_x_diff = 8
+ else if(direction & WEST)
+ pixel_x_diff = -8
+
+ animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, time = 2)
+ animate(pixel_x = initial(pixel_x), pixel_y = final_pixel_y, time = 2)
+
+/atom/movable/proc/do_item_attack_animation(atom/A, visual_effect_icon, obj/item/used_item)
+ var/image/I
+ if(visual_effect_icon)
+ I = image('icons/effects/effects.dmi', A, visual_effect_icon, A.layer + 0.1)
+ else if(used_item)
+ I = image(used_item.icon, A, used_item.icon_state, A.layer + 0.1)
+
+ // Scale the icon.
+ I.transform *= 0.75
+ // The icon should not rotate.
+ I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
+
+ // Set the direction of the icon animation.
+ var/direction = get_dir(src, A)
+ if(direction & NORTH)
+ I.pixel_y = -16
+ else if(direction & SOUTH)
+ I.pixel_y = 16
+
+ if(direction & EAST)
+ I.pixel_x = -16
+ else if(direction & WEST)
+ I.pixel_x = 16
+
+ if(!direction) // Attacked self?!
+ I.pixel_z = 16
+
+ if(!I)
+ return
+
+ // Who can see the attack?
+ var/list/viewing = list()
+ for(var/mob/M in viewers(A))
+ if(M.client && M.client.prefs.show_ghostitem_attack)
+ viewing |= M.client
+
+ flick_overlay(I, viewing, 5) // 5 ticks/half a second
+
+ // And animate the attack!
+ animate(I, alpha = 175, pixel_x = 0, pixel_y = 0, pixel_z = 0, time = 3)
\ No newline at end of file
diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm
index 99355320491..93d9977b5e8 100644
--- a/code/game/dna/dna_modifier.dm
+++ b/code/game/dna/dna_modifier.dm
@@ -192,7 +192,7 @@
return
for(var/mob/living/carbon/slime/M in range(1,L))
if(M.Victim == L)
- to_chat(usr, "[L.name] will not fit into the [src] because they have a slime latched onto their head.")
+ to_chat(usr, "[L.name] will not fit into the [src] because [L.p_they()] [L.p_have()] a slime latched onto [L.p_their()] head.")
return
if(L == user)
visible_message("[user] climbs into the [src].")
diff --git a/code/game/dna/genes/goon_powers.dm b/code/game/dna/genes/goon_powers.dm
index 6fbc30883ca..37292beb8fe 100644
--- a/code/game/dna/genes/goon_powers.dm
+++ b/code/game/dna/genes/goon_powers.dm
@@ -179,8 +179,7 @@
C.ExtinguishMob()
C.visible_message("[user] sprays a cloud of fine ice crystals, engulfing [C]!")
- log_attack(user, C, "Used cryokinesis on a victim without internals or a suit")
- msg_admin_attack("[key_name_admin(user)] has cast cryokinesis on [key_name_admin(C)] (NO SUIT)")
+ add_attack_logs(user, C, "Cryokinesis- NO SUIT/INTERNALS")
//playsound(user.loc, 'bamf.ogg', 50, 0)
@@ -318,14 +317,6 @@
var/atom/movable/the_item = targets[1]
if(ishuman(the_item))
- //My gender
- var/m_his = "his"
- if(user.gender == FEMALE)
- m_his = "her"
- // Their gender
- var/t_his = "his"
- if(the_item.gender == FEMALE)
- t_his = "her"
var/mob/living/carbon/human/H = the_item
var/obj/item/organ/external/limb = H.get_organ(user.zone_sel.selecting)
if(!istype(limb))
@@ -334,15 +325,15 @@
return 0
if(istype(limb,/obj/item/organ/external/head))
// Bullshit, but prevents being unable to clone someone.
- to_chat(user, "You try to put \the [limb] in your mouth, but [t_his] ears tickle your throat!")
+ to_chat(user, "You try to put \the [limb] in your mouth, but [the_item.p_their()] ears tickle your throat!")
revert_cast()
return 0
if(istype(limb,/obj/item/organ/external/chest))
// Bullshit, but prevents being able to instagib someone.
- to_chat(user, "You try to put their [limb] in your mouth, but it's too big to fit!")
+ to_chat(user, "You try to put [the_item.p_their()] [limb] in your mouth, but it's too big to fit!")
revert_cast()
return 0
- user.visible_message("[user] begins stuffing [the_item]'s [limb.name] into [m_his] gaping maw!")
+ user.visible_message("[user] begins stuffing [the_item]'s [limb.name] into [user.p_their()] gaping maw!")
var/oldloc = H.loc
if(!do_mob(user,H,EAT_MOB_DELAY))
to_chat(user, "You were interrupted before you could eat [the_item]!")
@@ -434,7 +425,7 @@
user.flying = prevFlying
if(FAT in user.mutations && prob(66))
- user.visible_message("[user.name] crashes due to their heavy weight!")
+ user.visible_message("[user.name] crashes due to [user.p_their()] heavy weight!")
//playsound(user.loc, 'zhit.wav', 50, 1)
user.AdjustWeakened(10)
user.AdjustStunned(5)
@@ -559,10 +550,10 @@
return
if(M.stat == 2)
- to_chat(user, "[M.name] is dead and cannot have their mind read.")
+ to_chat(user, "[M.name] is dead and cannot have [M.p_their()] mind read.")
return
if(M.health < 0)
- to_chat(user, "[M.name] is dying, and their thoughts are too scrambled to read.")
+ to_chat(user, "[M.name] is dying, and [M.p_their()] thoughts are too scrambled to read.")
return
to_chat(user, "Mind Reading of [M.name]:")
@@ -570,8 +561,8 @@
var/pain_condition = M.health / M.maxHealth
// lower health means more pain
var/list/randomthoughts = list("what to have for lunch","the future","the past","money",
- "their hair","what to do next","their job","space","amusing things","sad things",
- "annoying things","happy things","something incoherent","something they did wrong")
+ "[M.p_their()] hair","what to do next","[M.p_their()] job","space","amusing things","sad things",
+ "annoying things","happy things","something incoherent","something [M.p_they()] did wrong")
var/thoughts = "thinking about [pick(randomthoughts)]"
if(M.fire_stacks)
@@ -592,7 +583,7 @@
to_chat(user, "Condition: [M.name] is suffering severe pain.")
else
to_chat(user, "Condition: [M.name] is suffering excruciating pain.")
- thoughts = "haunted by their own mortality"
+ thoughts = "haunted by [M.p_their()] own mortality"
switch(M.a_intent)
if(INTENT_HELP)
@@ -655,7 +646,7 @@
action_icon_state = "superfart"
/obj/effect/proc_holder/spell/aoe_turf/superfart/invocation(mob/user = usr)
- invocation = "[user] hunches down and grits their teeth!"
+ invocation = "[user] hunches down and grits [user.p_their()] teeth!"
invocation_emote_self = "You hunch down and grit your teeth!"
..(user)
diff --git a/code/game/dna/genes/vg_powers.dm b/code/game/dna/genes/vg_powers.dm
index bfd75f486e0..3e709560a45 100644
--- a/code/game/dna/genes/vg_powers.dm
+++ b/code/game/dna/genes/vg_powers.dm
@@ -173,7 +173,7 @@
M.update_dna()
- M.visible_message("[src] morphs and changes [M.get_visible_gender() == MALE ? "his" : M.get_visible_gender() == FEMALE ? "her" : "their"] appearance!", "You change your appearance!", "Oh, god! What the hell was that? It sounded like flesh getting squished and bone ground into a different shape!")
+ M.visible_message("[src] morphs and changes [p_their()] appearance!", "You change your appearance!", "Oh, god! What the hell was that? It sounded like flesh getting squished and bone ground into a different shape!")
/datum/dna/gene/basic/grant_spell/remotetalk
name="Telepathy"
diff --git a/code/game/gamemodes/blob/blob.dm b/code/game/gamemodes/blob/blob.dm
index 0bcd942b7a0..80bba117a20 100644
--- a/code/game/gamemodes/blob/blob.dm
+++ b/code/game/gamemodes/blob/blob.dm
@@ -119,7 +119,7 @@ var/list/blob_nodes = list()
if(!is_station_level(location.z) || istype(location, /turf/space))
if(!warned)
to_chat(C, "You feel ready to burst, but this isn't an appropriate place! You must return to the station!")
- message_admins("[key_name_admin(C)] was in space when the blobs burst, and will die if he doesn't return to the station.")
+ message_admins("[key_name_admin(C)] was in space when the blobs burst, and will die if [C.p_they()] [C.p_do()] not return to the station.")
spawn(300)
burst_blob(blob, 1)
else
diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm
index c6dc0833afb..bae37c04c2c 100644
--- a/code/game/gamemodes/blob/blobs/blob_mobs.dm
+++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm
@@ -62,7 +62,7 @@
factory.spores += src
..()
-/mob/living/simple_animal/hostile/blob/blobspore/Life()
+/mob/living/simple_animal/hostile/blob/blobspore/Life(seconds, times_fired)
if(!is_zombie && isturf(src.loc))
for(var/mob/living/carbon/human/H in oview(src,1)) //Only for corpse right next to/on same tile
diff --git a/code/game/gamemodes/blob/blobs/core.dm b/code/game/gamemodes/blob/blobs/core.dm
index 9dcb5b7e3eb..0e1fc7daa86 100644
--- a/code/game/gamemodes/blob/blobs/core.dm
+++ b/code/game/gamemodes/blob/blobs/core.dm
@@ -60,7 +60,7 @@
/obj/structure/blob/core/RegenHealth()
return // Don't regen, we handle it in Life()
-/obj/structure/blob/core/Life()
+/obj/structure/blob/core/Life(seconds, times_fired)
if(!overmind)
create_overmind()
else
diff --git a/code/game/gamemodes/blob/blobs/node.dm b/code/game/gamemodes/blob/blobs/node.dm
index 232511744ea..19ac320287a 100644
--- a/code/game/gamemodes/blob/blobs/node.dm
+++ b/code/game/gamemodes/blob/blobs/node.dm
@@ -28,7 +28,7 @@
processing_objects.Remove(src)
return ..()
-/obj/structure/blob/node/Life()
+/obj/structure/blob/node/Life(seconds, times_fired)
if(overmind)
for(var/i = 1; i < 8; i += i)
Pulse(5, i, overmind.blob_reagent_datum.color)
diff --git a/code/game/gamemodes/blob/overmind.dm b/code/game/gamemodes/blob/overmind.dm
index 5da84fbc460..60ea94befb0 100644
--- a/code/game/gamemodes/blob/overmind.dm
+++ b/code/game/gamemodes/blob/overmind.dm
@@ -36,7 +36,7 @@
updateallghostimages()
..()
-/mob/camera/blob/Life()
+/mob/camera/blob/Life(seconds, times_fired)
if(!blob_core)
qdel(src)
..()
diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm
index e53a74c8daa..15a3b2e222f 100644
--- a/code/game/gamemodes/blob/theblob.dm
+++ b/code/game/gamemodes/blob/theblob.dm
@@ -147,6 +147,9 @@
..()
take_damage(power/400, BURN)
+/obj/structure/blob/hulk_damage()
+ return 15
+
/obj/structure/blob/attackby(var/obj/item/W, var/mob/living/user, params)
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src)
diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm
index a9c5882094d..329408bffce 100644
--- a/code/game/gamemodes/changeling/changeling.dm
+++ b/code/game/gamemodes/changeling/changeling.dm
@@ -113,7 +113,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
identity_theft.target_real_name = kill_objective.target.current.real_name //Whoops, forgot this.
var/mob/living/carbon/human/H = identity_theft.target.current
if(can_absorb_species(H.species)) // For species that can't be absorbed - should default to an escape objective
- identity_theft.explanation_text = "Escape on the shuttle or an escape pod with the identity of [identity_theft.target_real_name], the [identity_theft.target.assigned_role] while wearing their identification card."
+ identity_theft.explanation_text = "Escape on the shuttle or an escape pod with the identity of [identity_theft.target_real_name], the [identity_theft.target.assigned_role] while wearing [identity_theft.target.p_their()] identification card."
changeling.objectives += identity_theft
else
qdel(identity_theft)
diff --git a/code/game/gamemodes/changeling/powers/absorb.dm b/code/game/gamemodes/changeling/powers/absorb.dm
index e9ae34d2cfa..b60cfee4718 100644
--- a/code/game/gamemodes/changeling/powers/absorb.dm
+++ b/code/game/gamemodes/changeling/powers/absorb.dm
@@ -73,8 +73,8 @@
recent_speech = target.say_log.Copy()
if(recent_speech.len)
- user.mind.store_memory("Some of [target]'s speech patterns, we should study these to better impersonate them!")
- to_chat(user, "Some of [target]'s speech patterns, we should study these to better impersonate them!")
+ user.mind.store_memory("Some of [target]'s speech patterns. We should study these to better impersonate [target.p_them()]!")
+ to_chat(user, "Some of [target]'s speech patterns. We should study these to better impersonate [target.p_them()]!")
for(var/spoken_memory in recent_speech)
user.mind.store_memory("\"[spoken_memory]\"")
to_chat(user, "\"[spoken_memory]\"")
diff --git a/code/game/gamemodes/changeling/powers/biodegrade.dm b/code/game/gamemodes/changeling/powers/biodegrade.dm
index 5e4b0e7fa12..5142734183b 100644
--- a/code/game/gamemodes/changeling/powers/biodegrade.dm
+++ b/code/game/gamemodes/changeling/powers/biodegrade.dm
@@ -16,18 +16,18 @@
var/obj/O = user.get_item_by_slot(slot_handcuffed)
if(!istype(O))
return FALSE
- user.visible_message("[user] vomits a glob of acid on \his [O]!", \
+ user.visible_message("[user] vomits a glob of acid on [user.p_their()] [O.name]!", \
"We vomit acidic ooze onto our restraints!")
- addtimer(src, "dissolve_handcuffs", 30, FALSE, user, O)
+ addtimer(CALLBACK(src, .proc/dissolve_handcuffs, user, O), 30)
used = TRUE
if(user.wear_suit && user.wear_suit.breakouttime && !used)
var/obj/item/clothing/suit/S = user.get_item_by_slot(slot_wear_suit)
if(!istype(S))
return FALSE
- user.visible_message("[user] vomits a glob of acid across the front of \his [S]!", \
+ user.visible_message("[user] vomits a glob of acid across the front of [user.p_their()] [S.name]!", \
"We vomit acidic ooze onto our straight jacket!")
- addtimer(src, "dissolve_straightjacket", 30, FALSE, user, S)
+ addtimer(CALLBACK(src, .proc/dissolve_straightjacket, user, S), 30)
used = TRUE
@@ -37,7 +37,7 @@
return FALSE
C.visible_message("[C]'s hinges suddenly begin to melt and run!")
to_chat(user, "We vomit acidic goop onto the interior of [C]!")
- addtimer(src, "open_closet", 70, FALSE, user, C)
+ addtimer(CALLBACK(src, .proc/open_closet, user, C), 70)
used = TRUE
if(istype(user.loc, /obj/structure/spider/cocoon) && !used)
@@ -46,7 +46,7 @@
return FALSE
C.visible_message("[src] shifts and starts to fall apart!")
to_chat(user, "We secrete acidic enzymes from our skin and begin melting our cocoon...")
- addtimer(src, "dissolve_cocoon", 25, FALSE, user, C) //Very short because it's just webs
+ addtimer(CALLBACK(src, .proc/dissolve_cocoon, user, C), 25) //Very short because it's just webs
used = TRUE
if(used)
diff --git a/code/game/gamemodes/changeling/powers/fakedeath.dm b/code/game/gamemodes/changeling/powers/fakedeath.dm
index 156e8ffb896..a166fd74502 100644
--- a/code/game/gamemodes/changeling/powers/fakedeath.dm
+++ b/code/game/gamemodes/changeling/powers/fakedeath.dm
@@ -17,7 +17,7 @@
user.status_flags |= FAKEDEATH //play dead
user.update_canmove()
- addtimer(src, "ready_to_regenerate", LING_FAKEDEATH_TIME, FALSE, user)
+ addtimer(CALLBACK(src, .proc/ready_to_regenerate, user), LING_FAKEDEATH_TIME)
feedback_add_details("changeling_powers","FD")
return 1
diff --git a/code/game/gamemodes/changeling/powers/fleshmend.dm b/code/game/gamemodes/changeling/powers/fleshmend.dm
index 08786b6d6db..56417ac4335 100644
--- a/code/game/gamemodes/changeling/powers/fleshmend.dm
+++ b/code/game/gamemodes/changeling/powers/fleshmend.dm
@@ -31,7 +31,7 @@
by quick repeated use!")
recent_uses++
- addtimer(src, "fleshmend", 0, FALSE, user)
+ INVOKE_ASYNC(src, .proc/fleshmend, user)
feedback_add_details("changeling_powers","RR")
return TRUE
diff --git a/code/game/gamemodes/changeling/powers/linglink.dm b/code/game/gamemodes/changeling/powers/linglink.dm
index 4b59c255128..52de921d7ec 100644
--- a/code/game/gamemodes/changeling/powers/linglink.dm
+++ b/code/game/gamemodes/changeling/powers/linglink.dm
@@ -47,7 +47,7 @@
to_chat(user, "We stealthily stab [target] with a minor proboscis...")
to_chat(target, "You experience a stabbing sensation and your ears begin to ring...")
if(3)
- to_chat(user, "You mold the [target]'s mind like clay, they can now speak in the hivemind!")
+ to_chat(user, "You mold the [target]'s mind like clay, [target.p_they()] can now speak in the hivemind!")
to_chat(target, "A migraine throbs behind your eyes, you hear yourself screaming - but your mouth has not opened!")
for(var/mob/M in mob_list)
if(all_languages["Changeling"] in M.languages)
diff --git a/code/game/gamemodes/changeling/powers/mutations.dm b/code/game/gamemodes/changeling/powers/mutations.dm
index 4e084e8b720..4cf998cf043 100644
--- a/code/game/gamemodes/changeling/powers/mutations.dm
+++ b/code/game/gamemodes/changeling/powers/mutations.dm
@@ -25,13 +25,13 @@
if(istype(user.l_hand, weapon_type)) //Not the nicest way to do it, but eh
qdel(user.l_hand)
if(!silent)
- user.visible_message("With a sickening crunch, [user] reforms his [weapon_name_simple] into an arm!", "We assimilate the [weapon_name_simple] back into our body.", "With a sickening crunch, [user] reforms [user.p_their()] [weapon_name_simple] into an arm!", "We assimilate the [weapon_name_simple] back into our body.", "With a sickening crunch, [user] reforms his [weapon_name_simple] into an arm!", "We assimilate the [weapon_name_simple] back into our body.", "With a sickening crunch, [user] reforms [user.p_their()] [weapon_name_simple] into an arm!", "We assimilate the [weapon_name_simple] back into our body.", "[H] casts off their [suit_name_simple]!", "We cast off our [suit_name_simple][genetic_damage > 0 ? ", temporarily weakening our genomes." : "."]", "You hear the organic matter ripping and tearing!")
+ H.visible_message("[H] casts off [H.p_their()] [suit_name_simple]!", "We cast off our [suit_name_simple][genetic_damage > 0 ? ", temporarily weakening our genomes." : "."]", "You hear the organic matter ripping and tearing!")
qdel(H.wear_suit)
qdel(H.head)
H.update_inv_wear_suit()
@@ -138,7 +138,7 @@
loc.visible_message("A grotesque blade forms around [loc.name]\'s arm!", "Our arm twists and mutates, transforming it into a deadly blade.", "You hear organic matter ripping and tearing!")
/obj/item/melee/arm_blade/dropped(mob/user)
- user.visible_message("With a sickening crunch, [user] reforms his blade into an arm!", "We assimilate the blade back into our body.", "With a sickening crunch, [user] reforms [user.p_their()] blade into an arm!", "We assimilate the blade back into our body.", "[user] forces the airlock to open with \his [src]!", "We force the airlock to open.", "You hear a metal screeching sound.")
+ user.visible_message("[user] forces the airlock to open with [user.p_their()] [name]!", "We force the airlock to open.", "You hear a metal screeching sound.")
A.open(2)
/***************************************\
@@ -219,7 +219,7 @@
to_chat(user, "The [name] is not ready yet.")
/obj/item/gun/magic/tentacle/suicide_act(mob/user)
- user.visible_message("[user] coils [src] tightly around \his neck! It looks like \he's trying to commit suicide.")
+ user.visible_message("[user] coils [src] tightly around [user.p_their()] neck! It looks like [user.p_theyre()] trying to commit suicide.")
return (OXYLOSS)
/obj/item/ammo_casing/magic/tentacle
@@ -278,7 +278,7 @@
C.visible_message("[src] impales [C] with [I]!", "[src] impales you with [I]!")
C.apply_damage(I.force, BRUTE, "chest")
- do_attack_animation(C)
+ do_item_attack_animation(C, used_item = I)
add_blood(C)
playsound(get_turf(src), I.hitsound, 75, 1)
@@ -386,7 +386,7 @@
if(remaining_uses < 1)
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
- H.visible_message("With a sickening crunch, [H] reforms his shield into an arm!", "We assimilate our shield into our body", "With a sickening crunch, [H] reforms [H.p_their()] shield into an arm!", "We assimilate our shield into our body", "[loc.name]\'s flesh rapidly inflates, forming a bloated mass around their body!", "We inflate our flesh, creating a spaceproof suit!", "You hear organic matter ripping and tearing!")
+ loc.visible_message("[loc.name]\'s flesh rapidly inflates, forming a bloated mass around [loc.p_their()] body!", "We inflate our flesh, creating a spaceproof suit!", "You hear organic matter ripping and tearing!")
processing_objects += src
/obj/item/clothing/suit/space/changeling/process()
@@ -485,4 +485,4 @@
icon_state = "lingarmorhelmet"
flags = BLOCKHAIR | NODROP | DROPDEL
armor = list(melee = 30, bullet = 30, laser = 40, energy = 20, bomb = 10, bio = 4, rad = 0)
- flags_inv = HIDEEARS
\ No newline at end of file
+ flags_inv = HIDEEARS
diff --git a/code/game/gamemodes/changeling/powers/swap_form.dm b/code/game/gamemodes/changeling/powers/swap_form.dm
index 99eb634a2ff..9015677c70e 100644
--- a/code/game/gamemodes/changeling/powers/swap_form.dm
+++ b/code/game/gamemodes/changeling/powers/swap_form.dm
@@ -36,7 +36,7 @@
to_chat(user, "The body swap has been interrupted!")
return
- to_chat(target, "[user] tightens their grip as a painful sensation invades your body.")
+ to_chat(target, "[user] tightens [user.p_their()] grip as a painful sensation invades your body.")
changeling.absorbed_dna -= changeling.find_dna(user.dna)
changeling.protected_dna -= changeling.find_dna(user.dna)
diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm
index b12a50bce13..f2e8db26b40 100644
--- a/code/game/gamemodes/cult/cult.dm
+++ b/code/game/gamemodes/cult/cult.dm
@@ -203,7 +203,7 @@ var/global/list/all_cults = list()
update_cult_icons_removed(cult_mind)
if(show_message)
for(var/mob/M in viewers(cult_mind.current))
- to_chat(M, "[cult_mind.current] looks like they just reverted to their old faith!")
+ to_chat(M, "[cult_mind.current] looks like [cult_mind.current.p_they()] just reverted to [cult_mind.current.p_their()] old faith!")
/datum/game_mode/proc/update_cult_icons_added(datum/mind/cult_mind)
diff --git a/code/game/gamemodes/cult/cult_objectives.dm b/code/game/gamemodes/cult/cult_objectives.dm
index 5ddc8ccdf98..34955ed42d4 100644
--- a/code/game/gamemodes/cult/cult_objectives.dm
+++ b/code/game/gamemodes/cult/cult_objectives.dm
@@ -24,7 +24,7 @@
spilltarget = 100 + rand(0,player_list.len * 3)
explanation = "We must prepare this place for [ticker.cultdat.entity_title1]'s coming. Spill blood and gibs over [spilltarget] floor tiles."
if("sacrifice")
- explanation = "We need to sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role], for their blood is the key that will lead our master to this realm. You will need 3 cultists around a Sacrifice rune to perform the ritual."
+ explanation = "We need to sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role], for [sacrifice_target.p_their()] blood is the key that will lead our master to this realm. You will need 3 cultists around a Sacrifice rune to perform the ritual."
for(var/datum/mind/cult_mind in cult)
to_chat(cult_mind.current, "Objective #[current_objective]: [explanation]")
@@ -81,7 +81,7 @@
spilltarget = 100 + rand(0,player_list.len * 3)
explanation = "We must prepare this place for [ticker.cultdat.entity_title1]'s coming. Spread blood and gibs over [spilltarget] of the Station's floor tiles."
if("sacrifice")
- explanation = "We need to sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role], for their blood is the key that will lead our master to this realm. You will need 3 cultists around a Sacrifice rune to perform the ritual."
+ explanation = "We need to sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role], for [sacrifice_target.p_their()] blood is the key that will lead our master to this realm. You will need 3 cultists around a Sacrifice rune to perform the ritual."
for(var/datum/mind/cult_mind in cult)
if(cult_mind)
diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm
index 19f9f57e9e7..a16cf76d9f1 100644
--- a/code/game/gamemodes/cult/ritual.dm
+++ b/code/game/gamemodes/cult/ritual.dm
@@ -294,7 +294,7 @@
var/mob/living/carbon/human/H = user
var/dam_zone = pick("head", "chest", "groin", "l_arm", "l_hand", "r_arm", "r_hand", "l_leg", "l_foot", "r_leg", "r_foot")
var/obj/item/organ/external/affecting = H.get_organ(ran_zone(dam_zone))
- user.visible_message("[user] cuts open their [affecting] and begins writing in their own blood!", "You slice open your [affecting] and begin drawing a sigil of [ticker.cultdat.entity_title3].")
+ user.visible_message("[user] cuts open [user.p_their()] [affecting] and begins writing in [user.p_their()] own blood!", "You slice open your [affecting] and begin drawing a sigil of [ticker.cultdat.entity_title3].")
user.apply_damage(initial(rune_to_scribe.scribe_damage), BRUTE , affecting)
if(!do_after(user, initial(rune_to_scribe.scribe_delay)-scribereduct, target = get_turf(user)))
for(var/V in shields)
@@ -305,7 +305,7 @@
if(locate(/obj/effect/rune) in runeturf)
to_chat(user, "There is already a rune here.")
return
- user.visible_message("[user] creates a strange circle in their own blood.", \
+ user.visible_message("[user] creates a strange circle in [user.p_their()] own blood.", \
"You finish drawing the arcane markings of [ticker.cultdat.entity_title3].")
for(var/V in shields)
var/obj/machinery/shield/S = V
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index 2bf4933e108..e014fa07785 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -700,7 +700,7 @@ var/list/teleport_runes = list()
return
mob_to_revive.revive() //This does remove disabilities and such, but the rune might actually see some use because of it!
to_chat(mob_to_revive, "\"PASNAR SAVRAE YAM'TOTH. Arise.\"")
- mob_to_revive.visible_message("[mob_to_revive] draws in a huge breath, red light shining from their eyes.", \
+ mob_to_revive.visible_message("[mob_to_revive] draws in a huge breath, red light shining from [mob_to_revive.p_their()] eyes.", \
"You awaken suddenly from the void. You're alive!")
rune_in_use = 0
@@ -740,7 +740,7 @@ var/list/teleport_runes = list()
to_chat(L, "You chant in unison and a colossal burst of energy knocks you backward!")
L.Weaken(2)
qdel(src) //delete before pulsing because it's a delay reee
- empulse(E, 9*invokers.len, 12*invokers.len) // Scales now, from a single room to most of the station depending on # of chanters
+ empulse(E, 9*invokers.len, 12*invokers.len, 1) // Scales now, from a single room to most of the station depending on # of chanters
//Rite of Astral Communion: Separates one's spirit from their body. They will take damage while it is active.
/obj/effect/rune/astral
@@ -787,11 +787,11 @@ var/list/teleport_runes = list()
return
affecting.apply_damage(1, BRUTE)
if(!(user in T.contents))
- user.visible_message("A spectral tendril wraps around [user] and pulls them back to the rune!")
+ user.visible_message("A spectral tendril wraps around [user] and pulls [user.p_them()] back to the rune!")
Beam(user,icon_state="drainbeam",time=2)
user.forceMove(get_turf(src)) //NO ESCAPE :^)
if(user.key)
- user.visible_message("[user] slowly relaxes, the glow around them dimming.", \
+ user.visible_message("[user] slowly relaxes, the glow around [user.p_them()] dimming.", \
"You are re-united with your physical form. [src] releases its hold over you.")
user.color = initial(user.color)
user.Weaken(3)
@@ -833,7 +833,7 @@ var/list/teleport_runes = list()
var/mob/living/user = invokers[1]
..()
density = !density
- user.visible_message("[user] places their hands on [src], and [density ? "the air above it begins to shimmer" : "the shimmer above it fades"].", \
+ user.visible_message("[user] places [user.p_their()] hands on [src], and [density ? "the air above it begins to shimmer" : "the shimmer above it fades"].", \
"You channel your life energy into [src], [density ? "preventing" : "allowing"] passage above it.")
if(iscarbon(user))
var/mob/living/carbon/C = user
diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm
index e909a33410f..8d858c6fade 100644
--- a/code/game/gamemodes/cult/talisman.dm
+++ b/code/game/gamemodes/cult/talisman.dm
@@ -151,7 +151,7 @@
if(!src || QDELETED(src) || !user || user.l_hand != src && user.r_hand != src || user.incapacitated() || !actual_selected_rune)
return ..(user, 0)
- user.visible_message("Dust flows from [user]'s hand, and they disappear in a flash of red light!", \
+ user.visible_message("Dust flows from [user]'s hand, and [user.p_they()] disappear[user.p_s()] in a flash of red light!", \
"You speak the words of the talisman and find yourself somewhere else!")
user.forceMove(get_turf(actual_selected_rune))
return ..()
@@ -220,7 +220,7 @@
. = ..()
user.visible_message("[user]'s hand flashes a bright blue!", \
"You speak the words of the talisman, emitting an EMP blast.")
- empulse(src, 4, 8)
+ empulse(src, 4, 8, 1)
//Rite of Disorientation: Stuns and inhibit speech on a single target for quite some time
@@ -419,4 +419,4 @@
/obj/item/restraints/handcuffs/energy/cult/used/dropped(mob/user)
user.visible_message("[user]'s shackles shatter in a discharge of dark magic!", \
"Your [src] shatters in a discharge of dark magic!")
- . = ..()
\ No newline at end of file
+ . = ..()
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 4a2622c536d..760868e8435 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -107,7 +107,7 @@
tries_left = 5 //reset our tries since we found a new chump
//make sure we have chumps before we try misinforming them. if we don't make a note of it.
if(!chumps.len)
- log_debug("Game mode failed to find ANY chumps. This is likely due to the server being in extreme low-pop with no one set to opposed or skeptical.")
+ log_debug("Game mode failed to find ANY chumps. This is likely due to the server being in extreme low-pop with no one set to opposed or skeptical.")
return 0
//we've got chumps! misinform them!
for(var/mob/living/carbon/human/chump in chumps)
@@ -490,34 +490,39 @@ proc/display_roundstart_logout_report()
M.ghostize()
M.key = theghost.key
else
- message_admins("[M] ([M.key] has been converted into [role_type] with an active antagonist jobban for said role since no ghost has volunteered to take their place.")
+ message_admins("[M] ([M.key] has been converted into [role_type] with an active antagonist jobban for said role since no ghost has volunteered to take [M.p_their()] place.")
to_chat(M, "You have been converted into [role_type] with an active jobban. Any further violations of the rules on your part are likely to result in a permanent ban.")
-/datum/game_mode/proc/printplayer(datum/mind/ply, fleecheck)
- var/text = "
[ply.key] was [ply.name] the [ply.assigned_role] and"
+/proc/printplayer(datum/mind/ply, fleecheck)
+ var/jobtext = ""
+ if(ply.assigned_role)
+ jobtext = " the [ply.assigned_role]"
+ var/text = "[ply.key] was [ply.name][jobtext] and"
if(ply.current)
if(ply.current.stat == DEAD)
- text += " died"
+ text += " died"
else
- text += " survived"
- if(fleecheck && !is_station_level(ply.current.z))
- text += " while fleeing the station"
+ text += " survived"
+ if(fleecheck)
+ var/turf/T = get_turf(ply.current)
+ if(!T || !is_station_level(T.z))
+ text += " while fleeing the station"
if(ply.current.real_name != ply.name)
text += " as [ply.current.real_name]"
else
- text += " had their body destroyed"
+ text += " had [ply.p_their()] body destroyed"
return text
-/datum/game_mode/proc/printobjectives(datum/mind/ply)
- var/text = ""
+/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())
- text += "
Objective #[count]: [objective.explanation_text] Success!"
+ objective_parts += "Objective #[count]: [objective.explanation_text] Success!"
else
- text += "
Objective #[count]: [objective.explanation_text] Fail."
+ objective_parts += "Objective #[count]: [objective.explanation_text] Fail."
count++
- return text
+ return objective_parts.Join("
")
/datum/game_mode/proc/generate_station_goals()
var/list/possible = list()
diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm
index 8058ff6e5c9..0c609c818b4 100644
--- a/code/game/gamemodes/gameticker.dm
+++ b/code/game/gamemodes/gameticker.dm
@@ -368,7 +368,7 @@ var/round_start_time = 0
if(player && player.mind && player.mind.assigned_role)
if(player.mind.assigned_role == "Captain")
captainless=0
- if(player.mind.assigned_role != "MODE")
+ if(player.mind.assigned_role != player.mind.special_role)
job_master.EquipRank(player, player.mind.assigned_role, 0)
EquipCustomItems(player)
if(captainless)
diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm
index 0693ca9b279..3b908952de7 100644
--- a/code/game/gamemodes/heist/heist.dm
+++ b/code/game/gamemodes/heist/heist.dm
@@ -51,7 +51,7 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind'
raider_num--
for(var/datum/mind/raider in raiders)
- raider.assigned_role = "MODE"
+ raider.assigned_role = SPECIAL_ROLE_RAIDER
raider.special_role = SPECIAL_ROLE_RAIDER
..()
return 1
diff --git a/code/game/gamemodes/intercept_report.dm b/code/game/gamemodes/intercept_report.dm
index 6cb2956d3ee..50b749a62a2 100644
--- a/code/game/gamemodes/intercept_report.dm
+++ b/code/game/gamemodes/intercept_report.dm
@@ -91,7 +91,7 @@
var/list/dudes = list()
for(var/mob/living/carbon/human/man in player_list)
if(!man.mind) continue
- if(man.mind.assigned_role=="MODE") continue
+ if(man.mind.assigned_role == man.mind.special_role) continue
dudes += man
if(dudes.len==0)
return null
@@ -210,14 +210,14 @@
var/prob_right_job = rand(prob_correct_job_lower, prob_correct_job_higher)
if(prob(prob_right_job))
if(correct_person)
- if(correct_person:assigned_role=="MODE")
+ if(correct_person:assigned_role == correct_person:special_role)
changeling_job = pick(joblist)
else
changeling_job = correct_person:assigned_role
else
changeling_job = pick(joblist)
if(prob(prob_right_dude) && ticker.mode == "changeling")
- if(correct_person:assigned_role=="MODE")
+ if(correct_person:assigned_role == correct_person:special_role)
changeling_name = correct_person:current
else
changeling_name = src.pick_mob()
diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm
index 57ce00c92af..8f4b5dab95e 100644
--- a/code/game/gamemodes/malfunction/Malf_Modules.dm
+++ b/code/game/gamemodes/malfunction/Malf_Modules.dm
@@ -159,9 +159,8 @@
for(var/obj/machinery/door/D in airlocks)
if(!is_station_level(D.z))
continue
- spawn(0)
- D.hostile_lockdown(src)
- addtimer(D, "disable_lockdown", 900)
+ INVOKE_ASYNC(D, /obj/machinery/door.proc/hostile_lockdown, src)
+ addtimer(CALLBACK(D, /obj/machinery/door.proc/disable_lockdown), 900)
post_status("alert", "lockdown")
diff --git a/code/game/gamemodes/miniantags/abduction/abduction.dm b/code/game/gamemodes/miniantags/abduction/abduction.dm
index b54b18335ef..1c6dc7d3022 100644
--- a/code/game/gamemodes/miniantags/abduction/abduction.dm
+++ b/code/game/gamemodes/miniantags/abduction/abduction.dm
@@ -74,11 +74,11 @@
agent = preset_agent
- scientist.assigned_role = "MODE"
+ scientist.assigned_role = SPECIAL_ROLE_ABDUCTOR_SCIENTIST
scientist.special_role = SPECIAL_ROLE_ABDUCTOR_SCIENTIST
log_game("[key_name(scientist)] has been selected as an abductor team [team_number] scientist.")
- agent.assigned_role = "MODE"
+ agent.assigned_role = SPECIAL_ROLE_ABDUCTOR_AGENT
agent.special_role = SPECIAL_ROLE_ABDUCTOR_AGENT
log_game("[key_name(agent)] has been selected as an abductor team [team_number] agent.")
diff --git a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
index 0b1962b1717..9a43df56926 100644
--- a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
+++ b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
@@ -176,7 +176,7 @@
if(ishuman(target))
if(console!=null)
console.AddSnapshot(target)
- to_chat(user, "You scan [target] and add them to the database.")
+ to_chat(user, "You scan [target] and add [target.p_them()] to the database.")
/obj/item/abductor/gizmo/proc/mark(atom/target, mob/living/user)
if(marked == target)
diff --git a/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm b/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm
index 328981b2ab5..2d3bed1e0cf 100644
--- a/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm
+++ b/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm
@@ -5,19 +5,19 @@
/datum/surgery/organ_extraction/can_start(mob/user, mob/living/carbon/target, target_zone, obj/item/tool,datum/surgery/surgery)
if(!ishuman(user))
- return 0
+ return FALSE
if(ishuman(target))
var/mob/living/carbon/human/H = target
var/obj/item/organ/external/affected = H.get_organ(target_zone)
if(!affected)
- return 0
+ return FALSE
if(affected.status & ORGAN_ROBOT)
- return 0
+ return FALSE
var/mob/living/carbon/human/H = user
// You must either: Be of the abductor species, or contain an abductor implant
if((H.get_species() == "Abductor" || (locate(/obj/item/implant/abductor) in H)))
- return 1
- return 0
+ return TRUE
+ return FALSE
/datum/surgery_step/internal/extract_organ
@@ -39,15 +39,19 @@
var/mob/living/carbon/human/AB = target
if(NO_INTORGANS in AB.species.species_traits)
user.visible_message("[user] prepares [target]'s [target_zone] for further dissection!", "You prepare [target]'s [target_zone] for further dissection.")
- return 1
+ return TRUE
if(IC)
user.visible_message("[user] pulls [IC] out of [target]'s [target_zone]!", "You pull [IC] out of [target]'s [target_zone].")
user.put_in_hands(IC)
IC.remove(target, special = 1)
- return 1
+ return TRUE
else
to_chat(user, "You don't find anything in [target]'s [target_zone]!")
- return 1
+ return TRUE
+
+/datum/surgery_step/internal/extract_organ/fail_step(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user]'s hand slips, failing to extract anything!", "Your hand slips, failing to extract anything!")
+ return FALSE
/datum/surgery_step/internal/gland_insert
name = "insert gland"
@@ -63,7 +67,11 @@
user.drop_item()
var/obj/item/organ/internal/heart/gland/gland = tool
gland.insert(target, 2)
- return 1
+ return TRUE
+
+/datum/surgery_step/internal/gland_insert/fail_step(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user]'s hand slips, failing to insert the gland!", "Your hand slips, failing to insert the gland!")
+ return FALSE
//IPC Gland Surgery//
@@ -91,4 +99,4 @@
/datum/surgery_step/internal/extract_organ/synth
name = "remove cell"
- organ_types = list(/obj/item/organ/internal/cell)
\ No newline at end of file
+ organ_types = list(/obj/item/organ/internal/cell)
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/console.dm b/code/game/gamemodes/miniantags/abduction/machinery/console.dm
index b0b879a30ab..10cd5473279 100644
--- a/code/game/gamemodes/miniantags/abduction/machinery/console.dm
+++ b/code/game/gamemodes/miniantags/abduction/machinery/console.dm
@@ -27,7 +27,7 @@
var/obj/machinery/computer/camera_advanced/abductor/camera
var/list/datum/icon_snapshot/disguises = list()
-/obj/machinery/abductor/console/initialize()
+/obj/machinery/abductor/console/Initialize()
..()
Link_Abduction_Equipment()
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
index 588900bb3e8..8682b50fc05 100644
--- a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
+++ b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
@@ -29,7 +29,7 @@
return
for(var/mob/living/carbon/slime/M in range(1, target))
if(M.Victim == target)
- to_chat(user, "[target] has a slime attached to them, deal with that first.")
+ to_chat(user, "[target] has a slime attached to [target.p_them()], deal with that first.")
return
visible_message("[user] puts [target] into the [src].")
diff --git a/code/game/gamemodes/miniantags/borer/borer.dm b/code/game/gamemodes/miniantags/borer/borer.dm
index e9a830e7ed6..11ec158db84 100644
--- a/code/game/gamemodes/miniantags/borer/borer.dm
+++ b/code/game/gamemodes/miniantags/borer/borer.dm
@@ -43,7 +43,8 @@
to_chat(B.host, "You feel the captive mind of [src] begin to resist your control.")
var/delay = (rand(350,450) + B.host.brainloss)
- addtimer(src, "return_control", delay, FALSE, B)
+ addtimer(CALLBACK(src, .proc/return_control, B), delay)
+
/mob/living/captive_brain/proc/return_control(mob/living/simple_animal/borer/B)
if(!B || !B.controlling)
@@ -243,7 +244,7 @@
to_chat(M, "Borer Communication from [B] ([ghost_follow_link(src, ghost=M)]): [input]")
to_chat(src, "[B.truename] says: [input]")
-/mob/living/simple_animal/borer/Life()
+/mob/living/simple_animal/borer/Life(seconds, times_fired)
..()
@@ -324,7 +325,7 @@
to_chat(src, "You cannot infest someone who is already infested!")
return
- to_chat(src, "You slither up [M] and begin probing at their ear canal...")
+ to_chat(src, "You slither up [M] and begin probing at [M.p_their()] ear canal...")
if(!do_after(src, 50, target = M))
to_chat(src, "As [M] moves away, you are dislodged and fall to the ground.")
@@ -499,7 +500,7 @@
to_chat(src, "You cannot dominate someone who is already infested!")
return
- to_chat(src, "You focus your psychic lance on [M] and freeze their limbs with a wave of terrible dread.")
+ to_chat(src, "You focus your psychic lance on [M] and freeze [M.p_their()] limbs with a wave of terrible dread.")
to_chat(M, "You feel a creeping, horrible sense of dread come over you, freezing your limbs and setting your heart racing.")
M.Weaken(3)
@@ -530,11 +531,11 @@
to_chat(src, "You decide against leaving your host.")
return
- to_chat(src, "You begin disconnecting from [host]'s synapses and prodding at their internal ear canal.")
+ to_chat(src, "You begin disconnecting from [host]'s synapses and prodding at [host.p_their()] internal ear canal.")
leaving = TRUE
- addtimer(src, "let_go", 200)
+ addtimer(CALLBACK(src, .proc/let_go), 200)
/mob/living/simple_animal/borer/proc/let_go()
@@ -611,7 +612,7 @@
bonding = TRUE
var/delay = 300+(host.getBrainLoss()*5)
- addtimer(src, "assume_control", delay)
+ addtimer(CALLBACK(src, .proc/assume_control), delay)
/mob/living/simple_animal/borer/proc/assume_control()
if(!host || !src || controlling)
@@ -622,7 +623,7 @@
to_chat(src,"You are feeling far too docile to do that.")
return
else
- to_chat(src, "You plunge your probosci deep into the cortex of the host brain, interfacing directly with their nervous system.")
+ to_chat(src, "You plunge your probosci deep into the cortex of the host brain, interfacing directly with [host.p_their()] nervous system.")
to_chat(host, "You feel a strange shifting sensation behind your eyes as an alien consciousness displaces yours.")
var/borer_key = src.key
add_attack_logs(src, host, "Assumed control of (borer)")
diff --git a/code/game/gamemodes/miniantags/guardian/guardian.dm b/code/game/gamemodes/miniantags/guardian/guardian.dm
index 822bfc9ce29..68e8c16c5da 100644
--- a/code/game/gamemodes/miniantags/guardian/guardian.dm
+++ b/code/game/gamemodes/miniantags/guardian/guardian.dm
@@ -57,7 +57,7 @@
else
holder.icon_state = "hudhealthy"
-/mob/living/simple_animal/hostile/guardian/Life() //Dies if the summoner dies
+/mob/living/simple_animal/hostile/guardian/Life(seconds, times_fired) //Dies if the summoner dies
..()
if(summoner)
if(summoner.stat == DEAD)
@@ -448,6 +448,14 @@
Support:Has two modes. Combat: Medium power attacks and damage resist. Healer: Attacks heal damage, but low damage resist and slow movemen. Can deploy a bluespace beacon and warp targets to it (including you) in either mode.
Explosive: High damage resist and medium power attack. Can turn any object into a bomb, dealing explosive damage to the next person to touch it. The object will return to normal after the trap is triggered.
+
+ Assassin: Medium damage with no damage resistance, can enter stealth which massively increases the damage of the next attack causing it to ignore armour.
+
+ Charger: Medium damage and defense, very fast and has a special charge attack which damages a target and knocks items out of their hands.
+
+ Lightning: Applies lightning chains to any targets on attack with a link to your summoner, lightning chains will shock anyone nearby.
+
+ Protector: You will become leashed to your holoparasite instead of them to you. Has two modes, a medium attack/defense mode and a protection mode which greatly reduces incoming damage to the holoparasite.
"}
/obj/item/paper/guardian/update_icon()
diff --git a/code/game/gamemodes/miniantags/guardian/types/assassin.dm b/code/game/gamemodes/miniantags/guardian/types/assassin.dm
index 426824f2e8c..5eb8c1b1cec 100644
--- a/code/game/gamemodes/miniantags/guardian/types/assassin.dm
+++ b/code/game/gamemodes/miniantags/guardian/types/assassin.dm
@@ -13,7 +13,7 @@
var/obj/screen/alert/canstealthalert
var/obj/screen/alert/instealthalert
-/mob/living/simple_animal/hostile/guardian/assassin/Life()
+/mob/living/simple_animal/hostile/guardian/assassin/Life(seconds, times_fired)
. = ..()
updatestealthalert()
if(loc == summoner && toggle)
diff --git a/code/game/gamemodes/miniantags/guardian/types/charger.dm b/code/game/gamemodes/miniantags/guardian/types/charger.dm
index abdc349f175..17ed569f256 100644
--- a/code/game/gamemodes/miniantags/guardian/types/charger.dm
+++ b/code/game/gamemodes/miniantags/guardian/types/charger.dm
@@ -6,7 +6,7 @@
ranged_cooldown_time = 40
speed = -1
damage_transfer = 0.6
- playstyle_string = "As a Charger type you do medium damage, have medium damage resistance, move very fast, and can charge at a location, damaging any target hit and forcing them to drop any items they are holding."
+ playstyle_string = "As a Charger type you do medium damage, have medium damage resistance, move very fast, and can charge at a location, damaging any target hit and forcing them to drop any items they are holding. (Click a tile to use your charge ability)"
magic_fluff_string = "..And draw the Hunter, an alien master of rapid assault."
tech_fluff_string = "Boot sequence complete. Charge modules loaded. Holoparasite swarm online."
bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, ready to deal damage."
diff --git a/code/game/gamemodes/miniantags/guardian/types/fire.dm b/code/game/gamemodes/miniantags/guardian/types/fire.dm
index 2a9dc2d2c8e..61905f942d2 100644
--- a/code/game/gamemodes/miniantags/guardian/types/fire.dm
+++ b/code/game/gamemodes/miniantags/guardian/types/fire.dm
@@ -13,7 +13,7 @@
bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, ready to sow havoc at random."
var/toggle = FALSE
-/mob/living/simple_animal/hostile/guardian/fire/Life() //Dies if the summoner dies
+/mob/living/simple_animal/hostile/guardian/fire/Life(seconds, times_fired) //Dies if the summoner dies
..()
if(summoner)
summoner.ExtinguishMob()
diff --git a/code/game/gamemodes/miniantags/guardian/types/healer.dm b/code/game/gamemodes/miniantags/guardian/types/healer.dm
index d51e4cefd45..c679beac91a 100644
--- a/code/game/gamemodes/miniantags/guardian/types/healer.dm
+++ b/code/game/gamemodes/miniantags/guardian/types/healer.dm
@@ -32,7 +32,7 @@
/mob/living/simple_animal/hostile/guardian/healer/New()
..()
-/mob/living/simple_animal/hostile/guardian/healer/Life()
+/mob/living/simple_animal/hostile/guardian/healer/Life(seconds, times_fired)
..()
var/datum/atom_hud/medsensor = huds[DATA_HUD_MEDICAL_ADVANCED]
medsensor.add_hud_to(src)
diff --git a/code/game/gamemodes/miniantags/guardian/types/protector.dm b/code/game/gamemodes/miniantags/guardian/types/protector.dm
index fe8b4897c42..9206b0d1b0b 100644
--- a/code/game/gamemodes/miniantags/guardian/types/protector.dm
+++ b/code/game/gamemodes/miniantags/guardian/types/protector.dm
@@ -51,7 +51,7 @@
Recall(TRUE)
else
to_chat(summoner, "You moved out of range, and were pulled back! You can only move [range] meters from [src]!")
- summoner.visible_message("[summoner] jumps back to their protector.")
+ summoner.visible_message("[summoner] jumps back to [summoner.p_their()] protector.")
new /obj/effect/temp_visual/guardian/phase/out(get_turf(summoner))
summoner.forceMove(get_turf(src))
new /obj/effect/temp_visual/guardian/phase(get_turf(summoner))//Protector
\ No newline at end of file
diff --git a/code/game/gamemodes/miniantags/morph/morph_event.dm b/code/game/gamemodes/miniantags/morph/morph_event.dm
index d9e26597a2b..ab875832451 100644
--- a/code/game/gamemodes/miniantags/morph/morph_event.dm
+++ b/code/game/gamemodes/miniantags/morph/morph_event.dm
@@ -19,7 +19,7 @@
return kill()
var/mob/living/simple_animal/hostile/morph/S = new /mob/living/simple_animal/hostile/morph(pick(xeno_spawn))
player_mind.transfer_to(S)
- player_mind.assigned_role = "Morph"
+ player_mind.assigned_role = SPECIAL_ROLE_MORPH
player_mind.special_role = SPECIAL_ROLE_MORPH
ticker.mode.traitors |= player_mind
to_chat(S, S.playstyle_string)
diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm
index 49380c57863..953e6e91762 100644
--- a/code/game/gamemodes/miniantags/revenant/revenant.dm
+++ b/code/game/gamemodes/miniantags/revenant/revenant.dm
@@ -54,7 +54,7 @@
var/image/ghostimage = null //Visible to ghost with darkness off
-/mob/living/simple_animal/revenant/Life()
+/mob/living/simple_animal/revenant/Life(seconds, times_fired)
..()
if(revealed && essence <= 0)
death()
@@ -392,7 +392,7 @@
var/datum/mind/player_mind = new /datum/mind(key_of_revenant)
player_mind.active = 1
player_mind.transfer_to(R)
- player_mind.assigned_role = "revenant"
+ player_mind.assigned_role = SPECIAL_ROLE_REVENANT
player_mind.special_role = SPECIAL_ROLE_REVENANT
ticker.mode.traitors |= player_mind
message_admins("[key_of_revenant] has been [client_to_revive ? "re":""]made into a revenant by reforming ectoplasm.")
diff --git a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm
index 32d51b579c4..5a7825c0cfe 100644
--- a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm
+++ b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm
@@ -73,7 +73,7 @@
icon_state = "revenant_draining"
reveal(27)
stun(27)
- target.visible_message("[target] suddenly rises slightly into the air, their skin turning an ashy gray.")
+ target.visible_message("[target] suddenly rises slightly into the air, [target.p_their()] skin turning an ashy gray.")
target.Beam(src,icon_state="drain_life",icon='icons/effects/effects.dmi',time=26)
if(do_after(src, 30, 0, target)) //As one cannot prove the existance of ghosts, ghosts cannot prove the existance of the target they were draining.
change_essence_amount(essence_drained, 0, target)
@@ -263,8 +263,8 @@
new/obj/effect/temp_visual/revenant(T)
T.ChangeTurf(/turf/simulated/wall/r_wall/rust)
for(var/obj/structure/window/window in T.contents)
- window.hit(rand(30,80))
- if(window && window.is_fulltile())
+ window.take_damage(rand(30,80))
+ if(window && window.fulltile)
new/obj/effect/temp_visual/revenant/cracks(window.loc)
for(var/obj/structure/closet/closet in T.contents)
closet.open()
diff --git a/code/game/gamemodes/miniantags/revenant/revenant_spawn_event.dm b/code/game/gamemodes/miniantags/revenant/revenant_spawn_event.dm
index 859f863b03c..a70114d8f5e 100644
--- a/code/game/gamemodes/miniantags/revenant/revenant_spawn_event.dm
+++ b/code/game/gamemodes/miniantags/revenant/revenant_spawn_event.dm
@@ -43,7 +43,7 @@
return kill()
var/mob/living/simple_animal/revenant/revvie = new /mob/living/simple_animal/revenant/(pick(spawn_locs))
player_mind.transfer_to(revvie)
- player_mind.assigned_role = "revenant"
+ player_mind.assigned_role = SPECIAL_ROLE_REVENANT
player_mind.special_role = SPECIAL_ROLE_REVENANT
ticker.mode.traitors |= player_mind
message_admins("[key_of_revenant] has been made into a revenant by an event.")
diff --git a/code/game/gamemodes/miniantags/slaughter/slaughter.dm b/code/game/gamemodes/miniantags/slaughter/slaughter.dm
index 42827d27f59..6b5705cfa7f 100644
--- a/code/game/gamemodes/miniantags/slaughter/slaughter.dm
+++ b/code/game/gamemodes/miniantags/slaughter/slaughter.dm
@@ -82,7 +82,7 @@
to_chat(src, "Objective #[2]: [fluffObjective.explanation_text]")
-/mob/living/simple_animal/slaughter/Life()
+/mob/living/simple_animal/slaughter/Life(seconds, times_fired)
..()
if(boostYou could not locate any sapient heretics for the Slaughter.")
return 0
- to_chat(usr, "You sense a terrified soul at [A]. Show them the error of their ways.")
+ to_chat(usr, "You sense a terrified soul at [A]. Show [A.p_them()] the error of [A.p_their()] ways.")
/mob/living/simple_animal/slaughter/cult/New()
..()
@@ -241,7 +241,7 @@
return // Just so people don't accidentally waste it
/obj/item/organ/internal/heart/demon/attack_self(mob/living/user)
- user.visible_message("[user] raises [src] to their mouth and tears into it with their teeth!", \
+ user.visible_message("[user] raises [src] to [user.p_their()] mouth and tears into it with [user.p_their()] teeth!", \
"An unnatural hunger consumes you. You raise [src] to your mouth and devour it!")
playsound(user, 'sound/misc/Demon_consume.ogg', 50, 1)
for(var/obj/effect/proc_holder/spell/knownspell in user.mind.spell_list)
diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm
index b2f06a7913a..feffadcf9ab 100644
--- a/code/game/gamemodes/nuclear/nuclear.dm
+++ b/code/game/gamemodes/nuclear/nuclear.dm
@@ -49,7 +49,7 @@ proc/issyndicate(mob/living/M as mob)
agent_number--
for(var/datum/mind/synd_mind in syndicates)
- synd_mind.assigned_role = "MODE" //So they aren't chosen for other jobs.
+ synd_mind.assigned_role = SPECIAL_ROLE_NUKEOPS //So they aren't chosen for other jobs.
synd_mind.special_role = SPECIAL_ROLE_NUKEOPS
return 1
diff --git a/code/game/gamemodes/nuclear/nuclear_challenge.dm b/code/game/gamemodes/nuclear/nuclear_challenge.dm
index 6bb181b4136..4158deb6380 100644
--- a/code/game/gamemodes/nuclear/nuclear_challenge.dm
+++ b/code/game/gamemodes/nuclear/nuclear_challenge.dm
@@ -30,7 +30,7 @@
to_chat(user, "On second thought, the element of surprise isn't so bad after all.")
return
- var/war_declaration = "[user.real_name] has declared his intent to utterly destroy [station_name()] with a nuclear device, and dares the crew to try and stop them."
+ var/war_declaration = "[user.real_name] has declared [user.p_their()] intent to utterly destroy [station_name()] with a nuclear device, and dares the crew to try and stop them."
declaring_war = TRUE
var/custom_threat = alert(user, "Do you want to customize your declaration?", "Customize?", "Yes", "No")
diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm
index 37a2979ae74..e9bea1d8b1d 100644
--- a/code/game/gamemodes/nuclear/pinpointer.dm
+++ b/code/game/gamemodes/nuclear/pinpointer.dm
@@ -53,7 +53,7 @@
var/turf/T = get_turf(target)
var/turf/L = get_turf(src)
- if(T.z != L.z)
+ if(!(T && L) || (T.z != L.z))
icon_state = icon_null
else
dir = get_dir(L, T)
@@ -341,7 +341,7 @@
if(active)
active = FALSE
icon_state = icon_off
- user.visible_message("[user] deactivates their pinpointer.", "You deactivate your pinpointer.")
+ user.visible_message("[user] deactivates [user.p_their()] pinpointer.", "You deactivate your pinpointer.")
return
var/list/name_counts = list()
@@ -354,7 +354,8 @@
var/name = "Unknown"
if(H.wear_id)
var/obj/item/card/id/I = H.wear_id.GetID()
- name = I.registered_name
+ if(I)
+ name = I.registered_name
while(name in name_counts)
name_counts[name]++
@@ -372,7 +373,7 @@
var/target = names[A]
active = TRUE
- user.visible_message("[user] activates their pinpointer.", "You activate your pinpointer.")
+ user.visible_message("[user] activates [user.p_their()] pinpointer.", "You activate your pinpointer.")
point_at(target)
/obj/item/pinpointer/crew/point_at(atom/target, spawnself = 1)
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index c9ad5ce69e4..07395aa0578 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -287,7 +287,7 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datu
target = pick(possible_targets)
if(target && target.current)
target_real_name = target.current.real_name
- explanation_text = "Escape on the shuttle or an escape pod with the identity of [target_real_name], the [target.assigned_role] while wearing their identification card."
+ explanation_text = "Escape on the shuttle or an escape pod with the identity of [target_real_name], the [target.assigned_role] while wearing [target.p_their()] identification card."
else
explanation_text = "Free Objective"
@@ -515,7 +515,7 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datu
var/list/priority_targets = list()
for(var/datum/mind/possible_target in ticker.minds)
- if(possible_target != owner && ishuman(possible_target.current) && (possible_target.current.stat != DEAD) && (possible_target.assigned_role != "MODE"))
+ if(possible_target != owner && ishuman(possible_target.current) && (possible_target.current.stat != DEAD) && (possible_target.assigned_role != possible_target.special_role))
possible_targets += possible_target
for(var/role in roles)
if(possible_target.assigned_role == role)
@@ -528,7 +528,7 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datu
target = pick(possible_targets)
if(target && target.current)
- explanation_text = "The Shoal has a need for [target.current.real_name], the [target.assigned_role]. Take them alive."
+ explanation_text = "The Shoal has a need for [target.current.real_name], the [target.assigned_role]. Take [target.current.p_them()] alive."
else
explanation_text = "Free Objective"
return target
diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm
index 4f500825065..089cad71a3a 100644
--- a/code/game/gamemodes/revolution/revolution.dm
+++ b/code/game/gamemodes/revolution/revolution.dm
@@ -279,7 +279,7 @@
to_chat(M, "The frame beeps contentedly, purging the hostile memory engram from the MMI before initalizing it.")
else
- to_chat(M, "[rev_mind.current] looks like they just remembered their real allegiance!")
+ to_chat(M, "[rev_mind.current] looks like [rev_mind.current.p_they()] just remembered [rev_mind.current.p_their()] real allegiance!")
/////////////////////////////////////
//Adds the rev hud to a new convert//
diff --git a/code/game/gamemodes/shadowling/shadowling.dm b/code/game/gamemodes/shadowling/shadowling.dm
index ed8603360fe..1d0bb3adf03 100644
--- a/code/game/gamemodes/shadowling/shadowling.dm
+++ b/code/game/gamemodes/shadowling/shadowling.dm
@@ -188,7 +188,7 @@ Made by Xhuis
M.audible_message("[M] lets out a short blip.", \
"You have been turned into a robot! You are no longer a thrall! Though you try, you cannot remember anything about your servitude...")
else
- M.visible_message("[M] looks like their mind is their own again!", \
+ M.visible_message("[M] looks like [M.p_their()] mind is [M.p_their()] own again!", \
"A piercing white light floods your eyes. Your mind is your own again! Though you try, you cannot remember anything about the shadowlings or your time \
under their command...")
return 1
diff --git a/code/game/gamemodes/shadowling/shadowling_abilities.dm b/code/game/gamemodes/shadowling/shadowling_abilities.dm
index 06f7bc9440c..89aee290422 100644
--- a/code/game/gamemodes/shadowling/shadowling_abilities.dm
+++ b/code/game/gamemodes/shadowling/shadowling_abilities.dm
@@ -40,9 +40,9 @@
return
var/mob/living/carbon/human/M = target
user.visible_message("[user]'s eyes flash a blinding red!")
- target.visible_message("[target] freezes in place, their eyes glazing over...")
+ target.visible_message("[target] freezes in place, [target.p_their()] eyes glazing over...")
if(in_range(target, user))
- to_chat(target, "Your gaze is forcibly drawn into [user]'s eyes, and you are mesmerized by their heavenly beauty...")
+ to_chat(target, "Your gaze is forcibly drawn into [user]'s eyes, and you are mesmerized by [user.p_their()] heavenly beauty...")
else //Only alludes to the shadowling if the target is close by
to_chat(target, "Red lights suddenly dance in your vision, and you are mesmerized by the heavenly lights...")
target.Stun(10)
@@ -306,7 +306,7 @@
switch(progress)
if(1)
to_chat(user, "You place your hands to [target]'s head...")
- user.visible_message("[user] places their hands onto the sides of [target]'s head!")
+ user.visible_message("[user] places [user.p_their()] hands onto the sides of [target]'s head!")
if(2)
to_chat(user, "You begin preparing [target]'s mind as a blank slate...")
user.visible_message("[user]'s palms flare a bright red against [target]'s temples!")
@@ -315,7 +315,7 @@
sleep(20)
if(ismindshielded(target))
to_chat(user, "They have a mindshield implant. You begin to deactivate it - this will take some time.")
- user.visible_message("[user] pauses, then dips their head in concentration!")
+ user.visible_message("[user] pauses, then dips [user.p_their()] head in concentration!")
to_chat(target, "Your mindshield implant becomes hot as it comes under attack!")
sleep(100) //10 seconds - not spawn() so the enthralling takes longer
to_chat(user, "The nanobots composing the mindshield implant have been rendered inert. Now to continue.")
@@ -361,7 +361,7 @@
if(!istype(target) || !ishuman(target))
return
var/mob/living/carbon/human/H = target
- H.visible_message("[H]'s skin suddenly bubbles and shifts around their body!", \
+ H.visible_message("[H]'s skin suddenly bubbles and shifts around [H.p_their()] body!", \
"You regenerate your protective armor and cleanse your form of defects.")
H.adjustCloneLoss(-target.getCloneLoss())
H.equip_to_slot_or_del(new /obj/item/clothing/under/shadowling(H), slot_w_uniform)
@@ -493,7 +493,7 @@
to_chat(M, "You breathe in the black smoke, and your eyes burn horribly!")
M.EyeBlind(5)
if(prob(25))
- M.visible_message("[M] claws at their eyes!")
+ M.visible_message("[M] claws at [M.p_their()] eyes!")
M.Stun(3)
else
to_chat(M, "You breathe in the black smoke, and you feel revitalized!")
@@ -540,9 +540,7 @@
sp.start()
S.Weaken(6)
for(var/obj/structure/window/W in T.contents)
- W.hit(rand(80, 100))
-
-
+ W.take_damage(rand(80, 100))
/obj/effect/proc_holder/spell/aoe_turf/drainLife
name = "Drain Life"
@@ -627,9 +625,9 @@
to_chat(user, "You cannot spare this much energy. There are too many empowered thralls.")
charge_counter = charge_max
return
- user.visible_message("[user] places their hands over [thrallToRevive]'s face, red light shining from beneath.", \
+ user.visible_message("[user] places [user.p_their()] hands over [thrallToRevive]'s face, red light shining from beneath.", \
"You place your hands on [thrallToRevive]'s face and begin gathering energy...")
- to_chat(thrallToRevive, "[user] places their hands over your face. You feel energy gathering. Stand still...")
+ to_chat(thrallToRevive, "[user] places [user.p_their()] hands over your face. You feel energy gathering. Stand still...")
if(!do_mob(user, thrallToRevive, 80))
to_chat(user, "Your concentration snaps. The flow of energy ebbs.")
charge_counter = charge_max
@@ -640,7 +638,7 @@
playsound(thrallToRevive, 'sound/machines/defib_zap.ogg', 50, 1)
user.Beam(thrallToRevive,icon_state="red_lightning",icon='icons/effects/effects.dmi',time=1)
thrallToRevive.Weaken(5)
- thrallToRevive.visible_message("[thrallToRevive] collapses, their skin and face distorting!", \
+ thrallToRevive.visible_message("[thrallToRevive] collapses, [thrallToRevive.p_their()] skin and face distorting!", \
"AAAAAAAAAAAAAAAAAAAGH-")
sleep(20)
thrallToRevive.visible_message("[thrallToRevive] slowly rises, no longer recognizable as human.", \
@@ -659,7 +657,7 @@
to_chat(user, "[thrallToRevive] is not dead.")
charge_counter = charge_max
return
- user.visible_message("[user] kneels over [thrallToRevive], placing their hands on \his chest.", \
+ user.visible_message("[user] kneels over [thrallToRevive], placing [user.p_their()] hands on [thrallToRevive.p_their()] chest.", \
"You crouch over the body of your thrall and begin gathering energy...")
thrallToRevive.notify_ghost_cloning("Your masters are resuscitating you! Re-enter your corpse if you wish to be brought to life.", source = thrallToRevive)
if(!do_mob(user, thrallToRevive, 30))
@@ -673,7 +671,7 @@
user.Beam(thrallToRevive,icon_state="red_lightning",icon='icons/effects/effects.dmi',time=1)
sleep(10)
if(thrallToRevive.revive())
- thrallToRevive.visible_message("[thrallToRevive] heaves in breath, dim red light shining in their eyes.", \
+ thrallToRevive.visible_message("[thrallToRevive] heaves in breath, dim red light shining in [thrallToRevive.p_their()] eyes.", \
"You have returned. One of your masters has brought you from the darkness beyond.")
thrallToRevive.Weaken(4)
thrallToRevive.emote("gasp")
@@ -710,7 +708,7 @@
var/mob/living/carbon/human/M = target
user.visible_message("[user]'s eyes flash a bright red!", \
"You begin to draw [M]'s life force.")
- M.visible_message("[M]'s face falls slack, their jaw slightly distending.", \
+ M.visible_message("[M]'s face falls slack, [M.p_their()] jaw slightly distending.", \
"You are suddenly transported... far, far away...")
if(!do_after(user, 50, target = M))
to_chat(M, "You are snapped back to reality, your haze dissipating!")
@@ -754,7 +752,7 @@
to_chat(user, "Making an ally explode seems unwise.")
charge_counter = charge_max
return
- user.visible_message("[user]'s markings flare as they gesture at [boom]!", \
+ user.visible_message("[user]'s markings flare as [user.p_they()] gesture[user.p_s()] at [boom]!", \
"You direct a lance of telekinetic energy at [boom].")
sleep(4)
if(iscarbon(boom))
@@ -798,7 +796,7 @@
charge_counter = charge_max
return
- to_chat(user, "You instantly rearrange [target]'s memories, hyptonitizing them into a thrall.")
+ to_chat(user, "You instantly rearrange [target]'s memories, hyptonitizing [target.p_them()] into a thrall.")
to_chat(target, "An agonizing spike of pain drives into your mind, and--")
ticker.mode.add_thrall(target.mind)
target.mind.special_role = SPECIAL_ROLE_SHADOWLING_THRALL
diff --git a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm
index 5c05a028df0..4239b5db327 100644
--- a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm
+++ b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm
@@ -43,7 +43,7 @@ var/list/possibleShadowlingNames = list("U'ruan", "Y`shej", "Nex", "Hel-uae", "N
var/temp_flags = H.status_flags
H.status_flags |= GODMODE //Can't die while hatching
- H.visible_message("A chrysalis forms around [H], sealing them inside.", \
+ H.visible_message("A chrysalis forms around [H], sealing [H.p_them()] inside.", \
"You create your chrysalis and begin to contort within.")
sleep(100)
@@ -51,7 +51,7 @@ var/list/possibleShadowlingNames = list("U'ruan", "Y`shej", "Nex", "Hel-uae", "N
"Spines pierce your back. Your claws break apart your fingers. You feel excruciating pain as your true form begins its exit.")
sleep(90)
- H.visible_message("[H], skin shifting, begins tearing at the walls around them.", \
+ H.visible_message("[H], skin shifting, begins tearing at the walls around [H.p_them()].", \
"Your false skin slips away. You begin tearing at the fragile membrane protecting you.")
sleep(80)
diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm
index ec8a1643c27..9234043976c 100644
--- a/code/game/gamemodes/traitor/traitor.dm
+++ b/code/game/gamemodes/traitor/traitor.dm
@@ -346,7 +346,7 @@
// Tell them about people they might want to contact.
var/mob/living/carbon/human/M = get_nt_opposed()
if(M && M != traitor_mob)
- to_chat(traitor_mob, "We have received credible reports that [M.real_name] might be willing to help our cause. If you need assistance, consider contacting them.")
+ to_chat(traitor_mob, "We have received credible reports that [M.real_name] might be willing to help our cause. If you need assistance, consider contacting [M.p_them()].")
traitor_mob.mind.store_memory("Potential Collaborator: [M.real_name]")
//let's also inform their contact that they might be called upon, but leave it vague.
inform_collab(M)
diff --git a/code/game/gamemodes/vampire/vampire.dm b/code/game/gamemodes/vampire/vampire.dm
index c2431f17318..ae9b8e3945a 100644
--- a/code/game/gamemodes/vampire/vampire.dm
+++ b/code/game/gamemodes/vampire/vampire.dm
@@ -280,7 +280,7 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha
draining = null
return
add_attack_logs(owner, H, "vampirebit & is draining their blood.", FALSE)
- owner.visible_message("[owner] grabs [H]'s neck harshly and sinks in their fangs!", "You sink your fangs into [H] and begin to drain their blood.", "You hear a soft puncture and a wet sucking noise.")
+ owner.visible_message("[owner] grabs [H]'s neck harshly and sinks in [owner.p_their()] fangs!", "You sink your fangs into [H] and begin to drain [owner.p_their()] blood.", "You hear a soft puncture and a wet sucking noise.")
if(!iscarbon(owner))
H.LAssailant = null
else
diff --git a/code/game/gamemodes/vampire/vampire_powers.dm b/code/game/gamemodes/vampire/vampire_powers.dm
index e9a249d8412..c9dad5c510d 100644
--- a/code/game/gamemodes/vampire/vampire_powers.dm
+++ b/code/game/gamemodes/vampire/vampire_powers.dm
@@ -175,7 +175,7 @@
/obj/effect/proc_holder/spell/vampire/targetted/hypnotise/cast(list/targets, mob/user = usr)
for(var/mob/living/target in targets)
- user.visible_message("[user]'s eyes flash briefly as he stares into [target]'s eyes")
+ user.visible_message("[user]'s eyes flash briefly as [user.p_they()] stare[user.p_s()] into [target]'s eyes")
if(do_mob(user, target, 50))
if(!affects(target))
to_chat(user, "Your piercing gaze fails to knock out [target].")
@@ -270,7 +270,7 @@
C.Stun(4)
C.Jitter(150)
for(var/obj/structure/window/W in view(4))
- W.destroy()
+ W.deconstruct(FALSE)
playsound(user.loc, 'sound/effects/creepyshriek.ogg', 100, 1)
@@ -345,8 +345,8 @@
ticker.mode.vampire_enthralled.Add(H.mind)
ticker.mode.vampire_enthralled[H.mind] = user.mind
H.mind.special_role = SPECIAL_ROLE_VAMPIRE_THRALL
- to_chat(H, "You have been Enthralled by [user]. Follow their every command.")
- to_chat(user, "You have successfully Enthralled [H]. If they refuse to do as you say just adminhelp.")
+ to_chat(H, "You have been Enthralled by [user]. Follow [user.p_their()] every command.")
+ to_chat(user, "You have successfully Enthralled [H]. If [H.p_they()] refuse[H.p_s()] to do as you say just adminhelp.")
add_attack_logs(user, H, "Vampire-thralled")
diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm
index 2e99f0238c5..7c1a3526002 100644
--- a/code/game/gamemodes/wizard/artefact.dm
+++ b/code/game/gamemodes/wizard/artefact.dm
@@ -56,7 +56,7 @@
new /obj/effect/particle_effect/smoke(H.loc)
var/mob/living/carbon/human/M = new/mob/living/carbon/human(H.loc)
M.key = C.key
- to_chat(M, "You are the [H.real_name]'s apprentice! You are bound by magic contract to follow their orders and help them in accomplishing their goals.")
+ to_chat(M, "You are the [H.real_name]'s apprentice! You are bound by magic contract to follow [H.p_their()] orders and help [H.p_them()] in accomplishing their goals.")
switch(href_list["school"])
if("destruction")
M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile(null))
@@ -213,7 +213,7 @@
/obj/item/scrying/attack_self(mob/user as mob)
to_chat(user, " You can see...everything!")
- visible_message("[user] stares into [src], their eyes glazing over.")
+ visible_message("[user] stares into [src], [user.p_their()] eyes glazing over.")
user.ghostize(1)
/////////////////////Multiverse Blade////////////////////
@@ -277,7 +277,7 @@ var/global/list/multiverse = list()
var/datum/objective/hijackclone/hijack_objective = new /datum/objective/hijackclone
hijack_objective.owner = usr.mind
usr.mind.objectives += hijack_objective
- hijack_objective.explanation_text = "Ensure only [usr.real_name] and their copies are on the shuttle!"
+ hijack_objective.explanation_text = "Ensure only [usr.real_name] and [usr.p_their()] copies are on the shuttle!"
to_chat(usr, "Objective #[1]: [hijack_objective.explanation_text]")
ticker.mode.traitors += usr.mind
usr.mind.special_role = "[usr.real_name] Prime"
@@ -318,7 +318,7 @@ var/global/list/multiverse = list()
C.prefs.copy_to(M)
M.key = C.key
M.mind.name = user.real_name
- to_chat(M, "You are an alternate version of [user.real_name] from another universe! Help them accomplish their goals at all costs.")
+ to_chat(M, "You are an alternate version of [user.real_name] from another universe! Help [user.p_them()] accomplish [user.p_their()] goals at all costs.")
M.faction = list("[user.real_name]")
if(duplicate_self)
M.set_species(user.get_species()) //duplicate the sword user's species.
@@ -342,7 +342,7 @@ var/global/list/multiverse = list()
var/datum/objective/hijackclone/hijack_objective = new /datum/objective/hijackclone
hijack_objective.owner = M.mind
M.mind.objectives += hijack_objective
- hijack_objective.explanation_text = "Ensure only [usr.real_name] and their copies are on the shuttle!"
+ hijack_objective.explanation_text = "Ensure only [usr.real_name] and [usr.p_their()] copies are on the shuttle!"
to_chat(M, "Objective #[1]: [hijack_objective.explanation_text]")
M.mind.special_role = SPECIAL_ROLE_MULTIVERSE
log_game("[M.key] was made a multiverse traveller with the objective to help [usr.real_name] hijack.")
@@ -350,7 +350,7 @@ var/global/list/multiverse = list()
var/datum/objective/protect/new_objective = new /datum/objective/protect
new_objective.owner = M.mind
new_objective.target = usr.mind
- new_objective.explanation_text = "Protect [usr.real_name], your copy, and help them defend the innocent from the mobs of multiverse clones."
+ new_objective.explanation_text = "Protect [usr.real_name], your copy, and help [usr.p_them()] defend the innocent from the mobs of multiverse clones."
M.mind.objectives += new_objective
to_chat(M, "Objective #[1]: [new_objective.explanation_text]")
M.mind.special_role = SPECIAL_ROLE_MULTIVERSE
@@ -652,7 +652,7 @@ var/global/list/multiverse = list()
equip_skeleton(M)
spooky_scaries |= M
to_chat(M, "You have been revived by [user.real_name]!")
- to_chat(M, "They are your master now, assist them even if it costs you your new life!")
+ to_chat(M, "[user.p_theyre(TRUE)] your master now, assist them even if it costs you your new life!")
desc = "A shard capable of resurrecting humans as skeleton thralls[unlimited ? "." : ", [spooky_scaries.len]/3 active thralls."]"
/obj/item/necromantic_stone/proc/check_spooky()
diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm
index cb303a90932..4bd7f3004d8 100644
--- a/code/game/gamemodes/wizard/soulstone.dm
+++ b/code/game/gamemodes/wizard/soulstone.dm
@@ -167,9 +167,9 @@
icon_state = "soulstone"
name = initial(name)
if(iswizard(usr) || usability)
- to_chat(A, "You have been released from your prison, but you are still bound to [usr.real_name]'s will. Help them succeed in their goals at all costs.")
+ to_chat(A, "You have been released from your prison, but you are still bound to [usr.real_name]'s will. Help [usr.p_them()] succeed in [usr.p_their()] goals at all costs.")
else if(iscultist(usr))
- to_chat(A, "You have been released from your prison, but you are still bound to the cult's will. Help them succeed in their goals at all costs.")
+ to_chat(A, "You have been released from your prison, but you are still bound to the cult's will. Help [usr.p_them()] succeed in [usr.p_their()] goals at all costs.")
was_used()
attack_self(U)
@@ -280,7 +280,7 @@
ticker.mode.update_cult_icons_added(Z.mind)
qdel(T)
to_chat(Z, "You are a Juggernaut. Though slow, your shell can withstand extreme punishment, create shield walls and even deflect energy weapons, and rip apart enemies and walls alike.")
- to_chat(Z, "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.")
+ to_chat(Z, "You are still bound to serve your creator, follow [U.p_their()] orders and help [U.p_them()] complete [U.p_their()] goals at all costs.")
Z.cancel_camera()
qdel(C)
@@ -296,7 +296,7 @@
ticker.mode.update_cult_icons_added(Z.mind)
qdel(T)
to_chat(Z, "You are a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls.")
- to_chat(Z, "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.")
+ to_chat(Z, "You are still bound to serve your creator, follow [U.p_their()] orders and help [U.p_them()] complete [U.p_their()] goals at all costs.")
Z.cancel_camera()
qdel(C)
@@ -312,7 +312,7 @@
ticker.mode.update_cult_icons_added(Z.mind)
qdel(T)
to_chat(Z, "You are an Artificer. You are incredibly weak and fragile, but you are able to construct fortifications, use magic missile, repair allied constructs (by clicking on them), and most important of all create new constructs (Use your Artificer spell to summon a new construct shell and Summon Soulstone to create a new soulstone).")
- to_chat(Z, "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.")
+ to_chat(Z, "You are still bound to serve your creator, follow [U.p_their()] orders and help [U.p_them()] complete [U.p_their()] goals at all costs.")
Z.cancel_camera()
qdel(C)
else
@@ -332,11 +332,11 @@
ticker.mode.cult+=newstruct.mind
ticker.mode.update_cult_icons_added(newstruct.mind)
if(stoner && iswizard(stoner))
- to_chat(newstruct, "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.")
+ to_chat(newstruct, "You are still bound to serve your creator, follow [stoner.p_their()] orders and help [stoner.p_them()] complete [stoner.p_their()] goals at all costs.")
else if(stoner && iscultist(stoner))
- to_chat(newstruct, "You are still bound to serve the cult, follow their orders and help them complete their goals at all costs.")
+ to_chat(newstruct, "You are still bound to serve the cult, follow [stoner.p_their()] orders and help [stoner.p_them()] complete [stoner.p_their()] goals at all costs.")
else
- to_chat(newstruct, "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.")
+ to_chat(newstruct, "You are still bound to serve your creator, follow [stoner.p_their()] orders and help [stoner.p_them()] complete [stoner.p_their()] goals at all costs.")
newstruct.cancel_camera()
/obj/item/soulstone/proc/init_shade(mob/living/carbon/human/T, mob/U, vic = 0)
@@ -362,11 +362,11 @@
name = "soulstone: Shade of [T.real_name]"
icon_state = "soulstone2"
if(U && iswizard(U))
- to_chat(S, "Your soul has been captured! You are now bound to [U.real_name]'s will. Help them succeed in their goals at all costs.")
+ to_chat(S, "Your soul has been captured! You are now bound to [U.real_name]'s will. Help [U.p_them()] succeed in their goals at all costs.")
else if(U && iscultist(U))
- to_chat(S, "Your soul has been captured! You are now bound to the cult's will. Help them succeed in their goals at all costs.")
+ to_chat(S, "Your soul has been captured! You are now bound to the cult's will. Help [U.p_them()] succeed in their goals at all costs.")
if(vic && U)
- to_chat(U, "Capture successful!: [T.real_name]'s soul has been ripped from their body and stored within the soul stone.")
+ to_chat(U, "Capture successful!: [T.real_name]'s soul has been ripped from [U.p_their()] body and stored within the soul stone.")
/obj/item/soulstone/proc/getCultGhost(mob/living/carbon/human/T, mob/U)
var/mob/dead/observer/chosen_ghost
diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm
index 9d7ddab9d71..0c380010e6a 100644
--- a/code/game/gamemodes/wizard/spellbook.dm
+++ b/code/game/gamemodes/wizard/spellbook.dm
@@ -505,7 +505,7 @@
var/list/datum/spellbook_entry/entries = list()
var/list/categories = list()
-/obj/item/spellbook/proc/Initialize()
+/obj/item/spellbook/proc/initialize()
var/entry_types = subtypesof(/datum/spellbook_entry) - /datum/spellbook_entry/item - /datum/spellbook_entry/summon
for(var/T in entry_types)
var/datum/spellbook_entry/E = new T
@@ -518,7 +518,7 @@
/obj/item/spellbook/New()
..()
- Initialize()
+ initialize()
/obj/item/spellbook/attackby(obj/item/O as obj, mob/user as mob, params)
if(istype(O, /obj/item/contract))
@@ -685,7 +685,7 @@
..()
name += spellname
-/obj/item/spellbook/oneuse/Initialize() //No need to init
+/obj/item/spellbook/oneuse/initialize() //No need to init
return
/obj/item/spellbook/oneuse/attack_self(mob/user)
diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm
index 44333b774cc..40c303ea36f 100644
--- a/code/game/gamemodes/wizard/wizard.dm
+++ b/code/game/gamemodes/wizard/wizard.dm
@@ -27,7 +27,7 @@
wizards += wizard
modePlayer += wizard
- wizard.assigned_role = "MODE" //So they aren't chosen for other jobs.
+ wizard.assigned_role = SPECIAL_ROLE_WIZARD //So they aren't chosen for other jobs.
wizard.special_role = SPECIAL_ROLE_WIZARD
wizard.original = wizard.current
if(wizardstart.len == 0)
@@ -141,8 +141,9 @@
wizard_mob.equip_to_slot_or_del(new /obj/item/radio/headset(wizard_mob), slot_l_ear)
wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(wizard_mob), slot_w_uniform)
wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(wizard_mob), slot_shoes)
- wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(wizard_mob), slot_wear_suit)
- wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(wizard_mob), slot_head)
+ if(!wizard_mob.get_species() == "Plasmaman")//handled in the species file for plasmen on the afterjob equip proc for now
+ wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(wizard_mob), slot_wear_suit)
+ wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(wizard_mob), slot_head)
if(wizard_mob.backbag == 2)
wizard_mob.equip_to_slot_or_del(new /obj/item/storage/backpack(wizard_mob), slot_back)
if(wizard_mob.backbag == 3)
diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm
index 61c14efc2e5..0e315e03b2c 100644
--- a/code/game/jobs/job_controller.dm
+++ b/code/game/jobs/job_controller.dm
@@ -1,10 +1,6 @@
var/global/datum/controller/occupations/job_master
-#define GET_RANDOM_JOB 0
-#define BE_ASSISTANT 1
-#define RETURN_TO_LOBBY 2
-
/datum/controller/occupations
//List of all jobs
var/list/occupations = list()
diff --git a/code/game/jobs/job_exp.dm b/code/game/jobs/job_exp.dm
index 3c17c6f0107..552654245dd 100644
--- a/code/game/jobs/job_exp.dm
+++ b/code/game/jobs/job_exp.dm
@@ -1,11 +1,12 @@
// Playtime requirements for special roles (hours)
var/global/list/role_playtime_requirements = list(
- // CREW-FRIENDLY ROLES
+ // NT ROLES
ROLE_PAI = 0,
ROLE_POSIBRAIN = 5, // Same as cyborg job.
ROLE_SENTIENT = 5,
ROLE_ERT = 10, // High, because they're team-based, and we want ERT to be robust
+ ROLE_DEATHSQUAD = 10,
ROLE_TRADER = 5,
ROLE_DRONE = 10, // High, because they're like mini engineering cyborgs that can ignore the AI, ventcrawl, and respawn themselves
diff --git a/code/game/jobs/job_objective.dm b/code/game/jobs/job_objective.dm
index 8860cdf4931..90bac6d8383 100644
--- a/code/game/jobs/job_objective.dm
+++ b/code/game/jobs/job_objective.dm
@@ -49,7 +49,7 @@
if(!employee.job_objectives.len)//If the employee had no objectives, don't need to process this.
continue
- if(!employee.assigned_role=="MODE")//If the employee is a gamemode thing, skip.
+ if(employee.assigned_role == employee.special_role) //If the character is an offstation character, skip them.
continue
var/tasks_completed=0
@@ -68,7 +68,7 @@
count++
if(tasks_completed >= 1)
- text += "
[employee.name] did their fucking job!"
+ text += "
[employee.name] did [employee.p_their()] fucking job!"
feedback_add_details("employee_success","SUCCESS")
else
feedback_add_details("employee_success","FAIL")
diff --git a/code/game/machinery/OpTable.dm b/code/game/machinery/OpTable.dm
index 3c9c27f1590..f7925fecda5 100644
--- a/code/game/machinery/OpTable.dm
+++ b/code/game/machinery/OpTable.dm
@@ -54,13 +54,12 @@
if(prob(75))
qdel(src)
-/obj/machinery/optable/attack_hand(mob/user as mob)
- if(HULK in usr.mutations)
- to_chat(usr, text("You destroy the table."))
- visible_message("[usr] destroys the operating table!")
- src.density = 0
+/obj/machinery/optable/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
+ if(user.a_intent == INTENT_HARM)
+ ..(user, TRUE)
+ visible_message("[user] destroys the operating table!")
qdel(src)
- return
+ return TRUE
/obj/machinery/optable/CanPass(atom/movable/mover, turf/target, height=0)
if(height==0) return 1
diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm
index 7d386ddfb1a..24311a8b12e 100644
--- a/code/game/machinery/Sleeper.dm
+++ b/code/game/machinery/Sleeper.dm
@@ -257,7 +257,7 @@
if(href_list["chemical"])
if(occupant)
if(occupant.stat == DEAD)
- to_chat(usr, "This person has no life for to preserve anymore. Take them to a department capable of reanimating them.")
+ to_chat(usr, "This person has no life for to preserve anymore. Take [occupant.p_them()] to a department capable of reanimating them.")
else if(occupant.health > min_health || (href_list["chemical"] in emergency_chems))
inject_chemical(usr,href_list["chemical"],text2num(href_list["amount"]))
else
@@ -327,34 +327,35 @@
return
if(istype(G, /obj/item/grab))
+ var/obj/item/grab/GG = G
if(panel_open)
to_chat(user, "Close the maintenance panel first.")
return
- if(!ismob(G:affecting))
+ if(!ismob(GG.affecting))
return
if(src.occupant)
to_chat(user, "The sleeper is already occupied!")
return
- for(var/mob/living/carbon/slime/M in range(1,G:affecting))
- if(M.Victim == G:affecting)
- to_chat(usr, "[G:affecting.name] will not fit into the sleeper because they have a slime latched onto their head.")
+ for(var/mob/living/carbon/slime/M in range(1,GG.affecting))
+ if(M.Victim == GG.affecting)
+ to_chat(usr, "[GG.affecting.name] will not fit into the sleeper because [GG.affecting.p_they()] [GG.affecting.p_have()] a slime latched onto [GG.affecting.p_their()] head.")
return
- visible_message("[user] starts putting [G:affecting:name] into the sleeper.")
+ visible_message("[user] starts putting [GG.affecting.name] into the sleeper.")
- if(do_after(user, 20, target = G:affecting))
+ if(do_after(user, 20, target = GG.affecting))
if(src.occupant)
to_chat(user, "The sleeper is already occupied!")
return
- if(!G || !G:affecting) return
- var/mob/M = G:affecting
+ if(!GG || !GG.affecting) return
+ var/mob/M = GG.affecting
M.forceMove(src)
src.occupant = M
src.icon_state = "[base_icon]"
to_chat(M, "You feel cool air surround you. You go numb as your senses turn inward.")
src.add_fingerprint(user)
- qdel(G)
+ qdel(GG)
return
return
@@ -496,7 +497,7 @@
return
for(var/mob/living/carbon/slime/M in range(1,L))
if(M.Victim == L)
- to_chat(usr, "[L.name] will not fit into the sleeper because they have a slime latched onto their head.")
+ to_chat(usr, "[L.name] will not fit into the sleeper because [L.p_they()] [L.p_have()] a slime latched onto their head.")
return
if(L == user)
visible_message("[user] starts climbing into the sleeper.")
diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm
index f2dc8c8bfa2..59009e9930f 100644
--- a/code/game/machinery/adv_med.dm
+++ b/code/game/machinery/adv_med.dm
@@ -95,7 +95,7 @@
return
for(var/mob/living/carbon/slime/M in range(1, TYPECAST_YOUR_SHIT.affecting))
if(M.Victim == TYPECAST_YOUR_SHIT.affecting)
- to_chat(user, "[TYPECAST_YOUR_SHIT.affecting.name] has a fucking slime attached to them, deal with that first.")
+ to_chat(user, "[TYPECAST_YOUR_SHIT.affecting.name] has a fucking slime attached to [TYPECAST_YOUR_SHIT.affecting.p_them()], deal with that first.")
return
var/mob/M = TYPECAST_YOUR_SHIT.affecting
if(M.abiotic())
@@ -133,7 +133,7 @@
return 0
for(var/mob/living/carbon/slime/M in range(1, O))
if(M.Victim == O)
- to_chat(user, "[O] has a fucking slime attached to them, deal with that first.")
+ to_chat(user, "[O] has a fucking slime attached to [O.p_them()], deal with that first.")
return 0
if(O == user)
diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm
index 13ab409ca1b..dd0231982d3 100644
--- a/code/game/machinery/alarm.dm
+++ b/code/game/machinery/alarm.dm
@@ -229,16 +229,18 @@
apply_preset(1) // Don't cycle.
air_alarm_repository.update_cache(src)
-/obj/machinery/alarm/initialize()
+/obj/machinery/alarm/Initialize()
..()
set_frequency(frequency)
if(!master_is_operating())
elect_master()
/obj/machinery/alarm/proc/master_is_operating()
- if(! alarm_area)
+ if(!alarm_area)
alarm_area = areaMaster
-
+ if(!alarm_area)
+ log_runtime(EXCEPTION("Air alarm /obj/machinery/alarm lacks alarm_area and areaMaster vars during proc/master_is_operating()"), src)
+ return FALSE
return alarm_area.master_air_alarm && !(alarm_area.master_air_alarm.stat & (NOPOWER|BROKEN))
diff --git a/code/game/machinery/atmo_control.dm b/code/game/machinery/atmo_control.dm
index b5e1bd59325..b6586d3c90a 100644
--- a/code/game/machinery/atmo_control.dm
+++ b/code/game/machinery/atmo_control.dm
@@ -127,7 +127,7 @@ obj/machinery/air_sensor
frequency = new_frequency
radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA)
- initialize()
+ Initialize()
..()
SSair.atmos_machinery += src
set_frequency(frequency)
@@ -275,7 +275,7 @@ legend {
frequency = new_frequency
radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA)
- initialize()
+ Initialize()
..()
set_frequency(frequency)
diff --git a/code/game/machinery/atmoalter/meter.dm b/code/game/machinery/atmoalter/meter.dm
index ce69429eace..03fa12a1c26 100644
--- a/code/game/machinery/atmoalter/meter.dm
+++ b/code/game/machinery/atmoalter/meter.dm
@@ -30,7 +30,7 @@
target = null
return ..()
-/obj/machinery/meter/initialize()
+/obj/machinery/meter/Initialize()
..()
if(!target)
target = locate(/obj/machinery/atmospherics/pipe) in loc
@@ -144,7 +144,7 @@
return 1
-/obj/machinery/meter/turf/initialize()
+/obj/machinery/meter/turf/Initialize()
if(!target)
target = loc
..()
diff --git a/code/game/machinery/atmoalter/portable_atmospherics.dm b/code/game/machinery/atmoalter/portable_atmospherics.dm
index 99070a35fd1..34088a6314c 100644
--- a/code/game/machinery/atmoalter/portable_atmospherics.dm
+++ b/code/game/machinery/atmoalter/portable_atmospherics.dm
@@ -21,7 +21,7 @@
return 1
-/obj/machinery/portable_atmospherics/initialize()
+/obj/machinery/portable_atmospherics/Initialize()
. = ..()
spawn()
var/obj/machinery/atmospherics/unary/portables_connector/port = locate() in loc
diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm
index a3eb5a5bd40..5382c9ec429 100644
--- a/code/game/machinery/buttons.dm
+++ b/code/game/machinery/buttons.dm
@@ -36,7 +36,7 @@
if(radio_controller)
set_frequency(frequency)
-/obj/machinery/driver_button/initialize()
+/obj/machinery/driver_button/Initialize()
..()
set_frequency(frequency)
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index c79904e1c59..0e9f261d73d 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -43,7 +43,7 @@
cameranet.cameras += src
cameranet.addCamera(src)
-/obj/machinery/camera/initialize()
+/obj/machinery/camera/Initialize()
..()
if(is_station_level(z) && prob(3) && !start_active)
toggle_cam()
diff --git a/code/game/machinery/camera/presets.dm b/code/game/machinery/camera/presets.dm
index 96db537d6dc..ac70a7c11ba 100644
--- a/code/game/machinery/camera/presets.dm
+++ b/code/game/machinery/camera/presets.dm
@@ -81,7 +81,7 @@
assembly.upgrades.Add(new /obj/item/assembly/prox_sensor(assembly))
setPowerUsage()
// Add it to machines that process
- machine_processing |= src
+ START_PROCESSING(SSmachines, src)
/obj/machinery/camera/proc/setPowerUsage()
var/mult = 1
diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm
index b7edd86b1af..57ade18dab3 100644
--- a/code/game/machinery/cell_charger.dm
+++ b/code/game/machinery/cell_charger.dm
@@ -75,7 +75,7 @@
/obj/machinery/cell_charger/proc/removecell()
- charging.updateicon()
+ charging.update_icon()
charging = null
chargelevel = -1
updateicon()
diff --git a/code/game/machinery/chiller.dm b/code/game/machinery/chiller.dm
index 4fae326fd6c..f48d59593ca 100644
--- a/code/game/machinery/chiller.dm
+++ b/code/game/machinery/chiller.dm
@@ -120,7 +120,7 @@
if("cellremove")
if(open && cell && !usr.get_active_hand())
- cell.updateicon()
+ cell.update_icon()
usr.put_in_hands(cell)
cell.add_fingerprint(usr)
cell = null
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index 0c6b293c680..ee53fdbce8b 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -113,7 +113,7 @@
var/datum/dna2/record/buf = null
var/read_only = 0 //Well,it's still a floppy disk
-/obj/item/disk/data/proc/Initialize()
+/obj/item/disk/data/proc/initialize()
buf = new
buf.dna=new
@@ -126,7 +126,7 @@
read_only = 1
/obj/item/disk/data/demo/New()
- Initialize()
+ initialize()
buf.types=DNA2_BUF_UE|DNA2_BUF_UI
//data = "066000033000000000AF00330660FF4DB002690"
//data = "0C80C80C80C80C80C8000000000000161FBDDEF" - Farmer Jeff
@@ -145,7 +145,7 @@
read_only = 1
/obj/item/disk/data/monkey/New()
- Initialize()
+ initialize()
buf.types=DNA2_BUF_SE
var/list/new_SE=list(0x098,0x3E8,0x403,0x44C,0x39F,0x4B0,0x59D,0x514,0x5FC,0x578,0x5DC,0x640,0x6A4)
for(var/i=new_SE.len;i<=DNA_SE_LENGTH;i++)
@@ -230,7 +230,8 @@
if(!R.dna)
R.dna = new /datum/dna()
- var/mob/living/carbon/human/H = new /mob/living/carbon/human(src, R.dna.species)
+ var/mob/living/carbon/human/H = new /mob/living/carbon/human(src)
+ H.set_species(R.dna.species)
occupant = H
if(!R.dna.real_name) //to prevent null names
diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index 1e207e3bdde..eebae34b9ea 100644
--- a/code/game/machinery/computer/arcade.dm
+++ b/code/game/machinery/computer/arcade.dm
@@ -814,7 +814,7 @@
if(ORION_TRAIL_SPACEPORT)
if(spaceport_raided)
- eventdat += "The Spaceport is on high alert! they wont let you dock since you tried to attack them!"
+ eventdat += "The Spaceport is on high alert! They wont let you dock since you tried to attack them!"
if(last_spaceport_action)
eventdat += "
Last Spaceport Action: [last_spaceport_action]"
eventdat += "Depart Spaceport
"
diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm
index cf94e35f1cf..30ccb23b467 100644
--- a/code/game/machinery/computer/buildandrepair.dm
+++ b/code/game/machinery/computer/buildandrepair.dm
@@ -362,7 +362,7 @@
/obj/item/circuitboard/rdconsole/attackby(obj/item/I as obj, mob/user as mob, params)
if(istype(I,/obj/item/card/id)||istype(I, /obj/item/pda))
if(allowed(user))
- user.visible_message("\the [user] waves their ID past the [src]'s access protocol scanner.", "You swipe your ID past the [src]'s access protocol scanner.")
+ user.visible_message("\the [user] waves [user.p_their()] ID past the [src]'s access protocol scanner.", "You swipe your ID past the [src]'s access protocol scanner.")
var/console_choice = input(user, "What do you want to configure the access to?", "Access Modification", "R&D Core") as null|anything in access_types
if(console_choice == null)
return
diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm
index 2195ee25522..00f6a98f2bc 100644
--- a/code/game/machinery/computer/camera_advanced.dm
+++ b/code/game/machinery/computer/camera_advanced.dm
@@ -8,16 +8,39 @@
var/list/networks = list("SS13")
var/datum/action/innate/camera_off/off_action = new
var/datum/action/innate/camera_jump/jump_action = new
+ var/list/actions = list()
/obj/machinery/computer/camera_advanced/proc/CreateEye()
eyeobj = new()
eyeobj.origin = src
-/obj/machinery/computer/camera_advanced/proc/GrantActions(mob/living/carbon/user)
- off_action.target = user
- off_action.Grant(user)
- jump_action.target = user
- jump_action.Grant(user)
+/obj/machinery/computer/camera_advanced/proc/GrantActions(mob/living/user)
+ if(off_action)
+ off_action.target = user
+ off_action.Grant(user)
+ actions += off_action
+
+ if(jump_action)
+ jump_action.target = user
+ jump_action.Grant(user)
+ actions += jump_action
+
+/obj/machinery/computer/camera_advanced/proc/remove_eye_control(mob/living/user)
+ if(!user)
+ return
+ for(var/V in actions)
+ var/datum/action/A = V
+ A.Remove(user)
+ if(user.client)
+ user.reset_perspective(null)
+ eyeobj.RemoveImages()
+ eyeobj.eye_user = null
+ user.remote_control = null
+ user.remote_view = FALSE
+
+ current_user = null
+ user.unset_machine()
+ playsound(src, 'sound/machines/terminal_off.ogg', 25, 0)
/obj/machinery/computer/camera_advanced/check_eye(mob/user)
if((stat & (NOPOWER|BROKEN)) || !Adjacent(user) || !user.has_vision() || user.incapacitated())
@@ -33,7 +56,7 @@
/obj/machinery/computer/camera_advanced/on_unset_machine(mob/M)
if(M == current_user)
- off_action.Activate()
+ remove_eye_control(M)
/obj/machinery/computer/camera_advanced/attack_hand(mob/user)
if(current_user)
@@ -95,6 +118,13 @@
origin = null
return ..()
+/mob/camera/aiEye/remote/RemoveImages()
+ ..()
+ if(visible_icon)
+ var/client/C = GetViewerClient()
+ if(C)
+ C.images -= user_image
+
/mob/camera/aiEye/remote/GetViewerClient()
if(eye_user)
return eye_user.client
@@ -140,20 +170,8 @@
return
var/mob/living/carbon/C = target
var/mob/camera/aiEye/remote/remote_eye = C.remote_control
- C.remote_view = 0
- remote_eye.origin.current_user = null
- remote_eye.origin.jump_action.Remove(C)
- remote_eye.eye_user = null
- if(C.client)
- C.reset_perspective(null)
- if(remote_eye.visible_icon)
- C.client.images -= remote_eye.user_image
- for(var/datum/camerachunk/chunk in remote_eye.visibleCameraChunks)
- C.client.images -= chunk.obscured
- C.remote_control = null
- C.unset_machine()
- src.Remove(C)
- playsound(remote_eye.origin, 'sound/machines/terminal_off.ogg', 25, 0)
+ var/obj/machinery/computer/camera_advanced/console = remote_eye.origin
+ console.remove_eye_control(target)
/datum/action/innate/camera_jump
name = "Jump To Camera"
diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm
index 49b3035646d..95aee7cb9fe 100644
--- a/code/game/machinery/computer/cloning.dm
+++ b/code/game/machinery/computer/cloning.dm
@@ -22,7 +22,7 @@
light_color = LIGHT_COLOR_DARKBLUE
-/obj/machinery/computer/cloning/initialize()
+/obj/machinery/computer/cloning/Initialize()
..()
updatemodules()
diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm
index ca44855d2aa..cfddc393875 100644
--- a/code/game/machinery/computer/computer.dm
+++ b/code/game/machinery/computer/computer.dm
@@ -19,7 +19,7 @@
overlay_layer = layer
..()
-/obj/machinery/computer/initialize()
+/obj/machinery/computer/Initialize()
..()
power_change()
update_icon()
diff --git a/code/game/machinery/computer/hologram.dm b/code/game/machinery/computer/hologram.dm
deleted file mode 100644
index 2d2e5d37ae0..00000000000
--- a/code/game/machinery/computer/hologram.dm
+++ /dev/null
@@ -1,118 +0,0 @@
-/obj/machinery/computer/hologram_comp
- name = "hologram computer"
- desc = "Rumoured to control holograms."
- icon = 'icons/obj/stationobjs.dmi'
- icon_keyboard = "tech_key"
- icon_screen = "holocontrol"
- var/obj/machinery/hologram/projector/projector = null
- var/temp = null
- var/lumens = 0.0
- var/h_r = 245.0
- var/h_g = 245.0
- var/h_b = 245.0
-
-
-/obj/machinery/computer/hologram_comp/New()
- ..()
- spawn( 10 )
- src.projector = locate(/obj/machinery/hologram/projector, get_step(src.loc, NORTH))
- return
- return
-
-/obj/machinery/computer/hologram_comp/attack_hand()
- if(!in_range(src, usr))
- return 0
- src.show_console(usr)
- return
-
-/obj/machinery/computer/hologram_comp/proc/render()
- var/icon/I = new /icon('icons/mob/human.dmi', "body_m_s")
-
- if(src.lumens >= 0)
- I.Blend(rgb(src.lumens, src.lumens, src.lumens), ICON_ADD)
- else
- I.Blend(rgb(- src.lumens, -src.lumens, -src.lumens), ICON_SUBTRACT)
-
- I.Blend(new /icon('icons/mob/human.dmi', "mouth_m_s"), ICON_OVERLAY)
- I.Blend(new /icon('icons/mob/underwear.dmi', "Mens White"), ICON_OVERLAY)
-
- var/icon/U = new /icon('icons/mob/human_face.dmi', "hair_a_s")
- U.Blend(rgb(src.h_r, src.h_g, src.h_b), ICON_ADD)
-
- I.Blend(U, ICON_OVERLAY)
-
- src.projector.hologram.icon = I
-
-/obj/machinery/computer/hologram_comp/proc/show_console(var/mob/user as mob)
- var/dat
- user.set_machine(src)
- if(src.temp)
- dat = text("[]
Clear", src.temp)
- else
- dat = text({"Hologram Status:
\n
- Power: []
\n
- Hologram Control:
\n
- Color Luminosity: []/220 \[Reset\]
\n
- Lighten: 1 10
\n
- Darken: 1 10
\n
-
\nHair Color: ([],[],[]) \[Reset\]
\n
- Red (0-255): \[0\] -10 -1 [] 1 10 \[255\]
\n
- Green (0-255): \[0\] -10 -1 [] 1 10 \[255\]
\n
- Blue (0-255): \[0\] -10 -1 [] 1 10 \[255\]
- "}, (src.projector.hologram ? "On" : "Off"), -src.lumens + 35, src.h_r, src.h_g, src.h_b, src.h_r, src.h_g, src.h_b)
- user << browse(dat, "window=hologram_console")
- onclose(user, "hologram_console")
- return
-
-/obj/machinery/computer/hologram_comp/Topic(href, href_list)
- if(..())
- return 1
- if(in_range(src, usr))
- flick("holo_console1", src)
- if(href_list["power"])
- if(src.projector.hologram)
- src.projector.icon_state = "hologram0"
- //src.projector.hologram = null
- qdel(src.projector.hologram)
- else
- src.projector.hologram = new(src.projector.loc)
- src.projector.hologram.icon = 'icons/mob/human.dmi'
- src.projector.hologram.icon_state = "body_m_s"
- src.projector.icon_state = "hologram1"
- src.render()
- else
- if(href_list["h_r"])
- if(src.projector.hologram)
- src.h_r += text2num(href_list["h_r"])
- src.h_r = min(max(src.h_r, 0), 255)
- render()
- else
- if(href_list["h_g"])
- if(src.projector.hologram)
- src.h_g += text2num(href_list["h_g"])
- src.h_g = min(max(src.h_g, 0), 255)
- render()
- else
- if(href_list["h_b"])
- if(src.projector.hologram)
- src.h_b += text2num(href_list["h_b"])
- src.h_b = min(max(src.h_b, 0), 255)
- render()
- else
- if(href_list["light"])
- if(src.projector.hologram)
- src.lumens += text2num(href_list["light"])
- src.lumens = min(max(src.lumens, -185.0), 35)
- render()
- else
- if(href_list["reset"])
- if(src.projector.hologram)
- src.lumens = 0
- render()
- else
- if(href_list["temp"])
- src.temp = null
- for(var/mob/M in viewers(1, src))
- if((M.client && M.machine == src))
- src.show_console(M)
- return
diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm
index aa7069d6e70..8bdc6b87243 100644
--- a/code/game/machinery/computer/message.dm
+++ b/code/game/machinery/computer/message.dm
@@ -80,7 +80,7 @@
..()
-/obj/machinery/computer/message_monitor/initialize()
+/obj/machinery/computer/message_monitor/Initialize()
..()
//Is the server isn't linked to a server, and there's a server available, default it to the first one in the list.
if(!linkedServer)
diff --git a/code/game/machinery/computer/power.dm b/code/game/machinery/computer/power.dm
index 4301350dc65..08f7a45221d 100644
--- a/code/game/machinery/computer/power.dm
+++ b/code/game/machinery/computer/power.dm
@@ -17,7 +17,7 @@
power_monitors = sortAtom(power_monitors)
power_monitor = new(src)
-/obj/machinery/computer/monitor/initialize()
+/obj/machinery/computer/monitor/Initialize()
..()
powermonitor_repository.update_cache()
powernet = find_powernet()
diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm
index 5ac655153a2..36a05e0442e 100644
--- a/code/game/machinery/cryo.dm
+++ b/code/game/machinery/cryo.dm
@@ -62,7 +62,7 @@
current_heat_capacity = 50 * C
efficiency = C
-/obj/machinery/atmospherics/unary/cryo_cell/initialize()
+/obj/machinery/atmospherics/unary/cryo_cell/atmos_init()
..()
if(node) return
for(var/cdir in cardinal)
@@ -108,7 +108,7 @@
return
for(var/mob/living/carbon/slime/M in range(1,L))
if(M.Victim == L)
- to_chat(usr, "[L.name] will not fit into the cryo cell because they have a slime latched onto their head.")
+ to_chat(usr, "[L.name] will not fit into the cryo cell because [L.p_they()] [L.p_have()] a slime latched onto [L.p_their()] head.")
return
if(put_mob(L))
if(L == user)
@@ -293,18 +293,19 @@
default_deconstruction_crowbar(G)
if(istype(G, /obj/item/grab))
+ var/obj/item/grab/GG = G
if(panel_open)
to_chat(user, "Close the maintenance panel first.")
return
- if(!ismob(G:affecting))
+ if(!ismob(GG.affecting))
return
- for(var/mob/living/carbon/slime/M in range(1,G:affecting))
- if(M.Victim == G:affecting)
- to_chat(usr, "[G:affecting:name] will not fit into the cryo because they have a slime latched onto their head.")
+ for(var/mob/living/carbon/slime/M in range(1,GG.affecting))
+ if(M.Victim == GG.affecting)
+ to_chat(usr, "[GG.affecting.name] will not fit into the cryo because [GG.affecting.p_they()] [GG.affecting.p_have()] a slime latched onto [GG.affecting.p_their()] head.")
return
- var/mob/M = G:affecting
+ var/mob/M = GG.affecting
if(put_mob(M))
- qdel(G)
+ qdel(GG)
return
/obj/machinery/atmospherics/unary/cryo_cell/update_icon()
diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
index f95c6f09e9b..80db23c59f7 100644
--- a/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -255,7 +255,7 @@
..()
-/obj/machinery/cryopod/initialize()
+/obj/machinery/cryopod/Initialize()
..()
find_control_computer()
@@ -551,7 +551,7 @@
for(var/mob/living/carbon/slime/M in range(1,L))
if(M.Victim == L)
- to_chat(usr, "[L.name] will not fit into the cryo pod because they have a slime latched onto their head.")
+ to_chat(usr, "[L.name] will not fit into the cryo pod because [L.p_they()] [L.p_have()] a slime latched onto [L.p_their()] head.")
return
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index baded609280..0d49cc1b0cd 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -115,10 +115,10 @@ About the new airlock wires panel:
..()
wires = new(src)
-/obj/machinery/door/airlock/initialize()
+/obj/machinery/door/airlock/Initialize()
. = ..()
if(closeOtherId != null)
- addtimer(src, "update_other_id", 5)
+ addtimer(CALLBACK(src, .proc/update_other_id), 5)
if(glass)
airlock_material = "glass"
if(security_level > AIRLOCK_SECURITY_METAL)
@@ -226,13 +226,11 @@ About the new airlock wires panel:
/obj/machinery/door/airlock/proc/loseMainPower()
main_power_lost_until = mainPowerCablesCut() ? -1 : world.time + SecondsToTicks(60)
if(main_power_lost_until > 0)
- main_power_timer = addtimer(src, "regainMainPower", SecondsToTicks(60), 1)
-
+ main_power_timer = addtimer(CALLBACK(src, .proc/regainMainPower), SecondsToTicks(60), TIMER_UNIQUE | TIMER_STOPPABLE)
// If backup power is permanently disabled then activate in 10 seconds if possible, otherwise it's already enabled or a timer is already running
if(backup_power_lost_until == -1 && !backupPowerCablesCut())
backup_power_lost_until = world.time + SecondsToTicks(10)
- backup_power_timer = addtimer(src, "regainBackupPower", SecondsToTicks(10), 1)
-
+ backup_power_timer = addtimer(CALLBACK(src, .proc/regainBackupPower), SecondsToTicks(10), TIMER_UNIQUE | TIMER_STOPPABLE)
// Disable electricity if required
if(electrified_until && isAllPowerLoss())
electrify(0)
@@ -240,7 +238,7 @@ About the new airlock wires panel:
/obj/machinery/door/airlock/proc/loseBackupPower()
backup_power_lost_until = backupPowerCablesCut() ? -1 : world.time + SecondsToTicks(60)
if(backup_power_lost_until > 0)
- backup_power_timer = addtimer(src, "regainBackupPower", SecondsToTicks(60), 1)
+ backup_power_timer = addtimer(CALLBACK(src, .proc/regainBackupPower), SecondsToTicks(60), TIMER_UNIQUE | TIMER_STOPPABLE)
// Disable electricity if required
if(electrified_until && isAllPowerLoss())
@@ -288,8 +286,7 @@ About the new airlock wires panel:
message = "The door is now electrified [duration == -1 ? "permanently" : "for [duration] second\s"]."
electrified_until = duration == -1 ? -1 : world.time + SecondsToTicks(duration)
if(duration != -1)
- electrified_timer = addtimer(src, "electrify", SecondsToTicks(duration), 1, 0)
-
+ electrified_timer = addtimer(CALLBACK(src, .proc/electrify, 0), SecondsToTicks(duration), TIMER_UNIQUE | TIMER_STOPPABLE)
if(feedback && message)
to_chat(usr, message)
@@ -650,7 +647,7 @@ About the new airlock wires panel:
if(affecting.receive_damage(10, 0))
H.UpdateDamageIcon()
else
- visible_message("[user] headbutts the airlock. Good thing they're wearing a helmet.")
+ visible_message("[user] headbutts the airlock. Good thing [user.p_theyre()] wearing a helmet.")
return
if(panel_open)
@@ -1080,8 +1077,7 @@ About the new airlock wires panel:
// The `addtimer` system has the advantage of being cancelable
if(autoclose)
- autoclose_timer = addtimer(src, "autoclose", normalspeed ? auto_close_time : auto_close_time_dangerous, unique = 1)
-
+ autoclose_timer = addtimer(CALLBACK(src, .proc/autoclose), normalspeed ? auto_close_time : auto_close_time_dangerous, TIMER_UNIQUE | TIMER_STOPPABLE)
return TRUE
/obj/machinery/door/airlock/close(forced=0, override = 0)
@@ -1098,7 +1094,7 @@ About the new airlock wires panel:
for(var/turf/turf in locs)
for(var/atom/movable/M in turf)
if(M.density && M != src) //something is blocking the door
- addtimer(src, "autoclose", 60)
+ addtimer(CALLBACK(src, .proc/autoclose), 60)
use_power(360) //360 W seems much more appropriate for an actuator moving an industrial door capable of crushing people
if(forced)
diff --git a/code/game/machinery/doors/airlock_control.dm b/code/game/machinery/doors/airlock_control.dm
index 930a4a2c045..4199d5e8c20 100644
--- a/code/game/machinery/doors/airlock_control.dm
+++ b/code/game/machinery/doors/airlock_control.dm
@@ -39,8 +39,8 @@
if(command_completed(cur_command))
cur_command = null
else
- if(!(src in machine_processing))
- machine_processing += src
+ if(!isprocessing)
+ START_PROCESSING(SSmachines, src)
/obj/machinery/door/airlock/proc/do_command(command)
switch(command)
@@ -132,7 +132,7 @@
frequency = new_frequency
radio_connection = radio_controller.add_object(src, frequency, RADIO_AIRLOCK)
-/obj/machinery/door/airlock/initialize()
+/obj/machinery/door/airlock/Initialize()
..()
if(frequency)
set_frequency(frequency)
@@ -207,7 +207,7 @@
frequency = new_frequency
radio_connection = radio_controller.add_object(src, frequency, RADIO_AIRLOCK)
-/obj/machinery/airlock_sensor/initialize()
+/obj/machinery/airlock_sensor/Initialize()
..()
set_frequency(frequency)
@@ -275,7 +275,7 @@
frequency = new_frequency
radio_connection = radio_controller.add_object(src, frequency, RADIO_AIRLOCK)
-/obj/machinery/access_button/initialize()
+/obj/machinery/access_button/Initialize()
..()
set_frequency(frequency)
diff --git a/code/game/machinery/doors/airlock_types.dm b/code/game/machinery/doors/airlock_types.dm
index 57027e4d366..5a8d04fa034 100644
--- a/code/game/machinery/doors/airlock_types.dm
+++ b/code/game/machinery/doors/airlock_types.dm
@@ -150,13 +150,15 @@
/obj/machinery/door/airlock/uranium/New()
..()
- addtimer(src, "radiate", event_step)
+ addtimer(CALLBACK(src, .proc/radiate), event_step)
+
/obj/machinery/door/airlock/uranium/proc/radiate()
if(prob(50))
for(var/mob/living/L in range (3,src))
L.apply_effect(15,IRRADIATE,0)
- addtimer(src, "radiate", event_step)
+ addtimer(CALLBACK(src, .proc/radiate), event_step)
+
/obj/machinery/door/airlock/uranium/glass
opacity = 0
@@ -350,7 +352,7 @@
if(isElectrified())
if(shock(user, 75))
return
- if(istype(C, /obj/item/detective_scanner) || istype(C, /obj/item/taperoll))
+ if(istype(C, /obj/item/detective_scanner))
return
if(istype(C, /obj/item/grenade/plastic/c4))
@@ -403,7 +405,7 @@
if(isElectrified())
if(shock(user, 75))
return
- if(istype(C, /obj/item/detective_scanner) || istype(C, /obj/item/taperoll))
+ if(istype(C, /obj/item/detective_scanner))
return
add_fingerprint(user)
diff --git a/code/game/machinery/doors/alarmlock.dm b/code/game/machinery/doors/alarmlock.dm
index cdada603a9b..c2e12618d79 100644
--- a/code/game/machinery/doors/alarmlock.dm
+++ b/code/game/machinery/doors/alarmlock.dm
@@ -18,7 +18,7 @@
air_connection = null
return ..()
-/obj/machinery/door/airlock/alarmlock/initialize()
+/obj/machinery/door/airlock/alarmlock/Initialize()
..()
radio_controller.remove_object(src, air_frequency)
air_connection = radio_controller.add_object(src, air_frequency, RADIO_TO_AIRALARM)
diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm
index 4d54c2e1e07..43156d2b484 100644
--- a/code/game/machinery/doors/brigdoors.dm
+++ b/code/game/machinery/doors/brigdoors.dm
@@ -73,7 +73,7 @@
return 1
-/obj/machinery/door_timer/initialize()
+/obj/machinery/door_timer/Initialize()
..()
Radio = new /obj/item/radio(src)
@@ -152,8 +152,7 @@
// Set releasetime
releasetime = world.timeofday + timetoset
- if(!(src in machine_processing))
- machine_processing += src
+ START_PROCESSING(SSmachines, src)
for(var/obj/machinery/door/window/brigdoor/door in targets)
if(door.density)
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index 61a528ed93d..563e4eb49f2 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -64,7 +64,7 @@
bound_width = world.icon_size
bound_height = width * world.icon_size
-/obj/machinery/door/initialize()
+/obj/machinery/door/Initialize()
air_update_turf(1)
..()
@@ -279,7 +279,7 @@
// The `addtimer` system has the advantage of being cancelable
if(autoclose)
- autoclose_timer = addtimer(src, "autoclose", normalspeed ? auto_close_time : auto_close_time_dangerous, unique = 1)
+ autoclose_timer = addtimer(CALLBACK(src, .proc/autoclose), normalspeed ? auto_close_time : auto_close_time_dangerous, TIMER_UNIQUE | TIMER_STOPPABLE)
return TRUE
@@ -292,7 +292,7 @@
for(var/atom/movable/M in get_turf(src))
if(M.density && M != src) //something is blocking the door
if(autoclose)
- addtimer(src, "autoclose", 60)
+ addtimer(CALLBACK(src, .proc/autoclose), 60)
return
operating = TRUE
@@ -325,7 +325,7 @@
/obj/machinery/door/proc/crush()
for(var/mob/living/L in get_turf(src))
- L.visible_message("[src] closes on [L], crushing them!", "[src] closes on you and crushes you!")
+ L.visible_message("[src] closes on [L], crushing [L.p_them()]!", "[src] closes on you and crushes you!")
if(isalien(L)) //For xenos
L.adjustBruteLoss(DOOR_CRUSH_DAMAGE * 1.5) //Xenos go into crit after aproximately the same amount of crushes as humans.
L.emote("roar")
diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm
index b20d99b2613..3f9e4f55a08 100644
--- a/code/game/machinery/doors/poddoor.dm
+++ b/code/game/machinery/doors/poddoor.dm
@@ -53,11 +53,38 @@
if(!hasPower())
open()
-/obj/machinery/door/poddoor/multi_tile // Whoever wrote the old code for multi-tile spesspod doors needs to burn in hell.
+ // Whoever wrote the old code for multi-tile spesspod doors needs to burn in hell. - Unknown
+ // Wise words. - Bxil
+/obj/machinery/door/poddoor/multi_tile
name = "large pod door"
layer = CLOSED_DOOR_LAYER
closingLayer = CLOSED_DOOR_LAYER
+/obj/machinery/door/poddoor/multi_tile/New()
+ . = ..()
+ apply_opacity_to_my_turfs(opacity)
+
+/obj/machinery/door/poddoor/multi_tile/open()
+ if(..())
+ apply_opacity_to_my_turfs(opacity)
+
+
+/obj/machinery/door/poddoor/multi_tile/close()
+ if(..())
+ apply_opacity_to_my_turfs(opacity)
+
+/obj/machinery/door/poddoor/multi_tile/Destroy()
+ apply_opacity_to_my_turfs(0)
+ return ..()
+
+//Multi-tile poddoors don't turn invisible automatically, so we change the opacity of the turfs below instead one by one.
+/obj/machinery/door/poddoor/multi_tile/proc/apply_opacity_to_my_turfs(var/new_opacity)
+ for(var/turf/T in locs)
+ T.opacity = new_opacity
+ T.has_opaque_atom = new_opacity
+ T.reconsider_lights()
+ update_freelook_sight()
+
/obj/machinery/door/poddoor/multi_tile/four_tile_ver/
icon = 'icons/obj/doors/1x4blast_vert.dmi'
width = 4
diff --git a/code/game/machinery/doors/spacepod.dm b/code/game/machinery/doors/spacepod.dm
index 93419b588f6..5aea5b477ed 100644
--- a/code/game/machinery/doors/spacepod.dm
+++ b/code/game/machinery/doors/spacepod.dm
@@ -7,7 +7,7 @@
anchored = 1
var/id = 1.0
-/obj/structure/spacepoddoor/initialize()
+/obj/structure/spacepoddoor/Initialize()
..()
air_update_turf(1)
diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm
index 181e273dd43..1ab22f341b6 100644
--- a/code/game/machinery/doors/windowdoor.dm
+++ b/code/game/machinery/doors/windowdoor.dm
@@ -16,17 +16,20 @@
var/obj/item/airlock_electronics/electronics
var/base_state = "left"
var/reinf = 0
+ var/cancolor = TRUE
var/shards = 2
var/rods = 2
var/cable = 1
var/list/debris = list()
-/obj/machinery/door/window/New()
+/obj/machinery/door/window/New(loc, set_dir)
..()
+ if(set_dir)
+ setDir(set_dir)
if(req_access && req_access.len)
icon_state = "[icon_state]"
base_state = icon_state
- if(!color)
+ if(!color && cancolor)
color = color_windows(src)
for(var/i in 1 to shards)
debris += new /obj/item/shard(src)
@@ -97,6 +100,16 @@
return 1
if(get_dir(loc, target) == dir) //Make sure looking at appropriate border
return !density
+ if(istype(mover, /obj/structure/window))
+ var/obj/structure/window/W = mover
+ if(!valid_window_location(loc, W.ini_dir))
+ return FALSE
+ else if(istype(mover, /obj/structure/windoor_assembly))
+ var/obj/structure/windoor_assembly/W = mover
+ if(!valid_window_location(loc, W.ini_dir))
+ return FALSE
+ else if(istype(mover, /obj/machinery/door/window) && !valid_window_location(loc, mover.dir))
+ return FALSE
else
return 1
@@ -128,7 +141,7 @@
if(emagged)
return 0
if(!operating) //in case of emag
- operating = 1
+ operating = TRUE
do_animate("opening")
playsound(loc, 'sound/machines/windowdoor.ogg', 100, 1)
icon_state ="[base_state]open"
@@ -152,7 +165,7 @@
if(forced < 2)
if(emagged)
return 0
- operating = 1
+ operating = TRUE
do_animate("closing")
playsound(loc, 'sound/machines/windowdoor.ogg', 100, 1)
icon_state = base_state
@@ -186,6 +199,11 @@
/obj/machinery/door/window/narsie_act()
color = NARSIE_WINDOW_COLOUR
+/obj/machinery/door/window/ratvar_act()
+ var/obj/machinery/door/window/clockwork/C = new(loc, dir)
+ C.name = name
+ qdel(src)
+
/obj/machinery/door/window/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > T0C + (reinf ? 1600 : 800))
take_damage(round(exposed_volume / 200), BURN, 0, 0)
@@ -204,7 +222,7 @@
/obj/machinery/door/window/emag_act(mob/user, obj/weapon)
if(!operating && density && !emagged)
emagged = TRUE
- operating = 1
+ operating = TRUE
flick("[base_state]spark", src)
playsound(src, "sparks", 75, 1)
sleep(6)
@@ -314,6 +332,45 @@
desc = "For keeping in criminal scum."
req_access = list(access_brig)
+/obj/machinery/door/window/clockwork
+ name = "brass windoor"
+ desc = "A thin door with translucent brass paneling."
+ icon_state = "clockwork"
+ base_state = "clockwork"
+ shards = 0
+ rods = 0
+ burn_state = FIRE_PROOF
+ cancolor = FALSE
+ var/made_glow = FALSE
+
+/obj/machinery/door/window/clockwork/New(loc, set_dir)
+ ..()
+ debris += new/obj/item/stack/tile/brass(src, 2)
+
+/obj/machinery/door/window/clockwork/setDir(direct)
+ if(!made_glow)
+ var/obj/effect/E = new /obj/effect/temp_visual/ratvar/door/window(get_turf(src))
+ E.setDir(direct)
+ made_glow = TRUE
+ ..()
+
+/obj/machinery/door/window/clockwork/emp_act(severity)
+ if(prob(80/severity))
+ open()
+
+/obj/machinery/door/window/clockwork/ratvar_act()
+ obj_integrity = max_integrity
+
+/obj/machinery/door/window/clockwork/hasPower()
+ return TRUE //yup that's power all right
+
+/obj/machinery/door/window/clockwork/narsie_act()
+ take_damage(rand(30, 60), BRUTE)
+ if(src)
+ var/previouscolor = color
+ color = "#960000"
+ animate(src, color = previouscolor, time = 8)
+
/obj/machinery/door/window/northleft
dir = NORTH
diff --git a/code/game/machinery/dye_generator.dm b/code/game/machinery/dye_generator.dm
index 3216c945106..bb47a4939ec 100644
--- a/code/game/machinery/dye_generator.dm
+++ b/code/game/machinery/dye_generator.dm
@@ -8,7 +8,7 @@
idle_power_usage = 40
var/dye_color = "#FFFFFF"
-/obj/machinery/dye_generator/initialize()
+/obj/machinery/dye_generator/Initialize()
..()
power_change()
diff --git a/code/game/machinery/embedded_controller/airlock_controllers.dm b/code/game/machinery/embedded_controller/airlock_controllers.dm
index 27ee0197514..5209003fc59 100644
--- a/code/game/machinery/embedded_controller/airlock_controllers.dm
+++ b/code/game/machinery/embedded_controller/airlock_controllers.dm
@@ -12,7 +12,7 @@
var/tag_shuttle_mech_sensor
var/tag_secure = 0
-/obj/machinery/embedded_controller/radio/airlock/initialize()
+/obj/machinery/embedded_controller/radio/airlock/Initialize()
..()
program = new/datum/computer/file/embedded_program/airlock(src)
diff --git a/code/game/machinery/embedded_controller/embedded_controller_base.dm b/code/game/machinery/embedded_controller/embedded_controller_base.dm
index 08143524744..889263da2f8 100644
--- a/code/game/machinery/embedded_controller/embedded_controller_base.dm
+++ b/code/game/machinery/embedded_controller/embedded_controller_base.dm
@@ -54,7 +54,7 @@
var/datum/radio_frequency/radio_connection
unacidable = 1
-/obj/machinery/embedded_controller/radio/initialize()
+/obj/machinery/embedded_controller/radio/Initialize()
..()
set_frequency(frequency)
diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm
index da64430b941..2b0691d5801 100644
--- a/code/game/machinery/flasher.dm
+++ b/code/game/machinery/flasher.dm
@@ -76,7 +76,7 @@
L.Weaken(strength)
if(L.weakeyes)
L.Weaken(strength * 1.5)
- L.visible_message("[L] gasps and shields their eyes!")
+ L.visible_message("[L] gasps and shields [L.p_their()] eyes!")
/obj/machinery/flasher/emp_act(severity)
if(stat & (BROKEN|NOPOWER))
diff --git a/code/game/machinery/floodlight.dm b/code/game/machinery/floodlight.dm
index 5428e03d4a8..8ac57a5cec6 100644
--- a/code/game/machinery/floodlight.dm
+++ b/code/game/machinery/floodlight.dm
@@ -48,7 +48,7 @@
cell.loc = loc
cell.add_fingerprint(user)
- cell.updateicon()
+ cell.update_icon()
src.cell = null
to_chat(user, "You remove the power cell")
diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm
index 58404b133bd..0fc532ab0e4 100644
--- a/code/game/machinery/hologram.dm
+++ b/code/game/machinery/hologram.dm
@@ -1,7 +1,7 @@
-/* Holograms!
+/* holograms!
* Contains:
* Holopad
- * Hologram
+ * hologram
* Other stuff
*/
@@ -9,11 +9,10 @@
Revised. Original based on space ninja hologram code. Which is also mine. /N
How it works:
AI clicks on holopad in camera view. View centers on holopad.
-AI clicks again on the holopad to display a hologram. Hologram stays as long as AI is looking at the pad and it (the hologram) is in range of the pad.
+AI clicks again on the holopad to display a hologram. hologram stays as long as AI is looking at the pad and it (the hologram) is in range of the pad.
AI can use the directional keys to move the hologram around, provided the above conditions are met and the AI in question is the holopad's master.
Only one AI may project from a holopad at any given time.
AI may cancel the hologram at any time by clicking on the holopad once more.
-
Possible to do for anyone motivated enough:
Give an AI variable for different hologram icons.
Itegrate EMP effect to disable the unit.
@@ -27,19 +26,35 @@ Possible to do for anyone motivated enough:
// HOLOPAD MODE
// 0 = RANGE BASED
// 1 = AREA BASED
-var/const/HOLOPAD_MODE = 0
+#define HOLOPAD_PASSIVE_POWER_USAGE 1
+#define HOLOGRAM_POWER_USAGE 2
+#define RANGE_BASED 0
+#define AREA_BASED 1
+
+var/const/HOLOPAD_MODE = RANGE_BASED
+
var/list/holopads = list()
/obj/machinery/hologram/holopad
- name = "\improper AI holopad"
- desc = "It's a floor-mounted device for projecting holographic images. It is activated remotely."
+ name = "holopad"
+ desc = "It's a floor-mounted device for projecting holographic images."
icon_state = "holopad0"
-
+ anchored = 1
+ use_power = 1
+ idle_power_usage = 5
+ active_power_usage = 100
layer = TURF_LAYER+0.1 //Preventing mice and drones from sneaking under them.
armor = list(melee = 50, bullet = 20, laser = 20, energy = 20, bomb = 0, bio = 0, rad = 0)
- var/mob/living/silicon/ai/master//Which AI, if any, is controlling the object? Only one AI may control a hologram at any time.
+ var/list/masters = list()//List of living mobs that use the holopad
+ var/list/holorays = list()//Holoray-mob link.
var/last_request = 0 //to prevent request spam. ~Carn
var/holo_range = 5 // Change to change how far the AI can move away from the holopad before deactivating.
+ 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/static/force_answer_call = FALSE //Calls will be automatically answered after a couple rings, here for debugging
+ var/obj/effect/overlay/holoray/ray
+ var/ringing = FALSE
/obj/machinery/hologram/holopad/New()
..()
@@ -49,6 +64,27 @@ var/list/holopads = list()
component_parts += new /obj/item/stock_parts/capacitor(null)
RefreshParts()
+/obj/machinery/hologram/holopad/Destroy()
+ if(outgoing_call)
+ outgoing_call.ConnectionFailure(src)
+
+ for(var/I in holo_calls)
+ var/datum/holocall/HC = I
+ HC.ConnectionFailure(src)
+
+ for(var/I in masters)
+ clear_holo(I)
+ holopads -= src
+ return ..()
+
+/obj/machinery/hologram/holopad/power_change()
+ if(powered())
+ stat &= ~NOPOWER
+ else
+ stat |= NOPOWER
+ if(outgoing_call)
+ outgoing_call.ConnectionFailure(src)
+
/obj/machinery/hologram/holopad/RefreshParts()
var/holograph_range = 4
for(var/obj/item/stock_parts/capacitor/B in component_parts)
@@ -68,197 +104,383 @@ var/list/holopads = list()
default_deconstruction_crowbar(P)
-/obj/machinery/hologram/holopad/attack_hand(var/mob/living/carbon/human/user) //Carn: Hologram requests.
+/obj/machinery/hologram/holopad/attack_hand(mob/living/carbon/human/user)
+ if(..())
+ return
+
+ if(outgoing_call)
+ return
+
+ user.set_machine(src)
+ interact(user)
+
+/obj/machinery/hologram/holopad/AltClick(mob/living/carbon/human/user)
+ if(..())
+ return
+ if(isAI(user))
+ hangup_all_calls()
+ return
+
+//Stop ringing the AI!!
+/obj/machinery/hologram/holopad/proc/hangup_all_calls()
+ for(var/I in holo_calls)
+ var/datum/holocall/HC = I
+ HC.Disconnect(src)
+
+/obj/machinery/hologram/holopad/interact(mob/living/carbon/human/user) //Carn: hologram requests.
if(!istype(user))
return
- if(alert(user,"Would you like to request an AI's presence?",,"Yes","No") == "Yes")
- if(last_request + 200 < world.time) //don't spam the AI with requests you jerk!
- last_request = world.time
- to_chat(user, "You request an AI's presence.")
- var/area/area = get_area(src)
- for(var/mob/living/silicon/ai/AI in living_mob_list)
- if(!AI.client) continue
- to_chat(AI, "Your presence is requested at \the [area].")
- else
- to_chat(user, "A request for AI presence was already sent recently.")
+ var/dat
+ if(temp)
+ dat = temp
+ else
+ dat = "Request an AI's presence.
"
+ dat += "Call another holopad.
"
+
+ if(LAZYLEN(holo_calls))
+ dat += "=====================================================
"
+
+ var/one_answered_call = FALSE
+ var/one_unanswered_call = FALSE
+ for(var/I in holo_calls)
+ var/datum/holocall/HC = I
+ if(HC.connected_holopad != src)
+ dat += "Answer call from [get_area(HC.calling_holopad)].
"
+ one_unanswered_call = TRUE
+ else
+ one_answered_call = TRUE
+
+ if(one_answered_call && one_unanswered_call)
+ dat += "=====================================================
"
+ //we loop twice for formatting
+ for(var/I in holo_calls)
+ var/datum/holocall/HC = I
+ if(HC.connected_holopad == src)
+ dat += "Disconnect call from [HC.user].
"
+
+ var/area/area = get_area(src)
+ var/datum/browser/popup = new(user, "holopad", "[area] holopad", 400, 300)
+ popup.set_content(dat)
+ popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
+ popup.open()
+
+/obj/machinery/hologram/holopad/Topic(href, href_list)
+ if(..() || isAI(usr))
+ return
+ add_fingerprint(usr)
+ if(stat & NOPOWER)
+ return
+ if(href_list["AIrequest"])
+ if(last_request + 200 < world.time)
+ last_request = world.time
+ temp = "You requested an AI's presence.
"
+ temp += "Main Menu"
+ var/area/area = get_area(src)
+ for(var/mob/living/silicon/ai/AI in ai_list)
+ if(!AI.client)
+ continue
+ to_chat(AI, "Your presence is requested at \the [area].")
+ else
+ temp = "A request for AI presence was already sent recently.
"
+ temp += "Main Menu"
+
+ else if(href_list["Holocall"])
+ if(outgoing_call)
+ return
+
+ temp = "You must stand on the holopad to make a call!
"
+ temp += "Main Menu"
+ if(usr.loc == loc)
+ var/list/callnames = list()
+ for(var/I in holopads)
+ var/area/A = get_area(I)
+ if(A)
+ LAZYADD(callnames[A], I)
+ callnames -= get_area(src)
+
+ var/result = input(usr, "Choose an area to call", "Holocall") as null|anything in callnames
+
+ if(QDELETED(usr) || !result || outgoing_call)
+ return
+
+ if(usr.loc == loc)
+ temp = "Dialing...
"
+ temp += "Main Menu"
+ new /datum/holocall(usr, src, callnames[result])
+
+ else if(href_list["connectcall"])
+ var/datum/holocall/call_to_connect = locateUID(href_list["connectcall"])
+ if(!QDELETED(call_to_connect) && (call_to_connect in holo_calls))
+ call_to_connect.Answer(src)
+ temp = ""
+
+ else if(href_list["disconnectcall"])
+ var/datum/holocall/call_to_disconnect = locateUID(href_list["disconnectcall"])
+ if(!QDELETED(call_to_disconnect))
+ call_to_disconnect.Disconnect(src)
+ temp = ""
+
+ else if(href_list["mainmenu"])
+ temp = ""
+ if(outgoing_call)
+ outgoing_call.Disconnect()
+
+ updateDialog()
+
+//do not allow AIs to answer calls or people will use it to meta the AI satellite
/obj/machinery/hologram/holopad/attack_ai(mob/living/silicon/ai/user)
if(!istype(user))
return
+ if(outgoing_call)
+ return
/*There are pretty much only three ways to interact here.
I don't need to check for client since they're clicking on an object.
This may change in the future but for now will suffice.*/
- if(user.eyeobj.loc != src.loc)//Set client eye on the object if it's not already.
+ if(user.eyeobj.loc != loc)//Set client eye on the object if it's not already.
user.eyeobj.setLoc(get_turf(src))
- else if(!hologram)//If there is no hologram, possibly make one.
- activate_holo(user, 0)
- else if(master == user)//If there is a hologram, remove it. But only if the user is the master. Otherwise do nothing.
- clear_holo()
- return
+ else if(!LAZYLEN(masters) || !masters[user])//If there is no hologram, possibly make one.
+ activate_holo(user, 1)
+ else//If there is a hologram, remove it.
+ clear_holo(user)
-/obj/machinery/hologram/holopad/proc/activate_holo(mob/living/silicon/ai/user, var/force = 0)
- if(!force && user.eyeobj.loc != src.loc) // allows holopads to pass off holograms to the next holopad in the chain
+/obj/machinery/hologram/holopad/process()
+ for(var/I in masters)
+ var/mob/living/master = I
+ if((stat & NOPOWER) || !validate_user(master))
+ clear_holo(master)
+
+ if(outgoing_call)
+ outgoing_call.Check()
+
+ ringing = FALSE
+
+ for(var/I in holo_calls)
+ var/datum/holocall/HC = I
+ //Sanity check and skip if no longer valid call
+ if(!HC.Check())
+ atom_say("Call was terminated at remote terminal.")
+ continue
+
+ if(HC.connected_holopad != src)
+ if(force_answer_call && world.time > (HC.call_start_time + (HOLOPAD_MAX_DIAL_TIME / 2)))
+ HC.Answer(src)
+ break
+ if(outgoing_call)
+ HC.Disconnect(src)//can't answer calls while calling
+ else
+ playsound(src, 'sound/machines/twobeep.ogg', 100) //bring, bring!
+ ringing = TRUE
+
+ update_icon()
+
+
+//Try to transfer hologram to another pad that can project on T
+/obj/machinery/hologram/holopad/proc/transfer_to_nearby_pad(turf/T, mob/holo_owner)
+ if(!isAI(holo_owner))
+ return
+ for(var/pad in holopads)
+ var/obj/machinery/hologram/holopad/another = pad
+ if(another == src)
+ continue
+ if(another.validate_location(T))
+ var/obj/effect/overlay/holo_pad_hologram/h = masters[holo_owner]
+ unset_holo(holo_owner)
+ another.set_holo(holo_owner, h)
+ return TRUE
+ return FALSE
+
+/obj/machinery/hologram/holopad/proc/validate_user(mob/living/user)
+ if(QDELETED(user) || user.incapacitated() || !user.client)
+ return FALSE
+
+ if(istype(user, /mob/living/silicon/ai))
+ var/mob/living/silicon/ai/AI = user
+ if(!AI.current)
+ return FALSE
+ return TRUE
+
+//Can we display holos there
+//Area check instead of line of sight check because this is a called a lot if AI wants to move around.
+/obj/machinery/hologram/holopad/proc/validate_location(turf/T,check_los = FALSE)
+ if(T.z == z && get_dist(T, src) <= holo_range && T.loc == get_area(src))
+ return TRUE
+ return FALSE
+
+
+/obj/machinery/hologram/holopad/proc/move_hologram(mob/living/user, turf/new_turf)
+ if(masters[user])
+ var/obj/effect/overlay/holo_pad_hologram/holo = masters[user]
+ var/transfered = FALSE
+ if(!validate_location(new_turf))
+ if(!transfer_to_nearby_pad(new_turf,user))
+ clear_holo(user)
+ return FALSE
+ else
+ transfered = TRUE
+ //All is good.
+ holo.setDir(get_dir(holo.loc, new_turf))
+ holo.forceMove(new_turf)
+ if(!transfered)
+ update_holoray(user,new_turf)
+ return TRUE
+
+/obj/machinery/hologram/holopad/proc/activate_holo(mob/living/user, var/force = 0)
+ var/mob/living/silicon/ai/AI = user
+ if(!istype(AI))
+ AI = null
+ if(AI && !force && AI.eyeobj.loc != loc) // allows holopads to pass off holograms to the next holopad in the chain
to_chat(user, "ERROR: Unable to project hologram.")
- else if(!(stat & NOPOWER))//If the projector has power
- if(user.holo)
- var/obj/machinery/hologram/holopad/current = user.holo
- current.clear_holo()
- if(!hologram)//If there is not already a hologram.
- create_holo(user)//Create one.
- src.visible_message("A holographic image of [user] flicks to life right before your eyes!")
- else
- to_chat(user, "ERROR: Image feed in progress.")
- else
- to_chat(user, "ERROR: Unable to project hologram.")
- return
+ if(!(stat & NOPOWER) && (!AI || force))
+ if(AI && (istype(AI.current, /obj/machinery/hologram/holopad)))
+ to_chat(user, "ERROR: Image feed in progress.")
+ return
+
+ var/obj/effect/overlay/holo_pad_hologram/hologram = new(loc)//Spawn a blank effect at the location.
+ if(isAI(user))
+ hologram.icon = AI.holo_icon
+ else //make it like real life
+ hologram.icon = getHologramIcon(get_id_photo(user))
+ hologram.icon_state = user.icon_state
+ hologram.alpha = 100
+ hologram.Impersonation = user
+
+ hologram.mouse_opacity = 0//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 = 1//So space wind cannot drag it.
+ hologram.name = "[user.name] (hologram)"//If someone decides to right click.
+ hologram.set_light(2) //hologram lighting
+ move_hologram()
+
+ set_holo(user, hologram)
+
+ if(!masters[user])//If there is not already a hologram.
+ visible_message("A holographic image of [user] flicks to life right before your eyes!")
+
+ return hologram
+
+
+ to_chat(user, "ERROR: Hologram Projection Malfunction.")
+ clear_holo(user)//safety check
/*This is the proc for special two-way communication between AI and holopad/people talking near holopad.
For the other part of the code, check silicon say.dm. Particularly robot talk.*/
-/obj/machinery/hologram/holopad/hear_talk(mob/living/M, text, verb, datum/language/speaking)
- if(M && hologram && master)//Master is mostly a safety in case lag hits or something.
- master.relay_speech(M, text, verb, speaking)
+/obj/machinery/hologram/holopad/hear_talk(atom/movable/speaker, message, verb, datum/language/message_language)
+ if(speaker && masters.len)//Master is mostly a safety in case lag hits or something. Radio_freq so AIs dont hear holopad stuff through radios.
+ for(var/mob/living/silicon/ai/master in masters)
+ if(masters[master] && speaker != master)
+ master.relay_speech(speaker, message, verb, message_language)
-/obj/machinery/hologram/holopad/hear_message(mob/living/M, text)
- if(M&&hologram&&master)//Master is mostly a safety in case lag hits or something.
- var/name_used = M.GetVoice()
- var/rendered = "Holopad received, [name_used] [text]"
- master.show_message(rendered, 2)
- return
+ for(var/I in holo_calls)
+ var/datum/holocall/HC = I
+ if(HC.connected_holopad == src && speaker != HC.hologram)
+ HC.user.hear_say(message, verb, message_language, speaker = speaker)
-/obj/machinery/hologram/holopad/proc/create_holo(mob/living/silicon/ai/A, turf/T = loc)
- hologram = new(T)//Spawn a blank effect at the location.
- hologram.icon = A.holo_icon
- hologram.mouse_opacity = 0//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 = 1//So space wind cannot drag it.
- hologram.name = "[A.name] (Hologram)"//If someone decides to right click.
- hologram.set_light(2) //hologram lighting
- set_light(2) //pad lighting
- icon_state = "holopad1"
- A.holo = src
- master = A//AI is the master.
- use_power = 2//Active power usage.
- return 1
+ if(outgoing_call && speaker == outgoing_call.user)
+ outgoing_call.hologram.atom_say(message)
-/obj/machinery/hologram/holopad/proc/clear_holo()
-// hologram.set_light(0)//Clear lighting. //handled by the lighting controller when its ower is deleted
- QDEL_NULL(hologram)//Get rid of hologram.
- if(master.holo == src)
- master.holo = null
- master = null//Null the master, since no-one is using it now.
- set_light(0) //pad lighting (hologram lighting will be handled automatically since its owner was deleted)
- icon_state = "holopad0"
- use_power = 1//Passive power usage.
- return 1
-/obj/machinery/hologram/holopad/process()
- if(hologram)//If there is a hologram.
- if(master && !master.stat && master.client && master.eyeobj)//If there is an AI attached, it's not incapacitated, it has a client, and the client eye is centered on the projector.
- if(!(stat & NOPOWER))//If the machine has power.
- if((HOLOPAD_MODE == 0 && (get_dist(master.eyeobj, src) <= holo_range)))
- return 1
- else if(HOLOPAD_MODE == 1)
-
- var/area/holo_area = get_area(src)
- var/area/eye_area = get_area(master.eyeobj)
-
- if(eye_area != holo_area)
- return 1
-
- var/mob/living/silicon/ai/theai = master
- var/turf/target_turf = get_turf(master.eyeobj)
- var/newdir = hologram.dir
- clear_holo()//If not, we want to get rid of the hologram.
- var/obj/machinery/hologram/holopad/pad_close = get_closest_atom(/obj/machinery/hologram/holopad, holopads, theai.eyeobj)
- if(get_dist(pad_close, theai.eyeobj) <= pad_close.holo_range)
- if(!(pad_close.stat & NOPOWER) && !pad_close.hologram && (theai && !theai.stat && theai.client))
- pad_close.activate_holo(theai, 1)
- if(pad_close.hologram)
- pad_close.hologram.forceMove(target_turf)
- pad_close.hologram.dir = newdir
- return 1
-
-/obj/machinery/hologram/holopad/proc/move_hologram()
- if(hologram)
- step_to(hologram, master.eyeobj) // So it turns.
- hologram.loc = get_turf(master.eyeobj)
-
- return 1
-
-// Simple helper to face what you clicked on, in case it should be needed in more than one place
-/obj/machinery/hologram/holopad/proc/face_atom(var/atom/A)
- if( !hologram || !A || !hologram.x || !hologram.y || !A.x || !A.y ) return
- var/dx = A.x - hologram.x
- var/dy = A.y - hologram.y
- if(!dx && !dy) // Wall items are graphically shifted but on the floor
- if(A.pixel_y > 16) hologram.dir = NORTH
- else if(A.pixel_y < -16)hologram.dir = SOUTH
- else if(A.pixel_x > 16) hologram.dir = EAST
- else if(A.pixel_x < -16)hologram.dir = WEST
- return
-
- if(abs(dx) < abs(dy))
- if(dy > 0) hologram.dir = NORTH
- else hologram.dir = SOUTH
+/obj/machinery/hologram/holopad/proc/SetLightsAndPower()
+ var/total_users = masters.len + LAZYLEN(holo_calls)
+ use_power = HOLOPAD_PASSIVE_POWER_USAGE + HOLOGRAM_POWER_USAGE * total_users
+ if(total_users)
+ set_light(2)
+ icon_state = "holopad1"
else
- if(dx > 0) hologram.dir = EAST
- else hologram.dir = WEST
+ set_light(0)
+ icon_state = "holopad0"
+ update_icon()
-/*
- * Hologram
- */
+/obj/machinery/hologram/holopad/update_icon()
+ var/total_users = LAZYLEN(masters) + LAZYLEN(holo_calls)
+ if(ringing)
+ icon_state = "holopad_ringing"
+ else if(total_users)
+ icon_state = "holopad1"
+ else
+ icon_state = "holopad0"
-/obj/machinery/hologram
- anchored = 1
- use_power = 1
- idle_power_usage = 5
- active_power_usage = 100
- var/obj/effect/overlay/hologram//The projection itself. If there is one, the instrument is on, off otherwise.
-//Destruction procs.
-/obj/machinery/hologram/ex_act(severity)
- switch(severity)
- if(1.0)
- qdel(src)
- if(2.0)
- if(prob(50))
- qdel(src)
- if(3.0)
- if(prob(5))
- qdel(src)
- return
+/obj/machinery/hologram/holopad/proc/set_holo(mob/living/user, var/obj/effect/overlay/holo_pad_hologram/h)
+ masters[user] = h
+ holorays[user] = new /obj/effect/overlay/holoray(loc)
+ var/mob/living/silicon/ai/AI = user
+ if(istype(AI))
+ AI.current = src
+ SetLightsAndPower()
+ update_holoray(user, get_turf(loc))
+ return TRUE
-/obj/machinery/hologram/blob_act()
- qdel(src)
- return
+/obj/machinery/hologram/holopad/proc/clear_holo(mob/living/user)
+ qdel(masters[user]) // Get rid of user's hologram
+ unset_holo(user)
+ return TRUE
-/obj/machinery/hologram/holopad/Destroy()
- holopads -= src
- if(hologram)
- clear_holo()
+/obj/machinery/hologram/holopad/proc/unset_holo(mob/living/user)
+ var/mob/living/silicon/ai/AI = user
+ if(istype(AI) && AI.current == src)
+ AI.current = null
+ masters -= user // Discard AI from the list of those who use holopad
+ qdel(holorays[user])
+ holorays -= user
+ SetLightsAndPower()
+ return TRUE
+
+/obj/machinery/hologram/holopad/proc/update_holoray(mob/living/user, turf/new_turf)
+ var/obj/effect/overlay/holo_pad_hologram/holo = masters[user]
+ var/obj/effect/overlay/holoray/ray = holorays[user]
+ var/disty = holo.y - ray.y
+ var/distx = holo.x - ray.x
+ var/newangle
+ if(!disty)
+ if(distx >= 0)
+ newangle = 90
+ else
+ newangle = 270
+ else
+ newangle = arctan(distx/disty)
+ if(disty < 0)
+ newangle += 180
+ else if(distx < 0)
+ newangle += 360
+ var/matrix/M = matrix()
+ if(get_dist(get_turf(holo), new_turf) <= 1)
+ animate(ray, transform = turn(M.Scale(1, sqrt(distx*distx+disty*disty)), newangle), time = 1)
+ else
+ ray.transform = turn(M.Scale(1, sqrt(distx*distx+disty*disty)), newangle)
+
+
+/obj/effect/overlay/holo_pad_hologram
+ var/mob/living/Impersonation
+ var/datum/holocall/HC
+
+/obj/effect/overlay/holo_pad_hologram/Destroy()
+ Impersonation = null
+ if(!QDELETED(HC))
+ HC.Disconnect(HC.calling_holopad)
return ..()
-/*
-Holographic project of everything else.
+/obj/effect/overlay/holo_pad_hologram/Process_Spacemove(movement_dir = 0)
+ return 1
-/mob/verb/hologram_test()
- set name = "Hologram Debug New"
- set category = "CURRENT DEBUG"
+/obj/effect/overlay/holo_pad_hologram/examine(mob/user)
+ if(Impersonation)
+ return Impersonation.examine(user)
+ return ..()
- var/obj/effect/overlay/hologram = new(loc)//Spawn a blank effect at the location.
- var/icon/flat_icon = icon(getFlatIcon(src,0))//Need to make sure it's a new icon so the old one is not reused.
- flat_icon.ColorTone(rgb(125,180,225))//Let's make it bluish.
- flat_icon.ChangeOpacity(0.5)//Make it half transparent.
- var/input = input("Select what icon state to use in effect.",,"")
- if(input)
- var/icon/alpha_mask = new('icons/effects/effects.dmi', "[input]")
- flat_icon.AddAlphaMask(alpha_mask)//Finally, let's mix in a distortion effect.
- hologram.icon = flat_icon
- to_chat(world, "Your icon should appear now.")
- return
-*/
+/obj/effect/overlay/holoray
+ name = "holoray"
+ icon = 'icons/effects/96x96.dmi'
+ icon_state = "holoray"
+ layer = FLY_LAYER
+ density = FALSE
+ anchored = TRUE
+ mouse_opacity = 1
+ pixel_x = -32
+ pixel_y = -32
+ alpha = 100
/*
* Other Stuff: Is this even used?
@@ -268,3 +490,6 @@ Holographic project of everything else.
desc = "It makes a hologram appear...with magnets or something..."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "hologram0"
+
+#undef HOLOPAD_PASSIVE_POWER_USAGE
+#undef HOLOGRAM_POWER_USAGE
diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm
index f4a306d8bf2..d7a4a3e2b04 100644
--- a/code/game/machinery/iv_drip.dm
+++ b/code/game/machinery/iv_drip.dm
@@ -82,7 +82,7 @@
if(beaker)
usr.visible_message("[usr] attaches [src] to [target].", "You attach [src] to [target].")
attached = target
- machine_processing += src
+ START_PROCESSING(SSmachines, src)
update_icon()
else
to_chat(usr, "There's nothing attached to the IV drip!")
diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm
index 9862d952244..343734804cb 100644
--- a/code/game/machinery/lightswitch.dm
+++ b/code/game/machinery/lightswitch.dm
@@ -44,7 +44,7 @@
src.on = src.area.lightswitch
updateicon()
-/obj/machinery/light_switch/initialize()
+/obj/machinery/light_switch/Initialize()
..()
set_frequency(frequency)
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index 34842a64b76..18fc505a49b 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -119,7 +119,7 @@ Class Procs:
atom_say_verb = "beeps"
var/speed_process = 0 // Process as fast as possible?
-/obj/machinery/initialize()
+/obj/machinery/Initialize()
addAtProcessing()
. = ..()
power_change()
@@ -128,24 +128,26 @@ Class Procs:
if(use_power)
myArea = get_area_master(src)
if(!speed_process)
- machine_processing += src
+ START_PROCESSING(SSmachines, src)
else
fast_processing += src
+ isprocessing = TRUE // all of these isprocessing = TRUE can be removed when the PS is dead
// gotta go fast
/obj/machinery/proc/makeSpeedProcess()
if(speed_process)
return
speed_process = 1
- machine_processing -= src
+ STOP_PROCESSING(SSmachines, src)
fast_processing += src
+ isprocessing = TRUE
// gotta go slow
/obj/machinery/proc/makeNormalProcess()
if(!speed_process)
return
speed_process = 0
- machine_processing += src
+ START_PROCESSING(SSmachines, src)
fast_processing -= src
/obj/machinery/New() //new
@@ -158,7 +160,7 @@ Class Procs:
if(myArea)
myArea = null
fast_processing -= src
- machine_processing -= src
+ STOP_PROCESSING(SSmachines, src)
machines -= src
return ..()
@@ -309,7 +311,7 @@ Class Procs:
re_init=1
if(re_init)
- initialize()
+ Initialize()
if(update_mt_menu)
//usr.set_machine(src)
update_multitool_menu(usr)
diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm
index 422e697e7b0..491cb93018e 100644
--- a/code/game/machinery/newscaster.dm
+++ b/code/game/machinery/newscaster.dm
@@ -306,21 +306,21 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
if(FC.channel_name == channel_name)
check = 1
break
- if(channel_name == "" || channel_name == REDACTED || scanned_user == "Unknown" || check || (scanned_user in existing_authors))
- temp = "ERROR: Could not submit feed channel to Network."
- if(scanned_user in existing_authors)
- temp += "- There already exists a feed channel under your name.
"
- if(channel_name == "" || channel_name == REDACTED)
- temp += "- Invalid channel name.
"
- if(check)
- temp += "- Channel name already in use.
"
- if(scanned_user == "Unknown")
- temp += "- Channel author unverified.
"
- temp += "
"
- temp_back_screen = NEWSCASTER_CREATE_FC
- else
- var/choice = alert("Please confirm feed channel creation", "Network Channel Handler", "Confirm", "Cancel")
- if(choice == "Confirm")
+ var/choice = alert("Please confirm feed channel creation", "Network Channel Handler", "Confirm", "Cancel")
+ if(choice == "Confirm")
+ if(channel_name == "" || channel_name == REDACTED || scanned_user == "Unknown" || check || (scanned_user in existing_authors))
+ temp = "ERROR: Could not submit feed channel to Network."
+ if(scanned_user in existing_authors)
+ temp += "- There already exists a feed channel under your name.
"
+ if(channel_name == "" || channel_name == REDACTED)
+ temp += "- Invalid channel name.
"
+ if(check)
+ temp += "- Channel name already in use.
"
+ if(scanned_user == "Unknown")
+ temp += "- Channel author unverified.
"
+ temp += "
"
+ temp_back_screen = NEWSCASTER_CREATE_FC
+ else
var/datum/feed_channel/newChannel = new /datum/feed_channel
newChannel.channel_name = channel_name
newChannel.author = scanned_user
@@ -422,19 +422,19 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
else if(href_list["submit_wanted"])
var/input_param = text2num(href_list["submit_wanted"])
- if(msg == "" || channel_name == "" || scanned_user == "Unknown")
- temp = "ERROR: Wanted issue rejected by Network."
- if(channel_name == "" || channel_name == REDACTED)
- temp += "- Invalid name for person wanted.
"
- if(scanned_user == "Unknown")
- temp += "- Channel author unverified.
"
- if(msg == "" || msg == REDACTED)
- temp += "- Invalid description.
"
- temp += "
"
- temp_back_screen = NEWSCASTER_MAIN
- else
- var/choice = alert("Please confirm wanted issue [input_param == 1 ? "creation." : "edit."]", "Network Security Handler", "Confirm", "Cancel")
- if(choice == "Confirm")
+ var/choice = alert("Please confirm wanted issue [input_param == 1 ? "creation." : "edit."]", "Network Security Handler", "Confirm", "Cancel")
+ if(choice == "Confirm")
+ if(msg == "" || channel_name == "" || scanned_user == "Unknown")
+ temp = "ERROR: Wanted issue rejected by Network."
+ if(channel_name == "" || channel_name == REDACTED)
+ temp += "- Invalid name for person wanted.
"
+ if(scanned_user == "Unknown")
+ temp += "- Channel author unverified.
"
+ if(msg == "" || msg == REDACTED)
+ temp += "- Invalid description.
"
+ temp += "
"
+ temp_back_screen = NEWSCASTER_MAIN
+ else
if(input_param == 1) //input_param == 1: new wanted issue, input_param == 2: editing an existing one
var/datum/feed_message/W = new /datum/feed_message
W.author = channel_name
diff --git a/code/game/machinery/poolcontroller.dm b/code/game/machinery/poolcontroller.dm
index f6ecd511b2b..6c10129c6ea 100644
--- a/code/game/machinery/poolcontroller.dm
+++ b/code/game/machinery/poolcontroller.dm
@@ -107,7 +107,7 @@
else
drownee.AdjustLoseBreath(2, bound_lower = 0, bound_upper = 20) //For every time you drown, you miss 2 breath attempts. Hope you catch on quick!
if(prob(35)) //35% chance to tell them what is going on. They should probably figure it out before then.
- drownee.visible_message("\The [drownee] flails, almost like they are drowning!","You're lacking air!") //*gasp* *gasp* *gasp* *gasp* *gasp*
+ drownee.visible_message("\The [drownee] flails, almost like [drownee.p_they()] [drownee.p_are()] drowning!","You're lacking air!") //*gasp* *gasp* *gasp* *gasp* *gasp*
diff --git a/code/game/machinery/programmable_unloader.dm b/code/game/machinery/programmable_unloader.dm
deleted file mode 100644
index 310d1798a09..00000000000
--- a/code/game/machinery/programmable_unloader.dm
+++ /dev/null
@@ -1,734 +0,0 @@
-
-// TODO: Check access
-// TODO: Renameable circuit boards
-// TODO: Disks? Disassembly?
-
-/obj/machinery/programmable
- name = "Programmable Unloader"
- icon = 'icons/obj/machines/mining_machines.dmi'
- icon_state = "unloader"
- density = 1
- anchored = 1.0
-
- var/debug = 0 // When set, this WILL spam people around the machine.
- // Identifies profile used and on which item.
-
- var/on = 1
- var/indir = 8
- var/outdir = 4
- var/turf/input = null
- var/turf/output = null
- var/typename = "Unloader"
- var/ident = "#1"
-
- var/const/workmax = 20
- var/datum/cargoprofile/default = new()
- var/list/profiles = list(new/datum/cargoprofile/cargo(),new/datum/cargoprofile/boxes(),new/datum/cargoprofile/supplies(),
- new/datum/cargoprofile/exotics(),new/datum/cargoprofile/tools(),new/datum/cargoprofile/weapons(),
- new/datum/cargoprofile/pressure(),new/datum/cargoprofile/chemical(),
- new/datum/cargoprofile/food(),new/datum/cargoprofile/clothing(),new/datum/cargoprofile/trash())
- var/list/overrides = list(new/datum/cargoprofile/cargo/unload(),new/datum/cargoprofile/in_stacker())
- var/list/emag_overrides = list(new/datum/cargoprofile/people(),new/datum/cargoprofile/unary/shredder(),new/datum/cargoprofile/unary/trainer())
- var/list/types = list()
-
- anchored = 1
- var/unwrenched = 0
- use_power = 1
- var/sleep = 0 // When set, the machine will skip the next however-many updates (to avoid spam)
- var/open = 0
- var/circuit_removed = 0
-
-
-
-/obj/machinery/programmable/New()
- ..()
- if(default)
- default.master = src
- if(!default.enabled)
- default.enabled = 1
- for(var/datum/cargoprofile/p in emag_overrides + overrides + profiles)
- p.master = src
- input = get_step(src.loc,indir)
- output = get_step(src.loc,outdir)
- var/count = 0
- for(var/obj/machinery/programmable/other in world)
- if(other.typename == typename)
- count++
- ident = "#[count]"
- name = "[typename] [ident]"
-
-/obj/machinery/programmable/RefreshParts()
- //This is called when the machine was constructed.
- //Unfortunately, it puts machine parts in our contents list, which we're using.
- //Fortunately, we aren't likely to ever need the components list, circuitboard excepted.
-
- for(var/obj/O in contents)
- if(istype(O,/obj/item/circuitboard/programmable))//retrieve settings here
-
- var/obj/item/circuitboard/programmable/C = O
-
- default = C.default
- emagged = C.emagged
- profiles = C.profiles
- overrides = C.overrides
- emag_overrides = C.emag_overrides
-
- //unary and binary methods (one vs two locales) don't mix
-
- if(istype(src,/obj/machinery/programmable/unary))
- for(var/datum/cargoprofile/P in profiles)
- if(!istype(P,/datum/cargoprofile/unary) && !P.universal)
- profiles -= P
- for(var/datum/cargoprofile/P in overrides)
- if(!istype(P,/datum/cargoprofile/unary) && !P.universal)
- overrides -= P
- for(var/datum/cargoprofile/P in emag_overrides)
- if(!istype(P,/datum/cargoprofile/unary) && !P.universal)
- emag_overrides -= P
- else
- for(var/datum/cargoprofile/P in profiles)
- if(istype(P,/datum/cargoprofile/unary) && !P.universal)
- profiles -= P
- for(var/datum/cargoprofile/P in overrides)
- if(istype(P,/datum/cargoprofile/unary) && !P.universal)
- overrides -= P
- for(var/datum/cargoprofile/P in emag_overrides)
- if(istype(P,/datum/cargoprofile/unary) && !P.universal)
- emag_overrides -= P
- if(default)
- default.master = src
- for(var/datum/cargoprofile/p in emag_overrides + overrides + profiles)
- p.master = src
-
- qdel(C)
- else
- qdel(O)
-
-/obj/machinery/programmable/attack_hand(mob/user as mob)
- if(stat) // moved, or something else
- return
- usr.set_machine(src)
- interact(user)
-
-/obj/machinery/programmable/proc/printlist(var/list/L)
- var/dat
- for(var/datum/cargoprofile/p in L)
- dat += "[p.name]: [p.enabled?"YES":"NO"]
"
- return dat
-
-/obj/machinery/programmable/proc/buildMenu()
- var/dat
- dat += "PROGRAMMABLE UNLOADER
"
- dat += "POWER: [on ? "ON" : "OFF"]
"
- dat += "INLET: [capitalize(dir2text(indir))] "
- dat += "OUTLET: [capitalize(dir2text(outdir))]"
- dat += " (SWAP)
"
- if(default)
- dat += "MAIN PROGRAM: "
- dat += "[default.name]: [default.enabled ? "YES" : "NO"]
"
- if(profiles.len)
- if(!default || !default.enabled)
- dat += printlist(profiles)
- dat += ""
- if(overrides.len)
- dat += "
OVERRIDES:
"
- dat += printlist(overrides)
- dat += ""
- return dat
-
-/obj/machinery/programmable/interact(mob/user as mob)
- var/dat = buildMenu()
- user << browse("Unloader[dat]", "window=progreload")
- onclose(user, "progreload")
- return
-
-/obj/machinery/programmable/Topic(href, href_list)
- if(..())
- return 1
- usr.set_machine(src)
- add_fingerprint(usr)
- switch(href_list["operation"])
- if("start")
- on = (on ? 0 : 1)
- if(on) use_power = 1
- else use_power = 0
- updateUsrDialog()
- return
- if("inlet")
- indir *= 2 // N S E W
- if(indir > 8)
- indir = 1 // W N
- if(indir == src.outdir)
- indir *= 2
- if(indir > 8)
- indir = 1
- input = get_step(src,indir) // todo: check for glasswalls / no path to target?
- updateUsrDialog()
- return
- if("outlet")
- outdir *= 2
- if(outdir > 8)
- outdir = 1
- if(outdir == indir)
- outdir *= 2
- if(outdir > 8)
- outdir = 1
- output = get_step(src,outdir) // todo: check for walls / glasswalls / invalid output locations
- updateUsrDialog()
- return
- if("swapdir")
- var/temp = outdir
- outdir = indir
- indir = temp
- input = get_step(src,indir)
- output = get_step(src,outdir)
- updateUsrDialog()
- return
- if("default")
- default.enabled = (default.enabled ? 0 : 1)
- updateUsrDialog()
- return
- var/which = href_list["operation"]
- for(var/datum/cargoprofile/p in overrides + profiles)
- if(which == p.id)
- p.enabled = (p.enabled? 0 : 1)
- updateUsrDialog()
- return
-
-/obj/machinery/programmable/attackby(obj/item/I as obj, mob/user as mob, params)
- if(istype(I,/obj/item/wrench)) // code borrowed from pipe dispenser
- if(unwrenched==0)
- playsound(src.loc, I.usesound, 50, 1)
- to_chat(user, "You begin to unfasten \the [src] from the floor...")
- if(do_after(user, 40 * I.toolspeed, target = src))
- user.visible_message( \
- "[user] unfastens \the [src].", \
- "You have unfastened \the [src]. Now it can be pulled somewhere else.", \
- "You hear ratchet.")
- src.anchored = 0
- src.stat |= MAINT
- src.unwrenched = 1
- if(usr.machine==src)
- usr << browse(null, "window=pipedispenser")
- else /* unwrenched */
- playsound(src.loc, I.usesound, 50, 1)
- to_chat(user, "You begin to fasten \the [src] to the floor...")
- if(do_after(user, 20 * I.toolspeed, target = src))
- user.visible_message( \
- "[user] fastens \the [src].", \
- "You fastened \the [src] into place.", \
- "You hear ratchet.")
- src.anchored = 1
- src.input = get_step(src.loc,src.indir)
- src.output = get_step(src.loc,src.outdir)
- if(!open && !circuit_removed)
- src.stat &= ~MAINT
- src.unwrenched = 0
- power_change()
- if(istype(I,/obj/item/screwdriver))
- if(open)
- open = 0
- if(!unwrenched && !circuit_removed)
- src.stat &= ~MAINT
- to_chat(user, "You close \the [src]'s maintenance panel.")
- else
- open = 1
- src.stat |= MAINT
- to_chat(user, "You open \the [src]'s maintenance panel.")
- if(istype(I,/obj/item/crowbar))
- if(open)
- to_chat(user, "You begin to pry out the [src]'s circuits.")
- if(do_after(user, 40 * I.toolspeed, target = src))
- to_chat(user, "You remove the circuitboard.")
- playsound(loc, I.usesound, 50, 1)
- circuit_removed = 1
- use_power = 0
- on = 0
-
- var/obj/item/circuitboard/programmable/P = new(src.loc)
- P.emagged = src.emagged
- P.default = src.default
- src.default = null
- P.profiles = src.profiles
- src.profiles = null
- P.overrides = src.overrides
- src.overrides = null
- P.emag_overrides = src.emag_overrides
- src.emag_overrides = null
- default_deconstruction_crowbar(I, 1)
- return
- else
- ..(I,user)
-
- if(istype(I,/obj/item/circuitboard/programmable))
- if(!open)
- to_chat(user, "You have to open the machine first!")
- return
- if(!circuit_removed)
- to_chat(user, "There is already a circuitboard present!")
- return
- circuit_removed = 0
- I.loc = src
- RefreshParts()
-
-/obj/machinery/programmable/emag_act(user as mob)
- if(emagged)
- return
- to_chat(user, "You swipe the unloader with your card. After a moment's grinding, it beeps in a sinister fashion.")
- playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0)
- emagged = 1
- overrides += emag_overrides
-
- var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
- s.set_up(2, 1, src)
- s.start()
- return
-
-/obj/machinery/programmable/process()
- if(!output || !input)
- return
-
- if(!on || stat || sleep)
- if(sleep > 0) // prevent input or output errors from happening every tick
- sleep--
- use_power = 0
-
- //Do not let things get stuck inside. That's broken behavior.
- for(var/obj/O in contents)
- O.loc = loc
- for(var/mob/M in contents)
- M.loc = loc
- M.reset_perspective(null)
- to_chat(M, "The machine turns off, and you fall out.")
-
- return
-
- //Normal output reaction
- if(contents.len)
- for(var/atom/movable/A in contents)
- var/datum/cargoprofile/p = types[A.type]
- if(p)
- p.outlet_reaction(A,output)
- else
- A.loc = output // may have been dropped by a mob, etc
-
- if(types.len > 50)
- types = list() // good luck mr. garbage collector
-
-
- var/work = 0
- for(var/mob/M in input.contents)
- for(var/datum/cargoprofile/p in overrides + default)
- if(p.enabled && p.mobcheck && p.contains(M))
- var/done = p.inlet_reaction(M,input,workmax - work)
- if(done)
- work += done
- if(src.debug)
- visible_message("[p.name]:[M.name] ([done])")
- break
-
- if(sleep)
- return // something stopped the machine
-
- for(var/obj/A in input.contents)// I fully expect this to cause unreasonable lag
- if(!A)
- break
- if(work > workmax)
- playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0) // Beep if the machine is full - testing only probably
- break
-
- var/done = 0 // work done - testing only
- var/aname // target item name - testing only
-
- for(var/datum/cargoprofile/p in overrides)
- if(p.enabled && p.contains(A))
- aname = A.name // in case of deletion
- done = p.inlet_reaction(A,input,workmax - work)
- if(done)
- work += done
- if(src.debug)
- visible_message("[p.name]:[aname] ([done])")
-
- else
- break
- if(sleep)
- break // Something stopped the machine
- if(!A || A.loc != input || done)
- continue // next item
-
- if(default && default.enabled)
- if(default.contains(A))
- aname = A.name
- done = default.inlet_reaction(A,input,workmax - work)
- if(done)
- work += done
- if(src.debug)
- visible_message("[default.name]: [aname] ([done])")
- continue
- for(var/datum/cargoprofile/p in profiles)
- if(p.enabled && p.contains(A))
- aname = A.name
- done = p.inlet_reaction(A,input,workmax - work)
- if(done)
- work += done
- if(src.debug)
- visible_message("[p.name]:[aname] ([done])")
- else
- break
- if(work)
- use_power = 2
- else
- use_power = 1
-//----------------------------------------------------------------------------
-// Specialty machines
-//----------------------------------------------------------------------------
-
-//Uses the inlet stacking profile. Ejects only full stacks.
-/obj/machinery/programmable/stacker
- name = "Stacking & Spooling Machine"
- default = new/datum/cargoprofile/in_stacker()
- profiles = list()
- overrides = list()
- emag_overrides = list()
- typename = "Stacking and Spooling Machine"
-
-
-/obj/machinery/programmable/unloader
- name = "Cargo Unloader"
- default = new/datum/cargoprofile/cargo/unload()
- profiles = list()
- overrides = list()
- emag_overrides = list()
- typename = "Cargo Unloader"
-
-/obj/machinery/programmable/delivery
- name = "Finished robot delivery"
- default = new/datum/cargoprofile/finished()
- profiles = list()
- overrides = list()
- emag_overrides = list()
- typename = "Robot Delivery"
-
-/obj/machinery/programmable/crate_handler
- name = "Crate Handler"
- default = null
- profiles = list(new/datum/cargoprofile/cargo/unload(),new/datum/cargoprofile/cargo(),new/datum/cargoprofile/cargo/empty(),new/datum/cargoprofile/cargo/full())
- overrides = list()
- emag_overrides = list()
- typename = "Crate Handler"
-
-//----------------------------------------------------------------------------
-// Unary machine: Input and output in the same location
-// Be careful with this, it could easily be running the same
-// computations every round needlessly
-//----------------------------------------------------------------------------
-/obj/machinery/programmable/unary
- name = "Programmable Processor"
- default = null
- profiles = list()
- overrides = list(new/datum/cargoprofile/unary/stacker(),new/datum/cargoprofile/unary/trainer())
- emag_overrides = list(new/datum/cargoprofile/unary/shredder())
- indir = 1
- outdir = 1
- typename = "Processor"
-
- New()
- ..()
- outdir = indir
- output = input
- buildMenu()
- var/dat
- dat += "PROGRAMMABLE PROCESSOR
"
- dat += "POWER: [on ? "ON" : "OFF"]
"
- dat += "INLET: [capitalize(dir2text(indir))]
"
- if(default)
- dat += "MAIN PROGRAM: "
- dat += "[default.name]: [default.enabled ? "YES" : "NO"]
"
- if(profiles.len)
- if(!default || !default.enabled)
- dat += printlist(profiles)
- dat += ""
- if(overrides.len)
- dat += "
OVERRIDES:
"
- dat += printlist(overrides)
- dat += ""
- return dat
- Topic(href, href_list)
- switch(href_list["operation"])
- if("inlet")
- indir *= 2 // N S E W
- if(indir > 8)
- indir = 1 // W N
- outdir = indir
- input = get_step(src,indir) // todo: check for glasswalls / no path to target?
- output = input
- updateUsrDialog()
- return
- return ..()
-
-/obj/machinery/programmable/unary/stacker
- name = "Stacking Machine"
- default = new/datum/cargoprofile/unary/stacker()
- profiles = list()
- overrides = list()
- emag_overrides = list()
- typename = "Stacking Machine"
-
-/obj/machinery/programmable/unary/shredder
- name = "Paper Shredder"
- default = new/datum/cargoprofile/unary/shredder()
- profiles = list()
- overrides = list()
- emag_overrides = list(new/datum/cargoprofile/unary/gibber())
- typename = "Paper Shredder"
-
-/obj/machinery/programmable/unary/trainer
- name = "\improper Boxing Trainer"
- default = new/datum/cargoprofile/unary/trainer()
- profiles = list()
- overrides = list()
- emag_overrides = list()
- typename = "Boxing Trainer"
-
- attack_hand(mob/user as mob) //How did I type this with boxing gloves on?
- if(!istype(user,/mob/living/carbon/human))
- return ..()
-
- var/mob/living/carbon/human/H = user
- if(H.gloves && istype(H.gloves, /obj/item/clothing/gloves/boxing))
- var/newsleep = 0
- if(H.loc != input)
- to_chat(H, "The boxing machine refuses to acknowledge you unless you face it head on!")
- return
- var/damage = 0
- if(H.a_intent != INTENT_HARM)
- damage += rand(0,5)
- else
- damage += rand(0,10)
- if(!damage)
- playsound(H.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
- visible_message("[H] tries to punch \the [src], but whiffs")
- return
-
- playsound(loc, "punch", 25, 1, -1)
- if(HULK in H.mutations) damage += 5
-
- if(damage < 5)
- visible_message("[H] gives \the [src] a weak punch.")
- if(prob(10))
- visible_message("\The [src] feints at [H], as though mocking \him.")
- else if(damage < 10)
- visible_message("[H] hits \the [src] with a solid [pick("punch","jab","smack")].")
- else if(damage < 15)
- visible_message("[pick("Whoa!","Nice!","Gasp!")] [H] hits [src] with a powerful [pick("punch","jab","uppercut","left hook", "right hook")].")
- else if(damage < 20)
- visible_message("[pick("WHOA!","ACK!","Jeez!")] [H] hits [src] so hard, the whole machine rocks band and forth for a moment.")
- else
- visible_message("Holy moly! [H] hits \the [src] so hard it stops working.")
- stat |= BROKEN
- return
- while(damage >= 5)
- if(prob(50))
- newsleep++
- damage -= 5
- if(newsleep)
- if(emagged)
- visible_message("\The [src]'s lights glow a bloodthirsty red. It refuses to stop!")
- sleep = 0
- else
- sleep += newsleep
- visible_message("\The [src]'s lights dim for a moment and it beeps, signifying a valid hit.")
- playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0)
- return
-
- else
- return ..()
-
-//----------------------------------------------------------------------------
-// For construction
-//----------------------------------------------------------------------------
-/obj/item/circuitboard/programmable
- name = "Circuit board (Programmable Unloader)"
- build_path = "/obj/machinery/programmable"
- board_type = "machine"
- origin_tech = "engineering=1;programming=2"
- frame_desc = "Requires 2 Manipulators, 1 Scanning Module, 1 Cable."
- req_components = list(
- /obj/item/stock_parts/scanning_module = 1,
- /obj/item/stock_parts/manipulator = 2,
- /obj/item/stack/cable_coil = 1)
-
- //Customization of the machine
- var/datum/cargoprofile/default = new/datum/cargoprofile()
- var/list/profiles = list()
- var/list/overrides = list()
- var/list/emag_overrides = list()
-
- var/emagged = 0
- var/hacking = 0
-
- proc/resetlists()
- profiles = list(new/datum/cargoprofile/cargo(),new/datum/cargoprofile/boxes(),new/datum/cargoprofile/supplies(),
- new/datum/cargoprofile/exotics(),new/datum/cargoprofile/tools(),new/datum/cargoprofile/weapons(),new/datum/cargoprofile/finished(),
- new/datum/cargoprofile/pressure(),new/datum/cargoprofile/pressure/full(),new/datum/cargoprofile/pressure/empty(),
- new/datum/cargoprofile/chemical(),new/datum/cargoprofile/organics(),new/datum/cargoprofile/food(),
- new/datum/cargoprofile/clothing(),new/datum/cargoprofile/trash())
- overrides = list(new/datum/cargoprofile/cargo/unload(),new/datum/cargoprofile/in_stacker(),
- new/datum/cargoprofile/unary/stacker(),new/datum/cargoprofile/unary/trainer())
- emag_overrides = list(new/datum/cargoprofile/people(),new/datum/cargoprofile/unary/shredder())
-
- New()
- ..()
- resetlists()
-
- attackby(obj/item/I as obj, mob/user as mob, params)
- if(istype(I,/obj/item/multitool))
- hacking = (hacking?0:1)
- if(hacking)
- to_chat(user, "You unlock the data port on the board. You can now use a PDA to alter its data.")
- else
- to_chat(user, "You relock the data port.")
- if(istype(I,/obj/item/pda))
- if(!hacking)
- to_chat(user, "It looks like you can't access the board's data port. You'll have to open it with a multitool.")
- else
- user.set_machine(src)
- interact(user)
- if(istype(I,/obj/item/card/emag) && !emagged)
- if(!hacking)
- to_chat(user, "There seems to be a data port on the card, but it's locked. A multitool could open it.")
- else
- emagged = 1
- overrides += emag_overrides
- to_chat(user, "You swipe the card in the card's data port. The lights flicker, then flash once.")
-
- proc/format(var/datum/cargoprofile/P,var/level)
- // PROFILE=0 OVERRIDE=1 MAIN=2
- if(P == null)
- return "NONE
"
- var/dat = "[P.name]"
- if(level == 0 || (level == 1 && !default))
- dat += " PROMOTE"
- if(level > 0)
- dat += " DEMOTE"
- dat += " REMOVE"
- dat += "
"
- return dat
-
- interact(mob/user as mob)
- var/dat
- dat = "MAIN FUNCTION
"
- dat += format(default,2)
- dat += "- CAUTION -
\[DELETE NON-MAIN ALGORITHMS\]
"
- dat += "\[MASTER RESET\]
"
-
- dat += "OVERRIDES:
"
- for(var/datum/cargoprofile/P in overrides)
- dat += format(P,1)
- dat += "
"
- dat += "- CAUTION -
\[DELETE ALL OVERRIDES\]
"
-
- dat += " TERTIARY PROFILES:
"
- for(var/datum/cargoprofile/P in profiles)
- dat += format(P,0)
- dat += "
"
- dat += "- CAUTION -
\[DELETE TERTIARY PROFILES\]"
-
- user << browse("Circuit Reprogramming[dat]", "window=progcircuit")
- onclose(user, "progcircuit")
-
- Topic(href, href_list)
- if(..())
- return
- usr.set_machine(src)
- var/id = href_list["id"]
- var/level = text2num(href_list["level"])
- switch(href_list["operation"])
- if("promote")
- if(level == 0)
- for(var/datum/cargoprofile/T in profiles)
- if(T.id == id)
- overrides += T
- profiles -= T
- //updateUsrDialog()
- interact(usr)
- return
-
- if(level == 1)
- if(default) return
- for(var/datum/cargoprofile/T in overrides)
- if(T.id == id)
- default = T
- overrides -= T
-
- if(default.dedicated_path)
- build_path = "[default.dedicated_path]"
- else
- if(istype(default,/datum/cargoprofile/unary))
- build_path = "/obj/machinery/programmable/unary"
- else
- build_path = "/obj/machinery/programmable"
-
- //updateUsrDialog()
- interact(usr)
- return
-
- if("demote")
- if(level == 2)
- overrides += default
- default = null
- //updateUsrDialog()
- interact(usr)
- return
- if(level == 1)
- for(var/datum/cargoprofile/T in overrides)
- if(T.id == id)
- profiles += T
- overrides -= T
- //updateUsrDialog()
- interact(usr)
- return
- if("delete")
- if(level == 2)
- default = null
- //updateUsrDialog()
- interact(usr)
- return
- if(level == 1)
- for(var/datum/cargoprofile/T in overrides)
- if(T.id == id)
- overrides -= T
- //updateUsrDialog()
- interact(usr)
- return
- if(level == 0)
- for(var/datum/cargoprofile/T in profiles)
- if(T.id == id)
- profiles -= T
- //updateUsrDialog()
- interact(usr)
- return
- if("deleteall")
- for(var/datum/cargoprofile/T in profiles)
- profiles -= T
- for(var/datum/cargoprofile/T in overrides)
- overrides -= T
- //updateUsrDialog()
- interact(usr)
- return
- if("deleteoverrides")
- for(var/datum/cargoprofile/T in overrides)
- overrides -= T
- interact(usr)
- return
- if("deleteprofiles")
- for(var/datum/cargoprofile/T in profiles)
- profiles -= T
- interact(usr)
- return
- if("reset")
- resetlists()
- interact(usr)
- return
-
- //End switch
diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm
index 13a2ba49ddd..d80a628927b 100644
--- a/code/game/machinery/recycler.dm
+++ b/code/game/machinery/recycler.dm
@@ -143,7 +143,7 @@ var/const/SAFETY_COOLDOWN = 100
safety_mode = 1
update_icon()
L.loc = loc
- addtimer(src, "reboot", SAFETY_COOLDOWN)
+ addtimer(CALLBACK(src, .proc/reboot), SAFETY_COOLDOWN)
/obj/machinery/recycler/proc/reboot()
playsound(loc, 'sound/machines/ping.ogg', 50, 0)
diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm
index 24251977ca9..6ef4d064ac7 100644
--- a/code/game/machinery/shieldgen.dm
+++ b/code/game/machinery/shieldgen.dm
@@ -14,7 +14,7 @@
src.dir = pick(1,2,3,4)
..()
-/obj/machinery/shield/initialize()
+/obj/machinery/shield/Initialize()
air_update_turf(1)
..()
diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm
index a4a4091df7b..1962e3631fb 100644
--- a/code/game/machinery/spaceheater.dm
+++ b/code/game/machinery/spaceheater.dm
@@ -127,7 +127,7 @@
if("cellremove")
if(open && cell && !usr.get_active_hand())
- cell.updateicon()
+ cell.update_icon()
usr.put_in_hands(cell)
cell.add_fingerprint(usr)
cell = null
diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm
index 414ec8d2e62..ebf3cfeadf9 100644
--- a/code/game/machinery/status_display.dm
+++ b/code/game/machinery/status_display.dm
@@ -54,7 +54,7 @@
return ..()
// register for radio system
-/obj/machinery/status_display/initialize()
+/obj/machinery/status_display/Initialize()
..()
if(radio_controller)
radio_controller.add_object(src, frequency)
@@ -276,7 +276,6 @@
overlays.Cut()
overlays += image('icons/obj/status_display.dmi', icon_state=picture_state)
-#undef CHARS_PER_LINE
#undef FONT_SIZE
#undef FONT_COLOR
#undef WARNING_FONT_COLOR
diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm
index a7d68adbe62..370cef73559 100644
--- a/code/game/machinery/suit_storage_unit.dm
+++ b/code/game/machinery/suit_storage_unit.dm
@@ -413,13 +413,13 @@
var/i
for(i=0,i<4,i++) //Gradually give the guy inside some damaged based on the intensity
spawn(50)
- if(src.OCCUPANT)
- if(src.issuperUV)
+ if(OCCUPANT)
+ if(issuperUV)
OCCUPANT.take_organ_damage(0,40)
- to_chat(user, "Test. You gave him 40 damage")
+ to_chat(user, "Test. You gave [OCCUPANT.p_them()] 40 damage")
else
OCCUPANT.take_organ_damage(0,8)
- to_chat(user, "Test. You gave him 8 damage")
+ to_chat(user, "Test. You gave [OCCUPANT.p_them()] 8 damage")
return*/
diff --git a/code/game/machinery/syndicatebeacon.dm b/code/game/machinery/syndicatebeacon.dm
index 59f9a667584..7ec64373373 100644
--- a/code/game/machinery/syndicatebeacon.dm
+++ b/code/game/machinery/syndicatebeacon.dm
@@ -131,7 +131,7 @@
singulo.target = src
icon_state = "[icontype]1"
active = 1
- machine_processing |= src
+ START_PROCESSING(SSmachines, src)
if(user)
to_chat(user, "You activate the beacon.")
diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm
index 48637f9e67f..c640d5d5554 100644
--- a/code/game/machinery/syndicatebomb.dm
+++ b/code/game/machinery/syndicatebomb.dm
@@ -231,7 +231,8 @@
var/area/A = get_area(bombturf)
if(payload && !istype(payload, /obj/item/bombcore/training))
msg_admin_attack("[key_name_admin(user)] has primed a [name] ([payload]) for detonation at [A.name] (JMP).")
- log_game("[key_name(user)] has primed a [name] ([payload]) for detonation at [A.name] ([bombturf.x], [bombturf.y], [bombturf.z])")
+ log_game("[key_name(user)] has primed a [name] ([payload]) for detonation at [A.name] [COORD(bombturf)]")
+ investigate_log("[key_name(user)] has has primed a [name] ([payload]) for detonation at [A.name] [COORD(bombturf)]", INVESTIGATE_BOMB)
payload.adminlog = "\The [src] that [key_name(user)] had primed detonated!"
/obj/machinery/syndicatebomb/proc/isWireCut(var/index)
@@ -438,7 +439,7 @@
chem_splash(get_turf(src), spread_range, list(reactants), temp_boost)
// Detonate it again in one second, until it's out of juice.
- addtimer(src, "detonate", 10)
+ addtimer(CALLBACK(src, .proc/detonate), 10)
// If it's not a time release bomb, do normal explosion
@@ -556,11 +557,11 @@
var/area/A = get_area(T)
detonated--
message_admins("[key_name_admin(user)] has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using a [name] at [A.name] (JMP).")
- bombers += "[key_name(user)] has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using a [name] at [A.name] ([T.x],[T.y],[T.z])"
+ investigate_log("[key_name(user)] has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using a [name] at [A.name] ([T.x],[T.y],[T.z])", INVESTIGATE_BOMB)
log_game("[key_name(user)] has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using a [name] at [A.name] ([T.x],[T.y],[T.z])")
detonated = 0
existant = 0
timer = world.time + BUTTON_COOLDOWN
#undef BUTTON_COOLDOWN
-#undef BUTTON_DELAY
\ No newline at end of file
+#undef BUTTON_DELAY
diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm
index 00465cf8b8b..9dc30edf61e 100644
--- a/code/game/machinery/telecomms/telecomunications.dm
+++ b/code/game/machinery/telecomms/telecomunications.dm
@@ -116,7 +116,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
// TODO: Make the radio system cooperate with the space manager
listening_level = position.z
-/obj/machinery/telecomms/initialize()
+/obj/machinery/telecomms/Initialize()
..()
if(autolinkers.len)
// Links nearby machines
diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm
index fa8f2e8d084..a1248fc0b6d 100644
--- a/code/game/machinery/teleporter.dm
+++ b/code/game/machinery/teleporter.dm
@@ -18,7 +18,7 @@
..()
return
-/obj/machinery/computer/teleporter/initialize()
+/obj/machinery/computer/teleporter/Initialize()
..()
link_power_station()
update_icon()
@@ -293,7 +293,7 @@
component_parts += new /obj/item/stock_parts/matter_bin/super(null)
RefreshParts()
-/obj/machinery/teleport/hub/initialize()
+/obj/machinery/teleport/hub/Initialize()
..()
link_power_station()
@@ -472,7 +472,7 @@
RefreshParts()
link_console_and_hub()
-/obj/machinery/teleport/station/initialize()
+/obj/machinery/teleport/station/Initialize()
..()
link_console_and_hub()
diff --git a/code/game/machinery/turret_control.dm b/code/game/machinery/turret_control.dm
index 3b34dd7d805..2a46eb40eba 100644
--- a/code/game/machinery/turret_control.dm
+++ b/code/game/machinery/turret_control.dm
@@ -65,7 +65,7 @@
A.turret_controls -= src
return ..()
-/obj/machinery/turretid/initialize()
+/obj/machinery/turretid/Initialize()
..()
if(!control_area)
control_area = get_area(src)
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index db228aff04f..fb8b8fb0f32 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -1,7 +1,3 @@
-#define CAT_NORMAL 1
-#define CAT_HIDDEN 2 // also used in corresponding wires/vending.dm
-#define CAT_COIN 4
-
/**
* Datum used to hold information about a product in a vending machine
*/
diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm
index 98e7b6f342d..62928c95be5 100644
--- a/code/game/mecha/equipment/mecha_equipment.dm
+++ b/code/game/mecha/equipment/mecha_equipment.dm
@@ -12,7 +12,6 @@
var/energy_drain = 0
var/obj/mecha/chassis = null
var/range = MELEE //bitflags
- reliability = 1000
var/salvageable = 1
var/selectable = 1 // Set to 0 for passive equipment such as mining scanner or armor plates
@@ -90,7 +89,7 @@
/obj/item/mecha_parts/mecha_equipment/proc/start_cooldown()
set_ready_state(0)
chassis.use_power(energy_drain)
- addtimer(src, "set_ready_state", equip_cooldown, FALSE, 1)
+ addtimer(CALLBACK(src, .proc/set_ready_state, 1), equip_cooldown)
/obj/item/mecha_parts/mecha_equipment/proc/do_after_cooldown(atom/target)
if(!chassis)
diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm
index 5f3483d2ce4..a9d4b4008b6 100644
--- a/code/game/mecha/equipment/tools/medical_tools.dm
+++ b/code/game/mecha/equipment/tools/medical_tools.dm
@@ -74,7 +74,7 @@
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/patient_insertion_check(mob/living/carbon/target)
if(target.buckled)
- occupant_message("[target] will not fit into the sleeper because they are buckled to [target.buckled]!")
+ occupant_message("[target] will not fit into the sleeper because [target.p_they()] [target.p_are()] buckled to [target.buckled]!")
return
if(target.has_buckled_mobs())
occupant_message("[target] will not fit into the sleeper because of the creatures attached to it!")
diff --git a/code/game/mecha/equipment/tools/work_tools.dm b/code/game/mecha/equipment/tools/work_tools.dm
index 866cb7580f6..7706f3120f0 100644
--- a/code/game/mecha/equipment/tools/work_tools.dm
+++ b/code/game/mecha/equipment/tools/work_tools.dm
@@ -444,7 +444,6 @@
if(!PN)
PN = new()
- powernets += PN
NC.powernet = PN
PN.cables += NC
NC.mergeConnectedNetworks(NC.d2)
diff --git a/code/game/mecha/mech_bay.dm b/code/game/mecha/mech_bay.dm
index b14825c7cc0..a34d43098cb 100644
--- a/code/game/mecha/mech_bay.dm
+++ b/code/game/mecha/mech_bay.dm
@@ -177,7 +177,7 @@
return data
-/obj/machinery/computer/mech_bay_power_console/initialize()
+/obj/machinery/computer/mech_bay_power_console/Initialize()
reconnect()
update_icon()
return ..()
diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm
index dbaaf68cc1b..2ff4f478e2d 100644
--- a/code/game/mecha/mech_fabricator.dm
+++ b/code/game/mecha/mech_fabricator.dm
@@ -104,7 +104,7 @@
return output
/obj/machinery/mecha_part_fabricator/proc/output_part_info(datum/design/D)
- var/output = "[initial(D.name)] (Cost: [output_part_cost(D)]) [get_construction_time_w_coeff(D)/10]sec"
+ var/output = "[initial(D.name)] (Cost: [output_part_cost(D)]) [get_construction_time_w_coeff(D)/10] seconds"
return output
/obj/machinery/mecha_part_fabricator/proc/output_part_cost(datum/design/D)
@@ -304,8 +304,8 @@
if("parts")
left_part += output_parts_list(part_set)
left_part += "
Return"
- dat = {"
-
+ dat = {"
+
[name]