diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000000..1770177310d
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,14 @@
+[*]
+indent_style = tab
+indent_size = 4
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+end_of_line = lf
+
+[*.yml]
+indent_style = space
+indent_size = 2
+
+[*.py]
+indent_style = space
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index a5b1484486b..295cdfce5cb 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -479,8 +479,6 @@ in the SQL/updates folder.
* You are expected to help maintain the code that you add, meaning that if there is a problem then you are likely to be approached in order to fix any issues, runtimes, or bugs.
-* Do not divide when you can easily convert it to multiplication. (ie `4/2` should be done as `4*0.5`)
-
* If you used regex to replace code during development of your code, post the regex in your PR for the benefit of future developers and downstream users.
* All new var/proc names should use the American English spelling of words. This is for consistency with BYOND.
diff --git a/.github/workflows/label_merge_conflicts.yml b/.github/workflows/label_merge_conflicts.yml
new file mode 100644
index 00000000000..d2a56e2ef3d
--- /dev/null
+++ b/.github/workflows/label_merge_conflicts.yml
@@ -0,0 +1,13 @@
+name: 'Merge Conflict Detection'
+on:
+ push:
+ branches:
+ - master
+jobs:
+ triage:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: mschilde/auto-label-merge-conflicts@master
+ with:
+ CONFLICT_LABEL_NAME: 'Merge Conflict'
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.gitignore b/.gitignore
index 74660294c3b..e76c9f6db1d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,7 +32,6 @@ stddef.dm
/tools/dmitool/.project
# ignore midi2piano build cache
-/tools/midi2piano/obj/*
-
+/tools/midi2piano/midi2piano/obj/*
diff --git a/.travis.yml b/.travis.yml
index 5a731170a79..2c2b9dec61d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,72 +1,41 @@
-#pretending we're C because otherwise ruby will initialize, even with "language: dm".
language: generic
-sudo: false
+dist: xenial
+os: linux
git:
depth: 1
-cache:
- directories:
- - $HOME/BYOND-${BYOND_MAJOR}.${BYOND_MINOR}
-
-addons:
- apt:
- packages:
- - libc6-i386
- - libgcc1:i386
- - libstdc++6:i386
-
-env:
- global:
- - BYOND_MAJOR="513"
- - BYOND_MINOR="1505"
- - BYOND_MACRO_COUNT=4
- matrix:
- - DM_MAPFILE="cyberiad"
- - DM_MAPFILE="metastation"
- - DM_MAPFILE="delta"
- - DM_MAPFILE="test_all_maps"
-
-stages:
- - File Checks
- - test
-
-before_script:
- - chmod +x ./install-byond.sh
- - ./install-byond.sh
-script:
- - source $HOME/BYOND-${BYOND_MAJOR}.${BYOND_MINOR}/byond/bin/byondsetup
- - bash dm.sh -M${DM_MAPFILE} paradise.dme
-
jobs:
include:
- # Basic styling/functionality checks
- - stage: File Checks
- env:
+ - name: "Run Linters"
addons:
+ apt:
+ packages:
+ - python3
+ - python3-pip
+ - python3-setuptools
install:
- - pip install --user PyYaml -q
- - pip install --user beautifulsoup4 -q
- before_script: skip
+ - tools/travis/install_build_deps.sh
+ - tools/travis/install_dreamchecker.sh
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
+ - find . -name "*.php" -print0 | xargs -0 -n1 php -l
+ - find . -name "*.json" -not -path "./nano/node_modules/*" -print0 | xargs -0 python3 ./tools/travis/json_verifier.py
+ - tools/travis/build_nanoui.sh
+ - tools/travis/check_grep.sh
+ - python3 tools/travis/check_line_endings.py
+ - ~/dreamchecker
- # Compile NanoUI to make sure it works
- - stage: NanoUI
- language: node_js
- node_js:
- - "9"
- env:
+ - name: "Compile All Maps"
addons:
- before_install:
- - npm install -g gulp-cli
- - cd ./nano/
+ apt:
+ packages:
+ - libstdc++6:i386
+ cache:
+ directories:
+ - $HOME/BYOND
install:
- - npm install --loglevel=error
- before_script:
+ - tools/travis/install_byond.sh
+ - source $HOME/BYOND/byond/bin/byondsetup
script:
- - node node_modules/gulp/bin/gulp.js --require less-loader
+ - tools/travis/dm.sh -Mtravis_map_testing paradise.dme
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index 9099488143b..9ab4061ce6a 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -1,6 +1,7 @@
{
"recommendations": [
"gbasood.byond-dm-language-support",
- "platymuus.dm-langclient"
+ "platymuus.dm-langclient",
+ "EditorConfig.EditorConfig"
]
}
diff --git a/README.md b/README.md
index eafdb5ffe91..943397b0fa8 100644
--- a/README.md
+++ b/README.md
@@ -70,6 +70,16 @@ Make sure to set the port to the one you specified in the config.txt,
and set the Security box to 'Trusted'.
Then press GO and the server should start up and be ready to join.
+### Installation (Linux)
+
+The code is able to run on Linux server side, however the libraries for MySQL and logging do require extra packages.
+
+For MySQL, run the following: `apt-get install libmysqlclient-dev:i386`
+
+For RustG, run the following: `apt-get install libssl-dev:i386 pkg-config:i386 zlib1g-dev:i386`
+
+After installing these packages, these libraries should function as intended.
+
---
### UPDATING
diff --git a/SQL/paradise_schema.sql b/SQL/paradise_schema.sql
index 837f8f440d6..a447c7993ba 100644
--- a/SQL/paradise_schema.sql
+++ b/SQL/paradise_schema.sql
@@ -594,4 +594,18 @@ CREATE TABLE `connection_log` (
`ip` varchar(32) NOT NULL,
`computerid` varchar(32) NOT NULL,
PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
\ No newline at end of file
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+
+--
+-- Table structure for table `changelog`
+--
+DROP TABLE IF EXISTS `changelog`;
+CREATE TABLE `changelog` (
+ `id` INT(11) NOT NULL AUTO_INCREMENT,
+ `pr_number` INT(11) NOT NULL,
+ `date_merged` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ `author` VARCHAR(32) NOT NULL,
+ `cl_type` ENUM('FIX','WIP','TWEAK','SOUNDADD','SOUNDDEL','CODEADD','CODEDEL','IMAGEADD','IMAGEDEL','SPELLCHECK','EXPERIMENT') NOT NULL,
+ `cl_entry` TEXT NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
diff --git a/SQL/paradise_schema_prefixed.sql b/SQL/paradise_schema_prefixed.sql
index b43141f6784..6096f0547e6 100644
--- a/SQL/paradise_schema_prefixed.sql
+++ b/SQL/paradise_schema_prefixed.sql
@@ -591,4 +591,18 @@ CREATE TABLE `SS13_connection_log` (
`ip` varchar(32) NOT NULL,
`computerid` varchar(32) NOT NULL,
PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
\ No newline at end of file
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+
+--
+-- Table structure for table `SS13_changelog`
+--
+DROP TABLE IF EXISTS `SS13_changelog`;
+CREATE TABLE `SS13_changelog` (
+ `id` INT(11) NOT NULL AUTO_INCREMENT,
+ `pr_number` INT(11) NOT NULL,
+ `date_merged` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ `author` VARCHAR(32) NOT NULL,
+ `cl_type` ENUM('FIX','WIP','TWEAK','SOUNDADD','SOUNDDEL','CODEADD','CODEDEL','IMAGEADD','IMAGEDEL','SPELLCHECK','EXPERIMENT') NOT NULL,
+ `cl_entry` TEXT NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
diff --git a/SQL/updates/10-11.sql b/SQL/updates/10-11.sql
index 9564d3efaad..b2718db85e6 100644
--- a/SQL/updates/10-11.sql
+++ b/SQL/updates/10-11.sql
@@ -38,4 +38,4 @@ ALTER TABLE feedback.population CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4
ALTER TABLE feedback.privacy CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.vpn_whitelist CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.watch CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-ALTER TABLE feedback.whitelist CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
\ No newline at end of file
+ALTER TABLE feedback.whitelist CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
diff --git a/SQL/updates/11-12.sql b/SQL/updates/11-12.sql
new file mode 100644
index 00000000000..f6e9ac01baa
--- /dev/null
+++ b/SQL/updates/11-12.sql
@@ -0,0 +1,13 @@
+#Updating the SQL from version 11 to version 12. -AffectedArc07
+#Creating a table for the new changelog system
+
+DROP TABLE IF EXISTS `changelog`;
+CREATE TABLE IF NOT EXISTS `changelog` (
+ `id` INT(11) NOT NULL AUTO_INCREMENT,
+ `pr_number` INT(11) NOT NULL,
+ `date_merged` TIMESTAMP NOT NULL DEFAULT current_timestamp(),
+ `author` VARCHAR(32) NOT NULL,
+ `cl_type` ENUM('FIX','WIP','TWEAK','SOUNDADD','SOUNDDEL','CODEADD','CODEDEL','IMAGEADD','IMAGEDEL','SPELLCHECK','EXPERIMENT') NOT NULL,
+ `cl_entry` TEXT NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
diff --git a/_build_dependencies.sh b/_build_dependencies.sh
new file mode 100644
index 00000000000..24a33ed3644
--- /dev/null
+++ b/_build_dependencies.sh
@@ -0,0 +1,11 @@
+# This file has all the information on what versions of libraries are thrown into the code
+# For dreamchecker
+export SPACEMANDMM_TAG=suite-1.2
+# For NanoUI
+export NODE_VERSION=9
+# For the scripts in tools
+export PHP_VERSION=5.6
+# Byond Major
+export BYOND_MAJOR=513
+# Byond Minor
+export BYOND_MINOR=1505
diff --git a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm
index 864981494ac..5a880549b8a 100644
--- a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm
@@ -2017,7 +2017,7 @@
/obj/machinery/vending/sustenance{
desc = "A vending machine normally reserved for work camps.";
name = "\improper sustenance vendor";
- product_slogans = "Enjoy your meal.;Enough calories to support any worker."
+ slogan_list = list("Enjoy your meal.","Enough calories to support any worker.")
},
/turf/simulated/floor/plasteel{
icon_state = "floorgrime"
diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm
index 279afa9713d..07f00c599c3 100644
--- a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm
+++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm
@@ -1241,21 +1241,6 @@
/obj/structure/sign/securearea,
/turf/simulated/wall/mineral/plastitanium/explosive,
/area/ruin/unpowered/syndicate_lava_base/main)
-"cf" = (
-/obj/structure/table/reinforced,
-/obj/effect/turf_decal/tile/neutral{
- dir = 1
- },
-/obj/effect/turf_decal/tile/neutral,
-/obj/effect/turf_decal/tile/neutral{
- dir = 4
- },
-/obj/effect/turf_decal/tile/neutral{
- dir = 8
- },
-/obj/item/radio/intercom/syndicate,
-/turf/simulated/floor/plasteel/dark,
-/area/ruin/unpowered/syndicate_lava_base/telecomms)
"cg" = (
/obj/machinery/portable_atmospherics/canister/nitrogen,
/turf/simulated/floor/engine{
@@ -1789,7 +1774,6 @@
/area/ruin/unpowered/syndicate_lava_base/cargo)
"ed" = (
/obj/structure/table,
-/obj/item/paper_bin,
/obj/item/pen,
/obj/effect/decal/cleanable/dirt,
/obj/effect/decal/cleanable/dirt,
@@ -1803,6 +1787,7 @@
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
+/obj/item/paper_bin/syndicate,
/turf/simulated/floor/plasteel/dark,
/area/ruin/unpowered/syndicate_lava_base/cargo)
"ef" = (
@@ -1898,7 +1883,6 @@
"ep" = (
/obj/structure/table/reinforced,
/obj/effect/decal/cleanable/dirt,
-/obj/item/paper_bin,
/obj/item/pen,
/obj/machinery/atmospherics/pipe/simple/hidden/supply,
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,
@@ -1912,6 +1896,7 @@
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
+/obj/item/paper_bin/syndicate,
/turf/simulated/floor/plasteel/dark,
/area/ruin/unpowered/syndicate_lava_base/testlab)
"eq" = (
@@ -3529,10 +3514,6 @@
/obj/machinery/alarm/syndicate{
pixel_y = 24
},
-/obj/item/radio/headset/syndicate/alt{
- pixel_x = -3;
- pixel_y = 3
- },
/turf/simulated/floor/plasteel/grimy,
/area/ruin/unpowered/syndicate_lava_base/dormitories)
"hN" = (
@@ -3558,10 +3539,6 @@
/obj/machinery/alarm/syndicate{
pixel_y = 24
},
-/obj/item/radio/headset/syndicate/alt{
- pixel_x = -3;
- pixel_y = 3
- },
/turf/simulated/floor/plasteel/grimy,
/area/ruin/unpowered/syndicate_lava_base/dormitories)
"hR" = (
@@ -4479,10 +4456,6 @@
/obj/structure/table/wood,
/obj/item/ammo_box/magazine/m10mm,
/obj/item/ammo_box/magazine/sniper_rounds,
-/obj/item/radio/headset/syndicate/alt{
- pixel_x = -3;
- pixel_y = 3
- },
/turf/simulated/floor/plasteel/grimy,
/area/ruin/unpowered/syndicate_lava_base/dormitories)
"jB" = (
@@ -6785,13 +6758,12 @@
/obj/machinery/computer/message_monitor{
dir = 1
},
-/obj/item/paper/monitorkey,
/turf/simulated/floor/plasteel/dark,
/area/ruin/unpowered/syndicate_lava_base/telecomms)
"ov" = (
/obj/structure/table/reinforced,
-/obj/item/paper_bin,
/obj/item/pen,
+/obj/item/paper_bin/syndicate,
/turf/simulated/floor/plasteel/dark,
/area/ruin/unpowered/syndicate_lava_base/telecomms)
"ox" = (
@@ -7400,7 +7372,7 @@ mp
mQ
nl
nJ
-cf
+nJ
ov
mn
ab
diff --git a/_maps/map_files/RandomRuins/SpaceRuins/abandonedzoo.dmm b/_maps/map_files/RandomRuins/SpaceRuins/abandonedzoo.dmm
index 62a22425926..43aa3cd98c7 100644
--- a/_maps/map_files/RandomRuins/SpaceRuins/abandonedzoo.dmm
+++ b/_maps/map_files/RandomRuins/SpaceRuins/abandonedzoo.dmm
@@ -832,6 +832,10 @@
/obj/item/shard,
/turf/space,
/area/space/nearstation)
+"Hv" = (
+/obj/item/gps/ruin,
+/turf/simulated/wall/r_wall,
+/area/ruin/unpowered)
(1,1,1) = {"
aa
@@ -973,7 +977,7 @@ aa
at
at
aF
-at
+Hv
aU
ay
ay
diff --git a/_maps/map_files/RandomRuins/SpaceRuins/gasthelizards.dmm b/_maps/map_files/RandomRuins/SpaceRuins/gasthelizards.dmm
index d869d21f539..0f7c36fe634 100644
--- a/_maps/map_files/RandomRuins/SpaceRuins/gasthelizards.dmm
+++ b/_maps/map_files/RandomRuins/SpaceRuins/gasthelizards.dmm
@@ -99,14 +99,14 @@
"m" = (
/obj/structure/closet/crate/freezer,
/obj/item/stack/sheet/animalhide/lizard,
-/obj/item/reagent_containers/food/snacks/lizardmeat,
+/obj/item/reagent_containers/food/snacks/monstermeat/lizardmeat,
/turf/simulated/floor/plasteel{
icon_state = "dark"
},
/area/ruin/unpowered)
"n" = (
/obj/structure/closet/crate/freezer,
-/obj/item/reagent_containers/food/snacks/lizardmeat,
+/obj/item/reagent_containers/food/snacks/monstermeat/lizardmeat,
/obj/machinery/light{
dir = 1
},
@@ -116,7 +116,7 @@
/area/ruin/unpowered)
"o" = (
/obj/structure/closet/crate/freezer,
-/obj/item/reagent_containers/food/snacks/lizardmeat,
+/obj/item/reagent_containers/food/snacks/monstermeat/lizardmeat,
/turf/simulated/floor/plasteel{
icon_state = "dark"
},
diff --git a/_maps/map_files/RandomRuins/SpaceRuins/listeningpost.dmm b/_maps/map_files/RandomRuins/SpaceRuins/listeningpost.dmm
index 22d4c0798aa..17d49d666bc 100644
--- a/_maps/map_files/RandomRuins/SpaceRuins/listeningpost.dmm
+++ b/_maps/map_files/RandomRuins/SpaceRuins/listeningpost.dmm
@@ -269,6 +269,10 @@
icon_state = "freezerfloor"
},
/area/ruin/powered)
+"Y" = (
+/obj/item/gps/ruin,
+/turf/simulated/wall/r_wall,
+/area/ruin/powered)
(1,1,1) = {"
a
@@ -960,7 +964,7 @@ b
f
f
p
-f
+Y
f
f
j
diff --git a/_maps/map_files/RandomRuins/SpaceRuins/mechtransport.dmm b/_maps/map_files/RandomRuins/SpaceRuins/mechtransport.dmm
index 2a5c0eae533..b4e36942d6a 100644
--- a/_maps/map_files/RandomRuins/SpaceRuins/mechtransport.dmm
+++ b/_maps/map_files/RandomRuins/SpaceRuins/mechtransport.dmm
@@ -240,6 +240,13 @@
/obj/structure/shuttle/engine/propulsion,
/turf/simulated/shuttle/plating,
/area/ruin/powered)
+"U" = (
+/obj/item/gps/ruin,
+/turf/simulated/shuttle/wall{
+ tag = "icon-swall12";
+ icon_state = "swall12"
+ },
+/area/ruin/powered)
(1,1,1) = {"
a
@@ -313,7 +320,7 @@ a
c
g
l
-q
+U
r
u
t
diff --git a/_maps/map_files/RandomRuins/SpaceRuins/wizardcrash.dmm b/_maps/map_files/RandomRuins/SpaceRuins/wizardcrash.dmm
index fef87df8950..ebfaf3b94b4 100644
--- a/_maps/map_files/RandomRuins/SpaceRuins/wizardcrash.dmm
+++ b/_maps/map_files/RandomRuins/SpaceRuins/wizardcrash.dmm
@@ -209,7 +209,6 @@
"aI" = (
/obj/structure/table/wood,
/obj/item/toy/character/wizard,
-/obj/item/paper/spells,
/turf/simulated/floor/carpet,
/area/ruin/unpowered)
"aJ" = (
diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm
index d046e4fb402..7cf27593f6f 100644
--- a/_maps/map_files/cyberiad/cyberiad.dmm
+++ b/_maps/map_files/cyberiad/cyberiad.dmm
@@ -1619,15 +1619,12 @@
/area/security/range)
"adH" = (
/obj/structure/table/wood,
-/obj/item/paper_bin{
- pixel_x = -3;
- pixel_y = 7
- },
/obj/item/pen/multi,
/obj/machinery/light{
dir = 1;
on = 1
},
+/obj/item/paper_bin/nanotrasen,
/turf/simulated/floor/plasteel{
icon_state = "dark"
},
@@ -16077,16 +16074,13 @@
/area/lawoffice)
"aAI" = (
/obj/structure/table/reinforced,
-/obj/item/paper_bin{
- pixel_x = -3;
- pixel_y = 7
- },
/obj/item/pen,
/obj/machinery/alarm{
dir = 8;
pixel_x = 25;
pixel_y = 0
},
+/obj/item/paper_bin/nanotrasen,
/turf/simulated/floor/plasteel{
tag = "icon-cult";
icon_state = "cult";
@@ -16863,11 +16857,8 @@
/area/magistrateoffice)
"aCj" = (
/obj/structure/table/reinforced,
-/obj/item/paper_bin{
- pixel_x = -3;
- pixel_y = 7
- },
/obj/item/stamp/magistrate,
+/obj/item/paper_bin/nanotrasen,
/turf/simulated/floor/carpet,
/area/magistrateoffice)
"aCk" = (
@@ -21875,11 +21866,8 @@
/area/maintenance/fpmaint2)
"aMO" = (
/obj/structure/table/reinforced,
-/obj/item/paper_bin{
- pixel_x = -3;
- pixel_y = 7
- },
/obj/item/pen,
+/obj/item/paper_bin/nanotrasen,
/turf/simulated/floor/plasteel{
tag = "icon-cult";
icon_state = "cult";
@@ -27795,16 +27783,13 @@
/obj/item/folder/yellow,
/obj/item/stamp/ce,
/obj/item/book/manual/sop_engineering,
-/obj/item/paper_bin{
- pixel_x = -3;
- pixel_y = 7
- },
/obj/item/storage/fancy/cigarettes,
/obj/item/lighter/zippo,
/obj/item/pen/multi,
/obj/item/enginepicker{
layer = 3.1
},
+/obj/item/paper_bin/nanotrasen,
/turf/simulated/floor/plasteel{
dir = 8;
icon_state = "neutralfull"
@@ -27893,7 +27878,6 @@
/area/chapel/main)
"aYA" = (
/obj/structure/table,
-/obj/item/lighter/zippo/black,
/turf/simulated/floor/plasteel{
icon_state = "vault";
dir = 5
@@ -29916,6 +29900,7 @@
network = list("SS13")
},
/obj/structure/table/wood,
+/obj/item/lighter/zippo/black,
/turf/simulated/floor/carpet/black,
/area/chapel/office)
"bcx" = (
@@ -43355,12 +43340,9 @@
},
/area/hallway/primary/central/west)
"bCG" = (
-/obj/item/paper_bin{
- pixel_x = -3;
- pixel_y = 7
- },
/obj/item/pen,
/obj/structure/table/wood,
+/obj/item/paper_bin/nanotrasen,
/turf/simulated/floor/carpet,
/area/bridge/meeting_room)
"bCH" = (
@@ -47113,10 +47095,6 @@
/area/shuttle/constructionsite)
"bJN" = (
/obj/structure/table/wood,
-/obj/item/paper_bin{
- pixel_x = -3;
- pixel_y = 10
- },
/obj/item/pen/multi/fountain,
/obj/machinery/door_control{
id = "captainofficedoor";
@@ -47129,6 +47107,7 @@
/obj/item/radio/intercom{
pixel_x = -28
},
+/obj/item/paper_bin/nanotrasen,
/turf/simulated/floor/wood,
/area/crew_quarters/captain)
"bJO" = (
@@ -50576,15 +50555,12 @@
},
/area/toxins/lab)
"bPE" = (
-/obj/item/paper_bin{
- pixel_x = 1;
- pixel_y = 9
- },
/obj/structure/table/glass,
/obj/item/pen/multi,
/obj/item/book/manual/sop_science{
pixel_y = -14
},
+/obj/item/paper_bin/nanotrasen,
/turf/simulated/floor/plasteel{
dir = 2;
icon_state = "cafeteria";
@@ -54151,10 +54127,6 @@
/area/hallway/primary/central/se)
"bVy" = (
/obj/structure/table,
-/obj/item/paper_bin{
- pixel_x = -3;
- pixel_y = 7
- },
/obj/item/pen/multi,
/obj/item/pen/multi,
/obj/item/megaphone,
@@ -55112,6 +55084,7 @@
/obj/item/book/manual/sop_service,
/obj/item/book/manual/sop_supply,
/obj/item/book/manual/sop_command,
+/obj/item/paper_bin/nanotrasen,
/turf/simulated/floor/plasteel,
/area/crew_quarters/heads)
"bXa" = (
@@ -60880,7 +60853,6 @@
/area/medical/cmo)
"cfW" = (
/obj/structure/table/glass,
-/obj/item/paper_bin,
/obj/item/pen/multi,
/obj/item/folder/white{
pixel_y = 7
@@ -60890,6 +60862,7 @@
pixel_x = 32;
pixel_y = 0
},
+/obj/item/paper_bin/nanotrasen,
/turf/simulated/floor/plasteel{
dir = 4;
icon_state = "darkblue"
@@ -67468,12 +67441,12 @@
/area/blueshield)
"cqS" = (
/obj/structure/table/wood,
-/obj/item/paper_bin,
/obj/item/flashlight/lamp/green{
pixel_x = -5;
pixel_y = 12
},
/obj/item/paper/ntrep,
+/obj/item/paper_bin/nanotrasen,
/turf/simulated/floor/carpet,
/area/ntrep)
"cqT" = (
diff --git a/_maps/map_files/cyberiad/z2.dmm b/_maps/map_files/cyberiad/z2.dmm
index 684365ada39..a4baee09320 100644
--- a/_maps/map_files/cyberiad/z2.dmm
+++ b/_maps/map_files/cyberiad/z2.dmm
@@ -2060,7 +2060,16 @@
icon_opened = "cabinet_open";
icon_state = "cabinet_closed"
},
+/obj/item/clothing/under/color/lightpurple,
+/obj/item/clothing/under/color/purple,
/obj/item/storage/backpack/satchel,
+/obj/item/storage/backpack/satchel,
+/obj/item/clothing/head/wizard/red,
+/obj/item/clothing/suit/wizrobe/red,
+/obj/item/clothing/head/wizard,
+/obj/item/clothing/suit/wizrobe,
+/obj/item/clothing/shoes/sandal,
+/obj/item/clothing/shoes/sandal,
/turf/unsimulated/floor{
dir = 9;
icon_state = "carpetside"
@@ -2148,8 +2157,6 @@
/area/wizard_station)
"fC" = (
/obj/structure/table/wood,
-/obj/item/trash/tray,
-/obj/item/paper/spells,
/turf/unsimulated/floor{
dir = 10;
icon_state = "carpetside"
@@ -3248,10 +3255,10 @@
/area/shuttle/assault_pod)
"iw" = (
/obj/structure/rack,
+/obj/item/clothing/under/plasmaman/wizard,
+/obj/item/clothing/head/helmet/space/plasmaman/wizard,
/obj/item/clothing/mask/breath,
-/obj/item/clothing/mask/breath/vox,
-/obj/item/tank/plasma/plasmaman,
-/obj/item/tank/emergency_oxygen/vox,
+/obj/item/tank/plasma/plasmaman/belt/full,
/turf/unsimulated/floor{
icon_state = "grimy"
},
@@ -3895,10 +3902,8 @@
/area/centcom/gamma)
"ke" = (
/obj/structure/rack,
-/obj/item/clothing/suit/wizrobe/red,
-/obj/item/clothing/shoes/sandal,
-/obj/item/clothing/head/wizard/red,
-/obj/item/twohanded/staff,
+/obj/item/tank/emergency_oxygen/vox,
+/obj/item/clothing/mask/breath/vox,
/turf/unsimulated/floor{
icon_state = "grimy"
},
@@ -5006,6 +5011,20 @@
name = "grass"
},
/area/centcom/control)
+"nc" = (
+/obj/machinery/door/airlock/centcom{
+ name = "Gamma Armory";
+ opacity = 1;
+ req_access_txt = "114"
+ },
+/obj/machinery/door/poddoor/impassable{
+ id_tag = "CCGAMMA";
+ name = "Gamma Security"
+ },
+/turf/simulated/floor/plasteel{
+ icon_state = "dark"
+ },
+/area/centcom/gamma)
"nd" = (
/obj/structure/flora/ausbushes/lavendergrass,
/turf/unsimulated/floor{
@@ -5381,7 +5400,7 @@
},
/area/syndicate_mothership)
"nQ" = (
-/obj/machinery/door/poddoor{
+/obj/machinery/door/poddoor/impassable{
id_tag = "GRAVPULTS";
name = "Gravity Catapults"
},
@@ -5391,7 +5410,7 @@
},
/area/centcom/specops)
"nR" = (
-/obj/machinery/door/poddoor{
+/obj/machinery/door/poddoor/impassable{
id_tag = "GRAVPULTS";
name = "Gravity Catapults"
},
@@ -5408,7 +5427,7 @@
},
/area/syndicate_mothership)
"nT" = (
-/obj/machinery/door/poddoor{
+/obj/machinery/door/poddoor/impassable{
id_tag = "ASSAULT";
name = "Assault Armor"
},
@@ -5854,7 +5873,7 @@
},
/area/centcom/gamma)
"oR" = (
-/obj/machinery/door/poddoor{
+/obj/machinery/door/poddoor/impassable{
id_tag = "SPECOPS";
name = "Ready Room"
},
@@ -5979,7 +5998,7 @@
opacity = 1;
req_access_txt = "114"
},
-/obj/machinery/door/poddoor{
+/obj/machinery/door/poddoor/impassable{
id_tag = "specopsoffice";
name = "Super Privacy Shutters"
},
@@ -6118,7 +6137,7 @@
/turf/simulated/floor/mech_bay_recharge_floor,
/area/shuttle/gamma/space)
"pv" = (
-/obj/machinery/door/poddoor{
+/obj/machinery/door/poddoor/impassable{
id_tag = "CCTELE";
name = "Specops Teleporter"
},
@@ -6365,7 +6384,7 @@
/area/centcom/specops)
"pX" = (
/obj/machinery/door_control{
- desc = "A remote control switch to block view of the singularity.";
+ desc = "A remote control switch to connect the ready room to the rest of Centcom.";
icon_state = "doorctrl0";
id = "SPECOPS";
name = "Ready Room";
@@ -29642,7 +29661,7 @@ fm
fm
md
md
-oO
+nc
fm
pv
sX
diff --git a/_maps/map_files/cyberiad/z6.dmm b/_maps/map_files/cyberiad/z6.dmm
index b2171008b2b..6cbb87b6f80 100644
--- a/_maps/map_files/cyberiad/z6.dmm
+++ b/_maps/map_files/cyberiad/z6.dmm
@@ -761,7 +761,7 @@
/area/derelict/bridge)
"bK" = (
/obj/machinery/vending/cigarette/free{
- product_slogans = "Just remember! No capitalist.;Best enjoyed with Vodka!.;Smoke!;Nine out of ten USSP scientists agree, smoking reduces stress!;There's no cigarette like a Russian cigarette!;Cigarettes! Now with 100% less capitalism."
+ slogan_list = list("Just remember! No capitalist.","Best enjoyed with Vodka!.","Smoke!","Nine out of ten USSP scientists agree, smoking reduces stress!","There's no cigarette like a Russian cigarette!","Cigarettes! Now with 100% less capitalism.")
},
/turf/simulated/floor/plasteel{
dir = 9;
@@ -1441,7 +1441,7 @@
pixel_y = 32
},
/obj/machinery/vending/cigarette/free{
- product_slogans = "Just remember! No capitalist.;Best enjoyed with Vodka!.;Smoke!;Nine out of ten USSP scientists agree, smoking reduces stress!;There's no cigarette like a Russian cigarette!;Cigarettes! Now with 100% less capitalism."
+ slogan_list = list("Just remember! No capitalist.","Best enjoyed with Vodka!.","Smoke!","Nine out of ten USSP scientists agree, smoking reduces stress!","There's no cigarette like a Russian cigarette!","Cigarettes! Now with 100% less capitalism.")
},
/obj/effect/decal/cleanable/dirt,
/turf/simulated/floor/plasteel{
@@ -4163,7 +4163,7 @@
name = "suspicious button"
},
/obj/machinery/vending/cigarette/free{
- product_slogans = "Just remember! No capitalist.;Best enjoyed with Vodka!.;Smoke!;Nine out of ten USSP scientists agree, smoking reduces stress!;There's no cigarette like a Russian cigarette!;Cigarettes! Now with 100% less capitalism."
+ slogan_list = list("Just remember! No capitalist.","Best enjoyed with Vodka!.","Smoke!","Nine out of ten USSP scientists agree, smoking reduces stress!","There's no cigarette like a Russian cigarette!","Cigarettes! Now with 100% less capitalism.")
},
/turf/simulated/floor/wood{
broken = 1;
@@ -5186,7 +5186,7 @@
"kW" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/vending/cigarette/free{
- product_slogans = "Just remember! No capitalist.;Best enjoyed with Vodka!.;Smoke!;Nine out of ten USSP scientists agree, smoking reduces stress!;There's no cigarette like a Russian cigarette!;Cigarettes! Now with 100% less capitalism."
+ slogan_list = list("Just remember! No capitalist.","Best enjoyed with Vodka!.","Smoke!","Nine out of ten USSP scientists agree, smoking reduces stress!","There's no cigarette like a Russian cigarette!","Cigarettes! Now with 100% less capitalism.")
},
/turf/simulated/floor/plasteel{
dir = 5;
@@ -5598,7 +5598,7 @@
},
/area/syndicate_depot/outer)
"lZ" = (
-/obj/item/reagent_containers/food/snacks/spiderleg,
+/obj/item/reagent_containers/food/snacks/monstermeat/spiderleg,
/obj/structure/spider,
/turf/simulated/floor/plasteel{
icon_state = "dark"
@@ -6363,7 +6363,7 @@
icon_state = "sink";
pixel_x = 12
},
-/turf/simulated/floor/mineral/plasma,
+/turf/simulated/floor/mineral/silver,
/area/syndicate_depot/core)
"of" = (
/obj/structure/closet/secure_closet/syndicate/depot,
@@ -6448,26 +6448,9 @@
icon_state = "wood"
},
/area/derelict/crew_quarters)
-"oo" = (
-/obj/effect/spawner/random_spawners/syndicate/layout/door/secret,
-/turf/simulated/floor/plasteel{
- icon_state = "dark"
- },
-/area/syndicate_depot/core)
"op" = (
/turf/simulated/floor/mineral/silver,
/area/syndicate_depot/core)
-"oq" = (
-/obj/machinery/door/airlock/plasma{
- welded = 1
- },
-/turf/simulated/floor/plasteel{
- icon_state = "dark"
- },
-/area/syndicate_depot/core)
-"or" = (
-/turf/simulated/floor/mineral/plasma,
-/area/syndicate_depot/core)
"os" = (
/obj/structure/table,
/obj/effect/spawner/random_spawners/syndicate/loot/stetchkin,
@@ -6543,7 +6526,7 @@
/area/syndicate_depot/core)
"oB" = (
/obj/effect/spawner/random_spawners/syndicate/mob,
-/turf/simulated/floor/mineral/plasma,
+/turf/simulated/floor/mineral/silver,
/area/syndicate_depot/core)
"oC" = (
/obj/effect/landmark{
@@ -6706,27 +6689,14 @@
icon_state = "dark"
},
/area/syndicate_depot/core)
-"oZ" = (
-/obj/structure/mirror{
- pixel_x = -32
- },
-/turf/simulated/floor/mineral/plasma,
-/area/syndicate_depot/core)
"pa" = (
/obj/structure/toilet{
dir = 8
},
/turf/simulated/floor/mineral/silver,
/area/syndicate_depot/core)
-"pb" = (
-/obj/machinery/portable_atmospherics/canister/toxins,
-/turf/simulated/floor/plasteel{
- icon_state = "dark"
- },
-/area/syndicate_depot/core)
"pc" = (
/obj/machinery/light,
-/obj/effect/spawner/random_spawners/syndicate/loot/level3,
/turf/simulated/floor/plasteel{
icon_state = "dark"
},
@@ -9114,7 +9084,7 @@
})
"tY" = (
/obj/machinery/vending/cigarette/free{
- product_slogans = "Just remember! No capitalist.;Best enjoyed with Vodka!.;Smoke!;Nine out of ten USSP scientists agree, smoking reduces stress!;There's no cigarette like a Russian cigarette!;Cigarettes! Now with 100% less capitalism."
+ slogan_list = list("Just remember! No capitalist.","Best enjoyed with Vodka!.","Smoke!","Nine out of ten USSP scientists agree, smoking reduces stress!","There's no cigarette like a Russian cigarette!","Cigarettes! Now with 100% less capitalism.")
},
/turf/simulated/floor/plasteel{
icon_state = "bar"
@@ -10678,7 +10648,7 @@
/area/derelict/arrival)
"xe" = (
/obj/machinery/vending/cigarette/free{
- product_slogans = "Just remember! No capitalist.;Best enjoyed with Vodka!.;Smoke!;Nine out of ten USSP scientists agree, smoking reduces stress!;There's no cigarette like a Russian cigarette!;Cigarettes! Now with 100% less capitalism."
+ slogan_list = list("Just remember! No capitalist.","Best enjoyed with Vodka!.","Smoke!","Nine out of ten USSP scientists agree, smoking reduces stress!","There's no cigarette like a Russian cigarette!","Cigarettes! Now with 100% less capitalism.")
},
/turf/simulated/floor/plasteel{
dir = 2;
@@ -11582,10 +11552,10 @@
},
/area/space/nearstation)
"zR" = (
-/obj/machinery/portable_atmospherics/canister/toxins,
/obj/machinery/light/small{
dir = 1
},
+/obj/effect/decal/cleanable/blood,
/turf/simulated/floor/plasteel{
icon_state = "dark"
},
@@ -57707,7 +57677,7 @@ of
ot
mA
mA
-pb
+nX
pi
mA
py
@@ -59251,7 +59221,7 @@ oE
oR
oE
oz
-pb
+mA
mA
mA
mm
@@ -61558,7 +61528,7 @@ mm
mB
mm
mm
-oo
+mm
mm
lV
mA
@@ -61816,7 +61786,7 @@ mA
zP
mm
zR
-oo
+mm
oL
ns
mA
@@ -62072,7 +62042,7 @@ mA
mA
mt
mm
-oq
+mm
mm
mm
mm
@@ -62332,7 +62302,7 @@ mm
op
oB
oM
-oZ
+oM
ob
mA
pu
@@ -62586,7 +62556,7 @@ zP
mA
mA
ob
-or
+op
nJ
oe
pa
diff --git a/_maps/test_all_maps.dm b/_maps/test_all_maps.dm
deleted file mode 100644
index 94bd9bac437..00000000000
--- a/_maps/test_all_maps.dm
+++ /dev/null
@@ -1,145 +0,0 @@
-// 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\academy.dmm"
- #include "map_files\RandomZLevels\beach.dmm"
- #include "map_files\RandomZLevels\blackmarketpackers.dmm"
- #include "map_files\RandomZLevels\centcomAway.dmm"
- #include "map_files\RandomZLevels\evil_santa.dmm"
- #include "map_files\RandomZLevels\example.dmm"
- #include "map_files\RandomZLevels\moonoutpost19.dmm"
- #include "map_files\RandomZLevels\spacebattle.dmm"
- #include "map_files\RandomZLevels\spacehotel.dmm"
- #include "map_files\RandomZLevels\stationCollision.dmm"
- #include "map_files\RandomZLevels\terrorspiders.dmm"
- #include "map_files\RandomZLevels\undergroundoutpost45.dmm"
- #include "map_files\RandomZLevels\wildwest.dmm"
-
-
- // Lavaland Ruins
- #include "map_files\RandomRuins\LavaRuins\lavaland_biodome_beach.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_biodome_clown_planet.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_biodome_winter.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_surface_animal_hospital.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_surface_ash_walker1.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_surface_blooddrunk1.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_surface_blooddrunk2.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_surface_blooddrunk3.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_surface_cube.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_surface_cultaltar.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_surface_dead_ratvar.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_surface_envy.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_surface_fountain_hall.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_surface_gluttony.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_surface_greed.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_surface_hermit.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_surface_hierophant.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_surface_pizzaparty.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_surface_pride.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_surface_puzzle.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_surface_random_ripley.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_surface_seed_vault.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_surface_sloth.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_surface_survivalpod.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_surface_swarmer_crash.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_surface_syndicate_base1.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_surface_ufo_crash.dmm"
- #include "map_files\RandomRuins\LavaRuins\lavaland_surface_xeno_nest.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\oldstation.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"
-
- // 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/travis_map_testing.dm b/_maps/travis_map_testing.dm
new file mode 100644
index 00000000000..89fc4ec49ce
--- /dev/null
+++ b/_maps/travis_map_testing.dm
@@ -0,0 +1,157 @@
+// This is for Travis testing. DO NOT SET THIS AS THE GAME'S MAP NORMALLY!
+
+#if !defined(USING_MAP_DATUM)
+ // Cyberiad
+ #include "map_files/Cyberiad/cyberiad.dmm"
+ #include "map_files/Cyberiad/z2.dmm"
+ #include "map_files/Cyberiad/z3.dmm"
+ #include "map_files/Cyberiad/z4.dmm"
+ #include "map_files/Cyberiad/z6.dmm"
+
+ // Debug Maps
+ #include "map_files/Debug/singletile.dmm"
+ #include "map_files/Debug/smoothing.dmm"
+
+ // Delta
+ #include "map_files/Delta/delta.dmm"
+
+ // Generic Z Levels
+ #include "map_files/Generic/Lavaland.dmm"
+ #include "map_files/Generic/z6.dmm"
+ #include "map_files/Generic/z7.dmm"
+
+ // MetaStation
+ #include "map_files/MetaStation/MetaStation.v41A.II.dmm"
+ #include "map_files/MetaStation/z2.dmm"
+ #include "map_files/MetaStation/z3.dmm"
+ #include "map_files/MetaStation/z4.dmm"
+
+ // Lavaland Ruins
+ #include "map_files/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_biodome_winter.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_surface_animal_hospital.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk1.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk2.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk3.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_surface_cube.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_surface_dead_ratvar.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_surface_envy.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_surface_fountain_hall.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_surface_gluttony.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_surface_golem_ship.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_surface_greed.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_surface_hermit.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_surface_hierophant.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_surface_pizzaparty.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_surface_pride.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_surface_puzzle.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_surface_random_ripley.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_surface_sloth.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_surface_survivalpod.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_surface_swarmer_crash.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_surface_ufo_crash.dmm"
+ #include "map_files/RandomRuins/LavaRuins/lavaland_surface_xeno_nest.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/oldstation.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"
+ #include "map_files/RandomRuins/SpaceRuins/wizardcrash.dmm"
+
+ // Gateway Missions
+ #include "map_files/RandomZLevels/academy.dmm"
+ #include "map_files/RandomZLevels/beach.dmm"
+ #include "map_files/RandomZLevels/blackmarketpackers.dmm"
+ #include "map_files/RandomZLevels/centcomAway.dmm"
+ #include "map_files/RandomZLevels/evil_santa.dmm"
+ #include "map_files/RandomZLevels/example.dmm"
+ #include "map_files/RandomZLevels/moonoutpost19.dmm"
+ #include "map_files/RandomZLevels/spacebattle.dmm"
+ #include "map_files/RandomZLevels/spacehotel.dmm"
+ #include "map_files/RandomZLevels/stationCollision.dmm"
+ #include "map_files/RandomZLevels/terrorspiders.dmm"
+ #include "map_files/RandomZLevels/undergroundoutpost45.dmm"
+ #include "map_files/RandomZLevels/wildwest.dmm"
+
+ // Shuttles
+ #include "map_files/shuttles/admin_admin.dmm"
+ #include "map_files/shuttles/admin_hospital.dmm"
+ #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"
+
+ // Templates
+ #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"
+
+ // Spacehotel Rooms
+ #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"
+
+#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 157b0312995..507142c0892 100644
--- a/code/ATMOSPHERICS/atmospherics.dm
+++ b/code/ATMOSPHERICS/atmospherics.dm
@@ -1,345 +1,345 @@
-/*
-Quick overview:
-
-Pipes combine to form pipelines
-Pipelines and other atmospheric objects combine to form pipe_networks
- Note: A single pipe_network represents a completely open space
-
-Pipes -> Pipelines
-Pipelines + Other Objects -> Pipe network
-*/
-GLOBAL_DATUM_INIT(pipe_icon_manager, /datum/pipe_icon_manager, new())
-/obj/machinery/atmospherics
- anchored = 1
- layer = GAS_PIPE_HIDDEN_LAYER //under wires
- resistance_flags = FIRE_PROOF
- max_integrity = 200
- plane = FLOOR_PLANE
- idle_power_usage = 0
- active_power_usage = 0
- power_channel = ENVIRON
- on_blueprints = TRUE
- var/nodealert = 0
- var/can_unwrench = 0
-
- var/connect_types[] = list(1) //1=regular, 2=supply, 3=scrubber
- var/connected_to = 1 //same as above, currently not used for anything
- var/icon_connect_type = "" //"-supply" or "-scrubbers"
-
- var/initialize_directions = 0
-
- var/pipe_color
- var/obj/item/pipe/stored
- var/image/pipe_image
-
-/obj/machinery/atmospherics/New()
- if (!armor)
- armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 70)
- ..()
-
- if(!pipe_color)
- pipe_color = color
- color = null
-
- if(!pipe_color_check(pipe_color))
- pipe_color = null
-
-/obj/machinery/atmospherics/Initialize()
- . = ..()
- SSair.atmos_machinery += src
-
-/obj/machinery/atmospherics/proc/atmos_init()
- if(can_unwrench)
- stored = new(src, make_from = src)
-
-/obj/machinery/atmospherics/Destroy()
- QDEL_NULL(stored)
- SSair.atmos_machinery -= src
- SSair.deferred_pipenet_rebuilds -= src
- for(var/mob/living/L in src) //ventcrawling is serious business
- L.remove_ventcrawl()
- L.forceMove(get_turf(src))
- QDEL_NULL(pipe_image) //we have to del it, or it might keep a ref somewhere else
- return ..()
-
-// Icons/overlays/underlays
-/obj/machinery/atmospherics/update_icon()
- var/turf/T = get_turf(loc)
- if(!T || level == 2 || !T.intact)
- plane = GAME_PLANE
- else
- plane = FLOOR_PLANE
-
-/obj/machinery/atmospherics/proc/update_pipe_image()
- pipe_image = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir) //the 20 puts it above Byond's darkness (not its opacity view)
- pipe_image.plane = HUD_PLANE
-
-/obj/machinery/atmospherics/proc/check_icon_cache(var/safety = 0)
- if(!istype(GLOB.pipe_icon_manager))
- if(!safety) //to prevent infinite loops
- GLOB.pipe_icon_manager = new()
- check_icon_cache(1)
- return 0
-
- return 1
-
-/obj/machinery/atmospherics/proc/color_cache_name(var/obj/machinery/atmospherics/node)
- //Don't use this for standard pipes
- if(!istype(node))
- return null
-
- return node.pipe_color
-
-/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 += 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 += 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 += 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())
- return 1
- else
- return 0
-
-// Connect types
-/obj/machinery/atmospherics/proc/check_connect_types(obj/machinery/atmospherics/atmos1, obj/machinery/atmospherics/atmos2)
- var/i
- var/list1[] = atmos1.connect_types
- var/list2[] = atmos2.connect_types
- for(i=1,i<=list1.len,i++)
- var/j
- for(j=1,j<=list2.len,j++)
- if(list1[i] == list2[j])
- var/n = list1[i]
- return n
- return 0
-
-/obj/machinery/atmospherics/proc/check_connect_types_construction(obj/machinery/atmospherics/atmos1, obj/item/pipe/pipe2)
- var/i
- var/list1[] = atmos1.connect_types
- var/list2[] = pipe2.connect_types
- for(i=1,i<=list1.len,i++)
- var/j
- for(j=1,j<=list2.len,j++)
- if(list1[i] == list2[j])
- var/n = list1[i]
- return n
- return 0
-
-// Pipenet related functions
-/obj/machinery/atmospherics/proc/returnPipenet()
- return
-
-/obj/machinery/atmospherics/proc/returnPipenetAir()
- return
-
-/obj/machinery/atmospherics/proc/setPipenet()
- return
-
-/obj/machinery/atmospherics/proc/replacePipenet()
- return
-
-/obj/machinery/atmospherics/proc/build_network(remove_deferral = FALSE)
- // Called to build a network from this node
- if(remove_deferral)
- SSair.deferred_pipenet_rebuilds -= src
-
-/obj/machinery/atmospherics/proc/defer_build_network()
- SSair.deferred_pipenet_rebuilds += src
-
-/obj/machinery/atmospherics/proc/disconnect(obj/machinery/atmospherics/reference)
- return
-
-/obj/machinery/atmospherics/proc/nullifyPipenet(datum/pipeline/P)
- if(P)
- P.other_atmosmch -= src
-
-//(De)construction
-/obj/machinery/atmospherics/attackby(obj/item/W, mob/user)
- if(can_unwrench && istype(W, /obj/item/wrench))
- var/turf/T = get_turf(src)
- if(level == 1 && isturf(T) && T.intact)
- to_chat(user, "You must remove the plating first.")
- return 1
- var/datum/gas_mixture/int_air = return_air()
- var/datum/gas_mixture/env_air = loc.return_air()
- add_fingerprint(user)
-
- var/unsafe_wrenching = FALSE
- var/I = int_air ? int_air.return_pressure() : 0
- var/E = env_air ? env_air.return_pressure() : 0
- var/internal_pressure = I - E
-
- playsound(src.loc, W.usesound, 50, 1)
- to_chat(user, "You begin to unfasten \the [src]...")
- if(internal_pressure > 2*ONE_ATMOSPHERE)
- to_chat(user, "As you begin unwrenching \the [src] a gush of air blows in your face... maybe you should reconsider?")
- unsafe_wrenching = TRUE //Oh dear oh dear
-
- if(do_after(user, 40 * W.toolspeed, target = src) && !QDELETED(src))
- user.visible_message( \
- "[user] unfastens \the [src].", \
- "You have unfastened \the [src].", \
- "You hear ratchet.")
- investigate_log("was REMOVED by [key_name(usr)]", "atmos")
-
- //You unwrenched a pipe full of pressure? let's splat you into the wall silly.
- if(unsafe_wrenching)
- unsafe_pressure_release(user,internal_pressure)
- deconstruct(TRUE)
- else
- return ..()
-
-//Called when an atmospherics object is unwrenched while having a large pressure difference
-//with it's locs air contents.
-/obj/machinery/atmospherics/proc/unsafe_pressure_release(mob/user, pressures)
- if(!user)
- return
-
- if(!pressures)
- var/datum/gas_mixture/int_air = return_air()
- var/datum/gas_mixture/env_air = loc.return_air()
- pressures = int_air.return_pressure() - env_air.return_pressure()
-
- var/fuck_you_dir = get_dir(src, user)
- var/turf/general_direction = get_edge_target_turf(user, fuck_you_dir)
- user.visible_message("[user] is sent flying by pressure!","The pressure sends you flying!")
- //Values based on 2*ONE_ATMOS (the unsafe pressure), resulting in 20 range and 4 speed
- user.throw_at(general_direction, pressures/10, pressures/50)
-
-/obj/machinery/atmospherics/deconstruct(disassembled = TRUE)
- if(!(flags & NODECONSTRUCT))
- if(can_unwrench)
- if(stored)
- stored.forceMove(get_turf(src))
- if(!disassembled)
- stored.obj_integrity = stored.max_integrity * 0.5
- transfer_fingerprints_to(stored)
- stored = null
- ..()
-
-/obj/machinery/atmospherics/on_construction(D, P, C)
- if(C)
- color = C
- dir = D
- initialize_directions = P
- var/turf/T = loc
- level = T.intact ? 2 : 1
- add_fingerprint(usr)
- if(!SSair.initialized) //If there's no atmos subsystem, we can't really initialize pipenets
- SSair.machinery_to_construct.Add(src)
- return
- initialize_atmos_network()
-
-/obj/machinery/atmospherics/proc/initialize_atmos_network()
- atmos_init()
- var/list/nodes = pipeline_expansion()
- for(var/obj/machinery/atmospherics/A in nodes)
- A.atmos_init()
- A.addMember(src)
- build_network()
-
-// Find a connecting /obj/machinery/atmospherics in specified direction.
-/obj/machinery/atmospherics/proc/findConnecting(var/direction)
- for(var/obj/machinery/atmospherics/target in get_step(src,direction))
- var/can_connect = check_connect_types(target, src)
- if(can_connect && (target.initialize_directions & get_dir(target,src)))
- return target
-
-// Ventcrawling
-#define VENT_SOUND_DELAY 30
-/obj/machinery/atmospherics/relaymove(mob/living/user, direction)
- direction &= initialize_directions
- if(!direction || !(direction in cardinal)) //cant go this way.
- return
-
- if(user in buckled_mobs)// fixes buckle ventcrawl edgecase fuck bug
- return
-
- var/obj/machinery/atmospherics/target_move = findConnecting(direction)
- if(target_move)
- if(is_type_in_list(target_move, ventcrawl_machinery) && target_move.can_crawl_through())
- user.remove_ventcrawl()
- user.forceMove(target_move.loc) //handles entering and so on
- user.visible_message("You hear something squeezing through the ducts.", "You climb out the ventilation system.")
- else if(target_move.can_crawl_through())
- if(returnPipenet() != target_move.returnPipenet())
- user.update_pipe_vision(target_move)
- user.loc = target_move
- user.client.eye = target_move //if we don't do this, Byond only updates the eye every tick - required for smooth movement
- if(world.time - user.last_played_vent > VENT_SOUND_DELAY)
- user.last_played_vent = world.time
- playsound(src, 'sound/machines/ventcrawl.ogg', 50, 1, -3)
- else
- if((direction & initialize_directions) || is_type_in_list(src, ventcrawl_machinery)) //if we move in a way the pipe can connect, but doesn't - or we're in a vent
- user.remove_ventcrawl()
- user.forceMove(src.loc)
- user.visible_message("You hear something squeezing through the pipes.", "You climb out the ventilation system.")
- user.canmove = 0
- spawn(1)
- user.canmove = 1
-
-/obj/machinery/atmospherics/AltClick(var/mob/living/L)
- if(is_type_in_list(src, ventcrawl_machinery))
- L.handle_ventcrawl(src)
- return
- ..()
-
-/obj/machinery/atmospherics/proc/can_crawl_through()
- return 1
-
-/obj/machinery/atmospherics/proc/change_color(var/new_color)
- //only pass valid pipe colors please ~otherwise your pipe will turn invisible
- if(!pipe_color_check(new_color))
- return
-
- pipe_color = new_color
- update_icon()
-
-// Additional icon procs
-/obj/machinery/atmospherics/proc/universal_underlays(var/obj/machinery/atmospherics/node, var/direction)
- var/turf/T = get_turf(src)
- if(!istype(T)) return
- if(node)
- var/node_dir = get_dir(src,node)
- if(node.icon_connect_type == "-supply")
- add_underlay_adapter(T, , node_dir, "")
- add_underlay_adapter(T, node, node_dir, "-supply")
- add_underlay_adapter(T, , node_dir, "-scrubbers")
- else if(node.icon_connect_type == "-scrubbers")
- add_underlay_adapter(T, , node_dir, "")
- add_underlay_adapter(T, , node_dir, "-supply")
- add_underlay_adapter(T, node, node_dir, "-scrubbers")
- else
- add_underlay_adapter(T, node, node_dir, "")
- add_underlay_adapter(T, , node_dir, "-supply")
- add_underlay_adapter(T, , node_dir, "-scrubbers")
- else
- add_underlay_adapter(T, , direction, "-supply")
- add_underlay_adapter(T, , direction, "-scrubbers")
- add_underlay_adapter(T, , direction, "")
-
-/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 += GLOB.pipe_icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type)
- else
- underlays += GLOB.pipe_icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type)
- else
- 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)
- deconstruct(FALSE)
- return ..()
-
-/obj/machinery/atmospherics/update_remote_sight(mob/user)
- user.sight |= (SEE_TURFS|BLIND)
- . = ..()
+/*
+Quick overview:
+
+Pipes combine to form pipelines
+Pipelines and other atmospheric objects combine to form pipe_networks
+ Note: A single pipe_network represents a completely open space
+
+Pipes -> Pipelines
+Pipelines + Other Objects -> Pipe network
+*/
+GLOBAL_DATUM_INIT(pipe_icon_manager, /datum/pipe_icon_manager, new())
+/obj/machinery/atmospherics
+ anchored = 1
+ layer = GAS_PIPE_HIDDEN_LAYER //under wires
+ resistance_flags = FIRE_PROOF
+ max_integrity = 200
+ plane = FLOOR_PLANE
+ idle_power_usage = 0
+ active_power_usage = 0
+ power_channel = ENVIRON
+ on_blueprints = TRUE
+ var/nodealert = 0
+ var/can_unwrench = 0
+
+ var/connect_types[] = list(1) //1=regular, 2=supply, 3=scrubber
+ var/connected_to = 1 //same as above, currently not used for anything
+ var/icon_connect_type = "" //"-supply" or "-scrubbers"
+
+ var/initialize_directions = 0
+
+ var/pipe_color
+ var/obj/item/pipe/stored
+ var/image/pipe_image
+
+/obj/machinery/atmospherics/New()
+ if (!armor)
+ armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 70)
+ ..()
+
+ if(!pipe_color)
+ pipe_color = color
+ color = null
+
+ if(!pipe_color_check(pipe_color))
+ pipe_color = null
+
+/obj/machinery/atmospherics/Initialize()
+ . = ..()
+ SSair.atmos_machinery += src
+
+/obj/machinery/atmospherics/proc/atmos_init()
+ if(can_unwrench)
+ stored = new(src, make_from = src)
+
+/obj/machinery/atmospherics/Destroy()
+ QDEL_NULL(stored)
+ SSair.atmos_machinery -= src
+ SSair.deferred_pipenet_rebuilds -= src
+ for(var/mob/living/L in src) //ventcrawling is serious business
+ L.remove_ventcrawl()
+ L.forceMove(get_turf(src))
+ QDEL_NULL(pipe_image) //we have to del it, or it might keep a ref somewhere else
+ return ..()
+
+// Icons/overlays/underlays
+/obj/machinery/atmospherics/update_icon()
+ var/turf/T = get_turf(loc)
+ if(!T || level == 2 || !T.intact)
+ plane = GAME_PLANE
+ else
+ plane = FLOOR_PLANE
+
+/obj/machinery/atmospherics/proc/update_pipe_image()
+ pipe_image = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir) //the 20 puts it above Byond's darkness (not its opacity view)
+ pipe_image.plane = HUD_PLANE
+
+/obj/machinery/atmospherics/proc/check_icon_cache(var/safety = 0)
+ if(!istype(GLOB.pipe_icon_manager))
+ if(!safety) //to prevent infinite loops
+ GLOB.pipe_icon_manager = new()
+ check_icon_cache(1)
+ return 0
+
+ return 1
+
+/obj/machinery/atmospherics/proc/color_cache_name(var/obj/machinery/atmospherics/node)
+ //Don't use this for standard pipes
+ if(!istype(node))
+ return null
+
+ return node.pipe_color
+
+/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 += 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 += 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 += 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())
+ return 1
+ else
+ return 0
+
+// Connect types
+/obj/machinery/atmospherics/proc/check_connect_types(obj/machinery/atmospherics/atmos1, obj/machinery/atmospherics/atmos2)
+ var/i
+ var/list1[] = atmos1.connect_types
+ var/list2[] = atmos2.connect_types
+ for(i=1,i<=list1.len,i++)
+ var/j
+ for(j=1,j<=list2.len,j++)
+ if(list1[i] == list2[j])
+ var/n = list1[i]
+ return n
+ return 0
+
+/obj/machinery/atmospherics/proc/check_connect_types_construction(obj/machinery/atmospherics/atmos1, obj/item/pipe/pipe2)
+ var/i
+ var/list1[] = atmos1.connect_types
+ var/list2[] = pipe2.connect_types
+ for(i=1,i<=list1.len,i++)
+ var/j
+ for(j=1,j<=list2.len,j++)
+ if(list1[i] == list2[j])
+ var/n = list1[i]
+ return n
+ return 0
+
+// Pipenet related functions
+/obj/machinery/atmospherics/proc/returnPipenet()
+ return
+
+/obj/machinery/atmospherics/proc/returnPipenetAir()
+ return
+
+/obj/machinery/atmospherics/proc/setPipenet()
+ return
+
+/obj/machinery/atmospherics/proc/replacePipenet()
+ return
+
+/obj/machinery/atmospherics/proc/build_network(remove_deferral = FALSE)
+ // Called to build a network from this node
+ if(remove_deferral)
+ SSair.deferred_pipenet_rebuilds -= src
+
+/obj/machinery/atmospherics/proc/defer_build_network()
+ SSair.deferred_pipenet_rebuilds += src
+
+/obj/machinery/atmospherics/proc/disconnect(obj/machinery/atmospherics/reference)
+ return
+
+/obj/machinery/atmospherics/proc/nullifyPipenet(datum/pipeline/P)
+ if(P)
+ P.other_atmosmch -= src
+
+//(De)construction
+/obj/machinery/atmospherics/attackby(obj/item/W, mob/user)
+ if(can_unwrench && istype(W, /obj/item/wrench))
+ var/turf/T = get_turf(src)
+ if(level == 1 && isturf(T) && T.intact)
+ to_chat(user, "You must remove the plating first.")
+ return 1
+ var/datum/gas_mixture/int_air = return_air()
+ var/datum/gas_mixture/env_air = loc.return_air()
+ add_fingerprint(user)
+
+ var/unsafe_wrenching = FALSE
+ var/I = int_air ? int_air.return_pressure() : 0
+ var/E = env_air ? env_air.return_pressure() : 0
+ var/internal_pressure = I - E
+
+ playsound(src.loc, W.usesound, 50, 1)
+ to_chat(user, "You begin to unfasten \the [src]...")
+ if(internal_pressure > 2*ONE_ATMOSPHERE)
+ to_chat(user, "As you begin unwrenching \the [src] a gush of air blows in your face... maybe you should reconsider?")
+ unsafe_wrenching = TRUE //Oh dear oh dear
+
+ if(do_after(user, 40 * W.toolspeed, target = src) && !QDELETED(src))
+ user.visible_message( \
+ "[user] unfastens \the [src].", \
+ "You have unfastened \the [src].", \
+ "You hear ratchet.")
+ investigate_log("was REMOVED by [key_name(usr)]", "atmos")
+
+ //You unwrenched a pipe full of pressure? let's splat you into the wall silly.
+ if(unsafe_wrenching)
+ unsafe_pressure_release(user,internal_pressure)
+ deconstruct(TRUE)
+ else
+ return ..()
+
+//Called when an atmospherics object is unwrenched while having a large pressure difference
+//with it's locs air contents.
+/obj/machinery/atmospherics/proc/unsafe_pressure_release(mob/user, pressures)
+ if(!user)
+ return
+
+ if(!pressures)
+ var/datum/gas_mixture/int_air = return_air()
+ var/datum/gas_mixture/env_air = loc.return_air()
+ pressures = int_air.return_pressure() - env_air.return_pressure()
+
+ var/fuck_you_dir = get_dir(src, user)
+ var/turf/general_direction = get_edge_target_turf(user, fuck_you_dir)
+ user.visible_message("[user] is sent flying by pressure!","The pressure sends you flying!")
+ //Values based on 2*ONE_ATMOS (the unsafe pressure), resulting in 20 range and 4 speed
+ user.throw_at(general_direction, pressures/10, pressures/50)
+
+/obj/machinery/atmospherics/deconstruct(disassembled = TRUE)
+ if(!(flags & NODECONSTRUCT))
+ if(can_unwrench)
+ if(stored)
+ stored.forceMove(get_turf(src))
+ if(!disassembled)
+ stored.obj_integrity = stored.max_integrity * 0.5
+ transfer_fingerprints_to(stored)
+ stored = null
+ ..()
+
+/obj/machinery/atmospherics/on_construction(D, P, C)
+ if(C)
+ color = C
+ dir = D
+ initialize_directions = P
+ var/turf/T = loc
+ level = T.intact ? 2 : 1
+ add_fingerprint(usr)
+ if(!SSair.initialized) //If there's no atmos subsystem, we can't really initialize pipenets
+ SSair.machinery_to_construct.Add(src)
+ return
+ initialize_atmos_network()
+
+/obj/machinery/atmospherics/proc/initialize_atmos_network()
+ atmos_init()
+ var/list/nodes = pipeline_expansion()
+ for(var/obj/machinery/atmospherics/A in nodes)
+ A.atmos_init()
+ A.addMember(src)
+ build_network()
+
+// Find a connecting /obj/machinery/atmospherics in specified direction.
+/obj/machinery/atmospherics/proc/findConnecting(var/direction)
+ for(var/obj/machinery/atmospherics/target in get_step(src,direction))
+ var/can_connect = check_connect_types(target, src)
+ if(can_connect && (target.initialize_directions & get_dir(target,src)))
+ return target
+
+// Ventcrawling
+#define VENT_SOUND_DELAY 30
+/obj/machinery/atmospherics/relaymove(mob/living/user, direction)
+ direction &= initialize_directions
+ if(!direction || !(direction in GLOB.cardinal)) //cant go this way.
+ return
+
+ if(user in buckled_mobs)// fixes buckle ventcrawl edgecase fuck bug
+ return
+
+ var/obj/machinery/atmospherics/target_move = findConnecting(direction)
+ if(target_move)
+ if(is_type_in_list(target_move, GLOB.ventcrawl_machinery) && target_move.can_crawl_through())
+ user.remove_ventcrawl()
+ user.forceMove(target_move.loc) //handles entering and so on
+ user.visible_message("You hear something squeezing through the ducts.", "You climb out the ventilation system.")
+ else if(target_move.can_crawl_through())
+ if(returnPipenet() != target_move.returnPipenet())
+ user.update_pipe_vision(target_move)
+ user.loc = target_move
+ user.client.eye = target_move //if we don't do this, Byond only updates the eye every tick - required for smooth movement
+ if(world.time - user.last_played_vent > VENT_SOUND_DELAY)
+ user.last_played_vent = world.time
+ playsound(src, 'sound/machines/ventcrawl.ogg', 50, 1, -3)
+ else
+ if((direction & initialize_directions) || is_type_in_list(src, GLOB.ventcrawl_machinery)) //if we move in a way the pipe can connect, but doesn't - or we're in a vent
+ user.remove_ventcrawl()
+ user.forceMove(src.loc)
+ user.visible_message("You hear something squeezing through the pipes.", "You climb out the ventilation system.")
+ user.canmove = 0
+ spawn(1)
+ user.canmove = 1
+
+/obj/machinery/atmospherics/AltClick(var/mob/living/L)
+ if(is_type_in_list(src, GLOB.ventcrawl_machinery))
+ L.handle_ventcrawl(src)
+ return
+ ..()
+
+/obj/machinery/atmospherics/proc/can_crawl_through()
+ return 1
+
+/obj/machinery/atmospherics/proc/change_color(var/new_color)
+ //only pass valid pipe colors please ~otherwise your pipe will turn invisible
+ if(!pipe_color_check(new_color))
+ return
+
+ pipe_color = new_color
+ update_icon()
+
+// Additional icon procs
+/obj/machinery/atmospherics/proc/universal_underlays(var/obj/machinery/atmospherics/node, var/direction)
+ var/turf/T = get_turf(src)
+ if(!istype(T)) return
+ if(node)
+ var/node_dir = get_dir(src,node)
+ if(node.icon_connect_type == "-supply")
+ add_underlay_adapter(T, , node_dir, "")
+ add_underlay_adapter(T, node, node_dir, "-supply")
+ add_underlay_adapter(T, , node_dir, "-scrubbers")
+ else if(node.icon_connect_type == "-scrubbers")
+ add_underlay_adapter(T, , node_dir, "")
+ add_underlay_adapter(T, , node_dir, "-supply")
+ add_underlay_adapter(T, node, node_dir, "-scrubbers")
+ else
+ add_underlay_adapter(T, node, node_dir, "")
+ add_underlay_adapter(T, , node_dir, "-supply")
+ add_underlay_adapter(T, , node_dir, "-scrubbers")
+ else
+ add_underlay_adapter(T, , direction, "-supply")
+ add_underlay_adapter(T, , direction, "-scrubbers")
+ add_underlay_adapter(T, , direction, "")
+
+/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 += GLOB.pipe_icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type)
+ else
+ underlays += GLOB.pipe_icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type)
+ else
+ 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)
+ deconstruct(FALSE)
+ return ..()
+
+/obj/machinery/atmospherics/update_remote_sight(mob/user)
+ user.sight |= (SEE_TURFS|BLIND)
+ . = ..()
diff --git a/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm b/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm
index 68a1033a266..0a8b9eb95a4 100644
--- a/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm
@@ -1,155 +1,155 @@
-/obj/machinery/atmospherics/binary
- dir = SOUTH
- initialize_directions = SOUTH|NORTH
- use_power = IDLE_POWER_USE
-
- layer = GAS_PUMP_LAYER
-
- var/datum/gas_mixture/air1
- var/datum/gas_mixture/air2
-
- var/obj/machinery/atmospherics/node1
- var/obj/machinery/atmospherics/node2
-
- var/datum/pipeline/parent1
- var/datum/pipeline/parent2
-
-/obj/machinery/atmospherics/binary/New()
- ..()
- switch(dir)
- if(NORTH)
- initialize_directions = NORTH|SOUTH
- if(SOUTH)
- initialize_directions = NORTH|SOUTH
- if(EAST)
- initialize_directions = EAST|WEST
- if(WEST)
- initialize_directions = EAST|WEST
-
- air1 = new
- air2 = new
-
- air1.volume = 200
- air2.volume = 200
-
-/obj/machinery/atmospherics/binary/Destroy()
- if(node1)
- node1.disconnect(src)
- node1 = null
- nullifyPipenet(parent1)
- if(node2)
- node2.disconnect(src)
- node2 = null
- nullifyPipenet(parent2)
- return ..()
-
-/obj/machinery/atmospherics/binary/atmos_init()
- ..()
- var/node2_connect = dir
- var/node1_connect = turn(dir, 180)
-
- for(var/obj/machinery/atmospherics/target in get_step(src,node1_connect))
- if(target.initialize_directions & get_dir(target,src))
- var/c = check_connect_types(target,src)
- if(c)
- target.connected_to = c
- connected_to = c
- node1 = target
- break
-
- for(var/obj/machinery/atmospherics/target in get_step(src,node2_connect))
- if(target.initialize_directions & get_dir(target,src))
- var/c = check_connect_types(target,src)
- if(c)
- target.connected_to = c
- connected_to = c
- node2 = target
- break
-
- update_icon()
- update_underlays()
-
-/obj/machinery/atmospherics/binary/build_network(remove_deferral = FALSE)
- if(!parent1)
- parent1 = new /datum/pipeline()
- parent1.build_pipeline(src)
-
- if(!parent2)
- parent2 = new /datum/pipeline()
- parent2.build_pipeline(src)
- ..()
-
-/obj/machinery/atmospherics/binary/disconnect(obj/machinery/atmospherics/reference)
- if(reference == node1)
- if(istype(node1, /obj/machinery/atmospherics/pipe))
- qdel(parent1)
- node1 = null
- else if(reference == node2)
- if(istype(node2, /obj/machinery/atmospherics/pipe))
- qdel(parent2)
- node2 = null
- update_icon()
-
-/obj/machinery/atmospherics/binary/nullifyPipenet(datum/pipeline/P)
- ..()
- if(!P)
- return
- if(P == parent1)
- parent1.other_airs -= air1
- parent1 = null
- else if(P == parent2)
- parent2.other_airs -= air2
- parent2 = null
-
-/obj/machinery/atmospherics/binary/returnPipenetAir(datum/pipeline/P)
- if(P == parent1)
- return air1
- else if(P == parent2)
- return air2
-
-/obj/machinery/atmospherics/binary/pipeline_expansion(datum/pipeline/P)
- if(P)
- if(parent1 == P)
- return list(node1)
- else if(parent2 == P)
- return list(node2)
- else
- return list(node1, node2)
-
-/obj/machinery/atmospherics/binary/setPipenet(datum/pipeline/P, obj/machinery/atmospherics/A)
- if(A == node1)
- parent1 = P
- else if(A == node2)
- parent2 = P
-
-/obj/machinery/atmospherics/binary/returnPipenet(obj/machinery/atmospherics/A)
- if(A == node1)
- return parent1
- else if(A == node2)
- return parent2
-
-/obj/machinery/atmospherics/binary/replacePipenet(datum/pipeline/Old, datum/pipeline/New)
- if(Old == parent1)
- parent1 = New
- else if(Old == parent2)
- parent2 = New
-
-/obj/machinery/atmospherics/binary/unsafe_pressure_release(var/mob/user,var/pressures)
- ..()
-
- var/turf/T = get_turf(src)
- if(T)
- //Remove the gas from air1+air2 and assume it
- var/datum/gas_mixture/environment = T.return_air()
- var/lost = pressures*environment.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
- lost += pressures*environment.volume/(air2.temperature * R_IDEAL_GAS_EQUATION)
- var/shared_loss = lost/2
-
- var/datum/gas_mixture/to_release = air1.remove(shared_loss)
- to_release.merge(air2.remove(shared_loss))
- T.assume_air(to_release)
- air_update_turf(1)
-
-/obj/machinery/atmospherics/binary/process_atmos()
- ..()
- return parent1 && parent2
+/obj/machinery/atmospherics/binary
+ dir = SOUTH
+ initialize_directions = SOUTH|NORTH
+ use_power = IDLE_POWER_USE
+
+ layer = GAS_PUMP_LAYER
+
+ var/datum/gas_mixture/air1
+ var/datum/gas_mixture/air2
+
+ var/obj/machinery/atmospherics/node1
+ var/obj/machinery/atmospherics/node2
+
+ var/datum/pipeline/parent1
+ var/datum/pipeline/parent2
+
+/obj/machinery/atmospherics/binary/New()
+ ..()
+ switch(dir)
+ if(NORTH)
+ initialize_directions = NORTH|SOUTH
+ if(SOUTH)
+ initialize_directions = NORTH|SOUTH
+ if(EAST)
+ initialize_directions = EAST|WEST
+ if(WEST)
+ initialize_directions = EAST|WEST
+
+ air1 = new
+ air2 = new
+
+ air1.volume = 200
+ air2.volume = 200
+
+/obj/machinery/atmospherics/binary/Destroy()
+ if(node1)
+ node1.disconnect(src)
+ node1 = null
+ nullifyPipenet(parent1)
+ if(node2)
+ node2.disconnect(src)
+ node2 = null
+ nullifyPipenet(parent2)
+ return ..()
+
+/obj/machinery/atmospherics/binary/atmos_init()
+ ..()
+ var/node2_connect = dir
+ var/node1_connect = turn(dir, 180)
+
+ for(var/obj/machinery/atmospherics/target in get_step(src,node1_connect))
+ if(target.initialize_directions & get_dir(target,src))
+ var/c = check_connect_types(target,src)
+ if(c)
+ target.connected_to = c
+ connected_to = c
+ node1 = target
+ break
+
+ for(var/obj/machinery/atmospherics/target in get_step(src,node2_connect))
+ if(target.initialize_directions & get_dir(target,src))
+ var/c = check_connect_types(target,src)
+ if(c)
+ target.connected_to = c
+ connected_to = c
+ node2 = target
+ break
+
+ update_icon()
+ update_underlays()
+
+/obj/machinery/atmospherics/binary/build_network(remove_deferral = FALSE)
+ if(!parent1)
+ parent1 = new /datum/pipeline()
+ parent1.build_pipeline(src)
+
+ if(!parent2)
+ parent2 = new /datum/pipeline()
+ parent2.build_pipeline(src)
+ ..()
+
+/obj/machinery/atmospherics/binary/disconnect(obj/machinery/atmospherics/reference)
+ if(reference == node1)
+ if(istype(node1, /obj/machinery/atmospherics/pipe))
+ qdel(parent1)
+ node1 = null
+ else if(reference == node2)
+ if(istype(node2, /obj/machinery/atmospherics/pipe))
+ qdel(parent2)
+ node2 = null
+ update_icon()
+
+/obj/machinery/atmospherics/binary/nullifyPipenet(datum/pipeline/P)
+ ..()
+ if(!P)
+ return
+ if(P == parent1)
+ parent1.other_airs -= air1
+ parent1 = null
+ else if(P == parent2)
+ parent2.other_airs -= air2
+ parent2 = null
+
+/obj/machinery/atmospherics/binary/returnPipenetAir(datum/pipeline/P)
+ if(P == parent1)
+ return air1
+ else if(P == parent2)
+ return air2
+
+/obj/machinery/atmospherics/binary/pipeline_expansion(datum/pipeline/P)
+ if(P)
+ if(parent1 == P)
+ return list(node1)
+ else if(parent2 == P)
+ return list(node2)
+ else
+ return list(node1, node2)
+
+/obj/machinery/atmospherics/binary/setPipenet(datum/pipeline/P, obj/machinery/atmospherics/A)
+ if(A == node1)
+ parent1 = P
+ else if(A == node2)
+ parent2 = P
+
+/obj/machinery/atmospherics/binary/returnPipenet(obj/machinery/atmospherics/A)
+ if(A == node1)
+ return parent1
+ else if(A == node2)
+ return parent2
+
+/obj/machinery/atmospherics/binary/replacePipenet(datum/pipeline/Old, datum/pipeline/New)
+ if(Old == parent1)
+ parent1 = New
+ else if(Old == parent2)
+ parent2 = New
+
+/obj/machinery/atmospherics/binary/unsafe_pressure_release(var/mob/user,var/pressures)
+ ..()
+
+ var/turf/T = get_turf(src)
+ if(T)
+ //Remove the gas from air1+air2 and assume it
+ var/datum/gas_mixture/environment = T.return_air()
+ var/lost = pressures*environment.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
+ lost += pressures*environment.volume/(air2.temperature * R_IDEAL_GAS_EQUATION)
+ var/shared_loss = lost/2
+
+ var/datum/gas_mixture/to_release = air1.remove(shared_loss)
+ to_release.merge(air2.remove(shared_loss))
+ T.assume_air(to_release)
+ air_update_turf(1)
+
+/obj/machinery/atmospherics/binary/process_atmos()
+ ..()
+ return parent1 && parent2
diff --git a/code/ATMOSPHERICS/components/binary_devices/circulator.dm b/code/ATMOSPHERICS/components/binary_devices/circulator.dm
index 5574f97ea66..b45dd8929b4 100644
--- a/code/ATMOSPHERICS/components/binary_devices/circulator.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/circulator.dm
@@ -1,125 +1,125 @@
-//node1, air1, network1 correspond to input
-//node2, air2, network2 correspond to output
-/obj/machinery/atmospherics/binary/circulator
- name = "circulator/heat exchanger"
- desc = "A gas circulator pump and heat exchanger. Its input port is on the south side, and its output port is on the north side."
- icon = 'icons/obj/atmospherics/circulator.dmi'
- icon_state = "circ1-off"
-
- var/side = CIRC_LEFT
-
- var/global/const/CIRC_LEFT = WEST
- var/global/const/CIRC_RIGHT = EAST
-
- var/last_pressure_delta = 0
-
- var/obj/machinery/power/generator/generator
-
- anchored = 1
- density = 1
-
- can_unwrench = 1
- var/side_inverted = 0
-
-// Creating a custom circulator pipe subtype to be delivered through cargo
-/obj/item/pipe/circulator
- name = "circulator/heat exchanger fitting"
-
-/obj/item/pipe/circulator/New(loc)
- var/obj/machinery/atmospherics/binary/circulator/C = new /obj/machinery/atmospherics/binary/circulator(null)
- ..(loc, make_from = C)
-
-/obj/machinery/atmospherics/binary/circulator/Destroy()
- if(generator && generator.cold_circ == src)
- generator.cold_circ = null
- else if(generator && generator.hot_circ == src)
- generator.hot_circ = null
- return ..()
-
-/obj/machinery/atmospherics/binary/circulator/proc/return_transfer_air()
- var/datum/gas_mixture/inlet = get_inlet_air()
- var/datum/gas_mixture/outlet = get_outlet_air()
- var/output_starting_pressure = outlet.return_pressure()
- var/input_starting_pressure = inlet.return_pressure()
-
- if(output_starting_pressure >= input_starting_pressure - 10)
- //Need at least 10 KPa difference to overcome friction in the mechanism
- last_pressure_delta = 0
- return null
-
- //Calculate necessary moles to transfer using PV = nRT
- if(inlet.temperature > 0)
- var/pressure_delta = (input_starting_pressure - output_starting_pressure) / 2
-
- var/transfer_moles = pressure_delta * outlet.volume/(inlet.temperature * R_IDEAL_GAS_EQUATION)
-
- last_pressure_delta = pressure_delta
-
- //log_debug("pressure_delta = [pressure_delta]; transfer_moles = [transfer_moles];")
-
- //Actually transfer the gas
- var/datum/gas_mixture/removed = inlet.remove(transfer_moles)
-
- parent1.update = 1
- parent2.update = 1
-
- return removed
-
- else
- last_pressure_delta = 0
-
-/obj/machinery/atmospherics/binary/circulator/process_atmos()
- ..()
- update_icon()
-
-/obj/machinery/atmospherics/binary/circulator/proc/get_inlet_air()
- if(side_inverted==0)
- return air2
- else
- return air1
-
-/obj/machinery/atmospherics/binary/circulator/proc/get_outlet_air()
- if(side_inverted==0)
- return air1
- else
- return air2
-
-/obj/machinery/atmospherics/binary/circulator/proc/get_inlet_side()
- if(dir==SOUTH||dir==NORTH)
- if(side_inverted==0)
- return "South"
- else
- return "North"
-
-/obj/machinery/atmospherics/binary/circulator/proc/get_outlet_side()
- if(dir==SOUTH||dir==NORTH)
- if(side_inverted==0)
- return "North"
- else
- return "South"
-
-/obj/machinery/atmospherics/binary/circulator/multitool_act(mob/user, obj/item/I)
- . = TRUE
- if(!I.use_tool(src, user, 0, volume = I.tool_volume))
- return
- if(!side_inverted)
- side_inverted = TRUE
- else
- side_inverted = FALSE
- to_chat(user, "You reverse the circulator's valve settings. The inlet of the circulator is now on the [get_inlet_side(dir)] side.")
- desc = "A gas circulator pump and heat exchanger. Its input port is on the [get_inlet_side(dir)] side, and its output port is on the [get_outlet_side(dir)] side."
-
-/obj/machinery/atmospherics/binary/circulator/update_icon()
- ..()
-
- if(stat & (BROKEN|NOPOWER))
- icon_state = "circ[side]-p"
- else if(last_pressure_delta > 0)
- if(last_pressure_delta > ONE_ATMOSPHERE)
- icon_state = "circ[side]-run"
- else
- icon_state = "circ[side]-slow"
- else
- icon_state = "circ[side]-off"
-
- return 1
\ No newline at end of file
+//node1, air1, network1 correspond to input
+//node2, air2, network2 correspond to output
+#define CIRC_LEFT WEST
+#define CIRC_RIGHT EAST
+
+/obj/machinery/atmospherics/binary/circulator
+ name = "circulator/heat exchanger"
+ desc = "A gas circulator pump and heat exchanger. Its input port is on the south side, and its output port is on the north side."
+ icon = 'icons/obj/atmospherics/circulator.dmi'
+ icon_state = "circ1-off"
+
+ var/side = CIRC_LEFT
+
+ var/last_pressure_delta = 0
+
+ var/obj/machinery/power/generator/generator
+
+ anchored = 1
+ density = 1
+
+ can_unwrench = 1
+ var/side_inverted = 0
+
+// Creating a custom circulator pipe subtype to be delivered through cargo
+/obj/item/pipe/circulator
+ name = "circulator/heat exchanger fitting"
+
+/obj/item/pipe/circulator/New(loc)
+ var/obj/machinery/atmospherics/binary/circulator/C = new /obj/machinery/atmospherics/binary/circulator(null)
+ ..(loc, make_from = C)
+
+/obj/machinery/atmospherics/binary/circulator/Destroy()
+ if(generator && generator.cold_circ == src)
+ generator.cold_circ = null
+ else if(generator && generator.hot_circ == src)
+ generator.hot_circ = null
+ return ..()
+
+/obj/machinery/atmospherics/binary/circulator/proc/return_transfer_air()
+ var/datum/gas_mixture/inlet = get_inlet_air()
+ var/datum/gas_mixture/outlet = get_outlet_air()
+ var/output_starting_pressure = outlet.return_pressure()
+ var/input_starting_pressure = inlet.return_pressure()
+
+ if(output_starting_pressure >= input_starting_pressure - 10)
+ //Need at least 10 KPa difference to overcome friction in the mechanism
+ last_pressure_delta = 0
+ return null
+
+ //Calculate necessary moles to transfer using PV = nRT
+ if(inlet.temperature > 0)
+ var/pressure_delta = (input_starting_pressure - output_starting_pressure) / 2
+
+ var/transfer_moles = pressure_delta * outlet.volume/(inlet.temperature * R_IDEAL_GAS_EQUATION)
+
+ last_pressure_delta = pressure_delta
+
+ //log_debug("pressure_delta = [pressure_delta]; transfer_moles = [transfer_moles];")
+
+ //Actually transfer the gas
+ var/datum/gas_mixture/removed = inlet.remove(transfer_moles)
+
+ parent1.update = 1
+ parent2.update = 1
+
+ return removed
+
+ else
+ last_pressure_delta = 0
+
+/obj/machinery/atmospherics/binary/circulator/process_atmos()
+ ..()
+ update_icon()
+
+/obj/machinery/atmospherics/binary/circulator/proc/get_inlet_air()
+ if(side_inverted==0)
+ return air2
+ else
+ return air1
+
+/obj/machinery/atmospherics/binary/circulator/proc/get_outlet_air()
+ if(side_inverted==0)
+ return air1
+ else
+ return air2
+
+/obj/machinery/atmospherics/binary/circulator/proc/get_inlet_side()
+ if(dir==SOUTH||dir==NORTH)
+ if(side_inverted==0)
+ return "South"
+ else
+ return "North"
+
+/obj/machinery/atmospherics/binary/circulator/proc/get_outlet_side()
+ if(dir==SOUTH||dir==NORTH)
+ if(side_inverted==0)
+ return "North"
+ else
+ return "South"
+
+/obj/machinery/atmospherics/binary/circulator/multitool_act(mob/user, obj/item/I)
+ . = TRUE
+ if(!I.use_tool(src, user, 0, volume = I.tool_volume))
+ return
+ if(!side_inverted)
+ side_inverted = TRUE
+ else
+ side_inverted = FALSE
+ to_chat(user, "You reverse the circulator's valve settings. The inlet of the circulator is now on the [get_inlet_side(dir)] side.")
+ desc = "A gas circulator pump and heat exchanger. Its input port is on the [get_inlet_side(dir)] side, and its output port is on the [get_outlet_side(dir)] side."
+
+/obj/machinery/atmospherics/binary/circulator/update_icon()
+ ..()
+
+ if(stat & (BROKEN|NOPOWER))
+ icon_state = "circ[side]-p"
+ else if(last_pressure_delta > 0)
+ if(last_pressure_delta > ONE_ATMOSPHERE)
+ icon_state = "circ[side]-run"
+ else
+ icon_state = "circ[side]-slow"
+ else
+ icon_state = "circ[side]-off"
+
+ return 1
diff --git a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm
index b9902dbb066..c0ed34ef206 100644
--- a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm
@@ -1,269 +1,269 @@
-/obj/machinery/atmospherics/binary/dp_vent_pump
- icon = 'icons/atmos/vent_pump.dmi'
- icon_state = "map_dp_vent"
-
- //node2 is output port
- //node1 is input port
-
- req_one_access_txt = "24;10"
-
- name = "dual-port air vent"
- desc = "Has a valve and pump attached to it. There are two ports."
-
- can_unwrench = 1
-
- level = 1
-
- connect_types = list(1,2,3) //connects to regular, supply and scrubbers pipes
-
- var/on = 0
- var/pump_direction = 1 //0 = siphoning, 1 = releasing
-
- var/external_pressure_bound = ONE_ATMOSPHERE
- var/input_pressure_min = 0
- var/output_pressure_max = 0
-
- var/frequency = ATMOS_VENTSCRUB
- var/id_tag = null
- var/datum/radio_frequency/radio_connection
- var/advcontrol = 0//does this device listen to the AAC
-
- settagwhitelist = list("id_tag")
-
- var/pressure_checks = 1
- //1: Do not pass external_pressure_bound
- //2: Do not pass input_pressure_min
- //4: Do not pass output_pressure_max
-
-/obj/machinery/atmospherics/binary/dp_vent_pump/New()
- ..()
- if(!id_tag)
- assign_uid()
- id_tag = num2text(uid)
- icon = null
-
-/obj/machinery/atmospherics/binary/dp_vent_pump/Destroy()
- if(SSradio)
- SSradio.remove_object(src, frequency)
- radio_connection = null
- return ..()
-
-/obj/machinery/atmospherics/binary/dp_vent_pump/atmos_init()
- ..()
- if(frequency)
- set_frequency(frequency)
-
-/obj/machinery/atmospherics/binary/dp_vent_pump/high_volume
- name = "large dual port air vent"
-
-/obj/machinery/atmospherics/binary/dp_vent_pump/high_volume/on
- on = TRUE
-
-/obj/machinery/atmospherics/binary/dp_vent_pump/high_volume/New()
- ..()
- air1.volume = 1000
- air2.volume = 1000
-
-/obj/machinery/atmospherics/binary/volume_pump/update_underlays()
- if(..())
- underlays.Cut()
- var/turf/T = get_turf(src)
- if(!istype(T))
- return
- add_underlay(T, node1, turn(dir, -180))
- add_underlay(T, node2, dir)
-
-/obj/machinery/atmospherics/binary/dp_vent_pump/update_icon(var/safety = 0)
- ..()
-
- if(!check_icon_cache())
- return
-
- overlays.Cut()
-
- var/vent_icon = "vent"
-
- var/turf/T = get_turf(src)
- if(!istype(T))
- return
-
- if(T.intact && node1 && node2 && node1.level == 1 && node2.level == 1 && istype(node1, /obj/machinery/atmospherics/pipe) && istype(node2, /obj/machinery/atmospherics/pipe))
- vent_icon += "h"
-
- if(!powered())
- vent_icon += "off"
- else
- vent_icon += "[on ? "[pump_direction ? "out" : "in"]" : "off"]"
-
- overlays += GLOB.pipe_icon_manager.get_atmos_icon("device", , , vent_icon)
-
-/obj/machinery/atmospherics/binary/dp_vent_pump/update_underlays()
- if(..())
- underlays.Cut()
- var/turf/T = get_turf(src)
- if(!istype(T))
- return
- if(T.intact && node1 && node2 && node1.level == 1 && node2.level == 1 && istype(node1, /obj/machinery/atmospherics/pipe) && istype(node2, /obj/machinery/atmospherics/pipe))
- return
- else
- if(node1)
- add_underlay(T, node1, turn(dir, -180), node1.icon_connect_type)
- else
- add_underlay(T, node1, turn(dir, -180))
- if(node2)
- add_underlay(T, node2, dir, node2.icon_connect_type)
- else
- add_underlay(T, node2, dir)
-
-/obj/machinery/atmospherics/binary/dp_vent_pump/process_atmos()
- ..()
- if(!on)
- return 0
-
- var/datum/gas_mixture/environment = loc.return_air()
- var/environment_pressure = environment.return_pressure()
-
- if(pump_direction) //input -> external
- var/pressure_delta = 10000
-
- if(pressure_checks&1)
- pressure_delta = min(pressure_delta, (external_pressure_bound - environment_pressure))
- if(pressure_checks&2)
- pressure_delta = min(pressure_delta, (air1.return_pressure() - input_pressure_min))
-
- if(pressure_delta > 0)
- if(air1.temperature > 0)
- var/transfer_moles = pressure_delta*environment.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
-
- var/datum/gas_mixture/removed = air1.remove(transfer_moles)
-
- loc.assume_air(removed)
-
- parent1.update = 1
- air_update_turf()
- else //external -> output
- var/pressure_delta = 10000
-
- if(pressure_checks&1)
- pressure_delta = min(pressure_delta, (environment_pressure - external_pressure_bound))
- if(pressure_checks&4)
- pressure_delta = min(pressure_delta, (output_pressure_max - air2.return_pressure()))
-
- if(pressure_delta > 0)
- if(environment.temperature > 0)
- var/transfer_moles = pressure_delta*air2.volume/(environment.temperature * R_IDEAL_GAS_EQUATION)
-
- var/datum/gas_mixture/removed = loc.remove_air(transfer_moles)
-
- air2.merge(removed)
-
- parent2.update = 1
- air_update_turf()
- return 1
-
-//Radio remote control
-/obj/machinery/atmospherics/binary/dp_vent_pump/proc/set_frequency(new_frequency)
- SSradio.remove_object(src, frequency)
- frequency = new_frequency
- if(frequency)
- radio_connection = SSradio.add_object(src, frequency, filter = RADIO_ATMOSIA)
-
-/obj/machinery/atmospherics/binary/dp_vent_pump/proc/broadcast_status()
- if(!radio_connection)
- return 0
-
- var/datum/signal/signal = new
- signal.transmission_method = 1 //radio signal
- signal.source = src
-
- signal.data = list(
- "tag" = id_tag,
- "device" = "ADVP",
- "power" = on,
- "direction" = pump_direction?("release"):("siphon"),
- "checks" = pressure_checks,
- "input" = input_pressure_min,
- "output" = output_pressure_max,
- "external" = external_pressure_bound,
- "sigtype" = "status"
- )
- radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
-
- return 1
-
-/obj/machinery/atmospherics/binary/dp_vent_pump/receive_signal(datum/signal/signal)
- if(!signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command") || (signal.data["advcontrol"] && !advcontrol))
- return 0
- if(signal.data["power"] != null)
- on = text2num(signal.data["power"])
-
- if(signal.data["power_toggle"] != null)
- on = !on
-
- if(signal.data["direction"] != null)
- pump_direction = text2num(signal.data["direction"])
-
- if(signal.data["checks"] != null)
- pressure_checks = text2num(signal.data["checks"])
-
- if(signal.data["purge"])
- pressure_checks &= ~1
- pump_direction = 0
-
- if(signal.data["stabilize"])//the fact that this was "stabalize" shows how many fucks people give about these wonders, none
- pressure_checks |= 1
- pump_direction = 1
-
- if(signal.data["set_input_pressure"] != null)
- input_pressure_min = between(
- 0,
- text2num(signal.data["set_input_pressure"]),
- ONE_ATMOSPHERE*50
- )
-
- if(signal.data["set_output_pressure"] != null)
- output_pressure_max = between(
- 0,
- text2num(signal.data["set_output_pressure"]),
- ONE_ATMOSPHERE*50
- )
-
- if(signal.data["set_external_pressure"] != null)
- external_pressure_bound = between(
- 0,
- text2num(signal.data["set_external_pressure"]),
- ONE_ATMOSPHERE*50
- )
-
- if(signal.data["status"])
- spawn(2)
- broadcast_status()
- return //do not update_icon
-
- spawn(2)
- broadcast_status()
- update_icon()
-
-/obj/machinery/atmospherics/binary/dp_vent_pump/attackby(var/obj/item/W as obj, var/mob/user as mob)
- if(istype(W, /obj/item/multitool))
- update_multitool_menu(user)
- return 1
-
- return ..()
-
-/obj/machinery/atmospherics/binary/dp_vent_pump/multitool_menu(var/mob/user,var/obj/item/multitool/P)
- return {"
-
- "}
-
-/obj/machinery/atmospherics/binary/dp_vent_pump/multitool_topic(var/mob/user, var/list/href_list, var/obj/O)
- . = ..()
- if(.)
- return .
- if("toggleadvcontrol" in href_list)
- advcontrol = !advcontrol
- return TRUE
+/obj/machinery/atmospherics/binary/dp_vent_pump
+ icon = 'icons/atmos/vent_pump.dmi'
+ icon_state = "map_dp_vent"
+
+ //node2 is output port
+ //node1 is input port
+
+ req_one_access_txt = "24;10"
+
+ name = "dual-port air vent"
+ desc = "Has a valve and pump attached to it. There are two ports."
+
+ can_unwrench = 1
+
+ level = 1
+
+ connect_types = list(1,2,3) //connects to regular, supply and scrubbers pipes
+
+ var/on = 0
+ var/pump_direction = 1 //0 = siphoning, 1 = releasing
+
+ var/external_pressure_bound = ONE_ATMOSPHERE
+ var/input_pressure_min = 0
+ var/output_pressure_max = 0
+
+ var/frequency = ATMOS_VENTSCRUB
+ var/id_tag = null
+ var/datum/radio_frequency/radio_connection
+ var/advcontrol = 0//does this device listen to the AAC
+
+ settagwhitelist = list("id_tag")
+
+ var/pressure_checks = 1
+ //1: Do not pass external_pressure_bound
+ //2: Do not pass input_pressure_min
+ //4: Do not pass output_pressure_max
+
+/obj/machinery/atmospherics/binary/dp_vent_pump/New()
+ ..()
+ if(!id_tag)
+ assign_uid()
+ id_tag = num2text(uid)
+ icon = null
+
+/obj/machinery/atmospherics/binary/dp_vent_pump/Destroy()
+ if(SSradio)
+ SSradio.remove_object(src, frequency)
+ radio_connection = null
+ return ..()
+
+/obj/machinery/atmospherics/binary/dp_vent_pump/atmos_init()
+ ..()
+ if(frequency)
+ set_frequency(frequency)
+
+/obj/machinery/atmospherics/binary/dp_vent_pump/high_volume
+ name = "large dual port air vent"
+
+/obj/machinery/atmospherics/binary/dp_vent_pump/high_volume/on
+ on = TRUE
+
+/obj/machinery/atmospherics/binary/dp_vent_pump/high_volume/New()
+ ..()
+ air1.volume = 1000
+ air2.volume = 1000
+
+/obj/machinery/atmospherics/binary/volume_pump/update_underlays()
+ if(..())
+ underlays.Cut()
+ var/turf/T = get_turf(src)
+ if(!istype(T))
+ return
+ add_underlay(T, node1, turn(dir, -180))
+ add_underlay(T, node2, dir)
+
+/obj/machinery/atmospherics/binary/dp_vent_pump/update_icon(var/safety = 0)
+ ..()
+
+ if(!check_icon_cache())
+ return
+
+ overlays.Cut()
+
+ var/vent_icon = "vent"
+
+ var/turf/T = get_turf(src)
+ if(!istype(T))
+ return
+
+ if(T.intact && node1 && node2 && node1.level == 1 && node2.level == 1 && istype(node1, /obj/machinery/atmospherics/pipe) && istype(node2, /obj/machinery/atmospherics/pipe))
+ vent_icon += "h"
+
+ if(!powered())
+ vent_icon += "off"
+ else
+ vent_icon += "[on ? "[pump_direction ? "out" : "in"]" : "off"]"
+
+ overlays += GLOB.pipe_icon_manager.get_atmos_icon("device", , , vent_icon)
+
+/obj/machinery/atmospherics/binary/dp_vent_pump/update_underlays()
+ if(..())
+ underlays.Cut()
+ var/turf/T = get_turf(src)
+ if(!istype(T))
+ return
+ if(T.intact && node1 && node2 && node1.level == 1 && node2.level == 1 && istype(node1, /obj/machinery/atmospherics/pipe) && istype(node2, /obj/machinery/atmospherics/pipe))
+ return
+ else
+ if(node1)
+ add_underlay(T, node1, turn(dir, -180), node1.icon_connect_type)
+ else
+ add_underlay(T, node1, turn(dir, -180))
+ if(node2)
+ add_underlay(T, node2, dir, node2.icon_connect_type)
+ else
+ add_underlay(T, node2, dir)
+
+/obj/machinery/atmospherics/binary/dp_vent_pump/process_atmos()
+ ..()
+ if(!on)
+ return 0
+
+ var/datum/gas_mixture/environment = loc.return_air()
+ var/environment_pressure = environment.return_pressure()
+
+ if(pump_direction) //input -> external
+ var/pressure_delta = 10000
+
+ if(pressure_checks&1)
+ pressure_delta = min(pressure_delta, (external_pressure_bound - environment_pressure))
+ if(pressure_checks&2)
+ pressure_delta = min(pressure_delta, (air1.return_pressure() - input_pressure_min))
+
+ if(pressure_delta > 0)
+ if(air1.temperature > 0)
+ var/transfer_moles = pressure_delta*environment.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
+
+ var/datum/gas_mixture/removed = air1.remove(transfer_moles)
+
+ loc.assume_air(removed)
+
+ parent1.update = 1
+ air_update_turf()
+ else //external -> output
+ var/pressure_delta = 10000
+
+ if(pressure_checks&1)
+ pressure_delta = min(pressure_delta, (environment_pressure - external_pressure_bound))
+ if(pressure_checks&4)
+ pressure_delta = min(pressure_delta, (output_pressure_max - air2.return_pressure()))
+
+ if(pressure_delta > 0)
+ if(environment.temperature > 0)
+ var/transfer_moles = pressure_delta*air2.volume/(environment.temperature * R_IDEAL_GAS_EQUATION)
+
+ var/datum/gas_mixture/removed = loc.remove_air(transfer_moles)
+
+ air2.merge(removed)
+
+ parent2.update = 1
+ air_update_turf()
+ return 1
+
+//Radio remote control
+/obj/machinery/atmospherics/binary/dp_vent_pump/proc/set_frequency(new_frequency)
+ SSradio.remove_object(src, frequency)
+ frequency = new_frequency
+ if(frequency)
+ radio_connection = SSradio.add_object(src, frequency, filter = RADIO_ATMOSIA)
+
+/obj/machinery/atmospherics/binary/dp_vent_pump/proc/broadcast_status()
+ if(!radio_connection)
+ return 0
+
+ var/datum/signal/signal = new
+ signal.transmission_method = 1 //radio signal
+ signal.source = src
+
+ signal.data = list(
+ "tag" = id_tag,
+ "device" = "ADVP",
+ "power" = on,
+ "direction" = pump_direction?("release"):("siphon"),
+ "checks" = pressure_checks,
+ "input" = input_pressure_min,
+ "output" = output_pressure_max,
+ "external" = external_pressure_bound,
+ "sigtype" = "status"
+ )
+ radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
+
+ return 1
+
+/obj/machinery/atmospherics/binary/dp_vent_pump/receive_signal(datum/signal/signal)
+ if(!signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command") || (signal.data["advcontrol"] && !advcontrol))
+ return 0
+ if(signal.data["power"] != null)
+ on = text2num(signal.data["power"])
+
+ if(signal.data["power_toggle"] != null)
+ on = !on
+
+ if(signal.data["direction"] != null)
+ pump_direction = text2num(signal.data["direction"])
+
+ if(signal.data["checks"] != null)
+ pressure_checks = text2num(signal.data["checks"])
+
+ if(signal.data["purge"])
+ pressure_checks &= ~1
+ pump_direction = 0
+
+ if(signal.data["stabilize"])//the fact that this was "stabalize" shows how many fucks people give about these wonders, none
+ pressure_checks |= 1
+ pump_direction = 1
+
+ if(signal.data["set_input_pressure"] != null)
+ input_pressure_min = between(
+ 0,
+ text2num(signal.data["set_input_pressure"]),
+ ONE_ATMOSPHERE*50
+ )
+
+ if(signal.data["set_output_pressure"] != null)
+ output_pressure_max = between(
+ 0,
+ text2num(signal.data["set_output_pressure"]),
+ ONE_ATMOSPHERE*50
+ )
+
+ if(signal.data["set_external_pressure"] != null)
+ external_pressure_bound = between(
+ 0,
+ text2num(signal.data["set_external_pressure"]),
+ ONE_ATMOSPHERE*50
+ )
+
+ if(signal.data["status"])
+ spawn(2)
+ broadcast_status()
+ return //do not update_icon
+
+ spawn(2)
+ broadcast_status()
+ update_icon()
+
+/obj/machinery/atmospherics/binary/dp_vent_pump/attackby(var/obj/item/W as obj, var/mob/user as mob)
+ if(istype(W, /obj/item/multitool))
+ update_multitool_menu(user)
+ return 1
+
+ return ..()
+
+/obj/machinery/atmospherics/binary/dp_vent_pump/multitool_menu(var/mob/user,var/obj/item/multitool/P)
+ return {"
+
+ "}
+
+/obj/machinery/atmospherics/binary/dp_vent_pump/multitool_topic(var/mob/user, var/list/href_list, var/obj/O)
+ . = ..()
+ if(.)
+ return .
+ if("toggleadvcontrol" in href_list)
+ advcontrol = !advcontrol
+ return TRUE
diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm
index 3448655c953..87c7c6426c1 100644
--- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm
@@ -1,192 +1,192 @@
-/obj/machinery/atmospherics/binary/passive_gate
- //Tries to achieve target pressure at output (like a normal pump) except
- // Uses no power but can not transfer gases from a low pressure area to a high pressure area
- icon = 'icons/atmos/passive_gate.dmi'
- icon_state = "map"
-
- name = "passive gate"
- desc = "A one-way air valve that does not require power"
-
- can_unwrench = 1
-
- var/on = 0
- var/target_pressure = ONE_ATMOSPHERE
-
- var/frequency = 0
- var/id = null
- var/datum/radio_frequency/radio_connection
-
-/obj/machinery/atmospherics/binary/passive_gate/atmos_init()
- ..()
- if(frequency)
- set_frequency(frequency)
-
-/obj/machinery/atmospherics/binary/passive_gate/Destroy()
- if(SSradio)
- SSradio.remove_object(src, frequency)
- radio_connection = null
- return ..()
-
-/obj/machinery/atmospherics/binary/passive_gate/update_icon()
- ..()
- icon_state = "[on ? "on" : "off"]"
-
-/obj/machinery/atmospherics/binary/passive_gate/update_underlays()
- if(..())
- underlays.Cut()
- var/turf/T = get_turf(src)
- if(!istype(T))
- return
- add_underlay(T, node1, turn(dir, 180))
- add_underlay(T, node2, dir)
-
-/obj/machinery/atmospherics/binary/passive_gate/process_atmos()
- ..()
- if(!on)
- return 0
-
- var/output_starting_pressure = air2.return_pressure()
- var/input_starting_pressure = air1.return_pressure()
-
- if(output_starting_pressure >= min(target_pressure,input_starting_pressure-10))
- //No need to pump gas if target is already reached or input pressure is too low
- //Need at least 10 KPa difference to overcome friction in the mechanism
- return 1
-
- //Calculate necessary moles to transfer using PV = nRT
- if((air1.total_moles() > 0) && (air1.temperature>0))
- var/pressure_delta = min(target_pressure - output_starting_pressure, (input_starting_pressure - output_starting_pressure)/2)
- //Can not have a pressure delta that would cause output_pressure > input_pressure
-
- var/transfer_moles = pressure_delta*air2.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
-
- //Actually transfer the gas
- var/datum/gas_mixture/removed = air1.remove(transfer_moles)
- air2.merge(removed)
-
- parent1.update = 1
-
- parent2.update = 1
- return 1
-
-//Radio remote control
-/obj/machinery/atmospherics/binary/passive_gate/proc/set_frequency(new_frequency)
- SSradio.remove_object(src, frequency)
- frequency = new_frequency
- if(frequency)
- radio_connection = SSradio.add_object(src, frequency, filter = RADIO_ATMOSIA)
-
-/obj/machinery/atmospherics/binary/passive_gate/proc/broadcast_status()
- if(!radio_connection)
- return 0
-
- var/datum/signal/signal = new
- signal.transmission_method = 1 //radio signal
- signal.source = src
-
- signal.data = list(
- "tag" = id,
- "device" = "AGP",
- "power" = on,
- "target_output" = target_pressure,
- "sigtype" = "status"
- )
-
- radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
-
- return 1
-
-/obj/machinery/atmospherics/binary/passive_gate/receive_signal(datum/signal/signal)
- if(!signal.data["tag"] || (signal.data["tag"] != id) || (signal.data["sigtype"]!="command"))
- return 0
-
- var/old_on = on //for logging
-
- if("power" in signal.data)
- on = text2num(signal.data["power"])
-
- if("power_toggle" in signal.data)
- on = !on
-
- if("set_output_pressure" in signal.data)
- target_pressure = between(
- 0,
- text2num(signal.data["set_output_pressure"]),
- ONE_ATMOSPHERE*50
- )
-
- if(on != old_on)
- investigate_log("was turned [on ? "on" : "off"] by a remote signal", "atmos")
-
- if("status" in signal.data)
- spawn(2)
- broadcast_status()
- return //do not update_icon
-
- spawn(2)
- broadcast_status()
- update_icon()
- return
-
-/obj/machinery/atmospherics/binary/passive_gate/attack_hand(mob/user)
- if(..())
- return
-
- if(!allowed(user))
- to_chat(user, "Access denied.")
- return
-
- add_fingerprint(user)
- ui_interact(user)
-
-/obj/machinery/atmospherics/binary/passive_gate/attack_ghost(mob/user)
- ui_interact(user)
-
-/obj/machinery/atmospherics/binary/passive_gate/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = default_state)
- user.set_machine(src)
- ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
- if(!ui)
- ui = new(user, src, ui_key, "atmos_pump.tmpl", name, 385, 115, state = state)
- ui.open()
-
-/obj/machinery/atmospherics/binary/passive_gate/ui_data(mob/user)
- var/list/data = list()
- data["on"] = on
- data["pressure"] = round(target_pressure)
- data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
- return data
-
-/obj/machinery/atmospherics/binary/passive_gate/Topic(href,href_list)
- if(..())
- return 1
-
- if(href_list["power"])
- on = !on
- investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
- . = TRUE
- if(href_list["pressure"])
- var/pressure = href_list["pressure"]
- if(pressure == "max")
- pressure = MAX_OUTPUT_PRESSURE
- . = TRUE
- else if(pressure == "input")
- pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null
- if(!isnull(pressure))
- . = TRUE
- else if(text2num(pressure) != null)
- pressure = text2num(pressure)
- . = TRUE
- if(.)
- target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
- investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
-
- update_icon()
- SSnanoui.update_uis(src)
-
-/obj/machinery/atmospherics/binary/passive_gate/attackby(obj/item/W, mob/user, params)
- if(!istype(W, /obj/item/wrench))
- return ..()
- if(on)
- to_chat(user, "You cannot unwrench this [src], turn it off first.")
- return 1
- return ..()
+/obj/machinery/atmospherics/binary/passive_gate
+ //Tries to achieve target pressure at output (like a normal pump) except
+ // Uses no power but can not transfer gases from a low pressure area to a high pressure area
+ icon = 'icons/atmos/passive_gate.dmi'
+ icon_state = "map"
+
+ name = "passive gate"
+ desc = "A one-way air valve that does not require power"
+
+ can_unwrench = 1
+
+ var/on = 0
+ var/target_pressure = ONE_ATMOSPHERE
+
+ var/frequency = 0
+ var/id = null
+ var/datum/radio_frequency/radio_connection
+
+/obj/machinery/atmospherics/binary/passive_gate/atmos_init()
+ ..()
+ if(frequency)
+ set_frequency(frequency)
+
+/obj/machinery/atmospherics/binary/passive_gate/Destroy()
+ if(SSradio)
+ SSradio.remove_object(src, frequency)
+ radio_connection = null
+ return ..()
+
+/obj/machinery/atmospherics/binary/passive_gate/update_icon()
+ ..()
+ icon_state = "[on ? "on" : "off"]"
+
+/obj/machinery/atmospherics/binary/passive_gate/update_underlays()
+ if(..())
+ underlays.Cut()
+ var/turf/T = get_turf(src)
+ if(!istype(T))
+ return
+ add_underlay(T, node1, turn(dir, 180))
+ add_underlay(T, node2, dir)
+
+/obj/machinery/atmospherics/binary/passive_gate/process_atmos()
+ ..()
+ if(!on)
+ return 0
+
+ var/output_starting_pressure = air2.return_pressure()
+ var/input_starting_pressure = air1.return_pressure()
+
+ if(output_starting_pressure >= min(target_pressure,input_starting_pressure-10))
+ //No need to pump gas if target is already reached or input pressure is too low
+ //Need at least 10 KPa difference to overcome friction in the mechanism
+ return 1
+
+ //Calculate necessary moles to transfer using PV = nRT
+ if((air1.total_moles() > 0) && (air1.temperature>0))
+ var/pressure_delta = min(target_pressure - output_starting_pressure, (input_starting_pressure - output_starting_pressure)/2)
+ //Can not have a pressure delta that would cause output_pressure > input_pressure
+
+ var/transfer_moles = pressure_delta*air2.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
+
+ //Actually transfer the gas
+ var/datum/gas_mixture/removed = air1.remove(transfer_moles)
+ air2.merge(removed)
+
+ parent1.update = 1
+
+ parent2.update = 1
+ return 1
+
+//Radio remote control
+/obj/machinery/atmospherics/binary/passive_gate/proc/set_frequency(new_frequency)
+ SSradio.remove_object(src, frequency)
+ frequency = new_frequency
+ if(frequency)
+ radio_connection = SSradio.add_object(src, frequency, filter = RADIO_ATMOSIA)
+
+/obj/machinery/atmospherics/binary/passive_gate/proc/broadcast_status()
+ if(!radio_connection)
+ return 0
+
+ var/datum/signal/signal = new
+ signal.transmission_method = 1 //radio signal
+ signal.source = src
+
+ signal.data = list(
+ "tag" = id,
+ "device" = "AGP",
+ "power" = on,
+ "target_output" = target_pressure,
+ "sigtype" = "status"
+ )
+
+ radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
+
+ return 1
+
+/obj/machinery/atmospherics/binary/passive_gate/receive_signal(datum/signal/signal)
+ if(!signal.data["tag"] || (signal.data["tag"] != id) || (signal.data["sigtype"]!="command"))
+ return 0
+
+ var/old_on = on //for logging
+
+ if("power" in signal.data)
+ on = text2num(signal.data["power"])
+
+ if("power_toggle" in signal.data)
+ on = !on
+
+ if("set_output_pressure" in signal.data)
+ target_pressure = between(
+ 0,
+ text2num(signal.data["set_output_pressure"]),
+ ONE_ATMOSPHERE*50
+ )
+
+ if(on != old_on)
+ investigate_log("was turned [on ? "on" : "off"] by a remote signal", "atmos")
+
+ if("status" in signal.data)
+ spawn(2)
+ broadcast_status()
+ return //do not update_icon
+
+ spawn(2)
+ broadcast_status()
+ update_icon()
+ return
+
+/obj/machinery/atmospherics/binary/passive_gate/attack_hand(mob/user)
+ if(..())
+ return
+
+ if(!allowed(user))
+ to_chat(user, "Access denied.")
+ return
+
+ add_fingerprint(user)
+ ui_interact(user)
+
+/obj/machinery/atmospherics/binary/passive_gate/attack_ghost(mob/user)
+ ui_interact(user)
+
+/obj/machinery/atmospherics/binary/passive_gate/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = GLOB.default_state)
+ user.set_machine(src)
+ ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
+ if(!ui)
+ ui = new(user, src, ui_key, "atmos_pump.tmpl", name, 385, 115, state = state)
+ ui.open()
+
+/obj/machinery/atmospherics/binary/passive_gate/ui_data(mob/user)
+ var/list/data = list()
+ data["on"] = on
+ data["pressure"] = round(target_pressure)
+ data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
+ return data
+
+/obj/machinery/atmospherics/binary/passive_gate/Topic(href,href_list)
+ if(..())
+ return 1
+
+ if(href_list["power"])
+ on = !on
+ investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
+ . = TRUE
+ if(href_list["pressure"])
+ var/pressure = href_list["pressure"]
+ if(pressure == "max")
+ pressure = MAX_OUTPUT_PRESSURE
+ . = TRUE
+ else if(pressure == "input")
+ pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null
+ if(!isnull(pressure))
+ . = TRUE
+ else if(text2num(pressure) != null)
+ pressure = text2num(pressure)
+ . = TRUE
+ if(.)
+ target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
+ investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
+
+ update_icon()
+ SSnanoui.update_uis(src)
+
+/obj/machinery/atmospherics/binary/passive_gate/attackby(obj/item/W, mob/user, params)
+ if(!istype(W, /obj/item/wrench))
+ return ..()
+ if(on)
+ to_chat(user, "You cannot unwrench this [src], turn it off first.")
+ return 1
+ return ..()
diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm
index 1998e67e17d..7e02f89c5e2 100644
--- a/code/ATMOSPHERICS/components/binary_devices/pump.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm
@@ -1,261 +1,261 @@
-/*
-Every cycle, the pump uses the air in air_in to try and make air_out the perfect pressure.
-
-node1, air1, network1 correspond to input
-node2, air2, network2 correspond to output
-
-Thus, the two variables affect pump operation are set in New():
- air1.volume
- This is the volume of gas available to the pump that may be transfered to the output
- air2.volume
- Higher quantities of this cause more air to be perfected later
- but overall network volume is also increased as this increases...
-*/
-
-/obj/machinery/atmospherics/binary/pump
- icon = 'icons/atmos/pump.dmi'
- icon_state = "map_off"
-
- name = "gas pump"
- desc = "A pump"
-
- can_unwrench = 1
-
- var/on = 0
- var/target_pressure = ONE_ATMOSPHERE
-
- var/frequency = 0
- var/id = null
- var/datum/radio_frequency/radio_connection
-
-/obj/machinery/atmospherics/binary/pump/CtrlClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
- to_chat(user, "You can't do that right now!")
- return
- if(!in_range(src, user) && !issilicon(usr))
- return
- if(!ishuman(usr) && !issilicon(usr))
- return
- toggle()
- return ..()
-
-/obj/machinery/atmospherics/binary/pump/AICtrlClick()
- toggle()
- return ..()
-
-/obj/machinery/atmospherics/binary/pump/AltClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
- to_chat(user, "You can't do that right now!")
- return
- if(!in_range(src, user) && !issilicon(usr))
- return
- if(!ishuman(usr) && !issilicon(usr))
- return
- set_max()
- return
-
-/obj/machinery/atmospherics/binary/pump/AIAltClick()
- set_max()
- return ..()
-
-/obj/machinery/atmospherics/binary/pump/proc/toggle()
- if(powered())
- on = !on
- update_icon()
-
-/obj/machinery/atmospherics/binary/pump/proc/set_max()
- if(powered())
- target_pressure = MAX_OUTPUT_PRESSURE
- update_icon()
-
-/obj/machinery/atmospherics/binary/pump/Destroy()
- if(SSradio)
- SSradio.remove_object(src, frequency)
- radio_connection = null
- return ..()
-
-/obj/machinery/atmospherics/binary/pump/on
- icon_state = "map_on"
- on = 1
-
-/obj/machinery/atmospherics/binary/pump/update_icon()
- ..()
-
- if(!powered())
- icon_state = "off"
- else
- icon_state = "[on ? "on" : "off"]"
-
-/obj/machinery/atmospherics/binary/pump/update_underlays()
- if(..())
- underlays.Cut()
- var/turf/T = get_turf(src)
- if(!istype(T))
- return
- add_underlay(T, node1, turn(dir, -180))
- add_underlay(T, node2, dir)
-
-/obj/machinery/atmospherics/binary/pump/process_atmos()
- ..()
- if((stat & (NOPOWER|BROKEN)) || !on)
- return 0
-
- var/output_starting_pressure = air2.return_pressure()
-
- if( (target_pressure - output_starting_pressure) < 0.01)
- //No need to pump gas if target is already reached!
- return 1
-
- //Calculate necessary moles to transfer using PV=nRT
- if((air1.total_moles() > 0) && (air1.temperature>0))
- var/pressure_delta = target_pressure - output_starting_pressure
- var/transfer_moles = pressure_delta*air2.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
-
- //Actually transfer the gas
- var/datum/gas_mixture/removed = air1.remove(transfer_moles)
- air2.merge(removed)
-
- parent1.update = 1
-
- parent2.update = 1
- return 1
-
-//Radio remote control
-/obj/machinery/atmospherics/binary/pump/proc/set_frequency(new_frequency)
- SSradio.remove_object(src, frequency)
- frequency = new_frequency
- if(frequency)
- radio_connection = SSradio.add_object(src, frequency, filter = RADIO_ATMOSIA)
-
-/obj/machinery/atmospherics/binary/pump/proc/broadcast_status()
- if(!radio_connection)
- return 0
-
- var/datum/signal/signal = new
- signal.transmission_method = 1 //radio signal
- signal.source = src
-
- signal.data = list(
- "tag" = id,
- "device" = "AGP",
- "power" = on,
- "target_output" = target_pressure,
- "sigtype" = "status"
- )
-
- radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
- return 1
-
-/obj/machinery/atmospherics/binary/pump/atmos_init()
- ..()
- if(frequency)
- set_frequency(frequency)
-
-/obj/machinery/atmospherics/binary/pump/receive_signal(datum/signal/signal)
- if(!signal.data["tag"] || (signal.data["tag"] != id) || (signal.data["sigtype"]!="command"))
- return 0
-
- var/old_on = on //for logging
-
- if(signal.data["power"])
- on = text2num(signal.data["power"])
-
- if(signal.data["power_toggle"])
- on = !on
-
- if(signal.data["set_output_pressure"])
- target_pressure = between(
- 0,
- text2num(signal.data["set_output_pressure"]),
- ONE_ATMOSPHERE*50
- )
-
- if(on != old_on)
- investigate_log("was turned [on ? "on" : "off"] by a remote signal", "atmos")
-
- if(signal.data["status"])
- spawn(2)
- broadcast_status()
- return //do not update_icon
-
- spawn(2)
- broadcast_status()
- update_icon()
- return
-
-/obj/machinery/atmospherics/binary/pump/attack_hand(mob/user)
- if(..())
- return
-
- if(!allowed(user))
- to_chat(user, "Access denied.")
- return
-
- add_fingerprint(user)
- ui_interact(user)
-
-/obj/machinery/atmospherics/binary/pump/attack_ghost(mob/user)
- ui_interact(user)
-
-/obj/machinery/atmospherics/binary/pump/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = default_state)
- user.set_machine(src)
- ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
- if(!ui)
- ui = new(user, src, ui_key, "atmos_pump.tmpl", name, 385, 115, state = state)
- ui.open()
-
-/obj/machinery/atmospherics/binary/pump/ui_data(mob/user)
- var/list/data = list()
- data["on"] = on
- data["pressure"] = round(target_pressure)
- data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
- return data
-
-/obj/machinery/atmospherics/binary/pump/Topic(href,href_list)
- if(..())
- return 1
-
- if(href_list["power"])
- on = !on
- investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
- . = TRUE
- if(href_list["pressure"])
- var/pressure = href_list["pressure"]
- if(pressure == "max")
- pressure = MAX_OUTPUT_PRESSURE
- . = TRUE
- else if(pressure == "input")
- pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null
- if(!isnull(pressure))
- . = TRUE
- else if(text2num(pressure) != null)
- pressure = text2num(pressure)
- . = TRUE
- if(.)
- target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
- investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
-
- update_icon()
- SSnanoui.update_uis(src)
-
-/obj/machinery/atmospherics/binary/pump/power_change()
- var/old_stat = stat
- ..()
- if(old_stat != stat)
- update_icon()
-
-/obj/machinery/atmospherics/binary/pump/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/pen))
- var/t = copytext(stripped_input(user, "Enter the name for the pump.", "Rename", name), 1, MAX_NAME_LEN)
- if(!t)
- return
- if(!in_range(src, usr) && loc != usr)
- return
- name = t
- return
- else if(!istype(W, /obj/item/wrench))
- return ..()
- if(!(stat & NOPOWER) && on)
- to_chat(user, "You cannot unwrench this [src], turn it off first.")
- return 1
- return ..()
\ No newline at end of file
+/*
+Every cycle, the pump uses the air in air_in to try and make air_out the perfect pressure.
+
+node1, air1, network1 correspond to input
+node2, air2, network2 correspond to output
+
+Thus, the two variables affect pump operation are set in New():
+ air1.volume
+ This is the volume of gas available to the pump that may be transfered to the output
+ air2.volume
+ Higher quantities of this cause more air to be perfected later
+ but overall network volume is also increased as this increases...
+*/
+
+/obj/machinery/atmospherics/binary/pump
+ icon = 'icons/atmos/pump.dmi'
+ icon_state = "map_off"
+
+ name = "gas pump"
+ desc = "A pump"
+
+ can_unwrench = 1
+
+ var/on = 0
+ var/target_pressure = ONE_ATMOSPHERE
+
+ var/frequency = 0
+ var/id = null
+ var/datum/radio_frequency/radio_connection
+
+/obj/machinery/atmospherics/binary/pump/CtrlClick(mob/living/user)
+ if(!istype(user) || user.incapacitated())
+ to_chat(user, "You can't do that right now!")
+ return
+ if(!in_range(src, user) && !issilicon(usr))
+ return
+ if(!ishuman(usr) && !issilicon(usr))
+ return
+ toggle()
+ return ..()
+
+/obj/machinery/atmospherics/binary/pump/AICtrlClick()
+ toggle()
+ return ..()
+
+/obj/machinery/atmospherics/binary/pump/AltClick(mob/living/user)
+ if(!istype(user) || user.incapacitated())
+ to_chat(user, "You can't do that right now!")
+ return
+ if(!in_range(src, user) && !issilicon(usr))
+ return
+ if(!ishuman(usr) && !issilicon(usr))
+ return
+ set_max()
+ return
+
+/obj/machinery/atmospherics/binary/pump/AIAltClick()
+ set_max()
+ return ..()
+
+/obj/machinery/atmospherics/binary/pump/proc/toggle()
+ if(powered())
+ on = !on
+ update_icon()
+
+/obj/machinery/atmospherics/binary/pump/proc/set_max()
+ if(powered())
+ target_pressure = MAX_OUTPUT_PRESSURE
+ update_icon()
+
+/obj/machinery/atmospherics/binary/pump/Destroy()
+ if(SSradio)
+ SSradio.remove_object(src, frequency)
+ radio_connection = null
+ return ..()
+
+/obj/machinery/atmospherics/binary/pump/on
+ icon_state = "map_on"
+ on = 1
+
+/obj/machinery/atmospherics/binary/pump/update_icon()
+ ..()
+
+ if(!powered())
+ icon_state = "off"
+ else
+ icon_state = "[on ? "on" : "off"]"
+
+/obj/machinery/atmospherics/binary/pump/update_underlays()
+ if(..())
+ underlays.Cut()
+ var/turf/T = get_turf(src)
+ if(!istype(T))
+ return
+ add_underlay(T, node1, turn(dir, -180))
+ add_underlay(T, node2, dir)
+
+/obj/machinery/atmospherics/binary/pump/process_atmos()
+ ..()
+ if((stat & (NOPOWER|BROKEN)) || !on)
+ return 0
+
+ var/output_starting_pressure = air2.return_pressure()
+
+ if( (target_pressure - output_starting_pressure) < 0.01)
+ //No need to pump gas if target is already reached!
+ return 1
+
+ //Calculate necessary moles to transfer using PV=nRT
+ if((air1.total_moles() > 0) && (air1.temperature>0))
+ var/pressure_delta = target_pressure - output_starting_pressure
+ var/transfer_moles = pressure_delta*air2.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
+
+ //Actually transfer the gas
+ var/datum/gas_mixture/removed = air1.remove(transfer_moles)
+ air2.merge(removed)
+
+ parent1.update = 1
+
+ parent2.update = 1
+ return 1
+
+//Radio remote control
+/obj/machinery/atmospherics/binary/pump/proc/set_frequency(new_frequency)
+ SSradio.remove_object(src, frequency)
+ frequency = new_frequency
+ if(frequency)
+ radio_connection = SSradio.add_object(src, frequency, filter = RADIO_ATMOSIA)
+
+/obj/machinery/atmospherics/binary/pump/proc/broadcast_status()
+ if(!radio_connection)
+ return 0
+
+ var/datum/signal/signal = new
+ signal.transmission_method = 1 //radio signal
+ signal.source = src
+
+ signal.data = list(
+ "tag" = id,
+ "device" = "AGP",
+ "power" = on,
+ "target_output" = target_pressure,
+ "sigtype" = "status"
+ )
+
+ radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
+ return 1
+
+/obj/machinery/atmospherics/binary/pump/atmos_init()
+ ..()
+ if(frequency)
+ set_frequency(frequency)
+
+/obj/machinery/atmospherics/binary/pump/receive_signal(datum/signal/signal)
+ if(!signal.data["tag"] || (signal.data["tag"] != id) || (signal.data["sigtype"]!="command"))
+ return 0
+
+ var/old_on = on //for logging
+
+ if(signal.data["power"])
+ on = text2num(signal.data["power"])
+
+ if(signal.data["power_toggle"])
+ on = !on
+
+ if(signal.data["set_output_pressure"])
+ target_pressure = between(
+ 0,
+ text2num(signal.data["set_output_pressure"]),
+ ONE_ATMOSPHERE*50
+ )
+
+ if(on != old_on)
+ investigate_log("was turned [on ? "on" : "off"] by a remote signal", "atmos")
+
+ if(signal.data["status"])
+ spawn(2)
+ broadcast_status()
+ return //do not update_icon
+
+ spawn(2)
+ broadcast_status()
+ update_icon()
+ return
+
+/obj/machinery/atmospherics/binary/pump/attack_hand(mob/user)
+ if(..())
+ return
+
+ if(!allowed(user))
+ to_chat(user, "Access denied.")
+ return
+
+ add_fingerprint(user)
+ ui_interact(user)
+
+/obj/machinery/atmospherics/binary/pump/attack_ghost(mob/user)
+ ui_interact(user)
+
+/obj/machinery/atmospherics/binary/pump/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = GLOB.default_state)
+ user.set_machine(src)
+ ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
+ if(!ui)
+ ui = new(user, src, ui_key, "atmos_pump.tmpl", name, 385, 115, state = state)
+ ui.open()
+
+/obj/machinery/atmospherics/binary/pump/ui_data(mob/user)
+ var/list/data = list()
+ data["on"] = on
+ data["pressure"] = round(target_pressure)
+ data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
+ return data
+
+/obj/machinery/atmospherics/binary/pump/Topic(href,href_list)
+ if(..())
+ return 1
+
+ if(href_list["power"])
+ on = !on
+ investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
+ . = TRUE
+ if(href_list["pressure"])
+ var/pressure = href_list["pressure"]
+ if(pressure == "max")
+ pressure = MAX_OUTPUT_PRESSURE
+ . = TRUE
+ else if(pressure == "input")
+ pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null
+ if(!isnull(pressure))
+ . = TRUE
+ else if(text2num(pressure) != null)
+ pressure = text2num(pressure)
+ . = TRUE
+ if(.)
+ target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
+ investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
+
+ update_icon()
+ SSnanoui.update_uis(src)
+
+/obj/machinery/atmospherics/binary/pump/power_change()
+ var/old_stat = stat
+ ..()
+ if(old_stat != stat)
+ update_icon()
+
+/obj/machinery/atmospherics/binary/pump/attackby(obj/item/W, mob/user, params)
+ if(istype(W, /obj/item/pen))
+ var/t = copytext(stripped_input(user, "Enter the name for the pump.", "Rename", name), 1, MAX_NAME_LEN)
+ if(!t)
+ return
+ if(!in_range(src, usr) && loc != usr)
+ return
+ name = t
+ return
+ else if(!istype(W, /obj/item/wrench))
+ return ..()
+ if(!(stat & NOPOWER) && on)
+ to_chat(user, "You cannot unwrench this [src], turn it off first.")
+ return 1
+ return ..()
diff --git a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm
index 0947b2ee860..8741acb47bf 100644
--- a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm
@@ -1,257 +1,257 @@
-/*
-Every cycle, the pump uses the air in air_in to try and make air_out the perfect pressure.
-
-node1, air1, network1 correspond to input
-node2, air2, network2 correspond to output
-
-Thus, the two variables affect pump operation are set in New():
- air1.volume
- This is the volume of gas available to the pump that may be transfered to the output
- air2.volume
- Higher quantities of this cause more air to be perfected later
- but overall network volume is also increased as this increases...
-*/
-
-/obj/machinery/atmospherics/binary/volume_pump
- icon = 'icons/atmos/volume_pump.dmi'
- icon_state = "map_off"
-
- name = "volumetric gas pump"
- desc = "A volumetric pump"
-
- can_unwrench = 1
-
- var/on = 0
- var/transfer_rate = 200
-
- var/frequency = 0
- var/id = null
- var/datum/radio_frequency/radio_connection
-
-/obj/machinery/atmospherics/binary/volume_pump/CtrlClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
- to_chat(user, "You can't do that right now!")
- return
- if(!in_range(src, user) && !issilicon(usr))
- return
- if(!ishuman(usr) && !issilicon(usr))
- return
- toggle()
- return ..()
-
-/obj/machinery/atmospherics/binary/volume_pump/AICtrlClick()
- toggle()
- return ..()
-
-/obj/machinery/atmospherics/binary/volume_pump/AltClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
- to_chat(user, "You can't do that right now!")
- return
- if(!in_range(src, user) && !issilicon(usr))
- return
- if(!ishuman(usr) && !issilicon(usr))
- return
- set_max()
- return
-
-/obj/machinery/atmospherics/binary/volume_pump/AIAltClick()
- set_max()
- return ..()
-
-/obj/machinery/atmospherics/binary/volume_pump/proc/toggle()
- if(powered())
- on = !on
- update_icon()
-
-/obj/machinery/atmospherics/binary/volume_pump/proc/set_max()
- if(powered())
- transfer_rate = MAX_TRANSFER_RATE
- update_icon()
-
-/obj/machinery/atmospherics/binary/volume_pump/Destroy()
- if(SSradio)
- SSradio.remove_object(src, frequency)
- radio_connection = null
- return ..()
-
-/obj/machinery/atmospherics/binary/volume_pump/on
- on = 1
- icon_state = "map_on"
-
-/obj/machinery/atmospherics/binary/volume_pump/atmos_init()
- ..()
- set_frequency(frequency)
-
-/obj/machinery/atmospherics/binary/volume_pump/update_icon()
- ..()
-
- if(!powered())
- icon_state = "off"
- else
- icon_state = "[on ? "on" : "off"]"
-
-/obj/machinery/atmospherics/binary/volume_pump/update_underlays()
- if(..())
- underlays.Cut()
- var/turf/T = get_turf(src)
- if(!istype(T))
- return
- add_underlay(T, node1, turn(dir, -180))
- add_underlay(T, node2, dir)
-
-/obj/machinery/atmospherics/binary/volume_pump/process_atmos()
- ..()
- if((stat & (NOPOWER|BROKEN)) || !on)
- return 0
-
- // Pump mechanism just won't do anything if the pressure is too high/too low
- var/input_starting_pressure = air1.return_pressure()
- var/output_starting_pressure = air2.return_pressure()
-
- if((input_starting_pressure < 0.01) || (output_starting_pressure > 9000))
- return 1
-
- var/transfer_ratio = max(1, transfer_rate/air1.volume)
-
- var/datum/gas_mixture/removed = air1.remove_ratio(transfer_ratio)
-
- air2.merge(removed)
-
-
- parent1.update = 1
- parent2.update = 1
-
- return 1
-
-/obj/machinery/atmospherics/binary/volume_pump/proc/set_frequency(new_frequency)
- SSradio.remove_object(src, frequency)
- frequency = new_frequency
- if(frequency)
- radio_connection = SSradio.add_object(src, frequency)
-
-/obj/machinery/atmospherics/binary/volume_pump/proc/broadcast_status()
- if(!radio_connection)
- return 0
-
- var/datum/signal/signal = new
- signal.transmission_method = 1 //radio signal
- signal.source = src
-
- signal.data = list(
- "tag" = id,
- "device" = "APV",
- "power" = on,
- "transfer_rate" = transfer_rate,
- "sigtype" = "status"
- )
- radio_connection.post_signal(src, signal)
-
- return 1
-
-/obj/machinery/atmospherics/binary/volume_pump/receive_signal(datum/signal/signal)
- if(!signal.data["tag"] || (signal.data["tag"] != id) || (signal.data["sigtype"]!="command"))
- return 0
-
- var/old_on = on //for logging
-
- if(signal.data["power"])
- on = text2num(signal.data["power"])
-
- if(signal.data["power_toggle"])
- on = !on
-
- if(signal.data["set_transfer_rate"])
- transfer_rate = between(
- 0,
- text2num(signal.data["set_transfer_rate"]),
- air1.volume
- )
-
- if(on != old_on)
- investigate_log("was turned [on ? "on" : "off"] by a remote signal", "atmos")
-
- if(signal.data["status"])
- spawn(2)
- broadcast_status()
- return //do not update_icon
-
- spawn(2)
- broadcast_status()
- update_icon()
-
-/obj/machinery/atmospherics/binary/volume_pump/attack_hand(mob/user)
- if(..())
- return
-
- if(!allowed(user))
- to_chat(user, "Access denied.")
- return
-
- add_fingerprint(user)
- ui_interact(user)
-
-/obj/machinery/atmospherics/binary/volume_pump/attack_ghost(mob/user)
- ui_interact(user)
-
-/obj/machinery/atmospherics/binary/volume_pump/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = default_state)
- user.set_machine(src)
- ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
- if(!ui)
- ui = new(user, src, ui_key, "atmos_pump.tmpl", name, 310, 115, state = state)
- ui.open()
-
-/obj/machinery/atmospherics/binary/volume_pump/ui_data(mob/user)
- var/list/data = list()
- data["on"] = on
- data["rate"] = round(transfer_rate)
- data["max_rate"] = round(MAX_TRANSFER_RATE)
- return data
-
-/obj/machinery/atmospherics/binary/volume_pump/Topic(href,href_list)
- if(..())
- return 1
-
- if(href_list["power"])
- on = !on
- investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
- . = TRUE
- if(href_list["rate"])
- var/rate = href_list["rate"]
- if(rate == "max")
- rate = MAX_TRANSFER_RATE
- . = TRUE
- else if(rate == "input")
- rate = input("New transfer rate (0-[MAX_TRANSFER_RATE] L/s):", name, transfer_rate) as num|null
- if(!isnull(rate))
- . = TRUE
- else if(text2num(rate) != null)
- rate = text2num(rate)
- . = TRUE
- if(.)
- transfer_rate = Clamp(rate, 0, MAX_TRANSFER_RATE)
- investigate_log("was set to [transfer_rate] L/s by [key_name(usr)]", "atmos")
-
- update_icon()
- SSnanoui.update_uis(src)
-
-/obj/machinery/atmospherics/binary/volume_pump/power_change()
- var/old_stat = stat
- ..()
- if(old_stat != stat)
- update_icon()
-
-/obj/machinery/atmospherics/binary/volume_pump/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/pen))
- var/t = copytext(stripped_input(user, "Enter the name for the volume pump.", "Rename", name), 1, MAX_NAME_LEN)
- if(!t)
- return
- if(!in_range(src, usr) && loc != usr)
- return
- name = t
- return
- else if(!istype(W, /obj/item/wrench))
- return ..()
- if(!(stat & NOPOWER) && on)
- to_chat(user, "You cannot unwrench this [src], turn it off first.")
- return 1
- return ..()
\ No newline at end of file
+/*
+Every cycle, the pump uses the air in air_in to try and make air_out the perfect pressure.
+
+node1, air1, network1 correspond to input
+node2, air2, network2 correspond to output
+
+Thus, the two variables affect pump operation are set in New():
+ air1.volume
+ This is the volume of gas available to the pump that may be transfered to the output
+ air2.volume
+ Higher quantities of this cause more air to be perfected later
+ but overall network volume is also increased as this increases...
+*/
+
+/obj/machinery/atmospherics/binary/volume_pump
+ icon = 'icons/atmos/volume_pump.dmi'
+ icon_state = "map_off"
+
+ name = "volumetric gas pump"
+ desc = "A volumetric pump"
+
+ can_unwrench = 1
+
+ var/on = 0
+ var/transfer_rate = 200
+
+ var/frequency = 0
+ var/id = null
+ var/datum/radio_frequency/radio_connection
+
+/obj/machinery/atmospherics/binary/volume_pump/CtrlClick(mob/living/user)
+ if(!istype(user) || user.incapacitated())
+ to_chat(user, "You can't do that right now!")
+ return
+ if(!in_range(src, user) && !issilicon(usr))
+ return
+ if(!ishuman(usr) && !issilicon(usr))
+ return
+ toggle()
+ return ..()
+
+/obj/machinery/atmospherics/binary/volume_pump/AICtrlClick()
+ toggle()
+ return ..()
+
+/obj/machinery/atmospherics/binary/volume_pump/AltClick(mob/living/user)
+ if(!istype(user) || user.incapacitated())
+ to_chat(user, "You can't do that right now!")
+ return
+ if(!in_range(src, user) && !issilicon(usr))
+ return
+ if(!ishuman(usr) && !issilicon(usr))
+ return
+ set_max()
+ return
+
+/obj/machinery/atmospherics/binary/volume_pump/AIAltClick()
+ set_max()
+ return ..()
+
+/obj/machinery/atmospherics/binary/volume_pump/proc/toggle()
+ if(powered())
+ on = !on
+ update_icon()
+
+/obj/machinery/atmospherics/binary/volume_pump/proc/set_max()
+ if(powered())
+ transfer_rate = MAX_TRANSFER_RATE
+ update_icon()
+
+/obj/machinery/atmospherics/binary/volume_pump/Destroy()
+ if(SSradio)
+ SSradio.remove_object(src, frequency)
+ radio_connection = null
+ return ..()
+
+/obj/machinery/atmospherics/binary/volume_pump/on
+ on = 1
+ icon_state = "map_on"
+
+/obj/machinery/atmospherics/binary/volume_pump/atmos_init()
+ ..()
+ set_frequency(frequency)
+
+/obj/machinery/atmospherics/binary/volume_pump/update_icon()
+ ..()
+
+ if(!powered())
+ icon_state = "off"
+ else
+ icon_state = "[on ? "on" : "off"]"
+
+/obj/machinery/atmospherics/binary/volume_pump/update_underlays()
+ if(..())
+ underlays.Cut()
+ var/turf/T = get_turf(src)
+ if(!istype(T))
+ return
+ add_underlay(T, node1, turn(dir, -180))
+ add_underlay(T, node2, dir)
+
+/obj/machinery/atmospherics/binary/volume_pump/process_atmos()
+ ..()
+ if((stat & (NOPOWER|BROKEN)) || !on)
+ return 0
+
+ // Pump mechanism just won't do anything if the pressure is too high/too low
+ var/input_starting_pressure = air1.return_pressure()
+ var/output_starting_pressure = air2.return_pressure()
+
+ if((input_starting_pressure < 0.01) || (output_starting_pressure > 9000))
+ return 1
+
+ var/transfer_ratio = max(1, transfer_rate/air1.volume)
+
+ var/datum/gas_mixture/removed = air1.remove_ratio(transfer_ratio)
+
+ air2.merge(removed)
+
+
+ parent1.update = 1
+ parent2.update = 1
+
+ return 1
+
+/obj/machinery/atmospherics/binary/volume_pump/proc/set_frequency(new_frequency)
+ SSradio.remove_object(src, frequency)
+ frequency = new_frequency
+ if(frequency)
+ radio_connection = SSradio.add_object(src, frequency)
+
+/obj/machinery/atmospherics/binary/volume_pump/proc/broadcast_status()
+ if(!radio_connection)
+ return 0
+
+ var/datum/signal/signal = new
+ signal.transmission_method = 1 //radio signal
+ signal.source = src
+
+ signal.data = list(
+ "tag" = id,
+ "device" = "APV",
+ "power" = on,
+ "transfer_rate" = transfer_rate,
+ "sigtype" = "status"
+ )
+ radio_connection.post_signal(src, signal)
+
+ return 1
+
+/obj/machinery/atmospherics/binary/volume_pump/receive_signal(datum/signal/signal)
+ if(!signal.data["tag"] || (signal.data["tag"] != id) || (signal.data["sigtype"]!="command"))
+ return 0
+
+ var/old_on = on //for logging
+
+ if(signal.data["power"])
+ on = text2num(signal.data["power"])
+
+ if(signal.data["power_toggle"])
+ on = !on
+
+ if(signal.data["set_transfer_rate"])
+ transfer_rate = between(
+ 0,
+ text2num(signal.data["set_transfer_rate"]),
+ air1.volume
+ )
+
+ if(on != old_on)
+ investigate_log("was turned [on ? "on" : "off"] by a remote signal", "atmos")
+
+ if(signal.data["status"])
+ spawn(2)
+ broadcast_status()
+ return //do not update_icon
+
+ spawn(2)
+ broadcast_status()
+ update_icon()
+
+/obj/machinery/atmospherics/binary/volume_pump/attack_hand(mob/user)
+ if(..())
+ return
+
+ if(!allowed(user))
+ to_chat(user, "Access denied.")
+ return
+
+ add_fingerprint(user)
+ ui_interact(user)
+
+/obj/machinery/atmospherics/binary/volume_pump/attack_ghost(mob/user)
+ ui_interact(user)
+
+/obj/machinery/atmospherics/binary/volume_pump/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = GLOB.default_state)
+ user.set_machine(src)
+ ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
+ if(!ui)
+ ui = new(user, src, ui_key, "atmos_pump.tmpl", name, 310, 115, state = state)
+ ui.open()
+
+/obj/machinery/atmospherics/binary/volume_pump/ui_data(mob/user)
+ var/list/data = list()
+ data["on"] = on
+ data["rate"] = round(transfer_rate)
+ data["max_rate"] = round(MAX_TRANSFER_RATE)
+ return data
+
+/obj/machinery/atmospherics/binary/volume_pump/Topic(href,href_list)
+ if(..())
+ return 1
+
+ if(href_list["power"])
+ on = !on
+ investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
+ . = TRUE
+ if(href_list["rate"])
+ var/rate = href_list["rate"]
+ if(rate == "max")
+ rate = MAX_TRANSFER_RATE
+ . = TRUE
+ else if(rate == "input")
+ rate = input("New transfer rate (0-[MAX_TRANSFER_RATE] L/s):", name, transfer_rate) as num|null
+ if(!isnull(rate))
+ . = TRUE
+ else if(text2num(rate) != null)
+ rate = text2num(rate)
+ . = TRUE
+ if(.)
+ transfer_rate = Clamp(rate, 0, MAX_TRANSFER_RATE)
+ investigate_log("was set to [transfer_rate] L/s by [key_name(usr)]", "atmos")
+
+ update_icon()
+ SSnanoui.update_uis(src)
+
+/obj/machinery/atmospherics/binary/volume_pump/power_change()
+ var/old_stat = stat
+ ..()
+ if(old_stat != stat)
+ update_icon()
+
+/obj/machinery/atmospherics/binary/volume_pump/attackby(obj/item/W, mob/user, params)
+ if(istype(W, /obj/item/pen))
+ var/t = copytext(stripped_input(user, "Enter the name for the volume pump.", "Rename", name), 1, MAX_NAME_LEN)
+ if(!t)
+ return
+ if(!in_range(src, usr) && loc != usr)
+ return
+ name = t
+ return
+ else if(!istype(W, /obj/item/wrench))
+ return ..()
+ if(!(stat & NOPOWER) && on)
+ to_chat(user, "You cannot unwrench this [src], turn it off first.")
+ return 1
+ return ..()
diff --git a/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm b/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm
index a1f80916aee..d03329e24fc 100644
--- a/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm
+++ b/code/ATMOSPHERICS/components/omni_devices/_omni_extras.dm
@@ -91,4 +91,4 @@
return WEST
else
return 0
-
\ No newline at end of file
+
diff --git a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm
index cde1c9e80b0..d75e2e683c1 100644
--- a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm
+++ b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm
@@ -31,7 +31,7 @@
icon_state = "base"
ports = new()
- for(var/d in cardinal)
+ for(var/d in GLOB.cardinal)
var/datum/omni_port/new_port = new(src, d)
switch(d)
if(NORTH)
diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm
index e45a8c3956f..84e212598c8 100755
--- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm
+++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm
@@ -1,267 +1,267 @@
-/obj/machinery/atmospherics/trinary/filter
- icon = 'icons/atmos/filter.dmi'
- icon_state = "map"
-
- can_unwrench = 1
-
- name = "gas filter"
-
- var/target_pressure = ONE_ATMOSPHERE
-
- var/filter_type = 0
-/*
-Filter types:
--1: Nothing
- 0: Toxins: Toxins, Oxygen Agent B
- 1: Oxygen: Oxygen ONLY
- 2: Nitrogen: Nitrogen ONLY
- 3: Carbon Dioxide: Carbon Dioxide ONLY
- 4: Sleeping Agent (N2O)
-*/
-
- var/frequency = 0
- var/datum/radio_frequency/radio_connection
-
-/obj/machinery/atmospherics/trinary/filter/CtrlClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
- to_chat(user, "You can't do that right now!")
- return
- if(!in_range(src, user) && !issilicon(usr))
- return
- if(!ishuman(usr) && !issilicon(usr))
- return
- toggle()
- return ..()
-
-/obj/machinery/atmospherics/trinary/filter/AICtrlClick()
- toggle()
- return ..()
-
-/obj/machinery/atmospherics/trinary/filter/AltClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
- to_chat(user, "You can't do that right now!")
- return
- if(!in_range(src, user) && !issilicon(usr))
- return
- if(!ishuman(usr) && !issilicon(usr))
- return
- set_max()
- return
-
-/obj/machinery/atmospherics/trinary/filter/AIAltClick()
- set_max()
- return ..()
-
-/obj/machinery/atmospherics/trinary/filter/proc/toggle()
- if(powered())
- on = !on
- update_icon()
-
-/obj/machinery/atmospherics/trinary/filter/proc/set_max()
- if(powered())
- target_pressure = MAX_OUTPUT_PRESSURE
- update_icon()
-
-/obj/machinery/atmospherics/trinary/filter/Destroy()
- if(SSradio)
- SSradio.remove_object(src, frequency)
- radio_connection = null
- return ..()
-
-/obj/machinery/atmospherics/trinary/filter/flipped
- icon_state = "mmap"
- flipped = 1
-
-/obj/machinery/atmospherics/trinary/filter/proc/set_frequency(new_frequency)
- SSradio.remove_object(src, frequency)
- frequency = new_frequency
- if(frequency)
- radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA)
-
-/obj/machinery/atmospherics/trinary/filter/update_icon()
- ..()
-
- if(flipped)
- icon_state = "m"
- else
- icon_state = ""
-
- if(!powered())
- icon_state += "off"
- else if(node2 && node3 && node1)
- icon_state += on ? "on" : "off"
- else
- icon_state += "off"
- on = 0
-
-/obj/machinery/atmospherics/trinary/filter/update_underlays()
- if(..())
- underlays.Cut()
- var/turf/T = get_turf(src)
- if(!istype(T))
- return
-
- add_underlay(T, node1, turn(dir, -180))
-
- if(flipped)
- add_underlay(T, node2, turn(dir, 90))
- else
- add_underlay(T, node2, turn(dir, -90))
-
- add_underlay(T, node3, dir)
-
-/obj/machinery/atmospherics/trinary/filter/power_change()
- var/old_stat = stat
- ..()
- if(old_stat != stat)
- update_icon()
-
-/obj/machinery/atmospherics/trinary/filter/process_atmos()
- ..()
- if(!on)
- return 0
-
- var/output_starting_pressure = air3.return_pressure()
-
- if(output_starting_pressure >= target_pressure || air2.return_pressure() >= target_pressure )
- //No need to mix if target is already full!
- return 1
-
- //Calculate necessary moles to transfer using PV=nRT
-
- var/pressure_delta = target_pressure - output_starting_pressure
- var/transfer_moles
-
- if(air1.temperature > 0)
- transfer_moles = pressure_delta*air3.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
-
- //Actually transfer the gas
-
- if(transfer_moles > 0)
- var/datum/gas_mixture/removed = air1.remove(transfer_moles)
-
- if(!removed)
- return
- var/datum/gas_mixture/filtered_out = new
- filtered_out.temperature = removed.temperature
-
- switch(filter_type)
- if(0) //removing hydrocarbons
- filtered_out.toxins = removed.toxins
- removed.toxins = 0
-
- if(removed.trace_gases.len>0)
- for(var/datum/gas/trace_gas in removed.trace_gases)
- if(istype(trace_gas, /datum/gas/oxygen_agent_b))
- removed.trace_gases -= trace_gas
- filtered_out.trace_gases += trace_gas
-
- if(1) //removing O2
- filtered_out.oxygen = removed.oxygen
- removed.oxygen = 0
-
- if(2) //removing N2
- filtered_out.nitrogen = removed.nitrogen
- removed.nitrogen = 0
-
- if(3) //removing CO2
- filtered_out.carbon_dioxide = removed.carbon_dioxide
- removed.carbon_dioxide = 0
-
- if(4)//removing N2O
- if(removed.trace_gases.len>0)
- for(var/datum/gas/trace_gas in removed.trace_gases)
- if(istype(trace_gas, /datum/gas/sleeping_agent))
- removed.trace_gases -= trace_gas
- filtered_out.trace_gases += trace_gas
-
- else
- filtered_out = null
-
-
- air2.merge(filtered_out)
- air3.merge(removed)
-
- parent2.update = 1
-
- parent3.update = 1
-
- parent1.update = 1
-
- return 1
-
-/obj/machinery/atmospherics/trinary/filter/atmos_init()
- set_frequency(frequency)
- ..()
-
-/obj/machinery/atmospherics/trinary/filter/attack_ghost(mob/user)
- ui_interact(user)
-
-/obj/machinery/atmospherics/trinary/filter/attack_hand(mob/user)
- if(..())
- return
-
- if(!allowed(user))
- to_chat(user, "Access denied.")
- return
-
- add_fingerprint(user)
- ui_interact(user)
-
-/obj/machinery/atmospherics/trinary/filter/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = default_state)
- user.set_machine(src)
- ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
- if(!ui)
- ui = new(user, src, ui_key, "atmos_filter.tmpl", name, 475, 155, state = state)
- ui.open()
-
-/obj/machinery/atmospherics/trinary/filter/ui_data(mob/user)
- var/list/data = list()
- data["on"] = on
- data["pressure"] = round(target_pressure)
- data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
- data["filter_type"] = filter_type
- return data
-
-/obj/machinery/atmospherics/trinary/filter/Topic(href, href_list) // -- TLE
- if(..())
- return 1
-
- if(href_list["power"])
- on = !on
- investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
- . = TRUE
- if(href_list["pressure"])
- var/pressure = href_list["pressure"]
- if(pressure == "max")
- pressure = MAX_OUTPUT_PRESSURE
- . = TRUE
- else if(pressure == "input")
- pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null
- if(!isnull(pressure) && !..())
- . = TRUE
- else if(text2num(pressure) != null)
- pressure = text2num(pressure)
- . = TRUE
- if(.)
- target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
- investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
- if(href_list["filter"])
- filter_type = text2num(href_list["filter"])
- investigate_log("was set to filter [filter_type] by [key_name(usr)]", "atmos")
- . = TRUE
-
- update_icon()
- SSnanoui.update_uis(src)
-
-/obj/machinery/atmospherics/trinary/filter/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/pen))
- var/t = copytext(stripped_input(user, "Enter the name for the filter.", "Rename", name), 1, MAX_NAME_LEN)
- if(!t)
- return
- if(!in_range(src, usr) && loc != usr)
- return
- name = t
- return
- else
- return ..()
\ No newline at end of file
+/obj/machinery/atmospherics/trinary/filter
+ icon = 'icons/atmos/filter.dmi'
+ icon_state = "map"
+
+ can_unwrench = 1
+
+ name = "gas filter"
+
+ var/target_pressure = ONE_ATMOSPHERE
+
+ var/filter_type = 0
+/*
+Filter types:
+-1: Nothing
+ 0: Toxins: Toxins, Oxygen Agent B
+ 1: Oxygen: Oxygen ONLY
+ 2: Nitrogen: Nitrogen ONLY
+ 3: Carbon Dioxide: Carbon Dioxide ONLY
+ 4: Sleeping Agent (N2O)
+*/
+
+ var/frequency = 0
+ var/datum/radio_frequency/radio_connection
+
+/obj/machinery/atmospherics/trinary/filter/CtrlClick(mob/living/user)
+ if(!istype(user) || user.incapacitated())
+ to_chat(user, "You can't do that right now!")
+ return
+ if(!in_range(src, user) && !issilicon(usr))
+ return
+ if(!ishuman(usr) && !issilicon(usr))
+ return
+ toggle()
+ return ..()
+
+/obj/machinery/atmospherics/trinary/filter/AICtrlClick()
+ toggle()
+ return ..()
+
+/obj/machinery/atmospherics/trinary/filter/AltClick(mob/living/user)
+ if(!istype(user) || user.incapacitated())
+ to_chat(user, "You can't do that right now!")
+ return
+ if(!in_range(src, user) && !issilicon(usr))
+ return
+ if(!ishuman(usr) && !issilicon(usr))
+ return
+ set_max()
+ return
+
+/obj/machinery/atmospherics/trinary/filter/AIAltClick()
+ set_max()
+ return ..()
+
+/obj/machinery/atmospherics/trinary/filter/proc/toggle()
+ if(powered())
+ on = !on
+ update_icon()
+
+/obj/machinery/atmospherics/trinary/filter/proc/set_max()
+ if(powered())
+ target_pressure = MAX_OUTPUT_PRESSURE
+ update_icon()
+
+/obj/machinery/atmospherics/trinary/filter/Destroy()
+ if(SSradio)
+ SSradio.remove_object(src, frequency)
+ radio_connection = null
+ return ..()
+
+/obj/machinery/atmospherics/trinary/filter/flipped
+ icon_state = "mmap"
+ flipped = 1
+
+/obj/machinery/atmospherics/trinary/filter/proc/set_frequency(new_frequency)
+ SSradio.remove_object(src, frequency)
+ frequency = new_frequency
+ if(frequency)
+ radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA)
+
+/obj/machinery/atmospherics/trinary/filter/update_icon()
+ ..()
+
+ if(flipped)
+ icon_state = "m"
+ else
+ icon_state = ""
+
+ if(!powered())
+ icon_state += "off"
+ else if(node2 && node3 && node1)
+ icon_state += on ? "on" : "off"
+ else
+ icon_state += "off"
+ on = 0
+
+/obj/machinery/atmospherics/trinary/filter/update_underlays()
+ if(..())
+ underlays.Cut()
+ var/turf/T = get_turf(src)
+ if(!istype(T))
+ return
+
+ add_underlay(T, node1, turn(dir, -180))
+
+ if(flipped)
+ add_underlay(T, node2, turn(dir, 90))
+ else
+ add_underlay(T, node2, turn(dir, -90))
+
+ add_underlay(T, node3, dir)
+
+/obj/machinery/atmospherics/trinary/filter/power_change()
+ var/old_stat = stat
+ ..()
+ if(old_stat != stat)
+ update_icon()
+
+/obj/machinery/atmospherics/trinary/filter/process_atmos()
+ ..()
+ if(!on)
+ return 0
+
+ var/output_starting_pressure = air3.return_pressure()
+
+ if(output_starting_pressure >= target_pressure || air2.return_pressure() >= target_pressure )
+ //No need to mix if target is already full!
+ return 1
+
+ //Calculate necessary moles to transfer using PV=nRT
+
+ var/pressure_delta = target_pressure - output_starting_pressure
+ var/transfer_moles
+
+ if(air1.temperature > 0)
+ transfer_moles = pressure_delta*air3.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
+
+ //Actually transfer the gas
+
+ if(transfer_moles > 0)
+ var/datum/gas_mixture/removed = air1.remove(transfer_moles)
+
+ if(!removed)
+ return
+ var/datum/gas_mixture/filtered_out = new
+ filtered_out.temperature = removed.temperature
+
+ switch(filter_type)
+ if(0) //removing hydrocarbons
+ filtered_out.toxins = removed.toxins
+ removed.toxins = 0
+
+ if(removed.trace_gases.len>0)
+ for(var/datum/gas/trace_gas in removed.trace_gases)
+ if(istype(trace_gas, /datum/gas/oxygen_agent_b))
+ removed.trace_gases -= trace_gas
+ filtered_out.trace_gases += trace_gas
+
+ if(1) //removing O2
+ filtered_out.oxygen = removed.oxygen
+ removed.oxygen = 0
+
+ if(2) //removing N2
+ filtered_out.nitrogen = removed.nitrogen
+ removed.nitrogen = 0
+
+ if(3) //removing CO2
+ filtered_out.carbon_dioxide = removed.carbon_dioxide
+ removed.carbon_dioxide = 0
+
+ if(4)//removing N2O
+ if(removed.trace_gases.len>0)
+ for(var/datum/gas/trace_gas in removed.trace_gases)
+ if(istype(trace_gas, /datum/gas/sleeping_agent))
+ removed.trace_gases -= trace_gas
+ filtered_out.trace_gases += trace_gas
+
+ else
+ filtered_out = null
+
+
+ air2.merge(filtered_out)
+ air3.merge(removed)
+
+ parent2.update = 1
+
+ parent3.update = 1
+
+ parent1.update = 1
+
+ return 1
+
+/obj/machinery/atmospherics/trinary/filter/atmos_init()
+ set_frequency(frequency)
+ ..()
+
+/obj/machinery/atmospherics/trinary/filter/attack_ghost(mob/user)
+ ui_interact(user)
+
+/obj/machinery/atmospherics/trinary/filter/attack_hand(mob/user)
+ if(..())
+ return
+
+ if(!allowed(user))
+ to_chat(user, "Access denied.")
+ return
+
+ add_fingerprint(user)
+ ui_interact(user)
+
+/obj/machinery/atmospherics/trinary/filter/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = GLOB.default_state)
+ user.set_machine(src)
+ ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
+ if(!ui)
+ ui = new(user, src, ui_key, "atmos_filter.tmpl", name, 475, 155, state = state)
+ ui.open()
+
+/obj/machinery/atmospherics/trinary/filter/ui_data(mob/user)
+ var/list/data = list()
+ data["on"] = on
+ data["pressure"] = round(target_pressure)
+ data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
+ data["filter_type"] = filter_type
+ return data
+
+/obj/machinery/atmospherics/trinary/filter/Topic(href, href_list) // -- TLE
+ if(..())
+ return 1
+
+ if(href_list["power"])
+ on = !on
+ investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
+ . = TRUE
+ if(href_list["pressure"])
+ var/pressure = href_list["pressure"]
+ if(pressure == "max")
+ pressure = MAX_OUTPUT_PRESSURE
+ . = TRUE
+ else if(pressure == "input")
+ pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null
+ if(!isnull(pressure) && !..())
+ . = TRUE
+ else if(text2num(pressure) != null)
+ pressure = text2num(pressure)
+ . = TRUE
+ if(.)
+ target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
+ investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
+ if(href_list["filter"])
+ filter_type = text2num(href_list["filter"])
+ investigate_log("was set to filter [filter_type] by [key_name(usr)]", "atmos")
+ . = TRUE
+
+ update_icon()
+ SSnanoui.update_uis(src)
+
+/obj/machinery/atmospherics/trinary/filter/attackby(obj/item/W, mob/user, params)
+ if(istype(W, /obj/item/pen))
+ var/t = copytext(stripped_input(user, "Enter the name for the filter.", "Rename", name), 1, MAX_NAME_LEN)
+ if(!t)
+ return
+ if(!in_range(src, usr) && loc != usr)
+ return
+ name = t
+ return
+ else
+ return ..()
diff --git a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm
index 19849582a0f..6128c1afa33 100644
--- a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm
+++ b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm
@@ -1,233 +1,233 @@
-/obj/machinery/atmospherics/trinary/mixer
- icon = 'icons/atmos/mixer.dmi'
- icon_state = "map"
-
- can_unwrench = 1
-
- name = "gas mixer"
-
- var/target_pressure = ONE_ATMOSPHERE
- var/node1_concentration = 0.5
- var/node2_concentration = 0.5
-
- //node 3 is the outlet, nodes 1 & 2 are intakes
-
-/obj/machinery/atmospherics/trinary/mixer/CtrlClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
- to_chat(user, "You can't do that right now!")
- return
- if(!in_range(src, user) && !issilicon(usr))
- return
- if(!ishuman(usr) && !issilicon(usr))
- return
- toggle()
- return ..()
-
-/obj/machinery/atmospherics/trinary/mixer/AICtrlClick()
- toggle()
- return ..()
-
-/obj/machinery/atmospherics/trinary/mixer/AltClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
- to_chat(user, "You can't do that right now!")
- return
- if(!in_range(src, user) && !issilicon(usr))
- return
- if(!ishuman(usr) && !issilicon(usr))
- return
- set_max()
- return
-
-/obj/machinery/atmospherics/trinary/mixer/AIAltClick()
- set_max()
- return ..()
-
-/obj/machinery/atmospherics/trinary/mixer/flipped
- icon_state = "mmap"
- flipped = 1
-
-/obj/machinery/atmospherics/trinary/mixer/proc/toggle()
- if(powered())
- on = !on
- update_icon()
-
-/obj/machinery/atmospherics/trinary/mixer/proc/set_max()
- if(powered())
- target_pressure = MAX_OUTPUT_PRESSURE
- update_icon()
-
-/obj/machinery/atmospherics/trinary/mixer/update_icon(safety = 0)
- ..()
-
- if(flipped)
- icon_state = "m"
- else
- icon_state = ""
-
- if(!powered())
- icon_state += "off"
- else if(node2 && node3 && node1)
- icon_state += on ? "on" : "off"
- else
- icon_state += "off"
- on = 0
-
-/obj/machinery/atmospherics/trinary/mixer/update_underlays()
- if(..())
- underlays.Cut()
- var/turf/T = get_turf(src)
- if(!istype(T))
- return
-
- add_underlay(T, node1, turn(dir, -180))
-
- if(flipped)
- add_underlay(T, node2, turn(dir, 90))
- else
- add_underlay(T, node2, turn(dir, -90))
-
- add_underlay(T, node3, dir)
-
-/obj/machinery/atmospherics/trinary/mixer/power_change()
- var/old_stat = stat
- ..()
- if(old_stat != stat)
- update_icon()
-
-/obj/machinery/atmospherics/trinary/mixer/New()
- ..()
- air3.volume = 300
-
-/obj/machinery/atmospherics/trinary/mixer/process_atmos()
- ..()
- if(!on)
- return 0
-
- var/output_starting_pressure = air3.return_pressure()
-
- if(output_starting_pressure >= target_pressure)
- //No need to mix if target is already full!
- return 1
-
- //Calculate necessary moles to transfer using PV=nRT
-
- var/pressure_delta = target_pressure - output_starting_pressure
- var/transfer_moles1 = 0
- var/transfer_moles2 = 0
-
- if(air1.temperature > 0)
- transfer_moles1 = (node1_concentration*pressure_delta)*air3.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
-
- if(air2.temperature > 0)
- transfer_moles2 = (node2_concentration*pressure_delta)*air3.volume/(air2.temperature * R_IDEAL_GAS_EQUATION)
-
- var/air1_moles = air1.total_moles()
- var/air2_moles = air2.total_moles()
-
- if((air1_moles < transfer_moles1) || (air2_moles < transfer_moles2))
- if(!transfer_moles1 || !transfer_moles2) return
- var/ratio = min(air1_moles/transfer_moles1, air2_moles/transfer_moles2)
-
- transfer_moles1 *= ratio
- transfer_moles2 *= ratio
-
- //Actually transfer the gas
-
- if(transfer_moles1 > 0)
- var/datum/gas_mixture/removed1 = air1.remove(transfer_moles1)
- air3.merge(removed1)
-
- if(transfer_moles2 > 0)
- var/datum/gas_mixture/removed2 = air2.remove(transfer_moles2)
- air3.merge(removed2)
-
- if(transfer_moles1)
- parent1.update = 1
-
- if(transfer_moles2)
- parent2.update = 1
-
- parent3.update = 1
-
- return 1
-
-/obj/machinery/atmospherics/trinary/mixer/attack_ghost(mob/user)
- ui_interact(user)
-
-/obj/machinery/atmospherics/trinary/mixer/attack_hand(mob/user)
- if(..())
- return
-
- if(!allowed(user))
- to_chat(user, "Access denied.")
- return
-
- add_fingerprint(user)
- ui_interact(user)
-
-/obj/machinery/atmospherics/trinary/mixer/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = default_state)
- user.set_machine(src)
- ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
- if(!ui)
- ui = new(user, src, ui_key, "atmos_mixer.tmpl", name, 370, 165, state = state)
- ui.open()
-
-/obj/machinery/atmospherics/trinary/mixer/ui_data(mob/user)
- var/list/data = list()
- data["on"] = on
- data["pressure"] = round(target_pressure)
- data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
- data["node1_concentration"] = round(node1_concentration*100)
- data["node2_concentration"] = round(node2_concentration*100)
- return data
-
-/obj/machinery/atmospherics/trinary/mixer/Topic(href,href_list)
- if(..())
- return 1
-
- if(href_list["power"])
- on = !on
- investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
- . = TRUE
- if(href_list["pressure"])
- var/pressure = href_list["pressure"]
- if(pressure == "max")
- pressure = MAX_OUTPUT_PRESSURE
- . = TRUE
- else if(pressure == "input")
- pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null
- if(!isnull(pressure) && !..())
- . = TRUE
- else if(text2num(pressure) != null)
- pressure = text2num(pressure)
- . = TRUE
- if(.)
- target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
- investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
- if(href_list["node1"])
- var/value = text2num(href_list["node1"])
- node1_concentration = max(0, min(1, node1_concentration + value))
- node2_concentration = max(0, min(1, node2_concentration - value))
- investigate_log("was set to [node1_concentration] % on node 1 by [key_name(usr)]", "atmos")
- . = TRUE
- if(href_list["node2"])
- var/value = text2num(href_list["node2"])
- node2_concentration = max(0, min(1, node2_concentration + value))
- node1_concentration = max(0, min(1, node1_concentration - value))
- investigate_log("was set to [node2_concentration] % on node 2 by [key_name(usr)]", "atmos")
- . = TRUE
-
- update_icon()
- SSnanoui.update_uis(src)
-
-/obj/machinery/atmospherics/trinary/mixer/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/pen))
- var/t = copytext(stripped_input(user, "Enter the name for the mixer.", "Rename", name), 1, MAX_NAME_LEN)
- if(!t)
- return
- if(!in_range(src, usr) && loc != usr)
- return
- name = t
- return
- else
- return ..()
\ No newline at end of file
+/obj/machinery/atmospherics/trinary/mixer
+ icon = 'icons/atmos/mixer.dmi'
+ icon_state = "map"
+
+ can_unwrench = 1
+
+ name = "gas mixer"
+
+ var/target_pressure = ONE_ATMOSPHERE
+ var/node1_concentration = 0.5
+ var/node2_concentration = 0.5
+
+ //node 3 is the outlet, nodes 1 & 2 are intakes
+
+/obj/machinery/atmospherics/trinary/mixer/CtrlClick(mob/living/user)
+ if(!istype(user) || user.incapacitated())
+ to_chat(user, "You can't do that right now!")
+ return
+ if(!in_range(src, user) && !issilicon(usr))
+ return
+ if(!ishuman(usr) && !issilicon(usr))
+ return
+ toggle()
+ return ..()
+
+/obj/machinery/atmospherics/trinary/mixer/AICtrlClick()
+ toggle()
+ return ..()
+
+/obj/machinery/atmospherics/trinary/mixer/AltClick(mob/living/user)
+ if(!istype(user) || user.incapacitated())
+ to_chat(user, "You can't do that right now!")
+ return
+ if(!in_range(src, user) && !issilicon(usr))
+ return
+ if(!ishuman(usr) && !issilicon(usr))
+ return
+ set_max()
+ return
+
+/obj/machinery/atmospherics/trinary/mixer/AIAltClick()
+ set_max()
+ return ..()
+
+/obj/machinery/atmospherics/trinary/mixer/flipped
+ icon_state = "mmap"
+ flipped = 1
+
+/obj/machinery/atmospherics/trinary/mixer/proc/toggle()
+ if(powered())
+ on = !on
+ update_icon()
+
+/obj/machinery/atmospherics/trinary/mixer/proc/set_max()
+ if(powered())
+ target_pressure = MAX_OUTPUT_PRESSURE
+ update_icon()
+
+/obj/machinery/atmospherics/trinary/mixer/update_icon(safety = 0)
+ ..()
+
+ if(flipped)
+ icon_state = "m"
+ else
+ icon_state = ""
+
+ if(!powered())
+ icon_state += "off"
+ else if(node2 && node3 && node1)
+ icon_state += on ? "on" : "off"
+ else
+ icon_state += "off"
+ on = 0
+
+/obj/machinery/atmospherics/trinary/mixer/update_underlays()
+ if(..())
+ underlays.Cut()
+ var/turf/T = get_turf(src)
+ if(!istype(T))
+ return
+
+ add_underlay(T, node1, turn(dir, -180))
+
+ if(flipped)
+ add_underlay(T, node2, turn(dir, 90))
+ else
+ add_underlay(T, node2, turn(dir, -90))
+
+ add_underlay(T, node3, dir)
+
+/obj/machinery/atmospherics/trinary/mixer/power_change()
+ var/old_stat = stat
+ ..()
+ if(old_stat != stat)
+ update_icon()
+
+/obj/machinery/atmospherics/trinary/mixer/New()
+ ..()
+ air3.volume = 300
+
+/obj/machinery/atmospherics/trinary/mixer/process_atmos()
+ ..()
+ if(!on)
+ return 0
+
+ var/output_starting_pressure = air3.return_pressure()
+
+ if(output_starting_pressure >= target_pressure)
+ //No need to mix if target is already full!
+ return 1
+
+ //Calculate necessary moles to transfer using PV=nRT
+
+ var/pressure_delta = target_pressure - output_starting_pressure
+ var/transfer_moles1 = 0
+ var/transfer_moles2 = 0
+
+ if(air1.temperature > 0)
+ transfer_moles1 = (node1_concentration*pressure_delta)*air3.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
+
+ if(air2.temperature > 0)
+ transfer_moles2 = (node2_concentration*pressure_delta)*air3.volume/(air2.temperature * R_IDEAL_GAS_EQUATION)
+
+ var/air1_moles = air1.total_moles()
+ var/air2_moles = air2.total_moles()
+
+ if((air1_moles < transfer_moles1) || (air2_moles < transfer_moles2))
+ if(!transfer_moles1 || !transfer_moles2) return
+ var/ratio = min(air1_moles/transfer_moles1, air2_moles/transfer_moles2)
+
+ transfer_moles1 *= ratio
+ transfer_moles2 *= ratio
+
+ //Actually transfer the gas
+
+ if(transfer_moles1 > 0)
+ var/datum/gas_mixture/removed1 = air1.remove(transfer_moles1)
+ air3.merge(removed1)
+
+ if(transfer_moles2 > 0)
+ var/datum/gas_mixture/removed2 = air2.remove(transfer_moles2)
+ air3.merge(removed2)
+
+ if(transfer_moles1)
+ parent1.update = 1
+
+ if(transfer_moles2)
+ parent2.update = 1
+
+ parent3.update = 1
+
+ return 1
+
+/obj/machinery/atmospherics/trinary/mixer/attack_ghost(mob/user)
+ ui_interact(user)
+
+/obj/machinery/atmospherics/trinary/mixer/attack_hand(mob/user)
+ if(..())
+ return
+
+ if(!allowed(user))
+ to_chat(user, "Access denied.")
+ return
+
+ add_fingerprint(user)
+ ui_interact(user)
+
+/obj/machinery/atmospherics/trinary/mixer/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = GLOB.default_state)
+ user.set_machine(src)
+ ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
+ if(!ui)
+ ui = new(user, src, ui_key, "atmos_mixer.tmpl", name, 370, 165, state = state)
+ ui.open()
+
+/obj/machinery/atmospherics/trinary/mixer/ui_data(mob/user)
+ var/list/data = list()
+ data["on"] = on
+ data["pressure"] = round(target_pressure)
+ data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
+ data["node1_concentration"] = round(node1_concentration*100)
+ data["node2_concentration"] = round(node2_concentration*100)
+ return data
+
+/obj/machinery/atmospherics/trinary/mixer/Topic(href,href_list)
+ if(..())
+ return 1
+
+ if(href_list["power"])
+ on = !on
+ investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
+ . = TRUE
+ if(href_list["pressure"])
+ var/pressure = href_list["pressure"]
+ if(pressure == "max")
+ pressure = MAX_OUTPUT_PRESSURE
+ . = TRUE
+ else if(pressure == "input")
+ pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null
+ if(!isnull(pressure) && !..())
+ . = TRUE
+ else if(text2num(pressure) != null)
+ pressure = text2num(pressure)
+ . = TRUE
+ if(.)
+ target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
+ investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
+ if(href_list["node1"])
+ var/value = text2num(href_list["node1"])
+ node1_concentration = max(0, min(1, node1_concentration + value))
+ node2_concentration = max(0, min(1, node2_concentration - value))
+ investigate_log("was set to [node1_concentration] % on node 1 by [key_name(usr)]", "atmos")
+ . = TRUE
+ if(href_list["node2"])
+ var/value = text2num(href_list["node2"])
+ node2_concentration = max(0, min(1, node2_concentration + value))
+ node1_concentration = max(0, min(1, node1_concentration - value))
+ investigate_log("was set to [node2_concentration] % on node 2 by [key_name(usr)]", "atmos")
+ . = TRUE
+
+ update_icon()
+ SSnanoui.update_uis(src)
+
+/obj/machinery/atmospherics/trinary/mixer/attackby(obj/item/W, mob/user, params)
+ if(istype(W, /obj/item/pen))
+ var/t = copytext(stripped_input(user, "Enter the name for the mixer.", "Rename", name), 1, MAX_NAME_LEN)
+ if(!t)
+ return
+ if(!in_range(src, usr) && loc != usr)
+ return
+ name = t
+ return
+ else
+ return ..()
diff --git a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm
index 8087db9966e..79fae0f7d88 100644
--- a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm
+++ b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm
@@ -1,213 +1,213 @@
-/obj/machinery/atmospherics/trinary
- dir = SOUTH
- initialize_directions = SOUTH|NORTH|WEST
- use_power = IDLE_POWER_USE
-
- var/on = 0
- layer = GAS_FILTER_LAYER
-
- var/datum/gas_mixture/air1
- var/datum/gas_mixture/air2
- var/datum/gas_mixture/air3
-
- var/obj/machinery/atmospherics/node1
- var/obj/machinery/atmospherics/node2
- var/obj/machinery/atmospherics/node3
-
- var/datum/pipeline/parent1
- var/datum/pipeline/parent2
- var/datum/pipeline/parent3
-
- var/flipped = 0
-
-/obj/machinery/atmospherics/trinary/New()
- ..()
-
- if(!flipped)
- switch(dir)
- if(NORTH)
- initialize_directions = EAST|NORTH|SOUTH
- if(SOUTH)
- initialize_directions = SOUTH|WEST|NORTH
- if(EAST)
- initialize_directions = EAST|WEST|SOUTH
- if(WEST)
- initialize_directions = WEST|NORTH|EAST
- else
- switch(dir)
- if(NORTH)
- initialize_directions = SOUTH|NORTH|WEST
- if(SOUTH)
- initialize_directions = NORTH|SOUTH|EAST
- if(EAST)
- initialize_directions = WEST|EAST|NORTH
- if(WEST)
- initialize_directions = EAST|WEST|SOUTH
-
- air1 = new
- air2 = new
- air3 = new
-
- air1.volume = 200
- air2.volume = 200
- air3.volume = 200
-
-/obj/machinery/atmospherics/trinary/Destroy()
- if(node1)
- node1.disconnect(src)
- node1 = null
- nullifyPipenet(parent1)
- if(node2)
- node2.disconnect(src)
- node2 = null
- nullifyPipenet(parent2)
- if(node3)
- node3.disconnect(src)
- node3 = null
- nullifyPipenet(parent3)
- return ..()
-
-/obj/machinery/atmospherics/trinary/atmos_init()
- ..()
- //Mixer:
- //1 and 2 is input
- //Node 3 is output
- //If we flip the mixer, 1 and 3 shall exchange positions
-
- //Filter:
- //Node 1 is input
- //Node 2 is filtered output
- //Node 3 is rest output
- //If we flip the filter, 1 and 3 shall exchange positions
-
- var/node1_connect = turn(dir, -180)
- var/node2_connect = turn(dir, -90)
- var/node3_connect = dir
-
- if(flipped)
- node2_connect = turn(node2_connect, -180)
-
- for(var/obj/machinery/atmospherics/target in get_step(src,node1_connect))
- if(target.initialize_directions & get_dir(target,src))
- node1 = target
- break
-
- for(var/obj/machinery/atmospherics/target in get_step(src,node2_connect))
- if(target.initialize_directions & get_dir(target,src))
- node2 = target
- break
-
- for(var/obj/machinery/atmospherics/target in get_step(src,node3_connect))
- if(target.initialize_directions & get_dir(target,src))
- node3 = target
- break
-
- update_icon()
- update_underlays()
-
-/obj/machinery/atmospherics/trinary/build_network(remove_deferral = FALSE)
- if(!parent1)
- parent1 = new /datum/pipeline()
- parent1.build_pipeline(src)
-
- if(!parent2)
- parent2 = new /datum/pipeline()
- parent2.build_pipeline(src)
-
- if(!parent3)
- parent3 = new /datum/pipeline()
- parent3.build_pipeline(src)
- ..()
-
-/obj/machinery/atmospherics/trinary/disconnect(obj/machinery/atmospherics/reference)
- if(reference == node1)
- if(istype(node1, /obj/machinery/atmospherics/pipe))
- qdel(parent1)
- node1 = null
- else if(reference == node2)
- if(istype(node2, /obj/machinery/atmospherics/pipe))
- qdel(parent2)
- node2 = null
- else if(reference == node3)
- if(istype(node3, /obj/machinery/atmospherics/pipe))
- qdel(parent3)
- node3 = null
- update_icon()
-
-/obj/machinery/atmospherics/trinary/nullifyPipenet(datum/pipeline/P)
- ..()
- if(!P)
- return
- if(P == parent1)
- parent1.other_airs -= air1
- parent1 = null
- else if(P == parent2)
- parent2.other_airs -= air2
- parent2 = null
- else if(P == parent3)
- parent3.other_airs -= air3
- parent3 = null
-
-/obj/machinery/atmospherics/trinary/returnPipenetAir(datum/pipeline/P)
- if(P == parent1)
- return air1
- else if(P == parent2)
- return air2
- else if(P == parent3)
- return air3
-
-/obj/machinery/atmospherics/trinary/pipeline_expansion(datum/pipeline/P)
- if(P)
- if(parent1 == P)
- return list(node1)
- else if(parent2 == P)
- return list(node2)
- else if(parent3 == P)
- return list(node3)
- return list(node1, node2, node3)
-
-/obj/machinery/atmospherics/trinary/setPipenet(datum/pipeline/P, obj/machinery/atmospherics/A)
- if(A == node1)
- parent1 = P
- else if(A == node2)
- parent2 = P
- else if(A == node3)
- parent3 = P
-
-/obj/machinery/atmospherics/trinary/returnPipenet(obj/machinery/atmospherics/A)
- if(A == node1)
- return parent1
- else if(A == node2)
- return parent2
- else if(A == node3)
- return parent3
-
-/obj/machinery/atmospherics/trinary/replacePipenet(datum/pipeline/Old, datum/pipeline/New)
- if(Old == parent1)
- parent1 = New
- else if(Old == parent2)
- parent2 = New
- else if(Old == parent3)
- parent3 = New
-
-/obj/machinery/atmospherics/trinary/unsafe_pressure_release(var/mob/user,var/pressures)
- ..()
-
- var/turf/T = get_turf(src)
- if(T)
- //Remove the gas from air1+air2+air3 and assume it
- var/datum/gas_mixture/environment = T.return_air()
- var/lost = pressures*environment.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
- lost += pressures*environment.volume/(air2.temperature * R_IDEAL_GAS_EQUATION)
- lost += pressures*environment.volume/(air3.temperature * R_IDEAL_GAS_EQUATION)
- var/shared_loss = lost/3
-
- var/datum/gas_mixture/to_release = air1.remove(shared_loss)
- to_release.merge(air2.remove(shared_loss))
- to_release.merge(air3.remove(shared_loss))
- T.assume_air(to_release)
- air_update_turf(1)
-
-/obj/machinery/atmospherics/trinary/process_atmos()
- ..()
- return parent1 && parent2 && parent3
+/obj/machinery/atmospherics/trinary
+ dir = SOUTH
+ initialize_directions = SOUTH|NORTH|WEST
+ use_power = IDLE_POWER_USE
+
+ var/on = 0
+ layer = GAS_FILTER_LAYER
+
+ var/datum/gas_mixture/air1
+ var/datum/gas_mixture/air2
+ var/datum/gas_mixture/air3
+
+ var/obj/machinery/atmospherics/node1
+ var/obj/machinery/atmospherics/node2
+ var/obj/machinery/atmospherics/node3
+
+ var/datum/pipeline/parent1
+ var/datum/pipeline/parent2
+ var/datum/pipeline/parent3
+
+ var/flipped = 0
+
+/obj/machinery/atmospherics/trinary/New()
+ ..()
+
+ if(!flipped)
+ switch(dir)
+ if(NORTH)
+ initialize_directions = EAST|NORTH|SOUTH
+ if(SOUTH)
+ initialize_directions = SOUTH|WEST|NORTH
+ if(EAST)
+ initialize_directions = EAST|WEST|SOUTH
+ if(WEST)
+ initialize_directions = WEST|NORTH|EAST
+ else
+ switch(dir)
+ if(NORTH)
+ initialize_directions = SOUTH|NORTH|WEST
+ if(SOUTH)
+ initialize_directions = NORTH|SOUTH|EAST
+ if(EAST)
+ initialize_directions = WEST|EAST|NORTH
+ if(WEST)
+ initialize_directions = EAST|WEST|SOUTH
+
+ air1 = new
+ air2 = new
+ air3 = new
+
+ air1.volume = 200
+ air2.volume = 200
+ air3.volume = 200
+
+/obj/machinery/atmospherics/trinary/Destroy()
+ if(node1)
+ node1.disconnect(src)
+ node1 = null
+ nullifyPipenet(parent1)
+ if(node2)
+ node2.disconnect(src)
+ node2 = null
+ nullifyPipenet(parent2)
+ if(node3)
+ node3.disconnect(src)
+ node3 = null
+ nullifyPipenet(parent3)
+ return ..()
+
+/obj/machinery/atmospherics/trinary/atmos_init()
+ ..()
+ //Mixer:
+ //1 and 2 is input
+ //Node 3 is output
+ //If we flip the mixer, 1 and 3 shall exchange positions
+
+ //Filter:
+ //Node 1 is input
+ //Node 2 is filtered output
+ //Node 3 is rest output
+ //If we flip the filter, 1 and 3 shall exchange positions
+
+ var/node1_connect = turn(dir, -180)
+ var/node2_connect = turn(dir, -90)
+ var/node3_connect = dir
+
+ if(flipped)
+ node2_connect = turn(node2_connect, -180)
+
+ for(var/obj/machinery/atmospherics/target in get_step(src,node1_connect))
+ if(target.initialize_directions & get_dir(target,src))
+ node1 = target
+ break
+
+ for(var/obj/machinery/atmospherics/target in get_step(src,node2_connect))
+ if(target.initialize_directions & get_dir(target,src))
+ node2 = target
+ break
+
+ for(var/obj/machinery/atmospherics/target in get_step(src,node3_connect))
+ if(target.initialize_directions & get_dir(target,src))
+ node3 = target
+ break
+
+ update_icon()
+ update_underlays()
+
+/obj/machinery/atmospherics/trinary/build_network(remove_deferral = FALSE)
+ if(!parent1)
+ parent1 = new /datum/pipeline()
+ parent1.build_pipeline(src)
+
+ if(!parent2)
+ parent2 = new /datum/pipeline()
+ parent2.build_pipeline(src)
+
+ if(!parent3)
+ parent3 = new /datum/pipeline()
+ parent3.build_pipeline(src)
+ ..()
+
+/obj/machinery/atmospherics/trinary/disconnect(obj/machinery/atmospherics/reference)
+ if(reference == node1)
+ if(istype(node1, /obj/machinery/atmospherics/pipe))
+ qdel(parent1)
+ node1 = null
+ else if(reference == node2)
+ if(istype(node2, /obj/machinery/atmospherics/pipe))
+ qdel(parent2)
+ node2 = null
+ else if(reference == node3)
+ if(istype(node3, /obj/machinery/atmospherics/pipe))
+ qdel(parent3)
+ node3 = null
+ update_icon()
+
+/obj/machinery/atmospherics/trinary/nullifyPipenet(datum/pipeline/P)
+ ..()
+ if(!P)
+ return
+ if(P == parent1)
+ parent1.other_airs -= air1
+ parent1 = null
+ else if(P == parent2)
+ parent2.other_airs -= air2
+ parent2 = null
+ else if(P == parent3)
+ parent3.other_airs -= air3
+ parent3 = null
+
+/obj/machinery/atmospherics/trinary/returnPipenetAir(datum/pipeline/P)
+ if(P == parent1)
+ return air1
+ else if(P == parent2)
+ return air2
+ else if(P == parent3)
+ return air3
+
+/obj/machinery/atmospherics/trinary/pipeline_expansion(datum/pipeline/P)
+ if(P)
+ if(parent1 == P)
+ return list(node1)
+ else if(parent2 == P)
+ return list(node2)
+ else if(parent3 == P)
+ return list(node3)
+ return list(node1, node2, node3)
+
+/obj/machinery/atmospherics/trinary/setPipenet(datum/pipeline/P, obj/machinery/atmospherics/A)
+ if(A == node1)
+ parent1 = P
+ else if(A == node2)
+ parent2 = P
+ else if(A == node3)
+ parent3 = P
+
+/obj/machinery/atmospherics/trinary/returnPipenet(obj/machinery/atmospherics/A)
+ if(A == node1)
+ return parent1
+ else if(A == node2)
+ return parent2
+ else if(A == node3)
+ return parent3
+
+/obj/machinery/atmospherics/trinary/replacePipenet(datum/pipeline/Old, datum/pipeline/New)
+ if(Old == parent1)
+ parent1 = New
+ else if(Old == parent2)
+ parent2 = New
+ else if(Old == parent3)
+ parent3 = New
+
+/obj/machinery/atmospherics/trinary/unsafe_pressure_release(var/mob/user,var/pressures)
+ ..()
+
+ var/turf/T = get_turf(src)
+ if(T)
+ //Remove the gas from air1+air2+air3 and assume it
+ var/datum/gas_mixture/environment = T.return_air()
+ var/lost = pressures*environment.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
+ lost += pressures*environment.volume/(air2.temperature * R_IDEAL_GAS_EQUATION)
+ lost += pressures*environment.volume/(air3.temperature * R_IDEAL_GAS_EQUATION)
+ var/shared_loss = lost/3
+
+ var/datum/gas_mixture/to_release = air1.remove(shared_loss)
+ to_release.merge(air2.remove(shared_loss))
+ to_release.merge(air3.remove(shared_loss))
+ T.assume_air(to_release)
+ air_update_turf(1)
+
+/obj/machinery/atmospherics/trinary/process_atmos()
+ ..()
+ return parent1 && parent2 && parent3
diff --git a/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm b/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm
index 7b3f8299339..31039a412d5 100644
--- a/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm
+++ b/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm
@@ -177,4 +177,4 @@
switch_side()
#undef TVALVE_STATE_STRAIGHT
-#undef TVALVE_STATE_SIDE
\ No newline at end of file
+#undef TVALVE_STATE_SIDE
diff --git a/code/ATMOSPHERICS/components/unary_devices/oxygen_generator.dm b/code/ATMOSPHERICS/components/unary_devices/oxygen_generator.dm
index a9c3b98ad74..9b06019e49e 100644
--- a/code/ATMOSPHERICS/components/unary_devices/oxygen_generator.dm
+++ b/code/ATMOSPHERICS/components/unary_devices/oxygen_generator.dm
@@ -45,4 +45,4 @@
parent.update = 1
- return 1
\ No newline at end of file
+ return 1
diff --git a/code/ATMOSPHERICS/components/unary_devices/tank.dm b/code/ATMOSPHERICS/components/unary_devices/tank.dm
index cb82417033b..11a752b9030 100644
--- a/code/ATMOSPHERICS/components/unary_devices/tank.dm
+++ b/code/ATMOSPHERICS/components/unary_devices/tank.dm
@@ -110,4 +110,4 @@
var/datum/gas/oxygen_agent_b/trace_gas = new
trace_gas.moles = (50 * ONE_ATMOSPHERE) * (air_contents.volume) / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
- air_contents.trace_gases += trace_gas
\ No newline at end of file
+ air_contents.trace_gases += trace_gas
diff --git a/code/ATMOSPHERICS/components/unary_devices/thermal_plate.dm b/code/ATMOSPHERICS/components/unary_devices/thermal_plate.dm
index 5a6e76a182b..6cd050de022 100644
--- a/code/ATMOSPHERICS/components/unary_devices/thermal_plate.dm
+++ b/code/ATMOSPHERICS/components/unary_devices/thermal_plate.dm
@@ -77,4 +77,4 @@
parent.update = 1
- return 1
\ No newline at end of file
+ return 1
diff --git a/code/ATMOSPHERICS/components/unary_devices/unary_base.dm b/code/ATMOSPHERICS/components/unary_devices/unary_base.dm
index 4ef7743fc8c..14c93dd0490 100644
--- a/code/ATMOSPHERICS/components/unary_devices/unary_base.dm
+++ b/code/ATMOSPHERICS/components/unary_devices/unary_base.dm
@@ -102,4 +102,4 @@
/obj/machinery/atmospherics/unary/process_atmos()
..()
- return parent
\ No newline at end of file
+ return parent
diff --git a/code/ATMOSPHERICS/datum_icon_manager.dm b/code/ATMOSPHERICS/datum_icon_manager.dm
index 75cb0fce8ce..2286b3523a0 100644
--- a/code/ATMOSPHERICS/datum_icon_manager.dm
+++ b/code/ATMOSPHERICS/datum_icon_manager.dm
@@ -6,26 +6,16 @@
// atmospherics devices.
//--------------------------------------------
-#define PIPE_COLOR_GREY "#ffffff" //yes white is grey
-#define PIPE_COLOR_RED "#ff0000"
-#define PIPE_COLOR_BLUE "#0000ff"
-#define PIPE_COLOR_CYAN "#00ffff"
-#define PIPE_COLOR_GREEN "#00ff00"
-#define PIPE_COLOR_YELLOW "#ffcc00"
-#define PIPE_COLOR_PURPLE "#5c1ec0"
-
-var/global/list/pipe_colors = list("grey" = PIPE_COLOR_GREY, "red" = PIPE_COLOR_RED, "blue" = PIPE_COLOR_BLUE, "cyan" = PIPE_COLOR_CYAN, "green" = PIPE_COLOR_GREEN, "yellow" = PIPE_COLOR_YELLOW, "purple" = PIPE_COLOR_PURPLE)
-
/proc/pipe_color_lookup(var/color)
- for(var/C in pipe_colors)
- if(color == pipe_colors[C])
+ for(var/C in GLOB.pipe_colors)
+ if(color == GLOB.pipe_colors[C])
return "[C]"
/proc/pipe_color_check(var/color)
if(!color)
return 1
- for(var/C in pipe_colors)
- if(color == pipe_colors[C])
+ for(var/C in GLOB.pipe_colors)
+ if(color == GLOB.pipe_colors[C])
return 1
return 0
@@ -105,10 +95,10 @@ var/global/list/pipe_colors = list("grey" = PIPE_COLOR_GREY, "red" = PIPE_COLOR_
var/image/I = image('icons/atmos/pipes.dmi', icon_state = state)
pipe_icons[cache_name] = I
- for(var/pipe_color in pipe_colors)
+ for(var/pipe_color in GLOB.pipe_colors)
I = image('icons/atmos/pipes.dmi', icon_state = state)
- I.color = pipe_colors[pipe_color]
- pipe_icons[state + "[pipe_colors[pipe_color]]"] = I
+ I.color = GLOB.pipe_colors[pipe_color]
+ pipe_icons[state + "[GLOB.pipe_colors[pipe_color]]"] = I
pipe = new ('icons/atmos/heat.dmi')
for(var/state in pipe.IconStates())
@@ -137,10 +127,10 @@ var/global/list/pipe_colors = list("grey" = PIPE_COLOR_GREY, "red" = PIPE_COLOR_
if(findtext(state, "core") || findtext(state, "4way"))
var/image/I = image('icons/atmos/manifold.dmi', icon_state = state)
manifold_icons[state] = I
- for(var/pipe_color in pipe_colors)
+ for(var/pipe_color in GLOB.pipe_colors)
I = image('icons/atmos/manifold.dmi', icon_state = state)
- I.color = pipe_colors[pipe_color]
- manifold_icons[state + pipe_colors[pipe_color]] = I
+ I.color = GLOB.pipe_colors[pipe_color]
+ manifold_icons[state + GLOB.pipe_colors[pipe_color]] = I
/datum/pipe_icon_manager/proc/gen_device_icons()
if(!device_icons)
@@ -185,10 +175,10 @@ var/global/list/pipe_colors = list("grey" = PIPE_COLOR_GREY, "red" = PIPE_COLOR_
var/cache_name = state
- for(var/D in cardinal)
+ for(var/D in GLOB.cardinal)
var/image/I = image(icon('icons/atmos/pipe_underlays.dmi', icon_state = state, dir = D))
underlays[cache_name + "[D]"] = I
- for(var/pipe_color in pipe_colors)
+ for(var/pipe_color in GLOB.pipe_colors)
I = image(icon('icons/atmos/pipe_underlays.dmi', icon_state = state, dir = D))
- I.color = pipe_colors[pipe_color]
- underlays[state + "[D]" + "[pipe_colors[pipe_color]]"] = I
+ I.color = GLOB.pipe_colors[pipe_color]
+ underlays[state + "[D]" + "[GLOB.pipe_colors[pipe_color]]"] = I
diff --git a/code/ATMOSPHERICS/datum_pipeline.dm b/code/ATMOSPHERICS/datum_pipeline.dm
index 43082c38ded..2cf3edfb275 100644
--- a/code/ATMOSPHERICS/datum_pipeline.dm
+++ b/code/ATMOSPHERICS/datum_pipeline.dm
@@ -1,276 +1,276 @@
-/datum/pipeline
- var/datum/gas_mixture/air
- var/list/datum/gas_mixture/other_airs = list()
-
- var/list/obj/machinery/atmospherics/pipe/members = list()
- var/list/obj/machinery/atmospherics/other_atmosmch = list()
-
- var/update = 1
-
- var/alert_pressure = 0
-
-/datum/pipeline/New()
- SSair.networks += src
-
-/datum/pipeline/Destroy()
- SSair.networks -= src
- if(air && air.volume)
- temporarily_store_air()
- for(var/obj/machinery/atmospherics/pipe/P in members)
- P.parent = null
- for(var/obj/machinery/atmospherics/A in other_atmosmch)
- A.nullifyPipenet(src)
- return ..()
-
-/datum/pipeline/process()//This use to be called called from the pipe networks
- if(update)
- update = 0
- reconcile_air()
- return
-
-var/pipenetwarnings = 10
-
-/datum/pipeline/proc/build_pipeline(obj/machinery/atmospherics/base)
- var/volume = 0
- if(istype(base, /obj/machinery/atmospherics/pipe))
- var/obj/machinery/atmospherics/pipe/E = base
- volume = E.volume
- alert_pressure = E.alert_pressure
- members += E
- if(E.air_temporary)
- air = E.air_temporary
- E.air_temporary = null
- else
- addMachineryMember(base)
- if(!air)
- air = new
- var/list/possible_expansions = list(base)
- while(possible_expansions.len>0)
- for(var/obj/machinery/atmospherics/borderline in possible_expansions)
-
- var/list/result = borderline.pipeline_expansion(src)
-
- if(result.len>0)
- for(var/obj/machinery/atmospherics/P in result)
- if(istype(P, /obj/machinery/atmospherics/pipe))
- var/obj/machinery/atmospherics/pipe/item = P
- if(!members.Find(item))
-
- if(item.parent)
- 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
-
- volume += item.volume
- item.parent = src
-
- alert_pressure = min(alert_pressure, item.alert_pressure)
-
- if(item.air_temporary)
- air.merge(item.air_temporary)
- item.air_temporary = null
- else
- P.setPipenet(src, borderline)
- addMachineryMember(P)
-
- possible_expansions -= borderline
-
- air.volume = volume
-
-/datum/pipeline/proc/addMachineryMember(obj/machinery/atmospherics/A)
- other_atmosmch |= A
- var/datum/gas_mixture/G = A.returnPipenetAir(src)
- other_airs |= G
-
-/datum/pipeline/proc/addMember(obj/machinery/atmospherics/A, obj/machinery/atmospherics/N)
- if(istype(A, /obj/machinery/atmospherics/pipe))
- var/obj/machinery/atmospherics/pipe/P = A
- P.parent = src
- var/list/adjacent = P.pipeline_expansion()
- for(var/obj/machinery/atmospherics/pipe/I in adjacent)
- if(I.parent == src)
- continue
- var/datum/pipeline/E = I.parent
- merge(E)
- if(!members.Find(P))
- members += P
- air.volume += P.volume
- else
- A.setPipenet(src, N)
- addMachineryMember(A)
-
-/datum/pipeline/proc/merge(datum/pipeline/E)
- air.volume += E.air.volume
- members.Add(E.members)
- for(var/obj/machinery/atmospherics/pipe/S in E.members)
- S.parent = src
- air.merge(E.air)
- for(var/obj/machinery/atmospherics/A in E.other_atmosmch)
- A.replacePipenet(E, src)
- other_atmosmch.Add(E.other_atmosmch)
- other_airs.Add(E.other_airs)
- E.members.Cut()
- E.other_atmosmch.Cut()
- qdel(E)
-
-/obj/machinery/atmospherics/proc/addMember(obj/machinery/atmospherics/A)
- var/datum/pipeline/P = returnPipenet(A)
- P.addMember(A, src)
-
-/obj/machinery/atmospherics/pipe/addMember(obj/machinery/atmospherics/A)
- parent.addMember(A, src)
-
-/datum/pipeline/proc/temporarily_store_air()
- //Update individual gas_mixtures by volume ratio
-
- for(var/obj/machinery/atmospherics/pipe/member in members)
- member.air_temporary = new
- member.air_temporary.volume = member.volume
-
- member.air_temporary.oxygen = air.oxygen*member.volume/air.volume
- member.air_temporary.nitrogen = air.nitrogen*member.volume/air.volume
- member.air_temporary.toxins = air.toxins*member.volume/air.volume
- member.air_temporary.carbon_dioxide = air.carbon_dioxide*member.volume/air.volume
-
- member.air_temporary.temperature = air.temperature
-
- if(air.trace_gases.len)
- for(var/datum/gas/trace_gas in air.trace_gases)
- var/datum/gas/corresponding = new trace_gas.type()
- member.air_temporary.trace_gases += corresponding
-
- corresponding.moles = trace_gas.moles*member.volume/air.volume
-
-/datum/pipeline/proc/temperature_interact(turf/target, share_volume, thermal_conductivity)
- var/total_heat_capacity = air.heat_capacity()
- var/partial_heat_capacity = total_heat_capacity*(share_volume/air.volume)
-
- if(istype(target, /turf/simulated))
- var/turf/simulated/modeled_location = target
-
- if(modeled_location.blocks_air)
-
- if((modeled_location.heat_capacity>0) && (partial_heat_capacity>0))
- var/delta_temperature = air.temperature - modeled_location.temperature
-
- var/heat = thermal_conductivity*delta_temperature* \
- (partial_heat_capacity*modeled_location.heat_capacity/(partial_heat_capacity+modeled_location.heat_capacity))
-
- air.temperature -= heat/total_heat_capacity
- modeled_location.temperature += heat/modeled_location.heat_capacity
-
- else
- var/delta_temperature = 0
- var/sharer_heat_capacity = 0
-
- delta_temperature = (air.temperature - modeled_location.air.temperature)
- sharer_heat_capacity = modeled_location.air.heat_capacity()
-
- var/self_temperature_delta = 0
- var/sharer_temperature_delta = 0
-
- if((sharer_heat_capacity>0) && (partial_heat_capacity>0))
- var/heat = thermal_conductivity*delta_temperature* \
- (partial_heat_capacity*sharer_heat_capacity/(partial_heat_capacity+sharer_heat_capacity))
-
- self_temperature_delta = -heat/total_heat_capacity
- sharer_temperature_delta = heat/sharer_heat_capacity
- else
- return 1
-
- air.temperature += self_temperature_delta
-
- modeled_location.air.temperature += sharer_temperature_delta
-
-
- else
- if((target.heat_capacity>0) && (partial_heat_capacity>0))
- var/delta_temperature = air.temperature - target.temperature
-
- var/heat = thermal_conductivity*delta_temperature* \
- (partial_heat_capacity*target.heat_capacity/(partial_heat_capacity+target.heat_capacity))
-
- air.temperature -= heat/total_heat_capacity
- update = 1
-
-/datum/pipeline/proc/reconcile_air()
- var/list/datum/gas_mixture/GL = list()
- var/list/datum/pipeline/PL = list()
- PL += src
-
- for(var/i=1;i<=PL.len;i++)
- var/datum/pipeline/P = PL[i]
- if(!P)
- return
- GL += P.air
- GL += P.other_airs
- for(var/obj/machinery/atmospherics/binary/valve/V in P.other_atmosmch)
- if(V.open)
- PL |= V.parent1
- PL |= V.parent2
- for(var/obj/machinery/atmospherics/trinary/tvalve/T in P.other_atmosmch)
- if(!T.state)
- if(src != T.parent2) // otherwise dc'd side connects to both other sides!
- PL |= T.parent1
- PL |= T.parent3
- else
- if(src != T.parent3)
- PL |= T.parent1
- PL |= T.parent2
- for(var/obj/machinery/atmospherics/unary/portables_connector/C in P.other_atmosmch)
- if(C.connected_device)
- GL += C.portableConnectorReturnAir()
-
- var/total_volume = 0
- var/total_thermal_energy = 0
- var/total_heat_capacity = 0
- var/total_oxygen = 0
- var/total_nitrogen = 0
- var/total_toxins = 0
- var/total_carbon_dioxide = 0
- var/list/total_trace_gases = list()
-
- for(var/datum/gas_mixture/G in GL)
- total_volume += G.volume
- total_thermal_energy += G.thermal_energy()
- total_heat_capacity += G.heat_capacity()
-
- total_oxygen += G.oxygen
- total_nitrogen += G.nitrogen
- total_toxins += G.toxins
- total_carbon_dioxide += G.carbon_dioxide
-
- if(G.trace_gases.len)
- for(var/datum/gas/trace_gas in G.trace_gases)
- var/datum/gas/corresponding = locate(trace_gas.type) in total_trace_gases
- if(!corresponding)
- corresponding = new trace_gas.type()
- total_trace_gases += corresponding
-
- corresponding.moles += trace_gas.moles
-
- if(total_volume > 0)
-
- //Calculate temperature
- var/temperature = 0
-
- if(total_heat_capacity > 0)
- temperature = total_thermal_energy/total_heat_capacity
-
- //Update individual gas_mixtures by volume ratio
- for(var/datum/gas_mixture/G in GL)
- G.oxygen = total_oxygen*G.volume/total_volume
- G.nitrogen = total_nitrogen*G.volume/total_volume
- G.toxins = total_toxins*G.volume/total_volume
- G.carbon_dioxide = total_carbon_dioxide*G.volume/total_volume
-
- G.temperature = temperature
-
- if(total_trace_gases.len)
- for(var/datum/gas/trace_gas in total_trace_gases)
- var/datum/gas/corresponding = locate(trace_gas.type) in G.trace_gases
- if(!corresponding)
- corresponding = new trace_gas.type()
- G.trace_gases += corresponding
-
- corresponding.moles = trace_gas.moles*G.volume/total_volume
+/datum/pipeline
+ var/datum/gas_mixture/air
+ var/list/datum/gas_mixture/other_airs = list()
+
+ var/list/obj/machinery/atmospherics/pipe/members = list()
+ var/list/obj/machinery/atmospherics/other_atmosmch = list()
+
+ var/update = 1
+
+ var/alert_pressure = 0
+
+/datum/pipeline/New()
+ SSair.networks += src
+
+/datum/pipeline/Destroy()
+ SSair.networks -= src
+ if(air && air.volume)
+ temporarily_store_air()
+ for(var/obj/machinery/atmospherics/pipe/P in members)
+ P.parent = null
+ for(var/obj/machinery/atmospherics/A in other_atmosmch)
+ A.nullifyPipenet(src)
+ return ..()
+
+/datum/pipeline/process()//This use to be called called from the pipe networks
+ if(update)
+ update = 0
+ reconcile_air()
+ return
+
+GLOBAL_VAR_INIT(pipenetwarnings, 10)
+
+/datum/pipeline/proc/build_pipeline(obj/machinery/atmospherics/base)
+ var/volume = 0
+ if(istype(base, /obj/machinery/atmospherics/pipe))
+ var/obj/machinery/atmospherics/pipe/E = base
+ volume = E.volume
+ alert_pressure = E.alert_pressure
+ members += E
+ if(E.air_temporary)
+ air = E.air_temporary
+ E.air_temporary = null
+ else
+ addMachineryMember(base)
+ if(!air)
+ air = new
+ var/list/possible_expansions = list(base)
+ while(possible_expansions.len>0)
+ for(var/obj/machinery/atmospherics/borderline in possible_expansions)
+
+ var/list/result = borderline.pipeline_expansion(src)
+
+ if(result.len>0)
+ for(var/obj/machinery/atmospherics/P in result)
+ if(istype(P, /obj/machinery/atmospherics/pipe))
+ var/obj/machinery/atmospherics/pipe/item = P
+ if(!members.Find(item))
+
+ if(item.parent)
+ 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
+
+ volume += item.volume
+ item.parent = src
+
+ alert_pressure = min(alert_pressure, item.alert_pressure)
+
+ if(item.air_temporary)
+ air.merge(item.air_temporary)
+ item.air_temporary = null
+ else
+ P.setPipenet(src, borderline)
+ addMachineryMember(P)
+
+ possible_expansions -= borderline
+
+ air.volume = volume
+
+/datum/pipeline/proc/addMachineryMember(obj/machinery/atmospherics/A)
+ other_atmosmch |= A
+ var/datum/gas_mixture/G = A.returnPipenetAir(src)
+ other_airs |= G
+
+/datum/pipeline/proc/addMember(obj/machinery/atmospherics/A, obj/machinery/atmospherics/N)
+ if(istype(A, /obj/machinery/atmospherics/pipe))
+ var/obj/machinery/atmospherics/pipe/P = A
+ P.parent = src
+ var/list/adjacent = P.pipeline_expansion()
+ for(var/obj/machinery/atmospherics/pipe/I in adjacent)
+ if(I.parent == src)
+ continue
+ var/datum/pipeline/E = I.parent
+ merge(E)
+ if(!members.Find(P))
+ members += P
+ air.volume += P.volume
+ else
+ A.setPipenet(src, N)
+ addMachineryMember(A)
+
+/datum/pipeline/proc/merge(datum/pipeline/E)
+ air.volume += E.air.volume
+ members.Add(E.members)
+ for(var/obj/machinery/atmospherics/pipe/S in E.members)
+ S.parent = src
+ air.merge(E.air)
+ for(var/obj/machinery/atmospherics/A in E.other_atmosmch)
+ A.replacePipenet(E, src)
+ other_atmosmch.Add(E.other_atmosmch)
+ other_airs.Add(E.other_airs)
+ E.members.Cut()
+ E.other_atmosmch.Cut()
+ qdel(E)
+
+/obj/machinery/atmospherics/proc/addMember(obj/machinery/atmospherics/A)
+ var/datum/pipeline/P = returnPipenet(A)
+ P.addMember(A, src)
+
+/obj/machinery/atmospherics/pipe/addMember(obj/machinery/atmospherics/A)
+ parent.addMember(A, src)
+
+/datum/pipeline/proc/temporarily_store_air()
+ //Update individual gas_mixtures by volume ratio
+
+ for(var/obj/machinery/atmospherics/pipe/member in members)
+ member.air_temporary = new
+ member.air_temporary.volume = member.volume
+
+ member.air_temporary.oxygen = air.oxygen*member.volume/air.volume
+ member.air_temporary.nitrogen = air.nitrogen*member.volume/air.volume
+ member.air_temporary.toxins = air.toxins*member.volume/air.volume
+ member.air_temporary.carbon_dioxide = air.carbon_dioxide*member.volume/air.volume
+
+ member.air_temporary.temperature = air.temperature
+
+ if(air.trace_gases.len)
+ for(var/datum/gas/trace_gas in air.trace_gases)
+ var/datum/gas/corresponding = new trace_gas.type()
+ member.air_temporary.trace_gases += corresponding
+
+ corresponding.moles = trace_gas.moles*member.volume/air.volume
+
+/datum/pipeline/proc/temperature_interact(turf/target, share_volume, thermal_conductivity)
+ var/total_heat_capacity = air.heat_capacity()
+ var/partial_heat_capacity = total_heat_capacity*(share_volume/air.volume)
+
+ if(istype(target, /turf/simulated))
+ var/turf/simulated/modeled_location = target
+
+ if(modeled_location.blocks_air)
+
+ if((modeled_location.heat_capacity>0) && (partial_heat_capacity>0))
+ var/delta_temperature = air.temperature - modeled_location.temperature
+
+ var/heat = thermal_conductivity*delta_temperature* \
+ (partial_heat_capacity*modeled_location.heat_capacity/(partial_heat_capacity+modeled_location.heat_capacity))
+
+ air.temperature -= heat/total_heat_capacity
+ modeled_location.temperature += heat/modeled_location.heat_capacity
+
+ else
+ var/delta_temperature = 0
+ var/sharer_heat_capacity = 0
+
+ delta_temperature = (air.temperature - modeled_location.air.temperature)
+ sharer_heat_capacity = modeled_location.air.heat_capacity()
+
+ var/self_temperature_delta = 0
+ var/sharer_temperature_delta = 0
+
+ if((sharer_heat_capacity>0) && (partial_heat_capacity>0))
+ var/heat = thermal_conductivity*delta_temperature* \
+ (partial_heat_capacity*sharer_heat_capacity/(partial_heat_capacity+sharer_heat_capacity))
+
+ self_temperature_delta = -heat/total_heat_capacity
+ sharer_temperature_delta = heat/sharer_heat_capacity
+ else
+ return 1
+
+ air.temperature += self_temperature_delta
+
+ modeled_location.air.temperature += sharer_temperature_delta
+
+
+ else
+ if((target.heat_capacity>0) && (partial_heat_capacity>0))
+ var/delta_temperature = air.temperature - target.temperature
+
+ var/heat = thermal_conductivity*delta_temperature* \
+ (partial_heat_capacity*target.heat_capacity/(partial_heat_capacity+target.heat_capacity))
+
+ air.temperature -= heat/total_heat_capacity
+ update = 1
+
+/datum/pipeline/proc/reconcile_air()
+ var/list/datum/gas_mixture/GL = list()
+ var/list/datum/pipeline/PL = list()
+ PL += src
+
+ for(var/i=1;i<=PL.len;i++)
+ var/datum/pipeline/P = PL[i]
+ if(!P)
+ return
+ GL += P.air
+ GL += P.other_airs
+ for(var/obj/machinery/atmospherics/binary/valve/V in P.other_atmosmch)
+ if(V.open)
+ PL |= V.parent1
+ PL |= V.parent2
+ for(var/obj/machinery/atmospherics/trinary/tvalve/T in P.other_atmosmch)
+ if(!T.state)
+ if(src != T.parent2) // otherwise dc'd side connects to both other sides!
+ PL |= T.parent1
+ PL |= T.parent3
+ else
+ if(src != T.parent3)
+ PL |= T.parent1
+ PL |= T.parent2
+ for(var/obj/machinery/atmospherics/unary/portables_connector/C in P.other_atmosmch)
+ if(C.connected_device)
+ GL += C.portableConnectorReturnAir()
+
+ var/total_volume = 0
+ var/total_thermal_energy = 0
+ var/total_heat_capacity = 0
+ var/total_oxygen = 0
+ var/total_nitrogen = 0
+ var/total_toxins = 0
+ var/total_carbon_dioxide = 0
+ var/list/total_trace_gases = list()
+
+ for(var/datum/gas_mixture/G in GL)
+ total_volume += G.volume
+ total_thermal_energy += G.thermal_energy()
+ total_heat_capacity += G.heat_capacity()
+
+ total_oxygen += G.oxygen
+ total_nitrogen += G.nitrogen
+ total_toxins += G.toxins
+ total_carbon_dioxide += G.carbon_dioxide
+
+ if(G.trace_gases.len)
+ for(var/datum/gas/trace_gas in G.trace_gases)
+ var/datum/gas/corresponding = locate(trace_gas.type) in total_trace_gases
+ if(!corresponding)
+ corresponding = new trace_gas.type()
+ total_trace_gases += corresponding
+
+ corresponding.moles += trace_gas.moles
+
+ if(total_volume > 0)
+
+ //Calculate temperature
+ var/temperature = 0
+
+ if(total_heat_capacity > 0)
+ temperature = total_thermal_energy/total_heat_capacity
+
+ //Update individual gas_mixtures by volume ratio
+ for(var/datum/gas_mixture/G in GL)
+ G.oxygen = total_oxygen*G.volume/total_volume
+ G.nitrogen = total_nitrogen*G.volume/total_volume
+ G.toxins = total_toxins*G.volume/total_volume
+ G.carbon_dioxide = total_carbon_dioxide*G.volume/total_volume
+
+ G.temperature = temperature
+
+ if(total_trace_gases.len)
+ for(var/datum/gas/trace_gas in total_trace_gases)
+ var/datum/gas/corresponding = locate(trace_gas.type) in G.trace_gases
+ if(!corresponding)
+ corresponding = new trace_gas.type()
+ G.trace_gases += corresponding
+
+ corresponding.moles = trace_gas.moles*G.volume/total_volume
diff --git a/code/ATMOSPHERICS/pipes/cap.dm b/code/ATMOSPHERICS/pipes/cap.dm
index 8421685d44c..15b53d83e9c 100644
--- a/code/ATMOSPHERICS/pipes/cap.dm
+++ b/code/ATMOSPHERICS/pipes/cap.dm
@@ -123,4 +123,4 @@
connect_types = list(2)
layer = 2.39
icon_connect_type = "-supply"
- color = PIPE_COLOR_BLUE
\ No newline at end of file
+ color = PIPE_COLOR_BLUE
diff --git a/code/ATMOSPHERICS/pipes/manifold.dm b/code/ATMOSPHERICS/pipes/manifold.dm
index 13e35d10c7b..2eef5ad74c4 100644
--- a/code/ATMOSPHERICS/pipes/manifold.dm
+++ b/code/ATMOSPHERICS/pipes/manifold.dm
@@ -33,7 +33,7 @@
/obj/machinery/atmospherics/pipe/manifold/atmos_init()
..()
- for(var/D in cardinal)
+ for(var/D in GLOB.cardinal)
if(D == dir)
continue
for(var/obj/machinery/atmospherics/target in get_step(src, D))
@@ -116,7 +116,7 @@
/obj/machinery/atmospherics/pipe/manifold/update_icon(var/safety = 0)
..()
-
+
if(!check_icon_cache())
return
diff --git a/code/ATMOSPHERICS/pipes/manifold4w.dm b/code/ATMOSPHERICS/pipes/manifold4w.dm
index d2cee29c0ba..2b384b3684b 100644
--- a/code/ATMOSPHERICS/pipes/manifold4w.dm
+++ b/code/ATMOSPHERICS/pipes/manifold4w.dm
@@ -90,7 +90,7 @@
/obj/machinery/atmospherics/pipe/manifold4w/update_icon(var/safety = 0)
..()
-
+
if(!check_icon_cache())
return
@@ -137,7 +137,7 @@
/obj/machinery/atmospherics/pipe/manifold4w/atmos_init()
..()
- for(var/D in cardinal)
+ for(var/D in GLOB.cardinal)
for(var/obj/machinery/atmospherics/target in get_step(src, D))
if(target.initialize_directions & get_dir(target,src))
var/c = check_connect_types(target,src)
diff --git a/code/ATMOSPHERICS/pipes/simple/pipe_simple.dm b/code/ATMOSPHERICS/pipes/simple/pipe_simple.dm
index b966690733b..94983f62acd 100644
--- a/code/ATMOSPHERICS/pipes/simple/pipe_simple.dm
+++ b/code/ATMOSPHERICS/pipes/simple/pipe_simple.dm
@@ -48,7 +48,7 @@
if(initPipe)
normalize_dir()
var/N = 2
- for(var/D in cardinal)
+ for(var/D in GLOB.cardinal)
if(D & initialize_directions)
N--
for(var/obj/machinery/atmospherics/target in get_step(src, D))
@@ -138,7 +138,7 @@
/obj/machinery/atmospherics/pipe/simple/update_icon(var/safety = 0)
..()
-
+
if(!check_icon_cache())
return
diff --git a/code/ATMOSPHERICS/pipes/simple/pipe_simple_he.dm b/code/ATMOSPHERICS/pipes/simple/pipe_simple_he.dm
index 35df3c60d23..9c6b0da2121 100644
--- a/code/ATMOSPHERICS/pipes/simple/pipe_simple_he.dm
+++ b/code/ATMOSPHERICS/pipes/simple/pipe_simple_he.dm
@@ -69,7 +69,7 @@
if(initPipe)
normalize_dir()
var/N = 2
- for(var/D in cardinal)
+ for(var/D in GLOB.cardinal)
if(D & initialize_directions_he)
N--
for(var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/target in get_step(src, D))
diff --git a/code/ATMOSPHERICS/pipes/simple/pipe_simple_hidden.dm b/code/ATMOSPHERICS/pipes/simple/pipe_simple_hidden.dm
index db982639c2f..e0bd78bc2de 100644
--- a/code/ATMOSPHERICS/pipes/simple/pipe_simple_hidden.dm
+++ b/code/ATMOSPHERICS/pipes/simple/pipe_simple_hidden.dm
@@ -68,4 +68,4 @@
color = PIPE_COLOR_GREEN
/obj/machinery/atmospherics/pipe/simple/hidden/purple
- color = PIPE_COLOR_PURPLE
\ No newline at end of file
+ color = PIPE_COLOR_PURPLE
diff --git a/code/ATMOSPHERICS/pipes/simple/pipe_simple_insulated.dm b/code/ATMOSPHERICS/pipes/simple/pipe_simple_insulated.dm
index ce6ff78b2d0..e7e5ec55e90 100644
--- a/code/ATMOSPHERICS/pipes/simple/pipe_simple_insulated.dm
+++ b/code/ATMOSPHERICS/pipes/simple/pipe_simple_insulated.dm
@@ -8,4 +8,4 @@
fatigue_pressure = 900*ONE_ATMOSPHERE
alert_pressure = 900*ONE_ATMOSPHERE
- level = 2
\ No newline at end of file
+ level = 2
diff --git a/code/ATMOSPHERICS/pipes/simple/pipe_simple_visible.dm b/code/ATMOSPHERICS/pipes/simple/pipe_simple_visible.dm
index 1ca4da646ac..410c992c74c 100644
--- a/code/ATMOSPHERICS/pipes/simple/pipe_simple_visible.dm
+++ b/code/ATMOSPHERICS/pipes/simple/pipe_simple_visible.dm
@@ -65,4 +65,4 @@
/obj/machinery/atmospherics/pipe/simple/visible/universal/update_underlays()
..()
- update_icon()
\ No newline at end of file
+ update_icon()
diff --git a/code/LINDA/LINDA_fire.dm b/code/LINDA/LINDA_fire.dm
index 9467f7a3742..6ec505d9f9a 100644
--- a/code/LINDA/LINDA_fire.dm
+++ b/code/LINDA/LINDA_fire.dm
@@ -66,7 +66,7 @@
if(!fake)
SSair.hotspots += src
perform_exposure()
- dir = pick(cardinal)
+ dir = pick(GLOB.cardinal)
air_update_turf()
/obj/effect/hotspot/proc/perform_exposure()
@@ -133,7 +133,7 @@
//Possible spread due to radiated heat
if(location.air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_SPREAD)
var/radiated_temperature = location.air.temperature*FIRE_SPREAD_RADIOSITY_SCALE
- for(var/direction in cardinal)
+ for(var/direction in GLOB.cardinal)
if(!(location.atmos_adjacent_turfs & direction))
var/turf/simulated/wall/W = get_step(src, direction)
if(istype(W))
@@ -309,7 +309,7 @@
if(dist == max_dist)
continue
- for(var/dir in cardinal)
+ for(var/dir in GLOB.cardinal)
var/turf/link = get_step(T, dir)
if (!link)
continue
@@ -338,4 +338,4 @@
if(prob(chance) || bypass_rng)
T.visible_message("[T] melts!")
T.burn_down()
- return affected
\ No newline at end of file
+ return affected
diff --git a/code/LINDA/LINDA_system.dm b/code/LINDA/LINDA_system.dm
index c9d168a0159..c5bc65d3bf7 100644
--- a/code/LINDA/LINDA_system.dm
+++ b/code/LINDA/LINDA_system.dm
@@ -62,7 +62,7 @@ turf/CanPass(atom/movable/mover, turf/target, height=1.5)
/turf/proc/CalculateAdjacentTurfs()
atmos_adjacent_turfs_amount = 0
- for(var/direction in cardinal)
+ for(var/direction in GLOB.cardinal)
var/turf/T = get_step(src, direction)
if(!istype(T))
continue
@@ -89,7 +89,7 @@ turf/CanPass(atom/movable/mover, turf/target, height=1.5)
var/adjacent_turfs = list()
var/turf/simulated/curloc = src
- for(var/direction in cardinal)
+ for(var/direction in GLOB.cardinal)
if(!(curloc.atmos_adjacent_turfs & direction))
continue
@@ -99,11 +99,11 @@ turf/CanPass(atom/movable/mover, turf/target, height=1.5)
if(!alldir)
return adjacent_turfs
- for(var/direction in diagonals)
+ for(var/direction in GLOB.diagonals)
var/matchingDirections = 0
var/turf/simulated/S = get_step(curloc, direction)
- for(var/checkDirection in cardinal)
+ for(var/checkDirection in GLOB.cardinal)
if(!(S.atmos_adjacent_turfs & checkDirection))
continue
var/turf/simulated/checkTurf = get_step(S, checkDirection)
@@ -142,44 +142,33 @@ turf/CanPass(atom/movable/mover, turf/target, height=1.5)
return
T.atmos_spawn_air(text, amount)
-var/const/SPAWN_HEAT = 1
-var/const/SPAWN_20C = 2
-var/const/SPAWN_TOXINS = 4
-var/const/SPAWN_OXYGEN = 8
-var/const/SPAWN_CO2 = 16
-var/const/SPAWN_NITROGEN = 32
-
-var/const/SPAWN_N2O = 64
-
-var/const/SPAWN_AIR = 256
-
/turf/simulated/proc/atmos_spawn_air(var/flag, var/amount)
if(!text || !amount || !air)
return
var/datum/gas_mixture/G = new
- if(flag & SPAWN_20C)
+ if(flag & LINDA_SPAWN_20C)
G.temperature = T20C
- if(flag & SPAWN_HEAT)
+ if(flag & LINDA_SPAWN_HEAT)
G.temperature += 1000
- if(flag & SPAWN_TOXINS)
+ if(flag & LINDA_SPAWN_TOXINS)
G.toxins += amount
- if(flag & SPAWN_OXYGEN)
+ if(flag & LINDA_SPAWN_OXYGEN)
G.oxygen += amount
- if(flag & SPAWN_CO2)
+ if(flag & LINDA_SPAWN_CO2)
G.carbon_dioxide += amount
- if(flag & SPAWN_NITROGEN)
+ if(flag & LINDA_SPAWN_NITROGEN)
G.nitrogen += amount
- if(flag & SPAWN_N2O)
+ if(flag & LINDA_SPAWN_N2O)
var/datum/gas/sleeping_agent/T = new
T.moles += amount
G.trace_gases += T
- if(flag & SPAWN_AIR)
+ if(flag & LINDA_SPAWN_AIR)
G.oxygen += MOLES_O2STANDARD * amount
G.nitrogen += MOLES_N2STANDARD * amount
diff --git a/code/LINDA/LINDA_turf_tile.dm b/code/LINDA/LINDA_turf_tile.dm
index b86ad2299ff..72f77d2440f 100644
--- a/code/LINDA/LINDA_turf_tile.dm
+++ b/code/LINDA/LINDA_turf_tile.dm
@@ -149,7 +149,7 @@
if (planet_atmos)
atmos_adjacent_turfs_amount++
- for(var/direction in cardinal)
+ for(var/direction in GLOB.cardinal)
if(!(atmos_adjacent_turfs & direction))
continue
@@ -260,9 +260,9 @@
/turf/simulated/proc/get_atmos_overlay_by_name(name)
switch(name)
if("plasma")
- return plmaster
+ return GLOB.plmaster
if("sleeping_agent")
- return slmaster
+ return GLOB.slmaster
return null
/turf/simulated/proc/tile_graphic()
@@ -412,13 +412,13 @@
archive()
else
//Does particate in air exchange so only consider directions not considered during process_cell()
- for(var/direction in cardinal)
+ for(var/direction in GLOB.cardinal)
if(!(atmos_adjacent_turfs & direction) && !(atmos_supeconductivity & direction))
conductivity_directions += direction
if(conductivity_directions>0)
//Conduct with tiles around me
- for(var/direction in cardinal)
+ for(var/direction in GLOB.cardinal)
if(conductivity_directions&direction)
var/turf/neighbor = get_step(src,direction)
@@ -499,7 +499,7 @@ turf/simulated/proc/radiate_to_spess() //Radiate excess tile heat to space
/turf/simulated/Initialize_Atmos(times_fired)
..()
update_visuals()
- for(var/direction in cardinal)
+ for(var/direction in GLOB.cardinal)
if(!(atmos_adjacent_turfs & direction))
continue
var/turf/enemy_tile = get_step(src, direction)
diff --git a/code/__DEFINES/_readme.dm b/code/__DEFINES/_readme.dm
index 42ad52286fe..8bf6ada6477 100644
--- a/code/__DEFINES/_readme.dm
+++ b/code/__DEFINES/_readme.dm
@@ -11,4 +11,4 @@
and most importantly,
how to undo your changes if you screw it up.
- Sayu
-*/
\ No newline at end of file
+*/
diff --git a/code/__DEFINES/_spacemandmm.dm b/code/__DEFINES/_spacemandmm.dm
new file mode 100644
index 00000000000..ca54ca4b932
--- /dev/null
+++ b/code/__DEFINES/_spacemandmm.dm
@@ -0,0 +1,26 @@
+// This file contains all the defines related to the spacemanDMM linter (dreamchecker). When running under normal conditions, BYOND will ignore all these
+#ifdef SPACEMAN_DMM
+ #define RETURN_TYPE(X) set SpacemanDMM_return_type = X
+ #define SHOULD_CALL_PARENT(X) set SpacemanDMM_should_call_parent = X
+ #define UNLINT(X) SpacemanDMM_unlint(X)
+ #define SHOULD_NOT_OVERRIDE(X) set SpacemanDMM_should_not_override = X
+ #define SHOULD_NOT_SLEEP(X)
+ #define SHOULD_BE_PURE(X)
+ #define PRIVATE_PROC(X)
+ #define PROTECTED_PROC(X)
+ #define VAR_FINAL var/SpacemanDMM_final
+ #define VAR_PRIVATE var
+ #define VAR_PROTECTED var
+#else
+ #define RETURN_TYPE(X)
+ #define SHOULD_CALL_PARENT(X)
+ #define UNLINT(X) X
+ #define SHOULD_NOT_OVERRIDE(X)
+ #define SHOULD_NOT_SLEEP(X)
+ #define SHOULD_BE_PURE(X)
+ #define PRIVATE_PROC(X)
+ #define PROTECTED_PROC(X)
+ #define VAR_FINAL var
+ #define VAR_PRIVATE var
+ #define VAR_PROTECTED var
+#endif
diff --git a/code/__DEFINES/_tick.dm b/code/__DEFINES/_tick.dm
index 666971e7209..10b815e547c 100644
--- a/code/__DEFINES/_tick.dm
+++ b/code/__DEFINES/_tick.dm
@@ -10,4 +10,4 @@
#define CHECK_TICK ( TICK_CHECK ? stoplag() : 0 )
#define TICK_CHECK_HIGH_PRIORITY ( TICK_USAGE > 95 )
-#define CHECK_TICK_HIGH_PRIORITY ( TICK_CHECK_HIGH_PRIORITY? stoplag() : 0 )
\ No newline at end of file
+#define CHECK_TICK_HIGH_PRIORITY ( TICK_CHECK_HIGH_PRIORITY? stoplag() : 0 )
diff --git a/code/__DEFINES/access.dm b/code/__DEFINES/access.dm
new file mode 100644
index 00000000000..ea319971a1b
--- /dev/null
+++ b/code/__DEFINES/access.dm
@@ -0,0 +1,111 @@
+#define ACCESS_SECURITY 1 // Security equipment
+#define ACCESS_BRIG 2 // Brig timers and permabrig
+#define ACCESS_ARMORY 3
+#define ACCESS_FORENSICS_LOCKERS 4
+#define ACCESS_MEDICAL 5
+#define ACCESS_MORGUE 6
+#define ACCESS_TOX 7
+#define ACCESS_TOX_STORAGE 8
+#define ACCESS_GENETICS 9
+#define ACCESS_ENGINE 10
+#define ACCESS_ENGINE_EQUIP 11
+#define ACCESS_MAINT_TUNNELS 12
+#define ACCESS_EXTERNAL_AIRLOCKS 13
+#define ACCESS_EMERGENCY_STORAGE 14
+#define ACCESS_CHANGE_IDS 15
+#define ACCESS_AI_UPLOAD 16
+#define ACCESS_TELEPORTER 17
+#define ACCESS_EVA 18
+#define ACCESS_HEADS 19
+#define ACCESS_CAPTAIN 20
+#define ACCESS_ALL_PERSONAL_LOCKERS 21
+#define ACCESS_CHAPEL_OFFICE 22
+#define ACCESS_TECH_STORAGE 23
+#define ACCESS_ATMOSPHERICS 24
+#define ACCESS_BAR 25
+#define ACCESS_JANITOR 26
+#define ACCESS_CREMATORIUM 27
+#define ACCESS_KITCHEN 28
+#define ACCESS_ROBOTICS 29
+#define ACCESS_RD 30
+#define ACCESS_CARGO 31
+#define ACCESS_CONSTRUCTION 32
+#define ACCESS_CHEMISTRY 33
+#define ACCESS_CARGO_BOT 34
+#define ACCESS_HYDROPONICS 35
+#define ACCESS_MANUFACTURING 36
+#define ACCESS_LIBRARY 37
+#define ACCESS_LAWYER 38
+#define ACCESS_VIROLOGY 39
+#define ACCESS_CMO 40
+#define ACCESS_QM 41
+#define ACCESS_COURT 42
+#define ACCESS_CLOWN 43
+#define ACCESS_MIME 44
+#define ACCESS_SURGERY 45
+#define ACCESS_THEATRE 46
+#define ACCESS_RESEARCH 47
+#define ACCESS_MINING 48
+#define ACCESS_MINING_OFFICE 49 //not in use
+#define ACCESS_MAILSORTING 50
+#define ACCESS_MINT 51
+#define ACCESS_MINT_VAULT 52
+#define ACCESS_HEADS_VAULT 53
+#define ACCESS_MINING_STATION 54
+#define ACCESS_XENOBIOLOGY 55
+#define ACCESS_CE 56
+#define ACCESS_HOP 57
+#define ACCESS_HOS 58
+#define ACCESS_RC_ANNOUNCE 59 //Request console announcements
+#define ACCESS_KEYCARD_AUTH 60 //Used for events which require at least two people to confirm them
+#define ACCESS_TCOMSAT 61 // has access to the entire telecomms satellite / machinery
+#define ACCESS_GATEWAY 62
+#define ACCESS_SEC_DOORS 63 // Security front doors
+#define ACCESS_PSYCHIATRIST 64 // Psychiatrist's office
+#define ACCESS_XENOARCH 65
+#define ACCESS_PARAMEDIC 66
+#define ACCESS_BLUESHIELD 67
+#define ACCESS_SALVAGE_CAPTAIN 69 // Salvage ship captain's quarters
+#define ACCESS_MECHANIC 70
+#define ACCESS_PILOT 71
+#define ACCESS_NTREP 73
+#define ACCESS_MAGISTRATE 74
+#define ACCESS_MINISAT 75
+#define ACCESS_MINERAL_STOREROOM 76
+#define ACCESS_NETWORK 77
+
+#define ACCESS_WEAPONS 99 //Weapon authorization for secbots
+
+ //BEGIN CENTCOM ACCESS
+#define ACCESS_CENT_GENERAL 101//General facilities.
+#define ACCESS_CENT_LIVING 102//Living quarters.
+#define ACCESS_CENT_MEDICAL 103//Medical.
+#define ACCESS_CENT_SECURITY 104//Security.
+#define ACCESS_CENT_STORAGE 105//Storage areas.
+#define ACCESS_CENT_SHUTTLES 106//Shuttle docks.
+#define ACCESS_CENT_TELECOMMS 107//Telecomms.
+#define ACCESS_CENT_TELEPORTER 108//Teleporter
+#define ACCESS_CENT_SPECOPS 109//Special Ops.
+#define ACCESS_CENT_SPECOPS_COMMANDER 110//Special Ops Commander.
+#define ACCESS_CENT_BLACKOPS 111//Black Ops.
+#define ACCESS_CENT_THUNDER 112//Thunderdome.
+#define ACCESS_CENT_BRIDGE 113//Bridge.
+#define ACCESS_CENT_COMMANDER 114//Commander's Office/ID computer.
+
+//The Syndicate
+#define ACCESS_SYNDICATE 150//General Syndicate Access
+#define ACCESS_SYNDICATE_LEADER 151//Nuke Op Leader Access
+#define ACCESS_VOX 152//Vox Access
+#define ACCESS_SYNDICATE_COMMAND 153//Admin syndi officer
+
+//Trade Stations
+#define ACCESS_TRADE_SOL 160
+
+//MONEY
+#define ACCESS_CRATE_CASH 200
+
+//Awaymissions
+#define ACCESS_AWAY01 271
+
+//Ghost roles
+#define ACCESS_FREE_GOLEMS 300
diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm
index 65f4da2b50a..95494fb88cf 100644
--- a/code/__DEFINES/admin.dm
+++ b/code/__DEFINES/admin.dm
@@ -40,10 +40,11 @@
#define R_MOD 8192
#define R_MENTOR 16384
#define R_PROCCALL 32768
+#define R_VIEWRUNTIMES 65536
-#define R_MAXPERMISSION 32768 //This holds the maximum value for a permission. It is used in iteration, so keep it updated.
+#define R_MAXPERMISSION 65536 //This holds the maximum value for a permission. It is used in iteration, so keep it updated.
-#define R_HOST 65535
+#define R_HOST 131071 // Sum of all permissions to allow easy setting
#define ADMIN_QUE(user,display) "[display]"
#define ADMIN_FLW(user,display) "[display]"
@@ -70,4 +71,4 @@
///Max amount of keypress messages per second over two seconds before client is autokicked
#define MAX_KEYPRESS_AUTOKICK 50
///Length of held key rolling buffer
-#define HELD_KEY_BUFFER_LENGTH 15
\ No newline at end of file
+#define HELD_KEY_BUFFER_LENGTH 15
diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm
index e69de29bb2d..8b137891791 100644
--- a/code/__DEFINES/antagonists.dm
+++ b/code/__DEFINES/antagonists.dm
@@ -0,0 +1 @@
+
diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm
index 2f296960622..de20ccd1a4c 100644
--- a/code/__DEFINES/atmospherics.dm
+++ b/code/__DEFINES/atmospherics.dm
@@ -131,4 +131,4 @@
#define ATMOS_ALARM_DANGER 2
//LAVALAND
-#define LAVALAND_EQUIPMENT_EFFECT_PRESSURE 50 //what pressure you have to be under to increase the effect of equipment meant for lavaland
\ No newline at end of file
+#define LAVALAND_EQUIPMENT_EFFECT_PRESSURE 50 //what pressure you have to be under to increase the effect of equipment meant for lavaland
diff --git a/code/__DEFINES/bots.dm b/code/__DEFINES/bots.dm
index 75bf8a0a553..c283445d0ad 100644
--- a/code/__DEFINES/bots.dm
+++ b/code/__DEFINES/bots.dm
@@ -38,4 +38,4 @@
#define SENTIENCE_ARTIFICIAL 2
#define SENTIENCE_OTHER 3
#define SENTIENCE_MINEBOT 4
-#define SENTIENCE_BOSS 5
\ No newline at end of file
+#define SENTIENCE_BOSS 5
diff --git a/code/__DEFINES/callbacks.dm b/code/__DEFINES/callbacks.dm
index 26c81f8b143..18059a60839 100644
--- a/code/__DEFINES/callbacks.dm
+++ b/code/__DEFINES/callbacks.dm
@@ -1,4 +1,4 @@
#define GLOBAL_PROC "some_magic_bullshit"
#define CALLBACK new /datum/callback
-#define INVOKE_ASYNC ImmediateInvokeAsync
\ No newline at end of file
+#define INVOKE_ASYNC ImmediateInvokeAsync
diff --git a/code/__DEFINES/clothing.dm b/code/__DEFINES/clothing.dm
index c44c65397dd..1678ea69c8e 100644
--- a/code/__DEFINES/clothing.dm
+++ b/code/__DEFINES/clothing.dm
@@ -78,7 +78,7 @@
//flags for covering body parts
#define GLASSESCOVERSEYES 1
-#define MASKCOVERSEYES 2 // get rid of some of the other retardation in these flags
+#define MASKCOVERSEYES 2 // get rid of some of the other mess in these flags
#define HEADCOVERSEYES 4 // feel free to realloc these numbers for other purposes
#define MASKCOVERSMOUTH 8 // on other items, these are just for mask/head
#define HEADCOVERSMOUTH 16
@@ -92,9 +92,7 @@
#define BLOCKHEADHAIR 4 // temporarily removes the user's hair overlay. Leaves facial hair.
#define BLOCKHAIR 32768 // temporarily removes the user's hair, facial and otherwise.
-#define ONESIZEFITSALL 1 // determines if something can be worn by a fatty or not.
-
//flags for muzzle speech blocking
#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
+#define MUZZLE_MUTE_ALL 2 // Completely mutes you.
diff --git a/code/__DEFINES/colors.dm b/code/__DEFINES/colors.dm
index 13f7777d386..2bb53c91ce4 100644
--- a/code/__DEFINES/colors.dm
+++ b/code/__DEFINES/colors.dm
@@ -99,3 +99,12 @@
#define COLOR_ASSEMBLY_LBLUE "#5D99BE"
#define COLOR_ASSEMBLY_BLUE "#38559E"
#define COLOR_ASSEMBLY_PURPLE "#6F6192"
+
+// Pipe colours
+#define PIPE_COLOR_GREY "#ffffff" //yes white is grey
+#define PIPE_COLOR_RED "#ff0000"
+#define PIPE_COLOR_BLUE "#0000ff"
+#define PIPE_COLOR_CYAN "#00ffff"
+#define PIPE_COLOR_GREEN "#00ff00"
+#define PIPE_COLOR_YELLOW "#ffcc00"
+#define PIPE_COLOR_PURPLE "#5c1ec0"
diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm
index 956930aae70..2f98b6ee7b5 100644
--- a/code/__DEFINES/combat.dm
+++ b/code/__DEFINES/combat.dm
@@ -35,7 +35,6 @@
#define CANPUSH 8
#define PASSEMOTES 16 //Mob has a cortical borer or holders inside of it that need to see emotes.
#define GOTTAGOFAST 32
-#define GOTTAGOFAST_METH 64
#define IGNORESLOWDOWN 128
#define GODMODE 4096
#define FAKEDEATH 8192 //Replaces stuff like changeling.changeling_fakedeath
diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm
index c94dff5ca6c..c9691c195b8 100644
--- a/code/__DEFINES/components.dm
+++ b/code/__DEFINES/components.dm
@@ -288,4 +288,4 @@
#define COMSIG_XENO_SLIME_CLICK_SHIFT "xeno_slime_click_shift" //from slime ShiftClickOn(): (/mob)
#define COMSIG_XENO_TURF_CLICK_SHIFT "xeno_turf_click_shift" //from turf ShiftClickOn(): (/mob)
#define COMSIG_XENO_TURF_CLICK_CTRL "xeno_turf_click_alt" //from turf AltClickOn(): (/mob)
-#define COMSIG_XENO_MONKEY_CLICK_CTRL "xeno_monkey_click_ctrl" //from monkey CtrlClickOn(): (/mob)
\ No newline at end of file
+#define COMSIG_XENO_MONKEY_CLICK_CTRL "xeno_monkey_click_ctrl" //from monkey CtrlClickOn(): (/mob)
diff --git a/code/__DEFINES/crafting.dm b/code/__DEFINES/crafting.dm
index 0fbd76b9e21..33c80e970cf 100644
--- a/code/__DEFINES/crafting.dm
+++ b/code/__DEFINES/crafting.dm
@@ -33,4 +33,4 @@
#define RECIPE_GRILL "Grill"
#define RECIPE_CANDY "Candy"
-#define RECIPE_FAIL null
\ No newline at end of file
+#define RECIPE_FAIL null
diff --git a/code/__DEFINES/criminal_status.dm b/code/__DEFINES/criminal_status.dm
new file mode 100644
index 00000000000..75c33909fc2
--- /dev/null
+++ b/code/__DEFINES/criminal_status.dm
@@ -0,0 +1,10 @@
+//criminal status defines
+#define SEC_RECORD_STATUS_NONE "None"
+#define SEC_RECORD_STATUS_ARREST "*Arrest*"
+#define SEC_RECORD_STATUS_EXECUTE "*Execute*"
+#define SEC_RECORD_STATUS_INCARCERATED "Incarcerated"
+#define SEC_RECORD_STATUS_RELEASED "Released"
+#define SEC_RECORD_STATUS_PAROLLED "Parolled"
+#define SEC_RECORD_STATUS_DEMOTE "Demote"
+#define SEC_RECORD_STATUS_SEARCH "Search"
+#define SEC_RECORD_STATUS_MONITOR "Monitor"
diff --git a/code/__DEFINES/dna.dm b/code/__DEFINES/dna.dm
new file mode 100644
index 00000000000..7984c1a6dde
--- /dev/null
+++ b/code/__DEFINES/dna.dm
@@ -0,0 +1,57 @@
+// Defines for all genetics/DNA related stuff
+
+// What each index means:
+#define DNA_OFF_LOWERBOUND 1 // changed as lists start at 1 not 0
+#define DNA_OFF_UPPERBOUND 2
+#define DNA_ON_LOWERBOUND 3
+#define DNA_ON_UPPERBOUND 4
+
+// Define block bounds (off-low,off-high,on-low,on-high)
+// Used in setupgame.dm
+#define DNA_DEFAULT_BOUNDS list(1,2049,2050,4095)
+#define DNA_HARDER_BOUNDS list(1,3049,3050,4095)
+#define DNA_HARD_BOUNDS list(1,3490,3500,4095)
+
+// UI Indices (can change to mutblock style, if desired)
+#define DNA_UI_HAIR_R 1
+#define DNA_UI_HAIR_G 2
+#define DNA_UI_HAIR_B 3
+#define DNA_UI_HAIR2_R 4
+#define DNA_UI_HAIR2_G 5
+#define DNA_UI_HAIR2_B 6
+#define DNA_UI_BEARD_R 7
+#define DNA_UI_BEARD_G 8
+#define DNA_UI_BEARD_B 9
+#define DNA_UI_BEARD2_R 10
+#define DNA_UI_BEARD2_G 11
+#define DNA_UI_BEARD2_B 12
+#define DNA_UI_SKIN_TONE 13
+#define DNA_UI_SKIN_R 14
+#define DNA_UI_SKIN_G 15
+#define DNA_UI_SKIN_B 16
+#define DNA_UI_HACC_R 17
+#define DNA_UI_HACC_G 18
+#define DNA_UI_HACC_B 19
+#define DNA_UI_HEAD_MARK_R 20
+#define DNA_UI_HEAD_MARK_G 21
+#define DNA_UI_HEAD_MARK_B 22
+#define DNA_UI_BODY_MARK_R 23
+#define DNA_UI_BODY_MARK_G 24
+#define DNA_UI_BODY_MARK_B 25
+#define DNA_UI_TAIL_MARK_R 26
+#define DNA_UI_TAIL_MARK_G 27
+#define DNA_UI_TAIL_MARK_B 28
+#define DNA_UI_EYES_R 29
+#define DNA_UI_EYES_G 30
+#define DNA_UI_EYES_B 31
+#define DNA_UI_GENDER 32
+#define DNA_UI_BEARD_STYLE 33
+#define DNA_UI_HAIR_STYLE 34
+/*#define DNA_UI_BACC_STYLE 23*/
+#define DNA_UI_HACC_STYLE 35
+#define DNA_UI_HEAD_MARK_STYLE 36
+#define DNA_UI_BODY_MARK_STYLE 37
+#define DNA_UI_TAIL_MARK_STYLE 38
+#define DNA_UI_LENGTH 38 // Update this when you add something, or you WILL break shit.
+
+#define DNA_SE_LENGTH 55 // Was STRUCDNASIZE, size 27. 15 new blocks added = 42, plus room to grow.
diff --git a/code/__DEFINES/game.dm b/code/__DEFINES/game.dm
index 5c262724a14..4ad2ca587d9 100644
--- a/code/__DEFINES/game.dm
+++ b/code/__DEFINES/game.dm
@@ -2,4 +2,4 @@
#define GAME_STATE_PREGAME 1
#define GAME_STATE_SETTING_UP 2
#define GAME_STATE_PLAYING 3
-#define GAME_STATE_FINISHED 4
\ No newline at end of file
+#define GAME_STATE_FINISHED 4
diff --git a/code/__DEFINES/gamemode.dm b/code/__DEFINES/gamemode.dm
index 308e7a5f6d9..73a812e8f5b 100644
--- a/code/__DEFINES/gamemode.dm
+++ b/code/__DEFINES/gamemode.dm
@@ -53,4 +53,4 @@
#define SPECIAL_ROLE_XENOMORPH_DRONE "Xenomorph Drone"
#define SPECIAL_ROLE_XENOMORPH_SENTINEL "Xenomorph Sentinel"
#define SPECIAL_ROLE_XENOMORPH_LARVA "Xenomorph Larva"
-#define SPECIAL_ROLE_EVENTMISC "Event Role"
\ No newline at end of file
+#define SPECIAL_ROLE_EVENTMISC "Event Role"
diff --git a/code/__DEFINES/genetics.dm b/code/__DEFINES/genetics.dm
index c8f98c1fbeb..4ac05376e9d 100644
--- a/code/__DEFINES/genetics.dm
+++ b/code/__DEFINES/genetics.dm
@@ -104,6 +104,7 @@
#define NUTRITION_LEVEL_FED 350
#define NUTRITION_LEVEL_HUNGRY 250
#define NUTRITION_LEVEL_STARVING 150
+#define NUTRITION_LEVEL_HYPOGLYCEMIA 100
#define NUTRITION_LEVEL_CURSED 0
//Used as an upper limit for species that continuously gain nutriment
@@ -151,7 +152,6 @@
#define NO_SCAN "no_scan"
#define NO_PAIN "no_pain"
#define IS_PLANT "is_plant"
-#define CAN_BE_FAT "can_be_fat"
#define NO_INTORGANS "no_internal_organs"
#define RADIMMUNE "rad_immunity"
#define NOGUNS "no_guns"
@@ -166,4 +166,4 @@
#define NO_GERMS "no_germs"
#define NO_DECAY "no_decay"
#define PIERCEIMMUNE "pierce_immunity"
-#define NO_HUNGER "no_hunger"
\ No newline at end of file
+#define NO_HUNGER "no_hunger"
diff --git a/code/__DEFINES/hydroponics.dm b/code/__DEFINES/hydroponics.dm
index f6693b0bcfc..8a3890d45f9 100644
--- a/code/__DEFINES/hydroponics.dm
+++ b/code/__DEFINES/hydroponics.dm
@@ -57,4 +57,4 @@
#define TRAIT_BIOLUM_COLOUR 37
#define TRAIT_IMMUTABLE 38
#define TRAIT_RARITY 39
-#define TRAIT_BATTERY_RECHARGE 40
\ No newline at end of file
+#define TRAIT_BATTERY_RECHARGE 40
diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm
index 33ce299c540..671897b612d 100644
--- a/code/__DEFINES/is_helpers.dm
+++ b/code/__DEFINES/is_helpers.dm
@@ -28,13 +28,13 @@
#define is_pen(W) (istype(W, /obj/item/pen))
-var/list/static/global/pointed_types = typecacheof(list(
+GLOBAL_LIST_INIT(pointed_types, typecacheof(list(
/obj/item/pen,
/obj/item/screwdriver,
/obj/item/reagent_containers/syringe,
- /obj/item/kitchen/utensil/fork))
+ /obj/item/kitchen/utensil/fork)))
-#define is_pointed(W) (is_type_in_typecache(W, pointed_types))
+#define is_pointed(W) (is_type_in_typecache(W, GLOB.pointed_types))
GLOBAL_LIST_INIT(glass_sheet_types, typecacheof(list(
/obj/item/stack/sheet/glass,
diff --git a/code/__DEFINES/job.dm b/code/__DEFINES/job.dm
new file mode 100644
index 00000000000..d72628e2cb7
--- /dev/null
+++ b/code/__DEFINES/job.dm
@@ -0,0 +1,64 @@
+///////////////////////////////
+// WARNING //
+////////////////////////////////////////////////////////////////////////
+// Do NOT touch the values associated with these defines, as they are //
+// used by the game database to keep track of job flags. Do NOT touch //
+////////////////////////////////////////////////////////////////////////
+
+#define JOBCAT_ENGSEC (1<<0)
+
+#define JOB_CAPTAIN (1<<0)
+#define JOB_HOS (1<<1)
+#define JOB_WARDEN (1<<2)
+#define JOB_DETECTIVE (1<<3)
+#define JOB_OFFICER (1<<4)
+#define JOB_CHIEF (1<<5)
+#define JOB_ENGINEER (1<<6)
+#define JOB_ATMOSTECH (1<<7)
+#define JOB_AI (1<<8)
+#define JOB_CYBORG (1<<9)
+#define JOB_CENTCOM (1<<10)
+#define JOB_SYNDICATE (1<<11)
+
+#define JOBCAT_MEDSCI (1<<1)
+
+#define JOB_RD (1<<0)
+#define JOB_SCIENTIST (1<<1)
+#define JOB_CHEMIST (1<<2)
+#define JOB_CMO (1<<3)
+#define JOB_DOCTOR (1<<4)
+#define JOB_GENETICIST (1<<5)
+#define JOB_VIROLOGIST (1<<6)
+#define JOB_PSYCHIATRIST (1<<7)
+#define JOB_ROBOTICIST (1<<8)
+#define JOB_PARAMEDIC (1<<9)
+#define JOB_CORONER (1<<10)
+
+
+#define JOBCAT_SUPPORT (1<<2)
+
+#define JOB_HOP (1<<0)
+#define JOB_BARTENDER (1<<1)
+#define JOB_BOTANIST (1<<2)
+#define JOB_CHEF (1<<3)
+#define JOB_JANITOR (1<<4)
+#define JOB_LIBRARIAN (1<<5)
+#define JOB_QUARTERMASTER (1<<6)
+#define JOB_CARGOTECH (1<<7)
+#define JOB_MINER (1<<8)
+#define JOB_LAWYER (1<<9)
+#define JOB_CHAPLAIN (1<<10)
+#define JOB_CLOWN (1<<11)
+#define JOB_MIME (1<<12)
+#define JOB_CIVILIAN (1<<13)
+
+
+#define JOBCAT_KARMA (1<<3)
+
+#define JOB_NANO (1<<0)
+#define JOB_BLUESHIELD (1<<1)
+#define JOB_BARBER (1<<3)
+#define JOB_MECHANIC (1<<4)
+#define JOB_BRIGDOC (1<<5)
+#define JOB_JUDGE (1<<6)
+#define JOB_PILOT (1<<7)
diff --git a/code/__DEFINES/js.dm b/code/__DEFINES/js.dm
new file mode 100644
index 00000000000..e1a86e664d4
--- /dev/null
+++ b/code/__DEFINES/js.dm
@@ -0,0 +1,91 @@
+//this function places received data into element with specified id.
+#define JS_BYJAX {"
+
+function replaceContent() {
+ var args = Array.prototype.slice.call(arguments);
+ var id = args\[0\];
+ var content = args\[1\];
+ var callback = null;
+ if(args\[2\]){
+ callback = args\[2\];
+ if(args\[3\]){
+ args = args.slice(3);
+ }
+ }
+ var parent = document.getElementById(id);
+ if(typeof(parent)!=='undefined' && parent!=null){
+ parent.innerHTML = content?content:'';
+ }
+ if(callback && window\[callback\]){
+ window\[callback\].apply(null,args);
+ }
+}
+"}
+
+/*
+sends data to control_id:replaceContent
+
+receiver - mob
+control_id - window id (for windows opened with browse(), it'll be "windowname.browser")
+target_element - HTML element id
+new_content - HTML content
+callback - js function that will be called after the data is sent
+callback_args - arguments for callback function
+
+Be sure to include required js functions in your page, or it'll raise an exception.
+
+And yes I know this is a proc in a defines file, but its highly relevant so it can be here
+*/
+proc/send_byjax(receiver, control_id, target_element, new_content=null, callback=null, list/callback_args=null)
+ if(receiver && target_element && control_id) // && winexists(receiver, control_id))
+ var/list/argums = list(target_element, new_content)
+ if(callback)
+ argums += callback
+ if(callback_args)
+ argums += callback_args
+ argums = list2params(argums)
+/* if(callback_args)
+ argums += "&[list2params(callback_args)]"
+*/
+ receiver << output(argums,"[control_id]:replaceContent")
+ return
+
+
+// Misc JS for some dropdowns
+#define JS_DROPDOWNS {"
+function dropdowns() {
+ var divs = document.getElementsByTagName('div');
+ var headers = new Array();
+ var links = new Array();
+ for(var i=0;i=0) {
+ elem.className = elem.className.replace('visible','hidden');
+ this.className = this.className.replace('open','closed');
+ this.innerHTML = this.innerHTML.replace('-','+');
+ }
+ else {
+ elem.className = elem.className.replace('hidden','visible');
+ this.className = this.className.replace('closed','open');
+ this.innerHTML = this.innerHTML.replace('+','-');
+ }
+ return false;
+ }
+ })(links\[i\]);
+ }
+ }
+}
+"}
diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm
index db88f46a676..ed4cb0d5940 100644
--- a/code/__DEFINES/layers.dm
+++ b/code/__DEFINES/layers.dm
@@ -110,4 +110,4 @@
#define ABOVE_HUD_LAYER 22
#define SPLASHSCREEN_LAYER 23
-#define SPLASHSCREEN_PLANE 23
\ No newline at end of file
+#define SPLASHSCREEN_PLANE 23
diff --git a/code/__DEFINES/lighting.dm b/code/__DEFINES/lighting.dm
index 7357c5f441e..34528090e86 100644
--- a/code/__DEFINES/lighting.dm
+++ b/code/__DEFINES/lighting.dm
@@ -89,4 +89,28 @@
#define FLASH_LIGHT_DURATION 2
#define FLASH_LIGHT_POWER 3
-#define FLASH_LIGHT_RANGE 3.8
\ No newline at end of file
+#define FLASH_LIGHT_RANGE 3.8
+
+/// Returns the red part of a #RRGGBB hex sequence as number
+#define GETREDPART(hexa) hex2num(copytext(hexa, 2, 4))
+
+/// Returns the green part of a #RRGGBB hex sequence as number
+#define GETGREENPART(hexa) hex2num(copytext(hexa, 4, 6))
+
+/// Returns the blue part of a #RRGGBB hex sequence as number
+#define GETBLUEPART(hexa) hex2num(copytext(hexa, 6, 8))
+
+/// Parse the hexadecimal color into lumcounts of each perspective.
+#define PARSE_LIGHT_COLOR(source) \
+do { \
+ if (source.light_color) { \
+ var/__light_color = source.light_color; \
+ source.lum_r = GETREDPART(__light_color) / 255; \
+ source.lum_g = GETGREENPART(__light_color) / 255; \
+ source.lum_b = GETBLUEPART(__light_color) / 255; \
+ } else { \
+ source.lum_r = 1; \
+ source.lum_g = 1; \
+ source.lum_b = 1; \
+ }; \
+} while (FALSE)
diff --git a/code/__DEFINES/logs.dm b/code/__DEFINES/logs.dm
new file mode 100644
index 00000000000..25d1fac7323
--- /dev/null
+++ b/code/__DEFINES/logs.dm
@@ -0,0 +1,6 @@
+#define ATTACK_LOG "Attack"
+#define DEFENSE_LOG "Defense"
+#define CONVERSION_LOG "Conversion"
+#define SAY_LOG "Say"
+#define EMOTE_LOG "Emote"
+#define MISC_LOG "Misc"
diff --git a/code/__DEFINES/machines.dm b/code/__DEFINES/machines.dm
index 7a691c44df2..b56024bfab8 100644
--- a/code/__DEFINES/machines.dm
+++ b/code/__DEFINES/machines.dm
@@ -88,3 +88,7 @@
#define SUPERMATTER_DANGER 4 // Integrity < 75%
#define SUPERMATTER_EMERGENCY 5 // Integrity < 50%
#define SUPERMATTER_DELAMINATING 6 // Pretty obvious, Integrity < 25%
+
+// Firelock states
+#define FD_OPEN 1
+#define FD_CLOSED 2
diff --git a/code/__DEFINES/mecha.dm b/code/__DEFINES/mecha.dm
index e8955e64b50..b414f146705 100644
--- a/code/__DEFINES/mecha.dm
+++ b/code/__DEFINES/mecha.dm
@@ -19,4 +19,4 @@
#define MECHA_SECURE_BOLTS 1
#define MECHA_LOOSE_BOLTS 2
#define MECHA_OPEN_HATCH 3
-#define MECHA_UNSECURE_CELL 4
\ No newline at end of file
+#define MECHA_UNSECURE_CELL 4
diff --git a/code/__DEFINES/medal.dm b/code/__DEFINES/medal.dm
index 81dea5f373b..b47d562efee 100644
--- a/code/__DEFINES/medal.dm
+++ b/code/__DEFINES/medal.dm
@@ -21,4 +21,4 @@
#define DRAKE_SCORE "Drakes Killed"
#define LEGION_SCORE "Legion Killed"
#define SWARMER_BEACON_SCORE "Swarmer Beacons Killed"
-#define TENDRIL_CLEAR_SCORE "Tendrils Killed"
\ No newline at end of file
+#define TENDRIL_CLEAR_SCORE "Tendrils Killed"
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index 51b895ff12d..cf27ec09143 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -122,10 +122,10 @@
)
#define FOR_DVIEW(type, range, center, invis_flags) \
- dview_mob.loc = center; \
- dview_mob.see_invisible = invis_flags; \
- for(type in view(range, dview_mob))
-#define END_FOR_DVIEW dview_mob.loc = null
+ GLOB.dview_mob.loc = center; \
+ GLOB.dview_mob.see_invisible = invis_flags; \
+ for(type in view(range, GLOB.dview_mob))
+#define END_FOR_DVIEW GLOB.dview_mob.loc = null
//Turf locational stuff
#define get_turf(A) (get_step(A, 0))
@@ -319,7 +319,7 @@
#define INVESTIGATE_BOMB "bombs"
// The SQL version required by this version of the code
-#define SQL_VERSION 11
+#define SQL_VERSION 12
// Vending machine stuff
#define CAT_NORMAL 1
@@ -345,7 +345,7 @@
#define MOUSE_OPACITY_OPAQUE 2
// Defib stats
-#define DEFIB_TIME_LIMIT 120
+#define DEFIB_TIME_LIMIT 300
#define DEFIB_TIME_LOSS 60
//different types of atom colorations
@@ -419,4 +419,19 @@
#define ENGTYPE_TESLA "Tesla"
#define SUMMON_GUNS "guns"
-#define SUMMON_MAGIC "magic"
\ No newline at end of file
+#define SUMMON_MAGIC "magic"
+
+// Medical stuff
+#define SYMPTOM_ACTIVATION_PROB 3
+
+// Atmos stuff that fucking terrifies me
+#define LINDA_SPAWN_HEAT 1
+#define LINDA_SPAWN_20C 2
+#define LINDA_SPAWN_TOXINS 4
+#define LINDA_SPAWN_OXYGEN 8
+#define LINDA_SPAWN_CO2 16
+#define LINDA_SPAWN_NITROGEN 32
+
+#define LINDA_SPAWN_N2O 64
+
+#define LINDA_SPAWN_AIR 256
diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index 293d97e4fa3..e1e15a926d6 100644
--- a/code/__DEFINES/mobs.dm
+++ b/code/__DEFINES/mobs.dm
@@ -239,4 +239,4 @@
#define is_admin(user) (check_rights(R_ADMIN, 0, (user)) != 0)
-#define SLEEP_CHECK_DEATH(X) sleep(X); if(QDELETED(src) || stat == DEAD) return;
\ No newline at end of file
+#define SLEEP_CHECK_DEATH(X) sleep(X); if(QDELETED(src) || stat == DEAD) return;
diff --git a/code/__DEFINES/move_force.dm b/code/__DEFINES/move_force.dm
index 750821bd898..8051a516298 100644
--- a/code/__DEFINES/move_force.dm
+++ b/code/__DEFINES/move_force.dm
@@ -16,4 +16,4 @@
#define MOVE_FORCE_NORMAL MOVE_FORCE_DEFAULT
#define MOVE_FORCE_WEAK MOVE_FORCE_DEFAULT / 2
#define MOVE_FORCE_VERY_WEAK (MOVE_FORCE_DEFAULT / MOVE_FORCE_CRUSH_RATIO) + 1
-#define MOVE_FORCE_EXTREMELY_WEAK MOVE_FORCE_DEFAULT / (MOVE_FORCE_CRUSH_RATIO * 3)
\ No newline at end of file
+#define MOVE_FORCE_EXTREMELY_WEAK MOVE_FORCE_DEFAULT / (MOVE_FORCE_CRUSH_RATIO * 3)
diff --git a/code/__DEFINES/pda.dm b/code/__DEFINES/pda.dm
index d22b90870b0..c5d32f03ba8 100644
--- a/code/__DEFINES/pda.dm
+++ b/code/__DEFINES/pda.dm
@@ -1,3 +1,3 @@
#define PDA_APP_UPDATE 0
#define PDA_APP_NOUPDATE 1
-#define PDA_APP_UPDATE_SLOW 2
\ No newline at end of file
+#define PDA_APP_UPDATE_SLOW 2
diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm
index 54fd59307f4..eb5fad0ff27 100644
--- a/code/__DEFINES/preferences.dm
+++ b/code/__DEFINES/preferences.dm
@@ -7,9 +7,10 @@
#define SOUND_BUZZ 64
#define SOUND_INSTRUMENTS 128
#define SOUND_MENTORHELP 256
-#define SOUND_DISCO 512
+#define SOUND_DISCO 512
+#define SOUND_AI_VOICE 1024
-#define SOUND_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|SOUND_HEARTBEAT|SOUND_BUZZ|SOUND_INSTRUMENTS|SOUND_MENTORHELP|SOUND_DISCO)
+#define SOUND_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|SOUND_HEARTBEAT|SOUND_BUZZ|SOUND_INSTRUMENTS|SOUND_MENTORHELP|SOUND_DISCO|SOUND_AI_VOICE)
#define CHAT_OOC 1
#define CHAT_DEAD 2
diff --git a/code/__DEFINES/qdel.dm b/code/__DEFINES/qdel.dm
index 6adb876da8d..0aaee0533d4 100644
--- a/code/__DEFINES/qdel.dm
+++ b/code/__DEFINES/qdel.dm
@@ -20,4 +20,4 @@
#define QDELING(X) (X.gc_destroyed)
#define QDELETED(X) (!X || QDELING(X))
-#define QDESTROYING(X) (!X || X.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
\ No newline at end of file
+#define QDESTROYING(X) (!X || X.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
diff --git a/code/__DEFINES/radio.dm b/code/__DEFINES/radio.dm
index e49a9ea9b67..e0c71836c72 100644
--- a/code/__DEFINES/radio.dm
+++ b/code/__DEFINES/radio.dm
@@ -1,60 +1,60 @@
-
-#define DISPLAY_FREQ 1435 //status displays
-#define ATMOS_FIRE_FREQ 1437 //air alarms
-#define ENGINE_FREQ 1438 //engine components
-#define ATMOS_VENTSCRUB 1439 //vents, scrubbers, atmos control
-#define ATMOS_DISTRO_FREQ 1443 //distro loop
-#define ATMOS_TANKS_FREQ 1441 //atmos supply tanks
-#define BOT_BEACON_FREQ 1445 //bot navigation beacons
-#define AIRLOCK_FREQ 1449 //airlock controls, electropack, magnets
-
-#define RSD_FREQ 1457 //radio signal device
-#define IMPL_FREQ 1451 //tracking implant
-
-#define RADIO_LOW_FREQ 1200 //minimum radio freq
-#define PUBLIC_LOW_FREQ 1441 //minimum radio chat freq
-#define PUBLIC_HIGH_FREQ 1489 //maximum radio chat freq
-#define RADIO_HIGH_FREQ 1600 //maximum radio freq
-
-#define SYND_FREQ 1213
-#define SYNDTEAM_FREQ 1244
-#define DTH_FREQ 1341 //Special Operations
-#define AI_FREQ 1343
-#define ERT_FREQ 1345
-#define COMM_FREQ 1353 //Command
-#define BOT_FREQ 1447 //mulebot, secbot, ed209
-
-
-// Department channels
-#define PUB_FREQ 1459 //standard radio chat
-#define SEC_FREQ 1359 //security
-#define ENG_FREQ 1357 //engineering
-#define SCI_FREQ 1351 //science
-#define MED_FREQ 1355 //medical
-#define SUP_FREQ 1347 //cargo
-#define SRV_FREQ 1349 //service
-
-// Internal department channels
-#define MED_I_FREQ 1485
-#define SEC_I_FREQ 1475
-
-// Transmission methods
-#define TRANSMISSION_WIRE 0
-#define TRANSMISSION_RADIO 1
-
-//This filter is special because devices belonging to default also recieve signals sent to any other filter.
-#define RADIO_DEFAULT "radio_default"
-#define RADIO_TO_AIRALARM "radio_airalarm" //air alarms
-#define RADIO_FROM_AIRALARM "radio_airalarm_rcvr" //devices interested in recieving signals from air alarms
-#define RADIO_CHAT "radio_telecoms"
-#define RADIO_ATMOSIA "radio_atmos"
-#define RADIO_NAVBEACONS "radio_navbeacon"
-#define RADIO_AIRLOCK "radio_airlock"
-#define RADIO_SECBOT "radio_secbot"
-#define RADIO_HONKBOT "radio_honkbot"
-#define RADIO_MULEBOT "radio_mulebot"
-#define RADIO_CLEANBOT "10"
-#define RADIO_FLOORBOT "11"
-#define RADIO_MEDBOT "12"
-#define RADIO_MAGNETS "radio_magnet"
-#define RADIO_LOGIC "radio_logic"
+
+#define DISPLAY_FREQ 1435 //status displays
+#define ATMOS_FIRE_FREQ 1437 //air alarms
+#define ENGINE_FREQ 1438 //engine components
+#define ATMOS_VENTSCRUB 1439 //vents, scrubbers, atmos control
+#define ATMOS_DISTRO_FREQ 1443 //distro loop
+#define ATMOS_TANKS_FREQ 1441 //atmos supply tanks
+#define BOT_BEACON_FREQ 1445 //bot navigation beacons
+#define AIRLOCK_FREQ 1449 //airlock controls, electropack, magnets
+
+#define RSD_FREQ 1457 //radio signal device
+#define IMPL_FREQ 1451 //tracking implant
+
+#define RADIO_LOW_FREQ 1200 //minimum radio freq
+#define PUBLIC_LOW_FREQ 1441 //minimum radio chat freq
+#define PUBLIC_HIGH_FREQ 1489 //maximum radio chat freq
+#define RADIO_HIGH_FREQ 1600 //maximum radio freq
+
+#define SYND_FREQ 1213
+#define SYNDTEAM_FREQ 1244
+#define DTH_FREQ 1341 //Special Operations
+#define AI_FREQ 1343
+#define ERT_FREQ 1345
+#define COMM_FREQ 1353 //Command
+#define BOT_FREQ 1447 //mulebot, secbot, ed209
+
+
+// Department channels
+#define PUB_FREQ 1459 //standard radio chat
+#define SEC_FREQ 1359 //security
+#define ENG_FREQ 1357 //engineering
+#define SCI_FREQ 1351 //science
+#define MED_FREQ 1355 //medical
+#define SUP_FREQ 1347 //cargo
+#define SRV_FREQ 1349 //service
+
+// Internal department channels
+#define MED_I_FREQ 1485
+#define SEC_I_FREQ 1475
+
+// Transmission methods
+#define TRANSMISSION_WIRE 0
+#define TRANSMISSION_RADIO 1
+
+//This filter is special because devices belonging to default also recieve signals sent to any other filter.
+#define RADIO_DEFAULT "radio_default"
+#define RADIO_TO_AIRALARM "radio_airalarm" //air alarms
+#define RADIO_FROM_AIRALARM "radio_airalarm_rcvr" //devices interested in recieving signals from air alarms
+#define RADIO_CHAT "radio_telecoms"
+#define RADIO_ATMOSIA "radio_atmos"
+#define RADIO_NAVBEACONS "radio_navbeacon"
+#define RADIO_AIRLOCK "radio_airlock"
+#define RADIO_SECBOT "radio_secbot"
+#define RADIO_HONKBOT "radio_honkbot"
+#define RADIO_MULEBOT "radio_mulebot"
+#define RADIO_CLEANBOT "10"
+#define RADIO_FLOORBOT "11"
+#define RADIO_MEDBOT "12"
+#define RADIO_MAGNETS "radio_magnet"
+#define RADIO_LOGIC "radio_logic"
diff --git a/code/__DEFINES/reagents.dm b/code/__DEFINES/reagents.dm
index e2dd3ee3ac7..564247455e3 100644
--- a/code/__DEFINES/reagents.dm
+++ b/code/__DEFINES/reagents.dm
@@ -16,3 +16,6 @@
// Is an open container for all intents and purposes.
#define OPENCONTAINER (REFILLABLE | DRAINABLE | TRANSPARENT)
+
+#define REAGENT_TOUCH 1
+#define REAGENT_INGEST 2
diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm
index 34ad4d69e54..8021fa4452d 100644
--- a/code/__DEFINES/role_preferences.dm
+++ b/code/__DEFINES/role_preferences.dm
@@ -1,81 +1,81 @@
-
-
-//Values for antag preferences, event roles, etc. unified here
-
-
-
-//These are synced with the Database, if you change the values of the defines
-//then you MUST update the database!
-// If you're adding a new role, remember to update modules/admin/topic.dm, so admins can dish out
-// justice if someone's abusing your role
-#define ROLE_SYNDICATE "Syndicate"
-#define ROLE_TRAITOR "traitor"
-#define ROLE_OPERATIVE "operative"
-#define ROLE_CHANGELING "changeling"
-#define ROLE_WIZARD "wizard"
-#define ROLE_REV "revolutionary"
-#define ROLE_ALIEN "xenomorph"
-#define ROLE_PAI "pAI"
-#define ROLE_CULTIST "cultist"
-#define ROLE_BLOB "blob"
-#define ROLE_NINJA "space ninja"
-#define ROLE_MONKEY "monkey"
-#define ROLE_GANG "gangster"
-#define ROLE_SHADOWLING "shadowling"
-#define ROLE_ABDUCTOR "abductor"
-#define ROLE_REVENANT "revenant"
-#define ROLE_HOG_GOD "hand of god: god" // We're prolly gonna port this one day or another
-#define ROLE_HOG_CULTIST "hand of god: cultist"
-#define ROLE_DEVIL "devil"
-#define ROLE_RAIDER "vox raider"
-#define ROLE_TRADER "trader"
-#define ROLE_VAMPIRE "vampire"
-// Role tags for EVERYONE!
-#define ROLE_BORER "cortical borer"
-#define ROLE_DEMON "slaughter demon"
-#define ROLE_SENTIENT "sentient animal"
-#define ROLE_POSIBRAIN "positronic brain"
-#define ROLE_GUARDIAN "guardian"
-#define ROLE_MORPH "morph"
-#define ROLE_ERT "emergency response team"
-#define ROLE_NYMPH "Dionaea"
-#define ROLE_GSPIDER "giant spider"
-#define ROLE_DRONE "drone"
-#define ROLE_DEATHSQUAD "deathsquad"
-#define ROLE_EVENTMISC "eventmisc"
-#define ROLE_GHOST "ghost role"
-
-//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
-//(in game days played) to play that role
-var/global/list/special_roles = list(
- ROLE_ABDUCTOR = /datum/game_mode/abduction, // Abductor
- ROLE_BLOB = /datum/game_mode/blob, // Blob
- ROLE_CHANGELING = /datum/game_mode/changeling, // Changeling
- ROLE_BORER, // Cortical borer
- ROLE_CULTIST = /datum/game_mode/cult, // Cultist
- ROLE_DEVIL = /datum/game_mode/devil/devil_agents, // Devil
- ROLE_GSPIDER, // Giant spider
- ROLE_GUARDIAN, // Guardian
- ROLE_MORPH, // Morph
- ROLE_OPERATIVE = /datum/game_mode/nuclear, // Operative
- ROLE_PAI, // PAI
- ROLE_POSIBRAIN, // Positronic brain
- ROLE_REVENANT, // Revenant
- ROLE_REV = /datum/game_mode/revolution, // Revolutionary
- ROLE_SENTIENT, // Sentient animal
- ROLE_SHADOWLING = /datum/game_mode/shadowling, // Shadowling
- ROLE_DEMON, // Slaguther demon
- ROLE_NINJA, // Space ninja
- ROLE_TRADER, // Trader
- ROLE_TRAITOR = /datum/game_mode/traitor, // Traitor
- ROLE_VAMPIRE = /datum/game_mode/vampire, // Vampire
- ROLE_RAIDER = /datum/game_mode/heist, // Vox raider
- ROLE_ALIEN, // Xenomorph
- ROLE_WIZARD = /datum/game_mode/wizard, // Wizard
- // UNUSED/BROKEN ANTAGS
-// ROLE_HOG_GOD = /datum/game_mode/hand_of_god,
-// ROLE_HOG_CULTIST = /datum/game_mode/hand_of_god,
-// ROLE_MONKEY = /datum/game_mode/monkey, Sooner or later these are going to get ported
-// ROLE_GANG = /datum/game_mode/gang,
-)
+
+
+//Values for antag preferences, event roles, etc. unified here
+
+
+
+//These are synced with the Database, if you change the values of the defines
+//then you MUST update the database!
+// If you're adding a new role, remember to update modules/admin/topic.dm, so admins can dish out
+// justice if someone's abusing your role
+#define ROLE_SYNDICATE "Syndicate"
+#define ROLE_TRAITOR "traitor"
+#define ROLE_OPERATIVE "operative"
+#define ROLE_CHANGELING "changeling"
+#define ROLE_WIZARD "wizard"
+#define ROLE_REV "revolutionary"
+#define ROLE_ALIEN "xenomorph"
+#define ROLE_PAI "pAI"
+#define ROLE_CULTIST "cultist"
+#define ROLE_BLOB "blob"
+#define ROLE_NINJA "space ninja"
+#define ROLE_MONKEY "monkey"
+#define ROLE_GANG "gangster"
+#define ROLE_SHADOWLING "shadowling"
+#define ROLE_ABDUCTOR "abductor"
+#define ROLE_REVENANT "revenant"
+#define ROLE_HOG_GOD "hand of god: god" // We're prolly gonna port this one day or another
+#define ROLE_HOG_CULTIST "hand of god: cultist"
+#define ROLE_DEVIL "devil"
+#define ROLE_RAIDER "vox raider"
+#define ROLE_TRADER "trader"
+#define ROLE_VAMPIRE "vampire"
+// Role tags for EVERYONE!
+#define ROLE_BORER "cortical borer"
+#define ROLE_DEMON "slaughter demon"
+#define ROLE_SENTIENT "sentient animal"
+#define ROLE_POSIBRAIN "positronic brain"
+#define ROLE_GUARDIAN "guardian"
+#define ROLE_MORPH "morph"
+#define ROLE_ERT "emergency response team"
+#define ROLE_NYMPH "Dionaea"
+#define ROLE_GSPIDER "giant spider"
+#define ROLE_DRONE "drone"
+#define ROLE_DEATHSQUAD "deathsquad"
+#define ROLE_EVENTMISC "eventmisc"
+#define ROLE_GHOST "ghost role"
+
+//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
+//(in game days played) to play that role
+GLOBAL_LIST_INIT(special_roles, list(
+ ROLE_ABDUCTOR = /datum/game_mode/abduction, // Abductor
+ ROLE_BLOB = /datum/game_mode/blob, // Blob
+ ROLE_CHANGELING = /datum/game_mode/changeling, // Changeling
+ ROLE_BORER, // Cortical borer
+ ROLE_CULTIST = /datum/game_mode/cult, // Cultist
+ ROLE_DEVIL = /datum/game_mode/devil/devil_agents, // Devil
+ ROLE_GSPIDER, // Giant spider
+ ROLE_GUARDIAN, // Guardian
+ ROLE_MORPH, // Morph
+ ROLE_OPERATIVE = /datum/game_mode/nuclear, // Operative
+ ROLE_PAI, // PAI
+ ROLE_POSIBRAIN, // Positronic brain
+ ROLE_REVENANT, // Revenant
+ ROLE_REV = /datum/game_mode/revolution, // Revolutionary
+ ROLE_SENTIENT, // Sentient animal
+ ROLE_SHADOWLING = /datum/game_mode/shadowling, // Shadowling
+ ROLE_DEMON, // Slaguther demon
+ ROLE_NINJA, // Space ninja
+ ROLE_TRADER, // Trader
+ ROLE_TRAITOR = /datum/game_mode/traitor, // Traitor
+ ROLE_VAMPIRE = /datum/game_mode/vampire, // Vampire
+ ROLE_RAIDER = /datum/game_mode/heist, // Vox raider
+ ROLE_ALIEN, // Xenomorph
+ ROLE_WIZARD = /datum/game_mode/wizard // Wizard
+ // UNUSED/BROKEN ANTAGS
+// ROLE_HOG_GOD = /datum/game_mode/hand_of_god,
+// ROLE_HOG_CULTIST = /datum/game_mode/hand_of_god,
+// ROLE_MONKEY = /datum/game_mode/monkey, Sooner or later these are going to get ported
+// ROLE_GANG = /datum/game_mode/gang
+))
diff --git a/code/__DEFINES/rolebans.dm b/code/__DEFINES/rolebans.dm
index d6e54abf14a..ad6f1324afa 100644
--- a/code/__DEFINES/rolebans.dm
+++ b/code/__DEFINES/rolebans.dm
@@ -1,5 +1,5 @@
// Bannable antag roles
-var/global/list/antag_roles = list(
+GLOBAL_LIST_INIT(antag_roles, list(
ROLE_TRAITOR,
ROLE_OPERATIVE,
ROLE_CHANGELING,
@@ -18,14 +18,14 @@ var/global/list/antag_roles = list(
ROLE_GUARDIAN,
ROLE_MORPH,
ROLE_GSPIDER,
-)
+))
// Bannable other roles
-var/global/list/other_roles = list(
+GLOBAL_LIST_INIT(other_roles, list(
ROLE_SENTIENT,
ROLE_NYMPH,
ROLE_ERT,
ROLE_GHOST,
"AntagHUD",
"Records"
-)
+))
diff --git a/code/__DEFINES/shuttle.dm b/code/__DEFINES/shuttle.dm
index 22af9a38670..72ed25d1518 100644
--- a/code/__DEFINES/shuttle.dm
+++ b/code/__DEFINES/shuttle.dm
@@ -13,4 +13,4 @@
#define SHUTTLE_DOCKER_LANDING_CLEAR 1
#define SHUTTLE_DOCKER_BLOCKED_BY_HIDDEN_PORT 2
-#define SHUTTLE_DOCKER_BLOCKED 3
\ No newline at end of file
+#define SHUTTLE_DOCKER_BLOCKED 3
diff --git a/code/__DEFINES/sight.dm b/code/__DEFINES/sight.dm
index 58f557c4b75..52fc66aa814 100644
--- a/code/__DEFINES/sight.dm
+++ b/code/__DEFINES/sight.dm
@@ -38,4 +38,4 @@
#define VISOR_TINT (1<<1)
#define VISOR_VISIONFLAGS (1<<2) //all following flags only matter for glasses
#define VISOR_DARKNESSVIEW (1<<3)
-#define VISOR_INVISVIEW (1<<4)
\ No newline at end of file
+#define VISOR_INVISVIEW (1<<4)
diff --git a/code/__DEFINES/sound.dm b/code/__DEFINES/sound.dm
index 7e131dcaa21..b0274e9d802 100644
--- a/code/__DEFINES/sound.dm
+++ b/code/__DEFINES/sound.dm
@@ -14,4 +14,4 @@
#define SOUND_MINIMUM_PRESSURE 10
-#define FALLOFF_SOUNDS 0.5
\ No newline at end of file
+#define FALLOFF_SOUNDS 0.5
diff --git a/code/__DEFINES/station_goals.dm b/code/__DEFINES/station_goals.dm
index 7c13f4f9e67..0c19da7b5f1 100644
--- a/code/__DEFINES/station_goals.dm
+++ b/code/__DEFINES/station_goals.dm
@@ -1,2 +1,2 @@
#define BSA_SIZE_FRONT 4
-#define BSA_SIZE_BACK 6
\ No newline at end of file
+#define BSA_SIZE_BACK 6
diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm
index 6a14e6fae66..54b85d80e76 100644
--- a/code/__DEFINES/status_effects.dm
+++ b/code/__DEFINES/status_effects.dm
@@ -81,4 +81,4 @@
#define STATUS_EFFECT_CRUSHERDAMAGETRACKING /datum/status_effect/crusher_damage //tracks total kinetic crusher damage on a target
-#define STATUS_EFFECT_SYPHONMARK /datum/status_effect/syphon_mark //tracks kills for the KA death syphon module
\ No newline at end of file
+#define STATUS_EFFECT_SYPHONMARK /datum/status_effect/syphon_mark //tracks kills for the KA death syphon module
diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm
index c55fec2cd87..b1773ba10d5 100644
--- a/code/__DEFINES/subsystems.dm
+++ b/code/__DEFINES/subsystems.dm
@@ -66,6 +66,7 @@
#define INIT_ORDER_TIMER 1
#define INIT_ORDER_DEFAULT 0
#define INIT_ORDER_AIR -1
+#define INIT_ORDER_SUN -2
#define INIT_ORDER_MINIMAP -3
#define INIT_ORDER_ASSETS -4
#define INIT_ORDER_ICON_SMOOTHING -5
@@ -144,4 +145,4 @@
A.overlays |= po;\
}\
A.flags_2 &= ~OVERLAY_QUEUED_2;\
-}
\ No newline at end of file
+}
diff --git a/code/__DEFINES/typeids.dm b/code/__DEFINES/typeids.dm
index 16b6e475b8e..56e0958d1a4 100644
--- a/code/__DEFINES/typeids.dm
+++ b/code/__DEFINES/typeids.dm
@@ -3,4 +3,4 @@
#define TYPEID_NORMAL_LIST "f"
//helper macros
#define GET_TYPEID(ref) ( ( (length(ref) <= 10) ? "TYPEID_NULL" : copytext(ref, 4, length(ref) - 6) ) )
-#define IS_NORMAL_LIST(L) (GET_TYPEID("\ref[L]") == TYPEID_NORMAL_LIST)
\ No newline at end of file
+#define IS_NORMAL_LIST(L) (GET_TYPEID("\ref[L]") == TYPEID_NORMAL_LIST)
diff --git a/code/__DEFINES/vv.dm b/code/__DEFINES/vv.dm
index 22e13f87f8a..0ac352f9ae9 100644
--- a/code/__DEFINES/vv.dm
+++ b/code/__DEFINES/vv.dm
@@ -19,4 +19,4 @@
#define VV_NULL "NULL"
#define VV_RESTORE_DEFAULT "Restore to Default"
#define VV_MARKED_DATUM "Marked Datum"
-#define VV_REGEX "Regex"
\ No newline at end of file
+#define VV_REGEX "Regex"
diff --git a/code/__HELPERS/AnimationLibrary.dm b/code/__HELPERS/AnimationLibrary.dm
index fd79fe197f2..cc496a85b63 100644
--- a/code/__HELPERS/AnimationLibrary.dm
+++ b/code/__HELPERS/AnimationLibrary.dm
@@ -187,4 +187,4 @@
var/original_y = A.pixel_y
animate(A, transform = matrix(punchstr, MATRIX_ROTATE), pixel_y = 16, time = 2, color = "#eeeeee", easing = BOUNCE_EASING)
animate(transform = matrix(-punchstr, MATRIX_ROTATE), pixel_y = original_y, time = 2, color = "#ffffff", easing = BOUNCE_EASING)
- animate(transform = null, time = 3, easing = BOUNCE_EASING)
\ No newline at end of file
+ animate(transform = null, time = 3, easing = BOUNCE_EASING)
diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm
index 7a91c3bf9bc..f5d582f5e42 100644
--- a/code/__HELPERS/_logging.dm
+++ b/code/__HELPERS/_logging.dm
@@ -5,7 +5,7 @@
// will get logs that are one big line if the system is Linux and they are using notepad. This solves it by adding CR to every line ending
// in the logs. ascii character 13 = CR
-/var/global/log_end = world.system_type == UNIX ? ascii2text(13) : ""
+GLOBAL_VAR_INIT(log_end, (world.system_type == UNIX ? ascii2text(13) : ""))
#define DIRECT_OUTPUT(A, B) A << B
#define SEND_IMAGE(target, image) DIRECT_OUTPUT(target, image)
@@ -30,13 +30,13 @@
#endif
/proc/log_admin(text)
- admin_log.Add(text)
+ GLOB.admin_log.Add(text)
if(config.log_admin)
- WRITE_LOG(GLOB.world_game_log, "ADMIN: [text][log_end]")
+ WRITE_LOG(GLOB.world_game_log, "ADMIN: [text][GLOB.log_end]")
/proc/log_debug(text)
if(config.log_debug)
- WRITE_LOG(GLOB.world_game_log, "DEBUG: [text][log_end]")
+ WRITE_LOG(GLOB.world_game_log, "DEBUG: [text][GLOB.log_end]")
for(var/client/C in GLOB.admins)
if(check_rights(R_DEBUG, 0, C.mob) && (C.prefs.toggles & CHAT_DEBUGLOGS))
@@ -44,88 +44,88 @@
/proc/log_game(text)
if(config.log_game)
- WRITE_LOG(GLOB.world_game_log, "GAME: [text][log_end]")
+ WRITE_LOG(GLOB.world_game_log, "GAME: [text][GLOB.log_end]")
/proc/log_vote(text)
if(config.log_vote)
- WRITE_LOG(GLOB.world_game_log, "VOTE: [text][log_end]")
+ WRITE_LOG(GLOB.world_game_log, "VOTE: [text][GLOB.log_end]")
/proc/log_access_in(client/new_client)
if(config.log_access)
var/message = "[key_name(new_client)] - IP:[new_client.address] - CID:[new_client.computer_id] - BYOND v[new_client.byond_version]"
- WRITE_LOG(GLOB.world_game_log, "ACCESS IN: [message][log_end]")
+ WRITE_LOG(GLOB.world_game_log, "ACCESS IN: [message][GLOB.log_end]")
/proc/log_access_out(mob/last_mob)
if(config.log_access)
var/message = "[key_name(last_mob)] - IP:[last_mob.lastKnownIP] - CID:[last_mob.computer_id] - BYOND Logged Out"
- WRITE_LOG(GLOB.world_game_log, "ACCESS OUT: [message][log_end]")
+ WRITE_LOG(GLOB.world_game_log, "ACCESS OUT: [message][GLOB.log_end]")
/proc/log_say(text, mob/speaker)
if(config.log_say)
- WRITE_LOG(GLOB.world_game_log, "SAY: [speaker.simple_info_line()]: [html_decode(text)][log_end]")
+ WRITE_LOG(GLOB.world_game_log, "SAY: [speaker.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
/proc/log_whisper(text, mob/speaker)
if(config.log_whisper)
- WRITE_LOG(GLOB.world_game_log, "WHISPER: [speaker.simple_info_line()]: [html_decode(text)][log_end]")
+ WRITE_LOG(GLOB.world_game_log, "WHISPER: [speaker.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
/proc/log_ooc(text, client/user)
if(config.log_ooc)
- WRITE_LOG(GLOB.world_game_log, "OOC: [user.simple_info_line()]: [html_decode(text)][log_end]")
+ WRITE_LOG(GLOB.world_game_log, "OOC: [user.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
/proc/log_aooc(text, client/user)
if(config.log_ooc)
- WRITE_LOG(GLOB.world_game_log, "AOOC: [user.simple_info_line()]: [html_decode(text)][log_end]")
+ WRITE_LOG(GLOB.world_game_log, "AOOC: [user.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
/proc/log_looc(text, client/user)
if(config.log_ooc)
- WRITE_LOG(GLOB.world_game_log, "LOOC: [user.simple_info_line()]: [html_decode(text)][log_end]")
+ WRITE_LOG(GLOB.world_game_log, "LOOC: [user.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
/proc/log_emote(text, mob/speaker)
if(config.log_emote)
- WRITE_LOG(GLOB.world_game_log, "EMOTE: [speaker.simple_info_line()]: [html_decode(text)][log_end]")
+ WRITE_LOG(GLOB.world_game_log, "EMOTE: [speaker.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
/proc/log_attack(attacker, defender, message)
if(config.log_attack)
- WRITE_LOG(GLOB.world_game_log, "ATTACK: [attacker] against [defender]: [message][log_end]") //Seperate attack logs? Why?
+ WRITE_LOG(GLOB.world_game_log, "ATTACK: [attacker] against [defender]: [message][GLOB.log_end]") //Seperate attack logs? Why?
/proc/log_adminsay(text, mob/speaker)
if(config.log_adminchat)
- WRITE_LOG(GLOB.world_game_log, "ADMINSAY: [speaker.simple_info_line()]: [html_decode(text)][log_end]")
+ WRITE_LOG(GLOB.world_game_log, "ADMINSAY: [speaker.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
/proc/log_qdel(text)
WRITE_LOG(GLOB.world_qdel_log, "QDEL: [text]")
/proc/log_mentorsay(text, mob/speaker)
if(config.log_adminchat)
- WRITE_LOG(GLOB.world_game_log, "MENTORSAY: [speaker.simple_info_line()]: [html_decode(text)][log_end]")
+ WRITE_LOG(GLOB.world_game_log, "MENTORSAY: [speaker.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
/proc/log_ghostsay(text, mob/speaker)
if(config.log_say)
- WRITE_LOG(GLOB.world_game_log, "DEADCHAT: [speaker.simple_info_line()]: [html_decode(text)][log_end]")
+ WRITE_LOG(GLOB.world_game_log, "DEADCHAT: [speaker.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
/proc/log_ghostemote(text, mob/speaker)
if(config.log_emote)
- WRITE_LOG(GLOB.world_game_log, "DEADEMOTE: [speaker.simple_info_line()]: [html_decode(text)][log_end]")
+ WRITE_LOG(GLOB.world_game_log, "DEADEMOTE: [speaker.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
/proc/log_adminwarn(text)
if(config.log_adminwarn)
- WRITE_LOG(GLOB.world_game_log, "ADMINWARN: [html_decode(text)][log_end]")
+ WRITE_LOG(GLOB.world_game_log, "ADMINWARN: [html_decode(text)][GLOB.log_end]")
/proc/log_pda(text, mob/speaker)
if(config.log_pda)
- WRITE_LOG(GLOB.world_game_log, "PDA: [speaker.simple_info_line()]: [html_decode(text)][log_end]")
+ WRITE_LOG(GLOB.world_game_log, "PDA: [speaker.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
/proc/log_chat(text, mob/speaker)
if(config.log_pda)
- WRITE_LOG(GLOB.world_game_log, "CHAT: [speaker.simple_info_line()] [html_decode(text)][log_end]")
+ WRITE_LOG(GLOB.world_game_log, "CHAT: [speaker.simple_info_line()] [html_decode(text)][GLOB.log_end]")
/proc/log_misc(text)
- WRITE_LOG(GLOB.world_game_log, "MISC: [text][log_end]")
+ WRITE_LOG(GLOB.world_game_log, "MISC: [text][GLOB.log_end]")
/proc/log_world(text)
SEND_TEXT(world.log, text)
if(config && config.log_world_output)
- WRITE_LOG(GLOB.world_game_log, "WORLD: [html_decode(text)][log_end]")
+ WRITE_LOG(GLOB.world_game_log, "WORLD: [html_decode(text)][GLOB.log_end]")
/proc/log_runtime_txt(text) // different from /tg/'s log_runtime because our error handler has a log_runtime proc already that does other stuff
WRITE_LOG(GLOB.world_runtime_log, text)
diff --git a/code/__HELPERS/_string_lists.dm b/code/__HELPERS/_string_lists.dm
index 36aa2f9b6fa..e2f0c6081e7 100644
--- a/code/__HELPERS/_string_lists.dm
+++ b/code/__HELPERS/_string_lists.dm
@@ -2,15 +2,15 @@
#define pick_list_replacements(FILE, KEY) (strings_replacement(FILE, KEY))
#define json_load(FILE) (json_decode(file2text(FILE)))
-var/global/list/string_cache
-var/global/list/string_filename_current_key
+GLOBAL_LIST_EMPTY(string_cache)
+GLOBAL_LIST_EMPTY(string_filename_current_key)
/proc/strings_replacement(filename, key)
load_strings_file(filename)
- if((filename in string_cache) && (key in string_cache[filename]))
- var/response = pick(string_cache[filename][key])
+ if((filename in GLOB.string_cache) && (key in GLOB.string_cache[filename]))
+ var/response = pick(GLOB.string_cache[filename][key])
var/regex/r = regex("@pick\\((\\D+?)\\)", "g")
response = r.Replace(response, /proc/strings_subkey_lookup)
return response
@@ -19,23 +19,23 @@ var/global/list/string_filename_current_key
/proc/strings(filename as text, key as text)
load_strings_file(filename)
- if((filename in string_cache) && (key in string_cache[filename]))
- return string_cache[filename][key]
+ if((filename in GLOB.string_cache) && (key in GLOB.string_cache[filename]))
+ return GLOB.string_cache[filename][key]
else
CRASH("strings list not found: strings/[filename], index=[key]")
/proc/strings_subkey_lookup(match, group1)
- return pick_list(string_filename_current_key, group1)
+ return pick_list(GLOB.string_filename_current_key, group1)
/proc/load_strings_file(filename)
- string_filename_current_key = filename
- if(filename in string_cache)
+ GLOB.string_filename_current_key = filename
+ if(filename in GLOB.string_cache)
return //no work to do
- if(!string_cache)
- string_cache = new
+ if(!GLOB.string_cache)
+ GLOB.string_cache = new
if(fexists("strings/[filename]"))
- string_cache[filename] = json_load("strings/[filename]")
+ GLOB.string_cache[filename] = json_load("strings/[filename]")
else
CRASH("file not found: strings/[filename]")
diff --git a/code/__HELPERS/cmp.dm b/code/__HELPERS/cmp.dm
index 0db57b27eae..afb70cb81e6 100644
--- a/code/__HELPERS/cmp.dm
+++ b/code/__HELPERS/cmp.dm
@@ -47,4 +47,4 @@
if(A.plane != B.plane)
return A.plane - B.plane
else
- return A.layer - B.layer
\ No newline at end of file
+ return A.layer - B.layer
diff --git a/code/__HELPERS/constants.dm b/code/__HELPERS/constants.dm
index f7db3166605..b976a28e195 100644
--- a/code/__HELPERS/constants.dm
+++ b/code/__HELPERS/constants.dm
@@ -1,2 +1,2 @@
-var/global/const/TICKS_IN_DAY = 864000
-var/global/const/TICKS_IN_SECOND = 10
\ No newline at end of file
+#define TICKS_IN_DAY 864000
+#define TICKS_IN_SECOND 10
diff --git a/code/__HELPERS/experimental.dm b/code/__HELPERS/experimental.dm
index 533f67b68d9..4f13c07cbd4 100644
--- a/code/__HELPERS/experimental.dm
+++ b/code/__HELPERS/experimental.dm
@@ -48,4 +48,4 @@
if(A != myArea)
myArea = A
- . = myArea
\ No newline at end of file
+ . = myArea
diff --git a/code/__HELPERS/files.dm b/code/__HELPERS/files.dm
index 27f3537d521..0a58ed035f7 100644
--- a/code/__HELPERS/files.dm
+++ b/code/__HELPERS/files.dm
@@ -1,60 +1,62 @@
-//checks if a file exists and contains text
-//returns text as a string if these conditions are met
-/proc/return_file_text(filename)
- if(fexists(filename) == 0)
- error("File not found ([filename])")
- return
-
- var/text = file2text(filename)
- if(!text)
- error("File empty ([filename])")
- return
-
- return text
-
-//Sends resource files to client cache
-/client/proc/getFiles()
- for(var/file in args)
- src << browse_rsc(file)
-
-/client/proc/browse_files(root="data/logs/", max_iterations=10, list/valid_extensions=list(".txt",".log",".htm"))
- var/path = root
-
- for(var/i=0, iError: browse_files(): File not found/Invalid file([path]).")
- return
-
- return path
-
-#define FTPDELAY 200 //200 tick delay to discourage spam
-/* This proc is a failsafe to prevent spamming of file requests.
- It is just a timer that only permits a download every [FTPDELAY] ticks.
- This can be changed by modifying FTPDELAY's value above.
-
- PLEASE USE RESPONSIBLY, Some log files canr each sizes of 4MB! */
-/client/proc/file_spam_check()
- var/time_to_wait = fileaccess_timer - world.time
- if(time_to_wait > 0)
- to_chat(src, "Error: file_spam_check(): Spam. Please wait [round(time_to_wait/10)] seconds.")
- return 1
- fileaccess_timer = world.time + FTPDELAY
- return 0
-#undef FTPDELAY
\ No newline at end of file
+//checks if a file exists and contains text
+//returns text as a string if these conditions are met
+/proc/return_file_text(filename)
+ if(fexists(filename) == 0)
+ error("File not found ([filename])")
+ return
+
+ var/text = file2text(filename)
+ if(!text)
+ error("File empty ([filename])")
+ return
+
+ return text
+
+//Sends resource files to client cache
+/client/proc/getFiles()
+ for(var/file in args)
+ src << browse_rsc(file)
+
+/client/proc/browse_files(root="data/logs/", max_iterations=10, list/valid_extensions=list(".txt",".log",".htm"))
+ // wow why was this ever a parameter
+ root = "data/logs/"
+ var/path = root
+
+ for(var/i=0, iError: browse_files(): File not found/Invalid file([path]).")
+ return
+
+ return path
+
+#define FTPDELAY 200 //200 tick delay to discourage spam
+/* This proc is a failsafe to prevent spamming of file requests.
+ It is just a timer that only permits a download every [FTPDELAY] ticks.
+ This can be changed by modifying FTPDELAY's value above.
+
+ PLEASE USE RESPONSIBLY, Some log files canr each sizes of 4MB! */
+/client/proc/file_spam_check()
+ var/time_to_wait = GLOB.fileaccess_timer - world.time
+ if(time_to_wait > 0)
+ to_chat(src, "Error: file_spam_check(): Spam. Please wait [round(time_to_wait/10)] seconds.")
+ return 1
+ GLOB.fileaccess_timer = world.time + FTPDELAY
+ return 0
+#undef FTPDELAY
diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index 0ab10447f8c..2217271a2e7 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -1,539 +1,523 @@
-/proc/get_area(atom/A)
- if(isarea(A))
- return A
- var/turf/T = get_turf(A)
- return T ? T.loc : null
-
-/proc/get_area_name(N) //get area by its name
- for(var/area/A in world)
- if(A.name == N)
- return A
- return 0
-
-/proc/get_location_name(atom/X, format_text = FALSE)
- var/area/A = isarea(X) ? X : get_area(X)
- if(!A)
- return null
- return format_text ? format_text(A.name) : A.name
-
-/proc/get_areas_in_range(dist=0, atom/center=usr)
- if(!dist)
- var/turf/T = get_turf(center)
- return T ? list(T.loc) : list()
- if(!center)
- return list()
-
- var/list/turfs = RANGE_TURFS(dist, center)
- var/list/areas = list()
- for(var/V in turfs)
- var/turf/T = V
- areas |= T.loc
- return areas
-
-// Like view but bypasses luminosity check
-
-/proc/hear(var/range, var/atom/source)
- var/lum = source.luminosity
- source.luminosity = 6
-
- var/list/heard = view(range, source)
- source.luminosity = lum
-
- return heard
-
-/proc/circlerange(center=usr,radius=3)
-
- var/turf/centerturf = get_turf(center)
- var/list/turfs = new/list()
- var/rsq = radius * (radius+0.5)
-
- for(var/atom/T in range(radius, centerturf))
- var/dx = T.x - centerturf.x
- var/dy = T.y - centerturf.y
- if(dx*dx + dy*dy <= rsq)
- turfs += T
-
- //turfs += centerturf
- return turfs
-
-/proc/circleview(center=usr,radius=3)
-
- var/turf/centerturf = get_turf(center)
- var/list/atoms = new/list()
- var/rsq = radius * (radius+0.5)
-
- for(var/atom/A in view(radius, centerturf))
- var/dx = A.x - centerturf.x
- var/dy = A.y - centerturf.y
- if(dx*dx + dy*dy <= rsq)
- atoms += A
-
- //turfs += centerturf
- return atoms
-
-/proc/ff_cansee(atom/A, atom/B)
- var/AT = get_turf(A)
- var/BT = get_turf(B)
- if(AT == BT)
- return 1
- var/list/line = getline(A, B)
- for(var/turf/T in line)
- if(T == AT || T == BT)
- break
- if(T.density)
- return FALSE
- return TRUE
-
-/proc/get_dist_euclidian(atom/Loc1 as turf|mob|obj,atom/Loc2 as turf|mob|obj)
- var/dx = Loc1.x - Loc2.x
- var/dy = Loc1.y - Loc2.y
-
- var/dist = sqrt(dx**2 + dy**2)
-
- return dist
-
-/proc/circlerangeturfs(center=usr,radius=3)
-
- var/turf/centerturf = get_turf(center)
- var/list/turfs = new/list()
- var/rsq = radius * (radius+0.5)
-
- for(var/turf/T in range(radius, centerturf))
- var/dx = T.x - centerturf.x
- var/dy = T.y - centerturf.y
- if(dx*dx + dy*dy <= rsq)
- turfs += T
- return turfs
-
-/proc/circleviewturfs(center=usr,radius=3) //Is there even a diffrence between this proc and circlerangeturfs()?
-
- var/turf/centerturf = get_turf(center)
- var/list/turfs = new/list()
- var/rsq = radius * (radius+0.5)
-
- for(var/turf/T in view(radius, centerturf))
- var/dx = T.x - centerturf.x
- var/dy = T.y - centerturf.y
- if(dx*dx + dy*dy <= rsq)
- turfs += T
- return turfs
-
-
-
-//var/debug_mob = 0
-
-// Will recursively loop through an atom's contents and check for mobs, then it will loop through every atom in that atom's contents.
-// It will keep doing this until it checks every content possible. This will fix any problems with mobs, that are inside objects,
-// being unable to hear people due to being in a box within a bag.
-
-/proc/recursive_mob_check(var/atom/O, var/list/L = list(), var/recursion_limit = 3, var/client_check = 1, var/sight_check = 1, var/include_radio = 1)
-
- //debug_mob += O.contents.len
- if(!recursion_limit)
- return L
- for(var/atom/A in O.contents)
-
- if(ismob(A))
- var/mob/M = A
- if(client_check && !M.client)
- L |= recursive_mob_check(A, L, recursion_limit - 1, client_check, sight_check, include_radio)
- continue
- if(sight_check && !isInSight(A, O))
- continue
- L |= M
- //log_world("[recursion_limit] = [M] - [get_turf(M)] - ([M.x], [M.y], [M.z])")
-
- else if(include_radio && istype(A, /obj/item/radio))
- if(sight_check && !isInSight(A, O))
- continue
- L |= A
-
- if(isobj(A) || ismob(A))
- L |= recursive_mob_check(A, L, recursion_limit - 1, client_check, sight_check, include_radio)
- return L
-
-// The old system would loop through lists for a total of 5000 per function call, in an empty server.
-// This new system will loop at around 1000 in an empty server.
-
-/proc/get_mobs_in_view(var/R, var/atom/source, var/include_clientless = FALSE)
- // Returns a list of mobs in range of R from source. Used in radio and say code.
-
- var/turf/T = get_turf(source)
- var/list/hear = list()
-
- if(!T)
- return hear
-
- var/list/range = hear(R, T)
-
- for(var/atom/A in range)
- if(ismob(A))
- var/mob/M = A
- if(M.client || include_clientless)
- hear += M
- //log_world("Start = [M] - [get_turf(M)] - ([M.x], [M.y], [M.z])")
- else if(istype(A, /obj/item/radio))
- hear += A
-
- if(isobj(A) || ismob(A))
- hear |= recursive_mob_check(A, hear, 3, 1, 0, 1)
-
- return hear
-
-
-/proc/get_mobs_in_radio_ranges(var/list/obj/item/radio/radios)
-
- set background = 1
-
- . = list()
- // Returns a list of mobs who can hear any of the radios given in @radios
- var/list/speaker_coverage = list()
- for(var/obj/item/radio/R in radios)
- if(R)
- //Cyborg checks. Receiving message uses a bit of cyborg's charge.
- var/obj/item/radio/borg/BR = R
- if(istype(BR) && BR.myborg)
- var/mob/living/silicon/robot/borg = BR.myborg
- var/datum/robot_component/CO = borg.get_component("radio")
- if(!CO)
- continue //No radio component (Shouldn't happen)
- if(!borg.is_component_functioning("radio"))
- continue //No power.
-
- var/turf/speaker = get_turf(R)
- if(speaker)
- for(var/turf/T in hear(R.canhear_range,speaker))
- speaker_coverage[T] = T
-
-
- // Try to find all the players who can hear the message
- for(var/A in GLOB.player_list + GLOB.hear_radio_list)
- var/mob/M = A
- if(M)
- var/turf/ear = get_turf(M)
- if(ear)
- // Ghostship is magic: Ghosts can hear radio chatter from anywhere
- if(speaker_coverage[ear] || (istype(M, /mob/dead/observer) && M.get_preference(CHAT_GHOSTRADIO)))
- . |= M // Since we're already looping through mobs, why bother using |= ? This only slows things down.
- return .
-
-/proc/inLineOfSight(X1,Y1,X2,Y2,Z=1,PX1=16.5,PY1=16.5,PX2=16.5,PY2=16.5)
- var/turf/T
- if(X1==X2)
- if(Y1==Y2)
- return 1 //Light cannot be blocked on same tile
- else
- var/s = SIMPLE_SIGN(Y2-Y1)
- Y1+=s
- while(Y1!=Y2)
- T=locate(X1,Y1,Z)
- if(T.opacity)
- return 0
- Y1+=s
- else
- var/m=(32*(Y2-Y1)+(PY2-PY1))/(32*(X2-X1)+(PX2-PX1))
- var/b=(Y1+PY1/32-0.015625)-m*(X1+PX1/32-0.015625) //In tiles
- var/signX = SIMPLE_SIGN(X2-X1)
- var/signY = SIMPLE_SIGN(Y2-Y1)
- if(X1 abs (dx)) //slope is above 1:1 (move horizontally in a tie)
- if(dy > 0)
- return get_step(start, SOUTH)
- else
- return get_step(start, NORTH)
- else
- if(dx > 0)
- return get_step(start, WEST)
- else
- return get_step(start, EAST)
-
-/proc/try_move_adjacent(atom/movable/AM)
- var/turf/T = get_turf(AM)
- for(var/direction in cardinal)
- if(AM.Move(get_step(T, direction)))
- break
-
-/proc/get_mob_by_key(var/key)
- for(var/mob/M in GLOB.mob_list)
- if(M.ckey == lowertext(key))
- return M
- return null
-
-/proc/get_candidates(be_special_type, afk_bracket=3000, override_age=0, override_jobban=0)
- var/roletext = get_roletext(be_special_type)
- var/list/candidates = list()
- // Keep looping until we find a non-afk candidate within the time bracket (we limit the bracket to 10 minutes (6000))
- while(!candidates.len && afk_bracket < 6000)
- for(var/mob/dead/observer/G in GLOB.player_list)
- if(G.client != null)
- if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
- if(!G.client.is_afk(afk_bracket) && (be_special_type in G.client.prefs.be_special))
- if(!override_jobban || (!jobban_isbanned(G, roletext) && !jobban_isbanned(G,"Syndicate")))
- if(override_age || player_old_enough_antag(G.client,be_special_type))
- candidates += G.client
- afk_bracket += 600 // Add a minute to the bracket, for every attempt
-
- return candidates
-
-/proc/get_candidate_ghosts(be_special_type, afk_bracket=3000, override_age=0, override_jobban=0)
- var/roletext = get_roletext(be_special_type)
- var/list/candidates = list()
- // Keep looping until we find a non-afk candidate within the time bracket (we limit the bracket to 10 minutes (6000))
- while(!candidates.len && afk_bracket < 6000)
- for(var/mob/dead/observer/G in GLOB.player_list)
- if(G.client != null)
- if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
- if(!G.client.is_afk(afk_bracket) && (be_special_type in G.client.prefs.be_special))
- if(!override_jobban || (!jobban_isbanned(G, roletext) && !jobban_isbanned(G,"Syndicate")))
- if(override_age || player_old_enough_antag(G.client,be_special_type))
- candidates += G
- afk_bracket += 600 // Add a minute to the bracket, for every attempt
-
- return candidates
-
-/proc/ScreenText(obj/O, maptext="", screen_loc="CENTER-7,CENTER-7", maptext_height=480, maptext_width=480)
- if(!isobj(O)) O = new /obj/screen/text()
- O.maptext = maptext
- O.maptext_height = maptext_height
- O.maptext_width = maptext_width
- O.screen_loc = screen_loc
- return O
-
-/proc/Show2Group4Delay(obj/O, list/group, delay=0)
- if(!isobj(O)) return
- if(!group) group = GLOB.clients
- for(var/client/C in group)
- C.screen += O
- if(delay)
- spawn(delay)
- for(var/client/C in group)
- C.screen -= O
-
-/proc/flick_overlay(image/I, list/show_to, duration)
- for(var/client/C in show_to)
- C.images += I
- spawn(duration)
- for(var/client/C in show_to)
- C.images -= I
-
-/proc/get_active_player_count()
- // Get active players who are playing in the round
- var/active_players = 0
- for(var/i = 1; i <= GLOB.player_list.len; i++)
- var/mob/M = GLOB.player_list[i]
- if(M && M.client)
- if(istype(M, /mob/new_player)) // exclude people in the lobby
- continue
- else if(isobserver(M)) // Ghosts are fine if they were playing once (didn't start as observers)
- var/mob/dead/observer/O = M
- if(O.started_as_observer) // Exclude people who started as observers
- continue
- active_players++
- return active_players
-
-/datum/projectile_data
- var/src_x
- var/src_y
- var/time
- var/distance
- var/power_x
- var/power_y
- var/dest_x
- var/dest_y
-
-/datum/projectile_data/New(var/src_x, var/src_y, var/time, var/distance, \
- var/power_x, var/power_y, var/dest_x, var/dest_y)
- src.src_x = src_x
- src.src_y = src_y
- src.time = time
- src.distance = distance
- src.power_x = power_x
- src.power_y = power_y
- src.dest_x = dest_x
- src.dest_y = dest_y
-
-/proc/projectile_trajectory(var/src_x, var/src_y, var/rotation, var/angle, var/power)
-
- // returns the destination (Vx,y) that a projectile shot at [src_x], [src_y], with an angle of [angle],
- // rotated at [rotation] and with the power of [power]
- // Thanks to VistaPOWA for this function
-
- var/power_x = power * cos(angle)
- var/power_y = power * sin(angle)
- var/time = 2* power_y / 10 //10 = g
-
- var/distance = time * power_x
-
- var/dest_x = src_x + distance*sin(rotation);
- var/dest_y = src_y + distance*cos(rotation);
-
- return new /datum/projectile_data(src_x, src_y, time, distance, power_x, power_y, dest_x, dest_y)
-
-
-/proc/mobs_in_area(var/area/the_area, var/client_needed=0, var/moblist=GLOB.mob_list)
- var/list/mobs_found[0]
- var/area/our_area = get_area(the_area)
- for(var/mob/M in moblist)
- if(client_needed && !M.client)
- continue
- if(our_area != get_area(M))
- continue
- mobs_found += M
- return mobs_found
-
-/proc/alone_in_area(var/area/the_area, var/mob/must_be_alone, var/check_type = /mob/living/carbon)
- var/area/our_area = get_area(the_area)
- for(var/C in GLOB.living_mob_list)
- if(!istype(C, check_type))
- continue
- if(C == must_be_alone)
- continue
- if(our_area == get_area(C))
- return 0
- return 1
-
-
-/proc/GetRedPart(const/hexa)
- return hex2num(copytext(hexa, 2, 4))
-
-/proc/GetGreenPart(const/hexa)
- return hex2num(copytext(hexa, 4, 6))
-
-/proc/GetBluePart(const/hexa)
- return hex2num(copytext(hexa, 6, 8))
-
-/proc/lavaland_equipment_pressure_check(turf/T)
- . = FALSE
- if(!istype(T))
- return
- var/datum/gas_mixture/environment = T.return_air()
- if(!istype(environment))
- return
- var/pressure = environment.return_pressure()
- if(pressure <= LAVALAND_EQUIPMENT_EFFECT_PRESSURE)
- . = TRUE
-
-/proc/GetHexColors(const/hexa)
- return list(
- GetRedPart(hexa),
- GetGreenPart(hexa),
- GetBluePart(hexa),
- )
-
-/proc/MinutesToTicks(var/minutes as num)
- return minutes * 60 * 10
-
-/proc/SecondsToTicks(var/seconds)
- return seconds * 10
-
-proc/pollCandidates(Question, be_special_type, antag_age_check = FALSE, poll_time = 300, ignore_respawnability = FALSE, 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
- if(!Question)
- Question = "Would you like to be a special role?"
-
- for(var/mob/dead/observer/G in (ignore_respawnability ? GLOB.player_list : GLOB.respawnable_list))
- if(!G.key || !G.client)
- continue
- if(be_special_type)
- if(!(be_special_type in G.client.prefs.be_special))
- continue
- if(antag_age_check)
- if(!player_old_enough_antag(G.client, be_special_type))
- continue
- if(roletext)
- if(jobban_isbanned(G, roletext) || jobban_isbanned(G, "Syndicate"))
- continue
- if(config.use_exp_restrictions && min_hours)
- if(G.client.get_exp_type_num(EXP_TYPE_LIVING) < min_hours * 60)
- continue
- if(check_antaghud && cannotPossess(G))
- continue
- spawn(0)
- G << 'sound/misc/notice2.ogg'//Alerting them to their consideration
- if(flashwindow)
- window_flash(G.client)
- var/ans = alert(G,Question,"Please answer in [poll_time/10] seconds!","No","Yes","Not This Round")
- if(!G?.client)
- return
- switch(ans)
- if("Yes")
- to_chat(G, "Choice registered: Yes.")
- if((world.time-time_passed)>poll_time)//If more than 30 game seconds passed.
- to_chat(G, "Sorry, you were too late for the consideration!")
- G << 'sound/machines/buzz-sigh.ogg'
- return
- candidates += G
- if("No")
- to_chat(G, "Choice registered: No.")
- return
- if("Not This Round")
- to_chat(G, "Choice registered: No.")
- to_chat(G, "You will no longer receive notifications for the role '[roletext]' for the rest of the round.")
- G.client.prefs.be_special -= be_special_type
- return
- else
- return
- sleep(poll_time)
-
- //Check all our candidates, to make sure they didn't log off during the 30 second wait period.
- for(var/mob/dead/observer/G in candidates)
- if(!G.key || !G.client)
- candidates.Remove(G)
-
- return candidates
-
-/proc/pollCandidatesWithVeto(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/selected_ghosts = list()
- if(!willing_ghosts.len)
- return selected_ghosts
-
- var/list/candidate_ghosts = willing_ghosts.Copy()
-
- to_chat(adminusr, "Candidate Ghosts:");
- for(var/mob/dead/observer/G in candidate_ghosts)
- if(G.key && G.client)
- to_chat(adminusr, "- [G] ([G.key])");
- else
- candidate_ghosts -= G
-
- for(var/i = max_slots, (i > 0 && candidate_ghosts.len), i--)
- var/this_ghost = input("Pick players. This will go on until there either no more ghosts to pick from or the [i] remaining slot(s) are full.", "Candidates") as null|anything in candidate_ghosts
- candidate_ghosts -= this_ghost
- selected_ghosts += this_ghost
- return selected_ghosts
-
-/proc/window_flash(client/C)
- if(ismob(C))
- var/mob/M = C
- if(M.client)
- C = M.client
- if(!C || !C.prefs.windowflashing)
- return
- winset(C, "mainwindow", "flash=5")
+/proc/get_area(atom/A)
+ RETURN_TYPE(/area)
+ if(isarea(A))
+ return A
+ var/turf/T = get_turf(A)
+ return T ? T.loc : null
+
+/proc/get_area_name(N) //get area by its name
+ for(var/area/A in world)
+ if(A.name == N)
+ return A
+ return 0
+
+/proc/get_location_name(atom/X, format_text = FALSE)
+ var/area/A = isarea(X) ? X : get_area(X)
+ if(!A)
+ return null
+ return format_text ? format_text(A.name) : A.name
+
+/proc/get_areas_in_range(dist=0, atom/center=usr)
+ if(!dist)
+ var/turf/T = get_turf(center)
+ return T ? list(T.loc) : list()
+ if(!center)
+ return list()
+
+ var/list/turfs = RANGE_TURFS(dist, center)
+ var/list/areas = list()
+ for(var/V in turfs)
+ var/turf/T = V
+ areas |= T.loc
+ return areas
+
+// Like view but bypasses luminosity check
+
+/proc/hear(var/range, var/atom/source)
+ var/lum = source.luminosity
+ source.luminosity = 6
+
+ var/list/heard = view(range, source)
+ source.luminosity = lum
+
+ return heard
+
+/proc/circlerange(center=usr,radius=3)
+
+ var/turf/centerturf = get_turf(center)
+ var/list/turfs = new/list()
+ var/rsq = radius * (radius+0.5)
+
+ for(var/atom/T in range(radius, centerturf))
+ var/dx = T.x - centerturf.x
+ var/dy = T.y - centerturf.y
+ if(dx*dx + dy*dy <= rsq)
+ turfs += T
+
+ //turfs += centerturf
+ return turfs
+
+/proc/circleview(center=usr,radius=3)
+
+ var/turf/centerturf = get_turf(center)
+ var/list/atoms = new/list()
+ var/rsq = radius * (radius+0.5)
+
+ for(var/atom/A in view(radius, centerturf))
+ var/dx = A.x - centerturf.x
+ var/dy = A.y - centerturf.y
+ if(dx*dx + dy*dy <= rsq)
+ atoms += A
+
+ //turfs += centerturf
+ return atoms
+
+/proc/ff_cansee(atom/A, atom/B)
+ var/AT = get_turf(A)
+ var/BT = get_turf(B)
+ if(AT == BT)
+ return 1
+ var/list/line = getline(A, B)
+ for(var/turf/T in line)
+ if(T == AT || T == BT)
+ break
+ if(T.density)
+ return FALSE
+ return TRUE
+
+/proc/get_dist_euclidian(atom/Loc1 as turf|mob|obj,atom/Loc2 as turf|mob|obj)
+ var/dx = Loc1.x - Loc2.x
+ var/dy = Loc1.y - Loc2.y
+
+ var/dist = sqrt(dx**2 + dy**2)
+
+ return dist
+
+/proc/circlerangeturfs(center=usr,radius=3)
+
+ var/turf/centerturf = get_turf(center)
+ var/list/turfs = new/list()
+ var/rsq = radius * (radius+0.5)
+
+ for(var/turf/T in range(radius, centerturf))
+ var/dx = T.x - centerturf.x
+ var/dy = T.y - centerturf.y
+ if(dx*dx + dy*dy <= rsq)
+ turfs += T
+ return turfs
+
+/proc/circleviewturfs(center=usr,radius=3) //Is there even a diffrence between this proc and circlerangeturfs()?
+
+ var/turf/centerturf = get_turf(center)
+ var/list/turfs = new/list()
+ var/rsq = radius * (radius+0.5)
+
+ for(var/turf/T in view(radius, centerturf))
+ var/dx = T.x - centerturf.x
+ var/dy = T.y - centerturf.y
+ if(dx*dx + dy*dy <= rsq)
+ turfs += T
+ return turfs
+
+
+
+//GLOBAL_VAR_INIT(debug_mob, 0)
+
+// Will recursively loop through an atom's contents and check for mobs, then it will loop through every atom in that atom's contents.
+// It will keep doing this until it checks every content possible. This will fix any problems with mobs, that are inside objects,
+// being unable to hear people due to being in a box within a bag.
+
+/proc/recursive_mob_check(var/atom/O, var/list/L = list(), var/recursion_limit = 3, var/client_check = 1, var/sight_check = 1, var/include_radio = 1)
+
+ //GLOB.debug_mob += O.contents.len
+ if(!recursion_limit)
+ return L
+ for(var/atom/A in O.contents)
+
+ if(ismob(A))
+ var/mob/M = A
+ if(client_check && !M.client)
+ L |= recursive_mob_check(A, L, recursion_limit - 1, client_check, sight_check, include_radio)
+ continue
+ if(sight_check && !isInSight(A, O))
+ continue
+ L |= M
+ //log_world("[recursion_limit] = [M] - [get_turf(M)] - ([M.x], [M.y], [M.z])")
+
+ else if(include_radio && istype(A, /obj/item/radio))
+ if(sight_check && !isInSight(A, O))
+ continue
+ L |= A
+
+ if(isobj(A) || ismob(A))
+ L |= recursive_mob_check(A, L, recursion_limit - 1, client_check, sight_check, include_radio)
+ return L
+
+// The old system would loop through lists for a total of 5000 per function call, in an empty server.
+// This new system will loop at around 1000 in an empty server.
+
+/proc/get_mobs_in_view(var/R, var/atom/source, var/include_clientless = FALSE)
+ // Returns a list of mobs in range of R from source. Used in radio and say code.
+
+ var/turf/T = get_turf(source)
+ var/list/hear = list()
+
+ if(!T)
+ return hear
+
+ var/list/range = hear(R, T)
+
+ for(var/atom/A in range)
+ if(ismob(A))
+ var/mob/M = A
+ if(M.client || include_clientless)
+ hear += M
+ //log_world("Start = [M] - [get_turf(M)] - ([M.x], [M.y], [M.z])")
+ else if(istype(A, /obj/item/radio))
+ hear += A
+
+ if(isobj(A) || ismob(A))
+ hear |= recursive_mob_check(A, hear, 3, 1, 0, 1)
+
+ return hear
+
+
+/proc/get_mobs_in_radio_ranges(var/list/obj/item/radio/radios)
+
+ set background = 1
+
+ . = list()
+ // Returns a list of mobs who can hear any of the radios given in @radios
+ var/list/speaker_coverage = list()
+ for(var/obj/item/radio/R in radios)
+ if(R)
+ //Cyborg checks. Receiving message uses a bit of cyborg's charge.
+ var/obj/item/radio/borg/BR = R
+ if(istype(BR) && BR.myborg)
+ var/mob/living/silicon/robot/borg = BR.myborg
+ var/datum/robot_component/CO = borg.get_component("radio")
+ if(!CO)
+ continue //No radio component (Shouldn't happen)
+ if(!borg.is_component_functioning("radio"))
+ continue //No power.
+
+ var/turf/speaker = get_turf(R)
+ if(speaker)
+ for(var/turf/T in hear(R.canhear_range,speaker))
+ speaker_coverage[T] = T
+
+
+ // Try to find all the players who can hear the message
+ for(var/A in GLOB.player_list + GLOB.hear_radio_list)
+ var/mob/M = A
+ if(M)
+ var/turf/ear = get_turf(M)
+ if(ear)
+ // Ghostship is magic: Ghosts can hear radio chatter from anywhere
+ if(speaker_coverage[ear] || (istype(M, /mob/dead/observer) && M.get_preference(CHAT_GHOSTRADIO)))
+ . |= M // Since we're already looping through mobs, why bother using |= ? This only slows things down.
+ return .
+
+/proc/inLineOfSight(X1,Y1,X2,Y2,Z=1,PX1=16.5,PY1=16.5,PX2=16.5,PY2=16.5)
+ var/turf/T
+ if(X1==X2)
+ if(Y1==Y2)
+ return 1 //Light cannot be blocked on same tile
+ else
+ var/s = SIMPLE_SIGN(Y2-Y1)
+ Y1+=s
+ while(Y1!=Y2)
+ T=locate(X1,Y1,Z)
+ if(T.opacity)
+ return 0
+ Y1+=s
+ else
+ var/m=(32*(Y2-Y1)+(PY2-PY1))/(32*(X2-X1)+(PX2-PX1))
+ var/b=(Y1+PY1/32-0.015625)-m*(X1+PX1/32-0.015625) //In tiles
+ var/signX = SIMPLE_SIGN(X2-X1)
+ var/signY = SIMPLE_SIGN(Y2-Y1)
+ if(X1 abs (dx)) //slope is above 1:1 (move horizontally in a tie)
+ if(dy > 0)
+ return get_step(start, SOUTH)
+ else
+ return get_step(start, NORTH)
+ else
+ if(dx > 0)
+ return get_step(start, WEST)
+ else
+ return get_step(start, EAST)
+
+/proc/try_move_adjacent(atom/movable/AM)
+ var/turf/T = get_turf(AM)
+ for(var/direction in GLOB.cardinal)
+ if(AM.Move(get_step(T, direction)))
+ break
+
+/proc/get_mob_by_key(var/key)
+ for(var/mob/M in GLOB.mob_list)
+ if(M.ckey == lowertext(key))
+ return M
+ return null
+
+/proc/get_candidates(be_special_type, afk_bracket=3000, override_age=0, override_jobban=0)
+ var/roletext = get_roletext(be_special_type)
+ var/list/candidates = list()
+ // Keep looping until we find a non-afk candidate within the time bracket (we limit the bracket to 10 minutes (6000))
+ while(!candidates.len && afk_bracket < 6000)
+ for(var/mob/dead/observer/G in GLOB.player_list)
+ if(G.client != null)
+ if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
+ if(!G.client.is_afk(afk_bracket) && (be_special_type in G.client.prefs.be_special))
+ if(!override_jobban || (!jobban_isbanned(G, roletext) && !jobban_isbanned(G,"Syndicate")))
+ if(override_age || player_old_enough_antag(G.client,be_special_type))
+ candidates += G.client
+ afk_bracket += 600 // Add a minute to the bracket, for every attempt
+
+ return candidates
+
+/proc/get_candidate_ghosts(be_special_type, afk_bracket=3000, override_age=0, override_jobban=0)
+ var/roletext = get_roletext(be_special_type)
+ var/list/candidates = list()
+ // Keep looping until we find a non-afk candidate within the time bracket (we limit the bracket to 10 minutes (6000))
+ while(!candidates.len && afk_bracket < 6000)
+ for(var/mob/dead/observer/G in GLOB.player_list)
+ if(G.client != null)
+ if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
+ if(!G.client.is_afk(afk_bracket) && (be_special_type in G.client.prefs.be_special))
+ if(!override_jobban || (!jobban_isbanned(G, roletext) && !jobban_isbanned(G,"Syndicate")))
+ if(override_age || player_old_enough_antag(G.client,be_special_type))
+ candidates += G
+ afk_bracket += 600 // Add a minute to the bracket, for every attempt
+
+ return candidates
+
+/proc/ScreenText(obj/O, maptext="", screen_loc="CENTER-7,CENTER-7", maptext_height=480, maptext_width=480)
+ if(!isobj(O)) O = new /obj/screen/text()
+ O.maptext = maptext
+ O.maptext_height = maptext_height
+ O.maptext_width = maptext_width
+ O.screen_loc = screen_loc
+ return O
+
+/proc/Show2Group4Delay(obj/O, list/group, delay=0)
+ if(!isobj(O)) return
+ if(!group) group = GLOB.clients
+ for(var/client/C in group)
+ C.screen += O
+ if(delay)
+ spawn(delay)
+ for(var/client/C in group)
+ C.screen -= O
+
+/proc/flick_overlay(image/I, list/show_to, duration)
+ for(var/client/C in show_to)
+ C.images += I
+ spawn(duration)
+ for(var/client/C in show_to)
+ C.images -= I
+
+/proc/get_active_player_count()
+ // Get active players who are playing in the round
+ var/active_players = 0
+ for(var/i = 1; i <= GLOB.player_list.len; i++)
+ var/mob/M = GLOB.player_list[i]
+ if(M && M.client)
+ if(istype(M, /mob/new_player)) // exclude people in the lobby
+ continue
+ else if(isobserver(M)) // Ghosts are fine if they were playing once (didn't start as observers)
+ var/mob/dead/observer/O = M
+ if(O.started_as_observer) // Exclude people who started as observers
+ continue
+ active_players++
+ return active_players
+
+/datum/projectile_data
+ var/src_x
+ var/src_y
+ var/time
+ var/distance
+ var/power_x
+ var/power_y
+ var/dest_x
+ var/dest_y
+
+/datum/projectile_data/New(var/src_x, var/src_y, var/time, var/distance, \
+ var/power_x, var/power_y, var/dest_x, var/dest_y)
+ src.src_x = src_x
+ src.src_y = src_y
+ src.time = time
+ src.distance = distance
+ src.power_x = power_x
+ src.power_y = power_y
+ src.dest_x = dest_x
+ src.dest_y = dest_y
+
+/proc/projectile_trajectory(var/src_x, var/src_y, var/rotation, var/angle, var/power)
+
+ // returns the destination (Vx,y) that a projectile shot at [src_x], [src_y], with an angle of [angle],
+ // rotated at [rotation] and with the power of [power]
+ // Thanks to VistaPOWA for this function
+
+ var/power_x = power * cos(angle)
+ var/power_y = power * sin(angle)
+ var/time = 2* power_y / 10 //10 = g
+
+ var/distance = time * power_x
+
+ var/dest_x = src_x + distance*sin(rotation);
+ var/dest_y = src_y + distance*cos(rotation);
+
+ return new /datum/projectile_data(src_x, src_y, time, distance, power_x, power_y, dest_x, dest_y)
+
+
+/proc/mobs_in_area(var/area/the_area, var/client_needed=0, var/moblist=GLOB.mob_list)
+ var/list/mobs_found[0]
+ var/area/our_area = get_area(the_area)
+ for(var/mob/M in moblist)
+ if(client_needed && !M.client)
+ continue
+ if(our_area != get_area(M))
+ continue
+ mobs_found += M
+ return mobs_found
+
+/proc/alone_in_area(var/area/the_area, var/mob/must_be_alone, var/check_type = /mob/living/carbon)
+ var/area/our_area = get_area(the_area)
+ for(var/C in GLOB.living_mob_list)
+ if(!istype(C, check_type))
+ continue
+ if(C == must_be_alone)
+ continue
+ if(our_area == get_area(C))
+ return 0
+ return 1
+
+/proc/lavaland_equipment_pressure_check(turf/T)
+ . = FALSE
+ if(!istype(T))
+ return
+ var/datum/gas_mixture/environment = T.return_air()
+ if(!istype(environment))
+ return
+ var/pressure = environment.return_pressure()
+ if(pressure <= LAVALAND_EQUIPMENT_EFFECT_PRESSURE)
+ . = TRUE
+
+/proc/MinutesToTicks(var/minutes as num)
+ return minutes * 60 * 10
+
+/proc/SecondsToTicks(var/seconds)
+ return seconds * 10
+
+proc/pollCandidates(Question, be_special_type, antag_age_check = FALSE, poll_time = 300, ignore_respawnability = FALSE, 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
+ if(!Question)
+ Question = "Would you like to be a special role?"
+
+ for(var/mob/dead/observer/G in (ignore_respawnability ? GLOB.player_list : GLOB.respawnable_list))
+ if(!G.key || !G.client)
+ continue
+ if(be_special_type)
+ if(!(be_special_type in G.client.prefs.be_special))
+ continue
+ if(antag_age_check)
+ if(!player_old_enough_antag(G.client, be_special_type))
+ continue
+ if(roletext)
+ if(jobban_isbanned(G, roletext) || jobban_isbanned(G, "Syndicate"))
+ continue
+ if(config.use_exp_restrictions && min_hours)
+ if(G.client.get_exp_type_num(EXP_TYPE_LIVING) < min_hours * 60)
+ continue
+ if(check_antaghud && cannotPossess(G))
+ continue
+ spawn(0)
+ G << 'sound/misc/notice2.ogg'//Alerting them to their consideration
+ if(flashwindow)
+ window_flash(G.client)
+ var/ans = alert(G,Question,"Please answer in [poll_time/10] seconds!","No","Yes","Not This Round")
+ if(!G?.client)
+ return
+ switch(ans)
+ if("Yes")
+ to_chat(G, "Choice registered: Yes.")
+ if((world.time-time_passed)>poll_time)//If more than 30 game seconds passed.
+ to_chat(G, "Sorry, you were too late for the consideration!")
+ G << 'sound/machines/buzz-sigh.ogg'
+ return
+ candidates += G
+ if("No")
+ to_chat(G, "Choice registered: No.")
+ return
+ if("Not This Round")
+ to_chat(G, "Choice registered: No.")
+ to_chat(G, "You will no longer receive notifications for the role '[roletext]' for the rest of the round.")
+ G.client.prefs.be_special -= be_special_type
+ return
+ else
+ return
+ sleep(poll_time)
+
+ //Check all our candidates, to make sure they didn't log off during the 30 second wait period.
+ for(var/mob/dead/observer/G in candidates)
+ if(!G.key || !G.client)
+ candidates.Remove(G)
+
+ return candidates
+
+/proc/pollCandidatesWithVeto(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/selected_ghosts = list()
+ if(!willing_ghosts.len)
+ return selected_ghosts
+
+ var/list/candidate_ghosts = willing_ghosts.Copy()
+
+ to_chat(adminusr, "Candidate Ghosts:");
+ for(var/mob/dead/observer/G in candidate_ghosts)
+ if(G.key && G.client)
+ to_chat(adminusr, "- [G] ([G.key])");
+ else
+ candidate_ghosts -= G
+
+ for(var/i = max_slots, (i > 0 && candidate_ghosts.len), i--)
+ var/this_ghost = input("Pick players. This will go on until there either no more ghosts to pick from or the [i] remaining slot(s) are full.", "Candidates") as null|anything in candidate_ghosts
+ candidate_ghosts -= this_ghost
+ selected_ghosts += this_ghost
+ return selected_ghosts
+
+/proc/window_flash(client/C)
+ if(ismob(C))
+ var/mob/M = C
+ if(M.client)
+ C = M.client
+ if(!C || !C.prefs.windowflashing)
+ return
+ winset(C, "mainwindow", "flash=5")
diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm
index 2a23cc8baa0..0002bc0d488 100644
--- a/code/__HELPERS/global_lists.dm
+++ b/code/__HELPERS/global_lists.dm
@@ -1,90 +1,90 @@
-
-//////////////////////////
-/////Initial Building/////
-//////////////////////////
-
-/proc/makeDatumRefLists()
- //markings
- init_sprite_accessory_subtypes(/datum/sprite_accessory/body_markings, GLOB.marking_styles_list)
- //head accessory
- init_sprite_accessory_subtypes(/datum/sprite_accessory/head_accessory, GLOB.head_accessory_styles_list)
- //hair
- init_sprite_accessory_subtypes(/datum/sprite_accessory/hair, GLOB.hair_styles_public_list, GLOB.hair_styles_male_list, GLOB.hair_styles_female_list, GLOB.hair_styles_full_list)
- //facial hair
- init_sprite_accessory_subtypes(/datum/sprite_accessory/facial_hair, GLOB.facial_hair_styles_list, GLOB.facial_hair_styles_male_list, GLOB.facial_hair_styles_female_list)
- //underwear
- init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear, GLOB.underwear_list, GLOB.underwear_m, GLOB.underwear_f)
- //undershirt
- init_sprite_accessory_subtypes(/datum/sprite_accessory/undershirt, GLOB.undershirt_list, GLOB.undershirt_m, GLOB.undershirt_f)
- //socks
- init_sprite_accessory_subtypes(/datum/sprite_accessory/socks, GLOB.socks_list, GLOB.socks_m, GLOB.socks_f)
- //alt heads
- init_sprite_accessory_subtypes(/datum/sprite_accessory/alt_heads, GLOB.alt_heads_list)
-
- init_subtypes(/datum/surgery_step, GLOB.surgery_steps)
-
- for(var/path in (subtypesof(/datum/surgery)))
- GLOB.surgeries_list += new path()
-
- init_datum_subtypes(/datum/job, GLOB.joblist, list(/datum/job/ai, /datum/job/cyborg), "title")
- init_datum_subtypes(/datum/superheroes, GLOB.all_superheroes, null, "name")
- init_datum_subtypes(/datum/language, GLOB.all_languages, null, "name")
-
- for(var/language_name in GLOB.all_languages)
- var/datum/language/L = GLOB.all_languages[language_name]
- if(!(L.flags & NONGLOBAL))
- GLOB.language_keys[":[lowertext(L.key)]"] = L
- GLOB.language_keys[".[lowertext(L.key)]"] = L
- GLOB.language_keys["#[lowertext(L.key)]"] = L
-
- var/rkey = 0
- for(var/spath in subtypesof(/datum/species))
- var/datum/species/S = new spath()
- S.race_key = ++rkey //Used in mob icon caching.
- GLOB.all_species[S.name] = S
-
- if(IS_WHITELISTED in S.species_traits)
- GLOB.whitelisted_species += S.name
-
- init_subtypes(/datum/crafting_recipe, GLOB.crafting_recipes)
-
- //Pipe list building
- init_subtypes(/datum/pipes, GLOB.construction_pipe_list)
- for(var/D in GLOB.construction_pipe_list)
- var/datum/pipes/P = D
- if(P.rpd_dispensable)
- GLOB.rpd_pipe_list += list(list("pipe_name" = P.pipe_name, "pipe_id" = P.pipe_id, "pipe_type" = P.pipe_type, "pipe_category" = P.pipe_category, "orientations" = P.orientations, "pipe_icon" = P.pipe_icon, "bendy" = P.bendy))
- return 1
-
-/* // Uncomment to debug chemical reaction list.
-/client/verb/debug_chemical_list()
-
- for(var/reaction in GLOB.chemical_reactions_list)
- . += "GLOB.chemical_reactions_list\[\"[reaction]\"\] = \"[GLOB.chemical_reactions_list[reaction]]\"\n"
- if(islist(GLOB.chemical_reactions_list[reaction]))
- var/list/L = GLOB.chemical_reactions_list[reaction]
- for(var/t in L)
- . += " has: [t]\n"
- to_chat(world, .)
-*/
-
-
-//creates every subtype of prototype (excluding prototype) and adds it to list L.
-//if no list/L is provided, one is created.
-/proc/init_subtypes(prototype, list/L)
- if(!istype(L)) L = list()
- for(var/path in subtypesof(prototype))
- L += new path()
- return L
-
-/proc/init_datum_subtypes(prototype, list/L, list/pexempt, assocvar)
- if(!istype(L)) L = list()
- for(var/path in subtypesof(prototype) - pexempt)
- var/datum/D = new path()
- if(istype(D))
- var/assoc
- if(D.vars["[assocvar]"]) //has the var
- assoc = D.vars["[assocvar]"] //access value of var
- if(assoc) //value gotten
- L["[assoc]"] = D //put in association
- return L
+
+//////////////////////////
+/////Initial Building/////
+//////////////////////////
+
+/proc/makeDatumRefLists()
+ //markings
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/body_markings, GLOB.marking_styles_list)
+ //head accessory
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/head_accessory, GLOB.head_accessory_styles_list)
+ //hair
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/hair, GLOB.hair_styles_public_list, GLOB.hair_styles_male_list, GLOB.hair_styles_female_list, GLOB.hair_styles_full_list)
+ //facial hair
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/facial_hair, GLOB.facial_hair_styles_list, GLOB.facial_hair_styles_male_list, GLOB.facial_hair_styles_female_list)
+ //underwear
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear, GLOB.underwear_list, GLOB.underwear_m, GLOB.underwear_f)
+ //undershirt
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/undershirt, GLOB.undershirt_list, GLOB.undershirt_m, GLOB.undershirt_f)
+ //socks
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/socks, GLOB.socks_list, GLOB.socks_m, GLOB.socks_f)
+ //alt heads
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/alt_heads, GLOB.alt_heads_list)
+
+ init_subtypes(/datum/surgery_step, GLOB.surgery_steps)
+
+ for(var/path in (subtypesof(/datum/surgery)))
+ GLOB.surgeries_list += new path()
+
+ init_datum_subtypes(/datum/job, GLOB.joblist, list(/datum/job/ai, /datum/job/cyborg), "title")
+ init_datum_subtypes(/datum/superheroes, GLOB.all_superheroes, null, "name")
+ init_datum_subtypes(/datum/language, GLOB.all_languages, null, "name")
+
+ for(var/language_name in GLOB.all_languages)
+ var/datum/language/L = GLOB.all_languages[language_name]
+ if(!(L.flags & NONGLOBAL))
+ GLOB.language_keys[":[lowertext(L.key)]"] = L
+ GLOB.language_keys[".[lowertext(L.key)]"] = L
+ GLOB.language_keys["#[lowertext(L.key)]"] = L
+
+ var/rkey = 0
+ for(var/spath in subtypesof(/datum/species))
+ var/datum/species/S = new spath()
+ S.race_key = ++rkey //Used in mob icon caching.
+ GLOB.all_species[S.name] = S
+
+ if(IS_WHITELISTED in S.species_traits)
+ GLOB.whitelisted_species += S.name
+
+ init_subtypes(/datum/crafting_recipe, GLOB.crafting_recipes)
+
+ //Pipe list building
+ init_subtypes(/datum/pipes, GLOB.construction_pipe_list)
+ for(var/D in GLOB.construction_pipe_list)
+ var/datum/pipes/P = D
+ if(P.rpd_dispensable)
+ GLOB.rpd_pipe_list += list(list("pipe_name" = P.pipe_name, "pipe_id" = P.pipe_id, "pipe_type" = P.pipe_type, "pipe_category" = P.pipe_category, "orientations" = P.orientations, "pipe_icon" = P.pipe_icon, "bendy" = P.bendy))
+ return 1
+
+/* // Uncomment to debug chemical reaction list.
+/client/verb/debug_chemical_list()
+
+ for(var/reaction in GLOB.chemical_reactions_list)
+ . += "GLOB.chemical_reactions_list\[\"[reaction]\"\] = \"[GLOB.chemical_reactions_list[reaction]]\"\n"
+ if(islist(GLOB.chemical_reactions_list[reaction]))
+ var/list/L = GLOB.chemical_reactions_list[reaction]
+ for(var/t in L)
+ . += " has: [t]\n"
+ to_chat(world, .)
+*/
+
+
+//creates every subtype of prototype (excluding prototype) and adds it to list L.
+//if no list/L is provided, one is created.
+/proc/init_subtypes(prototype, list/L)
+ if(!istype(L)) L = list()
+ for(var/path in subtypesof(prototype))
+ L += new path()
+ return L
+
+/proc/init_datum_subtypes(prototype, list/L, list/pexempt, assocvar)
+ if(!istype(L)) L = list()
+ for(var/path in subtypesof(prototype) - pexempt)
+ var/datum/D = new path()
+ if(istype(D))
+ var/assoc
+ if(D.vars["[assocvar]"]) //has the var
+ assoc = D.vars["[assocvar]"] //access value of var
+ if(assoc) //value gotten
+ L["[assoc]"] = D //put in association
+ return L
diff --git a/code/__HELPERS/icon_smoothing.dm b/code/__HELPERS/icon_smoothing.dm
index acf202f0eee..dc256a93478 100644
--- a/code/__HELPERS/icon_smoothing.dm
+++ b/code/__HELPERS/icon_smoothing.dm
@@ -66,7 +66,7 @@
if(AM.can_be_unanchored && !AM.anchored)
return 0
- for(var/direction in cardinal)
+ for(var/direction in GLOB.cardinal)
AM = find_type_in_direction(A, direction)
if(AM == NULLTURF_BORDER)
if((A.smooth & SMOOTH_BORDER))
diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm
index 0b37872decd..4e11dbf4140 100644
--- a/code/__HELPERS/icons.dm
+++ b/code/__HELPERS/icons.dm
@@ -1,963 +1,975 @@
-/*
-IconProcs README
-
-A BYOND library for manipulating icons and colors
-
-by Lummox JR
-
-version 1.0
-
-The IconProcs library was made to make a lot of common icon operations much easier. BYOND's icon manipulation
-routines are very capable but some of the advanced capabilities like using alpha transparency can be unintuitive to beginners.
-
-CHANGING ICONS
-
-Several new procs have been added to the /icon datum to simplify working with icons. To use them,
-remember you first need to setup an /icon var like so:
-
-var/icon/my_icon = new('iconfile.dmi')
-
-icon/ChangeOpacity(amount = 1)
- A very common operation in DM is to try to make an icon more or less transparent. Making an icon more
- transparent is usually much easier than making it less so, however. This proc basically is a frontend
- for MapColors() which can change opacity any way you like, in much the same way that SetIntensity()
- can make an icon lighter or darker. If amount is 0.5, the opacity of the icon will be cut in half.
- If amount is 2, opacity is doubled and anything more than half-opaque will become fully opaque.
-icon/GrayScale()
- Converts the icon to grayscale instead of a fully colored icon. Alpha values are left intact.
-icon/ColorTone(tone)
- Similar to GrayScale(), this proc converts the icon to a range of black -> tone -> white, where tone is an
- RGB color (its alpha is ignored). This can be used to create a sepia tone or similar effect.
- See also the global ColorTone() proc.
-icon/MinColors(icon)
- The icon is blended with a second icon where the minimum of each RGB pixel is the result.
- Transparency may increase, as if the icons were blended with ICON_ADD. You may supply a color in place of an icon.
-icon/MaxColors(icon)
- The icon is blended with a second icon where the maximum of each RGB pixel is the result.
- Opacity may increase, as if the icons were blended with ICON_OR. You may supply a color in place of an icon.
-icon/Opaque(background = "#000000")
- All alpha values are set to 255 throughout the icon. Transparent pixels become black, or whatever background color you specify.
-icon/BecomeAlphaMask()
- You can convert a simple grayscale icon into an alpha mask to use with other icons very easily with this proc.
- The black parts become transparent, the white parts stay white, and anything in between becomes a translucent shade of white.
-icon/AddAlphaMask(mask)
- The alpha values of the mask icon will be blended with the current icon. Anywhere the mask is opaque,
- the current icon is untouched. Anywhere the mask is transparent, the current icon becomes transparent.
- Where the mask is translucent, the current icon becomes more transparent.
-icon/UseAlphaMask(mask, mode)
- Sometimes you may want to take the alpha values from one icon and use them on a different icon.
- This proc will do that. Just supply the icon whose alpha mask you want to use, and src will change
- so it has the same colors as before but uses the mask for opacity.
-
-COLOR MANAGEMENT AND HSV
-
-RGB isn't the only way to represent color. Sometimes it's more useful to work with a model called HSV, which stands for hue, saturation, and value.
-
- * The hue of a color describes where it is along the color wheel. It goes from red to yellow to green to
- cyan to blue to magenta and back to red.
- * The saturation of a color is how much color is in it. A color with low saturation will be more gray,
- and with no saturation at all it is a shade of gray.
- * The value of a color determines how bright it is. A high-value color is vivid, moderate value is dark,
- and no value at all is black.
-
-Just as BYOND uses "#rrggbb" to represent RGB values, a similar format is used for HSV: "#hhhssvv". The hue is three
-hex digits because it ranges from 0 to 0x5FF.
-
- * 0 to 0xFF - red to yellow
- * 0x100 to 0x1FF - yellow to green
- * 0x200 to 0x2FF - green to cyan
- * 0x300 to 0x3FF - cyan to blue
- * 0x400 to 0x4FF - blue to magenta
- * 0x500 to 0x5FF - magenta to red
-
-Knowing this, you can figure out that red is "#000ffff" in HSV format, which is hue 0 (red), saturation 255 (as colorful as possible),
-value 255 (as bright as possible). Green is "#200ffff" and blue is "#400ffff".
-
-More than one HSV color can match the same RGB color.
-
-Here are some procs you can use for color management:
-
-ReadRGB(rgb)
- Takes an RGB string like "#ffaa55" and converts it to a list such as list(255,170,85). If an RGBA format is used
- that includes alpha, the list will have a fourth item for the alpha value.
-hsv(hue, sat, val, apha)
- Counterpart to rgb(), this takes the values you input and converts them to a string in "#hhhssvv" or "#hhhssvvaa"
- format. Alpha is not included in the result if null.
-ReadHSV(rgb)
- Takes an HSV string like "#100FF80" and converts it to a list such as list(256,255,128). If an HSVA format is used that
- includes alpha, the list will have a fourth item for the alpha value.
-RGBtoHSV(rgb)
- Takes an RGB or RGBA string like "#ffaa55" and converts it into an HSV or HSVA color such as "#080aaff".
-HSVtoRGB(hsv)
- Takes an HSV or HSVA string like "#080aaff" and converts it into an RGB or RGBA color such as "#ff55aa".
-BlendRGB(rgb1, rgb2, amount)
- Blends between two RGB or RGBA colors using regular RGB blending. If amount is 0, the first color is the result;
- if 1, the second color is the result. 0.5 produces an average of the two. Values outside the 0 to 1 range are allowed as well.
- The returned value is an RGB or RGBA color.
-BlendHSV(hsv1, hsv2, amount)
- Blends between two HSV or HSVA colors using HSV blending, which tends to produce nicer results than regular RGB
- blending because the brightness of the color is left intact. If amount is 0, the first color is the result; if 1,
- the second color is the result. 0.5 produces an average of the two. Values outside the 0 to 1 range are allowed as well.
- The returned value is an HSV or HSVA color.
-BlendRGBasHSV(rgb1, rgb2, amount)
- Like BlendHSV(), but the colors used and the return value are RGB or RGBA colors. The blending is done in HSV form.
-HueToAngle(hue)
- Converts a hue to an angle range of 0 to 360. Angle 0 is red, 120 is green, and 240 is blue.
-AngleToHue(hue)
- Converts an angle to a hue in the valid range.
-RotateHue(hsv, angle)
- Takes an HSV or HSVA value and rotates the hue forward through red, green, and blue by an angle from 0 to 360.
- (Rotating red by 60° produces yellow.) The result is another HSV or HSVA color with the same saturation and value
- as the original, but a different hue.
-GrayScale(rgb)
- Takes an RGB or RGBA color and converts it to grayscale. Returns an RGB or RGBA string.
-ColorTone(rgb, tone)
- Similar to GrayScale(), this proc converts an RGB or RGBA color to a range of black -> tone -> white instead of
- using strict shades of gray. The tone value is an RGB color; any alpha value is ignored.
-*/
-
-/*
-Get Flat Icon DEMO by DarkCampainger
-
-This is a test for the get flat icon proc, modified approprietly for icons and their states.
-Probably not a good idea to run this unless you want to see how the proc works in detail.
-mob
- icon = 'old_or_unused.dmi'
- icon_state = "green"
-
- Login()
- // Testing image underlays
- underlays += image(icon='old_or_unused.dmi',icon_state="red")
- underlays += image(icon='old_or_unused.dmi',icon_state="red", pixel_x = 32)
- underlays += image(icon='old_or_unused.dmi',icon_state="red", pixel_x = -32)
-
- // Testing image overlays
- overlays += image(icon='old_or_unused.dmi',icon_state="green", pixel_x = 32, pixel_y = -32)
- overlays += image(icon='old_or_unused.dmi',icon_state="green", pixel_x = 32, pixel_y = 32)
- overlays += image(icon='old_or_unused.dmi',icon_state="green", pixel_x = -32, pixel_y = -32)
-
- // Testing icon file overlays (defaults to mob's state)
- overlays += '_flat_demoIcons2.dmi'
-
- // Testing icon_state overlays (defaults to mob's icon)
- overlays += "white"
-
- // Testing dynamic icon overlays
- var/icon/I = icon('old_or_unused.dmi', icon_state="aqua")
- I.Shift(NORTH,16,1)
- overlays+=I
-
- // Testing dynamic image overlays
- I=image(icon=I,pixel_x = -32, pixel_y = 32)
- overlays+=I
-
- // Testing object types (and layers)
- overlays+=/obj/effect/overlayTest
-
- loc = locate (10,10,1)
- verb
- Browse_Icon()
- set name = "1. Browse Icon"
- // Give it a name for the cache
- var/iconName = "[ckey(src.name)]_flattened.dmi"
- // Send the icon to src's local cache
- src<